Skip to content
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

channeldb+invoices: add set id index for AMP #4338

Merged
merged 13 commits into from
Mar 4, 2021

Conversation

cfromknecht
Copy link
Contributor

@cfromknecht cfromknecht commented May 31, 2020

This PR adds an additional invoice index to track invoices by the set id of AMP style payments. The control paths for accepting real AMP payments are not enabled by this PR, but it does expose the necessary data structures and validation logic for accept AMP HTLC sets.

Summary of changes:

  • persist additional AMP related fields on each InvoiceHTLC
  • introduce HTLCSet method to compute the Accepted HTLCs belonging to a particular set id
  • adds an invoice index over set id, mapping non-nil set ids to invoices with HTLCs that carry a particular set id. this is can be used by users to lookup, cancel, or settle AMP HTLC sets.
  • add additional safety checks to invoice state transitions
    • ensure that HTLCs can only be persisted when added through UpdateInvoice
    • ensure that an invoice can only enter the Accepted or Settled state when targeting a non-empty HTLC set
    • validate the per-HTLC hash/preimage pairs for AMP HTLCs when transitioning an invoice to Accepted or Settled. this will be more relevant when the secret share reconstruction is fully integrated.
  • assert that the exepcted AMP-related fields are exposed via RPC but unpopulated for regular payments

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Completed an initial pass mainly to build up my mental model on how everything will fit together in the end. So far things are looking pretty good! Will do another deeper pass once the PR leaves the draft state.

@cfromknecht cfromknecht force-pushed the set-id-index branch 2 times, most recently from f86d202 to 6003dae Compare June 2, 2020 10:24
@cfromknecht cfromknecht force-pushed the set-id-index branch 2 times, most recently from 1c3edee to b447b1f Compare June 3, 2020 10:55
@cfromknecht cfromknecht marked this pull request as ready for review June 3, 2020 20:02
Copy link
Contributor

@joostjager joostjager left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It definitely gets a bit heavy with all these payment types. Dropping some comments now and also need to do another pass. One question for now is how to test? Can it be done with manual custom record sending?

@Roasbeef
Copy link
Member

Roasbeef commented Jun 5, 2020

Can it be done with manual custom record sending?

I think one way would be to manually create a new "compliant" key-send and verify that it goes thru the new code paths. Also that once it's settled, then the relevant fields show in in ListInvoices on the other end.

@cfromknecht
Copy link
Contributor Author

Can it be done with manual custom record sending?

Mock payloads? https://github.com/lightningnetwork/lnd/pull/4338/files#diff-912650820f0598a654610a053ad16954R26

@joostjager
Copy link
Contributor

So currently the only way this PR is not dead code is for keysend right?

@cfromknecht
Copy link
Contributor Author

Yes without the last commit that promotes keysend this be mostly dead code. Some minor things would not be, e.g. the way HTLC sets are now computed, but most of it would

@joostjager joostjager self-requested a review June 8, 2020 07:46
@cfromknecht cfromknecht force-pushed the set-id-index branch 4 times, most recently from 0d62721 to 0b91cb8 Compare June 9, 2020 03:37
Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🗿

@cfromknecht cfromknecht force-pushed the set-id-index branch 2 times, most recently from 05343cd to 355088f Compare June 9, 2020 05:15
@halseth
Copy link
Contributor

halseth commented Feb 25, 2021

@cfromknecht Please re-request review when ready.

Copy link
Member

@Roasbeef Roasbeef left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 🍫

Copy link
Contributor

@halseth halseth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! Only a last lingering question from me, when that is cleared up this LGTM 🌷

htlc.Hash)
}

htlcState = HtlcStateSettled
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below comments trySettle should be no-op for non-AMP HTLCs. This looks like is not?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The NOP is referring to the check that we can settle the HTLC portion, but i agree it could be more clear.

// the process by updating the state transitions for individual HTLCs
// and recalculate the total amount paid to the invoice.
var amtPaid lnwire.MilliSatoshi
for _, htlc := range invoice.Htlcs {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Earlier we would iterate through all the invoice's HTLCs, calling cancelSingleHtlc on those canceled by the update, and calling updateHtlc on the rest.

With this commit we are still calling cancelSingleHtlc on canceled HTLCs, but we are calling updateHtlc for ALL, regardless of canceled or non-canceled.

I'm wondering if this is an intentional change.

@cfromknecht cfromknecht force-pushed the set-id-index branch 2 times, most recently from d3657c9 to 9733cd8 Compare March 3, 2021 23:41
Mainly affects ResolveTime which can be 0 before its settled.
Prior to AMP, there could only be one HTLC set. Now that there can be
multiple, we introduce the inherent risk that we might be persisting a
settle/accept of the wrong HTLC set. To migitigate this risk, we add a
check to assert that an invoice can only be transitioned into an
Accepted or Settled state if the specified HTLC set is non-empty, i.e.
has accepted HTLCs.

To do this check, we unroll the loops in UpdateInvoice to first process
any added or canceled HTLCs. This ensures that the set of accepted HTLCs
is up-to-date when we got to transition the invoice into a new state, at
which point we can accurately check that the HTLC set is non-empty.
Previously this sort of check wasn't possible because a newly added HTLC
wouldn't be populated on the invoice when going to call
updateInvoiceState.

Once the invoice-level transition checks have completed, we complete a
final pass to move the HTLCs into their final states and recompute the
amount paid.

With this refactor, it is now possible to make stronger assertions
about the invoice and the state transitions being made by the
invoiceregistry before those changes are ultimately persisted.
@Roasbeef
Copy link
Member

Roasbeef commented Mar 4, 2021

Type mismatch related assertion failure?

    lnd_single_hop_invoice_test.go:178: 
        	Error Trace:	lnd_single_hop_invoice_test.go:178
        	            				test_harness.go:112
        	            				lnd_test.go:14583
        	Error:      	Not equal: 
        	            	expected: int(0)
        	            	actual  : uint64(0x0)
        	Test:       	TestLightningNetworkDaemon/15-of-71/btcd/single_hop_invoice

We also test that legacy keysend payments are promoted to AMP payments
on the receiver-sdie by asserting basic properties of the fields
returned via the rpc.
@cfromknecht
Copy link
Contributor Author

@Roasbeef weird how this never showed up before? fixed now

@cfromknecht cfromknecht merged commit 56b6107 into lightningnetwork:master Mar 4, 2021
@cfromknecht cfromknecht deleted the set-id-index branch March 4, 2021 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
amp P1 MUST be fixed or reviewed v0.13
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants