This fixes an oversight in ac842ed9dd
namely that it left users unable to implement their own
`ChainMonitor` from outside of the `rust-lightning` crate.
This makes our `ProbabilisticScorer` field names more consistent,
as we add more types of penalties, referring to a penalty as only
the "amount penalty" no longer makes sense - we not have several
amount multiplier penalties.
There's not much reason to not have a per-hop-per-amount penalty in
the `ProbabilisticScorer` to go along with the per-hop penalty to
let it scale up to larger amounts, so we add one here.
Notably, we use a divisor of 2^30 instead of 2^20 (like the
equivalent liquidity penalty) as it allows for more flexibility,
and there's not really any reason to worry about us not being able
to create high enough penalties.
Closes#1616
This simplifies things for bindings (and, to some extent,
downstream users) by exploiting the fact that we can always "clone"
a reference to a struct by dereferencing and then creating a new
reference.
This should make it somewhat more difficult to accidentally use a
straight fee estimator when we actually want a
LowerBoundedFeeEstimator by not having the types be exchangeable at
all.
In 4703d4e725 we changed
PeerManager::socket_disconnected to no longer require that sockets
which the PeerManager decided to disconnect not be disconnected.
However, we forgot to remove the scary warnings on the
`new_{inbound,outbound}_connection` functions which warned of the
old behavior.
We do so here.
We add `HTLCHandlingFailedConditions` to express the failure parameters,
that will be enforced by a new macro, `expect_pending_htlcs_forwardable_conditions`.
Adds a HTLCHandlingFailed that expresses failure by our node to process
a specific HTLC. A HTLCDestination enum is defined to express the
possible cases that causes the handling to fail.
Our existing lockorder inversion checks look at specific instances
of mutexes rather than the general mutex itself. This changes that
behavior to look at the instruction pointer at which a mutex was
created and treat all mutexes which were created at the same
location as equivalent.
This allows us to detect lockorder inversions which occur across
tests, though it does substantially reduce parallelism during test
runs.
When we add lockorder detection based on mutex construction site
rather than mutex instance in the next commit, ChannelMonitor's
PartialEq implementation causes spurious failures. This is caused
by the lockorder detection logic considering the ChannelMonitor
inner mutex to be two distinct mutexes - one when monitors are
deserialized and one when monitors are created fresh. Instead, we
attempt to tell the lockorder detection logic that they are the
same by ensuring they're constructed in the same place - in this
case a util method.
Saturating a channel beyond 1/4 of its capacity seems like a more
reasonable threshold for avoiding a path than 1/2, especially given
we should still be willing to send a payment with a lower
saturation limit if it comes to that.
This requires an (obvious) change to some router tests, but also
requires a change to the `fake_network_test`, opting to simply
remove some over-limit test code there - `fake_network_test` was
our first ever functional test, and while it worked great to ensure
LDK worked at all on day one, we now have a rather large breadth
of functional tests, and a broad "does it work at all" test is no
longer all that useful.
Currently, after we've selected a number of candidate paths, we
construct a route from a random set of paths repeatedly, and then
select the route with the lowest total cost. In the vast majority
of cases this ends up doing a bunch of additional work in order to
select the path(s) with the total lowest cost, with some vague
attempt at randomization that doesn't actually work.
Instead, here, we simply sort available paths by `cost / amount`
and select the top paths. This ends up in practice having the same
end result with substantially less complexity. In some rare cases
it gets a better result, which also would have been achieved
through more random trials. This implies there may in such cases be
a potential privacy loss, but not a substantial one, given our path
selection is ultimately mostly deterministic in many cases (or, if
it is not, then privacy is achieved through randomization at the
scorer level).
If we end up "paying" for an `htlc_minimum_msat` with fees, we
increment `already_collected_value_msat` by more than the amount
of the path that we collected (who's `value_contribution_msat` is
higher than the total payment amount, despite having been reduced
down to the payment amount).
This throws off our total value collection target, though in the
coming commit(s) it would also throw off our path selection
calculations.
In general we should avoid taking paths that we are confident will
not work as much possible, but we should be willing to try each
payment at least once, even if its over a channel that failed
recently. A full Bitcoin penalty for such a channel seems
reasonable - lightning fees are unlikely to ever reach that point
so such channels will be scored much worse than any other potential
path, while still being below `u64::max_value()`.
When we consider sending an HTLC over a given channel impossible
due to our current knowledge of the channel's liquidity, we
currently always assign a penalty of `u64::max_value()`. However,
because we now refuse to retry a payment along the same path in
the router itself, we can now make this value configurable. This
allows users to have a relatively high knowledge decay interval
without the side-effect of refusing to try the only available path
in cases where a channel is intermittently available.
When an HTLC fails, we currently rely on the scorer learning the
failed channel and assigning an infinite (`u64::max_value()`)
penalty to the channel so as to avoid retrying over the exact same
path (if there's only one available path). This is common when
trying to pay a mobile client behind an LSP if the mobile client is
currently offline.
This leads to the scorer being overly conservative in some cases -
returning `u64::max_value()` when a given path hasn't been tried
for a given payment may not be the best decision, even if that
channel failed 50 minutes ago.
By tracking channels which failed on a payment part level and
explicitly refusing to route over them we can relax the
requirements on the scorer, allowing it to make different decisions
on how to treat channels that failed relatively recently without
causing payments to retry the same path forever.
This does have the drawback that it could allow two separate part
of a payment to traverse the same path even though that path just
failed, however this should only occur if the payment is going to
fail anyway, at least as long as the scorer is properly learning.
Closes#1241, superseding #1252.