Commit graph

415 commits

Author SHA1 Message Date
Matt Corallo
593d8c4610
Merge pull request #1413 from ViktorTigerstrom/2022-04-default-to-bolt4-tlv-onions
Drop support for creating BOLT 4 Legacy onion format payloads
2022-11-11 00:49:45 +00:00
Wilmer Paulino
b0d0f3d749
Apply network graph updates through NetworkUpdate's instead of Event's 2022-11-10 10:56:59 -08:00
Jeffrey Czyz
48bb9edba1
Add PrintableString utility
Strings defined by third parties may contain control characters. Provide
a wrapper such that these are replaced when displayed. Useful in node
aliases and offer fields.
2022-11-04 15:07:01 -05:00
Matt Corallo
e55e0d53c7
Merge pull request #1811 from valentinewallace/2022-10-chanman-router
Move `InflightHtlcs` and `Router` trait into `ChannelManager`
2022-11-03 23:43:03 +00:00
Valentine Wallace
9d3324968c
Move InvoicePayer's Router into ChannelManager
This helps prepare to parameterize ChannelManager with a Router, to eventually
use in trampoline payments.
2022-11-03 16:22:40 -04:00
Valentine Wallace
1840cae321
Move InFlightHtlcs into ChannelManager
This is part of moving the Router trait into ChannelManager, which will help
allow ChannelManager to fetch routes on-the-fly as part of supporting
trampoline payments.
2022-11-03 16:19:07 -04:00
Matt Corallo
d15b7cb86e
Merge pull request #1817 from TheBlueMatt/2022-10-removed-no-score-after 2022-11-03 17:22:34 +00:00
Matt Corallo
00607a5286 Add missing break when scoring a path with a missing channel
If we send payments over a path where a channel ended up being
closed, we'll remove it before we call
`ProbabilisticPaymentScorer::payment_path_failed`. This should be
fine, except that `payment_path_failed` does not break out of its
scoring loop if a channel is missing, causing it to assign a
minimum available-liquidity of the payment amount even to channels
which our attempt never arrived at.

The fix is simple - add the missing check and break.
2022-11-02 20:09:32 +00:00
Gleb Naumenko
080c70f98f Track the time a stale channel was pruned 2022-11-02 09:45:21 +02:00
Gleb Naumenko
a39d9bfa03 Prune channels if *either* not updated 2022-11-01 16:51:08 +02:00
Gleb Naumenko
494e3aad9f Non-mandatory "fix" enabling future tests 2022-11-01 16:51:08 +02:00
Matt Corallo
4df0ff74f5 Make htlc_maximum_msat in EffectiveCapacity non-Optional
Because we now never generate an `EffectiveCapacity` with an
`htlc_maximum_msat` set to `None`, making it non-`Option`al
effectively removes dead code, which we do here.
2022-10-29 20:38:59 +00:00
Matt Corallo
81afc2f172 Require directional updates for a DirectionalChannelInfo
We currently construct `DirectedChannelInfo`s for routing before
checking if the given direction has its directional info filled in.
We then always check for directional info before actually deciding
to route over a channel, as otherwise we assume the channel is not
online.

This makes for somewhat redundant checks, and `DirectedCHannelInfo`
isn't, by itself, a very useful API. Because fetching the HTLC-max
or effective channel capacity gives spurious data if no directional
info is available, there's little reason to have that data
available, and so we here check for directional info first. This
effectively merges `DirectionalChannelInfo` and
`DirectionalChannelInfoWithUpdate`.
2022-10-29 20:38:54 +00:00
Viktor Tigerström
6777ab643c Only create BOLT4 tlv payload format onions 2022-10-25 15:44:27 +02:00
Wilmer Paulino
f4f1093edc
Bump workspace to rust edition 2018
Mostly motivated by the need of async/await.
2022-10-21 14:47:34 -07:00
Matt Corallo
6ec9b5357f Add WriteableScore bindings impl for MultiThreadedLockableScore
In 56b07e52aa we made
`MultiThreadedLockableScore` fully bindings-compatible. However, it
did not add a `WriteableScore` implementation for it. This was an
oversight as it is a `WriteableScore` in Rust and needs to be for
use in other parts of the API.

Here we add the required impl in a way that the bindings generator
is able to handle it and add conversion utilities.
2022-10-21 01:08:30 +00:00
Jeffrey Czyz
c06ab02900
Merge pull request #1764 from G8XSU/rgs-ignore-error
Ignore Duplicate Gossip Error while updating networkGraph from RGS
2022-10-19 08:50:09 -05:00
Gursharan Singh
7f089df1e3 Dedupe gossip msgs while updating networkGraph from RGS
While applying gossip info from RGS-server, number of harmless
errors might arise which should be ignored. E.g. client should not
fail if there is a duplicate gossip for same channel or duplicate
update.
2022-10-18 10:43:53 -07:00
Matt Corallo
e61f3a238a
Merge pull request #1763 from gcomte/feature/derive-eq
Derive Eq for all structs that derive PartialEq
2022-10-17 16:03:23 +00:00
Gabriel Comte
aa916bb594
Derive Eq for all structs that derive PartialEq 2022-10-14 13:24:02 +02:00
Gabriel Comte
8abf02ccfe
Remove redundant field names 2022-10-12 00:35:22 +02:00
Matt Corallo
9e8496659f Increase the default liquidity_offset_half_life to six hours
Even at relatively high payment volumes, decaying knowledge of each
individual channel every hour causes aggressive retrying of
channels as we quickly forget the state of a channel. Even with the
historical tracker, this isn't fully remedied, as we'll track the
history bounds with the decayed value.

Instead, we decay every six hours here, reducing how often we'll
retry a channel due to decay.

In addition to this, the decay likely needs to be substantially
more linear, as tracked in #1752.
2022-10-11 18:25:43 +00:00
Matt Corallo
fe531c583d Rewrite documentation some on ProbabilisticScorer
We had some user confusion on how the probabilistic scorer works,
especially in reference to the half-life parameter. This attempts
to clarify how the bounds work, and how they are decayed.
2022-10-11 18:25:43 +00:00
Matt Corallo
a626828c96
Merge pull request #1649 from dunxen/2022-08-implementnodefailure
Implement permanent node failure handling
2022-10-07 18:41:19 +00:00
Matt Corallo
4cd9901427
Merge pull request #1625 from TheBlueMatt/2022-07-history-tracking 2022-10-07 16:32:10 +00:00
Duncan Dean
63d7b2bf3e
Remove and track perm failed nodes & channels
We never had the `NetworkGraph::node_failed` method implemented. The
scorer now handles non-permanent failures by downgrading nodes, so we
don't want that implemented.

The method is renamed to `node_failed_permanent` to explicitly indicate
that this is the only case it handles. We also add tracking in the form
of two maps as fields of `NetworkGraph`, namely, `removed_nodes` and
`removed_channels`. We track these removed graph entries to ensure we
don't just resync them right away from gossip soon after removing them.
We stop tracking these removed nodes whenever `remove_stale_channels_and_tracking()`
is called and the entries have been tracked for longer than
`REMOVED_ENTRIES_TRACKING_AGE_LIMIT_SECS` which is currently set to one
week.
2022-10-07 12:00:39 +02:00
Matt Corallo
c8fb859ad6 Decay historical liquidity tracking when no new data is added
To avoid scoring based on incredibly old historical liquidity data,
we add a new half-life here which is used to (very slowly) decay
historical liquidity tracking buckets.
2022-10-06 21:10:23 +00:00
Matt Corallo
ec68f1326d Track a reference to scoring parameters in DirectedChannelLiquidity
This simplifies adding additional half lives in
DirectedChannelLiquidity by simply storing a reference to the full
parameter set rather than only the single current half-life.
2022-10-06 21:10:23 +00:00
Matt Corallo
6852ea9741 Calculate a new penalty based on historical channel liquidity range
Our current `ProbabilisticScorer` attempts to build a model of the
current liquidity across the payment channel network. This works
fine to ignore channels we *just* tried to pay through, but it
fails to remember patterns over longer time horizons.

Specifically, there are *many* channels within the network that are
very often either fully saturated in one direction, or are
regularly rebalanced and rarely saturated. While our model may
discover that, when it decays its offsets or if there is a
temporary change in liquidity, it effectively forgets the "normal"
state of the channel.

This causes substantially suboptimal routing in practice, and
avoiding discarding older knowledge when new datapoints come in is
a potential solution to this.

Here, we implement one such design, using the decaying buckets
added in the previous commit to calculate a probability of payment
success based on a weighted average of recent liquidity estimates
for a channel.

For each min/max liquidity bucket pair (where the min liquidity is
less than the max liquidity), we can calculate the probability that
a payment succeeds using our traditional `amount / capacity`
formula. From there, we weigh the probability by the number of
points in each bucket pair, calculating a total probability for the
payment, and assigning a penalty using the same log-probability
calculation used for the non-historical penalties.
2022-10-06 21:10:23 +00:00
Matt Corallo
c5eab6e11f Track history of where channel liquidities have been in the past
This introduces two new fields to the `ChannelLiquidity` struct -
`min_liquidity_offset_history` and `max_liquidity_offset_history`,
both an array of 8 `u16`s. Each entry represents the proportion of
time that we spent with the min or max liquidity offset in the
given 1/8th of the channel's liquidity range. ie the first bucket
in `min_liquidity_offset_history` represents the proportion of time
we've thought the channel's minimum liquidity is lower than 1/8th's
the channel's capacity.

Each bucket is stored, effectively, as a fixed-point number with
5 bits for the fractional part, which is incremented by one (ie 32)
each time we update our liquidity estimates and decide our
estimates are in that bucket. We then decay each bucket by
2047/2048.

Thus, memory of a payment sticks around for more than 8,000
data points, though the majority of that memory decays after 1,387
data points.
2022-10-06 21:10:23 +00:00
Matt Corallo
5d0deacc3d Correct the directionality of liquidity non-update messages
When we log liquidity updates, if we decline to update anything as
the new bounds are already within the old bounds, the
directionality of the log entries was reversed.

While we're at it, we also log the old values.
2022-10-06 17:54:28 +00:00
Matt Corallo
ba021f80c0 Rename MultiThreadedLockableScoreLock to MultiThreadedScoreLock
as the first is quite a mouthful, and the second isn't materially
less specific.
2022-09-23 15:57:48 +00:00
Valentine Wallace
95a4173b66
Import util::test_utils as ::ln_test_utils in router
To disambiguate between util::test_utils and router::test_utils
2022-09-21 15:09:55 -04:00
Valentine Wallace
feabd61bfe
Rename routing::router::test_utils to ::bench_utils
To disambiguate it from routing::test_utils
2022-09-20 10:08:57 -04:00
Valentine Wallace
615b401f7b
Move router test utils into their own module
Useful for testing onion message pathfinding in upcoming PRs and any future
routing modules we add
2022-09-19 14:16:37 -04:00
Matt Corallo
56b07e52aa Add a MutexGuard wrapper for the bindings-only LockableScore
In the bindings, we don't directly export any `std` types. Instead,
we provide trivial wrappers around them which expose only a
bindings-compatible API (and which is code in-crate, where the
bindings generator can see it).

We never quite finished this for `MultiThreadedLockableScore` - due
to some limitations in the bindings generator and the way the
scores are used in `lightning-invoice`, the scoring API ended up
being further concretized in patches for the bindings. Luckily the
scoring interface has been rewritten somewhat, and it so happens
that we can now generate bindings with the upstream code.

The final piece of the puzzle is done here, where we add a struct
which wraps `MutexGuard` so that we can expose the lock for
`MultiThreadedLockableScore`.
2022-09-19 09:21:56 +00:00
Matt Corallo
b93fe327d2 Remove all remaining references to *Features::known
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.

In anticipation of removing the `known` constructor, this commit
removes all remaining references to it outside of features.rs.
2022-09-14 20:09:36 +00:00
Matt Corallo
1a3273792b 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.
2022-09-14 20:09:35 +00:00
valentinewallace
d2a9ae0b8e
Merge pull request #1717 from TheBlueMatt/2022-09-req-features-in-handlers
Move checking of specific require peer feature bits to handlers
2022-09-13 16:17:57 -04:00
Matt Corallo
f725c5a90a Add now-missing unwraps on test calls to peer_connected. 2022-09-13 16:59:30 +00:00
Matt Corallo
bbb590b551 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`.
2022-09-13 16:59:30 +00:00
Matt Corallo
0f3536f87a 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)]`.
2022-09-12 16:26:58 +00:00
Matt Corallo
15a5966fa2
Merge pull request #1710 from TheBlueMatt/2022-09-compile-warn
Fix several compile warnings added in some of my recent commits
2022-09-11 14:54:05 +00:00
Matt Corallo
0cc3572719 Fix several compile warnings when testing in no-std mode 2022-09-10 00:18:32 +00:00
Valentine Wallace
c106d4ff9f
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.
2022-09-09 15:58:20 -04:00
Matt Corallo
06cb48afd4 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
e742894492, 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.
2022-09-09 15:36:46 +00:00
Matt Corallo
c57bb42204 Rename rejected_by_dest -> payment_failed_permanently
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.
2022-09-07 20:58:05 +00:00
jurvis
c70bd1fd55
Keep track of inflight HTLCs across payments
Added two methods, `process_path_inflight_htlcs` and
`remove_path_inflight_htlcs`, that updates that `payment_cache` map with
path information that may have failed, succeeded, or have been given up
on.

Introduced `AccountForInflightHtlcs`, which will wrap our user-provided
scorer. We move the `S:Score` type parameterization from the `Router` to
`find_route`, so we can use our newly introduced
`AccountForInflightHtlcs`.

`AccountForInflightHtlcs` keeps track of a map of inflight HTLCs by
their short channel id, direction, and give us the value that is being
used up.

This map will in turn be populated prior to calling `find_route`, where
we’ll use `create_inflight_map`, to generate a current map of all
inflight HTLCs based on what was stored in `payment_cache`.
2022-08-31 18:50:02 -07:00
Matt Corallo
5847abd92d Avoid querying the chain for outputs for channels we already have
If we receive a ChannelAnnouncement message but we already have the
channel, there's no reason to do a chain lookup. Instead of
immediately calling the user-provided `chain::Access` when handling
a ChannelAnnouncement, we first check if we have the corresponding
channel in the graph.

Note that if we do have the corresponding channel but it was not
previously checked against the blockchain, we should still check
with the `chain::Access` and update if necessary.
2022-08-23 17:46:12 +00:00
Arik Sosman
f53492eff2
Fix script order in gossip key mismatch error. 2022-08-19 10:07:55 -07:00