-
Notifications
You must be signed in to change notification settings - Fork 2.2k
[Part 3|*] Implement Second Part for SQL Backend functions #10291
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
ziggie1984
wants to merge
14
commits into
lightningnetwork:elle-payment-sql-series-new
Choose a base branch
from
ziggie1984:introduce-sql-schema-payments-part-3
base: elle-payment-sql-series-new
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
18f03ec
sqldb: add index and comment to payment tables
ziggie1984 c908b52
multi: add relevant queries for QueryPayments implemenation
ziggie1984 52d466f
paymentsdb: add new internal error
ziggie1984 353160c
paymentsdb: implement QueryPayments for sql backend
ziggie1984 fc4ce67
paymentsdb: implement FetchPayment for sql backend
ziggie1984 0849296
docs: add release-notes
ziggie1984 ed5622c
sqldb: add queries for deleting a payment and attempts
ziggie1984 215490c
paymentsdb: implement DeletePayment for sql backend
ziggie1984 3a39bdc
paymentsdb: implement DeleteFailedAttempts for sql backend
ziggie1984 1aae195
sqldb+paymentsdb: add queries to insert all relavant data
ziggie1984 f6f2ee3
paymentsdb: implement InitPayment for sql backend
ziggie1984 53b47ea
paymentsdb: implement RegisterAttempt for sql backend
ziggie1984 b3f3627
paymentsdb: implement SettleAttempt for sql backend
ziggie1984 6145682
docs: add release-notes
ziggie1984 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,10 +6,12 @@ import ( | |
| "errors" | ||
| "fmt" | ||
| "math" | ||
| "strconv" | ||
| "time" | ||
|
|
||
| "github.com/lightningnetwork/lnd/lntypes" | ||
| "github.com/lightningnetwork/lnd/lnwire" | ||
| "github.com/lightningnetwork/lnd/routing/route" | ||
| "github.com/lightningnetwork/lnd/sqldb" | ||
| "github.com/lightningnetwork/lnd/sqldb/sqlc" | ||
| ) | ||
|
|
@@ -734,3 +736,203 @@ func (s *SQLStore) InitPayment(paymentHash lntypes.Hash, | |
|
|
||
| return nil | ||
| } | ||
|
|
||
| // insertRouteHops inserts all route hop data for a given set of hops. | ||
| func (s *SQLStore) insertRouteHops(ctx context.Context, db SQLQueries, | ||
| hops []*route.Hop, attemptID uint64) error { | ||
|
|
||
| for i, hop := range hops { | ||
| // Insert the basic route hop data and get the generated ID | ||
| hopID, err := db.InsertRouteHop(ctx, sqlc.InsertRouteHopParams{ | ||
| HtlcAttemptIndex: int64(attemptID), | ||
| HopIndex: int32(i), | ||
| PubKey: hop.PubKeyBytes[:], | ||
| Scid: strconv.FormatUint( | ||
| hop.ChannelID, 10, | ||
| ), | ||
| OutgoingTimeLock: int32(hop.OutgoingTimeLock), | ||
| AmtToForward: int64(hop.AmtToForward), | ||
| MetaData: hop.Metadata, | ||
| }) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert route hop: %w", err) | ||
| } | ||
|
|
||
| // Insert the per-hop custom records | ||
| if len(hop.CustomRecords) > 0 { | ||
| for key, value := range hop.CustomRecords { | ||
| err = db.InsertPaymentHopCustomRecord(ctx, sqlc.InsertPaymentHopCustomRecordParams{ | ||
| HopID: hopID, | ||
| Key: int64(key), | ||
| Value: value, | ||
| }) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert "+ | ||
| "payment hop custom record: %w", err) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Insert MPP data if present | ||
| if hop.MPP != nil { | ||
| paymentAddr := hop.MPP.PaymentAddr() | ||
| err = db.InsertRouteHopMpp(ctx, sqlc.InsertRouteHopMppParams{ | ||
| HopID: hopID, | ||
| PaymentAddr: paymentAddr[:], | ||
| TotalMsat: int64(hop.MPP.TotalMsat()), | ||
| }) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert "+ | ||
| "route hop MPP: %w", err) | ||
| } | ||
| } | ||
|
|
||
| // Insert AMP data if present | ||
| if hop.AMP != nil { | ||
| rootShare := hop.AMP.RootShare() | ||
| setID := hop.AMP.SetID() | ||
| err = db.InsertRouteHopAmp(ctx, sqlc.InsertRouteHopAmpParams{ | ||
| HopID: hopID, | ||
| RootShare: rootShare[:], | ||
| SetID: setID[:], | ||
| }) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert "+ | ||
| "route hop AMP: %w", err) | ||
| } | ||
| } | ||
|
|
||
| // Insert blinded route data if present | ||
| if hop.EncryptedData != nil || hop.BlindingPoint != nil { | ||
| var blindingPointBytes []byte | ||
| if hop.BlindingPoint != nil { | ||
| blindingPointBytes = hop.BlindingPoint. | ||
| SerializeCompressed() | ||
| } | ||
|
|
||
| err = db.InsertRouteHopBlinded(ctx, | ||
| sqlc.InsertRouteHopBlindedParams{ | ||
| HopID: hopID, | ||
| EncryptedData: hop.EncryptedData, | ||
| BlindingPoint: blindingPointBytes, | ||
| BlindedPathTotalAmt: sqldb.SQLInt64( | ||
| hop.TotalAmtMsat, | ||
| ), | ||
| }, | ||
| ) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert "+ | ||
| "route hop blinded: %w", err) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return nil | ||
| } | ||
|
|
||
| // RegisterAttempt registers an attempt for a payment. | ||
| // | ||
| // This is part of the DB interface. | ||
| func (s *SQLStore) RegisterAttempt(paymentHash lntypes.Hash, | ||
| attempt *HTLCAttemptInfo) (*MPPayment, error) { | ||
|
|
||
| ctx := context.TODO() | ||
|
|
||
| var mpPayment *MPPayment | ||
|
|
||
| err := s.db.ExecTx(ctx, sqldb.WriteTxOpt(), func(db SQLQueries) error { | ||
| // 1. First Fetch the payment and check if it is registrable. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: started with numbering and then stopped |
||
| existingPayment, err := db.FetchPayment(ctx, paymentHash[:]) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to fetch payment: %w", err) | ||
| } | ||
|
|
||
| mpPayment, err = s.fetchPaymentWithCompleteData( | ||
| ctx, db, existingPayment, | ||
| ) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to fetch payment with "+ | ||
| "complete data: %w", err) | ||
| } | ||
|
|
||
| if err := mpPayment.Registrable(); err != nil { | ||
| return fmt.Errorf("htlc attempt not registrable: %w", | ||
| err) | ||
| } | ||
|
|
||
| // Verify the attempt is compatible with the existing payment. | ||
| if err := verifyAttempt(mpPayment, attempt); err != nil { | ||
| return fmt.Errorf("failed to verify attempt: %w", err) | ||
| } | ||
|
|
||
| // Fist register the plain HTLC attempt. | ||
| // Prepare the session key. | ||
| sessionKey := attempt.SessionKey() | ||
| sessionKeyBytes := sessionKey.Serialize() | ||
|
|
||
| _, err = db.InsertHtlcAttempt(ctx, sqlc.InsertHtlcAttemptParams{ | ||
| PaymentID: existingPayment.Payment.ID, | ||
| AttemptIndex: int64(attempt.AttemptID), | ||
| SessionKey: sessionKeyBytes, | ||
| AttemptTime: attempt.AttemptTime, | ||
| PaymentHash: paymentHash[:], | ||
| FirstHopAmountMsat: int64( | ||
| attempt.Route.FirstHopAmount.Val.Int(), | ||
| ), | ||
| RouteTotalTimeLock: int32(attempt.Route.TotalTimeLock), | ||
| RouteTotalAmount: int64(attempt.Route.TotalAmount), | ||
| RouteSourceKey: attempt.Route.SourcePubKey[:], | ||
| }) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert HTLC "+ | ||
| "attempt: %w", err) | ||
| } | ||
|
|
||
| // Insert the route level first hop custom records. | ||
| attemptFirstHopCustomRecords := attempt.Route. | ||
| FirstHopWireCustomRecords | ||
|
|
||
| for key, value := range attemptFirstHopCustomRecords { | ||
| err = db.InsertPaymentAttemptFirstHopCustomRecord(ctx, | ||
| sqlc.InsertPaymentAttemptFirstHopCustomRecordParams{ | ||
| HtlcAttemptIndex: int64(attempt.AttemptID), | ||
| Key: int64(key), | ||
| Value: value, | ||
| }) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert "+ | ||
| "payment attempt first hop custom "+ | ||
| "record: %w", err) | ||
| } | ||
| } | ||
|
|
||
| // Insert the route hops. | ||
| err = s.insertRouteHops( | ||
| ctx, db, attempt.Route.Hops, attempt.AttemptID, | ||
| ) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to insert route hops: %w", | ||
| err) | ||
| } | ||
|
|
||
| // Add the attempt to the payment without fetching it from the | ||
| // DB again. | ||
|
Comment on lines
+918
to
+919
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
| mpPayment.HTLCs = append(mpPayment.HTLCs, HTLCAttempt{ | ||
| HTLCAttemptInfo: *attempt, | ||
| }) | ||
|
|
||
| if err := mpPayment.SetState(); err != nil { | ||
| return fmt.Errorf("failed to set payment state: %w", | ||
| err) | ||
| } | ||
|
|
||
| return nil | ||
| }, func() { | ||
| mpPayment = nil | ||
| }) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("failed to register attempt: %w", err) | ||
| } | ||
|
|
||
| return mpPayment, nil | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function inserts route hops and their associated data one by one in a loop. For routes with many hops, this can result in a large number of database queries, impacting performance. Consider refactoring this to use batch inserts.
sqlcsupports batch inserts, which would require modifying the SQL queries to accept slices of parameters and then calling them once with all the data for the hops.