Commit graph

846 commits

Author SHA1 Message Date
Jeffrey Czyz
8e3744813a
Add ChannelMonitor::update_best_block
Expose a way for Electrum users to update the best block on a
ChannelMonitor independently of confirming transactions.
2021-04-14 12:57:05 -07:00
Jeffrey Czyz
13a33409b5
Add ChannelMonitor::transactions_confirmed
Define an Electrum-friendly interface for ChannelMonitor where
transactions are confirmed independently of updating the last connected
block.
2021-04-14 12:57:05 -07:00
Jeffrey Czyz
2db1f1f656
Track block height in ChannelMonitor 2021-04-14 12:57:05 -07:00
Jeffrey Czyz
5610ca193d
Combine ChannelManager's block hash and height
There is a possible race condition when both the latest block hash and
height are needed. Combine these in one struct and place them behind a
single lock.
2021-04-14 12:57:04 -07:00
Jeffrey Czyz
24351f5868
Add txid to on-chain event tracking
When using Electrum, transactions are individually unconfirmed during a
reorg rather than by block. Store the txid of the transaction creating
the on-chain event so that it can be used to determine which events need
to be removed when a transaction is unconfirmed.
2021-04-14 12:57:04 -07:00
Jeffrey Czyz
561ddc0b44
Check for duplicate HTLC events having matured 2021-04-14 12:57:04 -07:00
Jeffrey Czyz
a89996564c
Flatten onchain_events_waiting_threshold_conf
Rather than mapping height to a vector of events, use a single vector
for all events. This allows for easily processing events by either
height or transaction. The latter will be used for an interface suitable
for Electrum.
2021-04-14 12:57:04 -07:00
Matt Corallo
6982434c58 Test new transactions_unconfirmed 2021-04-14 14:26:31 -04:00
Matt Corallo
46ac4c796a Expose ChannelManager's current config and use it in reload in tests 2021-04-14 14:26:18 -04:00
Matt Corallo
bdbba5e98f Add method to note transaction unconfirmed/reorged-out 2021-04-14 14:26:17 -04:00
Matt Corallo
9577928557
Merge pull request #885 from p2pderivatives/use-secp256k1-consts-in-ser
Fix size check in Vec<Signature> serialization + use consts
2021-04-14 02:20:27 +00:00
Matt Corallo
eee1c30ea6
Merge pull request #875 from TheBlueMatt/2021-04-fix-bench
Fix benchmark compile warnings and errors
2021-04-14 01:51:33 +00:00
Tibo-lg
2e49758127 Fix size check in Vec<Signature> serialization + use consts 2021-04-14 10:37:49 +09:00
Matt Corallo
daa1979aae Fix compile warning with --cfg require_route_graph_test 2021-04-12 23:35:44 -04:00
Valentine Wallace
5b4c3c603c
Rename timer_chan_freshness_every_min for uniformity with PeerManager 2021-04-12 20:42:09 -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
8088e4ba15
Merge pull request #856 from TheBlueMatt/2021-03-check-tx
Take the full funding transaction from the user on generation
2021-04-10 20:27:24 +00:00
Matt Corallo
ba3ef0a3ba
Merge pull request #873 from TheBlueMatt/2021-861-missing-eof-eol
Add missing EOF newline
2021-04-10 20:26:36 +00:00
Matt Corallo
3f2efcdfa7 Take the full funding transaction from the user on generation
Instead of relying on the user to ensure the funding transaction is
correct (and panicing when it is confirmed), we should check it is
correct when it is generated. By taking the full funding transaciton
from the user on generation, we can also handle broadcasting for
them instead of doing so via an event.
2021-04-09 19:59:06 -04:00
Matt Corallo
dba0709b08
Merge pull request #861 from lightning-signer/degenerify
De-generify Sign methods
2021-04-09 23:57:20 +00:00
Matt Corallo
32a9a82396 Add missing EOF newline 2021-04-09 19:57:12 -04:00
Matt Corallo
021959f822
Merge pull request #866 from TheBlueMatt/2021-04-log-err-node
Log the node generating an onion error
2021-04-09 22:23:14 +00:00
Devrandom
0821fb3de0 Test that BaseSign can have a vtable 2021-04-09 11:20:58 +02:00
Devrandom
14e094adc1 Move Writeable from BaseSign to Sign 2021-04-09 11:20:58 +02:00
Devrandom
db0287137f Separate Clone from Sign
Clone requires Sized, which prevents Sign from being a dyn object.
2021-04-09 11:19:22 +02:00
Devrandom
b69ae07c11 Eliminate unnecessary generics from Sign
The generic methods prevent Sign from being a dyn object.

Use Secp256k1<All> as part of removing generics from Secp256k1 contexts passed into Sign methods.
2021-04-09 11:19:22 +02:00
Matt Corallo
d3231a2391
Merge pull request #815 from TheBlueMatt/2021-03-router-fuzzzzzzzz
Track full-path htlc-minimum-msat while routing
2021-04-08 02:06:13 +00: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
Matt Corallo
e23c270720
Merge pull request #838 from TheBlueMatt/2021-03-skip-blocks
Make `Channel`'s block connection API more electrum-friendly
2021-04-05 22:12:45 +00:00
Matt Corallo
47ad3d6bd8 Handle 1-conf funding_locked in channel no matter the event order
See comment in the diff for more details
2021-04-05 17:33:04 -04:00
Matt Corallo
5cd1857c55 Allow changing the way we [dis]connect blocks in funtional tests 2021-04-05 17:33:04 -04:00
Matt Corallo
c88b707ac2 Drop ChannelManager::block_disconnected() entirely
It is now entirely redundant with ChannelManager::update_best_block
and is still accessible via `Listen::block_disconnected`.
2021-04-05 17:33:04 -04:00
Matt Corallo
a15c8541dc Make the ChannelManager::block_connected API more electrum-friendly
See the similar commit that operates on `Channel`'s internal API
for more details on the reasoning.
2021-04-05 17:33:04 -04:00
Matt Corallo
d255d91a2a Log the node generating an onion error 2021-04-05 16:23:34 -04:00
Matt Corallo
60b962a18e Move ChannelManager to Channel's new block data API
This also moves the scanning of the block for commitment
transactions into channel, unifying the error path.
2021-04-05 13:03:04 -04:00
Matt Corallo
871f414367 More regularly send an Error message when we force-close a channel
When we force-close a channel, for whatever reason, it is nice to
send an error message to our peer. This allows them to closes the
channel on their end instead of trying to send through it and
failing. Further, it may induce them to broadcast their commitment
transaction, possibly getting that confirmed and saving us on fees.

This commit adds a few more cases where we should have been sending
error messages but weren't. It also includes an almost-global
replace in tests of the second argument in
`check_closed_broadcast!()` from false to true (indicating an error
message is expected). There are only a few exceptions, notably
those where the closure is the result of our counterparty having
sent *us* an error message.
2021-04-05 13:03:04 -04:00
Matt Corallo
2a432c6fa5 Make Channel's block connection API more electrum-friendly
Electrum clients primarily operate in a world where they query (and
subscribe to notifications for) transactions by script_pubkeys.
They may never learn very much about the actual blockchain and
orient their events around individual transactions, not the
blockchain.

This makes our ChannelManager interface somewhat more amenable to
such a client by splitting `block_connected` into
`transactions_confirmed` and `update_best_block`. The first handles
checking the funding transaction and storing its height/confirmation
block, whereas the second handles funding_locked and reorg logic.

Sadly, this interface is somewhat easy to misuse - notifying the
channel of the funding transaction being reorganized out of the
chain is complicated when the only notification received is that
a new block is connected at a given height. This will be addressed
in a future commit.
2021-04-02 13:32:34 -04:00
Matt Corallo
494d7dd4be Switch to height-based funding-tx tracking from conf-based tracking
Previously, we expected every block to be connected in-order,
allowing us to track confirmations by simply incrementing a counter
for each new block connected. In anticipation of moving to a
update-height model in the next commit, this moves to tracking
confirmations by simply storing the height at which the funding
transaction was confirmed.

This commit also corrects our "funding was reorganized out of the
best chain" heuristic, instead of a flat 6 blocks, it uses half the
confirmation count required as the point at which we force-close.

Even still, for low confirmation counts (eg 1 block), an ill-timed
reorg may still cause spurious force-closes, though that behavior
is not new in this commit.
2021-04-02 13:32:34 -04:00
Matt Corallo
8a9f0b8ced Also benchmark sending funds with a FilesystemPersister 2021-04-01 15:15:36 -04:00
Matt Corallo
780625674d Cache our node ID in ChannelManager
While its not necessarily a common operation on a running node,
`get_our_node_id()` is used incredibly heavily in tests, and there
is no reason to not eat the extra ~64 bytes to just cache it.
2021-03-31 19:55:25 -04:00