Commit graph

2902 commits

Author SHA1 Message Date
Matt Corallo
08cb01e6ef Mark IndexedMap types as (C-not exported)
While we could try to expose the type explicitly, we already have
alternative accessors for bindings, and mapping `Hash`, `Ord` and
the other requirements for `IndexedMap` would be a good chunk of
additional work.
2023-03-01 00:21:23 +00:00
Matt Corallo
2c15bb437e Remove peers from the node_id_to_descriptor even without init
When a peer has finished the noise handshake, but has not yet
completed the lightning `Init`-based handshake, they will be
present in the `node_id_to_descriptor` set, even though
`Peer::handshake_complete()` returns false. Thus, when we go to
disconnect such a peer, we must ensure that we remove it from the
descriptor set as well.

Failing to do so caused an `Inconsistent peers set state!` panic in
the C bindings network handler.
2023-02-28 21:40:20 +00:00
Wilmer Paulino
0b1a64f12d
Merge pull request #2046 from TheBlueMatt/2023-02-rgs-robust-and-log
Do not fail to apply RGS updates for removed channels
2023-02-28 11:36:04 -08:00
Matt Corallo
df20bcf188 Make log macros more usable outside of the lightning crate
... by using explicit paths rather than requiring imports.
2023-02-28 17:56:16 +00:00
Wilmer Paulino
8311581fe1
Merge pull request #2006 from TheBlueMatt/2023-02-no-recursive-read-locks
Refuse recursive read locks
2023-02-28 00:24:16 -08:00
Matt Corallo
065dc6e689 Make sure individual mutexes are constructed on different lines
Our lockdep logic (on Windows) identifies a mutex based on which
line it was constructed on. Thus, if we have two mutexes
constructed on the same line it will generate false positives.
2023-02-28 01:06:35 +00:00
Matt Corallo
f082ad40b5 Disallow taking two instances of the same mutex at the same time
Taking two instances of the same mutex may be totally fine, but it
requires a total lockorder that we cannot (trivially) check. Thus,
its generally unsafe to do if we can avoid it.

To discourage doing this, here we default to panicing on such locks
in our lockorder tests, with a separate lock function added that is
clearly labeled "unsafe" to allow doing so when we can guarantee a
total lockorder.

This requires adapting a number of sites to the new API, including
fixing a bug this turned up in `ChannelMonitor`'s `PartialEq` where
no lockorder was guaranteed.
2023-02-28 01:06:35 +00:00
Matt Corallo
9c08fbd435 Refuse recursive read locks in lockorder testing
Our existing lockorder tests assume that a read lock on a thread
that is already holding the same read lock is totally fine. This
isn't at all true. The `std` `RwLock` behavior is
platform-dependent - on most platforms readers can starve writers
as readers will never block for a pending writer. However, on
platforms where this is not the case, one thread trying to take a
write lock may deadlock with another thread that both already has,
and is attempting to take again, a read lock.

Worse, our in-tree `FairRwLock` exhibits this behavior explicitly
on all platforms to avoid the starvation issue.

Thus, we shouldn't have any special handling for allowing recursive
read locks, so we simply remove it here.
2023-02-28 01:06:35 +00:00
Matt Corallo
2c8a26c6d2 Don't per_peer_state read locks recursively in monitor updating
When handling a `ChannelMonitor` update via the new
`handle_new_monitor_update` macro, we always call the macro with
the `per_peer_state` read lock held and have the macro drop the
per-peer state lock. Then, when handling the resulting updates, we
may take the `per_peer_state` read lock again in another function.

In a coming commit, recursive read locks will be disallowed, so we
have to drop the `per_peer_state` read lock before calling
additional functions in `handle_new_monitor_update`, which we do
here.
2023-02-28 01:06:35 +00:00
Matt Corallo
38374dde42 Expect callers to hold read locks before channel_monitor_updated
Our existing lockorder tests assume that a read lock on a thread
that is already holding the same read lock is totally fine. This
isn't at all true. The `std` `RwLock` behavior is
platform-dependent - on most platforms readers can starve writers
as readers will never block for a pending writer. However, on
platforms where this is not the case, one thread trying to take a
write lock may deadlock with another thread that both already has,
and is attempting to take again, a read lock.

Worse, our in-tree `FairRwLock` exhibits this behavior explicitly
on all platforms to avoid the starvation issue.

Sadly, a user ended up hitting this deadlock in production in the
form of a call to `get_and_clear_pending_msg_events` which holds
the `ChannelManager::total_consistency_lock` before calling
`process_pending_monitor_events` and eventually
`channel_monitor_updated`, which tries to take the same read lock
again.

Luckily, the fix is trivial, simply remove the redundand read lock
in `channel_monitor_updated`.

Fixes #2000
2023-02-28 01:06:35 +00:00
Matt Corallo
1d4bc1e0fb Hold the total_consistency_lock while in outbound_payment fns
We previously avoided holding the `total_consistency_lock` while
doing crypto operations to build onions. However, now that we've
abstracted out the outbound payment logic into a utility module,
ensuring the state is consistent at all times is now abstracted
away from code authors and reviewers, making it likely to break.

Further, because we now call `send_payment_along_path` both with,
and without, the `total_consistency_lock`, and because recursive
read locks may deadlock, it would now be quite difficult to figure
out which paths through `outbound_payment` need the lock and which
don't.

While it may slow writes somewhat, it's not really worth trying to
figure out this mess, instead we just hold the
`total_consistency_lock` before going into `outbound_payment`
functions.
2023-02-28 01:06:35 +00:00
Matt Corallo
f03b7cd448 Remove the final_cltv_expiry_delta in RouteParameters entirely
fbc08477e8 purported to "move" the
`final_cltv_expiry_delta` field to `PaymentParamters` from
`RouteParameters`. However, for naive backwards-compatibility
reasons it left the existing on in place and only added a new,
redundant field in `PaymentParameters`.

It turns out there's really no reason for this - if we take a more
critical eye towards backwards compatibility we can figure out the
correct value in every `PaymentParameters` while deserializing.

We do this here - making `PaymentParameters` a `ReadableArgs`
taking a "default" `cltv_expiry_delta` when it goes to read. This
allows existing `RouteParameters` objects to pass the read
`final_cltv_expiry_delta` field in to be used if the new field
wasn't present.
2023-02-27 22:33:21 +00:00
Matt Corallo
6aa5ebb1aa Support ReadableArgs types across in the TLV struct serialization
This adds `required` support for trait-wrapped reading (e.g. for
objects read via `ReadableArgs`) as well as support for the
trait-wrapped reading syntax across the TLV struct/enum
serialization macros.
2023-02-27 22:31:11 +00:00
Matt Corallo
9364154022 Require a non-0 number of non-empty paths when deserializing routes
When we read a `Route` (or a list of `RouteHop`s), we should never
have zero paths or zero `RouteHop`s in a path. As such, its fine to
simply reject these at deserialization-time. Technically this could
lead to something which we can generate not round-trip'ing
serialization, but that seems okay here.
2023-02-27 22:31:11 +00:00
Matt Corallo
bb0f696466 Fix silent rebase conflict in previous PR 2023-02-27 18:28:40 +00:00
Matt Corallo
a0c65c32a5
Merge pull request #2043 from valentinewallace/2023-02-initial-send-path-fails
`PaymentPathFailed`: add initial send error details
2023-02-27 18:10:27 +00:00
Matt Corallo
16b3c720a6
Merge pull request #2025 from TheBlueMatt/2023-02-no-pub-genesis-hashes
Remove genesis block hash from public API
2023-02-27 17:50:22 +00:00
Valentine Wallace
f2f90d5fb0
Fix PaymentPathFailed generation and scid on initial send 2023-02-25 16:13:43 -05:00
Valentine Wallace
1dcb3ecb6c
Change PaymentPathFailed's optional network update to a Failure enum
This let us capture the errors when we fail without committing to an HTLC vs
failing via update_fail.
2023-02-25 16:13:42 -05:00
Valentine Wallace
8d686d83cb
Implement writeable for APIError 2023-02-25 16:13:42 -05:00
Valentine Wallace
34f8c39630
ser_macros: Document behavior of upgradable_* variants 2023-02-25 16:13:42 -05:00
Valentine Wallace
5d0ee867ea
Fix upgradable_required fields to actually be required in lower level macros
When using lower level macros such as read_tlv_stream, upgradable_required
fields have been treated as regular options. This is incorrect, they should
either be upgradable_options or treated as required fields.
2023-02-25 16:13:39 -05:00
Matt Corallo
f71daed02d
Merge pull request #1977 from jkczyz/2023-01-offers-fuzz
BOLT 12 deserialization fuzzers
2023-02-25 18:03:51 +00:00
Valentine Wallace
70c7161dbe
Rename OptionDeserWrapper->RequiredWrapper
Makes more sense and sets us up for the UpgradableRequired version of it
2023-02-24 20:00:14 -05:00
Valentine Wallace
0e88538b78
Disambiguate ignorable and ignorable_option
Would rather not rename ignorable to ignorable_required, so rename both of them
to upgradable_*
2023-02-24 14:21:11 -05:00
Valentine Wallace
52551a9fc8
Support deserializing an Option-al MaybeReadable
Prior to this change, our impl_writeable_tlv_based macros only supported
deserializing a MaybeReadable if it's non-Optional.
2023-02-24 14:21:11 -05:00
Valentine Wallace
2037a241f4
Remove all_paths_failed from PaymentPathFailed
This field was previous useful in manual retries for users to know when all
paths of a payment have failed and it is safe to retry. Now that we support
automatic retries in ChannelManager and no longer support manual retries, the
field is no longer useful.

For backwards compat, we now always write false for this field. If we didn't do
this, previous versions would default this field's value to true, which can be
problematic because some clients have relied on the field to indicate when a
full payment retry is safe.
2023-02-24 14:21:08 -05:00
Jeffrey Czyz
9c2a3d090b
Fix amount overflow in Invoice building
An overflow can occur when multiplying the offer amount by the requested
quantity when no amount is given in the request. Return an error instead
of overflowing.
2023-02-23 18:25:50 -06:00
Jeffrey Czyz
32ed69a2bd
Fix amount overflow in Offer parsing and building
An overflow can occur when multiplying the offer amount by the requested
quantity when checking if the given amount is enough. Return an error
instead of overflowing.
2023-02-23 18:25:50 -06:00
Jeffrey Czyz
56a01de61d
Expose Bech32Encode trait for fuzzing
In order to fuzz test Bech32Encode parsing independent of the underlying
message deserialization, the trait needs to be exposed. Conditionally
expose it only for fuzzing.
2023-02-23 18:25:49 -06:00
Jeffrey Czyz
e049e97993
Fuzz test for parsing InvoiceRequest
An invoice request is serialized as a TLV stream and encoded as bytes.
Add a fuzz test that parses the TLV stream and deserializes the
underlying InvoiceRequest. Then compare the original bytes with those
obtained by re-serializing the InvoiceRequest.
2023-02-23 18:24:41 -06:00
Matt Corallo
d7c818a3ad Rename BestBlock::from_genesis to from_network for clarity 2023-02-24 00:22:58 +00:00
Matt Corallo
2c3e12e309 Remove genesis block hash from public API
Forcing users to pass a genesis block hash has ended up being
error-prone largely due to byte-swapping questions for bindings
users. Further, our API is currently inconsistent - in
`ChannelManager` we take a `Bitcoin::Network` but in `NetworkGraph`
we take the genesis block hash.

Luckily `NetworkGraph` is the only remaining place where we require
users pass the genesis block hash, so swapping it for a `Network`
is a simple change.
2023-02-24 00:22:58 +00:00
Valentine Wallace
f361aa62a4
Add missing import path in ser macro 2023-02-23 17:04:04 -05:00
Matt Corallo
46fd7035b3
Merge pull request #2014 from valentinewallace/2023-02-rework-partial-pmt-fail
Rework auto-retry send errors
2023-02-23 21:54:16 +00:00
Valentine Wallace
a6e9123d3f
Clarify Retry::Timeout vs PaymentParams::expiry_time in docs 2023-02-23 15:50:25 -05:00
Valentine Wallace
12bcc9ae43
Fix outdated PendingOutboundPayment::Abandoned docs 2023-02-23 15:50:25 -05:00
Valentine Wallace
1224dac862
On initial send retries, avoid previously failed scids
Previously, we could have tried the same failed channels over and over until
retries are exhausted.
2023-02-23 15:50:25 -05:00
Valentine Wallace
b826d1735d
In-line retry_with_route method
Since it's only used one place now
2023-02-23 15:50:25 -05:00
Valentine Wallace
d471d9746c
Rework auto retry send errors
Prior to this, we returned PaymentSendFailure from auto retry send payment
methods. This implied that we might return a PartialFailure from them, which
has never been the case. So it makes sense to rework the errors to be a better
fit for the methods.

We're taking error handling in a totally different direction now to make it
more asynchronous, see send_payment_internal for more information.
2023-02-23 15:50:23 -05:00
Valentine Wallace
5e4f0bcff0
Fix InvalidRoute error to be ChannelUnavailable
InvalidRoute is reserved for malformed routes, not routes where a channel or
its peer is unavailable
2023-02-22 23:05:43 -05:00
Matt Corallo
96c8507fbf
Merge pull request #1897 from TheBlueMatt/2022-11-monitor-updates-always-async
Always process `ChannelMonitorUpdate`s asynchronously
2023-02-22 19:12:31 +00:00
Matt Corallo
2adb8eeb49 Don't generate a ChannelMonitorUpdate for closed chans on shutdown
The `Channel::get_shutdown` docs are very clear - if the channel
jumps to `Shutdown` as a result of not being funded when we go to
initiate shutdown we should not generate a `ChannelMonitorUpdate`
as there's no need to bother with the shutdown script - we're
force-closing anyway.

However, this wasn't actually implemented, potentially causing a
spurious monitor update for no reason.
2023-02-22 17:34:46 +00:00
Matt Corallo
685b08d8c1 Use the new monitor persistence flow for funding_created handling
Building on the previous commits, this finishes our transition to
doing all message-sending in the monitor update completion
pipeline, unifying our immediate- and async- `ChannelMonitor`
update and persistence flows.
2023-02-22 17:34:46 +00:00
Matt Corallo
c35253d6a8 Use new monitor persistence flow in funding_signed handling
In the previous commit, we moved all our `ChannelMonitorUpdate`
pipelines to use a new async path via the
`handle_new_monitor_update` macro. This avoids having two message
sending pathways and simply sends messages in the "monitor update
completed" flow, which is shared between sync and async monitor
updates.

Here we reuse the new macro for handling `funding_signed` messages
when doing an initial `ChannelMonitor` persistence. This provides
a similar benefit, simplifying the code a trivial amount, but
importantly allows us to fully remove the original
`handle_monitor_update_res` macro.
2023-02-22 17:34:46 +00:00
Matt Corallo
4e002dcf5c Always process ChannelMonitorUpdates asynchronously
We currently have two codepaths on most channel update functions -
most methods return a set of messages to send a peer iff the
`ChannelMonitorUpdate` succeeds, but if it does not we push the
messages back into the `Channel` and then pull them back out when
the `ChannelMonitorUpdate` completes and send them then. This adds
a substantial amount of complexity in very critical codepaths.

Instead, here we swap all our channel update codepaths to
immediately set the channel-update-required flag and only return a
`ChannelMonitorUpdate` to the `ChannelManager`. Internally in the
`Channel` we store a queue of `ChannelMonitorUpdate`s, which will
become critical in future work to surface pending
`ChannelMonitorUpdate`s to users at startup so they can complete.

This leaves some redundant work in `Channel` to be cleaned up
later. Specifically, we still generate the messages which we will
now ignore and regenerate later.

This commit updates the `ChannelMonitorUpdate` pipeline across all
the places we generate them.
2023-02-22 17:34:46 +00:00
Matt Corallo
46c6fb7f91 Move TODO from handle_monitor_update_res into Channel
The TODO mentioned in `handle_monitor_update_res` about how we
might forget about HTLCs in case of permanent monitor update
failure still applies in spite of all our changes. If a channel is
drop'd in general, monitor-pending updates may be lost if the
monitor update failed to persist.

This was always the case, and is ultimately the general form of the
the specific TODO, so we simply leave comments there
2023-02-22 00:51:13 +00:00
Matt Corallo
9802afa53b Handle MonitorUpdateCompletionActions after monitor update sync
In a previous PR, we added a `MonitorUpdateCompletionAction` enum
which described actions to take after a `ChannelMonitorUpdate`
persistence completes. At the time, it was only used to execute
actions in-line, however in the next commit we'll start (correctly)
leaving the existing actions until after monitor updates complete.
2023-02-22 00:51:13 +00:00
Matt Corallo
d5fb804a32 Limit the number of pending un-funded inbound channel
Because we store some (not large, but not zero) state per-peer,
it's useful to limit the number of peers we have connected, at
least with some buffer.

Much more importantly, each channel has a relatively large cost,
especially around the `ChannelMonitor`s we have to build for each.

Thus, here, we limit the number of channels per-peer which aren't
(yet) on-chain, as well as limit the number of (inbound) peers
which don't have a (funded-on-chain) channel.

Fixes #1889
2023-02-21 22:01:47 +00:00
Matt Corallo
4155f54716 Add an inbound flag to the peer_connected message handlers
Its useful for the message handlers to know if a peer is inbound
for DoS decision-making reasons.
2023-02-21 22:00:42 +00:00