Default to creating tlv onions for nodes for which we haven't received
any features through node announcements or which aren't in the
`network_graph`, and where no other features are known such as invoice
features nor features in the init msg for nodes we have channels to.
When we start getting a numerator and divisor particularly close to
each other, the log approximation starts to get very noisy. In
order to avoid applying scores that are basically noise (and can
range upwards of 2x the default per-hop penalty), simply consider
such cases as having a success probability of 100%.
When we send values over channels of rather substantial size, the
imprecision of our log lookup tables creates a rather substantial
non-linearity between values that round up or down one bit.
For example, with the default scoring values, sending 100k sats
over channels with 1m, 2m, 3m, and 4m sats of capacity score
rather drastically differently: 3645, 2512, 500, and 1442 msat.
Here we expand the precision of our log lookup tables rather
substantially by: (a) making the multiplier 2048 instead of 1024,
which still fits inside a u16, and (b) quadrupling the size of the
lookup table to look at the top 6 bits after the most-significant
bit of an input instead of the top 4.
This makes the scores of the same channels substantially more
linear, with values of 3613, 1977, 1474, and 1223 msat.
The same channels would be scored at 3611, 1972, 1464, and 1216
msat with a non-approximating scorer.
Having public types in a private module is somewhat awkward from a
readability standpoint, but, more importantly, the bindings logic
has a relatively rough go of converting them - it doesn't implement
`pub use` as its "implement this function" logic is all within the
context of a module. We'd need to keep a set of re-exported things
to implement them when parsing modules...or we could just move two
enums from `de.rs` to `lib.rs` here, which is substantially less
work.
Querying a BlockSource is a logically immutable operation. Use non-mut
references in its interface to reflect this, which allows for users to
hold multiple references if desired.
We generally make no effort to ensure all writes are buffered in
lower-level objects, so wrapping write calls in `BufWriter` may
substantially improve performance in some cases. This is especially
important now that we block the sample node exit until the
`NetworkGraph` has been written out, which includes many small-ish
writes.
With this change, shutdown of the sample node on a relatively
underpowered device went from 15-30 seconds of CPU time to a second
or two, plus IO sync time.
The cost of large payments tends to be dominated by the channel fees. To
avoid this, add an amount penalty to ProbabilisticScorer with a user
configurable multiplier. The multiplier is applied for every 2^20th of
the amount weighted by the negative log10 of the channel's success
probability for the payment.
In ProbabilisticScorer, the channel liquidity balance is reduced
whenever a payment fails at the corresponding channel. The payment may
still be retried through the channel, however, because the liquidity
penalty is capped. Use u64::max_value instead in this situation to avoid
retrying over the same path. This effectively makes u64::max_value the
penalty for amounts exceeding the upper bound, as well.
As an edge case, avoid using u64::max_value on attempts where the amount
is equal to the effective capacity, which may be the HTLC maximum when
the channel capacity is unknown.
During the first pass of path finding, we seek a single path with the
exact payment amount, and only seek additional paths if (a) no single
path can carry the entire balance of the payment or (b) we found a good
path, but along the way we found candidate paths with the potential to
result in a lower total fee. This commit fixes the behavior of (b) -- we
were previously considering some paths to be candidates for a lower fee
when in fact they never would have worked. This caused us to re-run
Dijkstra's when it might not have been beneficial.
Instead of creating a separate trait for persisting NetworkGraph, use and rename the existing ChannelManagerPersister to handle them both. persist_graph is then called on removal of stale channels and on exit.
As part of preparing to expose some of its methods as pub for ChannelManager-less
phantom invoice generation.
Pure code move of the module + the addition of module-level documentation
There's not a lot of reason to keep it given its used in one place
outside of tests, and this lets us clean up some of the byte_utils
calls that are still lying around.
When we fail an HTLC which was destined for a channel that the HTLC
sender didn't know the real SCID for, we should ensure we continue
to use the alias in the channel_update we provide them. Otherwise
we will leak the channel's real SCID to HTLC senders.
This reduces unwraps in channelmanager by a good bit, providing
robustness for the upcoming 0conf changes which allow SCIDs to be
missing after a channel is in use, making
`get_channel_update_for_unicast` more fallible.
This also serves as a useful refactor for the next commit,
consolidating the channel_update creation sites which are changed
in the next commit.
Because negotiating `scid_alias` for all of our channels will cause
us to create channels which LDK versions prior to 0.0.106 do not
understand, we disable `scid_alias` negotiation by default.
This does not, however, ever send the scid_alias feature bit for
outgoing channels, as that would cause the immediately prior
version of LDK to be unable to read channel data.