Skip to content

Commit 41c0c93

Browse files
committed
paymentsdb: implement SettleAttempt for sql backend
1 parent 1f5ad75 commit 41c0c93

File tree

1 file changed

+65
-1
lines changed

1 file changed

+65
-1
lines changed

payments/db/sql_store.go

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1092,7 +1092,8 @@ func (s *SQLStore) insertRouteHops(ctx context.Context, db SQLQueries,
10921092
})
10931093
if err != nil {
10941094
return fmt.Errorf("failed to insert "+
1095-
"payment hop custom record: %w", err)
1095+
"payment hop custom "+
1096+
"record: %w", err)
10961097
}
10971098
}
10981099
}
@@ -1291,3 +1292,66 @@ func (s *SQLStore) RegisterAttempt(paymentHash lntypes.Hash,
12911292

12921293
return mpPayment, nil
12931294
}
1295+
1296+
// SettleAttempt marks the specified HTLC attempt as successfully settled,
1297+
// recording the payment preimage and settlement time. The preimage serves as
1298+
// cryptographic proof of payment and is atomically saved to the database.
1299+
//
1300+
// This method is part of the PaymentControl interface, which is embedded in
1301+
// the PaymentWriter interface and ultimately the DB interface. It represents
1302+
// step 3a in the payment lifecycle control flow (step 3b is FailAttempt),
1303+
// called after RegisterAttempt when an HTLC successfully completes.
1304+
func (s *SQLStore) SettleAttempt(paymentHash lntypes.Hash,
1305+
attemptID uint64, settleInfo *HTLCSettleInfo) (*MPPayment, error) {
1306+
1307+
ctx := context.TODO()
1308+
1309+
var mpPayment *MPPayment
1310+
1311+
err := s.db.ExecTx(ctx, sqldb.WriteTxOpt(), func(db SQLQueries) error {
1312+
dbPayment, err := db.FetchPayment(ctx, paymentHash[:])
1313+
if err != nil {
1314+
return fmt.Errorf("failed to fetch payment: %w", err)
1315+
}
1316+
1317+
paymentStatus, err := computePaymentStatusFromDB(
1318+
ctx, db, dbPayment,
1319+
)
1320+
if err != nil {
1321+
return fmt.Errorf("failed to compute payment "+
1322+
"status: %w", err)
1323+
}
1324+
1325+
if err := paymentStatus.updatable(); err != nil {
1326+
return fmt.Errorf("payment is not updatable: %w", err)
1327+
}
1328+
1329+
err = db.SettleAttempt(ctx, sqlc.SettleAttemptParams{
1330+
AttemptIndex: int64(attemptID),
1331+
ResolutionTime: time.Now(),
1332+
ResolutionType: int32(HTLCAttemptResolutionSettled),
1333+
SettlePreimage: settleInfo.Preimage[:],
1334+
})
1335+
if err != nil {
1336+
return fmt.Errorf("failed to settle attempt: %w", err)
1337+
}
1338+
1339+
// Fetch the complete payment after we settled the attempt.
1340+
mpPayment, err = s.fetchPaymentWithCompleteData(
1341+
ctx, db, dbPayment,
1342+
)
1343+
if err != nil {
1344+
return fmt.Errorf("failed to fetch payment with "+
1345+
"complete data: %w", err)
1346+
}
1347+
1348+
return nil
1349+
}, func() {
1350+
mpPayment = nil
1351+
})
1352+
if err != nil {
1353+
return nil, fmt.Errorf("failed to settle attempt: %w", err)
1354+
}
1355+
1356+
return mpPayment, nil
1357+
}

0 commit comments

Comments
 (0)