What changed, and why it matters
This commit only adds a documentation comment warning future developers that a function must be called serially for the same payment. It does not change any code behavior, fix a bug, or add synchronization. It is a code-comment-only change with no direct security effect by itself.
No immediate action required for this commit alone. Treat it as documentation. If reviewing related code, verify that callers of RegisterAttempt already serialize per payment hash or consider adding explicit synchronization if the invariant is safety-critical.
Security signals we found
Race condition documented in comment
Potential overpayment scenario described
No code change to enforce serialization
Evidence from the diff
The diff adds an 11-line GoDoc comment to the RegisterAttempt method in payments/db/interface.go. The comment warns that concurrent calls for the same payment hash can cause race conditions leading to overpayment because each call may read the same initial state and validate independently. The commit does not implement locking, change call sites, or alter logic. It documents an existing design assumption/requirement.
Changed components
payments/db/interface.goPaymentControl.RegisterAttemptInspect captured patch +11 / −0
diff --git a/payments/db/interface.go b/payments/db/interface.go
index c41dc37..7fefad0 100644
--- a/payments/db/interface.go
+++ b/payments/db/interface.go
@@ -61,6 +61,17 @@ type PaymentControl interface {
InitPayment(lntypes.Hash, *PaymentCreationInfo) error
// RegisterAttempt atomically records the provided HTLCAttemptInfo.
+ //
+ // IMPORTANT: Callers MUST serialize calls to RegisterAttempt for the
+ // same payment hash. Concurrent calls will result in race conditions
+ // where both calls read the same initial payment state, validate
+ // against stale data, and could cause overpayment. For example:
+ // - Both goroutines fetch payment with 400 sats sent
+ // - Both validate sending 650 sats won't overpay (within limit)
+ // - Both commit successfully
+ // - Result: 1700 sats sent, exceeding the payment amount
+ // The payment router/controller layer is responsible for ensuring
+ // serialized access per payment hash.
RegisterAttempt(lntypes.Hash, *HTLCAttemptInfo) (*MPPayment, error)
// SettleAttempt marks the given attempt settled with the preimage. If
Why this scored 13/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.