lnd icon indicating copy to clipboard operation
lnd copied to clipboard

[feature]: Add Support for P2TR Fallback Addresses and Standardize Multiple Fallback Address Handling in BOLT-11

Open erickcestari opened this issue 10 months ago • 4 comments

Is your feature request related to a problem? Please describe.

LND currently does not properly support P2TR (Taproot) fallback addresses in BOLT-11 invoices. Additionally, there's ambiguity in how multiple fallback addresses within a single invoice should be handled. As identified in discussion with Laolu, the BOLT-11 specification lacks test vectors for both P2TR fallback addresses and scenarios with multiple fallback addresses, leaving implementations without clear guidance.

Describe the solution you'd like

  1. Add support for P2TR fallback addresses in LND's BOLT-11 invoice parsing

  2. Implement well-defined behavior for handling multiple fallback addresses in a single invoice (either consistently discard subsequent addresses or replace earlier ones)

  3. Coordinate with the Lightning specification team to:

  • Update the BOLT-11 spec to explicitly define how implementations should handle multiple fallback addresses
  • Add test vectors for both P2TR fallback addresses and multiple fallback address scenarios

Describe alternatives you've considered Continuing with the current implementation would mean:

  • Users with P2TR fallback addresses would have compatibility issues
  • Inconsistent behavior across Lightning implementations when handling multiple fallback addresses
  • Although fallback addresses are rarely used in practice, leaving this unaddressed creates technical debt and potential interoperability issues as Taproot adoption increases

Additional context

During differential fuzzing testing between LND and LDK (using lightningfuzz, soon to be merged into bitcoinfuzz), I discovered inconsistent behavior when parsing BOLT-11 invoices containing certain fallback addresses.

Technical Details

  • LDK validates SegWit programs for versions 0-16, checking length constraints (2-40 bytes) and rejecting invalid ones with the error: fallback SegWit program is too long or too short.
  • LND only processes version 0 SegWit programs (checking for exactly 20 or 32 bytes) and silently ignores versions 1-16, including Taproot (v1) addresses. Furthermore, once it finds a single valid fallback address, it begins ignoring all other fallback address tagged fields without validating them.

Laolu has noted that while fallback addresses are rarely used in practice and most implementations don't use them for payment completion, this remains an underspecified feature of BOLT-11 that should be properly addressed for completeness and future compatibility. This issue has already been flagged for discussion in upcoming Lightning specification meetings.

The BOLT-11 specification can be found here: https://github.com/lightning/bolts/blob/master/11-payment-encoding.md#examples

erickcestari avatar Mar 07 '25 17:03 erickcestari

cc @brunoerg

erickcestari avatar Mar 07 '25 17:03 erickcestari

Hello @saubyk, I joined @erickcestari during the tests he ran. I'll be happy to jump into this one.

MPins avatar Mar 07 '25 20:03 MPins

Hello @saubyk, since I’m already working on this issue, I could also address #9904 and #9915 in the same PR — each in a separate commit, of course.

Or do you think it would be better to open a separate PR for each one?

MPins avatar Jun 06 '25 20:06 MPins

@MPins If the fixes are small and review is not too onerous, can do it one pr

saubyk avatar Jun 10 '25 03:06 saubyk

LND only processes version 0 SegWit programs (checking for exactly 20 or 32 bytes) and silently ignores versions 1-16, including Taproot (v1) addresses. Furthermore, once it finds a single valid fallback address, it begins ignoring all other fallback address tagged fields without validating them.

I think it is ok to exit early once a valid address is found, without validating the other one or ? What is your proposal how multiple addresses should be validated, something probably perfect for the BOLT spec. cc @MPins

ziggie1984 avatar Aug 02 '25 12:08 ziggie1984

LND only processes version 0 SegWit programs (checking for exactly 20 or 32 bytes) and silently ignores versions 1-16, including Taproot (v1) addresses. Furthermore, once it finds a single valid fallback address, it begins ignoring all other fallback address tagged fields without validating them.

I think it is ok to exit early once a valid address is found, without validating the other one or ? What is your proposal how multiple addresses should be validated, something probably perfect for the BOLT spec. cc @MPins

I will make a research to see the actual behavior across major implementations (rust-lightning, Eclair, LND, c-lightning) regarding multiple fallback address validation. If most implementations verify all fallback addresses, it would make sense to formalize that approach in the BOLT specification. Conversely, if they all validate only the first address and skip subsequent ones, formalizing that behavior in the BOLT spec would be equally valuable for consistency.

For me, both validation approaches are fine. I'd prefer to use the one most implementations already use, just to formalize it.

erickcestari avatar Aug 05 '25 14:08 erickcestari

Hello, the PR that added the test vector do BOLT just received its first approval. As noted, the fallback address might be deprecated in the future, so I think it wouldn't make sense to propose any further changes int the fallback address specification.

IMO we can just move forward with the PR as it is and have LND accept the P2TR fallback address in the same way it handles the other address types.

MPins avatar Aug 15 '25 15:08 MPins