Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull
, '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" + '
Simplify LSPS5/validator: drop time checks & custom signature storage by martinsaposnic · Pull Request #3961 · lightningdevkit/rust-lightning · GitHub
Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull
, '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('^' + ".*" + ' Simplify LSPS5/validator: drop time checks & custom signature storage by martinsaposnic · Pull Request #3961 · lightningdevkit/rust-lightning · GitHub
Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull
, '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('^' + ".*" + ' Simplify LSPS5/validator: drop time checks & custom signature storage by martinsaposnic · Pull Request #3961 · lightningdevkit/rust-lightning · GitHub
Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull
, '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" + ' Simplify LSPS5/validator: drop time checks & custom signature storage by martinsaposnic · Pull Request #3961 · lightningdevkit/rust-lightning · GitHub
Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull
, '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('^' + ".*" + ' Simplify LSPS5/validator: drop time checks & custom signature storage by martinsaposnic · Pull Request #3961 · lightningdevkit/rust-lightning · GitHub
Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull
, '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('^' + ".*" + ' Simplify LSPS5/validator: drop time checks & custom signature storage by martinsaposnic · Pull Request #3961 · lightningdevkit/rust-lightning · GitHub
Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull
, '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); } })(); })(); Simplify LSPS5/validator: drop time checks & custom signature storage by martinsaposnic · Pull Request #3961 · lightningdevkit/rust-lightning · GitHub
Skip to content

Simplify LSPS5/validator: drop time checks & custom signature storage - #3961

Merged
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up
Jul 30, 2025
Merged

Simplify LSPS5/validator: drop time checks & custom signature storage#3961
tnull merged 1 commit into
lightningdevkit:mainfrom
martinsaposnic:lsps5-validator-follow-up

Conversation

@martinsaposnic

Copy link
Copy Markdown
Contributor

Remove timestamp validation, TimeProvider, SignatureStore trait and its InMemory implementation in favor of a fixed size signature cache. HTTPS already secures delivery, so a small cache is sufficient for basic replay protection.

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

This is a planned follow up for the recently merged PR #3662, here is link with the discussion and motivation for this change #3662 (comment)

@ldk-reviews-bot

ldk-reviews-bot commented Jul 25, 2025

Copy link
Copy Markdown

👋 Thanks for assigning @tnull 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.

@martinsaposnicmartinsaposnic mentioned this pull request Jul 24, 2025
18 tasks
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

pub const MAX_RECENT_SIGNATURES: usize = 5; -> I came up with the 5 number limit, not sure if we need more/less. Please comment your opinion on this

thoughts? @tnull@TheBlueMatt

@codecov

codecovBot commented Jul 25, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.88889% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 88.94%. Comparing base (55d8666) to head (dc97b9c).
⚠️ Report is 7 commits behind head on main.

Files with missing linesPatch %Lines
lightning-liquidity/src/lsps5/msgs.rs0.00%1 Missing ⚠️
lightning-liquidity/src/lsps5/validator.rs94.11%0 Missing and 1 partial ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3961 +/- ##
=======================================
Coverage 88.93% 88.94% =======================================
Files 174 174 Lines 123880 123835 -45 Branches 123880 123835 -45 =======================================
- Hits 110176 110147 -29 + Misses 11251 11240 -11 + Partials 2453 2448 -5 
FlagCoverage Δ
fuzzing22.61% <0.00%> (-0.01%)⬇️
tests88.77% <88.88%> (+<0.01%)⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@martinsaposnic
martinsaposnicforce-pushed the lsps5-validator-follow-up branch 3 times, most recently from a882fed to 2122b24CompareJuly 25, 2025 17:33
TheBlueMatt
TheBlueMatt previously approved these changes Jul 25, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

I'm a fan of this, and the code seems Obviously Correct (tm), but I'll let @tnull chime in in case he thinks there is some attack the more full-featured replay protection fixes.

@TheBlueMatt
TheBlueMatt requested review from tnull and removed request for valentinewallaceJuly 25, 2025 19:50
@ldk-reviews-bot

Copy link
Copy Markdown

🔔 1st Reminder

Hey @tnull! This PR has been waiting for your review.
Please take a look when you have a chance. If you're unable to review, please let us know so we can find another reviewer.

@tnulltnull 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.

As discussed elsewhere, concept ACK from my side. I'll actually also see to update the bLIP-55 PR to drop the mention of the timestamp header there.

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

That said, I'm a bit confused why we have a signature cache at all now? If we think TLS sufficiently protects against replaying packets, what additional protection does the cache give us? Especially, since the cache is of course easily gamed, as any adversary able to intercept and replay messages could now simply intercept 6 different messages and replay them in batches, ensuring that the cache lookup always misses?

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

@tnulltnull 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.

Independently from the discussion on whether we need to store signatures at all, this needs a rebase.

Remove timestamp validation, TimeProvider, SignatureStore trait
and its InMemory implementation in favor of a fixed size signature
cache. HTTPS already secures delivery, so a small cache is sufficient
for basic replay protection.
@martinsaposnic

Copy link
Copy Markdown
ContributorAuthor

this needs a rebase

done ✅

Comment threadlightning-liquidity/tests/lsps5_integration_tests.rs
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

from what I remember from our convo a few weeks ago, the cache is mainly there to handle "accidental" replays from the LSP, e.g. the connection drops and the LSP doesn’t get the ACK, so it retries even though the notification actually landed. but yeah, I agree we could just drop those extra lines and keep things simpler. @TheBlueMatt what are your thoughts?

Yea, this was my thinking. IMO this is gonna happen occasionally, and it might be nice to protect against. But at the same time maybe it doesn't matter - if its two servers talking to each other, re-transmitting a notification will happen occasionally, but it should be quick-ish and maybe we wake the phone twice in a minute but its fine? Its currently < 20 LoC, though, so it kinda seems worth keeping to me 🤷‍♂️

}
fn check_for_replay_attack(&self, signature: &str) -> Result<(), LSPS5ClientError> {
let mut signatures = self.recent_signatures.lock().unwrap();
if signatures.contains(&signature.to_string()) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if signatures.contains(&signature.to_string()){
if signatures.iter().any(|sig| &sig == &signature){

@tnulltnull 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.

Alright, I'm not convinced that we really need the signature store (esp. given that it's yet another thing that will need to be persisted), but apart from that this PR LGTM.

@tnull
tnull merged commit 00c4059 into lightningdevkit:mainJul 30, 2025
24 of 25 checks passed
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@martinsaposnic@ldk-reviews-bot@TheBlueMatt@tnull