Matt Corallo [Thu, 8 Sep 2022 21:04:11 +0000 (21:04 +0000)]
Stop relying on the `*Features::known` method in `routing` tests
As we move towards specify supported/required feature bits in the
module(s) where they are supported, the global `known` feature set
constructors no longer make sense.
Here we stop relying on the `known` method in the `routing` module,
which was only used in tests.
Matt Corallo [Mon, 12 Sep 2022 17:47:16 +0000 (17:47 +0000)]
List supported/required feature bits explicitly in ChannelManager
Historically, LDK has considered the "set of known/supported
feature bits" to be an LDK-level thing. Increasingly this doesn't
make sense - different message handlers may provide or require
different feature sets.
In a previous PR, we began the process of transitioning with
feature bits sent to peers being sourced from the attached message
handler.
This commit makes further progress by moving the concept of which
feature bits are supported by our ChannelManager into
channelmanager.rs itself, via the new `provided_*_features`
methods, rather than in features.rs via the `known_channel_features`
and `known` methods.
Wilmer Paulino [Fri, 26 Aug 2022 19:56:09 +0000 (12:56 -0700)]
Update anchors test vectors to zero HTLC transaction fee variant
Each test featuring HTLCs had a minimum and maximum feerate case. This
is no longer necessary for the zero HTLC transaction anchors variant as
the commitment feerate does not impact whether HTLCs can be trimmed or
not, only the dust limit does.
Wilmer Paulino [Mon, 29 Aug 2022 19:34:34 +0000 (12:34 -0700)]
Account for zero fee HTLC transaction within dust limit calculation
With the zero fee HTLC transaction anchors variant, HTLCs can no longer
be trimmed due to their amount being too low to have a mempool valid
HTLC transaction. Now they can only be trimmed based on the dust limit
of each party within the channel.
Wilmer Paulino [Thu, 25 Aug 2022 20:36:17 +0000 (13:36 -0700)]
Exclude HTLC transactions from broadcast on anchor channels
HTLC transactions from anchor channels are constrained by a CSV of 1
block, so broadcasting them along with the unconfirmed commitment
tranasction will result in them being immediately rejected as premature.
Wilmer Paulino [Thu, 25 Aug 2022 20:11:19 +0000 (13:11 -0700)]
Avoid commitment broadcast upon detected funding spend
There's no need to broadcast our local commitment transaction if we've
already seen a confirmed one as it'll be immediately rejected as a
duplicate/conflict.
This will also help prevent dispatching spurious events for bumping
commitment and HTLC transactions through anchor outputs (once
implemented in future work) and the dispatch for said events follows the
same flow as our usual commitment broadcast.
Expand the BlockSource trait to allow filtered blocks now that
chain::Listen supports them (d629a7edb7241eee7fde9f5ccdf1c481d2d6297b).
This makes it possible to use BIP 157/158 compact block filters with
lightning-block-sync.
Matt Corallo [Mon, 12 Sep 2022 19:06:17 +0000 (19:06 +0000)]
Move checking of specific require peer feature bits to handlers
As we remove the concept of a global "known/supported" feature set
in LDK, we should also remove the concept of a global "required"
feature set. This does so by moving the checks for specific
required features into handlers.
Specifically, it allows the handler `peer_connected` method to
return an `Err` if the peer should be disconnected. Only one such
required feature bit is currently set - `static_remote_key`, which
is required in `ChannelManager`.
Matt Corallo [Mon, 12 Sep 2022 19:34:59 +0000 (19:34 +0000)]
Swap some `peer_connected` features to `known` from `empty` in test
In the next commit we'll enforce counterparty `InitFeatures`
matching our required set in `ChannelManager`, implying they must
be set for many tests where they previously did not need to be (as
they were enforced in `PeerManager`, which is not used in
functional tests).
Matt Corallo [Wed, 7 Sep 2022 21:08:22 +0000 (21:08 +0000)]
Correctly handle BADONION onion errors
Currently we entirely ignore the BADONION bit when deciding how to
handle HTLC failures. This opens us up to an attack where a
malicious node always fails HTLCs backwards via
`update_fail_malformed_htlc` with an error code of
`BADONION|NODE|PERM|X`. In this case, we may decide to interpret
this as a permanent node failure for the node encrypting the onion,
i.e. the counterparty of the node who sent the
`update_fail_malformed_htlc` message and ultimately failed the
HTLC.
Thus, any node we route through could cause us to fully remove its
counterparty from our network graph. Luckily we do not do any
persistent tracking of removed nodes, and thus will re-add the
removed node once it is re-announced or on restart, however we are
likely to add such persistent tracking (at least in-memory) in the
future.
Matt Corallo [Mon, 12 Sep 2022 15:20:37 +0000 (15:20 +0000)]
Encrypt+MAC most P2P messages in-place
For non-gossip-broadcast messages, our current flow is to first
serialize the message into a `Vec`, and then allocate a new `Vec`
into which we write the encrypted+MAC'd message and header.
This is somewhat wasteful, and its rather simple to instead
allocate only one buffer and encrypt the message in-place.
Matt Corallo [Mon, 12 Sep 2022 15:16:41 +0000 (15:16 +0000)]
Fix encryption of broadcasted gossip messages
In 47e818f198abafba01b9ad278582886f9007dac2, forwarding broadcasted
gossip messages was split into a separate per-peer message buffer.
However, both it and the original regular-message queue are
encrypted immediately when the messages are enqueued. Because the
lightning P2P encryption algorithm is order-dependent, this causes
messages to fail their MAC checks as the messages from the two
queues may not be sent to peers in the order in which they were
encrypted.
The fix is to simply queue broadcast gossip messages unencrypted,
encrypting them when we add them to the regular outbound buffer.
Matt Corallo [Sun, 11 Sep 2022 21:18:01 +0000 (21:18 +0000)]
Drop unused type parameter on `BlindedRoute::new`
I'm not sure why rustc didn't complain about the unused parameter
or why we're allowed to get away without explicitly bounding the
`Sign` in the `KeysInterface`, but the current code requires all
`BlindedPath` construction to explicitly turbofish an unused type.
Matt Corallo [Sat, 10 Sep 2022 20:31:52 +0000 (20:31 +0000)]
Inline generic bounds rather than using the `where` clause
The bindings generator is pretty naive in its generic resolution
and doesn't like `where` clauses for bounds that are simple traits.
This should eventually change, but for now its simplest to just
inline the relevant generic bounds.
Matt Corallo [Sat, 10 Sep 2022 20:31:42 +0000 (20:31 +0000)]
Do not use blanket impls when building for `c_bindings`
The C bindings generator isn't capable of figuring out if a blanket
impl applies in a given context, and instead opts to always write
out any relevant impl's for a trait. Thus, blanket impls should be
disabled when building with `#[cfg(c_bindings)]`.
OR InitFeatures and NodeFeatures from onion message handler
Similar to how we OR our InitFeaures and NodeFeatures across both our channel
and routing message handlers, we also want to OR the features of our onion
message handler.
Add a new NodeFeatures constructor to capture the types of flags
When ChannelMessageHandler implementations wish to return a NodeFeatures which
contain all the known flags that are relevant to channel handling, but not
gossip handling, they currently need to do so by manually constructing a
NodeFeatures with all known flags and then clearing the ones they don't want.
Instead of spreading this logic across the codebase, this consolidates such
construction into one place in features.rs.
OR NodeFeatures from both Channel and Routing message handlers
When we broadcast a node announcement, the features we support are really a
combination of all the various features our different handlers support. This
commit captures this concept by OR'ing our NodeFeatures across both our channel
and routing message handlers.
Matt Corallo [Fri, 9 Sep 2022 19:30:30 +0000 (19:30 +0000)]
Correct `get_claimable_balance` version info
5a8ede09fb3c8bbcd8694d94c12dac9ea7485537 updated the documentation
on `get_claimable_balance` to note that if a channel went on-chain
with an LDK version older than 0.0.108 some
counterparty-revoked-output claimable balances my be missing.
However, this failed to account for the fact that we rely on the
entirely-new-in-0.0.111
`confirmed_commitment_tx_counterparty_output` field for some
balances as well.
Thus, the comment should have been in terms of 0.0.111, not
0.0.108.
Matt Corallo [Mon, 29 Aug 2022 18:42:34 +0000 (18:42 +0000)]
Fix spurious panic on receipt of a block while awaiting funding
When we receive a block we always test if we should send our
channel_ready via `check_get_channel_ready`. If the channel in
question requires confirmations, we quickly return if the funding
transaction has not yet confirmed (or even been defined), however
for 0conf channels the checks are necessarily more involved.
In any case, we wish to panic if the funding transaction has
confirmations prior to when it should have been broadcasted. This
is useful as it is easy for users to violate our broadcast-time
invariants without noticing and the panic gives us an opportunity
to catch it.
Sadly, in the case of 0conf channels, if we hadn't yet seen the
funding transaction at all but receive a block we would hit this
sanity check as we don't check whether there are actually funding
transaction confirmations prior to panicing.
Matt Corallo [Wed, 7 Sep 2022 17:55:01 +0000 (17:55 +0000)]
Add a new InitFeatures constructor to capture the types of flags
When `ChannelMessageHandler` implementations wish to return an
`InitFeatures` which contain all the known flags that are relevant
to channel handling, but not gossip handling, they currently need
to do so by manually constructing an InitFeatures with all known
flags and then clearing the ones they dont want.
Instead of spreading this logic out across the codebase, this
consolidates such construction to one place in features.rs.
Matt Corallo [Wed, 7 Sep 2022 17:35:50 +0000 (17:35 +0000)]
OR InitFeatures from both Channel and Routing message handlers
When we go to send an Init message to new peers, the features we
support are really a combination of all the various features our
different handlers support. This commit captures this concept by
OR'ing our InitFeatures across both our Channel and Routing
handlers.
Note that this also disables setting the `initial_routing_sync`
flag in init messages, as was intended in e742894492c55802b241eebc585bbd28aa16481b, per the comment added on
`clear_initial_routing_sync`, though this should not be a behavior
change in practice as nodes which support gossip queries ignore the
initial routing sync flag.
Matt Corallo [Wed, 7 Sep 2022 17:51:16 +0000 (17:51 +0000)]
Fetch our `InitFeatures` from `ChannelMessageHandler`
Like we now do for `NodeFeatures`, this converts to asking our
registered `ChannelMessageHandler` for our `InitFeatures` instead
of hard-coding them to the global LDK known set.
This allows handlers to set different feature bits based on what
our configuration actually supports rather than what LDK supports
in aggregate.
Matt Corallo [Tue, 6 Sep 2022 22:34:29 +0000 (22:34 +0000)]
Move `broadcast_node_announcement` to `PeerManager`
Some `NodeFeatures` will, in the future, represent features which
are not enabled by the `ChannelManager`, but by other message
handlers handlers. Thus, it doesn't make sense to determine the
node feature bits in the `ChannelManager`.
The simplest fix for this is to change to generating the
node_announcement in `PeerManager`, asking all the connected
handlers which feature bits they support and simply OR'ing them
together. While this may not be sufficient in the future as it
doesn't consider feature bit dependencies, support for those could
be handled at the feature level in the future.
This commit moves the `broadcast_node_announcement` function to
`PeerHandler` but does not yet implement feature OR'ing.
Matt Corallo [Tue, 6 Sep 2022 21:30:33 +0000 (21:30 +0000)]
Send channel_{announcement,update} msgs on connection, not timer
When we connect to a new peer, immediately send them any
channel_announcement and channel_update messages for any public
channels we have with other peers. This allows us to stop sending
those messages on a timer when they have not changed and ensures
we are sending messages when we have peers connected, rather than
broadcasting at startup when we have no peers connected.
Matt Corallo [Wed, 7 Sep 2022 21:39:17 +0000 (21:39 +0000)]
Dont use PaymentPathFailed a probe fails without making it out
When we fail to forward a probe HTLC at all and immediately fail it
(e.g. due to the first hop channel closing) we'd previously
spuriously generate only a `PaymentPathFailed` event. This violates
the expected API, as users expect a `ProbeFailed` event instead.
This fixes the oversight by ensuring we generate the correct event.
Matt Corallo [Wed, 7 Sep 2022 21:09:50 +0000 (21:09 +0000)]
Drop redundant code in `fail_holding_cell_htlcs`
`fail_holding_cell_htlcs` calls through to
`fail_htlc_backwards_internal` for HTLCs that need to be
failed-backwards but opts to generate its own payment failure
events for `HTLCSource:;OutboundRoute` HTLCs. There is no reason
for that as `fail_htlc_backwards_internal` will also happily
generate (now-)equivalent events for `HTLCSource::OutboundRoute`
HTLCs.
Thus, we can drop the redundant code and always call
`fail_htlc_backwards_internal` for each HTLC in
`fail_holding_cell_htlcs`.
Matt Corallo [Tue, 6 Sep 2022 22:51:29 +0000 (22:51 +0000)]
Add missing deserialization of Event::HTLCHandlingFailed
17e6c374c513f2eca810fa4e931be65f0d4fc29f added the
`HTLCHandlingFailed` event, including serialization thereof,
however failed to add corresponding deserialization. This corrects
that oversight by adding said deserialization.
The `rejected_by_dest` field of the `PaymentPathFailed` event has
always been a bit of a misnomer, as its really more about retry
than where a payment failed. Now is as good a time as any to
rename it.
Matt Corallo [Wed, 7 Sep 2022 20:02:04 +0000 (20:02 +0000)]
Mark failed counterparty-is-destination HTLCs retryable
When our counterparty is the payment destination and we receive
an `HTLCFailReason::Reason` in `fail_htlc_backwards_internal` we
currently always set `rejected_by_dest` in the `PaymentPathFailed`
event, implying the HTLC should *not* be retried.
There are a number of cases where we use `HTLCFailReason::Reason`,
but most should reasonably be treated as retryable even if our
counterparty was the destination (i.e. `!rejected_by_dest`):
* If an HTLC times out on-chain, this doesn't imply that the
payment is no longer retryable, though the peer may well be
offline so retrying may not be very useful,
* If a commitment transaction "containing" a dust HTLC is
confirmed on-chain, this definitely does not imply the payment
is no longer retryable
* If the channel we intended to relay over was closed (or
force-closed) we should retry over another path,
* If the channel we intended to relay over did not have enough
capacity we should retry over another path,
* If we received a update_fail_malformed_htlc message from our
peer, we likely should *not* retry, however this should be
exceedingly rare, and appears to nearly never appear in practice
Thus, this commit simply disables the behavior here, opting to
treat all `HTLCFailReason::Reason` errors as retryable.
Note that prior to 93e645daf46f85949ae0edf60d36bf21e9fde8af this
change would not have made sense as it would have resulted in us
retrying the payment over the same channel in some cases, however
we now "blame" our own channel and will avoid it when routing for
the same payment.
Matt Corallo [Tue, 6 Sep 2022 20:56:24 +0000 (20:56 +0000)]
Clarify and consolidate event handling requirements
We've seen a bit of user confusion about the requirements for event
handling, largely because the idempotency and consistency
requirements weren't super clearly phrased. While we're at it, we
also consolidate some documentation out of the event handling
function onto the trait itself.
Matt Corallo [Fri, 2 Sep 2022 21:10:43 +0000 (21:10 +0000)]
Correct payment resolution after on chain failure of dust HTLCs
Previously, we wouldn't mark a dust HTLC as permanently resolved if
the commitment transaction went on chain. This resulted in us
always considering the HTLC as pending on restart, when we load the
pending payments set from the monitors.
Matt Corallo [Mon, 5 Sep 2022 16:28:11 +0000 (16:28 +0000)]
Ensure we log private channel_updates at a non-GOSSIP log level
If we receive a channel_update for one of our private channels, we
will not log the message at the usual TRACE log level as the
message falls into the gossip range. However, for our own channels
they aren't *just* gossip, as we store that info and it changes
how we generate invoices. Thus, we add a log in `ChannelManager`
here at the DEBUG log level.
Matt Corallo [Tue, 9 Aug 2022 04:15:21 +0000 (04:15 +0000)]
Add a `Future` which can receive manager persistence events
This allows users who don't wish to block a full thread to receive
persistence events.
The `Future` added here is really just a trivial list of callbacks,
but from that we can build a (somewhat ineffecient)
std::future::Future implementation and can (at least once a mapping
for Box<dyn Trait> is added) include the future in no-std bindings
as well.
Matt Corallo [Fri, 2 Sep 2022 21:57:32 +0000 (21:57 +0000)]
Handle monotonic clock going backwards during runtime
We've had some users complain that `duration_since` is panic'ing
for them. This is possible if the machine being run on is buggy and
the "monotonic clock" goes backwards, which sadly some ancient
systems can do.
Rust addressed this issue in 1.60 by forcing
`Instant::duration_since` to not panic if the machine is buggy
(and time goes backwards), but for users on older rust versions we
do the same by hand here.
jurvis [Sun, 28 Aug 2022 06:07:50 +0000 (23:07 -0700)]
Make payment tests more realistic
Made sure that every hop has a unique receipient. When we simulate
calling `channel_penalty_msat` in `TestRouter`’s find route, use
actual previous node ids instead of just using the payer’s.