@@ -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