Commit graph

1253 commits

Author SHA1 Message Date
Matt Corallo
16f742833e Move PaymentId to a [u8; 32] in bindings as for other hash objects
This should allow us to fix
https://github.com/lightningdevkit/ldk-garbagecollected/issues/52
2021-10-30 01:53:19 +00: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
Matt Corallo
070e22bf09
Merge pull request #1137 from TheBlueMatt/2021-10-ping-fixes
Give peers which are sending us messages/receiving messages from us longer to respond to ping
2021-10-28 20:57:21 +00:00
Matt Corallo
0caa8bb5d5 Log peer public key more thoroughly when logging in peer_handler 2021-10-28 20:06:47 +00:00
Matt Corallo
be123f7d22 Give peers one timer tick to finish handshake before disconnecting
This ensures we don't let a hung connection stick around forever if
the peer never completes the initial handshake.

This also resolves a race where, on receiving a second connection
from a peer, we may reset their_node_id to None to prevent sending
messages even though the `channel_encryptor`
`is_ready_for_encryption()`. Sending pings only checks the
`channel_encryptor` status, not `their_node_id` resulting in an
`unwrap` on `None` in `enqueue_message`.
2021-10-28 20:06:47 +00:00
Matt Corallo
ed4a39fe1e Give peers which are sending us messages longer to respond to ping
See comment for rationale.
2021-10-28 20:06:47 +00:00
Matt Corallo
3f9a7de188 Util-ify enqueueing an encoded message in peer_handler
This marginally simplifies coming commits.
2021-10-28 20:06:47 +00:00
Matt Corallo
e496c9beb6 Constify the ratio in buf limits between forward and init sync msgs 2021-10-28 20:06:47 +00:00
Matt Corallo
04d4a8f835 Track the amount spent on fees as payments are retried
Especially once we merge the `InvoicePayer` logic soon, we'll want
to expose the total fee paid in the `PaymentSent` event.
2021-10-27 20:43:18 +00:00
Matt Corallo
af94db8111 Pass the failing/succeeding Path to PendingOutboundPayment meths
This will make the next commit much simpler
2021-10-27 20:43:18 +00:00
Jeffrey Czyz
2d102a3065
Unify route finding methods
An upcoming Router interface will be used for finding a Route both when
initially sending a payment and also when retrying failed payment paths.
Unify the three varieties of get_route so the interface can consist of a
single method implemented by the new `find_route` method. Give get_route
pub(crate) visibility so it can still be used in tests.
2021-10-26 20:15:19 -05:00
Jeffrey Czyz
73f601fd3d
Add PaymentId to PaymentPathFailed event
The PaymentId is needed when retrying payments. Include it in the
PaymentPathFailed event so it can be used in that manner.
2021-10-26 01:12:30 -05:00
Jeffrey Czyz
3410f1803a
Add PaymentId to PaymentSent event
The payment_hash may not uniquely identify the payment if it has been
reused. Include the payment_id in PaymentSent events so it can
correlated with the send_payment call.
2021-10-26 01:12:30 -05:00
Matt Corallo
4a58e9ad83 Add PeerManager::disconnect_all_peers to avoid complexity in BP
In the coming commits simply calling `timer_tick_occurred` will no
longer disconnect all peers, so its helpful to have a utility
method.
2021-10-26 02:04:34 +00:00
Matt Corallo
1b99c93334 Store Payee information in HTLCSource::OutboundRoute.
This stores and tracks HTLC payee information with HTLCSource info,
allowing us to provide it back to the user if the HTLC fails and
ensuring persistence by keeping it with the HTLC itself as it
passes between Channel and ChannelMonitor.
2021-10-25 19:40:58 +00:00
Matt Corallo
fe237f9280 Copy Payee into Routes to provide them to ChannelManager 2021-10-25 17:58:18 +00:00
Matt Corallo
ca103491eb
Merge pull request #1134 from jkczyz/2021-10-payee-arg
Payee abstraction for use in get_route and PaymentPathFailed
2021-10-25 16:09:06 +00:00
Jeffrey Czyz
46b68c517d
Include PaymentPathRetry data in PaymentPathFailed
When a payment path fails, it may be retried. Typically, this means
re-computing the route after updating the NetworkGraph and channel
scores in order to avoid the failing hop. The last hop in
PaymentPathFailed's path field contains the pubkey, amount, and CLTV
values needed to pass to get_route. However, it does not contain the
payee's features and route hints from the invoice.

Include the entire set of parameters in PaymentPathRetry and add it to
the PaymentPathFailed event. Add a get_retry_route wrapper around
get_route that takes PaymentPathRetry. This allows an EventHandler to
retry failed payment paths using the payee's route hints and features.
2021-10-25 10:18:11 -05:00
Jeffrey Czyz
b5be4c210c
Define Payee abstraction for use in get_route
A payee can be identified by a pubkey and optionally have an associated
set of invoice features and route hints. Use this in get_route instead
of three separate parameters. This may be included in PaymentPathFailed
later to use when finding a new route.
2021-10-25 10:18:11 -05:00
Matt Corallo
db2e7e75c4 Support send/recv'ing the new channel_type field in open_channel
This implements the channel type negotiation, though as we currently
only support channels with only static_remotekey set, it doesn't
implement the negotiation explicitly.
2021-10-22 19:38:17 +00:00
Matt Corallo
b7a8dd4a1d Support de/ser of the new channel_type field in open_channel 2021-10-22 19:34:18 +00:00
Matt Corallo
e847c87dc2 Add a ChannelTypeFeatures features object for the new channel_type
Its semantics are somewhat different from existing features,
however not enough to merit a different struct entirely.
Specifically, it only supports required features (if you send a
channel_type, the counterparty has to accept it wholesale or try
again, it cannot select only a subset of the flags) and it is
serialized differently (only appearing in TLVs).
2021-10-22 19:34:18 +00:00
Matt Corallo
7af5d127ac Add a test of an HTLC being fulfilled and then later failed
Peers probably shouldn't do this, but if they want to give us free
money, we should take it and not generate any spurious events.
2021-10-22 18:41:42 +00:00
Matt Corallo
251eb3bda8 Move test_dup_htlc_onchain_fails_on_reload to payment_tests
test_dup_htlc_onchain_fails_on_reload is now more of a
payment_test than a functional_test, testing for handling of
pending payments.
2021-10-22 18:41:42 +00:00
Matt Corallo
5296a4a04d Add some basic test coverage of monitor payment data reloading 2021-10-22 18:41:42 +00:00
Matt Corallo
fe660c5786 Reload pending payments from ChannelMonitor HTLC data on reload
If we go to send a payment, add the HTLC(s) to the channel(s),
commit the ChannelMonitor updates to disk, and then crash, we'll
come back up with no pending payments but HTLC(s) ready to be
claim/failed.

This makes it rather impractical to write a payment sender/retryer,
as you cannot guarantee atomicity - you cannot guarantee you'll
have retry data persisted even if the HTLC(s) are actually pending.

Because ChannelMonitors are *the* atomically-persisted data in LDK,
we lean on their current HTLC data to figure out what HTLC(s) are a
part of an outbound payment, rebuilding the pending payments list
on reload.
2021-10-22 18:41:42 +00:00
Matt Corallo
0d5050833d Add PaymentSecrets to HTLCSource::OutboundRoute objects 2021-10-22 18:41:42 +00:00
Matt Corallo
2727c52d3c Rename payment object vars to refer to payments and not session IDs 2021-10-22 18:41:42 +00:00
Matt Corallo
5fedae85d1 Track payments after they resolve until all HTLCs are finalized
In the next commit, we will reload lost pending payments from
ChannelMonitors during restart. However, in order to avoid
re-adding pending payments which have already been fulfilled, we
must ensure that we do not fully remove pending payments until all
HTLCs for the payment have been fully removed from their
ChannelMonitors.

We do so here, introducing a new PendingOutboundPayment variant
called `Completed` which only tracks the set of pending HTLCs.
2021-10-22 18:41:42 +00:00
Matt Corallo
f624cc9ac2 Inform ChannelManager when fulfilled HTLCs are finalized
When an HTLC has been failed, we track it up until the point there
exists no broadcastable commitment transaction which has the HTLC
present, at which point Channel returns the HTLCSource back to the
ChannelManager, which fails the HTLC backwards appropriately.

When an HTLC is fulfilled, however, we fulfill on the backwards path
immediately. This is great for claiming upstream HTLCs, but when we
want to track pending payments, we need to ensure we can check with
ChannelMonitor data to rebuild pending payments. In order to do so,
we need an event similar to the HTLC failure event, but for
fulfills instead.

Specifically, if we force-close a channel, we remove its off-chain
`Channel` object entirely, at which point, on reload, we may notice
HTLC(s) which are not present in our pending payments map (as they
may have received a payment preimage, but not fully committed to
it). Thus, we'd conclude we still have a retryable payment, which
is untrue.

This commit does so, informing the ChannelManager via a new return
element where appropriate of the HTLCSource corresponding to the
failed HTLC.
2021-10-22 18:41:42 +00:00
Matt Corallo
fcb178faeb Make Channel::monitor_updating_restored's return tuple a struct
This improves readability at the callsite and in the function.
2021-10-22 18:41:42 +00:00
Matt Corallo
c54d4703f5 Make Channel::revoke_and_ack's return tuple a struct
This substantially improves readability at the callsite and in the
function.
2021-10-22 18:41:42 +00:00
Matt Corallo
107c6c7939
Merge pull request #1108 from TheBlueMatt/2021-10-persist-mon-blocks
Persist ChannelMonitors after new blocks are connected
2021-10-20 00:53:26 +00:00
Matt Corallo
3016ed2d91 Update test_dup_htlc_onchain_fails_on_reload for new persist API
ChannelMonitors now require that they be re-persisted before
MonitorEvents be provided to the ChannelManager, the exact thing
that test_dup_htlc_onchain_fails_on_reload was testing for when it
*didn't* happen. As such, test_dup_htlc_onchain_fails_on_reload is
now testing that we bahve correctly when the API guarantees are not
met, something we don't need to do.

Here, we adapt it to test the new API requirements through
ChainMonitor's calls to the Persist trait instead.
2021-10-20 00:06:18 +00:00
Matt Corallo
5c2ff2cb30 Persist ChannelMonitors after new blocks are connected
This resolves several user complaints (and issues in the sample
node) where startup is substantially delayed as we're always
waiting for the chain data to sync.

Further, in an upcoming PR, we'll be reloading pending payments
from ChannelMonitors on restart, at which point we'll need the
change here which avoids handling events until after the user
has confirmed the `ChannelMonitor` has been persisted to disk.
It will avoid a race where we
 * send a payment/HTLC (persisting the monitor to disk with the
   HTLC pending),
 * force-close the channel, removing the channel entry from the
   ChannelManager entirely,
 * persist the ChannelManager,
 * connect a block which contains a fulfill of the HTLC, generating
   a claim event,
 * handle the claim event while the `ChannelMonitor` is being
   persisted,
 * persist the ChannelManager (before the CHannelMonitor is
   persisted fully),
 * restart, reloading the HTLC as a pending payment in the
   ChannelManager, which now has no references to it except from
   the ChannelMonitor which still has the pending HTLC,
 * replay the block connection, generating a duplicate PaymentSent
   event.
2021-10-20 00:06:17 +00:00
Matt Corallo
89ad059548 Use an opaque type to describe monitor updates in Persist
In the next commit, we'll be originating monitor updates both from
the ChainMonitor and from the ChannelManager, making simple
sequential update IDs impossible.

Further, the existing async monitor update API was somewhat hard to
work with - instead of being able to generate monitor_updated
callbacks whenever a persistence process finishes, you had to
ensure you only did so at least once all previous updates had also
been persisted.

Here we eat the complexity for the user by moving to an opaque
type for monitor updates, tracking which updates are in-flight for
the user and only generating monitor-persisted events once all
pending updates have been committed.
2021-10-19 23:49:04 +00:00
Matt Corallo
4500270488 Move ChannelManager::monitor_updated to a MonitorEvent
In the next commit we'll need ChainMonitor to "see" when a monitor
persistence completes, which means `monitor_updated` needs to move
to `ChainMonitor`. The simplest way to then communicate that
information to `ChannelManager` is via `MonitorEvet`s, which seems
to line up ok, even if they're now constructed by multiple
different places.
2021-10-19 23:49:04 +00:00
Matt Corallo
df8bde9b2e Move the two-AtomicUsize counter in peer_handler to a util struct
We also take this opportunity to drop byte_utils::le64_to_array, as
our MSRV now supports the native to_le_bytes() call.
2021-10-18 22:04:56 +00:00
Matt Corallo
001bc7113a
Merge pull request #1121 from TheBlueMatt/2021-10-return-temp-id
Expose temporary channel ID and user channel ID pre-funding
2021-10-16 02:15:07 +00:00
Matt Corallo
2398f1746d
Merge pull request #1124 from jkczyz/2021-10-default-channel-scoring
Add channel scoring to get_route
2021-10-16 01:58:15 +00:00
Matt Corallo
bb7ef6c290 Rename create_channel param to user_channel_id to standardize it 2021-10-16 00:27:04 +00:00
Jeffrey Czyz
e15a18a503
Add channel scoring to get_route
Failed payments may be retried, but calling get_route may return a Route
with the same failing path. Add a routing::Score trait used to
parameterize get_route, which it calls to determine how much a channel
should be penalized in terms of msats willing to pay to avoid the
channel.

Also, add a Scorer struct that implements routing::Score with a constant
constant penalty. Subsequent changes will allow for more robust scoring
by feeding back payment path success and failure to the scorer via event
handling.
2021-10-15 15:29:49 -05:00
Matt Corallo
c396dc6ee5 Use Persister to return errors in tests not chain::Watch
As ChainMonitor will need to see those errors in a coming PR,
we need to return errors via Persister so that our ChainMonitor
chain::Watch implementation sees them.
2021-10-14 00:19:42 +00:00
Matt Corallo
49dbabff27 Simplify channelmonitor tests which use chain::Watch and Persister
test_simple_monitor_permanent_update_fail and
test_simple_monitor_temporary_update_fail both have a mode where
they use either chain::Watch or persister to return errors.

As we won't be doing any returns directly from the chain::Watch
wrapper in a coming commit, the chain::Watch-return form of the
test will no longer make sense.
2021-10-14 00:19:12 +00:00
Matt Corallo
79541b11e8 Make ChainMonitor::monitors private and expose monitor via getter
Exposing a `RwLock<HashMap<>>` directly was always a bit strange,
and in upcoming changes we'd like to change the internal
datastructure in `ChainMonitor`.

Further, the use of `RwLock` and `HashMap` meant we weren't able
to expose the ChannelMonitors themselves to users in bindings,
leaving a bindings/rust API gap.

Thus, we take this opportunity go expose ChannelMonitors directly
via a wrapper, hiding the internals of `ChainMonitor` behind
getters. We also update tests to use the new API.
2021-10-14 00:17:31 +00:00
Matt Corallo
6a7c48b60d Move ChannelMonitorUpdateErr to chain as it is a chain::Watch val 2021-10-14 00:16:50 +00:00
Matt Corallo
0dfb24e661 Move Persist trait to chainmonitor as that's the only reference 2021-10-14 00:16:50 +00:00
Jeffrey Czyz
d4ec090bb8
Move mpp_failure test to payment_tests.rs 2021-10-13 18:37:05 -05:00
Jeffrey Czyz
0a5ccd1f13
Replace get_route with get_route_and_payment_hash
The interface for get_route will change to take a scorer. Using
get_route_and_payment_hash whenever possible allows for keeping the
scorer inside get_route_and_payment_hash rather than at every call site.

Replace get_route with get_route_and_payment_hash wherever possible.
Additionally, update get_route_and_payment_hash to use the known invoice
features and the sending node's logger.
2021-10-13 18:37:01 -05:00