Jeffrey Czyz [Fri, 4 Mar 2022 07:59:44 +0000 (23:59 -0800)]
Check for no-std compatibility across dependencies
To ensure no-std is honored across dependencies, add a crate depending
on lightning crates supporting no-std. This should ensure any
regressions are caught. Otherwise, cargo doesn't seem to catch some
incompatibilities (e.g., f64::log10 unavailable in core) and seemingly
across other dependencies as describe here:
Matt Corallo [Fri, 4 Mar 2022 21:31:55 +0000 (21:31 +0000)]
Clean up `TestKeysInterface` random bytes override interface
Its very confusing to have multiple fields that do the same thing,
one of which isn't even used for its stated purpose anymore after
the previous few commits.
Matt Corallo [Wed, 16 Feb 2022 05:36:54 +0000 (05:36 +0000)]
Fix what `bolt2_open_channel_sending_node_checks_part1` tests
There are currently two issues with
`bolt2_open_channel_sending_node_checks_part1` which counteract
each other and hide that the test isn't testing what it should be.
First of all, the final `create_channel` call actually fails
because we try to open a channel with ourselves, instead of
panicing as the test is supposed to check for.
However, when we fix the create_channel call to panic, when we
drop `nodes[1]` after `create_channel` panics, we fail the
no-pending-messages test as it as an expeted `accept_channel` in
its outbound buffer. This causes a double-panic.
Previously, these two offset each other - instead of panicing in
`create_channel` we'd panic in the Node drop checks.
This fixes both by fetching the `accept_channel` before we go into
the panic'ing `create_channel` call (who's arguments were
corrected).
Matt Corallo [Fri, 25 Feb 2022 05:18:29 +0000 (05:18 +0000)]
Ensure `get_claimable_balances` never panicks in tests
... by calling it both before and after every chain event in
testing and fuzzing.
This requires fixing some blockchain inconsistencies in
`do_test_onchain_htlc_reorg`, `do_retry_with_no_persist`, and
`do_test_dup_htlc_onchain_fails_on_reload` where we'd connect
conflicting transactions in the same chain.
Matt Corallo [Fri, 25 Feb 2022 05:14:00 +0000 (05:14 +0000)]
Fix HTLC tx balance calculation on local commitment transactions
When handling the broadcast of a local commitment transactions
(with associated CSV delays prior to spendability), we incorrectly
handled the CSV delays on HTLC transactions. This caused us to miss
spendable outputs for HTLCs which were awaiting a CSV delay.
Further, because of this, we could hit an assertion as
`get_claimable_balances` asserted that HTLCs were resolved after
the funding spend was resolved, which was not true if the HTLC did
not have a CSV delay attached (due to the above bug or due to it
being an HTLC claim by our counterparty).
This fixes both bugs, also converting some assertions to
`debug_assert`s to avoid future issues as balance mis-calculation
is not currently an indication of potential funds loss.
Matt Corallo [Thu, 10 Feb 2022 21:33:26 +0000 (21:33 +0000)]
Correct default value for A* heuristic for non-public nodes
This doesn't (appear) to change behavior, however if we have a
non-public node, we assign an A* heuristic of max-u32 fees, which
may result in us de-prioritizing the path in some rare cases around
multi-hop route hints which compete with public nodes.
Matt Corallo [Thu, 10 Feb 2022 21:29:43 +0000 (21:29 +0000)]
Fix panic when routing through multiple private last-hops
When we added support for routing through a multi-hop invoice hint
we failed to remove an assertion that we always are able to fill
in features for each hop except the last one. However, when a
multi-hop invoice hint is used, we will not have features for any
of the hinted hops, causing us to panic.
Fix bug where we encode flags field into all updates on htlc fail
Failing an HTLC with onion error channel_disabled requires encoding a 'flags' field into the failure
packet. However, we were encoding this 'flags' field for all failures packets that were failing on
update_add_htlc with an update (error 0x1000 UPDATE).
Discovered in the course of adding phantom payment failure tests, which also added testing for this bug
In any place where fail_htlc_backwards_internal was called for a phantom payment
failure, we weren't encoding the onion failure as if the phantom were the one
failing. Instead, we were encoding the failure as if it were coming from the
second-to-last hop. This caused our failures to not be parsed properly on the
payer's side.
Places we were encoding failures incorrectly include:
* on failure of a call to inbound_payment::verify
* on a user call to fail_htlc_backwards
Also drop some unnecessary panics when reading OnionHopData objects. This also
enables one of the phantom failure tests because we can construct OnionHopDatas
with invalid amounts.
This also fixes a bug where we were failing back phantom payments with the
wrong scid, causing them to never actually be failed backwards (L3022 in
channelmanager.rs)
This new field will be used in upcoming commit(s) to encrypt phantom payment failure
packets.
Matt Corallo [Wed, 23 Feb 2022 22:06:33 +0000 (22:06 +0000)]
Ignore .tmp files when loading ChannelMonitors in persister
If we are in the middle of persisting an update to a
`ChannelMonitor` when we shutdown (or crash), we'll start up with
a .tmp file lying around. We should ignore it, as failure to
return from the update call should have prevented the
`ChannelManager` from taking any irrevocable action based on the
update.
We're somewhat protected from any filesystem inconsistency behavior
as the `ChannelManager` will refuse to load if we're outright
missing `ChannelMonitor`s.
Jeffrey Czyz [Sat, 12 Feb 2022 04:14:06 +0000 (22:14 -0600)]
Unhide struct docs in scoring module
The docs were hidden since a type alias should be used. However, the
alias docs don't contain much useful information and don't link to the
corresponding struct.
Matt Corallo [Wed, 19 Jan 2022 03:52:56 +0000 (03:52 +0000)]
Fix a debug panic caused by receiving MPP parts after a failure
Prior to cryptographic payment secrets, when we process a received
payment in `process_pending_htlc_fowards` we'd remove its entry
from the `pending_inbound_payments` map and give the user a
`PaymentReceived` event.
Thereafter, if a second HTLC came in with the same payment hash, it
would find no entry in the `pending_inbound_payments` map and be
immediately failed in `process_pending_htlc_forwards`.
Thus, each HTLC will either result in a `PaymentReceived` event or
be failed, with no possibility for both.
As of 846487555556d8465c5b7b811f976e78f265c48f, we no longer
materially have a pending-inbound-payments map, and thus
more-than-happily accept a second payment with the same payment
hash even if we just failed a previous one for having mis-matched
payment data.
This can cause an issue if the two HTLCs are received back-to-back,
with the first being accepted as valid, generating a
`PaymentReceived` event. Then, when the second comes in we'll hit
the "total value {} ran over expected value" condition and fail
*all* pending HTLCs with the same payment hash. At this point,
we'll have a pending failure for both HTLCs, as well as a
`PaymentReceived` event for the user.
Thereafter, if the user attempts to fail the HTLC in response to
the `PaymentReceived`, they'll get a debug panic at channel.rs:1657
'Tried to fail an HTLC that was already failed'.
The solution is to avoid bulk-failing all pending HTLCs for a
payment. This feels like the right thing to do anyway - if a sender
accidentally sends an extra HTLC after a payment has ben fully
paid, we shouldn't fail the entire payment.
Matt Corallo [Wed, 16 Feb 2022 21:34:16 +0000 (21:34 +0000)]
Update channel-type implementation to upstream spec as merged
Somehow, our channel type implementation doesn't echo back the
channel type as we believe it was negotiated, as we should. Though
the spec doesn't explicitly require this, some implementations may
require it and it appears to have been in the BOLTs from the start
of the channel type logic.
Matt Corallo [Tue, 8 Feb 2022 21:28:11 +0000 (21:28 +0000)]
Bump MSRV to 1.41.1.
1.41.1 is currently the Firefox ESR MSRV, which means its also the
version several Linux distros ship. Further, rust-bitcoin is likely
to make a similar change soon, see
https://github.com/rust-bitcoin/rust-bitcoin/issues/510.
keysmanager: support phantom payments with PhantomKeysManager
To support the feature of generating invoices that can be paid to any of
multiple nodes, a key manager need to be able to share an inbound_payment_key
and phantom secret key. This is because a phantom payment may be received by
any node participating in the invoice, so all nodes must be able to decrypt the
phantom payment (and therefore must share decryption key(s)) in the act of
pretending to be the phantom node. Thus we add a new `PhantomKeysManager` that
supports these features.
To be more specific, the inbound payment key must be shared because it is used
to decrypt the payment details for verification (LDK avoids storing inbound
payment data by encrypting payment metadata in the payment hash and/or payment
secret).
The phantom secret must be shared because enables any real node included in the
phantom invoice to decrypt the final layer of the onion packet, since the onion
is encrypted by the sender using the phantom public key provided in the
invoice.
Add functional tests for manually responding to inbound channel requests.
Responding to inbound channel requests are required when the
`manually_accept_inbound_channels` config flag is set to true.
The tests cover the following cases:
* Accepting an inbound channel request
* Rejecting an inbound channel request
* FundingCreated message sent by the counterparty before accepting the
inbound channel request
* Attempting to accept an inbound channel request twice
* Attempting to accept an unkown inbound channel
Add a new config flag `UserConfig::manually_accept_inbound_channels`,
which when set to true allows the node operator to accept or reject new
channel requests.
When set to true, `Event::OpenChannelRequest` will be triggered once a
request to open a new inbound channel is received. When accepting the
request, `ChannelManager::accept_inbound_channel` should be called.
Rejecting the request is done through
`ChannelManager::force_close_channel`.
Matt Corallo [Thu, 10 Feb 2022 21:13:19 +0000 (21:13 +0000)]
Make router benchmarks more realistic by not running test-only code
`cargo bench` sets `cfg(test)`, causing us to hit some test-only
code in the router when benchmarking, throwing off our benchmarks
substantially. Here we swap from the `unstable` feature to a more
clearly internal feature (`_bench_unstable`) and also checking for
it when enabling test-only code.
Matt Corallo [Thu, 20 Jan 2022 04:28:38 +0000 (04:28 +0000)]
Include inbound-claimed-HTLCs in reported channel balances
Given the balance is reported as "total balance if we went to chain
ignoring fees", it seems reasonable to include claimed HTLCs - if
we went to chain we'd get those funds, less on-chain fees. Further,
if we do not include them, its possible to have pending outbound
holding-cell HTLCs underflow the balance calculation, causing a
panic in debug mode, and bogus values in release.
This resolves a subtraction underflow bug found by the
`chanmon_consistency` fuzz target.
Matt Corallo [Thu, 10 Feb 2022 21:11:59 +0000 (21:11 +0000)]
Work around rustc compilation regression on nightly
Apparently rustc doesn't (actually) provide any kind of
compilation-stability guarantees, despite their claims. Here we
work around rustc being unstable by making the trait call explicit.
See also https://github.com/rust-lang/rust/issues/93599
Jeffrey Czyz [Wed, 5 Jan 2022 00:15:59 +0000 (18:15 -0600)]
Decay channel liquidity balance offsets
ProbabilisticScorer uses successful and unsuccessful payments to gain
more certainty of a channel's liquidity balance. Decay this knowledge
over time to indicate decreasing certainty about the liquidity balance.
Jeffrey Czyz [Mon, 3 Jan 2022 14:35:19 +0000 (08:35 -0600)]
Probabilistic channel scoring
Add a Score implementation based on "Optimally Reliable & Cheap Payment
Flows on the Lightning Network" by Rene Pickhardt and Stefan Richter[1].
Given the uncertainty of channel liquidity balances, probability
distributions are defined based on knowledge learned from successful and
unsuccessful attempts. Then the negative log of the success probability
is used to determine the cost of routing a specific HTLC amount through
a channel.
Jeffrey Czyz [Wed, 29 Dec 2021 15:56:54 +0000 (09:56 -0600)]
Effective channel capacity for router and scoring
A channel's capacity may be inferred or learned and is used to make
routing decisions, including as a parameter to channel scoring. Define
an EffectiveCapacity for this purpose. Score::channel_penalty_msat takes
the effective capacity (less in-flight HTLCs for the same payment), and
never None. Thus, for hops given in an invoice, the effective capacity
is now considered (near) infinite if over a private channel or based on
learned information if over a public channel.
If a Score implementations needs the effective capacity when updating a
channel's score, i.e. in payment_path_failed or payment_path_successful,
it can access the channel's EffectiveCapacity via the NetworkGraph by
first looking up the channel and then specifying which direction is
desired using ChannelInfo::as_directed.
Matt Corallo [Tue, 1 Feb 2022 21:16:27 +0000 (21:16 +0000)]
Store override counterparty handshake limits until we enforce them
We currently allow users to provide an `override_config` in
`ChannelManager::create_channel` which it seems should apply to the
channel. However, because we don't store any of it, the only parts
which we apply to the channel are those which are set in the
`Channel` object immediately in `Channel::new_outbound` and used
from there.
This is great in most cases, however the
`UserConfig::peer_channel_config_limits` `ChannelHandshakeLimits`
object is used in `accept_channel` to bound what is acceptable in
our peer's `AcceptChannel` message. Thus, for outbound channels, we
are given a full `UserConfig` object to "override" the default
config, but we don't use any of the handshake limits specified in
it.
Here, we move to storing the `ChannelHandshakeLimits` explicitly
and applying it when we receive our peer's `AcceptChannel`. Note
that we don't need to store it anywhere because if we haven't
received an `AcceptChannel` from our peer when we reload from disk
we will forget the channel entirely anyway.
Matt Corallo [Tue, 7 Dec 2021 19:11:18 +0000 (19:11 +0000)]
Make `Channel::get_announcement_sigs` return an Option and log
Channel::get_announcement_sigs is only used in contexts where we
have a logger already, and the error returned is always ignored, so
instead of returning an ignored error message we return an `Option`
directly and log when it won't be too verbose.
Matt Corallo [Thu, 18 Nov 2021 21:54:13 +0000 (21:54 +0000)]
Disconect `announcement_signatures` sending from `funding_locked`
The spec actually requires we never send `announcement_signatures`
(and, thus, `channel_announcement`s) until after six confirmations.
However, we would happily have sent them prior to that as long as
we exchange `funding_locked` messages with our countarparty. Thanks
to re-broadcasting this issue is largely harmless, however it could
have some negative interactions with less-robust peers. Much more
importantly, this represents an important step towards supporting
0-conf channels, where `funding_locked` messages may be exchanged
before we even have an SCID to construct the messages with.
Because there is no ACK mechanism for `announcement_signatures` we
rely on existing channel updates to stop rebroadcasting them - if
we sent a `commitment_signed` after an `announcement_signatures`
and later receive a `revoke_and_ack`, we know our counterparty also
received our `announcement_signatures`. This may resolve some rare
edge-cases where we send a `funding_locked` which our counterparty
receives, but lose connection before the `announcement_signatures`
(usually the very next message) arrives.
Sadly, because the set of places where an `announcement_signatures`
may now be generated more closely mirrors where `funding_locked`
messages may be generated, but they are now separate, there is a
substantial amount of code motion providing relevant parameters
about current block information and ensuring we can return new
`announcement_signatures` messages.
Matt Corallo [Thu, 18 Nov 2021 21:54:10 +0000 (21:54 +0000)]
Unset `Channel::is_usable` if mon update is blocking funding_locked
If we have not yet sent `funding_locked` only because of a pending
channel monitor update, we shouldn't consider a channel
`is_usable`. This has a number of downstream effects, including
not attempting to route payments through the channel, not sending
private `channel_update` messages to our counterparty, or sending
channel_announcement messages if our couterparty has already signed
for it.
We further gate generation of `node_announcement`s on `is_usable`,
preventing generation of those or `announcement_signatures` until
we've sent our `funding_locked`.
Finally, `during_funding_monitor_fail` is updated to test a case
where we see the funding transaction lock in but have a pending
monitor update failure, then receive `funding_locked` from our
counterparty and ensure we don't generate the above messages until
after the monitor update completes.
Matt Corallo [Mon, 15 Nov 2021 01:09:27 +0000 (01:09 +0000)]
Do not Send FundingLocked messages while disconnected
While its generally harmless to do so (the messages will simply be
dropped in `PeerManager`) there is a potential race condition where
the FundingLocked message enters the outbound message queue, then
the peer reconnects, and then the FundingLocked message is
delivered prior to the normal ChannelReestablish flow.
We also take this opportunity to rewrite
`test_funding_peer_disconnect` to be explicit instead of using
`reconnect_peers`. This allows it to check each message being sent
carefully, whereas `reconnect_peers` is rather lazy and accepts
that sometimes signatures will be exchanged, and sometimes not.