In other languages (Java and C#, notably), overriding `Eq` without
overriding `Hash` can lead to surprising or broken behavior. Even
in Rust, its usually the case that you actually want both. Here we
add missing `Hash` derivations for P2P messages, to at least
address the first pile of warnings the C# compiler dumps.
Implementation of standard traits on arrays longer than 32 elements
was shipped in rustc 1.47, which is below our MSRV of 1.48 and we
can use to remove some unnecessary manual implementation of
`PartialEq` on `OnionPacket`.
This breaks backwards compatibility with versions of LDK prior to
0.0.113 as they expect to always read signer data.
This also substantially reduces allocations during `ChannelManager`
serialization, as we currently don't pre-allocate the `Vec` that
the signer gets written in to. We could alternatively pre-allocate
that `Vec`, but we've been set up to skip the write entirely for a
while, and 0.0.113 was released nearly a year ago. Users
downgrading to LDK 0.0.112 and before at this point should not be
expected.
When we check gossip message signatures, there's no reason to
serialize out the full gossip message before hashing, and it
generates a lot of allocations during the initial startup when we
fetch the full gossip from peers.
Whenever we go to send bytes to a peer, we need to construct a
waker for tokio to call back into if we need to finish sending
later. That waker needs some reference to the peer's read task to
wake it up, hidden behind a single `*const ()`. To do this, we'd
previously simply stored a `Box<tokio::mpsc::Sender>` in that
pointer, which requires a `clone` for each waker construction. This
leads to substantial malloc traffic.
Instead, here, we replace this box with an `Arc`, leaving a single
`tokio::mpsc::Sender` floating around and simply change the
refcounts whenever we construct a new waker, which we can do
without allocations.
When we forward gossip messages, we store them in a separate buffer
before we encrypt them (and commit to the order in which they'll
appear on the wire). Rather than storing that buffer encoded with
no headroom, requiring re-allocating to add the message length and
two MAC blocks, we here add the headroom prior to pushing it into
the gossip buffer, avoiding an allocation.
When buffering outbound messages for peers, `LinkedList` adds
rather substantial allocation overhead, which we avoid here by
swapping for a `VecDeque`.
When decrypting P2P messages, we already have a read buffer that we
read the message into. There's no reason to allocate a new `Vec` to
store the decrypted message when we can just overwrite the read
buffer and call it a day.
We end up generating a substantial amount of allocations just
doubling `Vec`s when serializing to them, and our
`serialized_length` method is generally rather effecient, so we
just rely on it and allocate correctly up front.
We change the Bolt12Invoice struct to carry a tagged hash. Because
message_digest is then only used in one place, we can inline it in
the TaggedHash constructor.
When we're reading a `NetworkGraph`, we know how many
nodes/channels we are reading, there's no reason not to
pre-allocate the `IndexedMap`'s inner `HashMap` and `Vec`, which we
do here.
This seems to reduce on-startup heap fragmentation with glibc by
something like 100MiB.
By default, LDK will generate the initial temporary channel ID for you.
However, in certain cases, it's desirable to have a temporary channel ID
specified by the caller in case of any pre-negotiation that needs to
happen between peers prior to the channel open message. For example, LND
has a `FundingShim` API that allows for advanced funding flows based on
the temporary channel ID of the channel.
This patch adds support for optionally specifying the temporary channel
ID of the channel through the `create_channel` API.
Adds a `get_signer` method to the context so that a test can get ahold of the
channel signer. Adds a `set_available` method on the `TestChannelSigner` to
allow a test to enable and disable the signer: when disabled some of the
signer's methods will return `Err` which will typically activate the error
handling case. Adds a `set_channel_signer_available` function on the test
`Node` class to make it easy to enable and disable a specific signer.
Adds a new `async_signer_tests` module:
* Check for asynchronous handling of `funding_created` and `funding_signed`.
* Check that we correctly resume processing after awaiting an asynchronous
signature for a `commitment_signed` event.
* Verify correct handling during peer disconnect.
* Verify correct handling for inbound zero-conf.
If sign_counterparty_commitment fails (i.e. because the signer is
temporarily disconnected), this really indicates that we should
retry the message sending which required the signature later,
rather than force-closing the channel (which probably won't even
work if the signer is missing).
This commit adds retrying of inbound funding_created signing
failures, regenerating the `FundingSigned` message, attempting to
re-sign, and sending it to our peers if we succeed.
If sign_counterparty_commitment fails (i.e. because the signer is
temporarily disconnected), this really indicates that we should
retry the message sending which required the signature later,
rather than force-closing the channel (which probably won't even
work if the signer is missing).
This commit adds retrying of outbound funding_created signing
failures, regenerating the `FundingCreated` message, attempting to
re-sign, and sending it to our peers if we succeed.
If sign_counterparty_commitment fails (i.e. because the signer is
temporarily disconnected), this really indicates that we should
retry the message sending which required the signature later,
rather than force-closing the channel (which probably won't even
work if the signer is missing).
This commit adds initial retrying of failures, specifically
regenerating commitment updates, attempting to re-sign the
`CommitmentSigned` message, and sending it to our peers if we
succed.
If sign_counterparty_commitment fails (i.e. because the signer is
temporarily disconnected), this really indicates that we should
retry the message sending which required the signature later,
rather than force-closing the channel (which probably won't even
work if the signer is missing).
Here we add initial handling of sign_counterparty_commitment
failing during inbound channel funding, setting a flag in
`ChannelContext` which indicates we should retry sending the
`funding_signed` later. We don't yet add any ability to do that
retry.
If sign_counterparty_commitment fails (i.e. because the signer is
temporarily disconnected), this really indicates that we should
retry the message sending which required the signature later,
rather than force-closing the channel (which probably won't even
work if the signer is missing).
Here we add initial handling of sign_counterparty_commitment
failing during outbound channel funding, setting a new flag in
`ChannelContext` which indicates we should retry sending the
`funding_created` later. We don't yet add any ability to do that
retry.
If sign_counterparty_commitment fails (i.e. because the signer is
temporarily disconnected), this really indicates that we should
retry the message sending later, rather than force-closing the
channel (which probably won't even work if the signer is missing).
Here we add initial handling of sign_counterparty_commitment
failing during normal channel operation, setting a new flag in
`ChannelContext` which indicates we should retry sending the
commitment update later. We don't yet add any ability to do that
retry.