Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Document compat. guarantees, monitor serialization compat by tnull · Pull Request #931 · lightningdevkit/ldk-node · GitHub
Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Document compat. guarantees, monitor serialization compat by tnull · Pull Request #931 · lightningdevkit/ldk-node · GitHub
Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Document compat. guarantees, monitor serialization compat by tnull · Pull Request #931 · lightningdevkit/ldk-node · GitHub
Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Document compat. guarantees, monitor serialization compat by tnull · Pull Request #931 · lightningdevkit/ldk-node · GitHub
Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Document compat. guarantees, monitor serialization compat by tnull · Pull Request #931 · lightningdevkit/ldk-node · GitHub
Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Document compat. guarantees, monitor serialization compat by tnull · Pull Request #931 · lightningdevkit/ldk-node · GitHub
Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Document compat. guarantees, monitor serialization compat by tnull · Pull Request #931 · lightningdevkit/ldk-node · GitHub
Skip to content

Document compat. guarantees, monitor serialization compat - #931

Merged
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070
Jun 11, 2026
Merged

Document compat. guarantees, monitor serialization compat#931
tnull merged 3 commits into
lightningdevkit:mainfrom
tnull:2026-06-compat-guarantees-downgrade-070

Conversation

@tnull

Copy link
Copy Markdown
Collaborator

Fixes#74.

We briefly document our compat guarantees in README.md.

We also add a canary test that checks whether we're forwards compatible with v0.7.0 on the serialization layer. Note that due to the recent schema upgrades of SqliteStore, FilesystemStore, VssStore we don't actually test full downgrades to prior versions. However, this canary is meant to be extended going forward, so that hopefully at some point we can be comfortable to guarantee forward compatibility guarantees also.

@tnull
tnull requested a review from joostjagerJune 11, 2026 09:31
@ldk-reviews-bot

ldk-reviews-bot commented Jun 11, 2026

Copy link
Copy Markdown

👋 Thanks for assigning @joostjager as a reviewer!
I'll wait for their review and will help manage the review process.
Once they submit their review, I'll check if a second reviewer would be helpful.

@tnulltnull self-assigned this Jun 11, 2026
@tnulltnull moved this to Goal: Merge in Weekly GoalsJun 11, 2026
@tnulltnull added this to the 0.8 milestone Jun 11, 2026
&esplora_url,
);

assert_eq!(node_a_v070.node_id(), node_id_a);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe recheck to see if the payment is still there?

Comment threadREADME.md Outdated

## Compatibility

LDK Node does not provide a stable public API until v1.0. We do aim to keep persisted node state backwards compatible, so newer releases are guaranteed to be able to load state written by older releases.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reads like an aspiration (aim) mixed with a guarantee. Is it a guarantee?

Perhaps also state explicitly that downgrades are not supported.

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. Codex first take was too lax and I only amended the second part of the sentence. Now added a fixup.


async fn drain_v070_events(node: &ldk_node_070::Node) {
while tokio::time::timeout(Duration::from_millis(250), node.next_event_async()).await.is_ok() {
node.event_handled().unwrap();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if you want to do any kind of matching on types here. Maybe an error surfaces here?

@tnulltnullJun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I follow, can you reformulate your question?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean events are drained without looking at them, and I was wondering if a downgrade problem could surface there too (and is currently ignored).

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, well, I think we have expect calls for the event types we want to check already, and for the rest we just ignore? Do you have any particular checks in mind that we'd should still be doing?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, nothing in mind. Just posing the question whether this is a way to detect problems. If not, also fine.

@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 69c4d3b to 6741c9dCompareJune 11, 2026 12:43
@tnull
tnull requested a review from joostjagerJune 11, 2026 12:43
joostjager
joostjager previously approved these changes Jun 11, 2026
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 6741c9d to 1f790a9CompareJune 11, 2026 13:36
@tnull
tnull requested a review from joostjagerJune 11, 2026 13:39
@tnull

Copy link
Copy Markdown
CollaboratorAuthor

Squashed fixups, and included minor change to account for uniffi API differences in tests.

tnull added 3 commits June 11, 2026 16:35
Clarify that public APIs remain unstable before 1.0 while persisted
node state is intended to remain readable by newer releases.
Co-Authored-By: HAL 9000
Add a downgrade canary that writes current node state through the legacy
v1 filesystem store and reopens it with ldk-node v0.7.0. This monitors
whether serialized node, channel, and payment state remains usable by
v0.7.0, including a restored channel and a post-restart payment.
This does not assert that the current filesystem-store v2 IO layout can
downgrade to v0.7.0's v1 layout. That IO-layer downgrade is unsupported:
v2 stores empty namespaces under [empty], which v1 readers do not look
up.
Co-Authored-By: HAL 9000
@tnull
tnullforce-pushed the 2026-06-compat-guarantees-downgrade-070 branch from 1f790a9 to a3a7606CompareJune 11, 2026 14:35
@tnull

tnull commented Jun 11, 2026

Copy link
Copy Markdown
CollaboratorAuthor

Accidentally rebased before (now reverted). Net diff since last push is:

> git diff-tree -U2 6741c a3a76061diff --git a/tests/upgrade_downgrade_tests.rs b/tests/upgrade_downgrade_tests.rs
index dbfcf7c0..b30b5a33 100644
--- a/tests/upgrade_downgrade_tests.rs+++ b/tests/upgrade_downgrade_tests.rs@@ -186,4 +186,5 @@ fn build_current_node(
let mut fs_store_path = PathBuf::from(&config.storage_dir_path);
fs_store_path.push("fs_store");
+	#[allow(unused_mut)]
let mut builder = ldk_node::Builder::from_config(config);
builder.set_node_alias(alias.to_string()).unwrap();
@@ -244,5 +245,8 @@ async fn send_current_bolt11_payment(
CurrentDescription::new(description.to_owned()).unwrap(),
);
-	let invoice = payee.bolt11_payment().receive(amount_msat, &invoice_description, 3600).unwrap();+	let invoice = payee+ .bolt11_payment()+ .receive(amount_msat, &invoice_description.clone().into(), 3600)+ .unwrap();
let payment_id = payer.bolt11_payment().send(&invoice, None).unwrap();
expect_current_payment_successful(payer, &payment_id).await;

@joostjagerjoostjager left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't verify whether uniffi tests pass locally now.

@tnull
tnull merged commit 010b483 into lightningdevkit:mainJun 11, 2026
@github-project-automationgithub-project-automationBot moved this from Goal: Merge to Done in Weekly GoalsJun 11, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Document compat. guarantees

3 participants

@tnull@ldk-reviews-bot@joostjager