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.
Jeffrey Czyz [Mon, 17 Jan 2022 03:07:57 +0000 (21:07 -0600)]
Benchmark router using a scorer seeded with data
Scorers may have different performance characteristics after seeing
failed and successful paths. Seed the scorer with some random data
before executing the benchmark in order to exercise such behavior.
Jeffrey Czyz [Sun, 16 Jan 2022 16:04:11 +0000 (10:04 -0600)]
Add first_hops to generate_routes benchmarks
Passing first_hops to get_route increases the coverage of the benchmark
test. For scorers needing the sending node, it allows for using a single
scorer in the benchmark rather than re-initializing on each iteration.
As a consequence, the scorer can be seeded with success and failure
data.
Jeffrey Czyz [Fri, 14 Jan 2022 18:28:30 +0000 (12:28 -0600)]
Remove duplicate generate_routes benchmark code
Refactor generate_routes and generate_mpp_routes into a single utility
for benchmarking. The utility is parameterized with features in order to
test both single path and multi-path routing. Additionally, it is
parameterized with a Score to be used with other scorers.
dependabot[bot] [Tue, 18 Jan 2022 22:05:49 +0000 (22:05 +0000)]
Update hex requirement from 0.3 to 0.4
Updates the requirements on [hex](https://github.com/KokaKiwi/rust-hex) to permit the latest version.
- [Release notes](https://github.com/KokaKiwi/rust-hex/releases)
- [Commits](https://github.com/KokaKiwi/rust-hex/compare/v0.3...v0.4.3)
Matt Corallo [Wed, 12 Jan 2022 19:58:08 +0000 (19:58 +0000)]
Make lockorder consistent in channelmanager
This resolves a lockorder inversion in
`ChannelManager::finalize_claims` where `pending_outbound_payments`
is locked after `pending_events`, opposite of, for example, the
lockorder in `ChannelManager::fail_htlc_backwards_internal` where
`pending_outbound_payments` is locked at the top of the
`HTLCSource::OutboundRoute` handling and then `pending_events` is
locked at the end.
Matt Corallo [Fri, 7 Jan 2022 20:11:31 +0000 (20:11 +0000)]
Rely on Error/Warning message data lengths being correct
In https://github.com/lightning/bolts/pull/950, the (somewhat
strange) requirement that error messages be handled even if the
length field is set larger than the size of the package was
removed. Here we change the code to drop the special handling for
this, opting to just fail to read the message if the length is
incorrect.
Matt Corallo [Thu, 30 Sep 2021 22:45:07 +0000 (22:45 +0000)]
Convert `shutdown` invalid script checks to warning messages
As required by the warning messages PR, we should simply warn our
counterparty in this case and let them try again, continuing to try
to use the channel until they tell us otherwise.
Matt Corallo [Sat, 18 Dec 2021 19:52:11 +0000 (19:52 +0000)]
Swap around generic argument ordering in InvoicePayer for bindings
The bindings generation really should support generic bounds other
than Deref::Target in where clauses, but currently does not. To
avoid needing to add support during the current release process,
we simply swap around the arguments to move them to the first <>
instead of the where.
Matt Corallo [Fri, 17 Dec 2021 22:38:46 +0000 (22:38 +0000)]
Swap around generic argument ordering in DefaultRouter for bindings
The bindings generation really should support default generic types
in where clauses, but currently does not. To avoid needing to add
support during the current release process, we simply swap around
the arguments to move them to the first <> instead of the where.
Add new invoice CreationError::InvalidAmount for use in checking `create_inbound_payment`
in an invoice creation utility. Note that if the error type of `create_inbound_payment` ever
changed, we'd be forced to update the invoice utility's callsite to handle the new error
Matt Corallo [Tue, 14 Dec 2021 01:33:37 +0000 (01:33 +0000)]
Reject channel_update messages with timestamps too old or new
Because we time out channel info that is older than two weeks now,
we should also reject new channel info that is older than two
weeks, in addition to rejecting future channel info.
Matt Corallo [Sat, 4 Dec 2021 23:41:37 +0000 (23:41 +0000)]
Use `Event::PaymentFailed` in `InvoicePayer` to remove retry count
This finally fixes the bug described in the previous commits where
we retry a payment after its retry count has expired due to early
removal of the payment from the retry count tracking map. A test is
also added which demonstrates the bug in previous versions and
which passes now.
Matt Corallo [Fri, 10 Dec 2021 00:28:24 +0000 (00:28 +0000)]
Expose an event when a payment has failed and retries complete
When a payment fails, a payer needs to know when they can consider
a payment as fully-failed, and when only some of the HTLCs in the
payment have failed. This isn't possible with the current event
scheme, as discovered recently and as described in the previous
commit.
This adds a new event which describes when a payment is fully and
irrevocably failed, generating it only after the payment has
expired or been marked as expired with
`ChannelManager::mark_retries_exceeded` *and* all HTLCs for it
have failed. With this, a payer can more simply deduce when a
payment has failed and use that to remove payment state or
finalize a payment failure.
Matt Corallo [Fri, 3 Dec 2021 19:57:37 +0000 (19:57 +0000)]
Add a variant to `PendingOutboundPayment` for retries-exceeded
When a payer gives up trying to retry a payment, they don't know
for sure what the current state of the event queue is.
Specifically, they cannot be sure that there are not multiple
additional `PaymentPathFailed` or even `PaymentSuccess` events
pending which they will see later. Thus, they have a very hard
time identifying whether a payment has truly failed (and informing
the UI of that fact) or if it is still pending. See [1] for more
information.
In order to avoid this mess, we will resolve it here by having the
payer give `ChannelManager` a bit more information - when they
have given up on a payment - and using that to generate a
`PaymentFailed` event when all paths have failed.
This commit adds the neccessary storage and changes for the new
state inside `ChannelManager` and a public method to mark a payment
as failed, the next few commits will add the new `Event` and use
the new features in our `PaymentRetrier`.
Matt Corallo [Tue, 7 Dec 2021 19:17:57 +0000 (19:17 +0000)]
Upgrade to codecov uploader v2
Some time ago codecov stopped supporting their old v1 uploader, and
it seems they've now finally turned it off, so we aren't getting
any coverage reports anymore. Hopefully upgrading is pretty trivial.
Matt Corallo [Mon, 6 Dec 2021 00:18:59 +0000 (00:18 +0000)]
Support the `channel_type` feature bit.
Note that this feature bit does absolutely nothing. We signal it
(as we already support channel type negotiation), but do not bother
to look to see if peers support it, as we don't care - we simply
look for the TLV entry and deduce if a peer supports channel type
negotiation from that.
The only behavioral change at all here is that we don't barf if a
peer sets channel type negotiation to required via the feature bit
(instead of failing the channel at open-time), but of course no
implementations do this, and likely won't for some time (if ever -
you can simply fail channels with unknown types later, and there's
no reason to refuse connections, really).
As defined in https://github.com/lightning/bolts/pull/906
Jeffrey Czyz [Fri, 3 Dec 2021 19:04:58 +0000 (13:04 -0600)]
Ensure ChannelManager methods are idempotent
During event handling, ChannelManager methods may need to be called as
indicated in the Event documentation. Ensure that these calls are
idempotent for the same event rather than panicking. This allows users
to persist events for later handling without needing to worry about
processing the same event twice (e.g., if ChannelManager is not
persisted but the events were, the restarted ChannelManager would return
some of the same events).