Commit Graph

74 Commits

Author SHA1 Message Date
Conner Fromknecht
f8d201a605
channeldb/invoice: only allow pay-addr lookup w/ no query hash
Without this check, it's possible to send a probe HTLC w/ a valid
payment address but invalid payment hash that gets settled. Because
there was no assertion that the HTLC's payment hash matches the
invoice, the link would fail when it receives an invalid preimage for
the HTLC on its commitment.
2021-04-13 12:18:42 -07:00
Conner Fromknecht
2a49b59f4f
channeldb/invoices: rigorously test updateHtlc for MPP/AMP scenarios 2021-04-07 12:08:35 -07:00
Conner Fromknecht
6780f74c87
channeldb/invoices: set AMP HTLC preimages when settling invoice 2021-04-07 12:08:35 -07:00
Conner Fromknecht
24d283e615
channeldb/invoice_test: only set htlc-level preimage on accept 2021-04-07 12:08:34 -07:00
Conner Fromknecht
7e2f5a184b
channeldb: validate feature dependencies when adding invoice 2021-04-07 12:08:34 -07:00
Conner Fromknecht
174d577524
channeldb: make payhash on InvoiceRef optional
Currently we support queries by payHash or payHash+payAddr. For handling
of AMP HTLCs, we only need to support querying by payAddr.
2021-04-07 12:08:34 -07:00
Conner Fromknecht
be6698447e
channeldb/invoice: add InvoiceRefByAddr 2021-04-07 12:08:34 -07:00
Conner Fromknecht
fc9af92dd9
channeldb: only accept/settle non-empty HTLC sets
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.
2021-03-03 16:28:02 -08:00
Conner Fromknecht
e1b0fe5e98
channeldb/invoices: update AMP invoice htlcs 2021-03-03 16:28:02 -08:00
Conner Fromknecht
fad25f3f26
channeldb/invoices: add invoices to set id index on update 2021-03-03 16:28:01 -08:00
Conner Fromknecht
da049ebcf7
channeldb: ensure invoices can't be added with HTLCs 2021-03-03 16:26:43 -08:00
Conner Fromknecht
b2234703f6
invoices+channeldb: add HTLCSet method to invoice 2021-03-03 16:26:43 -08:00
Conner Fromknecht
7f05c9d3bb
channeldb/invoice: persist optional AMP fields on InvoiceHTLC 2021-03-03 16:26:43 -08:00
Andras Banki-Horvath
a5778c4673
channeldb: add DeleteInvoices call
This commit extends channeldb with the DeleteInvoices call which is when
passed a slice of delete references will attempt to delete the invoices
pointed to by the references and also clean up all our invoice indexes.
2020-08-05 12:24:15 +02:00
Andras Banki-Horvath
92f3b0a30c
channeldb+invoices: add ScanInvoices and integrate with InvoiceRegistry
This commit adds channeldb.ScanInvoices to scan through all invoices in
the database. The new call will also replace the already existing
channeldb.FetchAllInvoicesWithPaymentHash call in preparation to collect
invoices we'd like to delete and watch for expiry in one scan in later
commits.
2020-08-05 12:24:14 +02:00
Andras Banki-Horvath
cbce8e8872
channeldb: move makeTestDB out of test to make it available for other tests
This commit moves makeTestDB to db.go and exports it so that we'll be
able to use this function in other unit tests to make them testable with
etcd if needed.
2020-07-28 17:57:29 +02:00
Conner Fromknecht
11e9fd3e92
channeldb/invoices: special-case all zeros pay addr
Avoids indexing the all-zeros pay addr, since it is still in use by
legacy keysend. Without this, the pay addr index will reject all but the
first keysend since they will be detected as duplicates within the set
id index.
2020-06-26 02:00:03 -07:00
carla
eea871b583
channeldb: add a paginator struct to process generic pagination
We now use the same method of pagination for invoices and payments.
Rather than duplicate logic across calls, we add a pagnator struct
which can have query specific logic plugged into it. This commit also
addresses an existing issue where a reverse query for invoices with an
offset larger than our last offset would not return any invoices. We
update this behaviour to act more like c.Seek and just start from the
last entry. This behaviour change is covered by a unit test that
previously checked for the lack of invoices.
2020-06-10 12:49:48 +02:00
carla
f4933c67fd
channeldb: add test case for index offset greater than index
In our current invoice pagination logic, we would not return any
invoices if our offset index was more than 1 off our last index and we
were paginating backwards. This commit adds a test case for this
behaviour before fixing it in the next commit.
2020-06-10 12:49:13 +02:00
Andras Banki-Horvath
80012c3936
invoice+test: changing testitfy asserts to specific requires 2020-06-05 15:16:31 +02:00
Andras Banki-Horvath
574bbe5eba
invoices+test: replace DeepEqual + spew dump with testify
This commit replaces reflect.DeepEqual tests and spew.Dump prints with
testify's require.Equal to make diffs smaller and test outputs more
readable.
2020-06-05 15:16:27 +02:00
Joost Jager
d416ed59ea
multi: add explicit hodl invoice flag to invoice
Previously it wasn't possible to store a preimage in the invoice
database and signal that a payment should not be settled right away. The
only way to hold a payment was to insert the magic UnknownPreimage value
in the invoice database. This commit introduces a distinct flag to
signal that an invoice is a hold invoice and thereby allows the preimage
to be present in the database already.

Preparation for (key send) hodl invoices for which we already know the
preimage.
2020-06-02 07:34:23 +02:00
Conner Fromknecht
0f3ab775c7
Merge pull request #4285 from cfromknecht/pay-addr-index
channeldb: index payments by payment addr, use payment hash as fallback
2020-05-27 17:36:30 -07:00
Conner Fromknecht
cbf71b5452
channeldb+invoices: use payment addr as primary index 2020-05-26 18:55:27 -07:00
Conner Fromknecht
3522f09a08
channeldb+invoices: track invoices by InvoiceRef 2020-05-26 18:55:27 -07:00
Conner Fromknecht
1332575482
channeldb/invoices: ignore error when no settles exist
This fixes a bug that would cause no backlog to be delivered at all.
2020-05-26 17:50:45 -07:00
Joost Jager
b600ecda86
channeldb: inject clock into database
Use our standard clock mock for database time queries.
2020-01-20 11:08:30 +01:00
Andras Banki-Horvath
8af5d8bc73 channeldb: remove unused, test only FetchAllInvoices function
This commit removes channeldb.FetchAllInvoices and changes tests such
that expectation sets are prepared in the test case instead of selected
from the DB.
2020-01-08 16:51:51 +01:00
Andras Banki-Horvath
4136b18e3d channeldb: remove time.Now() from tests 2020-01-08 16:51:51 +01:00
Andras Banki-Horvath
fa14ff67ad channeldb+invoices: fix what pending invoice means in ChannelDB
This commits builds on top of PR #3694 to further clarify invoice
state by defining pending invoices as the ones which are not
settled or canceled. Automatic cancellation of expired invoices
makes this possbile. While this change only directly affects
ChannelDB, users of the listinvoices RPC will receive actual
pending invoices when pending_only flag is set.
2019-12-19 17:44:32 +01:00
Andras Banki-Horvath
9b60685961 channeldb: remove math/rand from tests
This commit removes random invoice state selection when testing
FetchAllInvoicesWithPaymentHash.
2019-12-19 17:44:31 +01:00
Andras Banki-Horvath
0758b9310e channeldb: adding a unit test for FetchAllInvoicesWithPaymentHash
This commit changes how FetchAllInvoicesWithPaymentHash behaves
when the DB is empty and also adds a unit test to test that
case as well as normal expected behavior.
2019-12-13 17:03:19 +01:00
Joost Jager
8b5bb0ac63
record: move CustomRecordSet 2019-12-12 00:12:19 +01:00
Joost Jager
5f4bd136cd
invoices: store custom records in invoice database 2019-12-10 06:54:24 +01:00
Joost Jager
6c07902a63
channeldb/test: add single htlc cancel test 2019-12-04 14:51:44 +01:00
Joost Jager
00d93ed87b
channeldb: stricter validation of invoice updates 2019-12-04 14:51:42 +01:00
Joost Jager
a4a3c41924
channeldb: split cancel and add htlc updates
Previously the cancel and add actions were combined in a single map.
Nil values implictly signaled cancel actions. This wasn't very obvious.
Furthermore this split prepares for processing the adds and cancels
separately, which is more efficient if there are already two maps.
2019-12-04 14:51:40 +01:00
Joost Jager
e234f88b82
channeldb: export now function
To allow mocking when testing other packages.
2019-12-04 14:51:31 +01:00
Conner Fromknecht
3b253e05f6
multi: restructure invoice Terms field
This commit restructures an invoice's ContractTerms to better encompass
the restrictions placed on settling. For instance, the final ctlv delta
and invoice expiry are moved from the main invoice body (where
additional metadata is stored). Additionally, it moves the State field
outside of the terms since it is rather metadata about the invoice
instead of any terms offered to the sender in the payment request.
2019-11-22 02:25:02 -08:00
Conner Fromknecht
4c872c438b
channeldb: complete migration 12 for TLV invoices 2019-11-22 02:24:28 -08:00
Joost Jager
d6d9ec6aa5
invoices: replay awareness
Previously the invoice registry wasn't aware of replayed htlcs. This was
dealt with by keeping the invoice accept/settle logic idempotent, so
that a replay wouldn't have an effect.

This mechanism has two limitations:

1. No accurate tracking of the total amount paid to an invoice. The total
amount couldn't just be increased with every htlc received, because it
could be a replay which would lead to counting the htlc amount multiple
times. Therefore the total amount was set to the amount of the first
htlc that was received, even though there may have been multiple htlcs
paying to the invoice.

2. Impossible to check htlc expiry consistently for hodl invoices. When
an htlc is new, its expiry needs to be checked against the invoice cltv
delta. But for a replay, that check must be skipped. The htlc was
accepted in time, the invoice was moved to the accepted state and a
replay some blocks later shouldn't lead to that htlc being cancelled.
Because the invoice registry couldn't recognize replays, it stopped
checking htlc expiry heights when the invoice reached the accepted
state. This prevents hold htlcs from being cancelled after a restart.
But unfortunately this also caused additional htlcs to be accepted on an
already accepted invoice without their expiry being checked.

In this commit, the invoice registry starts to persistently track htlcs
so that replays can be recognized. For replays, an htlc resolution
action is returned early. This fixes both limitations mentioned above.
2019-09-04 19:20:31 +02:00
Joost Jager
53eea09b63
channeldb: add now function
Needed for time control in unit tests.
2019-09-04 19:20:29 +02:00
Joost Jager
416bc8c68c
channeldb+invoices: move hold invoice settle logic into registry
This commit is a continuation of the centralization of invoice state
transition logic in the invoice registry.
2019-09-04 19:20:23 +02:00
Joost Jager
ad3522f1a6
channeldb+invoices: move invoice accept or settle logic into registry
As the logic around invoice mutations gets more complex, the friction
caused by having this logic split between invoice registry and channeldb
becomes more apparent. This commit brings a clearer separation of
concerns by centralizing the accept/settle logic in the invoice
registry.

The original AcceptOrSettle method is renamed to UpdateInvoice because
the update to perform is controlled by the callback.
2019-09-04 19:20:21 +02:00
Joost Jager
4105142c96
channeldb+invoices: add invoice htlcs
This commit adds a set of htlcs to the Invoice struct and
serializes/deserializes this set to/from disk. It is a preparation for
accurate invoice accounting across restarts of lnd.

A migration is added for the invoice htlcs.

In addition to these changes, separate final cltv delta and expiry
invoice fields are created and populated. Previously it was required
to decode this from the stored payment request. The reason to create
a combined commit is to prevent multiple migrations.
2019-09-04 19:20:17 +02:00
Joost Jager
18c025151a
invoices+channeldb: move invoice state check to invoiceregistry 2019-06-10 16:12:08 +02:00
Joost Jager
064e8492de
cnct+htlcswitch+invoices: move invoice parameter check out of link
This commit is the final step in making the link unaware of invoices. It
now purely offers the htlc to the invoice registry and follows
instructions from the invoice registry about how and when to respond to
the htlc.

The change also fixes a bug where upon restart, hodl htlcs were
subjected to the invoice minimum cltv delta requirement again. If the
block height has increased in the mean while, the htlc would be canceled
back.

Furthermore the invoice registry interaction is aligned between link and
contract resolvers.
2019-05-15 14:42:12 +02:00
Joost Jager
32f2b047e8
htlcswitch: hodl invoice
This commit modifies the invoice registry to handle invoices for which
the preimage is not known yet (hodl invoices). In that case, the
resolution channel passed in from links and resolvers is stored until we
either learn the preimage or want to cancel the htlc.
2019-03-15 10:09:17 +01:00
Joost Jager
19f79613df
channeldb: store hold invoice 2019-03-15 10:08:55 +01:00
Joost Jager
436dd41c77
channeldb: move idempotency up the call tree
As a preparation for subscribing to single invoices, InvoiceRegistry
needs to become aware of settling a settled invoice.
2019-02-01 09:42:56 +01:00