Skip to content

[v0.20.x-branch] Backport #11190: zpay32: reject duplicate payment hash fields - #11235

Merged
ziggie1984 merged 1 commit into
v0.20.x-branchfrom
backport-11190-to-v0.20.x-branch
Sep 23, 2026
Merged

ziggie1984 merged 1 commit into
v0.20.x-branchfrom
backport-11190-to-v0.20.x-branch

Conversation

@github-actions

Copy link
Copy Markdown

Backport of #11190


Change Description

In this PR, we reject BOLT 11 invoices that contain more than one payment
hash (p) field. zpay32.Decode previously kept the first supported payment
hash and ignored later fields, so the interpreted payment hash depended on
field order.

The decoder now tracks whether a p field has appeared separately from whether
its contents parsed successfully. Any later p field returns
ErrDuplicatePaymentHash. This covers identical hashes, distinct hashes, and a
malformed first field followed by a valid one.

This change is deliberately stricter than the current BOLT 11 text, which
tells a reader to use the first p field; it is motivated by
lightning/bolts#1357.

Note: the same order dependence remains for the other single-occurrence fields
(s, d, m, n, h, x, c, f, 9), which all keep first-seen-wins
behavior. This PR is intentionally limited to the payment hash; the s
(payment address) field looks like the natural candidate for the same treatment
in a follow-up.

Steps to Test

go test ./zpay32
make lint-native

Pull Request Checklist

Testing

  • Your PR passes all CI checks.
  • Tests covering the positive and negative (error paths) are included.
  • Bug fixes contain tests triggering the bug to prevent regressions.

Code Style and Documentation

@github-actions github-actions Bot added this to the v0.21.4 milestone Sep 23, 2026
@github-actions

Copy link
Copy Markdown
Author

Please cherry-pick the changes locally and resolve any conflicts.

git fetch origin backport-11190-to-v0.20.x-branch
git worktree add --checkout .worktree/backport-11190-to-v0.20.x-branch backport-11190-to-v0.20.x-branch
cd .worktree/backport-11190-to-v0.20.x-branch
git reset --hard HEAD^
git cherry-pick -x e2f2706367aa6e7a39f8ee14204b43087e27600f
git push --force-with-lease

In this commit, we reject BOLT 11 invoices that contain more than one
payment hash (`p`) field. `zpay32.Decode` previously kept the first
supported payment hash and ignored later fields, so the interpreted
payment hash depended on field order.

The decoder now tracks whether a `p` field has appeared separately from
whether its contents parsed successfully, and any later `p` field returns
`ErrDuplicatePaymentHash`. This covers identical hashes, distinct hashes,
and a malformed first field followed by a valid one. The change is
deliberately stricter than the current BOLT 11 text, which tells a reader
to use the first `p` field; it is motivated by lightning/bolts#1357, and
will be backported to the v0.20.5 and v0.21.4 releases.

We also replace the stale comment above parse32Bytes, which quoted the
old BOLT 11 rule that a reader must skip over 32-byte fields with an
unsupported length. The current reader requirements say the opposite: a
reader must fail the payment if a fixed-length field (p, h, s, n) does
not have the correct length. The new comment states that reporting the
field as absent is a known divergence, and explains why the end result
for the payment hash is the same either way.

In the tests, we cover identical and distinct duplicate hashes, a
malformed first field followed by a valid one, and the signed vectors. A
valid variant of the flipped vector keeps the wrong-length h and n
fields, so the coverage that such fields are skipped survives. The
duplicate vector in the decode table pins ErrDuplicatePaymentHash
through a new wantErr field rather than asserting any decode error.

(cherry picked from commit e2f2706)
@ziggie1984
ziggie1984 force-pushed the backport-11190-to-v0.20.x-branch branch from ac3ee08 to 5e7d3e1 Compare September 23, 2026 13:26
@ziggie1984
ziggie1984 marked this pull request as ready for review September 23, 2026 13:28

@ziggie1984 ziggie1984 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM

@ziggie1984
ziggie1984 merged commit d2cc80b into v0.20.x-branch Sep 23, 2026
31 of 34 checks passed
@github-actions github-actions Bot added the severity-medium Focused review required label Sep 23, 2026
@github-actions

Copy link
Copy Markdown
Author

🟡 PR Severity: MEDIUM

gh pr view | 5 files | 150 lines changed

🟡 Medium (2 files)
  • zpay32/decode.go - zpay32 package (BOLT-11 invoice decoding)
  • zpay32/invoice.go - zpay32 package (BOLT-11 invoice type)
🟢 Low (3 files)
  • docs/release-notes/release-notes-0.20.5.md - release notes
  • zpay32/invoice_internal_test.go - test-only change
  • zpay32/invoice_test.go - test-only change

Analysis

This is a backport of #‌11190 (reject duplicate payment hashes) to the v0.20.x branch. The substantive change is confined to zpay32/decode.go and zpay32/invoice.go, which fall under the zpay32/* package (MEDIUM tier). The remaining files are tests and release notes. Total non-test/non-generated lines changed (~38) and file count (3) are well below the bump thresholds, and no critical packages are touched, so no severity escalation applies.


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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog severity-medium Focused review required

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants