payments/db: fix silent error in duplicate payment lookup
What changed, and why it matters
This commit fixes a bug in LND's payment database where a missing piece of data inside a stored duplicate payment was silently treated as 'not found' instead of reporting an error. The fix makes the database return a clear, dedicated error so corrupted or malformed payment records are detected immediately rather than ignored.
Apply the patch. Audit related duplicate-payment lookup paths for similar shadowing of err variables. Consider adding regression tests that simulate a missing duplicatePaymentSequenceKey and assert ErrNoDuplicateSequenceNumber is returned.
Security signals we found
Silent error swallowing in database lookup
Potential data-integrity issue in payment storage
Missing key in nested bucket treated as benign
Fix converts silent failure to explicit error
Evidence from the diff
In fetchPaymentWithSequenceNumber, when iterating duplicate payment sub-buckets, the code checks for duplicatePaymentSequenceKey. Previously, if seqBytes was nil, it returned the outer function’s err variable, which was nil at that point. This caused a missing sequence number key to be silently swallowed as a successful ‘not found’ condition. The patch introduces ErrNoDuplicateSequenceNumber and returns it explicitly, converting silent data corruption/malformation into a loud failure.
Changed components
payments/db/kv_store.gopayments/db/errors.goLND payment database lookupInspect captured patch +6 / −1
diff --git a/payments/db/errors.go b/payments/db/errors.go
index 0457db6..3b4e25b 100644
--- a/payments/db/errors.go
+++ b/payments/db/errors.go
@@ -136,6 +136,11 @@ var (
ErrNoDuplicateNestedBucket = errors.New("nested duplicate bucket not " +
"found")
+ // ErrNoDuplicateSequenceNumber is returned when a duplicate payment
+ // sub-bucket does not contain the sequence number key.
+ ErrNoDuplicateSequenceNumber = errors.New("duplicate payment " +
+ "sequence number not found")
+
// ErrNoSequenceNrIndex is returned when an attempt to lookup a payment
// index is made for a sequence number that is not indexed.
//
diff --git a/payments/db/kv_store.go b/payments/db/kv_store.go
index 6d21048..b3fffe1 100644
--- a/payments/db/kv_store.go
+++ b/payments/db/kv_store.go
@@ -1236,7 +1236,7 @@ func fetchPaymentWithSequenceNumber(tx kvdb.RTx, paymentHash lntypes.Hash,
seqBytes := subBucket.Get(duplicatePaymentSequenceKey)
if seqBytes == nil {
- return err
+ return ErrNoDuplicateSequenceNumber
}
// If this duplicate payment is not the sequence number we are
Why this scored 42/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.