Matt Corallo [Thu, 23 Sep 2021 04:02:58 +0000 (04:02 +0000)]
Make method time on trait impl explitit to help bindings generator
Associated types in C bindings is somewhat of a misnomer - we
concretize each trait to a single struct. Thus, different trait
implementations must still have the same type, which defeats the
point of associated types.
In this particular case, however, we can reasonably special-case
the `Infallible` type, as an instance of it existing implies
something has gone horribly wrong.
In order to help our bindings code figure out how to do so when
referencing a parent trait's associated type, we specify the
explicit type in the implementation method signature.
Matt Corallo [Wed, 22 Sep 2021 19:00:30 +0000 (19:00 +0000)]
Use Infallible for the unconstructable default custom message type
When we landed custom messages, we used the empty tuple for the
custom message type for `IgnoringMessageHandler`. This was fine,
except that we also implemented `Writeable` to panic when writing
a `()`. Later, we added support for anchor output construction in
CommitmentTransaction, signified by setting a field to `Some(())`,
which is serialized as-is.
This causes us to panic when writing a `CommitmentTransaction`
with `opt_anchors` set. Note that we never set it inside of LDK,
but downstream users may.
Instead, we implement `Writeable` to write nothing for `()` and use
`core::convert::Infallible` for the default custom message type as
it is, appropriately, unconstructable.
This also makes it easier to implement various things in bindings,
as we can always assume `Infallible`-conversion logic is
unreachable.
Matt Corallo [Wed, 22 Sep 2021 03:57:53 +0000 (03:57 +0000)]
Make `ChainMonitor::get_claimable_balances` take a slice of refs
For the same reason as `get_route`, a slice of objects isn't
practical to map to bindings - the objects in the bindings space
are structs with a pointer and some additional metadata. Thus, to
create a slice of them, we'd need to take ownership of the objects
behind the pointer, place them into a slace, and then restore them
to the pointer.
This would be a lot of memory copying and marshalling, not to
mention wouldn't be thread-safe, which the same function otherwise
would be if we used a slice of references instead of a slice of
objects.
Matt Corallo [Wed, 22 Sep 2021 01:04:35 +0000 (01:04 +0000)]
Move trait bounds on `wire::Type` from use to the trait itself
`wire::Type` is only (publicly) used as the `CustomMessage`
associated type in `CustomMessageReader`, where it has additional
trait bounds on `Debug` and `Writeable`. The documentation for
`Type` even mentions that you need to implement `Writeable` because
this is the one place it is used.
To make this more clear, we move the type bounds onto the trait
itself and not on the associated type.
This is also the only practical way to build C bindings for `Type`
as we cannot have a concrete, single, `Type` struct in C which only
optionally implements various subtraits, at least not without
runtime checking of the type bounds.
In 8ffc2d1742ff1171a87b0410b21cbbd557ff8247, in 0.0.100, we added
a backwards compatibility feature to the reading of `Event`s - if
the type was unknown and odd, we'd simply ignore the event and
treat it as no event. However, we failed to read the
length-prefixed TLV stream when doing so, resulting in us reading
some of the skipped-event data as the next event or other data in
the ChannelManager.
We fix this by reading the varint length prefix written, then
skipping that many bytes when we come across an unknown odd event
type.
Antoine Riard [Tue, 21 Sep 2021 16:25:38 +0000 (12:25 -0400)]
Add ChannelClosed generation at cooperative/force-close/error processing
When we detect a channel `is_shutdown()` or call on it
`force_shutdown()`, we notify the user with a Event::ChannelClosed
informing about the id and closure reason.
Matt Corallo [Tue, 21 Sep 2021 18:09:15 +0000 (18:09 +0000)]
Fix a panic in Route's new fee-calculation methods and clean up
This addresses Val's feedback on the new Route fee- and
amount-calculation methods, including fixing the panic she
identified and cleaning up various docs and comments.
Add methods to count total fees and total amount in a Route #999
* Added `get_total_fees` method to route,
to calculate all the fees paid accross each path.
* Added `get_total_amount` method to route,
to calculate the total of actual amounts paid in each path.
Matt Corallo [Sun, 29 Aug 2021 06:03:41 +0000 (06:03 +0000)]
Convert most P2P msg serialization to a new macro with TLV suffixes
The network serialization format for all messages was changed some
time ago to include a TLV suffix for all messages, however we never
bothered to implement it as there isn't a lot of use validating a
TLV stream with nothing to do with it. However, messages are
increasingly utilizing the TLV suffix feature, and there are some
compatibility concerns with messages written as a part of other
structs having their format changed (see previous commit).
Thus, here we go ahead and convert most message serialization to a
new macro which includes a TLV suffix after a series of fields,
simplifying several serialization implementations in the process.
Matt Corallo [Sun, 29 Aug 2021 02:55:39 +0000 (02:55 +0000)]
Add forward-compat due serialization variants of HTLCFailureMsg
Going forward, all lightning messages have a TLV stream suffix,
allowing new fields to be added as needed. In the P2P protocol,
messages have an explicit length, so there is no implied length in
the TLV stream itself. HTLCFailureMsg enum variants have messages
in them, but without a size prefix or any explicit end. Thus, if a
HTLCFailureMsg is read as a part of a ChannelManager, with a TLV
stream at the end, there is no way to differentiate between the end
of the message and the next field(s) in the ChannelManager.
Here we add two new variant values for HTLCFailureMsg variants in
the read path, allowing us to switch to the new values if/when we
add new TLV fields in UpdateFailHTLC or UpdateFailMalformedHTLC so
that older versions can still read the new TLV fields.
Matt Corallo [Sun, 29 Aug 2021 05:26:39 +0000 (05:26 +0000)]
Drop writer size hinting/message vec preallocation
In order to avoid significant malloc traffic, messages previously
explicitly stated their serialized length allowing for Vec
preallocation during the message serialization pipeline. This added
some amount of complexity in the serialization code, but did avoid
some realloc() calls.
Instead, here, we drop all the complexity in favor of a fixed 2KiB
buffer for all message serialization. This should not only be
simpler with a similar reduction in realloc() traffic, but also
may reduce heap fragmentation by allocating identically-sized
buffers more often.
Matt Corallo [Wed, 25 Aug 2021 20:13:01 +0000 (20:13 +0000)]
Add an accessor to `ChainMonitor` to get the claimable balances
The common user desire is to get the set of claimable balances for
all non-closed channels. In order to do so, they really want to
just ask their `ChainMonitor` for the set of balances, which they
can do here by passing the `ChannelManager::list_channels` output
to `ChainMonitor::get_claimable_balances`.
Matt Corallo [Wed, 4 Aug 2021 15:16:43 +0000 (15:16 +0000)]
Track how our HTLCs are resolved on-chain persistently
This tracks how any HTLC outputs in broadcast commitment
transactions are resolved on-chain, storing the result of the HTLC
resolution persistently in the ChannelMonitor.
This can be used to determine which outputs may still be available
for claiming on-chain.
Decorate the user-supplied EventHandler with NetGraphMsgHandler in
the BackgroundProcessor. The resulting handler will intercept
PaymentFailed events in order to update the NetworkGraph in the
background before delegating to the user's event handler.
Jeffrey Czyz [Thu, 12 Aug 2021 21:02:42 +0000 (16:02 -0500)]
EventHandler for applying NetworkUpdate
PaymentFailed events contain an optional NetworkUpdate describing
changes to the NetworkGraph as conveyed by a node along a failed payment
path according to BOLT 4. An EventHandler should apply the update to the
graph so that future routing decisions can account for it.
Implement EventHandler for NetGraphMsgHandler to update NetworkGraph.
Previously, NetGraphMsgHandler::handle_htlc_fail_channel_update
implemented this behavior.
Jeffrey Czyz [Thu, 12 Aug 2021 20:30:53 +0000 (15:30 -0500)]
Refactor PaymentFailureNetworkUpdate event
MessageSendEvent::PaymentFailureNetworkUpdate served as a hack to pass
an HTLCFailChannelUpdate from ChannelManager to NetGraphMsgHandler via
PeerManager. Instead, remove the event entirely and move the contained
data (renamed NetworkUpdate) to Event::PaymentFailed to be processed by
an event handler.
Matt Corallo [Mon, 6 Sep 2021 03:25:27 +0000 (03:25 +0000)]
Move CounterpartyForwardingInfo from channel to channelmanager
CounterpartyForwardingInfo is public (previously exposed with a
`pub use`), and used inside of ChannelCounterparty in
channelmanager.rs. However, it is defined in channel.rs, away from
where it is used.
This would be fine, except that the bindings generator is somewhat
confused by this - it doesn't currently support interpreting
`pub use` as a struct to expose, instead ignoring it.
Jeffrey Czyz [Tue, 10 Aug 2021 14:47:27 +0000 (09:47 -0500)]
Remove RwLock from around NetworkGraph
Now that NetworkGraph uses interior mutability, the RwLock used around
it in NetGraphMsgHandler is no longer needed. This allows for shared
ownership without a lock.
Jeffrey Czyz [Tue, 10 Aug 2021 03:24:41 +0000 (22:24 -0500)]
Individually lock NetworkGraph fields
In preparation for giving NetworkGraph shared ownership, wrap individual
fields in RwLock. This allows removing the outer RwLock used in
NetGraphMsgHandler.
Matt Corallo [Thu, 9 Sep 2021 01:09:41 +0000 (01:09 +0000)]
Reduce our stated max closing-transaction fee to be the true value
When communicating the maximum fee we're willing to accept on a
cooperative closing transaction to our peer, we currently tell them
we'll accept `u64::max_value()` if they're the ones who have to pay
it. Spec-wise this is fine - they aren't allowed to try to claim
our balance, and we don't care how much of their own funds they
want to spend on transaction fees.
However, the Eclair folks prefer to check all values on the wire
do not exceed 21 million BTC, which seems like generally good
practice to avoid overflows and such issues. Thus, our close
messages are rejected by Eclair.
Here we simply relax our stated maximum to be the real value - our
counterparty's current balance in satoshis.
Matt Corallo [Tue, 24 Aug 2021 23:15:07 +0000 (23:15 +0000)]
[invoice] Ignore InvalidLength fields
BOLT 11 states that a reader "MUST skip over...`p`, `h`, `s` or `n`
fields that do NOT have data_lengths of 52, 52, 52 or 53,
respectively." Here we do so by simply ignoring any invalid-length
field.
Matt Corallo [Sun, 22 Aug 2021 19:42:29 +0000 (19:42 +0000)]
Convert the invoice creation API to millisats and req it for parse
The BOLT 11 invalid invoice test vectors suggest failing to parse
invoices which have an amount which is not a whole number of
millisatoshis. lightning-invoice, however, happily parses such
invoices. While we could continue to parse them, failing them makes
for one less check on the user code side, so we might as well.
In order to keep the invoice creation less likely to fail, we also
switch the Builder amount-setting function to use millisatoshis.
Matt Corallo [Sun, 22 Aug 2021 19:36:01 +0000 (19:36 +0000)]
[invoice] Fix non-recoverable sig handling and bogus SI prefix err
This adds two additional tests from the BOLT 11 invalid invoice
tests, fixing the two errors that broke them. It fixes a panic on
the "nonrecoverable signature" test and makes the error variant
more sensible on the bogus SI prefix test.
abhik-99 [Mon, 9 Aug 2021 15:06:51 +0000 (20:36 +0530)]
Multi-Hop Route Hint as per Bolt 12 now considered
Bolt 12 details the process of picking up route hints from payee
using the lightning invoice. This PR brings the changes to use
multiple route hints from payee picked from the invoice.
The route hints are processed in the following manner:-
- `get_route()` receives the hints in `last_hops`.
- Every `RouteHintHop` in `RouteHint` is processed based on
feasiblity of channel capacity and fees.
- If a `RouteHintHop` then preceeding `RouteHintHop`s are not
processed.
- A direct route is checked from `first_hops_targets` to the
first `RouteHintHop` if the respective `RouteHint` is
processed from the payee's end till the first `RouteHintHop`.
`partial_route_hint_test`, `ignores_empty_last_hops_test`,
`multi_hint_last_hops_test` and `last_hops_with_public_channel_test`
test usage of partial route hints for building optimal route,
processing empty route hint hops, complete usage of private route
hints and presence of public channels in route hints respectively.