Commit graph

317 commits

Author SHA1 Message Date
Jeffrey Czyz
d924c5d6ed
Benchmark zero-penalty scorer 2022-01-24 19:32:53 -06:00
Jeffrey Czyz
4512fd3685
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.
2022-01-24 19:32:47 -06:00
Jeffrey Czyz
486df783e9
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.
2022-01-24 19:05:49 -06:00
Jeffrey Czyz
06053fc21c
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.
2022-01-24 18:52:36 -06:00
Elias Rohrer
808477a5ce Rename Payee to PaymentParameters 2022-01-21 10:39:01 +01:00
Elias Rohrer
367ed31dc9 Limit maximum total CLTV expiry delta during routing. 2022-01-20 16:00:00 +01:00
Elias Rohrer
689518520e Fixed some typos 2022-01-19 18:15:47 +01:00
Matt Corallo
a82067d359
Merge pull request #1013 from TheBlueMatt/2021-07-warning-msgs 2022-01-11 22:52:44 +00:00
Matt Corallo
e137cfb3c4 Send warning messages when appropriate in gossip handling pipeline 2022-01-11 19:48:20 +00:00
Matt Corallo
3ca63426f9
Merge pull request #1220 from TheBlueMatt/2021-12-stale-update-gossip-log
Log gossip rejections due to stale channel_updates at GOSSIP level
2022-01-03 19:54:20 +00:00
Matt Corallo
d5a1435905 Log gossip rejections due to stale channel_updates at GOSSIP level
This further reduces noise at the TRACE level during initial gossip
sync.
2021-12-19 20:13:38 +00:00
Matt Corallo
d26469a77a Add a C-not exported tag to NetGraphMsgHandler.network_graph 2021-12-18 20:20:23 +00:00
Matt Corallo
ae4f6198db Add a constructor to MultiThreadedLockableScore
...as otherwise the struct is rather useless.
2021-12-18 20:20:23 +00:00
Matt Corallo
73e8dc41a6 Automatically prune NetworkGraph of stale channels hourly in BP 2021-12-16 18:33:24 +00:00
Matt Corallo
cd43ff4a5e 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.
2021-12-16 18:33:24 +00:00
Matt Corallo
4677e14c00 Add a method to prune stale channels from NetworkGraph
We define "stale" as "haven't heard an updated channel_update in
two weeks", as described in BOLT 7.

We also filter out stale channels at write-time for `std` users, as
we can look up the current time.
2021-12-16 18:33:24 +00:00
Matt Corallo
11d644824e DRY up network_graph tests substantially with message creation fns 2021-12-16 18:33:24 +00:00
Matt Corallo
09714e6fe2
Merge pull request #1169 from TheBlueMatt/2021-11-fix-update-announcements
Fix announcements of our own gossip
2021-12-09 18:21:55 +00:00
Matt Corallo
0fe2aef0e6 Add a comment describing the timestamp field's use 2021-12-09 03:49:50 +00:00
Devrandom
02a9f92ea4 Getter for the total channel balance
The existing balance getters subtract reserve, this one does not.
2021-12-07 15:06:22 +01:00
Jeffrey Czyz
857b4c08a5
Fix shift overflow in Scorer::channel_penalty_msat
An unchecked shift of more than 64 bits on u64 values causes a shift
overflow panic. This may happen if a channel is penalized only once and
(1) is not successfully routed through and (2) after 64 or more half
life decays. Use a checked shift to prevent this from happening.
2021-12-03 14:00:52 -06:00
Jeffrey Czyz
d28d6a5403
Decay channel failure penalty upon success
If a payment failed to route through a channel, a penalty is applied to
the channel in the future when finding a route. This penalty decays over
time. Immediately decay the penalty by one half life when a payment is
successfully routed through the channel.
2021-12-03 14:00:52 -06:00
Jeffrey Czyz
c36bf92499
Score successful payment paths
Expand the Score trait with a payment_path_successful function for
scoring successful payment paths. Called by InvoicePayer's EventHandler
implementation when processing PaymentPathSuccessful events. May be used
by Score implementations to revert any channel penalties that were
applied by calls to payment_path_failed.
2021-12-03 14:00:51 -06:00
Matt Corallo
3539f270c4 Seal scoring::Time and only use Instant or Eternity publicly
`scoring::Time` exists in part to make testing the passage of time
in `Scorer` practical. To allow no-std users to provide a time
source it was exposed as a trait as well. However, it seems
somewhat unlikely that a no-std user is going to have a use for
providing their own time source (otherwise they wouldn't be a
no-std user), and likely they won't have a graph in memory either.

`scoring::Time` as currently written is also exceptionally hard to
write C bindings for - the C bindings trait mappings relies on the
ability to construct trait implementations at runtime with function
pointers (i.e. `dyn Trait`s). `scoring::Time`, on the other hand,
is a supertrait of `core::ops::Sub` which requires a `sub` method
which takes a type parameter and returns a type parameter. Both of
which aren't practical in bindings, especially given the
`Sub::Output` associated type is not bound by any trait bounds at
all (implying we cannot simply map the `sub` function to return an
opaque trait object).

Thus, for simplicity, we here simply seal `scoring::Time` and make
it effectively-private, ensuring the bindings don't need to bother
with it.
2021-11-24 19:08:12 +00:00
Matt Corallo
a173ded03f Make Score : Writeable in c_bindings and impl on LockedScore
Ultimately we likely need to wrap the locked `Score` in a struct
that exposes writeable somehow, but because all traits have to be
fully concretized for C bindings we'll still need `Writeable` on
all `Score` in order to expose `Writeable` on the locked score.
Otherwise, we'll only have a `LockedScore` with a `Score` visible
that only has the `Score` methods, never the original type.
2021-11-24 19:08:12 +00:00
Matt Corallo
391fbfbe1a Re-broadcast our own gossip even if its same as the last broadcast
Even if our gossip hasn't changed, we should be willing to
re-broadcast it to our peers. All our peers may have been
disconnected the last time we broadcasted it.
2021-11-23 22:18:00 +00:00
Matt Corallo
22398853c9
Merge pull request #1168 from TheBlueMatt/2021-11-mpp-routing-fixes
Fix MPP routefinding when we first collect 95% of payment value
2021-11-22 21:55:06 +00:00
Matt Corallo
1180b633b4 Fix MPP routefinding when we first collect 95% of payment value
See comment in new test for more details.
2021-11-22 19:01:17 +00:00
Elias Rohrer
3b4b74bc66 Add a new log-level for gossip messages. 2021-11-22 18:19:08 +01:00
Matt Corallo
42ebf77415 Move Score into a scoring module instead of a top-level module
Traits in top-level modules is somewhat confusing - generally
top-level modules are just organizational modules and don't contain
things themselves, instead placing traits and structs in
sub-modules. Further, its incredibly awkward to have a `scorer`
sub-module, but only have a single struct in it, with the relevant
trait it is the only implementation of somewhere else. Not having
`Score` in the `scorer` sub-module is further confusing because
it's the only module anywhere that references scoring at all.
2021-11-16 20:58:37 +00:00
Matt Corallo
9bec35ddde Penalize large HTLCs relative to channels in default Scorer
Sending HTLCs which are any greater than a very small fraction of the
channel size tend to fail at a much higher rate. Thus, by default
we start applying a penalty at only 1/8th the channel size and
increase it linearly as the amount reaches the channel's capacity,
20 msat per 1024th of the channel capacity.
2021-11-16 20:58:04 +00:00
Matt Corallo
8dc7cfab3a Provide Score the HTLC amount and channel capacity
This should allow `Score` implementations to make substantially
better decisions, including of the form "willing to pay X to avoid
routing over this channel which may have a high failure rate".
2021-11-16 20:58:04 +00:00
Jeffrey Czyz
b57ed7982f
Add unit tests for Scorer
Test basic and channel failure penalties, including after a
(de-)serialization round trip.
2021-11-08 15:31:42 -06:00
Jeffrey Czyz
2a7d9c8ddd
Add SinceEpoch time to test Scorer hermetically
In order to test Scorer hermetically, sleeps must be avoided. Add a
SinceEpoch abstraction for manually advancing time. Implement the Time
trait for SinceEpoch so that it can be used with ScorerUsingTime in
tests.
2021-11-08 15:31:42 -06:00
Matt Corallo
d25f332592 Tweak serialization of ScorerUsingTime for better forward compat 2021-11-03 01:30:03 +00:00
Matt Corallo
80802006ab Add (C-not exported) tag to a Payee modifier with move semantics
This matches the other `Payee` move-modifier functions.
2021-11-02 20:50:42 +00:00
Matt Corallo
0f0530a67a Remove now-unused import in routing/mod.rs 2021-11-02 20:50:42 +00:00
Matt Corallo
51d146c566 Make payment_path_failed path type bindings-mappable
The bindings don't currently support passing `Vec`s of objects
which it mappes as "opaque types". This is because it will require
clones to convert its own list of references to Rust's list of
objects.

In the near future we should resolve this limitation, allowing us
to revert this (and make `find_route`'s method signature similarly
cleaner), but for now we must avoid `Vec<OpaqueType>`.
2021-11-02 20:50:42 +00:00
Matt Corallo
2ec427f148 Rename Payee::new to Payee::from_node_id to clarify it somewhat
This also differentiates it from the bindings default-constructed
`new` method which is constructed when all fields are exposed and
of mappable types.
2021-11-02 20:50:42 +00:00
Jeffrey Czyz
ae210e7d09
Implement (de)serialization for Scorer
Scorer should be serialized to retain penalty data between restarts.
Implement (de)serialization for Scorer by serializing last failure times
as duration since the UNIX epoch. For no-std, the zero-Duration is used.
2021-11-02 14:48:40 -05:00
Jeffrey Czyz
a8d3b5aabf
Parameterize Scorer by a Time trait
Scorer uses time to determine how much to penalize a channel after a
failure occurs. Parameterizing it by time cleans up the code such that
no-std support is in a single AlwaysPresent struct, which implements the
Time trait. Time is implemented for std::time::Instant when std is
available.

This parameterization also allows for deterministic testing since a
clock could be devised to advance forward as needed.
2021-11-02 14:48:39 -05:00
Jeffrey Czyz
88cf9b33c3
Refactor channel failure penalty logic
Move channel failure penalty logic into a ChannelFailure abstraction.
This encapsulates the logic for accumulating penalties and decaying them
over time. It also is responsible for the no-std behavior. This cleans
up Scorer and will make it easier to serialize it.
2021-11-02 14:48:35 -05:00
Jeffrey Czyz
1c2b3c244e
Clarify Scorer docs around penalizing channels 2021-11-01 20:33:52 -05:00
Jeffrey Czyz
c4d7b9d50f
Make NetGraphMsgHandler::network_graph private
Since NetworkGraph has shared ownership, NetGraphMsgHandler does not
need to expose its field.
2021-11-01 15:01:39 -05:00
Jeffrey Czyz
bcdd852279
Parameterize NetGraphMsgHandler with NetworkGraph
NetworkGraph is owned by NetGraphMsgHandler, but DefaultRouter requires
a reference to it. Introduce shared ownership to NetGraphMsgHandler so
that both can use the same NetworkGraph.
2021-11-01 13:14:14 -05:00
Matt Corallo
c53048a40f
Merge pull request #1144 from jkczyz/2021-10-invoice-payer-scoring
Penalize failed channels
2021-10-29 20:16:36 +00:00
Jeffrey Czyz
c34ab42961
Penalize failed channels in Scorer
As payments fail, the channel responsible for the failure may be
penalized. Implement Scorer::payment_path_failed to penalize the failed
channel using a configured penalty. As time passes, the penalty is
reduced using exponential decay, though penalties will accumulate if the
channel continues to fail. The decay interval is also configurable.
2021-10-29 14:26:58 -05:00
Jeffrey Czyz
7a8954e1ca
Notify scorer of failing payment path and channel
Upon receiving a PaymentPathFailed event, the failing payment may be
retried on a different path. To avoid using the channel responsible for
the failure, a scorer should be notified of the failure before being
used to find a new route.

Add a payment_path_failed method to routing::Score and call it in
InvoicePayer's event handler. Introduce a LockableScore parameterization
to InvoicePayer so the scorer is locked only once before calling
find_route.
2021-10-29 14:24:53 -05:00
Matt Corallo
517a1540e0 Add a utility trait in router to get the fees along a given path 2021-10-27 20:43:18 +00:00
Jeffrey Czyz
d9b9916601
Fail payment retry if Invoice is expired
According to BOLT 11:

- after the `timestamp` plus `expiry` has passed
  - SHOULD NOT attempt a payment

Add a convenience method for checking if an Invoice has expired, and use
it to short-circuit payment retries.
2021-10-27 10:54:53 -05:00