Implement pending claim rebroadcast on force-closed channels
This attempts to rebroadcast/fee-bump each pending claim a monitor is
tracking for a force-closed channel. This is crucial in preventing
certain classes of pinning attacks and ensures reliability if
broadcasting fails. For implementations of `FeeEstimator` that also
support mempool fee estimation, we may broadcast a fee-bumped claim
instead, ensuring we can also react to mempool fee spikes between
blocks.
Extend OnchainTxHandler::generate_claim to optionally force feerate bump
In the next commit, we plan to extend the `OnchainTxHandler` to retry
pending claims on a timer. This timer may fire with much more frequency
than incoming blocks, so we want to avoid manually bumping feerates
(currently by 25%) each time our fee estimator provides a lower feerate
than before.
Elias Rohrer [Fri, 21 Apr 2023 16:02:54 +0000 (18:02 +0200)]
Allow events processing without holding `total_consistency_lock`
Unfortunately, the RAII types used by `RwLock` are not `Send`, which is
why they can't be held over `await` boundaries. In order to allow
asynchronous events processing in multi-threaded environments, we here
allow to process events without holding the `total_consistency_lock`.
To match the local signatures found in test vectors, we must make sure
we don't use any additional randomess when generating signatures, as
we'll arrive at a different signature otherwise.
Generate local signatures with additional randomness
Previously, our local signatures would always be deterministic, whether
we'd grind for low R value signatures or not. For peers supporting
SegWit, Bitcoin Core will generally use a transaction's witness-txid, as
opposed to its txid, to advertise transactions. Therefore, to ensure a
transaction has the best chance to propagate across node mempools in the
network, each of its broadcast attempts should have a unique/distinct
witness-txid, which we can achieve by introducing random nonce data when
generating local signatures, such that they are no longer deterministic.
For offers where the signing pubkey is derived, the keys need to be
extracted from the Offer::metadata in order to sign an invoice.
Parameterize InvoiceBuilder such that a build_and_sign method is
available for this situation.
Jeffrey Czyz [Mon, 6 Feb 2023 21:30:44 +0000 (15:30 -0600)]
Stateless verification of Invoice for Refund
Stateless verification of Invoice for Offer
Verify that an Invoice was produced from a Refund constructed by the
payer using the payer metadata reflected in the Invoice. The payer
metadata consists of a 128-bit encrypted nonce and possibly a 256-bit
HMAC over the nonce and Refund TLV records (excluding the payer id)
using an ExpandedKey.
Thus, the HMAC can be reproduced from the refund bytes using the nonce
and the original ExpandedKey, and then checked against the metadata. If
metadata does not contain an HMAC, then the reproduced HMAC was used to
form the signing keys, and thus can be checked against the payer id.
Jeffrey Czyz [Mon, 6 Feb 2023 21:10:07 +0000 (15:10 -0600)]
Refund metadata and payer id derivation
Add support for deriving a transient payer id for each Refund from an
ExpandedKey and a nonce. This facilitates payer privacy by not tying any
Refund to any other nor to the payer's node id.
Additionally, support stateless Invoice verification by setting payer
metadata using an HMAC over the nonce and the remaining TLV records,
which will be later verified when receiving an Invoice response.
Jeffrey Czyz [Mon, 30 Jan 2023 20:57:43 +0000 (14:57 -0600)]
Stateless verification of Invoice for Offer
Verify that an Invoice was produced from an InvoiceRequest constructed
by the payer using the payer metadata reflected in the Invoice. The
payer metadata consists of a 128-bit encrypted nonce and possibly a
256-bit HMAC over the nonce and InvoiceRequest TLV records (excluding
the payer id) using an ExpandedKey.
Thus, the HMAC can be reproduced from the invoice request bytes using
the nonce and the original ExpandedKey, and then checked against the
metadata. If metadata does not contain an HMAC, then the reproduced HMAC
was used to form the signing keys, and thus can be checked against the
payer id.
Jeffrey Czyz [Mon, 30 Jan 2023 20:56:42 +0000 (14:56 -0600)]
InvoiceRequest metadata and payer id derivation
Add support for deriving a transient payer id for each InvoiceRequest
from an ExpandedKey and a nonce. This facilitates payer privacy by not
tying any InvoiceRequest to any other nor to the payer's node id.
Additionally, support stateless Invoice verification by setting payer
metadata using an HMAC over the nonce and the remaining TLV records,
which will be later verified when receiving an Invoice response.
Jeffrey Czyz [Fri, 10 Mar 2023 23:12:12 +0000 (17:12 -0600)]
Refactor InvoiceRequestContents fields into a sub-struct
InvoiceRequestBuilder has a field containing InvoiceRequestContents.
When deriving the payer_id from the remaining fields, a struct is needed
without payer_id as it not optional. Refactor InvoiceRequestContents to
have an inner struct without the payer_id such that
InvoiceRequestBuilder can use it instead.
Jeffrey Czyz [Wed, 8 Feb 2023 01:15:44 +0000 (19:15 -0600)]
Stateless verification of InvoiceRequest
Verify that an InvoiceRequest was produced from an Offer constructed by
the recipient using the Offer metadata reflected in the InvoiceRequest.
The Offer metadata consists of a 128-bit encrypted nonce and possibly a
256-bit HMAC over the nonce and Offer TLV records (excluding the signing
pubkey) using an ExpandedKey.
Thus, the HMAC can be reproduced from the offer bytes using the nonce
and the original ExpandedKey, and then checked against the metadata. If
metadata does not contain an HMAC, then the reproduced HMAC was used to
form the signing keys, and thus can be checked against the signing
pubkey.
Jeffrey Czyz [Wed, 25 Jan 2023 17:34:43 +0000 (11:34 -0600)]
TlvStream range iterator
Add an iterator that yields TlvRecords over a range of a TlvStream.
Useful for verifying that, e.g., an InvoiceRequest was sent in response
to an Offer constructed by the intended recipient.
Jeffrey Czyz [Wed, 8 Feb 2023 01:13:08 +0000 (19:13 -0600)]
Offer metadata and signing pubkey derivation
Add support for deriving a transient signing pubkey for each Offer from
an ExpandedKey and a nonce. This facilitates recipient privacy by not
tying any Offer to any other nor to the recipient's node id.
Additionally, support stateless Offer verification by setting its
metadata using an HMAC over the nonce and the remaining TLV records,
which will be later verified when receiving an InvoiceRequest.
Now that we leverage a package's `height_timer` even for untractable
packages, there's no need to have it be an `Option` anymore. We aim to
not break compatibility by keeping the deserialization of such as an
`option`, and use the package's `height_original` when not present. This
allows us to retry packages from older `ChannelMonitor` versions that
have had a failed initial package broadcast.
Use existing height timer to retry untractable packages
Untractable packages are those which cannot have their fees updated once
signed, hence why they weren't retried. There's no harm in retrying
these packages by simply re-broadcasting them though, as the fee market
could have spontaneously spiked when we first broadcast it, leading to
our transaction not propagating throughout node mempools unless
broadcast manually.
Matt Corallo [Fri, 7 Apr 2023 20:48:01 +0000 (20:48 +0000)]
Expose the `RecipientOnionFields` in `Event::PaymentClaimable`
This finally completes the piping of the `payment_metadata` from
from the BOLT11 invoice on the sending side all the way through the
onion sending + receiving ends to the user on the receive events.
Matt Corallo [Fri, 7 Apr 2023 20:43:54 +0000 (20:43 +0000)]
Pipe received `payment_metadata` through the HTLC receipt pipeline
When we receive an HTLC, we want to pass the `payment_metadata`
through to the `PaymentClaimable` event. This does most of the
internal refactoring required to do so - storing a
`RecipientOnionFields` in the inbound HTLC tracking structs,
including the `payment_metadata`.
In the future this struct will allow us to do MPP keysend receipts
(as it now stores an Optional `payment_secret` for all inbound
payments) as well as custom TLV receipts (as the struct is
extensible to store additional fields and the internal API supports
filtering for fields which are consistent across HTLCs).
Matt Corallo [Fri, 7 Apr 2023 20:41:53 +0000 (20:41 +0000)]
`continue` automatically after `fail_htlc` in receiving an HTLC
If we receive an HTLC and are processing it a potential MPP part,
we always continue in the per-HTLC loop if we call the `fail_htlc`
macro, thus its nice to actually do the `continue` therein rather
than at the callsites.
Matt Corallo [Wed, 19 Apr 2023 14:51:45 +0000 (14:51 +0000)]
Add a debug_assert the newly-documented (but existing) requirement
If we add an entry to `claimable_payments` we have to ensure we
actually accept the HTLC we're considering, otherwise we'll end up
with an empty `claimable_payments` entry.
Matt Corallo [Fri, 24 Mar 2023 01:31:14 +0000 (01:31 +0000)]
Add a `payment_metadata` field to `RecipientOnionFields`
This adds the new `payment_metadata` to `RecipientOnionFields`,
passing the metadata from BOLT11 invoices through the send pipeline
and finally copying them info the onion when sending HTLCs.
This completes send-side support for the new payment metadata
feature.
Matt Corallo [Tue, 21 Dec 2021 06:03:07 +0000 (06:03 +0000)]
Support setting the new payment metadata field in invoices
This adds support for setting the new payment metadata field in
BOLT11 invoices, using a new type flag on the builder to enforce
transition correctness.
We allow users to set the payment metadata as either optional or
required, defaulting to optional so that invoice parsing does not
fail if the sender does not support payment metadata fields.
Matt Corallo [Tue, 21 Dec 2021 05:25:18 +0000 (05:25 +0000)]
Support reading the new `payment_metadata` field in invoices
This adds support for reading the new `PaymentMetadata` BOLT11
invoice field, giving us access to the `Vec<u8>` storing arbitrary
bytes we have to send to the recipient.
Jeffrey Czyz [Tue, 7 Feb 2023 21:25:36 +0000 (15:25 -0600)]
Add another ExpandedKey derivation for Offers
To support transient signing pubkeys and payer ids for Offers, add
another key derivation to ExpandedKey. Also useful for constructing
metadata for stateless message authentication.
Jeffrey Czyz [Thu, 2 Feb 2023 23:13:09 +0000 (17:13 -0600)]
Common offers test_utils module
Move utility functions used across all offers modules into a common
module. Avoids duplicating larger utilities such as payment_path across
more than one module.
Matt Corallo [Mon, 17 Apr 2023 23:09:11 +0000 (23:09 +0000)]
Only disable channels ~10 min after disconnect, rather than one
We correctly send out a gossip channel disable update after one
full time tick being down (1-2 minutes). This is pretty nice in
that it avoids nodes trying to route through our nodes too often
if they're down. Other nodes have a much longer time window,
causing them to have much less aggressive channel disables. Sadly,
at one minute it's not super uncommon for tor nodes to get disabled
(once a day or so on two nodes I looked at), and this causes the
lightning terminal scorer to consider the LDK node unstable (even
though it's the one doing the disabling - so is online). This
causes user frustration and makes LDK look bad (even though it's
probably failing fewer payments).
Given this, and future switches to block-based `channel_update`
timestamp fields, it makes sense to go ahead and switch to delaying
channel disable announcements for 10 minutes. This puts us more in
line with other implementations and reduces gossip spam, at the
cost of less reliable payments.
Fixes #2175, at least the currently visible parts.
Matt Corallo [Mon, 17 Apr 2023 22:59:18 +0000 (22:59 +0000)]
Set `channel_update` disable bit based on staged even for onions
When generating a `channel_update` either in response to a fee
configuration change or an HTLC failure, we currently poll the
channel to check if the peer's connected when setting the disabled
bit in the `channel_update`. This could cause cases where we set
the disable bit even though the peer *just* disconnected, and don't
generate a followup broadcast `channel_update` with the disabled
bit unset.
While a node generally shouldn't rebroadcast a `channel_update` it
received in an onion, there's nothing inherently stopping them from
doing so. Obviously in the fee-update case we expect the message to
propagate.
Luckily, since we already "stage" disable-changed updates, we can
check the staged state and use that to set the disabled bit in all
`channel_update` cases.
At times, PRs can go through multiple pushes in a short amount of time,
spawning a workflow run for each. Most of the time, there's no need to
let the previous jobs running if the code itself has changed (e.g., via
a force push), and we'd benefit from having those slots be used by other
PRs/branches instead.
Matt Corallo [Sun, 16 Apr 2023 21:57:20 +0000 (21:57 +0000)]
Fix deserialization of u16 arrays
u16 arrays are used in the historical liquidity range tracker.
Previously, we read them without applying the stride multiple,
reading bytes repeatedly and at an offset, corrupting data as we
go.
This applies the correct stride multiplayer fixing the issue.
Matt Corallo [Fri, 17 Mar 2023 20:50:19 +0000 (20:50 +0000)]
Introduce traits to make test utils generic across the `CM` Holder
In our test utilities, we generally refer to a `Node` struct which
holds a `ChannelManager` and a number of other structs. However, we
use the same utilities in benchmarking, where we have a different
`Node`-like struct. This made moving from macros to functions
entirely impossible, as we end up needing multiple types in a given
context.
Thus, here, we take the pain and introduce some wrapper traits
which encapsulte what we need from `Node`, swapping some of our
macros to functions.
Matt Corallo [Sun, 9 Apr 2023 01:43:39 +0000 (01:43 +0000)]
Remove a race-y debug assertion in new channel update handling
In 6090d9e6a862a2010eb80be56b7449947bc08374 we swapped out old
debug assertions that checked that a lock was `try_lock`able to
test that certain locks weren't held when we needed to be able to
take them in some near branch. However, another slipped in after in
the `ChannelMonitorUpdate` handling rework, which is replaced with
the new debug assertions here.