BOLT 12 messages are limited to a range of TLV record types. Refactor
decode_tlv_stream into a decode_tlv_stream_range macro for limiting
which types are parsed. Requires a SeekReadable trait for rewinding when
a type outside of the range is seen. This allows for composing TLV
streams of different ranges.
Updates offer parsing accordingly and adds a test demonstrating failure
if a type outside of the range is included.
Add common bech32 parsing for BOLT 12 messages. The encoding is similar
to bech32 only without a checksum and with support for continuing
messages across multiple parts.
Messages implementing Bech32Encode are parsed into a TLV stream, which
is converted to the desired message content while performing semantic
checks. Checking after conversion allows for more elaborate checks of
data composed of multiple TLV records and for more meaningful error
messages.
The parsed bytes are also saved to allow creating messages with mirrored
data, even if TLV records are unknown.
As it was previously omitted, we clarify here starting from which version users can expect the `user_channel_id` to be randomized for inbound channels.
When we mark a future as complete, if the user is using the
`std::future::Future` impl to get notified, we shouldn't just
assume we have completed the `Future` when we call the `Waker`. A
`Future` may have been `drop`'d at that point (or may not be
`poll`'d again) even though we wake the `Waker`.
Because we now have a `callbacks_made` flag, we can fix this rather
trivially, simply not setting the flag until the `Future` is
`poll`'d `Complete`.
When we return from one of the wait functions in `Notifier`, we
should also ensure that the next `Future` doesn't start in the
`complete` state, as we have already notified the user, as far as
we're concerned.
This is technically a regression from the previous commit, but as
it is a logically separate change it is in its own commit.
If a `Notifier` gets `notify()`ed and the a `Future` is fetched,
even though the `Future` is marked completed from the start and
the user may pass callbacks which are called, we'll never wipe the
needs-notify bit in the `Notifier`.
The solution is to keep track of the `FutureState` in the returned
`Future` even though its `complete` from the start, adding a new
flag in the `FutureState` which indicates callbacks have been made
and checking that flag when waiting or returning a second `Future`.
We increase the `user_channel_id` type from `u64` to `u128`. In order to
maintain backwards compatibility, we have to de-/serialize it as two
separate `u64`s in `Event` as well as in the `Channel` itself.
After the first persistence-required `Future` wakeup, we'll always
complete additional futures instantly as we don't clear the
"need wake" bit. Instead, we need to just assume that if a future
was generated (and not immediately drop'd) that its sufficient to
notify the user.
Add a builder for creating offers given a required description and
node_id. Other settings are optional and duplicative settings will
override previous settings for non-Vec fields.
BOLT 12's offer message is encoded as a TLV stream (i.e., a sequence of
TLV records). impl_writeable_tlv_based can't be used because it writes
the overall length of the struct, whereas TLV streams only include the
length of each TLV record. Add a `tlv_stream` macro for defining structs
used in encoding.
TLV records containing a single variable-length type should not encode
the types length in the value since it is redundant. Add a wrapper type
that can be used within a TLV stream to support the correct behavior
during serialization and de-serialization.
When serializing variable-length types as part of a TLV stream, the
length does not need to be serialized as it is already encoded in TLV
records. Add a WithoutLength wrapper for this encoding. Replace
VecReadWrapper and VecWriteWrapper with this single type to avoid
redundant encoders.
Define an interface for BOLT 12 `offer` messages. The underlying format
consists of the original bytes and the parsed contents.
The bytes are later needed when constructing an `invoice_request`
message. This is because it must mirror all the `offer` TLV records,
including unknown ones, which aren't represented in the contents.
The contents will be used in `invoice_request` messages to avoid
duplication. Some fields while required in a typical user-pays-merchant
flow may not be necessary in the merchant-pays-user flow (i.e., refund).
Strings defined by third parties may contain control characters. Provide
a wrapper such that these are replaced when displayed. Useful in node
aliases and offer fields.
When the `abandon_payment` flow was added there was some concern
that upgrading users may not migrate to the new flow, causing
memory leaks in the pending-payment tracking.
While this is true, now that we're relying on the
pending_outbound_payments map for `send_payment` idempotency, the
risk of removing a payment prematurely goes up from "spurious
retry failure" to "sending a duplicative payment", which is much
worse.
Thus, we simply remove the automated payment timeout here,
explicitly requiring that users call `abandon_payment` when they
give up retrying a payment.
+ remove MaybeReadableArgs trait as it is now unused
+ remove onion_utils::DecodeInput as it would've now needed to be parameterized
by the CustomOnionMessageHandler trait, and we'd like to avoid either
implementing DecodeInput in messenger or having onion_utils depend on
onion_message::*
Co-authored-by: Matt Corallo <git@bluematt.me>
Co-authored-by: Valentine Wallace <vwallace@protonmail.com>
Useful since we're working on getting rid of KeysInterface::get_node_secret to
complete support for remote signing.
Will be used in upcoming work to check whether an outbound onion message
blinded path has our node id as the introduction node id
If the initial ChannelMonitor persistence is done asynchronously
but does not complete before the node restarts (with a
ChannelManager persistence), we'll start back up with a channel
present but no corresponding ChannelMonitor.
Because the Channel is pending-monitor-update and has not yet
broadcasted its initial funding transaction or sent channel_ready,
this is not a violation of our API contract nor a safety violation.
However, the previous code would refuse to deserialize the
ChannelManager treating it as an API contract violation.
The solution is to test for this case explicitly and drop the
channel entirely as if the peer disconnected before we received
the funding_signed for outbound channels or before sending the
channel_ready for inbound channels.