When a lightning node wishes to send payments to a BIP 353 human
readable name (using BOLT 12), it first has to resolve that name to
a DNS TXT record. bLIP 32 defines a way to do so over onion
messages, and this completes our implementation thereof by adding
the server side.
It operates by simply accepting new messages and spawning tokio
tasks to do DNS lookups using the `dnsse_prover` crate. It also
contains full end-to-end tests of the BIP 353 -> BOLT 12 -> payment
logic using the new server code to do the resolution.
Note that because we now have a workspace crate which sets the
"lightning/dnssec" feature in its `dev-dependencies`, a naive
`cargo test` will test the "dnssec" feature.
Now that `ChannelManager` supports using bLIP 32 to resolve BIP 353
Human Readable Names we should encourage users to use that feature
by making the "default" (in various type aliases) to use
`ChannelManager` as the `DNSResolverMessageHandler`.
Now that we have the ability to resolve BIP 353 Human Readable
Names directly and have tracking for outbound payments waiting on
an offer resolution, we can implement full BIP 353 support in
`ChannelManager`.
Users will need one or more known nodes which offer DNS resolution
service over onion messages using bLIP 32, which they pass to
`ChannelManager::pay_for_offer_from_human_readable_name`, as well
as the `HumanReadableName` itself.
From there, `ChannelManager` asks the DNS resolver to provide a
DNSSEC proof, which it verifies, parses into an `Offer`, and then
pays.
For those who wish to support on-chain fallbacks, sadly, this will
not work, and they'll still have to use `OMNameResolver` directly
in order to use their existing `bitcoin:` URI parsing.
When we receive a payment to an offer we issued resolved with a
human readable name, it may have been resolved using a wildcard
DNS entry which we want to map to a specific recipient account
locally. To do this, we need the human readable name from the
`InvoiceRequest` in the `PaymentClaim{able,ed}`, which we pipe
through here using `InvoiceRequestFields`.
When we resolve a Human Readable Name to a BOLT 12 `offer`, we may
end up resolving to a wildcard DNS name covering all possible
`user` parts. In that case, if we just blindly pay the `offer`, the
recipient would have no way to tell which `user` we paid.
Instead, BOLT 12 defines a field to include the HRN resolved in the
`invoice_request`, which we implement here.
We also take this opportunity to remove constant parameters from
the `outbound_payment.rs` interface to `channelmanager.rs`
Domain names implicitly have a trailing `.`, which we require in
bLIP 32 but generally shouldn't be exposing to the user in
`HumanReadableName`s (after all, they're human-readable). Here we
make sure the trailing `.` is dropped in `HumanReadableName`s
before we re-add them when building the bLIP 32 messages.
When creating an InvoiceRequests, users may choose to either use a
transient signing pubkey generated by LDK or provide a static one.
Disallow the latter as it allows users to reuse the same pubkey, which
results in poor sender privacy.
If we're receiving a keysend to a blinded path, then we created the payment
secret within. Using our inbound_payment_key, we can decrypt the payment secret
bytes to get the payment's min_cltv_expiry_delta and min amount, to verify the
payment is valid. However, if we're receiving an MPP keysend *not* to a blinded
path, then we did not create the payment secret and shouldn't verify it since
it's only used to correlate MPP parts.
Therefore, store whether the payment secret is recipient-generated in our pending
inbound payment data so we know whether to verify it or not.
Bolt11InvoiceParameters allows for setting currency and
duration_since_epoch. If currency is not set, test that the one
corresponding to ChannelManager's chain hash is usd. If
duration_since_epoch, is not set then highest seen timestamp is used in
non-std compilations.
ChannelManager::create_bolt11_invoice is a simpler and more flexible way
of creating a BOLT11 invoice, so deprecate the corresponding functions
in the invoice_utils module.
Now that the lightning crate depends on the lightning_invoice crate, the
utility functions previously living in the latter can be implemented on
ChannelManager. Additionally, the parameters are now moved to a struct
in order to remove the increasingly combinatorial blow-up of methods.
The new Bolt11InvoiceParameters is used to determine what values to set
in the invoice. Using None for any given parameter results in a
reasonable the default or a behavior determined by the ChannelManager as
detailed in the documentation.
When creating an invoice using a ChannelManager, payments for a specific
ChainHash / Network are only valid. Use the one from the ChannelManager
instead of allowing arbitrary ones in the form of a Currency.
Add a new payment type for this, because normally the payment hash is factored
into the payment secrets we create for invoices, but static invoices don't have
a payment hash since they are paid via keysend.
This key will be used in upcoming commits for encrypting metadata bytes for
spontaneous payments' payment secrets, to be included in the blinded paths of
static invoices for async payments. We need a new type of payment secret for
these payments because they don't have an a prior known payment hash, see the
next commit.
LDK versions prior to 0.0.104 had stateful inbound payments written in this
map. In 0.0.104, we added support for stateless inbound payments with
deterministically generated payment secrets, and maintained deprecated support
for stateful inbound payments until 0.0.116. After 0.0.116, no further inbound
payments could have been written into this map.
The upcoming ChannelManager::create_bolt11_invoice will not support
setting a specific creation time, so remove that functionality from the
invoice_utils functions. This will avoid duplicate code when
deprecating.
Try to make it a bit more clear that there are downsides to solely
relying on `lightning-net-tokio`, and it's still recommended to
occasionally call this function in a separate loop.
1b711ed15f changed it so that we can
enqueue broadcast gossip messages to peers even though their buffer
is full as long as its our `ChannelMessageHandler` doing it. This
broke a debug assertion that the buffer isn't too large when
appending the broadcast message which is simply dropped here.
Found by the `full_stack_target` fuzzer.
The BOLT12 spec defines an experimental TLV range that is allowed in
offer and invoice_request messages. The remaining TLV-space is for
experimental use in invoice messages. Allow this range when parsing an
invoice and include it when signing one.
Payer metadata is generated from the invreq TLVs and should included
those in the experimental range. When verifying invoice messages, these
TLVs must be included. Modify the BOLT12 verification tests to cover
them.
The BOLT12 spec defines an experimental TLV range that are allowed in
invoice_request messages. Allow this range when parsing an invoice
request and include those bytes in any invoice. Also include those bytes
when verifying that a Bolt12Invoice is for a valid InvoiceRequest.
Offer metadata is generated from the offer TLVs and should included
those in the experimental range. When verifying invoice request and
invoice messages, these TLVs must be included. Similarly, OfferId
construction should included these TLVs as well. Modify the BOLT12
verification tests to cover these TLVs.
The BOLT12 spec defines an experimental TLV range that are allowed in
offer messages. Allow this range when parsing an offer and include those
bytes in any invoice requests. Also include those bytes when computing
an OfferId and verifying that an InvoiceRequest is for a valid Offer.
Upcoming commits will allow parsing BOLT12 messages that include TLV
records in the experimental range. Include these ranges when verifying
messages since they will be included in the message bytes.
Passing bytes directly to InvoiceContents::verify improves readability
as then a TlvStream for each TLV record range can be created from the
bytes instead of needing to clone the TlvStream upfront. In an upcoming
commit, the experimental TLV record range will utilize this.
Add a utility function for iterating over Offer TLV records contained in
any valid TLV stream bytes. Using a common function ensures that
experimental TLV records are included once they are supported.