Skip to content

bolt12: add invoice_error message for onion message replies#10958

Open
bitromortac wants to merge 7 commits into
lightningnetwork:masterfrom
bitromortac:2604-bolt12-1d
Open

bolt12: add invoice_error message for onion message replies#10958
bitromortac wants to merge 7 commits into
lightningnetwork:masterfrom
bitromortac:2604-bolt12-1d

Conversation

@bitromortac

Copy link
Copy Markdown
Collaborator

Based on #10941, part of #10736.

Adds the BOLT 12 invoice_error message to bolt12.

Add the truncated uint32 (tu32) TLV type used by invoice_relative_expiry
and the dynamic invoice subtypes BlindedPayInfo and FallbackAddress,
along with their encode/decode helpers and round-trip tests.

These primitives are the building blocks for the BOLT 12 Invoice message
struct that follows. Isolating them keeps that codec commit focused on
the message shape rather than its component records.
…alidators

Inject known feature-bit catalogues into the read-side validators to enable
correct must-understand capability checks, and remove write-side feature
enforcement entirely.

Whether a feature bit is "unknown" is a runtime property of the reading node,
not of the wire format or pure codec.
Add the BOLT 12 Invoice message: a struct mirroring the invoice_request
fields (types 0-91) plus the invoice-specific fields (types 160-176) and
the signature (type 240), together with its pure-TLV Encode/DecodeInvoice
codec and the UsableFallbackAddresses accessor that applies the spec's
MUST-ignore filter.

Additionally, add the NewInvoiceFromRequest constructor to build an Invoice
from a corresponding request. This copies all non-signature fields from the
request (including unknown signed-range TLVs via the decodedTLVs sidecar)
and mirrors invreq_amount into invoice_amount.
Implement the structural validators for the BOLT 12 invoice, adding
ValidateInvoiceWrite, ValidateInvoiceRead, ValidateInvoiceExpiry, and
ValidateInvoiceAgainstRequest.

The validators implement the spec writer and reader requirements in the
order the spec lists them. The reader confirms the signature TLV is
present but defers actual Schnorr verification until the merkle and
signing primitives land, mirroring the ValidateInvoiceRequestRead
precedent.
Add release notes for the BOLT 12 invoice codec.
InvoiceError is the negative-reply counterpart to an invoice, sent over
onion messages at namespace type 68 when the receiver rejects an invoice
request or the sender rejects a returned invoice. All three fields are
odd (informational): erroneous_field (TLV 1, the offending TLV type),
suggested_value (TLV 3, a valid replacement), and error (TLV 5, a UTF-8
explanation). Unlike Offer/InvoiceRequest/Invoice this type has no
bech32 form and no Merkle signature — it travels only inside onion
message payloads.
@github-actions github-actions Bot added the severity-high Requires knowledgeable engineer review label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

🟠 PR Severity: HIGH

file-based classification | 10 files | 3671 lines changed (3650 additions, 21 deletions)

🟡 Medium (5 files, bumped to HIGH)
  • bolt12/invoice.go - new file, not in an explicitly categorized package; falls under "other Go files not categorized above"
  • bolt12/invoice_error.go - same as above
  • bolt12/subtypes.go - same as above
  • bolt12/tlv_types.go - same as above
  • bolt12/validate.go - same as above
🟢 Low (1 file)
  • docs/release-notes/release-notes-0.22.0.md - release notes entry
Excluded from counting (test files)
  • bolt12/invoice_error_test.go
  • bolt12/invoice_test.go
  • bolt12/subtypes_test.go
  • bolt12/validate_test.go

Analysis

All substantive changes are confined to the bolt12 package, which is not explicitly listed in the CRITICAL/HIGH/MEDIUM tiers of the classification rubric, so it defaults to MEDIUM ("other Go files not categorized above"). This package implements BOLT12 invoice construction, error types, TLV subtypes, and validation logic for offers/invoices.

However, excluding test files and the release-notes doc, the non-test diff totals 1,699 lines across 5 files (440 + 109 + 361 + 17 + 761), well past the 500-line bump threshold. This triggers a one-level severity bump from MEDIUM → HIGH.

Note that bolt12/validate.go and bolt12/invoice.go are large, mostly-new files implementing spec-compliant parsing/validation for a wire-adjacent format (BOLT12), so correctness here has real security surface (malformed/malicious invoice handling) even though the package isn't in the explicit CRITICAL list — reviewers should treat the validation logic with care despite the automated MEDIUM baseline.


To override, add a severity-override-{critical,high,medium,low} label.

@saubyk saubyk added this to the v0.22.0 milestone Jul 9, 2026
@saubyk saubyk added this to lnd v0.22 Jul 9, 2026
@saubyk saubyk moved this from Backlog to In progress in lnd v0.22 Jul 9, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in lnd v0.22 Jul 9, 2026
@Abdulkbk

Copy link
Copy Markdown
Contributor

I guess this is ready for review, right?

@bitromortac

Copy link
Copy Markdown
Collaborator Author

I guess this is ready for review, right?

Yes, would be great 🙏

@bitromortac
bitromortac requested review from GeorgeTsagk and Copilot and removed request for Copilot July 16, 2026 16:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity-high Requires knowledgeable engineer review

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

3 participants