payments/db/migration1: sync bugfixes from main sql_store
What changed, and why it matters
This commit fixes two bugs in a frozen copy of LND's payment database code used during data migration. One bug would overwrite historical success/failure timestamps with the current time when updating old payment attempts. The other bug made payment list ordering non-deterministic. The commit message explicitly states these fixed functions are not actually called by the migration itself, so the fixes are for completeness rather than active vulnerability remediation.
No immediate security action required. Treat as routine code-quality/maintenance backport. If using this migration snapshot, verify that downstream tooling does not rely on the corrected functions being called during migration, since the commit message says they are not. Review whether the original missed backport indicates process gaps in migration snapshot preparation.
Security signals we found
Incorrect use of time.Now() instead of stored historical timestamp could corrupt audit/reconciliation data
Non-deterministic map iteration order could cause inconsistent query results
Backport of bugfixes into frozen migration snapshot suggests prior main code was already fixed
Functions containing fixes are stated to be unused by actual migration path
Evidence from the diff
The patch backports two bugfixes from the main sql_store into payments/db/migration1/sql_store.go. First, SettleAttempt and FailAttempt now use settleInfo.SettleTime.UTC() and failInfo.FailTime.UTC() respectively instead of time.Now() for ResolutionTime, preserving historical resolution timestamps. Second, QueryPayments now sorts the resulting slice by SequenceNum after collecting values from a map, giving deterministic ordering. The commit message notes that SettleAttempt, FailAttempt, and QueryPayments are not invoked by the migration code; the migration only writes historical KV data into SQL and reads it back for validation.
Changed components
payments/db/migration1/sql_store.goSettleAttempt functionFailAttempt functionQueryPayments functionInspect captured patch +10 / −3
diff --git a/payments/db/migration1/sql_store.go b/payments/db/migration1/sql_store.go
index 96ee193..d984ba9 100644
--- a/payments/db/migration1/sql_store.go
+++ b/payments/db/migration1/sql_store.go
@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"math"
+ "sort"
"strconv"
"time"
@@ -1122,12 +1123,18 @@ func (s *SQLStore) FetchInFlightPayments(ctx context.Context) ([]*MPPayment,
return err
}
- // Convert map to slice.
+ // Convert map to slice and sort by sequence number to
+ // produce a deterministic ordering.
mpPayments = make([]*MPPayment, 0, len(processedPayments))
for _, payment := range processedPayments {
mpPayments = append(mpPayments, payment)
}
+ sort.Slice(mpPayments, func(i, j int) bool {
+ return mpPayments[i].SequenceNum <
+ mpPayments[j].SequenceNum
+ })
+
return nil
}, func() {
mpPayments = nil
@@ -1691,7 +1698,7 @@ func (s *SQLStore) SettleAttempt(ctx context.Context, paymentHash lntypes.Hash,
err = db.SettleAttempt(ctx, sqlc.SettleAttemptParams{
AttemptIndex: int64(attemptID),
- ResolutionTime: time.Now(),
+ ResolutionTime: settleInfo.SettleTime.UTC(),
ResolutionType: int32(HTLCAttemptResolutionSettled),
SettlePreimage: settleInfo.Preimage[:],
})
@@ -1778,7 +1785,7 @@ func (s *SQLStore) FailAttempt(ctx context.Context, paymentHash lntypes.Hash,
err = db.FailAttempt(ctx, sqlc.FailAttemptParams{
AttemptIndex: int64(attemptID),
- ResolutionTime: time.Now(),
+ ResolutionTime: failInfo.FailTime.UTC(),
ResolutionType: int32(HTLCAttemptResolutionFailed),
FailureSourceIndex: sqldb.SQLInt32(
failInfo.FailureSourceIndex,
Why this scored 23/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.