Skip to content

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser - #3665

Merged
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit
Mar 17, 2025
Merged

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser#3665
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit

Conversation

@phlip9

Copy link
Copy Markdown
Contributor

The new bech32-v0.11.0 version (prev: v0.9.1) now enforces a max length of 1023 bytes. Before there was no max.

BOLT11 invoices can definitely exceed 1023 B with a long-ish description and 2 route hints, so this limit is likely too low.

Having a limit is probably a good idea. What do other projects choose? Here's a brief survey:

LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND 1: 7089 B
CLN 2: (no limit)
ACINQ 34: (no limit)

LND uses 7089 B, which was chosen to be "the max number of bytes that can fit in a QR code". LND's rationale is technically incorrect as QR codes actually have a max capacity of 7089 numeric characters and only support up to 4296 all-uppercase alphanumeric characters 5. However, ecosystem-wide consistency is probably more important.

A more conservative limit that would probably also suffice might be 2953 B. This would handle lowercase QR-encoded invoices while still giving us enough space for all "reasonable" invoices.

@ldk-reviews-bot

ldk-reviews-bot commented Mar 13, 2025

Copy link
Copy Markdown

I've assigned @valentinewallace 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.

@codecov

codecovBot commented Mar 13, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.56863% with 7 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (87c5cae) to head (3870823).
Report is 5 commits behind head on main.

Files with missing linesPatch %Lines
lightning-invoice/src/de.rs96.56%7 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3665 +/- ##
==========================================
- Coverage 89.23% 89.20% -0.04% 
==========================================
Files 155 155 Lines 119671 119874 +203 Branches 119671 119874 +203 ==========================================
+ Hits 106787 106930 +143 - Misses 10268 10320 +52 - Partials 2616 2624 +8 

☔ 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.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated

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

Looks good after feedback is addressed!

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

@phlip9

Copy link
Copy Markdown
ContributorAuthor

oh yeah here's some neat invoices I managed to generate:

The longest valid invoice with all known tags (4458 B):

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242jqrktctdhtu89wzzrmswsuxh8jzj3aawnufsujk9f8h0h97ass0pceawpc75jqyqyv0h0vs4x3kh5nvjuv808xp7nwx4znnu5ece9wspsgwv66

And the one generated in the test, at exactly 7089 B. It does need some non-standard tag fields to reach the limit though:

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242qllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqjqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppdjltalknlvrk3dtenzpzn2cwejxn4q0wacrmxhtye26pyvuexv4rrs3v9d3fvn3h67t9qhkmax54kzemsu3gnmv478ca7tdkhh6s5gqpfg3737

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

Just some formatting nits, otherwise LGTM.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
The new `bech32-v0.11.0` version (prev: `v0.9.1`) now enforces a max length of
1023 bytes. Before there was no max.
BOLT11 invoices can definitely exceed 1023 B with a long-ish description and
2 route hints, so this limit is likely too low.
Having a limit is probably a good idea. What do other projects choose? Here's
a brief survey:
LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND[1]: 7089 B
CLN[2]: (no limit)
ACINQ[3][4]: (no limit)
LND uses 7089 B, which was chosen to be "the max number of bytes that can fit
in a QR code". LND's rationale is technically incorrect as QR codes actually
have a max capacity of 7089 _numeric_ characters and only support up to 4296
all-uppercase alphanumeric characters. However, ecosystem-wide consistency
is more important.
A more conservative limit that would probably also suffice might be 2953 B,
the QR code length limit for a lowercase bech32-encoded invoice.
[1]: https://github.com/lightningnetwork/lnd/blob/6531d4505098eb14e6c24aedfd752fc15e85845d/zpay32/invoice.go#L87
[2]: https://github.com/ElementsProject/lightning/blob/0e7615b1b73eee161911763840d6260baf596755/common/bolt11.c#L683
[3]: https://github.com/ACINQ/lightning-kmp/blob/feda82c853660a792b911be518367a228ed6e0ee/modules/core/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt#L165
[4]: https://github.com/ACINQ/bitcoin-kmp/blob/master/src/commonMain/kotlin/fr/acinq/bitcoin/Bech32.kt#L122
@phlip9
phlip9force-pushed the phlip9/increase-invoice-length-limit branch from d8f2aa5 to 3870823CompareMarch 14, 2025 19:00
@phlip9

Copy link
Copy Markdown
ContributorAuthor

Squashed and rebased on main

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

LGTM

@phlip9

phlip9 commented Mar 17, 2025

Copy link
Copy Markdown
ContributorAuthor

I'm not exactly sure how to interpret the incremental-mutants CI failure, but it looks like the relative diff pulled in a bunch of unrelated changes in channelmanager.rs and found MISSING test coverage or something? Is there something I can do to fix this?

EDIT: The only mutation in lightning-invoice says it's "unviable" so I don't believe anything is wrong with this PR.

@valentinewallace
valentinewallace merged commit d671596 into lightningdevkit:mainMar 17, 2025
@valentinewallace

Copy link
Copy Markdown
Contributor

Thanks @phlip9! Sorry for the delay, it's helpful for me if you re-request a review :)

MaxFangX pushed a commit to lexe-app/lexe-public that referenced this pull request Mar 17, 2025
The long invoice tests work on LDK 0.0.125 but fail on LDK 0.1.0.
Awaiting PR: <lightningdevkit/rust-lightning#3665>
@phlip9
phlip9 deleted the phlip9/increase-invoice-length-limit branch March 18, 2025 02:38
@TheBlueMattTheBlueMatt mentioned this pull request Apr 1, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Backported in #3697

TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Apr 3, 2025
v0.1.2 - Apr 02, 2025 - "Foolishly Edgy Cases"
API Updates
===========
* `lightning-invoice` is now re-exported as `lightning::bolt11_invoice`
(lightningdevkit#3671).
Performance Improvements
========================
* `rapid-gossip-sync` graph parsing is substantially faster, resolving a
regression in 0.1 (lightningdevkit#3581).
* `NetworkGraph` loading is now substantially faster and does fewer
allocations, resulting in a 20% further improvement in `rapid-gossip-sync`
loading when initializing from scratch (lightningdevkit#3581).
* `ChannelMonitor`s for closed channels are no longer always re-persisted
immediately after startup, reducing on-startup I/O burden (lightningdevkit#3619).
Bug Fixes
=========
* BOLT 11 invoices longer than 1023 bytes long (and up to 7089 bytes) now
properly parse (lightningdevkit#3665).
* In some cases, when using synchronous persistence with higher latency than
the latency to communicate with peers, when receiving an MPP payment with
multiple parts received over the same channel, a channel could hang and not
make progress, eventually leading to a force-closure due to timed-out HTLCs.
This has now been fixed (lightningdevkit#3680).
* Some rare cases with multi-hop BOLT 11 route hints or multiple redundant
blinded paths could have led to the router creating invalid `Route`s were
fixed (lightningdevkit#3586).
* Corrected the decay logic in `ProbabilisticScorer`'s historical buckets
model. Note that by default historical buckets are only decayed if no new
datapoints have been added for a channel for two weeks (lightningdevkit#3562).
* `{Channel,Onion}MessageHandler::peer_disconnected` will now be called if a
different message handler refused connection by returning an `Err` from its
`peer_connected` method (lightningdevkit#3580).
* If the counterparty broadcasts a revoked state with pending HTLCs, those
will now be claimed with other outputs which we consider to not be
vulnerable to pinning attacks if they are not yet claimable by our
counterparty, potentially reducing our exposure to pinning attacks (lightningdevkit#3564).
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.

5 participants

@phlip9@ldk-reviews-bot@valentinewallace@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" + '
lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser by phlip9 · Pull Request #3665 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser - #3665

Merged
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit
Mar 17, 2025
Merged

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser#3665
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit

Conversation

@phlip9

Copy link
Copy Markdown
Contributor

The new bech32-v0.11.0 version (prev: v0.9.1) now enforces a max length of 1023 bytes. Before there was no max.

BOLT11 invoices can definitely exceed 1023 B with a long-ish description and 2 route hints, so this limit is likely too low.

Having a limit is probably a good idea. What do other projects choose? Here's a brief survey:

LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND 1: 7089 B
CLN 2: (no limit)
ACINQ 34: (no limit)

LND uses 7089 B, which was chosen to be "the max number of bytes that can fit in a QR code". LND's rationale is technically incorrect as QR codes actually have a max capacity of 7089 numeric characters and only support up to 4296 all-uppercase alphanumeric characters 5. However, ecosystem-wide consistency is probably more important.

A more conservative limit that would probably also suffice might be 2953 B. This would handle lowercase QR-encoded invoices while still giving us enough space for all "reasonable" invoices.

@ldk-reviews-bot

ldk-reviews-bot commented Mar 13, 2025

Copy link
Copy Markdown

I've assigned @valentinewallace 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.

@codecov

codecovBot commented Mar 13, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.56863% with 7 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (87c5cae) to head (3870823).
Report is 5 commits behind head on main.

Files with missing linesPatch %Lines
lightning-invoice/src/de.rs96.56%7 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3665 +/- ##
==========================================
- Coverage 89.23% 89.20% -0.04% 
==========================================
Files 155 155 Lines 119671 119874 +203 Branches 119671 119874 +203 ==========================================
+ Hits 106787 106930 +143 - Misses 10268 10320 +52 - Partials 2616 2624 +8 

☔ 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.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated

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

Looks good after feedback is addressed!

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

@phlip9

Copy link
Copy Markdown
ContributorAuthor

oh yeah here's some neat invoices I managed to generate:

The longest valid invoice with all known tags (4458 B):

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242jqrktctdhtu89wzzrmswsuxh8jzj3aawnufsujk9f8h0h97ass0pceawpc75jqyqyv0h0vs4x3kh5nvjuv808xp7nwx4znnu5ece9wspsgwv66

And the one generated in the test, at exactly 7089 B. It does need some non-standard tag fields to reach the limit though:

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242qllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqjqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppdjltalknlvrk3dtenzpzn2cwejxn4q0wacrmxhtye26pyvuexv4rrs3v9d3fvn3h67t9qhkmax54kzemsu3gnmv478ca7tdkhh6s5gqpfg3737

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

Just some formatting nits, otherwise LGTM.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
The new `bech32-v0.11.0` version (prev: `v0.9.1`) now enforces a max length of
1023 bytes. Before there was no max.
BOLT11 invoices can definitely exceed 1023 B with a long-ish description and
2 route hints, so this limit is likely too low.
Having a limit is probably a good idea. What do other projects choose? Here's
a brief survey:
LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND[1]: 7089 B
CLN[2]: (no limit)
ACINQ[3][4]: (no limit)
LND uses 7089 B, which was chosen to be "the max number of bytes that can fit
in a QR code". LND's rationale is technically incorrect as QR codes actually
have a max capacity of 7089 _numeric_ characters and only support up to 4296
all-uppercase alphanumeric characters. However, ecosystem-wide consistency
is more important.
A more conservative limit that would probably also suffice might be 2953 B,
the QR code length limit for a lowercase bech32-encoded invoice.
[1]: https://github.com/lightningnetwork/lnd/blob/6531d4505098eb14e6c24aedfd752fc15e85845d/zpay32/invoice.go#L87
[2]: https://github.com/ElementsProject/lightning/blob/0e7615b1b73eee161911763840d6260baf596755/common/bolt11.c#L683
[3]: https://github.com/ACINQ/lightning-kmp/blob/feda82c853660a792b911be518367a228ed6e0ee/modules/core/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt#L165
[4]: https://github.com/ACINQ/bitcoin-kmp/blob/master/src/commonMain/kotlin/fr/acinq/bitcoin/Bech32.kt#L122
@phlip9
phlip9force-pushed the phlip9/increase-invoice-length-limit branch from d8f2aa5 to 3870823CompareMarch 14, 2025 19:00
@phlip9

Copy link
Copy Markdown
ContributorAuthor

Squashed and rebased on main

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

LGTM

@phlip9

phlip9 commented Mar 17, 2025

Copy link
Copy Markdown
ContributorAuthor

I'm not exactly sure how to interpret the incremental-mutants CI failure, but it looks like the relative diff pulled in a bunch of unrelated changes in channelmanager.rs and found MISSING test coverage or something? Is there something I can do to fix this?

EDIT: The only mutation in lightning-invoice says it's "unviable" so I don't believe anything is wrong with this PR.

@valentinewallace
valentinewallace merged commit d671596 into lightningdevkit:mainMar 17, 2025
@valentinewallace

Copy link
Copy Markdown
Contributor

Thanks @phlip9! Sorry for the delay, it's helpful for me if you re-request a review :)

MaxFangX pushed a commit to lexe-app/lexe-public that referenced this pull request Mar 17, 2025
The long invoice tests work on LDK 0.0.125 but fail on LDK 0.1.0.
Awaiting PR: <lightningdevkit/rust-lightning#3665>
@phlip9
phlip9 deleted the phlip9/increase-invoice-length-limit branch March 18, 2025 02:38
@TheBlueMattTheBlueMatt mentioned this pull request Apr 1, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Backported in #3697

TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Apr 3, 2025
v0.1.2 - Apr 02, 2025 - "Foolishly Edgy Cases"
API Updates
===========
* `lightning-invoice` is now re-exported as `lightning::bolt11_invoice`
(lightningdevkit#3671).
Performance Improvements
========================
* `rapid-gossip-sync` graph parsing is substantially faster, resolving a
regression in 0.1 (lightningdevkit#3581).
* `NetworkGraph` loading is now substantially faster and does fewer
allocations, resulting in a 20% further improvement in `rapid-gossip-sync`
loading when initializing from scratch (lightningdevkit#3581).
* `ChannelMonitor`s for closed channels are no longer always re-persisted
immediately after startup, reducing on-startup I/O burden (lightningdevkit#3619).
Bug Fixes
=========
* BOLT 11 invoices longer than 1023 bytes long (and up to 7089 bytes) now
properly parse (lightningdevkit#3665).
* In some cases, when using synchronous persistence with higher latency than
the latency to communicate with peers, when receiving an MPP payment with
multiple parts received over the same channel, a channel could hang and not
make progress, eventually leading to a force-closure due to timed-out HTLCs.
This has now been fixed (lightningdevkit#3680).
* Some rare cases with multi-hop BOLT 11 route hints or multiple redundant
blinded paths could have led to the router creating invalid `Route`s were
fixed (lightningdevkit#3586).
* Corrected the decay logic in `ProbabilisticScorer`'s historical buckets
model. Note that by default historical buckets are only decayed if no new
datapoints have been added for a channel for two weeks (lightningdevkit#3562).
* `{Channel,Onion}MessageHandler::peer_disconnected` will now be called if a
different message handler refused connection by returning an `Err` from its
`peer_connected` method (lightningdevkit#3580).
* If the counterparty broadcasts a revoked state with pending HTLCs, those
will now be claimed with other outputs which we consider to not be
vulnerable to pinning attacks if they are not yet claimable by our
counterparty, potentially reducing our exposure to pinning attacks (lightningdevkit#3564).
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.

5 participants

@phlip9@ldk-reviews-bot@valentinewallace@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('^' + ".*" + ' lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser by phlip9 · Pull Request #3665 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser - #3665

Merged
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit
Mar 17, 2025
Merged

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser#3665
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit

Conversation

@phlip9

Copy link
Copy Markdown
Contributor

The new bech32-v0.11.0 version (prev: v0.9.1) now enforces a max length of 1023 bytes. Before there was no max.

BOLT11 invoices can definitely exceed 1023 B with a long-ish description and 2 route hints, so this limit is likely too low.

Having a limit is probably a good idea. What do other projects choose? Here's a brief survey:

LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND 1: 7089 B
CLN 2: (no limit)
ACINQ 34: (no limit)

LND uses 7089 B, which was chosen to be "the max number of bytes that can fit in a QR code". LND's rationale is technically incorrect as QR codes actually have a max capacity of 7089 numeric characters and only support up to 4296 all-uppercase alphanumeric characters 5. However, ecosystem-wide consistency is probably more important.

A more conservative limit that would probably also suffice might be 2953 B. This would handle lowercase QR-encoded invoices while still giving us enough space for all "reasonable" invoices.

@ldk-reviews-bot

ldk-reviews-bot commented Mar 13, 2025

Copy link
Copy Markdown

I've assigned @valentinewallace 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.

@codecov

codecovBot commented Mar 13, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.56863% with 7 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (87c5cae) to head (3870823).
Report is 5 commits behind head on main.

Files with missing linesPatch %Lines
lightning-invoice/src/de.rs96.56%7 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3665 +/- ##
==========================================
- Coverage 89.23% 89.20% -0.04% 
==========================================
Files 155 155 Lines 119671 119874 +203 Branches 119671 119874 +203 ==========================================
+ Hits 106787 106930 +143 - Misses 10268 10320 +52 - Partials 2616 2624 +8 

☔ 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.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated

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

Looks good after feedback is addressed!

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

@phlip9

Copy link
Copy Markdown
ContributorAuthor

oh yeah here's some neat invoices I managed to generate:

The longest valid invoice with all known tags (4458 B):

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242jqrktctdhtu89wzzrmswsuxh8jzj3aawnufsujk9f8h0h97ass0pceawpc75jqyqyv0h0vs4x3kh5nvjuv808xp7nwx4znnu5ece9wspsgwv66

And the one generated in the test, at exactly 7089 B. It does need some non-standard tag fields to reach the limit though:

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242qllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqjqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppdjltalknlvrk3dtenzpzn2cwejxn4q0wacrmxhtye26pyvuexv4rrs3v9d3fvn3h67t9qhkmax54kzemsu3gnmv478ca7tdkhh6s5gqpfg3737

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

Just some formatting nits, otherwise LGTM.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
The new `bech32-v0.11.0` version (prev: `v0.9.1`) now enforces a max length of
1023 bytes. Before there was no max.
BOLT11 invoices can definitely exceed 1023 B with a long-ish description and
2 route hints, so this limit is likely too low.
Having a limit is probably a good idea. What do other projects choose? Here's
a brief survey:
LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND[1]: 7089 B
CLN[2]: (no limit)
ACINQ[3][4]: (no limit)
LND uses 7089 B, which was chosen to be "the max number of bytes that can fit
in a QR code". LND's rationale is technically incorrect as QR codes actually
have a max capacity of 7089 _numeric_ characters and only support up to 4296
all-uppercase alphanumeric characters. However, ecosystem-wide consistency
is more important.
A more conservative limit that would probably also suffice might be 2953 B,
the QR code length limit for a lowercase bech32-encoded invoice.
[1]: https://github.com/lightningnetwork/lnd/blob/6531d4505098eb14e6c24aedfd752fc15e85845d/zpay32/invoice.go#L87
[2]: https://github.com/ElementsProject/lightning/blob/0e7615b1b73eee161911763840d6260baf596755/common/bolt11.c#L683
[3]: https://github.com/ACINQ/lightning-kmp/blob/feda82c853660a792b911be518367a228ed6e0ee/modules/core/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt#L165
[4]: https://github.com/ACINQ/bitcoin-kmp/blob/master/src/commonMain/kotlin/fr/acinq/bitcoin/Bech32.kt#L122
@phlip9
phlip9force-pushed the phlip9/increase-invoice-length-limit branch from d8f2aa5 to 3870823CompareMarch 14, 2025 19:00
@phlip9

Copy link
Copy Markdown
ContributorAuthor

Squashed and rebased on main

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

LGTM

@phlip9

phlip9 commented Mar 17, 2025

Copy link
Copy Markdown
ContributorAuthor

I'm not exactly sure how to interpret the incremental-mutants CI failure, but it looks like the relative diff pulled in a bunch of unrelated changes in channelmanager.rs and found MISSING test coverage or something? Is there something I can do to fix this?

EDIT: The only mutation in lightning-invoice says it's "unviable" so I don't believe anything is wrong with this PR.

@valentinewallace
valentinewallace merged commit d671596 into lightningdevkit:mainMar 17, 2025
@valentinewallace

Copy link
Copy Markdown
Contributor

Thanks @phlip9! Sorry for the delay, it's helpful for me if you re-request a review :)

MaxFangX pushed a commit to lexe-app/lexe-public that referenced this pull request Mar 17, 2025
The long invoice tests work on LDK 0.0.125 but fail on LDK 0.1.0.
Awaiting PR: <lightningdevkit/rust-lightning#3665>
@phlip9
phlip9 deleted the phlip9/increase-invoice-length-limit branch March 18, 2025 02:38
@TheBlueMattTheBlueMatt mentioned this pull request Apr 1, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Backported in #3697

TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Apr 3, 2025
v0.1.2 - Apr 02, 2025 - "Foolishly Edgy Cases"
API Updates
===========
* `lightning-invoice` is now re-exported as `lightning::bolt11_invoice`
(lightningdevkit#3671).
Performance Improvements
========================
* `rapid-gossip-sync` graph parsing is substantially faster, resolving a
regression in 0.1 (lightningdevkit#3581).
* `NetworkGraph` loading is now substantially faster and does fewer
allocations, resulting in a 20% further improvement in `rapid-gossip-sync`
loading when initializing from scratch (lightningdevkit#3581).
* `ChannelMonitor`s for closed channels are no longer always re-persisted
immediately after startup, reducing on-startup I/O burden (lightningdevkit#3619).
Bug Fixes
=========
* BOLT 11 invoices longer than 1023 bytes long (and up to 7089 bytes) now
properly parse (lightningdevkit#3665).
* In some cases, when using synchronous persistence with higher latency than
the latency to communicate with peers, when receiving an MPP payment with
multiple parts received over the same channel, a channel could hang and not
make progress, eventually leading to a force-closure due to timed-out HTLCs.
This has now been fixed (lightningdevkit#3680).
* Some rare cases with multi-hop BOLT 11 route hints or multiple redundant
blinded paths could have led to the router creating invalid `Route`s were
fixed (lightningdevkit#3586).
* Corrected the decay logic in `ProbabilisticScorer`'s historical buckets
model. Note that by default historical buckets are only decayed if no new
datapoints have been added for a channel for two weeks (lightningdevkit#3562).
* `{Channel,Onion}MessageHandler::peer_disconnected` will now be called if a
different message handler refused connection by returning an `Err` from its
`peer_connected` method (lightningdevkit#3580).
* If the counterparty broadcasts a revoked state with pending HTLCs, those
will now be claimed with other outputs which we consider to not be
vulnerable to pinning attacks if they are not yet claimable by our
counterparty, potentially reducing our exposure to pinning attacks (lightningdevkit#3564).
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.

5 participants

@phlip9@ldk-reviews-bot@valentinewallace@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('^' + ".*" + ' lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser by phlip9 · Pull Request #3665 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser - #3665

Merged
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit
Mar 17, 2025
Merged

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser#3665
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit

Conversation

@phlip9

Copy link
Copy Markdown
Contributor

The new bech32-v0.11.0 version (prev: v0.9.1) now enforces a max length of 1023 bytes. Before there was no max.

BOLT11 invoices can definitely exceed 1023 B with a long-ish description and 2 route hints, so this limit is likely too low.

Having a limit is probably a good idea. What do other projects choose? Here's a brief survey:

LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND 1: 7089 B
CLN 2: (no limit)
ACINQ 34: (no limit)

LND uses 7089 B, which was chosen to be "the max number of bytes that can fit in a QR code". LND's rationale is technically incorrect as QR codes actually have a max capacity of 7089 numeric characters and only support up to 4296 all-uppercase alphanumeric characters 5. However, ecosystem-wide consistency is probably more important.

A more conservative limit that would probably also suffice might be 2953 B. This would handle lowercase QR-encoded invoices while still giving us enough space for all "reasonable" invoices.

@ldk-reviews-bot

ldk-reviews-bot commented Mar 13, 2025

Copy link
Copy Markdown

I've assigned @valentinewallace 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.

@codecov

codecovBot commented Mar 13, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.56863% with 7 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (87c5cae) to head (3870823).
Report is 5 commits behind head on main.

Files with missing linesPatch %Lines
lightning-invoice/src/de.rs96.56%7 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3665 +/- ##
==========================================
- Coverage 89.23% 89.20% -0.04% 
==========================================
Files 155 155 Lines 119671 119874 +203 Branches 119671 119874 +203 ==========================================
+ Hits 106787 106930 +143 - Misses 10268 10320 +52 - Partials 2616 2624 +8 

☔ 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.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated

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

Looks good after feedback is addressed!

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

@phlip9

Copy link
Copy Markdown
ContributorAuthor

oh yeah here's some neat invoices I managed to generate:

The longest valid invoice with all known tags (4458 B):

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242jqrktctdhtu89wzzrmswsuxh8jzj3aawnufsujk9f8h0h97ass0pceawpc75jqyqyv0h0vs4x3kh5nvjuv808xp7nwx4znnu5ece9wspsgwv66

And the one generated in the test, at exactly 7089 B. It does need some non-standard tag fields to reach the limit though:

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242qllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqjqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppdjltalknlvrk3dtenzpzn2cwejxn4q0wacrmxhtye26pyvuexv4rrs3v9d3fvn3h67t9qhkmax54kzemsu3gnmv478ca7tdkhh6s5gqpfg3737

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

Just some formatting nits, otherwise LGTM.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
The new `bech32-v0.11.0` version (prev: `v0.9.1`) now enforces a max length of
1023 bytes. Before there was no max.
BOLT11 invoices can definitely exceed 1023 B with a long-ish description and
2 route hints, so this limit is likely too low.
Having a limit is probably a good idea. What do other projects choose? Here's
a brief survey:
LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND[1]: 7089 B
CLN[2]: (no limit)
ACINQ[3][4]: (no limit)
LND uses 7089 B, which was chosen to be "the max number of bytes that can fit
in a QR code". LND's rationale is technically incorrect as QR codes actually
have a max capacity of 7089 _numeric_ characters and only support up to 4296
all-uppercase alphanumeric characters. However, ecosystem-wide consistency
is more important.
A more conservative limit that would probably also suffice might be 2953 B,
the QR code length limit for a lowercase bech32-encoded invoice.
[1]: https://github.com/lightningnetwork/lnd/blob/6531d4505098eb14e6c24aedfd752fc15e85845d/zpay32/invoice.go#L87
[2]: https://github.com/ElementsProject/lightning/blob/0e7615b1b73eee161911763840d6260baf596755/common/bolt11.c#L683
[3]: https://github.com/ACINQ/lightning-kmp/blob/feda82c853660a792b911be518367a228ed6e0ee/modules/core/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt#L165
[4]: https://github.com/ACINQ/bitcoin-kmp/blob/master/src/commonMain/kotlin/fr/acinq/bitcoin/Bech32.kt#L122
@phlip9
phlip9force-pushed the phlip9/increase-invoice-length-limit branch from d8f2aa5 to 3870823CompareMarch 14, 2025 19:00
@phlip9

Copy link
Copy Markdown
ContributorAuthor

Squashed and rebased on main

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

LGTM

@phlip9

phlip9 commented Mar 17, 2025

Copy link
Copy Markdown
ContributorAuthor

I'm not exactly sure how to interpret the incremental-mutants CI failure, but it looks like the relative diff pulled in a bunch of unrelated changes in channelmanager.rs and found MISSING test coverage or something? Is there something I can do to fix this?

EDIT: The only mutation in lightning-invoice says it's "unviable" so I don't believe anything is wrong with this PR.

@valentinewallace
valentinewallace merged commit d671596 into lightningdevkit:mainMar 17, 2025
@valentinewallace

Copy link
Copy Markdown
Contributor

Thanks @phlip9! Sorry for the delay, it's helpful for me if you re-request a review :)

MaxFangX pushed a commit to lexe-app/lexe-public that referenced this pull request Mar 17, 2025
The long invoice tests work on LDK 0.0.125 but fail on LDK 0.1.0.
Awaiting PR: <lightningdevkit/rust-lightning#3665>
@phlip9
phlip9 deleted the phlip9/increase-invoice-length-limit branch March 18, 2025 02:38
@TheBlueMattTheBlueMatt mentioned this pull request Apr 1, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Backported in #3697

TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Apr 3, 2025
v0.1.2 - Apr 02, 2025 - "Foolishly Edgy Cases"
API Updates
===========
* `lightning-invoice` is now re-exported as `lightning::bolt11_invoice`
(lightningdevkit#3671).
Performance Improvements
========================
* `rapid-gossip-sync` graph parsing is substantially faster, resolving a
regression in 0.1 (lightningdevkit#3581).
* `NetworkGraph` loading is now substantially faster and does fewer
allocations, resulting in a 20% further improvement in `rapid-gossip-sync`
loading when initializing from scratch (lightningdevkit#3581).
* `ChannelMonitor`s for closed channels are no longer always re-persisted
immediately after startup, reducing on-startup I/O burden (lightningdevkit#3619).
Bug Fixes
=========
* BOLT 11 invoices longer than 1023 bytes long (and up to 7089 bytes) now
properly parse (lightningdevkit#3665).
* In some cases, when using synchronous persistence with higher latency than
the latency to communicate with peers, when receiving an MPP payment with
multiple parts received over the same channel, a channel could hang and not
make progress, eventually leading to a force-closure due to timed-out HTLCs.
This has now been fixed (lightningdevkit#3680).
* Some rare cases with multi-hop BOLT 11 route hints or multiple redundant
blinded paths could have led to the router creating invalid `Route`s were
fixed (lightningdevkit#3586).
* Corrected the decay logic in `ProbabilisticScorer`'s historical buckets
model. Note that by default historical buckets are only decayed if no new
datapoints have been added for a channel for two weeks (lightningdevkit#3562).
* `{Channel,Onion}MessageHandler::peer_disconnected` will now be called if a
different message handler refused connection by returning an `Err` from its
`peer_connected` method (lightningdevkit#3580).
* If the counterparty broadcasts a revoked state with pending HTLCs, those
will now be claimed with other outputs which we consider to not be
vulnerable to pinning attacks if they are not yet claimable by our
counterparty, potentially reducing our exposure to pinning attacks (lightningdevkit#3564).
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.

5 participants

@phlip9@ldk-reviews-bot@valentinewallace@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" + ' lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser by phlip9 · Pull Request #3665 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser - #3665

Merged
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit
Mar 17, 2025
Merged

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser#3665
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit

Conversation

@phlip9

Copy link
Copy Markdown
Contributor

The new bech32-v0.11.0 version (prev: v0.9.1) now enforces a max length of 1023 bytes. Before there was no max.

BOLT11 invoices can definitely exceed 1023 B with a long-ish description and 2 route hints, so this limit is likely too low.

Having a limit is probably a good idea. What do other projects choose? Here's a brief survey:

LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND 1: 7089 B
CLN 2: (no limit)
ACINQ 34: (no limit)

LND uses 7089 B, which was chosen to be "the max number of bytes that can fit in a QR code". LND's rationale is technically incorrect as QR codes actually have a max capacity of 7089 numeric characters and only support up to 4296 all-uppercase alphanumeric characters 5. However, ecosystem-wide consistency is probably more important.

A more conservative limit that would probably also suffice might be 2953 B. This would handle lowercase QR-encoded invoices while still giving us enough space for all "reasonable" invoices.

@ldk-reviews-bot

ldk-reviews-bot commented Mar 13, 2025

Copy link
Copy Markdown

I've assigned @valentinewallace 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.

@codecov

codecovBot commented Mar 13, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.56863% with 7 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (87c5cae) to head (3870823).
Report is 5 commits behind head on main.

Files with missing linesPatch %Lines
lightning-invoice/src/de.rs96.56%7 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3665 +/- ##
==========================================
- Coverage 89.23% 89.20% -0.04% 
==========================================
Files 155 155 Lines 119671 119874 +203 Branches 119671 119874 +203 ==========================================
+ Hits 106787 106930 +143 - Misses 10268 10320 +52 - Partials 2616 2624 +8 

☔ 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.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated

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

Looks good after feedback is addressed!

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

@phlip9

Copy link
Copy Markdown
ContributorAuthor

oh yeah here's some neat invoices I managed to generate:

The longest valid invoice with all known tags (4458 B):

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242jqrktctdhtu89wzzrmswsuxh8jzj3aawnufsujk9f8h0h97ass0pceawpc75jqyqyv0h0vs4x3kh5nvjuv808xp7nwx4znnu5ece9wspsgwv66

And the one generated in the test, at exactly 7089 B. It does need some non-standard tag fields to reach the limit though:

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242qllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqjqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppdjltalknlvrk3dtenzpzn2cwejxn4q0wacrmxhtye26pyvuexv4rrs3v9d3fvn3h67t9qhkmax54kzemsu3gnmv478ca7tdkhh6s5gqpfg3737

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

Just some formatting nits, otherwise LGTM.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
The new `bech32-v0.11.0` version (prev: `v0.9.1`) now enforces a max length of
1023 bytes. Before there was no max.
BOLT11 invoices can definitely exceed 1023 B with a long-ish description and
2 route hints, so this limit is likely too low.
Having a limit is probably a good idea. What do other projects choose? Here's
a brief survey:
LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND[1]: 7089 B
CLN[2]: (no limit)
ACINQ[3][4]: (no limit)
LND uses 7089 B, which was chosen to be "the max number of bytes that can fit
in a QR code". LND's rationale is technically incorrect as QR codes actually
have a max capacity of 7089 _numeric_ characters and only support up to 4296
all-uppercase alphanumeric characters. However, ecosystem-wide consistency
is more important.
A more conservative limit that would probably also suffice might be 2953 B,
the QR code length limit for a lowercase bech32-encoded invoice.
[1]: https://github.com/lightningnetwork/lnd/blob/6531d4505098eb14e6c24aedfd752fc15e85845d/zpay32/invoice.go#L87
[2]: https://github.com/ElementsProject/lightning/blob/0e7615b1b73eee161911763840d6260baf596755/common/bolt11.c#L683
[3]: https://github.com/ACINQ/lightning-kmp/blob/feda82c853660a792b911be518367a228ed6e0ee/modules/core/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt#L165
[4]: https://github.com/ACINQ/bitcoin-kmp/blob/master/src/commonMain/kotlin/fr/acinq/bitcoin/Bech32.kt#L122
@phlip9
phlip9force-pushed the phlip9/increase-invoice-length-limit branch from d8f2aa5 to 3870823CompareMarch 14, 2025 19:00
@phlip9

Copy link
Copy Markdown
ContributorAuthor

Squashed and rebased on main

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

LGTM

@phlip9

phlip9 commented Mar 17, 2025

Copy link
Copy Markdown
ContributorAuthor

I'm not exactly sure how to interpret the incremental-mutants CI failure, but it looks like the relative diff pulled in a bunch of unrelated changes in channelmanager.rs and found MISSING test coverage or something? Is there something I can do to fix this?

EDIT: The only mutation in lightning-invoice says it's "unviable" so I don't believe anything is wrong with this PR.

@valentinewallace
valentinewallace merged commit d671596 into lightningdevkit:mainMar 17, 2025
@valentinewallace

Copy link
Copy Markdown
Contributor

Thanks @phlip9! Sorry for the delay, it's helpful for me if you re-request a review :)

MaxFangX pushed a commit to lexe-app/lexe-public that referenced this pull request Mar 17, 2025
The long invoice tests work on LDK 0.0.125 but fail on LDK 0.1.0.
Awaiting PR: <lightningdevkit/rust-lightning#3665>
@phlip9
phlip9 deleted the phlip9/increase-invoice-length-limit branch March 18, 2025 02:38
@TheBlueMattTheBlueMatt mentioned this pull request Apr 1, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Backported in #3697

TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Apr 3, 2025
v0.1.2 - Apr 02, 2025 - "Foolishly Edgy Cases"
API Updates
===========
* `lightning-invoice` is now re-exported as `lightning::bolt11_invoice`
(lightningdevkit#3671).
Performance Improvements
========================
* `rapid-gossip-sync` graph parsing is substantially faster, resolving a
regression in 0.1 (lightningdevkit#3581).
* `NetworkGraph` loading is now substantially faster and does fewer
allocations, resulting in a 20% further improvement in `rapid-gossip-sync`
loading when initializing from scratch (lightningdevkit#3581).
* `ChannelMonitor`s for closed channels are no longer always re-persisted
immediately after startup, reducing on-startup I/O burden (lightningdevkit#3619).
Bug Fixes
=========
* BOLT 11 invoices longer than 1023 bytes long (and up to 7089 bytes) now
properly parse (lightningdevkit#3665).
* In some cases, when using synchronous persistence with higher latency than
the latency to communicate with peers, when receiving an MPP payment with
multiple parts received over the same channel, a channel could hang and not
make progress, eventually leading to a force-closure due to timed-out HTLCs.
This has now been fixed (lightningdevkit#3680).
* Some rare cases with multi-hop BOLT 11 route hints or multiple redundant
blinded paths could have led to the router creating invalid `Route`s were
fixed (lightningdevkit#3586).
* Corrected the decay logic in `ProbabilisticScorer`'s historical buckets
model. Note that by default historical buckets are only decayed if no new
datapoints have been added for a channel for two weeks (lightningdevkit#3562).
* `{Channel,Onion}MessageHandler::peer_disconnected` will now be called if a
different message handler refused connection by returning an `Err` from its
`peer_connected` method (lightningdevkit#3580).
* If the counterparty broadcasts a revoked state with pending HTLCs, those
will now be claimed with other outputs which we consider to not be
vulnerable to pinning attacks if they are not yet claimable by our
counterparty, potentially reducing our exposure to pinning attacks (lightningdevkit#3564).
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.

5 participants

@phlip9@ldk-reviews-bot@valentinewallace@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('^' + ".*" + ' lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser by phlip9 · Pull Request #3665 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser - #3665

Merged
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit
Mar 17, 2025
Merged

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser#3665
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit

Conversation

@phlip9

Copy link
Copy Markdown
Contributor

The new bech32-v0.11.0 version (prev: v0.9.1) now enforces a max length of 1023 bytes. Before there was no max.

BOLT11 invoices can definitely exceed 1023 B with a long-ish description and 2 route hints, so this limit is likely too low.

Having a limit is probably a good idea. What do other projects choose? Here's a brief survey:

LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND 1: 7089 B
CLN 2: (no limit)
ACINQ 34: (no limit)

LND uses 7089 B, which was chosen to be "the max number of bytes that can fit in a QR code". LND's rationale is technically incorrect as QR codes actually have a max capacity of 7089 numeric characters and only support up to 4296 all-uppercase alphanumeric characters 5. However, ecosystem-wide consistency is probably more important.

A more conservative limit that would probably also suffice might be 2953 B. This would handle lowercase QR-encoded invoices while still giving us enough space for all "reasonable" invoices.

@ldk-reviews-bot

ldk-reviews-bot commented Mar 13, 2025

Copy link
Copy Markdown

I've assigned @valentinewallace 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.

@codecov

codecovBot commented Mar 13, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.56863% with 7 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (87c5cae) to head (3870823).
Report is 5 commits behind head on main.

Files with missing linesPatch %Lines
lightning-invoice/src/de.rs96.56%7 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3665 +/- ##
==========================================
- Coverage 89.23% 89.20% -0.04% 
==========================================
Files 155 155 Lines 119671 119874 +203 Branches 119671 119874 +203 ==========================================
+ Hits 106787 106930 +143 - Misses 10268 10320 +52 - Partials 2616 2624 +8 

☔ 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.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated

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

Looks good after feedback is addressed!

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

@phlip9

Copy link
Copy Markdown
ContributorAuthor

oh yeah here's some neat invoices I managed to generate:

The longest valid invoice with all known tags (4458 B):

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242jqrktctdhtu89wzzrmswsuxh8jzj3aawnufsujk9f8h0h97ass0pceawpc75jqyqyv0h0vs4x3kh5nvjuv808xp7nwx4znnu5ece9wspsgwv66

And the one generated in the test, at exactly 7089 B. It does need some non-standard tag fields to reach the limit though:

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242qllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqjqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppdjltalknlvrk3dtenzpzn2cwejxn4q0wacrmxhtye26pyvuexv4rrs3v9d3fvn3h67t9qhkmax54kzemsu3gnmv478ca7tdkhh6s5gqpfg3737

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

Just some formatting nits, otherwise LGTM.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
The new `bech32-v0.11.0` version (prev: `v0.9.1`) now enforces a max length of
1023 bytes. Before there was no max.
BOLT11 invoices can definitely exceed 1023 B with a long-ish description and
2 route hints, so this limit is likely too low.
Having a limit is probably a good idea. What do other projects choose? Here's
a brief survey:
LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND[1]: 7089 B
CLN[2]: (no limit)
ACINQ[3][4]: (no limit)
LND uses 7089 B, which was chosen to be "the max number of bytes that can fit
in a QR code". LND's rationale is technically incorrect as QR codes actually
have a max capacity of 7089 _numeric_ characters and only support up to 4296
all-uppercase alphanumeric characters. However, ecosystem-wide consistency
is more important.
A more conservative limit that would probably also suffice might be 2953 B,
the QR code length limit for a lowercase bech32-encoded invoice.
[1]: https://github.com/lightningnetwork/lnd/blob/6531d4505098eb14e6c24aedfd752fc15e85845d/zpay32/invoice.go#L87
[2]: https://github.com/ElementsProject/lightning/blob/0e7615b1b73eee161911763840d6260baf596755/common/bolt11.c#L683
[3]: https://github.com/ACINQ/lightning-kmp/blob/feda82c853660a792b911be518367a228ed6e0ee/modules/core/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt#L165
[4]: https://github.com/ACINQ/bitcoin-kmp/blob/master/src/commonMain/kotlin/fr/acinq/bitcoin/Bech32.kt#L122
@phlip9
phlip9force-pushed the phlip9/increase-invoice-length-limit branch from d8f2aa5 to 3870823CompareMarch 14, 2025 19:00
@phlip9

Copy link
Copy Markdown
ContributorAuthor

Squashed and rebased on main

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

LGTM

@phlip9

phlip9 commented Mar 17, 2025

Copy link
Copy Markdown
ContributorAuthor

I'm not exactly sure how to interpret the incremental-mutants CI failure, but it looks like the relative diff pulled in a bunch of unrelated changes in channelmanager.rs and found MISSING test coverage or something? Is there something I can do to fix this?

EDIT: The only mutation in lightning-invoice says it's "unviable" so I don't believe anything is wrong with this PR.

@valentinewallace
valentinewallace merged commit d671596 into lightningdevkit:mainMar 17, 2025
@valentinewallace

Copy link
Copy Markdown
Contributor

Thanks @phlip9! Sorry for the delay, it's helpful for me if you re-request a review :)

MaxFangX pushed a commit to lexe-app/lexe-public that referenced this pull request Mar 17, 2025
The long invoice tests work on LDK 0.0.125 but fail on LDK 0.1.0.
Awaiting PR: <lightningdevkit/rust-lightning#3665>
@phlip9
phlip9 deleted the phlip9/increase-invoice-length-limit branch March 18, 2025 02:38
@TheBlueMattTheBlueMatt mentioned this pull request Apr 1, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Backported in #3697

TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Apr 3, 2025
v0.1.2 - Apr 02, 2025 - "Foolishly Edgy Cases"
API Updates
===========
* `lightning-invoice` is now re-exported as `lightning::bolt11_invoice`
(lightningdevkit#3671).
Performance Improvements
========================
* `rapid-gossip-sync` graph parsing is substantially faster, resolving a
regression in 0.1 (lightningdevkit#3581).
* `NetworkGraph` loading is now substantially faster and does fewer
allocations, resulting in a 20% further improvement in `rapid-gossip-sync`
loading when initializing from scratch (lightningdevkit#3581).
* `ChannelMonitor`s for closed channels are no longer always re-persisted
immediately after startup, reducing on-startup I/O burden (lightningdevkit#3619).
Bug Fixes
=========
* BOLT 11 invoices longer than 1023 bytes long (and up to 7089 bytes) now
properly parse (lightningdevkit#3665).
* In some cases, when using synchronous persistence with higher latency than
the latency to communicate with peers, when receiving an MPP payment with
multiple parts received over the same channel, a channel could hang and not
make progress, eventually leading to a force-closure due to timed-out HTLCs.
This has now been fixed (lightningdevkit#3680).
* Some rare cases with multi-hop BOLT 11 route hints or multiple redundant
blinded paths could have led to the router creating invalid `Route`s were
fixed (lightningdevkit#3586).
* Corrected the decay logic in `ProbabilisticScorer`'s historical buckets
model. Note that by default historical buckets are only decayed if no new
datapoints have been added for a channel for two weeks (lightningdevkit#3562).
* `{Channel,Onion}MessageHandler::peer_disconnected` will now be called if a
different message handler refused connection by returning an `Err` from its
`peer_connected` method (lightningdevkit#3580).
* If the counterparty broadcasts a revoked state with pending HTLCs, those
will now be claimed with other outputs which we consider to not be
vulnerable to pinning attacks if they are not yet claimable by our
counterparty, potentially reducing our exposure to pinning attacks (lightningdevkit#3564).
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.

5 participants

@phlip9@ldk-reviews-bot@valentinewallace@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); } })(); })(); lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser by phlip9 · Pull Request #3665 · lightningdevkit/rust-lightning · GitHub
Skip to content

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser - #3665

Merged
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit
Mar 17, 2025
Merged

lightning-invoice: explicitly enforce a 7089 B max length on BOLT11 invoice deser#3665
valentinewallace merged 1 commit into
lightningdevkit:mainfrom
lexe-app:phlip9/increase-invoice-length-limit

Conversation

@phlip9

Copy link
Copy Markdown
Contributor

The new bech32-v0.11.0 version (prev: v0.9.1) now enforces a max length of 1023 bytes. Before there was no max.

BOLT11 invoices can definitely exceed 1023 B with a long-ish description and 2 route hints, so this limit is likely too low.

Having a limit is probably a good idea. What do other projects choose? Here's a brief survey:

LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND 1: 7089 B
CLN 2: (no limit)
ACINQ 34: (no limit)

LND uses 7089 B, which was chosen to be "the max number of bytes that can fit in a QR code". LND's rationale is technically incorrect as QR codes actually have a max capacity of 7089 numeric characters and only support up to 4296 all-uppercase alphanumeric characters 5. However, ecosystem-wide consistency is probably more important.

A more conservative limit that would probably also suffice might be 2953 B. This would handle lowercase QR-encoded invoices while still giving us enough space for all "reasonable" invoices.

@ldk-reviews-bot

ldk-reviews-bot commented Mar 13, 2025

Copy link
Copy Markdown

I've assigned @valentinewallace 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.

@codecov

codecovBot commented Mar 13, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.56863% with 7 lines in your changes missing coverage. Please review.

Project coverage is 89.20%. Comparing base (87c5cae) to head (3870823).
Report is 5 commits behind head on main.

Files with missing linesPatch %Lines
lightning-invoice/src/de.rs96.56%7 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #3665 +/- ##
==========================================
- Coverage 89.23% 89.20% -0.04% 
==========================================
Files 155 155 Lines 119671 119874 +203 Branches 119671 119874 +203 ==========================================
+ Hits 106787 106930 +143 - Misses 10268 10320 +52 - Partials 2616 2624 +8 

☔ 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.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated

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

Looks good after feedback is addressed!

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
@ldk-reviews-bot

Copy link
Copy Markdown

👋 The first review has been submitted!

Do you think this PR is ready for a second reviewer? If so, click here to assign a second reviewer.

@phlip9

Copy link
Copy Markdown
ContributorAuthor

oh yeah here's some neat invoices I managed to generate:

The longest valid invoice with all known tags (4458 B):

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242jqrktctdhtu89wzzrmswsuxh8jzj3aawnufsujk9f8h0h97ass0pceawpc75jqyqyv0h0vs4x3kh5nvjuv808xp7nwx4znnu5ece9wspsgwv66

And the one generated in the test, at exactly 7089 B. It does need some non-standard tag fields to reach the limit though:

lnbc10000000000000000010p1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdllg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zs2pg9q5zsgnp4qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cxqd0llllllllllllcqd0llllllllllllfp4qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr75qvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpsxfr986kyx3ygqqkvq6alklcslcvfj834l8lyxqkmafkjx57up2cuqypqxpq9qcrssqqqqqqsqqqqzsqqxqeyv5l2cs6y3qqzesrth7mlzrlp3xg7xhulusczm04x6g6nms9trsqsyqcyq5rqwzqqqqqqzqqqqq2qqqcry3jnatzrgjyqqtxqdwlm0ug0uxyerc6lnljrqtd75mfr20wq4vwqzqsrqszsvpcgqqqqqqgqqqqpgqqrqvjx204vgdzgsqpvcp4mldl3plscny0rt707gvpdh6ndydfacz43cqgzqvzq2ps8pqqqqqqpqqqqq9qqqvpjgef743p5fzqq9nqxh0ah7y87rzv3ud0eleps9kl2d5348hq2k8qpqgpsgpgxquyqqqqqqyqqqqq5qqpssp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygsmlld95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6tfd95kj6g9llz42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242qllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqllpppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppqjqppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppdjltalknlvrk3dtenzpzn2cwejxn4q0wacrmxhtye26pyvuexv4rrs3v9d3fvn3h67t9qhkmax54kzemsu3gnmv478ca7tdkhh6s5gqpfg3737

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

Just some formatting nits, otherwise LGTM.

Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
Comment threadlightning-invoice/src/de.rs Outdated
The new `bech32-v0.11.0` version (prev: `v0.9.1`) now enforces a max length of
1023 bytes. Before there was no max.
BOLT11 invoices can definitely exceed 1023 B with a long-ish description and
2 route hints, so this limit is likely too low.
Having a limit is probably a good idea. What do other projects choose? Here's
a brief survey:
LDK (pre-0.1): (no limit)
LDK (post-0.1): 1023 B
LDK (post-PR): 7089 B
LND[1]: 7089 B
CLN[2]: (no limit)
ACINQ[3][4]: (no limit)
LND uses 7089 B, which was chosen to be "the max number of bytes that can fit
in a QR code". LND's rationale is technically incorrect as QR codes actually
have a max capacity of 7089 _numeric_ characters and only support up to 4296
all-uppercase alphanumeric characters. However, ecosystem-wide consistency
is more important.
A more conservative limit that would probably also suffice might be 2953 B,
the QR code length limit for a lowercase bech32-encoded invoice.
[1]: https://github.com/lightningnetwork/lnd/blob/6531d4505098eb14e6c24aedfd752fc15e85845d/zpay32/invoice.go#L87
[2]: https://github.com/ElementsProject/lightning/blob/0e7615b1b73eee161911763840d6260baf596755/common/bolt11.c#L683
[3]: https://github.com/ACINQ/lightning-kmp/blob/feda82c853660a792b911be518367a228ed6e0ee/modules/core/src/commonMain/kotlin/fr/acinq/lightning/payment/Bolt11Invoice.kt#L165
[4]: https://github.com/ACINQ/bitcoin-kmp/blob/master/src/commonMain/kotlin/fr/acinq/bitcoin/Bech32.kt#L122
@phlip9
phlip9force-pushed the phlip9/increase-invoice-length-limit branch from d8f2aa5 to 3870823CompareMarch 14, 2025 19:00
@phlip9

Copy link
Copy Markdown
ContributorAuthor

Squashed and rebased on main

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

LGTM

@phlip9

phlip9 commented Mar 17, 2025

Copy link
Copy Markdown
ContributorAuthor

I'm not exactly sure how to interpret the incremental-mutants CI failure, but it looks like the relative diff pulled in a bunch of unrelated changes in channelmanager.rs and found MISSING test coverage or something? Is there something I can do to fix this?

EDIT: The only mutation in lightning-invoice says it's "unviable" so I don't believe anything is wrong with this PR.

@valentinewallace
valentinewallace merged commit d671596 into lightningdevkit:mainMar 17, 2025
@valentinewallace

Copy link
Copy Markdown
Contributor

Thanks @phlip9! Sorry for the delay, it's helpful for me if you re-request a review :)

MaxFangX pushed a commit to lexe-app/lexe-public that referenced this pull request Mar 17, 2025
The long invoice tests work on LDK 0.0.125 but fail on LDK 0.1.0.
Awaiting PR: <lightningdevkit/rust-lightning#3665>
@phlip9
phlip9 deleted the phlip9/increase-invoice-length-limit branch March 18, 2025 02:38
@TheBlueMattTheBlueMatt mentioned this pull request Apr 1, 2025
@TheBlueMatt

Copy link
Copy Markdown
Collaborator

Backported in #3697

TheBlueMatt added a commit to TheBlueMatt/rust-lightning that referenced this pull request Apr 3, 2025
v0.1.2 - Apr 02, 2025 - "Foolishly Edgy Cases"
API Updates
===========
* `lightning-invoice` is now re-exported as `lightning::bolt11_invoice`
(lightningdevkit#3671).
Performance Improvements
========================
* `rapid-gossip-sync` graph parsing is substantially faster, resolving a
regression in 0.1 (lightningdevkit#3581).
* `NetworkGraph` loading is now substantially faster and does fewer
allocations, resulting in a 20% further improvement in `rapid-gossip-sync`
loading when initializing from scratch (lightningdevkit#3581).
* `ChannelMonitor`s for closed channels are no longer always re-persisted
immediately after startup, reducing on-startup I/O burden (lightningdevkit#3619).
Bug Fixes
=========
* BOLT 11 invoices longer than 1023 bytes long (and up to 7089 bytes) now
properly parse (lightningdevkit#3665).
* In some cases, when using synchronous persistence with higher latency than
the latency to communicate with peers, when receiving an MPP payment with
multiple parts received over the same channel, a channel could hang and not
make progress, eventually leading to a force-closure due to timed-out HTLCs.
This has now been fixed (lightningdevkit#3680).
* Some rare cases with multi-hop BOLT 11 route hints or multiple redundant
blinded paths could have led to the router creating invalid `Route`s were
fixed (lightningdevkit#3586).
* Corrected the decay logic in `ProbabilisticScorer`'s historical buckets
model. Note that by default historical buckets are only decayed if no new
datapoints have been added for a channel for two weeks (lightningdevkit#3562).
* `{Channel,Onion}MessageHandler::peer_disconnected` will now be called if a
different message handler refused connection by returning an `Err` from its
`peer_connected` method (lightningdevkit#3580).
* If the counterparty broadcasts a revoked state with pending HTLCs, those
will now be claimed with other outputs which we consider to not be
vulnerable to pinning attacks if they are not yet claimable by our
counterparty, potentially reducing our exposure to pinning attacks (lightningdevkit#3564).
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.

5 participants

@phlip9@ldk-reviews-bot@valentinewallace@TheBlueMatt@tnull