Commit graph

107 commits

Author SHA1 Message Date
Gene Ferneau
12461fcba1
Use alloc for no_std builds
Replace std structs with alloc equivalents to support no_std builds

f use prelude::* credit @devrandom
2021-05-27 17:35:20 +00:00
Matt Corallo
3d1c72e73f Update net graph copy used in tests and bench for new format 2021-05-25 20:06:45 +00:00
Matt Corallo
5b59178f89 Add version and TLV suffix for more user-facing "major" structs 2021-05-25 20:06:45 +00:00
Gene Ferneau
ec3739b7a2
Use core replacements for std members
In preparation for no_std build support, replace std structs and
functions with core equivalents
2021-05-23 23:48:27 +00:00
Matt Corallo
62f466a0a2 Rename ChannelDetails::is_live to is_usable
This matches is_usable_channels and slightly better captures the
meaning.
2021-05-06 20:49:20 +00:00
Matt Corallo
6a79eece21 Indiciate if a channel is outbound/confirmed in ChannelDetails 2021-05-06 20:49:20 +00:00
Matt Corallo
2d6f060c06 Add flags for if a channel is pub and funding txo in ChannelDetails 2021-05-06 20:49:20 +00:00
Valentine Wallace
ad900658ce
Rename RouteHint to RouteHintHop (which is more accurate) 2021-04-20 16:26:56 -04:00
Valentine Wallace
21cb8db1b6
invoice: swap RouteHop for RouteHint
To prevent naming conflicts in bindings
2021-04-20 16:26:52 -04:00
Matt Corallo
daa1979aae Fix compile warning with --cfg require_route_graph_test 2021-04-12 23:35:44 -04:00
Matt Corallo
7e39f8735a Fix benchmark compile warnings and errors
Hopefully soon once a few more PRs get merged we can require this
in CI so we won't have any more regressions here.
2021-04-12 18:04:55 -04:00
Matt Corallo
5f5bc41201 [router] Add and clarify comments describing router internals 2021-04-06 21:41:45 -04:00
Matt Corallo
bb62420b0f Drop unreachable underflow-handling block in route calculation
See comment in the removed block, note that the subsequent
subtraction will underflow if the block would otherwise have been
reached.
2021-04-06 21:41:45 -04:00
Matt Corallo
4c75437262 Don't clone Features during Dijkstras graph walk
We currently copy the features objects in each channel as we walk
the graph during route calculation. This implies a significant
amount of malloc traffic as the features flags object are stored
on the heap.

Instead, because they features being referenced are in the network
graph which we hold a reference to, we can simply store references
to them.

This nontrivially improves our get_route benchmark by around 5%.
2021-04-06 21:41:45 -04:00
Matt Corallo
0d7c316259 [router] Avoid re-processing peers when a score component decreases
While walking the graph doing Dijkstra's, we may decrease the
amount being sent along one path, and not others, based on the
htlc_minimum_msat value. This may result in a lower relative fees
on that path in comparison to others. In the extreme, this may
result in finding a second path to a node with a lower fee than the
first path found (normally impossible in a Dijkstra's
implementation, as we walk next hops in fee-order).

In such a case, we end up with parts of our state invalid as
further hops beyond that node have been filled in using the
original total fee information.

Instead, we simply track which nodes have been processed and ignore
and further updates to them (as it implies we've reduced the amount
we're sending to find a lower absolute fee, but a higher relative
fee, which isn't a better route).

We check that we are in exactly this case in test builds with new
in-line assertions. Note that these assertions successfully detect
the bug in the previous commit.

Sadly this requires an extra HashMap lookup every time we pop an
element off of our heap, though we can skip a number of heap pushes
during the channel walking.
2021-04-06 21:41:45 -04:00
Matt Corallo
c2cd8d4855 Add a random real-world-network-graph test for the router
This is the same code as was recently failing in our benchmarks,
adapted to use a random starting seed instead of a fixed one and
a smaller iteration to reduce runtime.
2021-04-06 21:41:45 -04:00
Matt Corallo
b728216fd9 [router] Calc min-to-node fees based on min value, not est value
When walking the network graph to calculate a route, we always
calculate the minimum fee which is required to make one further
hop. This avoids some extra hop processing at the end of each path
selection loop (saving around 10% runtime in our benchmarks).

However, if we use the real value which we expect
to send over a channel in that calculation, we may find an
alternate path to the same node which is more expensive but
capacity-constrained, resulting in us considering it cheaper as the
relative fee paid will be lower.

Instead, we can use the `minimal_value_contribution_msat`, which is
a constant through an entire path finding iteration, as the amount,
preventing any basis change in the relative fee paid.
2021-04-06 21:41:45 -04:00
Matt Corallo
ed54379ee4 [router] Make Dijkstra's path scoring non-decreasing + consistent
Currently, the "best source" for a given node tracked during
Dijkstra's is updated with a different critera from the heap
sorting, resulting in loops in calculated paths.

This adds a test for the specific failure currently seen, utilizing
the new path-htlc-minimum tracking in the heap entries in place of
the per-hop htlc-minimum values which the MPP changeset partially
used.
2021-04-06 21:41:45 -04:00
Matt Corallo
16a6e9c5c8 [router] Avoid re-selecting the same path over and over again
If we walk the network graph and find a route that meets are
payment amount and has a liquidiy limit far in excess of our
payment amount, we may select the same path several times in the
main path-gathering loop.

Instead, if the path we selected was not limited by the available
liquidity, we set the middle hop in the path's liquidity available
to zero, disabling that channel in future path finding steps.
2021-04-06 21:41:45 -04:00
Matt Corallo
93311b3684 [router] Track full-path htlc-minimum-msat while graph-walking
Previously, we'd happily send funds through a path where, while
generating the path, in some middle hope we reduce the value being
sent to meet an htlc_maximum, making a later hop invalid due to it
no longer meeting its htlc_minimum. Instead, we need to track the
path's htlc-minimum while we're transiting the graph.
2021-04-06 21:41:45 -04:00
Matt Corallo
5c38e09b26 [router] Do not fail if we are exactly (or 3x) limited by a maximum
The new MPP routing algorithm attempts to build paths with a higher
value than our payment to find paths which may allow us to pay a
fee to meet an htlc_minimum limit. This is great if we're
min-bounded, however it results in us rejecting paths where we are
bounded by a maximum near the end of the path, with fees, and then
bounded by a minimum earlier in the path. Further, it means we will
not find the cheapest path where paths have a lower relative fee
but a higher absolute fee.

Instead, we calculate routes using the actual amount we wish to
send. To maintain the previous behavior of searching for cheaper
paths where we can "pay the difference" to meet an htlc_minimum, we
detect if we were minimum-bounded during graph walking and, if we
are, we walk the graph again with a higher value.
2021-04-06 21:41:45 -04:00
Matt Corallo
512642c32d Add comment in get_route describing our dijkstra's mods 2021-04-06 21:41:45 -04:00
Valentine Wallace
c318ad87e0
Expose counterparty forwarding info in ChannelDetails.
Useful for constructing route hints for private channels in invoices.

Co-authored-by: Valentine Wallace <vwallace@protonmail.com>
Co-authored-by: Antoine Riard <ariard@student.42.fr>
2021-03-17 17:36:26 -04:00
Matt Corallo
b9fef85aa3 Split router benchmark into an MPP and a non-MPP route benchmark 2021-03-08 17:19:23 -05:00
Matt Corallo
ef0f249294 Disable MPP routing when the payee does not support it 2021-03-08 17:19:23 -05:00
Matt Corallo
9e57364a89 Add an Option<>al InvoiceFeatures object for the payee in get_route
We currently only use it to override the graph-specific features
returned in the route, though we should also use it to enable or
disable MPP.

Note that tests which relied on MPP behavior have had all of their
get_route calls upgraded to provide the MPP flag.
2021-03-08 17:19:23 -05:00
Jeffrey Czyz
a571ecccbc
Fix build warnings 2021-03-02 21:30:34 -08:00
Matt Corallo
4894d52d30 Merge pull request #646 from naumenkogs/2020-06-router-mpp
MPP on the router side
2021-03-02 20:33:08 -05:00
Gleb Naumenko
e0600e5b1e Don't underpay htlc_min due to path contribution
We could have possibly constructed a slightly inconsistent
path: since we reduce value being transferred all the way, we
could have violated htlc_minimum_msat on some channels
we already passed (assuming dest->source direction). Here,
we recompute the fees again, so that if that's the case, we
match the currently underpaid htlc_minimum_msat with fees.
2021-03-02 21:40:08 +02:00
Gleb Naumenko
18c7730040 Mind htlc_minimum_msat when truncating overpaid value
At truncating the overpaid value, if we fall below
htlc_minimum_msat, reach it by increasing fees.
2021-03-02 21:19:58 +02:00
Gleb Naumenko
ef12ceb8dd Use outbound_capacity_msat from first_hops for routing 2021-03-02 21:09:50 +02:00
Gleb Naumenko
db4721f3a7 Implement finding paths for MPP 2021-03-02 21:09:49 +02:00
Matt Corallo
2ae6b3fad4 Add a trivial benchmark of calculating routes on today's graph
Sadly rust upstream never really figured out the benchmark story,
and it looks like the API we use here may not be long for this
world. Luckily, we can switch to criterion with largely the same
API if that happens before upstream finishes ongoing work with the
custom test framework stuff.

Sadly, it requires fetching the current network graph, which I did
using Val's route-testing script written to test the MPP router.
2021-02-15 16:51:51 -05:00
Matt Corallo
ac078c103c [bindings] Don't require trait impl for-structs to have no generics
This (finally) exposes `ChannelManager`/`ChannelMonitor` _write
methods, which were (needlessly) excluded as the structs themselves
have generic parameters. Sadly, we also now need to parse
`(C-not exported)` doc comments on impl blocks as we otherwise try
to expose _write methods for `&Vec<RouteHop>`, which doesn't work
(and isn't particularly interesting for users anyway). We add such
doc comments there.
2021-02-03 10:11:28 -05:00
Gleb Naumenko
368c534679 Store available routing amounts per channel to use it in routing decisions 2020-12-24 13:04:47 +02:00
bmancini55
d183b975da Add genesis block hash to NetworkGraph
This changes adds the genesis block hash as a BlockHash to the
NetworkGraph struct. Making the NetworkGraph aware allows the message
handler to validate the chain_hash for received messages. This change
also adds the hash value to the Writeable and Readable methods.
2020-12-09 15:02:32 -05:00
Matt Corallo
fc7df54f8d
Merge pull request #748 from TheBlueMatt/2020-11-router-fuzzer
Make router_target a bit easier for fuzzers to explore and fix two found bugs
2020-11-24 08:36:14 -08:00
Matt Corallo
50b348c4fa [router] Fix + test routing via next/last-hop hints only
We had code in the router to support sending a payment via a single
hop across channels exclusively provided by the next-/last-hop hints.
However, in updating the fuzzer, I noted that this case not only
didn't work, but paniced in some cases.

Here, we both fix the panic, as well as write a new test which
ensures we don't break support for such routing in the future.
2020-11-23 13:52:51 -05:00
Matt Corallo
d737111044 derive(Clone) for several pub simple data structs.
There is no reason not to and Clone can be useful especially in the
bindings context.
2020-11-23 11:08:34 -05:00
Jeffrey Czyz
3ee6a27bc6
Replace ChainWatchInterface in NetGraphMsgHandler
ChainWatchInterface was intended as an interface for watching rather
than accessing the chain. Remove get_chain_utxo and add chain::Access
trait for this behavior. Wrap it with an Option in NetGraphMsgHandler in
order to simplify the error interface.
2020-09-30 22:39:38 -07:00
Matt Corallo
b9707da138 Update to latest upstream rust-bitcoin 2020-09-10 16:20:01 -04:00
Matt Corallo
de8c5dc76d Use slices to references not slices of concrete objects in pub API
Because the C bindings maps objects into new structs which contain
only a pointer to the underlying (immovable) Rust type, it cannot
create a list of Rust types which are contiguous in memory. Thus,
in order to allow C clients to call certain Rust functions, we have
to use &[&Type] not &[Type]. This commit fixes this issue for the
get_route function.
2020-08-25 17:09:51 -04:00
Dominik Spicher
edeb122ce5 Refactor route tests
* Splits up the monolithic test into smaller unit tests

* Factors out helpers for graph setup

* Changes `id_to_feature_flags` to be a function, there was no
reason why it had to be a macro

* Activates a previously commented-out test that checks for
the failure case in `disable_node_test`
2020-08-25 00:50:54 +02:00
Matt Corallo
4395b92cc8 Relicense as dual Apache-2.0 + MIT
This changes the LICENSE file and adds license headers to most files
to relicense under dual Apache-2.0 and MIT. This is helpful in that
we retain the patent grant issued under Apache-2.0-licensed work,
avoiding some sticky patent issues, while still allowing users who
are more comfortable with the simpler MIT license to use that.

See https://github.com/rust-bitcoin/rust-lightning/issues/659 for
relicensing statements from code authors.
2020-08-10 21:12:44 -04:00
Gleb Naumenko
8b4f6e8861 Add htlc_maximum_msat field 2020-07-27 14:06:16 +03:00
Gleb Naumenko
430d57c610 Fix formatting 2020-07-22 16:21:04 +03:00
Gleb Naumenko
5309197150 Use constant for max msats 2020-07-22 16:21:04 +03:00
Gleb Naumenko
7838727a5c Update get_route comment to reflect new parameters 2020-07-22 16:20:19 +03:00
joe.miyamoto
1fc6d6b5ee
Improve error message.
... for ChannelError and APIMisuseError
Before this commit, When rl returns error, we don't know
The actual parameter which caused the error.
By returning parameterised `String` instead of predefined `&'static str`,
We can give a caller improved error message.

TestLogger now has two additional methods
1. `assert_log_contains` which checks the logged messsage
  has how many entry which includes the specified string as a substring.
2. `aasert_log_regex` mostly the same with `assert_log_contains`
  but it is more flexible that caller specifies regex which has
  to be satisfied instead of just a substring.
For regex, tests now includes `regex` as dev-dependency.
2020-07-22 10:34:47 +09:00
Matt Corallo
bcd65bed7b Take &NetworkGraph as input in get_route, not a NetGraphMsgHandler
This was just an oversight when route calculation was split up into
parts - it makes no sense for get_route to require that we have a
full route message handler, only a network graph (which can always
be accessed from a NetGraphMsgHandler anyway).
2020-06-23 16:12:55 -04:00