Skip to content

Commit 3981c47

Browse files
committed
paymentsdb: implement SettleAttempt for sql backend
1 parent ad87e35 commit 3981c47

File tree

1 file changed

+69
-1
lines changed

1 file changed

+69
-1
lines changed

payments/db/sql_store.go

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,8 @@ func (s *SQLStore) insertRouteHops(ctx context.Context, db SQLQueries,
10301030
})
10311031
if err != nil {
10321032
return fmt.Errorf("failed to insert "+
1033-
"payment hop custom record: %w", err)
1033+
"payment hop custom "+
1034+
"record: %w", err)
10341035
}
10351036
}
10361037
}
@@ -1222,3 +1223,70 @@ func (s *SQLStore) RegisterAttempt(paymentHash lntypes.Hash,
12221223

12231224
return mpPayment, nil
12241225
}
1226+
1227+
// SettleAttempt marks the specified HTLC attempt as successfully settled,
1228+
// recording the payment preimage and settlement time. The preimage serves as
1229+
// cryptographic proof of payment and is atomically saved to the database.
1230+
//
1231+
// This method is part of the PaymentControl interface, which is embedded in
1232+
// the PaymentWriter interface and ultimately the DB interface. It represents
1233+
// step 3a in the payment lifecycle control flow (step 3b is FailAttempt),
1234+
// called after RegisterAttempt when an HTLC successfully completes.
1235+
func (s *SQLStore) SettleAttempt(paymentHash lntypes.Hash,
1236+
attemptID uint64, settleInfo *HTLCSettleInfo) (*MPPayment, error) {
1237+
1238+
ctx := context.TODO()
1239+
1240+
var mpPayment *MPPayment
1241+
1242+
err := s.db.ExecTx(ctx, sqldb.WriteTxOpt(), func(db SQLQueries) error {
1243+
// Before updating the attempt, we fetch the payment to get the
1244+
// payment ID.
1245+
payment, err := db.FetchPayment(ctx, paymentHash[:])
1246+
if err != nil && !errors.Is(err, sql.ErrNoRows) {
1247+
return fmt.Errorf("failed to fetch payment: %w", err)
1248+
}
1249+
if errors.Is(err, sql.ErrNoRows) {
1250+
return ErrPaymentNotInitiated
1251+
}
1252+
completePayment, err := s.fetchPaymentWithCompleteData(
1253+
ctx, db, payment,
1254+
)
1255+
if err != nil {
1256+
return fmt.Errorf("failed to fetch payment with "+
1257+
"complete data: %w", err)
1258+
}
1259+
1260+
if completePayment.Status.updatable() != nil {
1261+
return fmt.Errorf("payment is not updatable: %w",
1262+
completePayment.Status.updatable())
1263+
}
1264+
1265+
err = db.SettleAttempt(ctx, sqlc.SettleAttemptParams{
1266+
AttemptIndex: int64(attemptID),
1267+
ResolutionTime: time.Now(),
1268+
ResolutionType: int32(HTLCAttemptResolutionSettled),
1269+
SettlePreimage: settleInfo.Preimage[:],
1270+
})
1271+
if err != nil {
1272+
return fmt.Errorf("failed to settle attempt: %w", err)
1273+
}
1274+
1275+
mpPayment, err = s.fetchPaymentWithCompleteData(
1276+
ctx, db, payment,
1277+
)
1278+
if err != nil {
1279+
return fmt.Errorf("failed to fetch payment with "+
1280+
"complete data: %w", err)
1281+
}
1282+
1283+
return nil
1284+
}, func() {
1285+
mpPayment = nil
1286+
})
1287+
if err != nil {
1288+
return nil, fmt.Errorf("failed to settle attempt: %w", err)
1289+
}
1290+
1291+
return mpPayment, nil
1292+
}

0 commit comments

Comments
 (0)