diff --git a/bolt-simple-taproot.md b/bolt-simple-taproot.md new file mode 100644 index 000000000..07fd2d5ae --- /dev/null +++ b/bolt-simple-taproot.md @@ -0,0 +1,2025 @@ +# Extension BOLT XX: Simple Taproot Channels + +Authors: + * Olaoluwa Osuntokun + * Eugene Siegel + +Created: 2022-04-20 + +# Table of Contents + +- [Introduction](#introduction) + * [Abstract](#abstract) + * [Motivation](#motivation) + * [Preliminaries](#preliminaries) + + [Pay-To-Taproot-Outputs](#pay-to-taproot-outputs) + - [Tapscript Tree Semantics](#tapscript-tree-semantics) + - [BIP 86](#bip-86) + - [Taproot Key Path Spends](#taproot-key-path-spends) + - [Taproot Script Path Spends](#taproot-script-path-spends) + + [MuSig2 & Associated Changes](#musig2--associated-changes) + - [Key Aggregation](#key-aggregation) + - [Nonce Generation](#nonce-generation) + - [Nonce Handling](#nonce-handling) + - [Signing](#signing) + + [Nothing Up My Sleeves Points](#nothing-up-my-sleeves-points) + * [Design Overview](#design-overview) + * [Specification](#specification) + + [Feature Bits](#feature-bits) + + [New TLV Types](#new-tlv-types) + + [Channel Funding](#channel-funding) + - [`open_channel` Extensions](#open_channel-extensions) + - [`accept_channel` Extensions](#accept_channel-extensions) + - [`funding_created` Extensions](#funding_created-extensions) + - [`funding_signed` Extensions](#funding_signed-extensions) + - [`channel_ready` Extensions](#channel_ready-extensions) + + [RBF Cooperative Close](#rbf-cooperative-close) + - [`shutdown` Extensions](#shutdown-extensions) + - [JIT (Just-In-Time) Nonce Pattern](#jit-just-in-time-nonce-pattern) + - [`closing_complete` Extensions](#closing_complete-extensions) + - [`closing_sig` Extensions](#closing_sig-extensions) + - [RBF Nonce Rotation Protocol](#rbf-nonce-rotation-protocol) + + [Channel Operation](#channel-operation) + - [`commitment_signed` Extensions](#commitment_signed-extensions) + - [`revoke_and_ack` Extensions](#revoke_and_ack-extensions) + + [Message Retransmission](#message-retransmission) + - [`channel_reestablish` Extensions](#channel_reestablish-extensions) + + [Funding Transactions](#funding-transactions) + + [Commitment Transactions](#commitment-transactions) + - [To Local Outputs](#to-local-outputs) + - [To Remote Outputs](#to-remote-outputs) + - [Anchor Outputs](#anchor-outputs) + + [HTLC Scripts & Transactions](#htlc-scripts--transactions) + - [Offered HTLCs](#offered-htlcs) + - [Accepted HTLCs](#accepted-htlcs) + - [HTLC Second Level Transactions](#htlc-second-level-transactions) + * [HTLC-Success Transactions](#htlc-success-transactions) + * [HTLC-Timeout Transactions](#htlc-timeout-transactions) +- [Appendix](#appendix) +- [Footnotes](#footnotes) +- [Test Vectors](#test-vectors) +- [Acknowledgements](#acknowledgements) + +# Introduction + +## Abstract + + +The activation of the Taproot soft-fork suite enables a number of updates to +the Lightning Network, allowing developers to improve the privacy, security, +and flexibility of the system. This document specifies extensions to BOLTs 2, +3, and 5 which describe new, Taproot based channels to update to the Lightning +Network to take advantage of _some_ of these new capabilities. Namely, we +mechanically translate the current funding and commitment design to utilize +`musig2` and the new tapscript tree capabilities. + +## Motivation + +The activation of Taproot grants protocol developers with a number of new tools +including: schnorr, musig2, scriptless scripts, PTLCs, merkalized script trees +and more. While it's technically possible to craft a _single_ update to the +Lightning Network to take advantage of _all_ these new capabilities, we instead +propose a step-wise update process, with each step layering on top of the prior +with new capabilities. While the ultimate realization of a more advanced +protocol may be delayed as a result of this approach, packing up smaller +incremental updates will be easier to implement and review, and may also +hasten the timeline to deploy initial taproot based channels. + +In this document, we start by revising the most fundamental component of a +Lightning Channel: the funding output. By first porting the funding output to +Segwit V1 (P2TR) `musig2` based output, we're able to re-anchor all channels in +the network with the help of dynamic commitments. Once those channels are +re-anchored, dynamic commitments allows developers to ship incremental changes +to the commitment transaction, HTLC structure, and overall channel structure -- +all without additional on-chain transactions. + +By restricting the surface area of the _initial_ update, we aim to expedite the +initial roll-out while also providing a solid base for future updates without +blocking off any interesting design paths. Implementing and shipping a +constrained update also gives implementers an opportunity to get more familiar +with the new tooling and capabilities, before tackling more advanced protocol +designs. + +## Preliminaries + +In this section we lay out some preliminary concepts, protocol flows, and +notation that'll be used later in the core channel specification. + +### Pay-To-Taproot-Outputs + +The Taproot soft fork package (BIPs +[340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki), +[341](https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki), and +[342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki)) +introduced a new +[Segwit](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki) +witness version: v1. This new witness version utilizes a new standardized +public key script template: +``` +OP_1 +``` + +The `taproot_output_key` is a 32-byte x-only `secp256k1` public key, with all +digital signatures based off of the schnorr signature scheme described in [BIP +340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki). + +A `taproot_output_key` commits to an internal key, and optional script root via +the following mapping: +``` +taproot_output_key = taproot_internal_key + tagged_hash("TapTweak", taproot_internal_key || script_root)*G +``` + +It's important to note that while `taproot_output_key` is serialized as a +32-byte public key, in order to properly spend the script path, the parity +(even or odd) of the output public key must be remembered. + +The `taproot_internal_key` is also a BIP 340 public key, ideally derived anew +for each output. The `tagged_hash` scheme is described in BIP 340, we briefly +define the function as: +``` +tagged_hash(tag, msg) = SHA256(SHA256(tag) || SHA256(tag) || msg) +``` + +#### Tapscript Tree Semantics + +The `script_root` is the root of a Tapscript tree as defined in BIP 341. A tree +is composed of `tap_leaves` and `tap_branches`. + +A `tap_leaf` is a two tuple of (`leaf_version`, `leaf_script`). A `tap_leaf` is serialized as: +``` +leaf_version || compact_size_of(leaf_script) || leaf_script +``` +where `compact_size_of` is the variable length integer used in the Bitcoin P2P +protocol. + +The digest of a `tap_leaf` is computed as: +``` +tagged_hash("TapLeaf", leaf_encoding) +``` + +where `leaf_encoding` is serialized as: +``` +leaf_version || compact_size_of(leaf_script) || leaf_script +``` + +A `tap_branch` can commit to either a `tap_leaf` or `tap_branch`. Before +hashing, a `tap_branch` sorts the two `tap_node` arguments based on +lexicographical ordering: +``` +tagged_hash("TapBranch", sort(node_1, node_2)) +``` + +A tapscript tree is constructed by hashing each pair of leaves into a +`tap_branch`, then combining these branches with each other until only a single +hash remains. There're no strict requirements at the consensus level for tree +construction, allowing systems to "weight" the tree by placing items that occur +more often at the top of the tree. A simple algorithm that attempts to [produce +a balanced script tree can be found here](https://github.com/btcsuite/btcd/blob/99e4e00345017a70eadc4e1d06353c56b23bb15c/txscript/taproot.go#L618-L776). + +#### BIP 86 + +A `taproot_output_key` doesn't necessarily _need_ to commit to a `script_root`, +unless the `script_root` is being revealed, a normal key (skipping the tweaking +operation) can be used. In many cases it's also nice to prove to a 3rd party +that the output can only be spent with a top-level signature and not also a +script path. + +[BIP 86](https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki) +defines a taproot output key derivation scheme, wherein only the internal key +is committed to without a script root: +``` +taproot_output_key = taproot_internal_key + tagged_hash("TapTweak", taproot_internal_key)*G +``` + +We use BIP 86 whenever we want to ensure that a script path spend isn't +possible, and an output can only be spent via a key path. + +We recommend that in any instances where a normal unencumbered output is used +(cooperative closures, etc) BIP 86 is used as well. + +#### Taproot Key Path Spends + +A taproot key path spend a transaction to spend a taproot output without +revealing the script root, which may or may not exist. + +The witness of a keypath spend is simply a 64 or 65 byte schnorr signature. A +signature is 64 bytes if the new `SIGHASH_DEFAULT` alias for `SIGHASH_ALL` is +being used. Otherwise a single byte for the sighash type is used as normal: +``` + +``` + +If an output commits to a script root (or uses BIP 86), a private key will need +to be tweaked in order to generate a valid signature, and negated if the +resulting output key has an odd y coordinate (see BIP 341 for details). + +For any revocation path based on a key spend (the HTLC revocation paths), the +tap tweak value MUST be known in order to spend the out unilaterally. As a +result, it's recommend that for a given revoked state, the tap tweak value is +also stored. + +#### Taproot Script Path Spends + +A script path spend is executed when a tapscript leaf is revealed. A script +path spends has three components: a control block, the script leaf being +revealed, and the valid witness. + +A control block has the following serialization: +``` +(output_key_y_parity | leaf_version) || internal_key || inclusion_proof +``` + +The first segment uses a spare bit of the `leaf_version` to encode the parity +of the output key, which is checked during control block verification. The +`internal_key` is just that. The `inclusion_proof` is the series of sibling +hashes in the path from the revealed leaf all the way up to the root of the +tree. In practice, if one hashes the revealed leaf, and each 32-byte hash of the +inclusion proof together, they'll reach the script root if the proof was valid. + +If only a single leaf is committed to in a tree, then the `inclusion_proof` +will be absent. + +The final witness stack to spend a script path output is: +``` + ... +``` + +Note that whenever a script path spend is required, in order to ensure an +output is unilaterally spendable by a party, the finalized control block MUST +either be stored as is, or the components needed to reconstruct the control +block are persisted. + +#### SIGHASH_ALL vs SIGHASH_DEFAULT + +Where ever applicable, signers SHOULD use the `SIGHASH_DEFAULT` sighash over +`SIGHASH_ALL`. When using taproot semantics, both algorithm refer to the very +same digest, but `SIGHASH_DEFAULT` allows us to save a byte for any signature, +as omitting the explicit sighash byte denotes that the default signing +algorithm was used. + +### MuSig2 & Associated Changes + +Musig2 is a multi-signature scheme based on schnorr signatures. It allows N +parties to construct an aggregated public key, and then generate a single +multi-signature that can only be generated with all the parties of the +aggregated key. In practice, we use this to allow the funding output of +channel to look just like any other P2TR output. + +A musig2 signing flow has 4 stages: + + 1. First, each party generates a public nonce, and exchanges it with every + other party. + + 2. Next, public keys are exchanged by each party, and combined into a single + aggregated public key. + + 3. Next, each party generates a _partial_ signature and exchanges it with + every other party. + + 4. Finally, once all partial signatures are known, they can be combined into a + valid schnorr Signature, which can be verified using BIP 340. + +Steps 1&2 may be performed out of order, or concurrently. In our case only two +parties exist, so as soon as one party knows both partial signatures, they can +be combined into a final signature. + +Thought this document `musig2` refers to the finalized (v1.0.0) +[BIP-0327](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki +specification. + +#### Key Aggregation + +We refer to the algorithm of `KeyAgg` algorithm [bip-musig2 +v1.0.0](https://github.com/bitcoin/bips/blob/master/bip-0327.mediawiki) for key +aggregation. In order to avoid sending extra ordering information, we always +assume that both keys are sorted first with the `KeySort` algorithm before +aggregating (`KeyAgg(KeySort(p1, p2))`). + +#### Nonce Generation + +A `musig2` secret nonce is the concatenation of two random, 32-byte integers. + +A `musig2` public nonce is technically the concatenation of two public keys, +each representing the EC-point corresponding to its secret integer, thus +resulting in a 66-byte value: + +``` +point_1 || point_2 +``` + +For nonce generation, we refer to the `NonceGen` algorithm defined in the +`musig2` BIP. We only specify the set of required arguments, though a signer +can also opt to specify the additional argument, in order to strengthen their +nonce. + +##### Counter Based Nonce Generation & JIT Nonce Strengthening + +Each new commitment state requires fresh nonces from both parties, as each +commitment state is signed using a fresh musig2 session. Nonces sent by either +party in the `commitment_signed` message can be generated Just-In-Time (JIT), +thus requiring no additional state. These nonces can also be further +strengthened by mixing in the commitment sighash information into the nonce +generation algorithm. + +Upon channel creation, and subsequent re-establishment, a fresh set of +verification nonces are exchanged by each party. This is the nonce the party +will use to _verify_ a new incoming commitment state sent by the remote party. +In order to force close a channel, the holder of a verification nonce must use +that same nonce to counter sign the commitment transaction with the other half +of the musig2 partial signature. Rather than force an implementation to retain +additional signing state (the verification nonce) to avoid holding a "hot" +(fully broadcast able) commitment on disk, we instead recommend a counter based +approach. + +In this scenario are nonce generated via a counter is deemed to be safe as: + + 1. Each commitment state only has a single signature exchanged to counter + sign the commitment transaction. + + 2. Each commitment state has a unique number which is currently encoded as a + 48-bit integer across the sequence and lock time of the commitment + transaction. + + 3. The shachain scheme is used today to generate a fresh nonce-like value for + the revocation scheme of today's penalty based channels. + + 4. A verification nonce is only used to _sign_ a local party's commitment + transaction when they go to broadcast a force close transaction. + + 5. The remote party never sees the unaggregated partial signature the local + party will use to broadcast, only the aggregated signature is seen on chain. + + 6. As a result of all the above, a verification nonce will never be used to + sign the exact same commitment transaction, thereby avoiding nonce reuse. + +As a result, we recommend the following counter based scheme to generate +verification nonce. With this scheme, signing can remain stateless, as given +the commitment height/number of the state to sign, and the original shachain +root, the verification nonce sent by that state can be deterministically +reproduced: + + 1. Given the shachain root used to generate revocation pre-images, + `shachain_root`, derive the `sha256` hash of this value as: + `shachain_root_hash = sha256(shachain_root)`. + + 2. Derive a _new_ shachain root to be used to generate `musig2` secret nonces + via a `HMAC` invocation as: `musig2_shachain_root = hmac(msg, + shachain_root_hash)`, where `msg` is any string that can serve to uniquely + bind the produced secret to this dedicated context. A recommended value is + the ASCII string `taproot-rev-root` concatenated with the `funding_txid` + (which allows deriving distinct deterministic shachains when splicing). + + 3. Given a commitment height/number (`N`), the verification nonce to send to + the remote party party can be derived by obtaining the `Nth` shachain leaf + preimage `k_i`. The verification nonce to be derived by calling the + `musig2.NonceGen` algorithm with the required values, and the `rand'` + value set to `k_i`. + +#### Nonce Handling + +For commitment transactions, Due to the asymmetric state of the current +revocation channels, two sets of public nonces need to be exchanged by each +party: one for the local commitment, and one for the remote commitment. + +The nonce for the local commitment MUST be sent a priori, thus enabling the +counterparty to create a valid partial signature. + +The nonce for the remote commitment _could_ be sent a priori, too, but for the +purposes of simplicity and disambiguation, MUST be sent alongside the partial +signature. To that end, we will create a new data type that will be reused in +multiple TLV extensions described further down in this document. + +The exception to this is the co-op close flow: as there's only a single message +to sign, we only require a single pair of nonces. These nonces can also be sent +right as the co-op flow begins. + +Note that if nonces for commitment updates are not generated using the counter +based scheme described above, then the nonces MUST be persisted to disk. As a +result, in order to minimize additional signing state, it is recommended that +the shachain counter nonce scheme is used. + +#### Nonce Terminology + +At all times, there exist _two_ nonces associated with a given commitment +state: the signing nonce, and the verification nonce. + +A peer's signing nonce is used to generate new commitments for the remote +party. Each time a party signs a commitment, they send another signing nonce +to the remote party. + +A peer's verification nonce is used to verify incoming commitments sent by the +remote party. Once a peer verifies and revoke a new commitment, another +verification nonce is sent to the remote party. + +Both sides will maintain a `musig2` sessions for their local commitment and the +commitment of the remote party. A peer's local commitment uses their +verification nonce, and the signing nonce of the remote party. The remote +commitment of the channel peer uses the peer's signing nonce, and their +verification nonce. + +In order to sign and broadcast a new commitment to force close a channel, a +peer uses their _verification_ nonce to generate their final signature. + +#### Signing + +Once public nonces have been exchanged, the `NonceAgg` algorithm is used to +combine the public nonces into the aggregate nonce which will be a part of the +final signature. + +The `Sign` method is used to generate a valid partial signature, with the +`PartialSigVerify` algorithm used to verify each signature. + +Once all partial signatures are known, the `PartialSigAgg` algorithm is used to +aggregate the partial signature into a final, valid [BIP +340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) Schnorr +signature. + +##### Partial Signature Encoding + +A standard `musig2` partial signature is simply the encoding of the `s` value, +which is a 32-byte-element modulo the order of the group. + +Throughout this specification, we will be using a custom type, +`PartialSignatureWithNonce`, comprised of the aforementioned `s` value, along +with the 66-byte-encoding of the public nonce used to sign remote commitments: + +``` +s || point_1 || point_2 +``` + +### Nothing Up My Sleeves Points + +Whenever we want to ensure that a given P2TR can _only_ be spent via a script +path, we utilize a Nothing Up My Sleeve (NUMS) point. A NUMS point is an EC +point that no one knows the private key to. If no one knows the private key, +then it can't be used for key path signing, forcing the script path to always +be taken. + +We refer to the `simple_taproot_nums` as the following value: +``` +02dca094751109d0bd055d03565874e8276dd53e926b44e3bd1bb6bf4bc130a279 +``` + +The value was [generated using this +tool](https://github.com/lightninglabs/lightning-node-connect/tree/master/mailbox/numsgen), +with the seed phrase "Lightning Simple Taproot". + +## Design Overview + +With the preliminaries out of the way, we provide a brief overview of the +Simple Taproot Channel design. + +The multisig output becomes a single P2TR key, with `musig2` key aggregation +used to combine two keys into one. + +For commitment transactions, when using `nVersion = 2`, we inherit the anchor output semantics, meaning +there are two outputs used for CPFP, with all other scripts inheriting a `1 +CSV` restriction. When using `nVersion = 3`, we inherit the zero-fee +commitments semantics, where one shared anchor is used for CPFP. + +When using `nVersion = 2`, the local output of the commitment transaction uses a script-path based +revocation scheme in order to ensure that the information needed by 3rd parties +to sweep the anchor outputs is always revealed on chain. + +The remote output of the commitment transaction uses the `combined_funding_key` +as the top-level internal key, and then commits to a normal remote script if +`nVersion = 2`, or no scripts if `nVersion = 3`. + +Anchor outputs use the `local_delayedpubkey` and the `remotepubkey` of both +parties as the top-level internal key committing to the script `16 CSV`. Unless +active HTLCs exist on the commitment transaction, if a local or remote output +is missing from the commitment, its corresponding anchor must not be present, +either. + +All HTLC scripts use the revocation key as the top-level internal key. This +allows the revocation to be executed without additional on-chain bytes, and +also reduces the amount of state that nodes need to keep in order to properly +handle channel breaches. + +## Specification + +### Feature Bits + +Inheriting the structure put forth in BOLT 9, we define a new feature bit to be +placed in the `init` message, and the `node_announcement` message. + +| Bits | Name | Description | Context | Dependencies | Link | +|---------|----------------------------------------|---------------------------------------------------|----------|----------------------------------------------|---------------------------------------| +| 80/81 | `option_simple_taproot` | Node supports simple taproot channels | IN | `option_channel_type`, `option_simple_close` | TODO(roasbeef): link | +| 82/83 | `taproot_zero_fee_commitments` | Node supports taproot zero-fee transactions | IN | `option_channel_type`, `option_simple_close` | [BOLT #3][bolt03-shared-anchor] | +| 180/181 | `option_simple_taproot_staging` | Node supports simple taproot channels | IN | `option_channel_type` | TODO(roasbeef): link | +| 182/183 | `taproot_zero_fee_commitments_staging` | Node supports taproot zero-fee transactions | IN | `option_channel_type`, `option_simple_close` | [BOLT #3][bolt03-shared-anchor] | + +Note that we allocate _two_ pairs of feature bits: one the final version of +this protocol proposal, and the higher bits (+100) for preliminary experimental +deployments before this protocol extension has been finalized. This +100 +feature bit is thus refereed to as the staging feature bit. + +The Context column decodes as follows: + * `I`: presented in the `init` message. + * `N`: presented in the `node_announcement` messages + * `C`: presented in the `channel_announcement` message. + * `C-`: presented in the `channel_announcement` message, but always odd (optional). + * `C+`: presented in the `channel_announcement` message, but always even (required). + * `9`: presented in [BOLT 11](11-payment-encoding.md) invoices. + +The `option_simple_taproot` and `taproot_zero_fee_commitments` feature bits +also become defined channel types for explicit channel negotiation. + +It's important to note that given the early version of this channel type +_cannot_ be announced on the public network (gossip protocol changes are +required), the taproot channels type cannot be used as an interchangeable +default channel type. As a result, this channel type SHOULD only be used with +_explicit_ channel negotiation. Otherwise, two parties that advertise the +feature bit would not be able to open publicly advertised channels. + +Throughout this document, we assume that `option_simple_taproot` or +`taproot_zero_fee_commitments` was negotiated, and that the corresponding +channel type is used. + +### New TLV Types + +Note that these TLV types exist across different messages, but their type IDs are always the same. + +#### partial_signature_with_nonce +- type: 2 +- data: + * [`32*byte`: `partial_signature`] + * [`66*byte`: `public_nonce`] + +#### next_local_nonce +- type: 4 +- data: + * [`66*byte`: `public_nonce`] + +#### partial_signature +- type: 6 +- data: + * [`32*byte`: `partial_signature`] + +#### shutdown_nonce +- type: 8 +- data: + * [`66*byte`: `public_nonce`] + +#### next_local_nonces +- type: 22 +- data: + * [`...*nonce_entry`: `entries`] + +where `nonce_entry` is: + * [`32*byte`: `funding_txid`] + * [`66*byte`: `public_nonce`] + +### Channel Funding + +`n_a_L`: Alice's local secret nonce + +`n_B_R`: Bob's remote public nonce + +![](taproot_channel_open.jpg) + +The `open_channel` and `accept_channel` messages are extended to specify a new +TLV type that houses the `musig2` public nonces. + +We add `option_simple_taproot` to the set of defined channel types. + +#### `open_channel` Extensions + +1. `tlv_stream`: `open_channel_tlvs` +2. types: + 1. type: 4 (`next_local_nonce`) + 2. data: + * [`66*byte`:`public_nonce`] + +##### Requirements + +The sending node: + + - MUST specify the `next_local_nonce` field. + - MUST use the `NonceGen` algorithm defined in `bip-musig2` to generate + `next_local_nonce` to ensure it generates nonces in a safe manner. + - MUST not set the `announce_channel` bit. + - if `channel_type` includes `taproot_zero_fee_commitments`: + - MUST set `feerate_per_kw` to `0`. + +The receiving node MUST fail the channel if: + + - the message doesn't include a `next_local_nonce` value. + - the specified public nonce cannot be parsed as two compressed secp256k1 + points + - `channel_type` includes `taproot_zero_fee_commitments` and: + - `max_accepted_htlcs` is greater than 114. + - `feerate_per_kw` is not `0`. + +##### Rationale + +For the initial Taproot channel type (`option_simple_taproot`), musig2 nonces +must be exchanged in the first round trip (open->, <-accept). This is done to +ensure to ensure that the initiator is able to generate a valid musig2 partial +signature at the next step once the transaction to be signed is fully +specified. + +The `next_local_nonce` field will be used to verify incoming commitment +signatures. Each incoming signature will carry the newly generated nonce used +to sign the commitment transaction. At force close broadcast time, the +verification nonce is then used to sign the local party's commitment +transaction. + +#### `accept_channel` Extensions + +1. `tlv_stream`: `accept_channel_tlvs` +2. types: + 1. type: 4 (`next_local_nonce`) + 2. data: + * [`66*byte`:`public_nonce`] + +##### Requirements + +The sender: + + - MUST set `next_local_nonce` to the `musig2` public nonce used to sign local + commitments as specified by the `NonceGen` algorithm of `bip-musig2`. + +The recipient: + + - MUST reject the channel if `next_local_nonce` is absent, or cannot be + parsed as two compressed secp256k1 points + +#### `funding_created` Extensions + +1. `tlv_stream`: `funding_created_tlvs` +2. types: + 1. type: 2 (`partial_signature_with_nonce`) + 2. data: + * [`98*byte`: `partial_signature || public_nonce`] + +##### Requirements + +The sender: + + - MUST set the original, non-TLV `signature` field to a 0-byte-array of length + 64. + + - MUST sort the exchanged `funding_pubkey`s using the `KeySort` algorithm from + `bip-musig2`. + + - MUST compute the aggregated `musig2` public key from the sorted + `funding_pubkey`s using the `KeyAgg` algorithm from `bip-musig2`. + + - MUST generate a unique nonce to combine with the `next_local_nonce` + previously received in `accept_channel` using `NonceAgg` from `bip-musig2`. + + - MUST use the generated secret nonce and the calculated aggregate nonce to + construct a `musig2` partial signature for the sender's remote commitment + using the `Sign` algorithm from `bip-musig2`. + + - MUST include the partial signature and the public counterpart of the + generated nonce in + the `partial_signature_with_nonce` field. + +The recipient: + + - MUST fail the channel if `partial_signature_with_nonce` is absent. + + - MUST fail the channel if `next_local_nonce` is absent. + + - MUST compute the aggregate nonce from: + + - the `next_local_nonce` field the recipient previously sent in + `accept_channel` + + - the `public_nonce` included as part of the `partial_signature_with_nonce` + field + + - MUST verify the `partial_signature_with_nonce` field using the + `PartialSigVerifyInternal` algorithm of `bip-musig2`: + + - if the partial signature is invalid, MUST fail the channel + +#### `funding_signed` Extensions + +1. `tlv_stream`: `funding_signed_tlvs` +2. types: + 1. type: 2 (`partial_signature_with_nonce`) + 2. data: + * [`98*byte`: `partial_signature || public_nonce`] + +##### Requirements + +The sender: + + - MUST set the original, non-TLV `signature` field to a 0-byte-array of length + 64. + + - MUST sort the exchanged `funding_pubkey`s using the `KeySort` algorithm from + `bip-musig2`. + + - MUST compute the aggregated `musig2` public key from the sorted + `funding_pubkey`s using the `KeyAgg` algorithm from `bip-musig2`. + + - MUST generate a unique nonce to combine with the `next_local_nonce` + previously received in `open_channel` using `NonceAgg` from `bip-musig2`. + + - MUST use the generated secret nonce and the calculated aggregate nonce to + construct a `musig2` partial signature for the sender's remote commitment + using the `Sign` algorithm from `bip-musig2`. + + - MUST include the partial signature and the public counterpart of the + generated nonce in the `partial_signature_with_nonce` field. + +The recipient: + + - MUST fail the channel if `partial_signature_with_nonce` is absent. + + - MUST compute the aggregate nonce from: + + - the `next_local_nonce` field the recipient previously sent in + `open_channel` + + - the `public_nonce` included as part of the `partial_signature_with_nonce` + field + + - MUST verify the `partial_signature_with_nonce` field using the + `PartialSigVerifyInternal` algorithm of `bip-musig2`: + + - if the partial signature is invalid, MUST fail the channel + +#### `channel_ready` Extensions + +We add a new TLV field to the `channel_ready` message: + +1. `tlv_stream`: `channel_ready_tlvs` +2. types: + 1. type: 4 (`next_local_nonce`) + 2. data: + * [`66*byte`: `public_nonce`] + +Similar to the `next_per_commitment_point`, by sending the `next_local_nonce` +value in this message, we ensure that the remote party has our public nonce +which is required to generate a new commitment signature. + +##### Requirements + +The sender: + +- MUST set `next_local_nonce` to a fresh, unique `musig2` nonce as specified by + `bip-musig2` + +The recipient: + +- MUST fail the channel if `next_local_nonce` is absent. + +### RBF Cooperative Close + +For simple taproot channels, the cooperative close protocol uses +`closing_complete` and `closing_sig` messages (as specified in BOLT #2) with +extensions for MuSig2 signature generation and RBF (Replace-By-Fee) iterations. + +#### `shutdown` Extensions + +For taproot channels, the shutdown message includes a single nonce: + +1. type: 38 (`shutdown`) +2. data: + * ... + * [`shutdown_tlvs`:`tlvs`] + +1. `tlv_stream`: `shutdown_tlvs` +2. types: + 1. type: 8 (`shutdown_nonce`) + 2. data: + * [`66*byte`:`public_nonce`] + +The `shutdown_nonce` represents the sender's "closee nonce" - the nonce they +will use when sending `closing_sig` messages. + +Additional nonces are provided just-in-time (JIT) with signatures: + +- `closing_complete` uses `PartialSigWithNonce` which includes the sender's +closer nonce + +- `closing_sig` uses just `PartialSig` (no nonce) since the receiver already +knows the nonce + +##### Requirements + +For taproot channels: + +A sending node: + - MUST set the `shutdown_nonce` to a valid `musig2` public nonce. + - MUST use this nonce when sending `closing_sig` messages. + +A receiving node: + - MUST verify that the `shutdown_nonce` value is a valid `musig2` public nonce. + - MUST store this nonce for use when verifying the peer's `closing_sig` messages. + +#### JIT (Just-In-Time) Nonce Pattern + +Final nonces are delivered just-in-time with signatures using an asymmetric +pattern: + +- `closing_complete` uses `PartialSigWithNonce` (98 bytes) to bundle the + signature with the next closer nonce + +- `closing_sig` uses `PartialSig` (32 bytes) with a separate `NextCloseeNonce` + field + +With this pattern, we exchange the set of `closee_nonces` up front in the +`shutdown` message. When either party wants to initiate a new update, they send +`closing_complete` which includes their JIT `closer_nonce`. Sending this +signatures serves to consume the `closee_nonce` of the remote party, so then +they respond with `closing_sig`, they include a new `next_closee_nonce`. + +#### `closing_complete` Extensions + +For taproot channels, the `closing_complete` message uses `PartialSigWithNonce` +to support MuSig2 signatures with JIT nonce delivery: + +1. `tlv_stream`: `closing_tlvs` +2. types: + 1. type: 5 (`closer_no_closee`) + 2. data: + * [`98*byte`:`partial_sig_with_nonce`] + 1. type: 6 (`no_closer_closee`) + 2. data: + * [`98*byte`:`partial_sig_with_nonce`] + 1. type: 7 (`closer_and_closee`) + 2. data: + * [`98*byte`:`partial_sig_with_nonce`] + +Note: The TLV type numbers (5, 6, 7) are different from the non-taproot types +(1, 2, 3) to distinguish taproot signatures. Each `partial_sig_with_nonce` +contains: + +- 32 bytes: MuSig2 partial signature +- 66 bytes: The sender's closer nonce used to produce the partial signature + +##### Requirements + +The sender of `closing_complete` (aka. "the closer"): + + - For taproot channels (when `option_simple_taproot` was negotiated): + - MUST provide `PartialSigWithNonce` (98 bytes) in the appropriate TLV + field based on output presence + - MUST compute the aggregated `musig2` public key from the sorted + `funding_pubkey`s using the `KeyAgg` algorithm from `bip-musig2` + - For the first closing transaction: + - MUST use the `shutdown_nonce` received from the peer as their closee + nonce + - MUST use a locally generated nonce as the closer nonce + - For RBF iterations: + - MUST use the nonce extracted from the peer's previous `closing_sig` + message as their closee nonce + - MUST use a fresh locally generated nonce as the closer nonce + - MUST generate the partial signature using the `Sign` algorithm from + `bip-musig2` + +The receiver of `closing_complete` (aka. "the closee"): + + - For taproot channels: + - MUST verify that signature fields contain `PartialSigWithNonce` (98 + bytes) + - MUST extract the partial signature (first 32 bytes) and the sender's + closer nonce (remaining 66 bytes) + - MUST compute the aggregate nonce by combining the closer nonce received + with: + - For the first closing transaction: + - the `shutdown_nonce` the receiver previously sent (their closee + nonce) + - For RBF iterations: + - the `next_closee_nonce` the receiver sent in their previous + `closing_sig` message + - MUST verify the partial signature using the `PartialSigVerifyInternal` + algorithm of `bip-musig2` + - MUST store (in memory) the extracted nonce for potential future RBF + iterations + +#### `closing_sig` Extensions + +For taproot channels, the `closing_sig` message uses `PartialSig` with a +separate next nonce field: + +1. `tlv_stream`: `closing_tlvs` +2. types: + 1. type: 5 (`closer_no_closee`) + 2. data: + * [`32*byte`:`partial_sig`] + 1. type: 6 (`no_closer_closee`) + 2. data: + * [`32*byte`:`partial_sig`] + 1. type: 7 (`closer_and_closee`) + 2. data: + * [`32*byte`:`partial_sig`] + 1. type: 22 (`next_closee_nonce`) + 2. data: + * [`66*byte`:`public_nonce`] + +Note: Unlike `closing_complete`, `closing_sig` separates the signature from the +next nonce (which will be used for the *next* RBF attempt signature): + +- The partial signature (32 bytes) is sent in the appropriate TLV field based + on output presence +- The `next_closee_nonce` (66 bytes) is sent separately in TLV type 22 +- The receiver (the closer) already knows the current closee signing nonce from + either the `shutdown` message or the previous `next_closee_nonce` + +##### Requirements + +The sender of `closing_sig`: + + - For taproot channels: + - MUST provide a 32-byte partial signature in the appropriate TLV field + based on output presence + - For the first closing transaction: + - MUST use the `shutdown_nonce` sent in their own `shutdown` message as + their closee nonce + - For RBF iterations: + - MUST use the `next_closee_nonce` sent in their own previous + `closing_sig` message as their closee nonce + - MUST use the nonce provided in the `PartialSigWithNonce` message of the + received `closing_complete` message as the closer nonce. + - MUST generate the partial signature using the `Sign` algorithm from + `bip-musig2` + - MUST include `next_closee_nonce` for potential future RBF iterations + - MUST generate `next_closee_nonce` using the `NonceGen` algorithm from + `bip-musig2` if included + +The receiver of `closing_sig`: + + - For taproot channels: + - MUST verify that signature fields contain 32-byte partial signatures + - MUST use the appropriate nonces for verification: + - The sender's closee nonce (from their `shutdown` message or previous + `closing_sig`) + - The receiver's own closer nonce included in `closing_complete` + - MUST verify the partial signature using `PartialSigVerifyInternal` from + `bip-musig2` + - MUST combine both partial signatures using `PartialSigAgg` to create the + final schnorr signature + - MUST broadcast the closing transaction with the aggregated signature + - SHOULD store `next_closee_nonce` for potential future RBF iterations + +#### RBF Nonce Rotation Protocol + +For taproot channels supporting RBF cooperative close, nonces are delivered +just-in-time (JIT) with signatures using an asymmetric pattern: + +1. **Initial Exchange**: Nonces are exchanged in `shutdown` messages + - Each party sends their "closee nonce" - the nonce they'll use when signing + as the closee + - This nonce is used by the remote party when they act as closer + +2. **RBF Iterations**: Subsequent nonces are delivered with signatures + - `closing_complete` (from closer): Uses `PartialSigWithNonce` (98 bytes) + - Bundles the partial signature with the sender's closer nonce + - The bundling is necessary because the closee doesn't know this nonce yet + - `closing_sig` (from closee): Uses `PartialSig` (32 bytes) + + `NextCloseeNonce` field + - Separates the signature from the next closee nonce because this nonce + is for the *next* RBF attempt, not the one currently being signed + +3. **Asymmetric Roles**: + - **Closer**: The party sending `closing_complete`, proposing a new fee + - **Closee**: The party sending `closing_sig`, accepting the fee proposal + - Each party alternates between these roles during RBF iterations + +##### Nonce State Management + +With this JIT nonce approach for coop close, an implementation only needs to +store (in memory) the current closee nonce for the remote and local party. When +either side is ready to sign, it'll generate a new closer nonce, and send that +along with the sig. + +##### Security Considerations + +- Nonces MUST be generated using cryptographically secure randomness +- Previously used nonces MUST NOT be reused for different closing transactions + +### Channel Operation + +`n_a_L`: Alice's local secret nonce + +`n_B_R`: Bob's remote public nonce + +![](taproot_channel_operation.jpg) + +#### `commitment_signed` Extensions + +A new TLV stream is added to the `commitment_signed` message: + +1. `tlv_stream`: `commitment_signed_tlvs` +2. types: + 1. type: 2 (`partial_signature_with_nonce`) + 2. data: + * [`98*byte`: `partial_signature || public_nonce`] + +##### Requirements + +The sender: + + - MUST set the original, non-TLV `signature` field to a 0-byte-array of length + 64. + + - MUST retrieve the `musig2` public key previously aggregated from the sorted + `funding_pubkey`s using the `KeyAgg` algorithm from `bip-musig2`. + + - MUST generate a unique nonce to combine with the `next_local_nonce` + previously received in the latest of `channel_ready`, `channel_reestablish`, + or `revoke_and_ack` using `NonceAgg` from `bip-musig2`. + + - MUST use the generated secret nonce and the calculated aggregate nonce to + construct a `musig2` partial signature for the sender's remote commitment + using the `Sign` algorithm from `bip-musig2`. + + - MUST include the partial signature and the public counterpart of the + generated nonce in the `partial_signature_with_nonce` field. + + - MUST compute each HTLC signature according to + [BIP 342](https://github.com/bitcoin/bips/blob/master/bip-0342.mediawiki), as + a BIP 340 Schnorr signature (non-partial). + + - Each HTLC signature must be packed as a 64-byte byte value within the + existing `htlc_signature` field. + + +The recipient: + + - MUST fail the channel if `signature` is non-zero. + + - MUST fail the channel if `partial_signature_with_nonce` is absent. + + - MUST compute the aggregate nonce from: + + - the `next_local_nonce` field the recipient previously sent in the latest + of `channel_ready`, `channel_reestablish`, or `revoke_and_ack` + + - the `public_nonce` included as part of the `partial_signature_with_nonce` + field + + - MUST verify the `partial_signature_with_nonce` field using the + `PartialSigVerifyInternal` algorithm of `bip-musig2`: + + - if the partial signature is invalid, MUST fail the channel + + - MUST fail the channel if _any_ of the received HTLC signatures is invalid + according to BIP 342. + +#### `revoke_and_ack` Extensions + +A new TLV stream is added to the `revoke_and_ack` message: + +1. `tlv_stream`: `revoke_and_ack_tlvs` +2. types: + 1. type: 22 (`next_local_nonces`) + 2. data: + * [`...*nonce_entry`: `nonces`] + +Similar to sending the `next_per_commitment_point`, we also send the _next_ +`musig2` nonces, after we revoke a state. Sending these nonces allows the remote +party to propose another state transition as soon as the message is received. + +##### Requirements + +The sender: + +- MUST use the `musig2.NonceGen` algorithm to generate unique nonces to send + in the `next_local_nonces` field. +- MUST include one entry for each active commitment transaction, indexed by the + commitment transaction's `funding_txid`. + +The recipient: + +- MUST fail the channel if `next_local_nonces` is absent. +- MUST fail the channel if an active commitment's `funding_txid` is missing in + `next_local_nonces`. +- If the local nonce generation is non-deterministic and the recipient co-signs + commitments only upon pending broadcast: + - MUST **securely** store the local nonce. + +### Message Retransmission + +#### `channel_reestablish` Extensions + +We add a new TLV field to the `channel_reestablish` message: + +1. `tlv_stream`: `channel_reestablish_tlvs` +2. types: + 1. type: 22 (`next_local_nonces`) + 2. data: + * [`...*nonce_entry`: `nonces`] + +Similar to the `next_per_commitment_point`, by sending the `next_local_nonces` +value in this message, we ensure that the remote party has our public nonces, +which are required to generate new commitment signatures. + +##### Requirements + +The sender: + +- MUST set `next_local_nonces` to fresh, unique `musig2` nonces as specified by + `bip-musig2`. +- MUST include one entry for each active commitment transaction, indexed by the + commitment transaction's `funding_txid`. + +The recipient: + +- MUST fail the channel if `next_local_nonces` is absent, or cannot be parsed. +- MUST fail the channel if an active commitment's `funding_txid` is missing in + `next_local_nonces`. + +A node: + + - If ALL of the following conditions apply: + + - It has previously sent a `commitment_signed` message + + - It never processed the corresponding `revoke_and_ack` message + + - It decides to retransmit the exact `update_` messages from the last sent + `commitment_signed` + + - THEN it must regenerate the partial signature using the newly received + `next_local_nonces` + +### Splice Coordination + +Splicing allows parties to modify the funding output of an existing channel +without closing it. During splice operations, multiple commitment transactions +may exist concurrently, each requiring its own MuSig2 nonce coordination. The +`next_local_nonces` field enables this coordination by mapping transaction IDs +to their respective nonces. + +#### Splice Nonce Management + +During splice negotiation: + +- Each splice transaction MUST have a unique TXID as the key in the + `next_local_nonces` map +- Parties MUST include nonces for all active commitment transactions in their + `next_local_nonces` map, indexed by their `funding_txid` + +##### Requirements for Splice Coordination + +When a splice is initiated: + +- The initiating party MUST generate a fresh nonce for the splice transaction +- Both parties MUST add the splice TXID and corresponding nonce to their + `next_local_nonces` map +- The nonce MUST be communicated in the next `revoke_and_ack` or + `channel_reestablish` message + +When multiple splices are pending: + +- Each splice MUST have a distinct TXID and nonce pair +- Nonces MUST NOT be reused across different splice transactions +- The `next_local_nonces` map MUST contain multiple entries during concurrent + splice operations + +##### Backward Compatibility + +Nodes that do not support splicing will simply use a nonce map with a single +entry indexed by the commitment transaction's `funding_txid`. + +### Funding Transactions + +For our Simple Taproot Channels, `musig2` is used to generate a single +aggregated public key. + +The resulting funding output script takes the form: +`OP_1 funding_key` + +where: + + * `funding_key = combined_funding_key + tagged_hash("TapTweak", combined_funding_key)*G` + * `combined_funding_key = musig2.KeyAgg(musig2.KeySort(pubkey1, pubkey2))` + +The funding key is derived via the recommendation in BIP 341 that states: "If +the spending conditions do not require a script path, the output key should +commit to an unspendable script path instead of having no script path. This can +be achieved by computing the output key point as `Q = P + +int(hashTapTweak(bytes(P)))G`". We refer to BIP 86 for the specifics of this +derivation. + +By using the musig2 sorting routine, we inherit the lexicographical key +ordering from the base segwit channels. Throughout the lifetime of a channel +any keys aggregated via musig2 also are assumed to use the `KeySort` routine + +### Commitment Transactions + +#### To Local Outputs + +##### With `option_simple_taproot` + +For the simple taproot commitment type, we use the same flow of revocation or +delay, while re-using the NUMS point to ensure that the internal key is always +revealed (script path always taken). This ensures that the anchor outputs can +_always_ be spent given chain revealed information. For the remote party, the +`remotepubkey` will be revealed once the remote party sweeps. For the local +party, we ensure that the `local_delayedpubkey` is revealed with an extra noop +data push. + +The new output has the following form: + + * `OP_1 to_local_output_key` + * where: + * `to_local_output_key = taproot_nums_point + tagged_hash("TapTweak", taproot_nums_point || to_delay_script_root)*G` + * `to_delay_script_root = tapscript_root([to_delay_script, revoke_script])` + * `to_delay_script` is the delay script: + ``` + OP_CHECKSIGVERIFY + OP_CHECKSEQUENCEVERIFY + * `revoke_script` is the revoke script: + ``` + OP_DROP + OP_CHECKSIG + ``` + +The parity (even or odd) of the y-coordinate of the derived +`to_local_output_key` MUST be known in order to derive a valid control block. + +The `tapscript_root` routine constructs a valid taproot commitment according to +BIP 341+342. Namely, a leaf version of `0xc0` MUST be used. + +In the case of a commitment breach, the `to_delay_script_root` can be used +along side `` to derive the private key needed to sweep the +top-level key spend path. The control block can be crafted as such: +``` +revoke_control_block = (output_key_y_parity | 0xc0) || taproot_nums_point || revoke_script +``` + +A valid witness is then: +``` + +``` + +In the case of a routine force close, the script path must be revealed so the +broadcaster can sweep their funds after a delay. The control block to spend is +only `33` bytes, as it just includes the internal key (along with the y-parity +bit and leaf version): +``` +delay_control_block = (output_key_y_parity | 0xc0) || taproot_nums-point || to_delay_srcipt +``` + +A valid witness is then: +``` + +``` + +As with base channels, the `nSequence` field must be set to `to_self_delay`. + +##### With `taproot_zero_fee_commitments` + +When using `nVersion = 3`, we use a single P2A output that doesn't need any +public key information. We thus don't need to use the NUMS point and simply +use the revocation key as internal key. + +The `to_local` output has the following form: + + * `OP_1 to_local_output_key` + * where: + * `to_local_output_key = revocation_pubkey + tagged_hash("TapTweak", revocation_pubkey || to_delay_script_root)*G` + * `to_delay_script_root = tapscript_root([to_delay_script])` + * `to_delay_script` is the delay script: + ``` + OP_CHECKSIGVERIFY + OP_CHECKSEQUENCEVERIFY + ``` + +In the case of a commitment breach, it is trivial to sweep all outputs by using +the key-path with the revealed revocation secret. A valid witness is thus +simply a signature using the `revocation_key`: +``` + +``` + +In the case of a routine force close, the script path must be revealed so the +broadcaster can sweep their funds after a delay. The control block to spend is +only `33` bytes, as it just includes the internal key (along with the y-parity +bit and leaf version): +``` +delay_control_block = (output_key_y_parity | 0xc0) || revocation_pubkey || to_delay_script +``` + +A valid witness is then: +``` + +``` + +As with base channels, the `nSequence` field must be set to `to_self_delay`. + +#### To Remote Outputs + +##### With `option_simple_taproot` + +As we inherit the anchor output semantics, we want to ensure that the remote +party can unilaterally sweep their funds after the 1 block CSV delay. In order +to achieve this property, we'll utilize a NUMS point (`simple_taproot_nums`) By +using this point as the internal key, we ensure that the remote party isn't +able to by pass the CSV delay. + +Using a NUMS key has a key benefit: the static internal key allows the remote +party to scan for their output on chain, which is useful for various recovery +scenarios. + +The `to_remote` output has the following form: + + * `OP_1 to_remote_output_key` + * where: + * `taproot_nums_point = 0245b18183a06ee58228f07d9716f0f121cd194e4d924b037522503a7160432f15` + * `to_remote_output_key = taproot_nums_point + tagged_hash("TapTweak", taproot_nums_point || to_remote_script_root)*G` + * `to_remote_script_root = tapscript_root([to_remote_script])` + * `to_remote_script` is the remote script: + ``` + OP_CHECKSIGVERIFY + 1 OP_CHECKSEQUENCEVERIFY + ``` + +This output can be swept by the remote party with the following witness: +``` + +``` + +where `to_remote_control_block` is: +``` +(output_key_y_parity | 0xc0) || combined_funding_key +``` + +The `sequence` field of the input MUST also be set to `1`. + +##### With `taproot_zero_fee_commitments` + +When using `nVersion = 3`, the remote party can immediately unilaterally +sweep their funds. We don't need the NUMS point. + +The `to_remote` output has the following form: + + * `OP_1 to_remote_output_key` + * where: + * `to_remote_output_key = remotepubkey + tagged_hash("TapTweak", remotepubkey)*G` + +A valid witness is simply a signature using the `remotepubkey`: +``` + +``` + +#### Anchor Outputs + +##### With `option_simple_taproot` + +For simple taproot channels (`option_simple_taproot`) we'll maintain the same +form as base segwit channels, but instead will utilize `local_delayedpubkey` +and the `remotepubkey` rather than the multi-sig keys as that's no longer +revealed due to musig2. + +An anchor output has the following form: + + * `OP_1 anchor_output_key` + * where: + * `anchor_internal_key = remotepubkey/local_delayedpubkey` + * `anchor_output_key = anchor_internal_key + tagged_hash("TapTweak", anchor_internal_key || anchor_script_root)` + * `anchor_script_root = tapscript_root([anchor_script])` + * `anchor_script`: + ``` + OP_16 OP_CHECKSEQUENCEVERIFY + ``` + +This output can be swept by anyone after 16 blocks with the following witness: +``` + +``` + +where `anchor_control_block` is: +``` +(output_key_y_parity | 0xc0) || anchor_internal_key +``` + +`nSequence` needs to be set to 16. + +##### With `taproot_zero_fee_commitments` + +We use the same form as `zero_fee_commitments` and thus include a single +standard P2A (pay-to-anchor) script. + +This anchor output has the following form: + + * `OP_1 <0x4e73>` + +Spending of the output requires the following (empty) witness: +``` +<> +``` + +### HTLC Scripts & Transactions + +#### Offered HTLCs + +We retain the same second-level HTLC mappings as base channels. The main +modifications are using the revocation public key as the internal key, and +splitting the timeout and success paths into individual script leaves. + +The HTLC-success script includes a `1 CSV` when using `nVersion = 2`, but +omits it when using `nVersion = 3`. + +An offered HTLC has the following form: + + * `OP_1 offered_htlc_key` + * where: + * `offered_htlc_key = revocation_pubkey + tagged_hash("TapTweak", revocation_pubkey || htlc_script_root)` + * `htlc_script_root = tapscript_root([htlc_timeout, htlc_success])` + * `htlc_timeout`: + ``` + OP_CHECKSIGVERIFY + OP_CHECKSIG + ``` + * `htlc_success`: + * if `nVersion = 2`: + ``` + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY + OP_CHECKSIGVERIFY + 1 OP_CHECKSEQUENCEVERIFY + ``` + * if `nVersion = 3`: + ``` + OP_CHECKSIGVERIFY + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUAL + ``` + +In order to spend a offered HTLC, via either script path, an `inclusion_proof` +must be specified along with the control block. This `inclusion_proof` is +simply the `tap_leaf` hash of the path _not_ taken. + +#### Accepted HTLCs + +Accepted HTLCs inherit a similar format: + + * `OP_1 accepted_htlc_key` + * where: + * `accepted_htlc_key = revocation_pubkey + tagged_hash("TapTweak", revocation_pubkey || htlc_script_root)` + * `htlc_script_root = tapscript_root([htlc_timeout, htlc_success])` + * `htlc_timeout`: + * if `nVersion = 2`: + ``` + OP_CHECKSIGVERIFY + 1 OP_CHECKSEQUENCEVERIFY OP_VERIFY + OP_CHECKLOCKTIMEVERIFY + ``` + * if `nVersion = 3`: + ``` + OP_CHECKSIGVERIFY + OP_CHECKLOCKTIMEVERIFY + ``` + * `htlc_success`: + ``` + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY + OP_CHECKSIGVERIFY + OP_CHECKSIG + ``` + +Note that there is no `OP_CHECKSEQUENCEVERIFY` in the offered HTLC's timeout +path nor in the accepted HTLC's success path, even when using `nVersion = 2`. +This is not needed here as these paths require a remote signature that commits +to the sequence, which needs to be set at 1. + +In order to spend an accepted HTLC, via either script path, an +`inclusion_proof` must be specified along with the control block. This +`inclusion_proof` is simply the `tap_leaf` hash of the path _not_ taken. + +#### HTLC Second Level Transactions + +For the second level transactions, we retain the existing structure: a 2-of-2 +multi-spend going to a CLTV delayed output. Like the normal HTLC transactions, +we also place the revocation key as the internal key, allowing easy breach +sweeps with each party only retaining the specific script root. + +An HTLC-Success or HTLC-Timeout is a one-in-one-out transaction signed using +the `SIGHASH_SINGLE|SIGHASH_ANYONECANPAY` flag. These transactions always have +_zero_ fees attached, forcing them to be aggregated with each other and a +change input. + +##### HTLC-Success Transactions + +A HTLC-Success transaction has the following structure: + + * version: 2 for `option_simple_taproot`, 3 for `taproot_zero_fee_commitments` + * locktime: 0 + * input: + * txid: commitment_tx + * vout: htlc_index + * sequence: 1 for `option_simple_taproot`, 0 for `taproot_zero_fee_commitments` + * witness: ` ` + * output: + * value: htlc_value + * script: + * OP_1 htlc_success_key + * where: + * `htlc_success_key = revocation_pubkey + tagged_hash("TapTweak", revocation_pubkey || htlc_script_root)` + * `htlc_script_root = tapscript_root([htlc_success])` + * `htlc_success`: + ``` + OP_CHECKSIGVERIFY + OP_CHECKSEQUENCEVERIFY + ``` + +##### HTLC-Timeout Transactions + +A HTLC-Timeout transaction has the following structure: + + * version: 2 for `option_simple_taproot`, 3 for `taproot_zero_fee_commitments` + * locktime: cltv_expiry + * input: + * txid: commitment_tx + * vout: htlc_index + * sequence: 1 for `option_simple_taproot`, 0 for `taproot_zero_fee_commitments` + * witness: ` ` + * output: + * value: htlc_value + * script: + * OP_1 htlc_timeout_key + * where: + * `htlc_timeout_key = revocation_pubkey + tagged_hash("TapTweak", revocation_pubkey || htlc_script_root)` + * `htlc_script_root = tapscript_root([htlc_timeout])` + * `htlc_timeout`: + ``` + OP_CHECKSIGVERIFY + OP_CHECKSEQUENCEVERIFY + ``` + +# Appendix + +# Footnotes + +# Test Vectors + +All test vectors are derived deterministically from a single 32-byte seed: +`000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f`. Private +keys are produced via `SHA256(seed || label)` where `label` is a fixed ASCII +string for each key (e.g. `"local-funding"`, `"remote-funding"`, etc.). The +per-commitment point is derived by computing `SHA256(seed || +"local-per-commit-secret")` and using the result as the per-commitment secret +scalar, then multiplying by the generator to obtain the per-commitment point. + +The vectors cover two areas: + +1. **Script vectors**: the decomposed tapscript trees for every output type + (funding, `to_local`, `to_remote`, anchors, offered/accepted HTLCs on both + local and remote commits, and second-level HTLC transactions). Each entry + includes the raw leaf scripts, leaf hashes, tapscript root, internal key, + output key, and the resulting `pkScript`. + +2. **Transaction vectors**: full serialized commitment transactions and their + HTLC resolution transactions for three scenarios — a simple commitment with + no HTLCs, a commitment with five untrimmed HTLCs, and a commitment with the + same HTLCs at a higher fee rate causing some to be trimmed. + +Channel parameters used: `funding_amount = 10,000,000 sat`, +`dust_limit = 354 sat` (taproot dust), `csv_delay = 144 blocks`, +`commit_height = 42`, `fee_per_kw` as specified per test case. + +### Key Derivation Labels + +The following labels are used with `SHA256(seed || label)` to derive each +private key: + +| Key | Label | +|-----|-------| +| `local_funding_privkey` | `"local-funding"` | +| `remote_funding_privkey` | `"remote-funding"` | +| `local_payment_basepoint_secret` | `"local-payment-basepoint"` | +| `remote_payment_basepoint_secret` | `"remote-payment-basepoint"` | +| `local_delayed_payment_basepoint_secret` | `"local-delayed-payment-basepoint"` | +| `remote_revocation_basepoint_secret` | `"remote-revocation-basepoint"` | +| `local_htlc_basepoint_secret` | `"local-htlc-basepoint"` | +| `remote_htlc_basepoint_secret` | `"remote-htlc-basepoint"` | +| `local_per_commit_secret` | `"local-per-commit-secret"` | + +### MuSig2 Nonce Generation + +MuSig2 partial signatures require deterministic nonces so that test vectors are +reproducible across implementations. The signing randomness for each party's +JIT nonces is derived as `SHA256(seed || label)` using: + +| Party | Label | +|-------|-------| +| Local signer | `"local-signing-rand"` | +| Remote signer | `"remote-signing-rand"` | + +The resulting 32-byte hash is used as the nonce randomness input to the MuSig2 +signing session. + +Because different MuSig2 implementations (e.g., libsecp256k1-zkp vs btcd) may +produce different nonces from the same randomness input, the test vectors +include both the raw secret nonces and the derived public nonces so that +implementations can inject them directly rather than re-derive them. + +Each transaction test case includes the following nonce fields: + +| Field | Size | Description | +|-------|------|-------------| +| `local_nonce` | 66 bytes | Local party's public nonce for this commitment tx | +| `remote_nonce` | 66 bytes | Remote party's public nonce for this commitment tx | +| `local_sec_nonce` | 97 bytes | Local party's secret nonce (two 32-byte scalars + 33-byte pubkey) | +| `remote_sec_nonce` | 97 bytes | Remote party's secret nonce (two 32-byte scalars + 33-byte pubkey) | + +All nonces in a given test case correspond to the **same commitment +transaction** (the local party's commitment, as produced by `ForceClose`). +Specifically: + + - `local_nonce` / `local_sec_nonce`: the verification nonce that the local + party contributes to the MuSig2 session for their own commitment. This + nonce is generated during the initial nonce exchange (or nonce rotation + after a prior commitment update) and sent to the remote party. + + - `remote_nonce` / `remote_sec_nonce`: the JIT signing nonce that the remote + party generates when producing their partial signature on the local party's + commitment transaction. + +To replay the MuSig2 signing from the test vectors: + + 1. Aggregate the two public nonces using `NonceAgg` from BIP-327. + 2. Use each party's secret nonce with `Sign` to reproduce their partial + signature. + 3. Combine both partial signatures to obtain the final 64-byte Schnorr + signature, which should match the commitment transaction witness. + +### Commitment Transaction Signatures + +The `remote_partial_sig` field in each transaction test case is a 32-byte +MuSig2 partial signature scalar (hex-encoded). This is the remote party's +contribution to the combined Schnorr signature on the commitment transaction. +The commitment transaction witness contains the final aggregated 64-byte +Schnorr signature produced by combining both parties' partial signatures. + +### HTLC Resolution Transactions + +Each `htlc_descs` entry describes a second-level HTLC transaction that spends +from one of the commitment transaction's HTLC outputs. The entries are ordered +by their corresponding commitment transaction output index (BIP 69 ordering), +which matches the order of `htlc_signature` messages exchanged during the +commitment signing protocol. + +The `remote_partial_sig_hex` for HTLC transactions is a 64-byte Schnorr +signature (not a MuSig2 partial sig), since HTLC second-level transactions use +a regular tapscript spend path rather than a keyspend MuSig2 path. These +Schnorr signatures use BIP-340 deterministic nonce derivation with zero +`auxrand` (32 zero bytes). Implementations must use the same nonce derivation +to reproduce matching signatures — passing no auxiliary randomness (or +explicitly zero bytes) to the BIP-340 `Sign` algorithm. + +The `resolution_tx_hex` contains the fully serialized second-level transaction +with a complete witness stack. For HTLC-success transactions, the witness +layout is: + + + +For HTLC-timeout transactions, the witness layout is: + + + +### HTLC Trimming + +Taproot channels use zero-fee HTLC transactions, meaning the HTLC output value +on the commitment transaction equals the HTLC amount directly (no fee is +deducted from the output). As a result, HTLC trimming depends solely on whether +the HTLC amount falls below the `dust_limit_satoshis`, not on the fee rate. The +"commitment tx with some HTLCs trimmed" test case uses `dust_limit = 2500 sat` +to trim the three smallest test HTLCs (1000, 2000, and 2000 sats), leaving only +the 3000 and 4000 sat HTLCs on the commitment transaction. + +Implementations SHOULD regenerate these vectors from the seed using the +derivation method described above and verify that all intermediate values +(keys, scripts, leaf hashes, transactions) match. + +```json +{ + "params": { + "seed": "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "funding_amount_satoshis": 10000000, + "dust_limit_satoshis": 354, + "csv_delay": 144, + "commit_height": 42, + "nums_point": "02dca094751109d0bd055d03565874e8276dd53e926b44e3bd1bb6bf4bc130a279", + "keys": { + "local_funding_privkey": "20ae2d254ab29afd3dcbf8744a5b88d06070f55a4bd5532483a093ac4db91277", + "local_funding_pubkey": "03b7203dec7c13896b6ff1f58b24f84458c441720a12b5a57426397e22f0a8c78b", + "remote_funding_privkey": "f0c5500a9dbd7cdcd46ced7bdeb937d4dcbf90f9b9357626e7ee54ab024c3df0", + "remote_funding_pubkey": "02956e6845a6f346f97c5e028c0f8ab38a76b0124fd7184deab60f682b3e657fdb", + "local_payment_basepoint_secret": "277975b5b081a9cbc4834e066d7bb494e4fde4f7637257dd3d312a0ae7cb7754", + "local_payment_basepoint": "03955b6085296cbd2447a1dde0f7e273e19b83e83de1814993b1517aaf193b7f33", + "remote_payment_basepoint_secret": "f1cd3a5ca44b52baf4eacb849fbf06e75aace97477b8bfe31d2b814dbbb562b1", + "remote_payment_basepoint": "03595f2ef2a51d2250a21077dbea4a7fc3ce550f10676996bf63719e2a71d1f4c9", + "local_delayed_payment_basepoint_secret": "83ccf0b638c514db5ebefdc6cbf901505e2bb20edb2bb7248ce1a51523325f9b", + "local_delayed_payment_basepoint": "02ae68d8ff4c59864c03a42bbff6c07f9ae18047e0daa9bc40d07c410f9a0f7899", + "remote_revocation_basepoint_secret": "36c4175b91cff9731a63d1472b5b1c4cf3e7b688e87d5fb806b2e8350484e68d", + "remote_revocation_basepoint": "02c354121ef71922b5cb32fa685c08ac0014b558f96e28f383c45eb28b7da264c3", + "local_htlc_basepoint_secret": "786eb5024e4851bea3ddc6e40036c81b1efcf50eeed440eedefe5245bde6fc14", + "local_htlc_basepoint": "033ce88bf3c8333e242996964ac91ee7cd945bfe4c49668ea10f3211f3d418fbc8", + "remote_htlc_basepoint_secret": "51c9b6cf8279def85e3925bc8f16fc0ff100ee7b03ce7c954149ca29c834b684", + "remote_htlc_basepoint": "02932dfbf6737001e3c516696ae3dcd323fd91a01ce7898f7f91ab98eebacc323e", + "local_per_commit_secret": "037b507180b3985cea6396d6a70987cea11ccd05fde49e943a3ea0fe56ee33ed", + "local_per_commit_point": "02a0f5a09017c1dec2d30dd54a25dc4037fc5a2aa3832ee3c7b58f3a88a0836287", + "derived_local_delayed_pubkey": "0315ec0138eb42f1ab4603042123988d53c854e89d1d87aa4dbb97a57482029c05", + "derived_revocation_pubkey": "03d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0", + "derived_local_htlc_pubkey": "0271e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739e", + "derived_remote_htlc_pubkey": "032deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47d", + "derived_remote_payment_pubkey": "03595f2ef2a51d2250a21077dbea4a7fc3ce550f10676996bf63719e2a71d1f4c9" + } + }, + "scripts": { + "funding": { + "funding_tx_hex": "02000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000018096980000000000225120d0ebb4909d563a7ae1213fddede4ae54132fba0ef0b97ee3f8469191fecd348e00000000", + "combined_key": "d0ebb4909d563a7ae1213fddede4ae54132fba0ef0b97ee3f8469191fecd348e", + "pkscript": "5120d0ebb4909d563a7ae1213fddede4ae54132fba0ef0b97ee3f8469191fecd348e" + }, + "to_local": { + "scripts": { + "revocation": "2015ec0138eb42f1ab4603042123988d53c854e89d1d87aa4dbb97a57482029c057520d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0ac", + "settle": "2015ec0138eb42f1ab4603042123988d53c854e89d1d87aa4dbb97a57482029c05ad029000b2" + }, + "leaf_hashes": { + "revocation": "8fcd64d212bbbf1bcec2360bbf229963240d05992fc2efb482fe6dca85b9469a", + "settle": "dbf0400e9c7c57f30b6ad0b0677e396b5a002cbf050d873c8925b966048e6a62" + }, + "tapscript_root": "b8b76c2e893ca785072f0d7393e35d5bd72adf8b7ff2a53538aa664378a38a36", + "internal_key": "02dca094751109d0bd055d03565874e8276dd53e926b44e3bd1bb6bf4bc130a279", + "output_key": "023e1fcbbd06c8a7414704612c72be9834a75d86ed85b29f0ef0c52e1950afaff3", + "pkscript": "51203e1fcbbd06c8a7414704612c72be9834a75d86ed85b29f0ef0c52e1950afaff3" + }, + "to_remote": { + "scripts": { + "settle": "20595f2ef2a51d2250a21077dbea4a7fc3ce550f10676996bf63719e2a71d1f4c9ad51b2" + }, + "leaf_hashes": { + "settle": "63ce35b16eb8f8687293d5a88c1d8ada3236843b79ca315fe9dd7c47f30f2bc9" + }, + "tapscript_root": "63ce35b16eb8f8687293d5a88c1d8ada3236843b79ca315fe9dd7c47f30f2bc9", + "internal_key": "02dca094751109d0bd055d03565874e8276dd53e926b44e3bd1bb6bf4bc130a279", + "output_key": "023609bb705034e5629aa6ec05c5ca906ac89ac08b34c4583c259521ec30174408", + "pkscript": "51203609bb705034e5629aa6ec05c5ca906ac89ac08b34c4583c259521ec30174408" + }, + "local_anchor": { + "scripts": { + "sweep": "60b2" + }, + "leaf_hashes": { + "sweep": "2b88a8f3f52386d61d5b3f2d822df659c35214d7360ed05352ad7ddc1ab03912" + }, + "tapscript_root": "2b88a8f3f52386d61d5b3f2d822df659c35214d7360ed05352ad7ddc1ab03912", + "internal_key": "0315ec0138eb42f1ab4603042123988d53c854e89d1d87aa4dbb97a57482029c05", + "output_key": "02f67ab012701705f3203d132f909a6810ef18c5da4c11d986cb50818803b8344e", + "pkscript": "5120f67ab012701705f3203d132f909a6810ef18c5da4c11d986cb50818803b8344e" + }, + "remote_anchor": { + "scripts": { + "sweep": "60b2" + }, + "leaf_hashes": { + "sweep": "2b88a8f3f52386d61d5b3f2d822df659c35214d7360ed05352ad7ddc1ab03912" + }, + "tapscript_root": "2b88a8f3f52386d61d5b3f2d822df659c35214d7360ed05352ad7ddc1ab03912", + "internal_key": "03595f2ef2a51d2250a21077dbea4a7fc3ce550f10676996bf63719e2a71d1f4c9", + "output_key": "021249c50576fdf914caa14f9221370b986df520bdbc73f57d5056a86ee03e5ac4", + "pkscript": "51201249c50576fdf914caa14f9221370b986df520bdbc73f57d5056a86ee03e5ac4" + }, + "offered_htlc_local_commit": { + "scripts": { + "success": "82012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dad51b2", + "timeout": "2071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac" + }, + "leaf_hashes": { + "success": "cd4b7ba74d132998f2bcea85f76082f5018e614c86f27f2631b6569c4914320f", + "timeout": "dd0bd08b3df902c399f5493a682f6c50c476c89e233ba454e89a234d2d16ffe3" + }, + "tapscript_root": "f36c8bd45002c5264cfce9944211e7bc6ea974a6b90cf99a87812d18acf28a2a", + "internal_key": "03d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0", + "output_key": "033e5c3be9f4ce7ae07c28ad5e0eb0ab617c06eeb82b8d6ef10a5bf561848df5f0", + "pkscript": "51203e5c3be9f4ce7ae07c28ad5e0eb0ab617c06eeb82b8d6ef10a5bf561848df5f0" + }, + "offered_htlc_remote_commit": { + "scripts": { + "success": "82012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dad51b2", + "timeout": "2071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac" + }, + "leaf_hashes": { + "success": "cd4b7ba74d132998f2bcea85f76082f5018e614c86f27f2631b6569c4914320f", + "timeout": "dd0bd08b3df902c399f5493a682f6c50c476c89e233ba454e89a234d2d16ffe3" + }, + "tapscript_root": "f36c8bd45002c5264cfce9944211e7bc6ea974a6b90cf99a87812d18acf28a2a", + "internal_key": "03d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0", + "output_key": "033e5c3be9f4ce7ae07c28ad5e0eb0ab617c06eeb82b8d6ef10a5bf561848df5f0", + "pkscript": "51203e5c3be9f4ce7ae07c28ad5e0eb0ab617c06eeb82b8d6ef10a5bf561848df5f0" + }, + "accepted_htlc_local_commit": { + "scripts": { + "success": "82012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dad2071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739eac", + "timeout": "2071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead51b26902f401b1" + }, + "leaf_hashes": { + "success": "69192ca730d4480044ade8741b8bd0845a32880aebaf58bc6f9186f8d2be8cbf", + "timeout": "4da43c795365bf757ed1e9656d12ea744b4cf52b01719a3ea94e6569115623f0" + }, + "tapscript_root": "1a990caa4bb0ed41ceb19e7466fcea5d9b31e3da968f348f6223201c5831d0a3", + "internal_key": "03d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0", + "output_key": "029aadbdd9aff986e5ea086cf53ae062972d33d0a5c7f5fb986dafec7fa6d7e6ea", + "pkscript": "51209aadbdd9aff986e5ea086cf53ae062972d33d0a5c7f5fb986dafec7fa6d7e6ea" + }, + "accepted_htlc_remote_commit": { + "scripts": { + "success": "82012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc688202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dad2071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739eac", + "timeout": "2071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead51b26902f401b1" + }, + "leaf_hashes": { + "success": "69192ca730d4480044ade8741b8bd0845a32880aebaf58bc6f9186f8d2be8cbf", + "timeout": "4da43c795365bf757ed1e9656d12ea744b4cf52b01719a3ea94e6569115623f0" + }, + "tapscript_root": "1a990caa4bb0ed41ceb19e7466fcea5d9b31e3da968f348f6223201c5831d0a3", + "internal_key": "03d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0", + "output_key": "029aadbdd9aff986e5ea086cf53ae062972d33d0a5c7f5fb986dafec7fa6d7e6ea", + "pkscript": "51209aadbdd9aff986e5ea086cf53ae062972d33d0a5c7f5fb986dafec7fa6d7e6ea" + }, + "second_level_htlc_success": { + "scripts": { + "success": "2015ec0138eb42f1ab4603042123988d53c854e89d1d87aa4dbb97a57482029c05ad029000b2" + }, + "leaf_hashes": { + "success": "dbf0400e9c7c57f30b6ad0b0677e396b5a002cbf050d873c8925b966048e6a62" + }, + "tapscript_root": "dbf0400e9c7c57f30b6ad0b0677e396b5a002cbf050d873c8925b966048e6a62", + "internal_key": "03d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0", + "output_key": "02df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba0", + "pkscript": "5120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba0" + }, + "second_level_htlc_timeout": { + "scripts": { + "success": "2015ec0138eb42f1ab4603042123988d53c854e89d1d87aa4dbb97a57482029c05ad029000b2" + }, + "leaf_hashes": { + "success": "dbf0400e9c7c57f30b6ad0b0677e396b5a002cbf050d873c8925b966048e6a62" + }, + "tapscript_root": "dbf0400e9c7c57f30b6ad0b0677e396b5a002cbf050d873c8925b966048e6a62", + "internal_key": "03d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0", + "output_key": "02df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba0", + "pkscript": "5120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba0" + } + }, + "transactions": [ + { + "name": "simple commitment tx with no HTLCs", + "local_balance_msat": 7000000000, + "remote_balance_msat": 3000000000, + "fee_per_kw": 15000, + "htlcs": null, + "local_sec_nonce": "22a453171ba4a634da1addcf660d63d8e23fb63169a2a7206f4e23290e4cc59bb3c3011fe3c31cb4f1192a2df56c2e52350ce0a82060fadf2404af9f81652c5f03b7203dec7c13896b6ff1f58b24f84458c441720a12b5a57426397e22f0a8c78b", + "remote_sec_nonce": "ccdaea6955c7bd9fcb082dc67e32809a5bdd3a3edf770cbb990116c45f4b006e4b56aa81f8e555d6bd1906b159af16d0ac352690ccff6f6a99c43842ac2606ca02956e6845a6f346f97c5e028c0f8ab38a76b0124fd7184deab60f682b3e657fdb", + "local_nonce": "025f2272ea289c5fe9d52d411f5a50a6d4882341bf0ecb201d5675850a2ba0b09d025bc489cf67752134ba81f8d7f1146d7455baf3190de75a6a661e2405212991a9", + "remote_nonce": "02d324627074522af8cf4287caf1e073a3493550b99aed2697e58f476ec402e272039c25fc616207e15917b7145cefcb4c9c702580baf255597d2fa115564a74a130", + "remote_partial_sig": "3fa93659d4c2d590eadbd422595a37597ed58607e026a91f4e6e19329134a931", + "expected_commitment_tx_hex": "020000000001015474cba49124ab0c4327c244bb2907059585c4af3fa5f3469701534120fec0170000000000c5fe1780044a010000000000002251201249c50576fdf914caa14f9221370b986df520bdbc73f57d5056a86ee03e5ac44a01000000000000225120f67ab012701705f3203d132f909a6810ef18c5da4c11d986cb50818803b8344ec0c62d00000000002251203609bb705034e5629aa6ec05c5ca906ac89ac08b34c4583c259521ec3017440874946a00000000002251203e1fcbbd06c8a7414704612c72be9834a75d86ed85b29f0ef0c52e1950afaff30140a4a9eb512a2f4094efdd2c566f1f20cc8a6e2c307a4a44cc3f9fea7fa147dd7038f1b048aa43fa0b4009175c1c37c37b96c01058541f9e1b61110fce4e831d9f55dc1920", + "htlc_descs": null + }, + { + "name": "commitment tx with five HTLCs untrimmed", + "local_balance_msat": 6988000000, + "remote_balance_msat": 3000000000, + "fee_per_kw": 644, + "htlcs": [ + { + "incoming": true, + "amount_msat": 1000000, + "expiry": 500, + "preimage": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "incoming": true, + "amount_msat": 2000000, + "expiry": 501, + "preimage": "0101010101010101010101010101010101010101010101010101010101010101" + }, + { + "incoming": false, + "amount_msat": 2000000, + "expiry": 502, + "preimage": "0202020202020202020202020202020202020202020202020202020202020202" + }, + { + "incoming": false, + "amount_msat": 3000000, + "expiry": 503, + "preimage": "0303030303030303030303030303030303030303030303030303030303030303" + }, + { + "incoming": true, + "amount_msat": 4000000, + "expiry": 504, + "preimage": "0404040404040404040404040404040404040404040404040404040404040404" + } + ], + "local_sec_nonce": "22a453171ba4a634da1addcf660d63d8e23fb63169a2a7206f4e23290e4cc59bb3c3011fe3c31cb4f1192a2df56c2e52350ce0a82060fadf2404af9f81652c5f03b7203dec7c13896b6ff1f58b24f84458c441720a12b5a57426397e22f0a8c78b", + "remote_sec_nonce": "8c40a8ab26f1bd7d58010e991c72b0f102df6d0f050df28f56cefdafb9d06479958ea0a72180184e338b1b77fdf20690d5d980aac5c34cf123b189e373dba33e02956e6845a6f346f97c5e028c0f8ab38a76b0124fd7184deab60f682b3e657fdb", + "local_nonce": "025f2272ea289c5fe9d52d411f5a50a6d4882341bf0ecb201d5675850a2ba0b09d025bc489cf67752134ba81f8d7f1146d7455baf3190de75a6a661e2405212991a9", + "remote_nonce": "038a4018a074b5ddfc1424551e871bd739259c4e209f47177eb67c70cfbdb1e57c03c75684ad3a42d8c86a3eddb83b8160d67ef272078b44f21a8f889ee25e2459d3", + "remote_partial_sig": "46efde50f08c128aa6472bbd50ea156fb9bde7b013f5e042f700729c94053613", + "expected_commitment_tx_hex": "020000000001015474cba49124ab0c4327c244bb2907059585c4af3fa5f3469701534120fec0170000000000c5fe1780094a010000000000002251201249c50576fdf914caa14f9221370b986df520bdbc73f57d5056a86ee03e5ac44a01000000000000225120f67ab012701705f3203d132f909a6810ef18c5da4c11d986cb50818803b8344ee8030000000000002251209ce82cd1b1f6f975049d58019a7145a3ec9680079969cf929d7d2c4bc9b30637d0070000000000002251208937f8afbc80cf4ba773f1adc3d63ea26259f80f5a3ba622211906d2e7e6e23dd007000000000000225120bf9ae94dda9b5b88485cc67a966ec946b237d19626916dee034b789ebd7fd5fcb80b0000000000002251208fe2e1306e414e896dfd879475b5c1a6a01d4e79b32c0544aa185ccb73c392aaa00f000000000000225120d93389ba5cdde8570d3ba73487ff7fc9f8c3816645009e42110fe5239f5a3e62c0c62d00000000002251203609bb705034e5629aa6ec05c5ca906ac89ac08b34c4583c259521ec30174408b3996a00000000002251203e1fcbbd06c8a7414704612c72be9834a75d86ed85b29f0ef0c52e1950afaff301409dfe3b178022d975e4b86bd1f04bccfc7576363dbaf58f2ac682136ad89cbeb1a1d07eca1e0bc547b5c5c1133214565e5dfdc230bc7d4736aa7e1be3fb8269d355dc1920", + "htlc_descs": [ + { + "remote_partial_sig_hex": "fc97f7cfb97e1e48792b0ed174704cd98c886d368ede5adeb6288f0b350c8f88d076488973d0656da72d072e03eb9eb8b31737850894bca0924d8fdd63ddea69", + "resolution_tx_hex": "02000000000101ec4c0a34c981864f9badcb8383bbe42ec6b32e68c2aa1a7c7c2e8422adde673f02000000000100000001e803000000000000225120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba00541fc97f7cfb97e1e48792b0ed174704cd98c886d368ede5adeb6288f0b350c8f88d076488973d0656da72d072e03eb9eb8b31737850894bca0924d8fdd63ddea6983405bd66541625ba684bb6ff0def3c542bb88d5195a760cb616a5d09dec6823238ccdde18c99d4f3634394d9c23d0e198babc609f464d9b4552664ca5d3b985758f2000000000000000000000000000000000000000000000000000000000000000005f82012088a914b8bcb07f6344b42ab04250c86a6e8b75d3fdbbc6882071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac41c0d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0e5e8fd071b9ade6367122afbd8acacc1a6727ddb6d478612af30827590027e0300000000" + }, + { + "remote_partial_sig_hex": "c99d8d1ca721d1d4b9796cde49698fd46bb3faddd2bc7215de291ae9bd85cd9b2ab9bf40e36c752b698098b0986abe92b3cb21de8d6a388d9a6988d468e981e5", + "resolution_tx_hex": "02000000000101ec4c0a34c981864f9badcb8383bbe42ec6b32e68c2aa1a7c7c2e8422adde673f03000000000100000001d007000000000000225120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba00541c99d8d1ca721d1d4b9796cde49698fd46bb3faddd2bc7215de291ae9bd85cd9b2ab9bf40e36c752b698098b0986abe92b3cb21de8d6a388d9a6988d468e981e583406a52ec691b47371892192e7222a76d978c18038b3f12479977366a09d2db91e66091332158d8f0b4e125394e1bf2d7ab40ab564c49e0686ffad56eadd6a1297e2001010101010101010101010101010101010101010101010101010101010101015f82012088a9144b6b2e5444c2639cc0fb7bcea5afba3f3cdce239882071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac41c0d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a0127d1790461eff920f14ba7cff2093c44b8a83e6f0a959fa60e04cf8c435cf4b00000000" + }, + { + "remote_partial_sig_hex": "b361ed8b70a09f4128fe610db649abcaafbc9b8600136e6f1b9735b4781cd65681faa32c29fef2a1485cc569c655b31b8eb75ab593749dd7f7d788fdec489133", + "resolution_tx_hex": "02000000000101ec4c0a34c981864f9badcb8383bbe42ec6b32e68c2aa1a7c7c2e8422adde673f04000000000100000001d007000000000000225120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba00441b361ed8b70a09f4128fe610db649abcaafbc9b8600136e6f1b9735b4781cd65681faa32c29fef2a1485cc569c655b31b8eb75ab593749dd7f7d788fdec48913383403e94dbe70a26fc19b0d0053dfbf3da4c3e75dacf4abe337866645ffe21834a152f2edf7e520f352f104eef17fefa5a1535d692012cc766d36bd54f658c5c797f442071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac41c1d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a040b30263c4d7cd1fa6544e8bc8cd9efe857d7b5fd691c958936c3a2e0df2232ef6010000" + }, + { + "remote_partial_sig_hex": "9d1193d1bae8793ec502aa705a43a140e9f4c46607b4b8b414f76923c746a81cc320ffef6575f4c1ba55795770b41885dc90ed19025522805b1d0f5f5d440ebd", + "resolution_tx_hex": "02000000000101ec4c0a34c981864f9badcb8383bbe42ec6b32e68c2aa1a7c7c2e8422adde673f05000000000100000001b80b000000000000225120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba004419d1193d1bae8793ec502aa705a43a140e9f4c46607b4b8b414f76923c746a81cc320ffef6575f4c1ba55795770b41885dc90ed19025522805b1d0f5f5d440ebd8340b149f17aab590815fbe4b19796dfc98aa857e81cdc1d15c82d64a2b626f40af8ae2a884197d74071e9b5648c7b5380db1084ac8ed2a8ed54ca9d589e6b5f7d8a442071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac41c0d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a064c44563d1bd58fa25c5c3ca7303c75849b6b3d91bf2e28f27068db4319b4c2ff7010000" + }, + { + "remote_partial_sig_hex": "58338a2d50a03ea615f0e0e295b12413308e6381412c14d276c4b39a2f1d17193a689cbe2ad0d33a63344cff36daa2edc94aa566d743ad6526ddb5cdb5819ea0", + "resolution_tx_hex": "02000000000101ec4c0a34c981864f9badcb8383bbe42ec6b32e68c2aa1a7c7c2e8422adde673f06000000000100000001a00f000000000000225120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba0054158338a2d50a03ea615f0e0e295b12413308e6381412c14d276c4b39a2f1d17193a689cbe2ad0d33a63344cff36daa2edc94aa566d743ad6526ddb5cdb5819ea08340efcfcda15da18a2791a80700b2716d2386ea67649a5e43a505dbe22bd110cc2352e558d62e7abd7afe7640d2ee414affd88555378bfe05aa28d0fa289e8d1b542004040404040404040404040404040404040404040404040404040404040404045f82012088a91418bc1a114ccf9c052d3d23e28d3b0a9d12274342882071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac41c1d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a06c3390c812b2596986592f02c7f22e4f857fb553805ff9ac1c2bda361c47c3fb00000000" + } + ] + }, + { + "name": "commitment tx with some HTLCs trimmed", + "local_balance_msat": 6988000000, + "remote_balance_msat": 3000000000, + "fee_per_kw": 644, + "dust_limit_satoshis": 2500, + "htlcs": [ + { + "incoming": true, + "amount_msat": 1000000, + "expiry": 500, + "preimage": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "incoming": true, + "amount_msat": 2000000, + "expiry": 501, + "preimage": "0101010101010101010101010101010101010101010101010101010101010101" + }, + { + "incoming": false, + "amount_msat": 2000000, + "expiry": 502, + "preimage": "0202020202020202020202020202020202020202020202020202020202020202" + }, + { + "incoming": false, + "amount_msat": 3000000, + "expiry": 503, + "preimage": "0303030303030303030303030303030303030303030303030303030303030303" + }, + { + "incoming": true, + "amount_msat": 4000000, + "expiry": 504, + "preimage": "0404040404040404040404040404040404040404040404040404040404040404" + } + ], + "local_sec_nonce": "22a453171ba4a634da1addcf660d63d8e23fb63169a2a7206f4e23290e4cc59bb3c3011fe3c31cb4f1192a2df56c2e52350ce0a82060fadf2404af9f81652c5f03b7203dec7c13896b6ff1f58b24f84458c441720a12b5a57426397e22f0a8c78b", + "remote_sec_nonce": "8c5bd39820b3e20d65bf72e530078bf5e8ba057c1654d0a15778a0d3225e0233eb8d7b1d3574e40e57a2cd12dc3b33193c0ac17545564df3ff88021f3c30033702956e6845a6f346f97c5e028c0f8ab38a76b0124fd7184deab60f682b3e657fdb", + "local_nonce": "025f2272ea289c5fe9d52d411f5a50a6d4882341bf0ecb201d5675850a2ba0b09d025bc489cf67752134ba81f8d7f1146d7455baf3190de75a6a661e2405212991a9", + "remote_nonce": "03fd9fa808377737b105f7df362ed513e3946f2bb49dfbca5c2ce2be138ff0607502e4c73701eae82afa7a01993f62321648a6235ef0c958e35766a9e53e4eaf9d34", + "remote_partial_sig": "3e454598e0661188da0e4cf1b806b13c627adb7ab38bab27418cc976769771c3", + "expected_commitment_tx_hex": "020000000001015474cba49124ab0c4327c244bb2907059585c4af3fa5f3469701534120fec0170000000000c5fe1780064a010000000000002251201249c50576fdf914caa14f9221370b986df520bdbc73f57d5056a86ee03e5ac44a01000000000000225120f67ab012701705f3203d132f909a6810ef18c5da4c11d986cb50818803b8344eb80b0000000000002251208fe2e1306e414e896dfd879475b5c1a6a01d4e79b32c0544aa185ccb73c392aaa00f000000000000225120d93389ba5cdde8570d3ba73487ff7fc9f8c3816645009e42110fe5239f5a3e62c0c62d00000000002251203609bb705034e5629aa6ec05c5ca906ac89ac08b34c4583c259521ec30174408009b6a00000000002251203e1fcbbd06c8a7414704612c72be9834a75d86ed85b29f0ef0c52e1950afaff30140dfd9604ad0b4fed040382f4829e20a0ef4b5558d0189178a5e9c26a8b4bd8547fd563ee60884daf91c8a1ae71e08b452a93ad3bdf5c572f642d42606736dc5f755dc1920", + "htlc_descs": [ + { + "remote_partial_sig_hex": "7058caa9a075344e095d95736bb6a00c5b7259f439e60e7e1c6cd641a20d6a25c13d2930ebe51a69ffea78daa12b07237179c8b0584c75499f7bfa4f5afa9776", + "resolution_tx_hex": "020000000001018c47e10e0d210da9e50d73b1adda7a598f79ced25806dd0fa6807bb78780dbbb02000000000100000001b80b000000000000225120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba004417058caa9a075344e095d95736bb6a00c5b7259f439e60e7e1c6cd641a20d6a25c13d2930ebe51a69ffea78daa12b07237179c8b0584c75499f7bfa4f5afa97768340d3a4bcb6c20446364506f75e1d1c4da8ad5ae2f6e5a7ad544965e48f28c02a4e250b0a958a4b2d9d78632771b8f5ea739b63bbf98a6c7511a2456c0d78844642442071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac41c0d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a064c44563d1bd58fa25c5c3ca7303c75849b6b3d91bf2e28f27068db4319b4c2ff7010000" + }, + { + "remote_partial_sig_hex": "818132325cc01e441876615f30c3df5c27df1722db49005dff3856226a41f34c776f98a35dd74fe2f863ea23ac611e06d0aac890227346b1fc53dc62c789d372", + "resolution_tx_hex": "020000000001018c47e10e0d210da9e50d73b1adda7a598f79ced25806dd0fa6807bb78780dbbb03000000000100000001a00f000000000000225120df20bcec43daa75161f7d013254e401812e0fee8bc3369220b6a33672fc18ba00541818132325cc01e441876615f30c3df5c27df1722db49005dff3856226a41f34c776f98a35dd74fe2f863ea23ac611e06d0aac890227346b1fc53dc62c789d37283408e0222c158069b3f19ec0798b3516b79cc2e6293abb1120d54c41c7bae3aa2579c5c3586ad68275a9f99ac14e9a1e48b9c3c7100fd834585264a943c523bea642004040404040404040404040404040404040404040404040404040404040404045f82012088a91418bc1a114ccf9c052d3d23e28d3b0a9d12274342882071e82ef65d5c667159036bfcf662cac2f6c41e38323d148bbbd00fdcd923739ead202deba21cf03c42362c9f912094f62ba045a040a2060882ba1ed3abf1f664a47dac41c1d4c77088d346bce67c13bbbf82ca112588f4b1c9595a1f8af3be9b2f95a109a06c3390c812b2596986592f02c7f22e4f857fb553805ff9ac1c2bda361c47c3fb00000000" + } + ] + } + ] +} +``` + +### Zero-fee commitments test vectors + +Test vectors [are provided](./bolt03/taproot-zero-fee-commitments-test.json) that detail commitment +and HTLC transactions created using `taproot_zero_fee_commitments` in various scenarios. +All parameters are provided to ensure that implementations generate exactly the same signed transactions. + +# Acknowledgements + +The commitment and HTLC scripts are heavily based off of t-bast's [Lightning Is +Getting Taprooty +Scriptless-Scripty](https://github.com/t-bast/lightning-docs/blob/master/taproot-updates.md#lightning-is-getting-taprooty-scriptless-scripty) +document. + +AJ Towns proposed a more ambitious ["one shot" upgrade which includes +PTLCs](https://lists.linuxfoundation.org/pipermail/lightning-dev/2021-October/003278.html) +and a modified revocation scheme which this proposal takes inspiration from. + +Arik and Wilmer Paulino for suggesting the "JIT nonce" approach used in this +specification when sending musig2 partial signatures. + +[bolt03-shared-anchor]: 03-transactions.md#shared_anchor-output-zero_fee_commitments diff --git a/bolt03/taproot-zero-fee-commitments-test.json b/bolt03/taproot-zero-fee-commitments-test.json new file mode 100644 index 000000000..e0377689d --- /dev/null +++ b/bolt03/taproot-zero-fee-commitments-test.json @@ -0,0 +1,417 @@ +{ + "local_funding_priv": "8f567cb6382507019349a47623902aa65d7a142ac85462eeb63dc11799ac2bb9", + "remote_funding_priv": "4d22d96f0c0ccecffee4554d20ed43e51235917508ee292d281235bb7ebe0e3e", + "funding_txid": "4b70a2ee47b3005a6316ff87055e94c6b3d433d0fd3b384c9ecf7813843c1eae", + "funding_index": 1, + "funding_amount_satoshis": 10000000, + "commitment_number": 42, + "to_self_delay": 720, + "local_payment_basepoint_secret": "94f29d20a225ea2f7093331ba0f0f28a9382d8ed08e1fd121329925cd0c01b6d", + "local_delayed_payment_basepoint_secret": "e9d4e1935bf16e948d76ad007baf0646df023af38f41bcf2c8799336949d291e", + "local_htlc_basepoint_secret": "f699038ef4f95b6b16b22a5c04fcb3c508d68d02cd2f86cf197e0fac451681b0", + "per_commitment_point": "0275d12130c276b4274358a328901f8fc47e6c72629102e4b46c9f27dd2c1dda98", + "remote_payment_basepoint_secret": "580bff39085f3a6ae8b1f32905e67366c522ea8f2418391145b2e98f1a7cb3f2", + "remote_htlc_basepoint_secret": "32df9c4dd46ab6210e74e81e15282106f8db883f45674eabb3324166c6513062", + "revocation_basepoint": "026788d019ed90149cbc9aa5ff26dd7f1a6d3cd1bee8bf36cf7d8310fbd3606b14", + "payment_hash_to_preimage": { + "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f": "d3ad493d19860e4744491cf0795c0bc96a8e2a49ebb30afadae7a7d077aa93b2", + "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a": "108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa", + "1a04764fd402b5557cba89ec3c4d8931b0225d6436923c65c079ce64a55084c4": "ec8f390e2ba4b8d807f1f83d25892169aecf63222f895469d04b521ccb9809dc", + "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf": "792dc27fc2bb0512bf2a203153f01d64458ca1dc3aea76f95e95399440120374", + "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1": "c916e086a4cd7d40f198708aefadd31149da628f820ca2fc213af10f7668501c", + "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983": "5591b96c0a6a03f51c27bfa658149260bd2fe5e2ce83130ce50d0229a3a947c5" + }, + "tests": [ + { + "name": "Commitment transaction without HTLCs, both outputs untrimmed", + "dust_limit_satoshis": 500, + "to_local_msat": 8000000000, + "to_remote_msat": 2000000000, + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "0903684eb30ba62a7b0fd347f9f5aee1560e2022ec6954762220a1357018cc5526e3049f4e395a880a2562a8c94204891cbab59a71ec704ee37a9b5912f7ac88027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "037afabc342b56501a13d4daf7c33a1552f460a4cba1f497b6b4086361aa6ad982020ee7fc0325290c475cdcb6d50f525bc89464b024e49b9c6882f3dd0c81f6e7fe", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800300000000000000000451024e7380841e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2a00127a000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f53014022f62fada86df959ada667761ffadab237174d55418510a6f281f3ea52cbeaea7af31f5512120b22f9e0938e337538915aaedd5501993537100caabb0ffb2598c50fbb20" + }, + { + "name": "Commitment transaction without HTLCs, one output trimmed below maximum anchor amount", + "dust_limit_satoshis": 330, + "to_local_msat": 9999800000, + "to_remote_msat": 200000, + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "4ff24478cced5ab4a71eff54a9bb4eb23b327351a45c35951a301c3a0d6e1f470a9dd374e59be067e76bbbad4ab29a641a6742acf8596a155953f82b5d74836b027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "021f8a84d5e3449529848d8ee594acdd68a90b49c594c1019caee05e264150961a02053e4ceac487c36e5f33503e0ea918c28e39e239acf0ac032fea6e3fd867bb3b", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef8002c8000000000000000451024e73b89598000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f53014005959c28cb9da049dd180997334bfbd02910bddb845d19583260edf9c8710e8fab7fc623c036e462b77c74675f27a3ee14c9deefb4f918eb7262a249195941fdc50fbb20" + }, + { + "name": "Commitment transaction without HTLCs, one output trimmed above maximum anchor amount", + "dust_limit_satoshis": 15000, + "to_local_msat": 9990000000, + "to_remote_msat": 10000000, + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "19c02d264e86a0076c2143d1909a8b7137adcfb717496f0f49c44b26c03e9a08d80281f6e37486701e10a7219e28f244afa4a994984f4adcffee6b77ea2c248b027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "034bc25992eee10a8cba136ad05873693971f45cd02ab66943c55bd338f2727d9e025ddac8b6e69dd8347481c18b8c8c11e395c7935703f478fbcca07d72e02cbce1", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef8002f0000000000000000451024e73706f98000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530140101125328ff3ab249b2c7c20cddd3ecc0821cda0700923dbfbfb0c0c025bfa071b473bb90882f9a92f636072a1cb5eff5cce7956456fe7ba4b56f78b27c91bddc50fbb20" + }, + { + "name": "Commitment transaction with all HTLCs above dust limit", + "dust_limit_satoshis": 5000, + "to_local_msat": 7925000000, + "to_remote_msat": 1985000000, + "incoming_htlcs": [ + { + "id": 1, + "amount_msat": 5000000, + "payment_hash": "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a", + "cltv_expiry": 920150 + }, + { + "id": 2, + "amount_msat": 5000000, + "payment_hash": "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a", + "cltv_expiry": 920150 + }, + { + "id": 5, + "amount_msat": 5000000, + "payment_hash": "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a", + "cltv_expiry": 920150 + } + ], + "outgoing_htlcs": [ + { + "id": 5, + "amount_msat": 25000000, + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "cltv_expiry": 920141 + }, + { + "id": 8, + "amount_msat": 25000000, + "payment_hash": "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1", + "cltv_expiry": 920141 + }, + { + "id": 13, + "amount_msat": 25000000, + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "cltv_expiry": 920141 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "b3d4ce001413e33947a7e9ecfd895e2a869339a63a7c6298dc5f0d379d28a46f5f787b85352b5cc71a79a0f75149361dedafc849f9548ce4f35566a24fda4601027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "03621062e3a3a5749aa98b93abbd5ee8de67b0797f932c9d53e59d025f5590e1240399f3338d3518bda1c14f6f9bdbef110b9de1767ea7bc0850dd0617e5b138b581", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800900000000000000000451024e7388130000000000002251200ebae7d7b56e2b69ef3f68813dcbaf76203e7a96a2a61aaf40fc701b78010b9988130000000000002251200ebae7d7b56e2b69ef3f68813dcbaf76203e7a96a2a61aaf40fc701b78010b9988130000000000002251200ebae7d7b56e2b69ef3f68813dcbaf76203e7a96a2a61aaf40fc701b78010b99a8610000000000002251203251b6725c2501f563936bb8a52c4f580d82dbb04a1ef665bd1a9b2e15a4b497a8610000000000002251203251b6725c2501f563936bb8a52c4f580d82dbb04a1ef665bd1a9b2e15a4b497a861000000000000225120f70c636cef59ed56b5412473fc4324f20ec0f960d5d6a5950c5f376de5b28ddde8491e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2a08ed78000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f53014057637245f5ed3a44d4ade2b723b54aaf61f703e13c412b5ec43170057749ec83b88f8884b72aa447f98b1883881aed6fd2aa8a88d99644ea649a87430c778c45c50fbb20", + "signed_htlc_success_txs": [ + "03000000000101d1a6135f1ff14b9cab8c985a8e8a0f592d35c853c650c94699f23d16e949c03801000000000000000001881300000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530541b9bacc18743d85c742cbad1e279795b9d65ceb6f65a3e74275c44d82397b49253e75a31f85b6a6457584c4e6f82665b092c0691c9f6dbb7a9e23c75eee0c005883408ce6a63f2cc5a74083b13c2ff00a157a942a7f612295aa60a67079ec5180fad382ca97a440e06d1a608409a2dec752c7e3d2af5f588ff916c9ed305108bdbde220108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa5f82012088a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c8820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc5c07c24c07efcc150e1b9146b0778635b14767243808d1ef151bd13a0c7b9aa800000000", + "03000000000101d1a6135f1ff14b9cab8c985a8e8a0f592d35c853c650c94699f23d16e949c03802000000000000000001881300000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530541e03fb12f0df28f44bc11f3616a7cea2fe917af6b313ebe172658bcf6cb7aab20e77cbe14f85b04e089115ef960b5f1f2366a56b974de5e204e2e01ba95ed9ca0834098f375906652892b3981614cbd934bf1cad5dac1a268512675ded7a864efc5222d3f15a82bc7ea9f660f0528b55168203523841f49eda2e5ab8d2c35104b3aa020108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa5f82012088a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c8820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc5c07c24c07efcc150e1b9146b0778635b14767243808d1ef151bd13a0c7b9aa800000000", + "03000000000101d1a6135f1ff14b9cab8c985a8e8a0f592d35c853c650c94699f23d16e949c03803000000000000000001881300000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530541ff5d2db0a146f63855de22f37e9b47ad16eb315501ca0e632d4ffb47a9d4b10e8d9a023f4ca8cb03d94106187f480b0db39db5b2d7a11c5257943368ec8298e08340f6a59b2916ecf0d8db5aedb36ff4fec171b00e6fb21ab1dcced274b24771f85ee367c8be3e15eaeb9671fd2d0ad4cce595e5dac25d8a7abcc14a6197acfd60ae20108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa5f82012088a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c8820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc5c07c24c07efcc150e1b9146b0778635b14767243808d1ef151bd13a0c7b9aa800000000" + ], + "signed_htlc_timeout_txs": [ + "03000000000101d1a6135f1ff14b9cab8c985a8e8a0f592d35c853c650c94699f23d16e949c03804000000000000000001a86100000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f53044111507e4bfb5c4e3c2a589485455198567c235fb292b1ac3eadf1b6c85606fc84147b6dc22f1dd1b9c9423ccb3dfe4759302a3aa947bcb91e0f8acbc0e953517183403eb08d427681b9524baaa55c9e14ededf9e8fe947294f9aa1d7e855ca145360ac93e2148533a717559f8f9913d17df6d89fac44ba53ef5b2c7aed76fa39271d44420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdcb9c77f9aea95f85b009611c0f3fd6c7fd8c6abb769f3f2b20b778f2ef57835cb4d0a0e00", + "03000000000101d1a6135f1ff14b9cab8c985a8e8a0f592d35c853c650c94699f23d16e949c03805000000000000000001a86100000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530441d0eabfa90134ca09fc37e86321f0eed24bfa39611ca8e7e803f0dbbe06ee02e027da9587c37c68814de3fa93c206506a3642a6b309904297bede6dc922bf2f9283409143998a61f1a74f6cf0118b5e1df3d8dfb293e59057c2325792fb3ec91ef173ba1f2cf238a12ae41f262705bfdd660b565a6b5d742ecf8dc7347bb7c12b31824420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdcb9c77f9aea95f85b009611c0f3fd6c7fd8c6abb769f3f2b20b778f2ef57835cb4d0a0e00", + "03000000000101d1a6135f1ff14b9cab8c985a8e8a0f592d35c853c650c94699f23d16e949c03806000000000000000001a86100000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530441f2acaef5a4bbef679062158f5af347f57f10278e4f2d0542e2c467dfb8394709ceb5e015001fc05b0df70ab2eec07e0c41d080cd026c015bfe1f5860273e9af38340b9e08d205badd9b88ba30eaee5595ca3eb9267219e1036bcf369aa36bbe7fab88ecc94a48a15e85fa7fc47fcbd316a6e95244d87c1af95b27285933aebfe4e074420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc855bf017f54352853790e29cd747dbd6d11f72fcc7d5620b3be0e55c9b20fff84d0a0e00" + ] + }, + { + "name": "Commitment transaction with all HTLCs above dust limit and millisatoshi truncation", + "dust_limit_satoshis": 5000, + "to_local_msat": 7949998969, + "to_remote_msat": 1983999030, + "incoming_htlcs": [ + { + "id": 7, + "amount_msat": 10000650, + "payment_hash": "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a", + "cltv_expiry": 920150 + }, + { + "id": 9, + "amount_msat": 6000320, + "payment_hash": "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a", + "cltv_expiry": 920150 + } + ], + "outgoing_htlcs": [ + { + "id": 5, + "amount_msat": 25000821, + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "cltv_expiry": 920141 + }, + { + "id": 8, + "amount_msat": 25000210, + "payment_hash": "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1", + "cltv_expiry": 920141 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "2d32f872c292b9d789fa8feba41bf94e2212e922f8c0d9a84ea76f392acd5712b9bc921081ad1cfd6120d57acd463c15b0c68326e1c6bf41b55ed4d1961c4142027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "03a04b07d8d7a0ea579a040377a8fc5a072ac7d2460932b904da8798a7648672de0202c3e864fbb4a82c17c2b080e1370b57821421b4160f9d9ee0c946fcf90cfc51", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800703000000000000000451024e7370170000000000002251200ebae7d7b56e2b69ef3f68813dcbaf76203e7a96a2a61aaf40fc701b78010b9910270000000000002251200ebae7d7b56e2b69ef3f68813dcbaf76203e7a96a2a61aaf40fc701b78010b99a8610000000000002251203251b6725c2501f563936bb8a52c4f580d82dbb04a1ef665bd1a9b2e15a4b497a861000000000000225120f70c636cef59ed56b5412473fc4324f20ec0f960d5d6a5950c5f376de5b28dddff451e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2aae4e79000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f5301400110971b4c77d23dacc437c73b602f3456bdf6cd8567c0abe65e94a953c22f29ba186352c4ef0131b3891580cccb35683cf9c3a2dae3f83d259e9617597dda1dc50fbb20", + "signed_htlc_success_txs": [ + "0300000000010196f6a555f9af38e2d5b74fd7d5ebfe060194bd84a692c1caa3a4890b6420163801000000000000000001701700000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f53054177a6bd9e85a28af99877ade26414a91d3fd6f0d3693f1b9392a65e8bbdde7cc5f4dacdcde3851003861838be99094b40e364c4e9b53654505c44835b3de4ff17834015b3b90c18d19bb2afe4fac1c6a7e0d0572e1746fb06f2663fe09ffd122f5eb02ca72d793a6c5b9df60d28888116744a740d94080e84df97af21177eea66babe20108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa5f82012088a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c8820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc5c07c24c07efcc150e1b9146b0778635b14767243808d1ef151bd13a0c7b9aa800000000", + "0300000000010196f6a555f9af38e2d5b74fd7d5ebfe060194bd84a692c1caa3a4890b6420163802000000000000000001102700000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f5305410cbaaf38ca646a9fc7ec6003b3896786a8b8ea57aecd6bb8cdf9f04d564f6d03e6ae2b2ad5468d6a5b952f81f2841bb02bc81772f125196b3ac5b5ab2eebfa8283403f11c8917af25892465d57641c91971313b760770beb905cd80055af5a3999427fcc958f49e75236a79d2f1a06d52190e93dad456166c4db4e37350bf67981b520108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa5f82012088a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c8820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc5c07c24c07efcc150e1b9146b0778635b14767243808d1ef151bd13a0c7b9aa800000000" + ], + "signed_htlc_timeout_txs": [ + "0300000000010196f6a555f9af38e2d5b74fd7d5ebfe060194bd84a692c1caa3a4890b6420163803000000000000000001a86100000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530441f9fc723dee4c4ede21cd06cd966e00da2a225d25df9b1a5a77973587f997eaa6879fadb866b6c7bc8c7a0466995d02420650c17a523e4cdbc4a10b1582861aef83401ae1a639380b42f9f3e18b2f443f2d8a2e4c0669f3c838f260616182d594454dc51aa3a9c6c7448e104817d4eb1f4e97ae7bdc12ee60d43ec3b06a2af8ef9e734420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdcb9c77f9aea95f85b009611c0f3fd6c7fd8c6abb769f3f2b20b778f2ef57835cb4d0a0e00", + "0300000000010196f6a555f9af38e2d5b74fd7d5ebfe060194bd84a692c1caa3a4890b6420163804000000000000000001a86100000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530441f5e26751a947e2692aa6c1cb680ae0e87b1afbe1935100484e02da1c0a0d854e1fb29f2539b70bee2f7ebd7564e30be5d468ca612a44aad2295bf68c27ccb31583407811c652363b7e797aa6ea009b483b0a5af85007e3e3ce57184aa9e28f325d48ce3ef84089463277c892719f5bafc787a4ff309cd4da19f93e4bb2e63598b2e24420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc855bf017f54352853790e29cd747dbd6d11f72fcc7d5620b3be0e55c9b20fff84d0a0e00" + ] + }, + { + "name": "Commitment transaction with dust HTLCs below maximum anchor amount", + "dust_limit_satoshis": 1000, + "to_local_msat": 7979870000, + "to_remote_msat": 1950000000, + "incoming_htlcs": [ + { + "id": 0, + "amount_msat": 100000, + "payment_hash": "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f", + "cltv_expiry": 920125 + }, + { + "id": 1, + "amount_msat": 49900000, + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "cltv_expiry": 920125 + } + ], + "outgoing_htlcs": [ + { + "id": 0, + "amount_msat": 10000000, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920140 + }, + { + "id": 1, + "amount_msat": 130000, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920140 + }, + { + "id": 2, + "amount_msat": 10000000, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920140 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "1ae6b574a6374a3b39cadeb330dce9bbbaf9bc30a8d1b58277c4a9672fb568ccc17f1cc117d88b3f35e21e85a5bba8e33bde25046e57a8eb1e6db61b0fca68f3027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "028325534e7a89d322ed61d70292e229731b42ef8a83b73b3fca16f4dd4cbae2a8029a7514ad81ac5b2acb104b97fbb755937859f9af6c5c233f5da375e7497179ac", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef8006e6000000000000000451024e731027000000000000225120db225366386af64827ca65304e9e6eb35a4e0c86e9e95fde7f234312ad3324b61027000000000000225120db225366386af64827ca65304e9e6eb35a4e0c86e9e95fde7f234312ad3324b6ecc2000000000000225120749b295cf618379c8b3be5b92a34b22030ce5e723e7ab766d6c31c9246dbd16430c11d0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2a5ec379000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530140d789ee1bffce938d84a2365c3e3f743f68a4a8ef52bb17213f8aaba63bce52071a46139b4cf95a6b5b83bcd26d1e77bbbafee3d849805c3a0c7b86ed703cf24ec50fbb20", + "signed_htlc_success_txs": [ + "03000000000101b0d9345cb08bb46f5d0c124f6b06db2c29419b29f6394327e938f133c58ce9ba03000000000000000001ecc200000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f5305419a459114d2388a222a95d206d38f0c2aa844f54cd78f12f89e4ac60c8511c2f3ead8d56f1ca8a392dd628d0e607a87303cce399cd8229589f53b3e6a1915acb78340649264c4dc2895b525f6f262cefbeb29f61ce75e00b1c2a2b2a2bcab34ff930ee64fcbbfa174e7e5d51e20e6da458c6f5d0781ebbf69f4bbc3fdc143dab70ddb205591b96c0a6a03f51c27bfa658149260bd2fe5e2ce83130ce50d0229a3a947c55f82012088a914488ed834d26f1a1dc5e3428e1e1a214f743e6a248820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc367472dacdd139c4f76b1d9b36b02fe57d4f29847848c5892adc754271d8aef900000000" + ], + "signed_htlc_timeout_txs": [ + "03000000000101b0d9345cb08bb46f5d0c124f6b06db2c29419b29f6394327e938f133c58ce9ba01000000000000000001102700000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530441d63b1203cc613c23c90f6a2f07ed03c0f6bfc66a8e495874186de28c67e171feab5289d2c8f62705a6e564d441549e0c2ddc5bf07c695cf43cc98c568d36598783407997593780d13162ed17e129eab624f21e10e5e8a09b03c799111aa6d338dce7fa44fb0789e929a9a1136fc74279537a833918fe7c1d1ba760c2295fc02936f94420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc90bec924e7290bd4648d4ffe2da5fa63f47de648eaa30522b6976db62ac8e8c84c0a0e00", + "03000000000101b0d9345cb08bb46f5d0c124f6b06db2c29419b29f6394327e938f133c58ce9ba02000000000000000001102700000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f5304414285b4581c78eabe8c07069afcb8aa4e7dc295ecdfd47c754012b376bf08dfd2688f5c8273c2df2cdf86362eece381b7be2f9ec403f5cee43e22efc39d29af3a834070e14f6cf2e28e90a0ed7859a201e9a5441bbbd7fd56b24a6a39bf8483aeb036b1c2d73244f503a0ac01189d825814dcbc7f3ead6a9577ba527086db62034c7f4420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc90bec924e7290bd4648d4ffe2da5fa63f47de648eaa30522b6976db62ac8e8c84c0a0e00" + ] + }, + { + "name": "Commitment transaction with similar dust HTLCs below maximum anchor amount", + "dust_limit_satoshis": 546, + "to_local_msat": 7999880000, + "to_remote_msat": 1999940000, + "incoming_htlcs": [ + { + "id": 0, + "amount_msat": 30000, + "payment_hash": "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f", + "cltv_expiry": 920125 + }, + { + "id": 1, + "amount_msat": 30000, + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "cltv_expiry": 920125 + } + ], + "outgoing_htlcs": [ + { + "id": 0, + "amount_msat": 30000, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920125 + }, + { + "id": 1, + "amount_msat": 30000, + "payment_hash": "1a04764fd402b5557cba89ec3c4d8931b0225d6436923c65c079ce64a55084c4", + "cltv_expiry": 920125 + }, + { + "id": 2, + "amount_msat": 30000, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920125 + }, + { + "id": 3, + "amount_msat": 30000, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920125 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "c05bb5fef40721fe3910c7ebb2abc7707d8d7315f48614331bc8fd1d3ee0c0ebe6cb9d0d4138f7e10f0f9cda1421c796c9bb45093dbff4ad4e9f3fcb9a0242f0027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "02eaa07bb702dba5f559612aae35a585bcd2cb1ae332b654cc5a03b0f3463cdc9902a535e4f7ab41e8e4d51fc99539320005546f50c55c29ce74f38d3590b8362647", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef8003b4000000000000000451024e7344841e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2a88117a000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530140d04a00d9dc83694c6041cf460aae13f71ac182c12b43bceb86594d7c140de5eecec95a3502a1e81476072d23d25e7022ec7548eb40d2dc70812a0549b40efe9dc50fbb20", + "signed_htlc_success_txs": [], + "signed_htlc_timeout_txs": [] + }, + { + "name": "Commitment transaction with millisatoshi dust HTLCs adding to less than 1 satoshi", + "dust_limit_satoshis": 330, + "to_local_msat": 7999978526, + "to_remote_msat": 1999970475, + "incoming_htlcs": [ + { + "id": 0, + "amount_msat": 29525, + "payment_hash": "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f", + "cltv_expiry": 920125 + } + ], + "outgoing_htlcs": [ + { + "id": 0, + "amount_msat": 21474, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920125 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "15c88142f22085b1084d6c20832116011fa08a79a7238da80dfbd05d198c5aaf22648c64a52ece3c0211ebc7733365612d5b14ae339c6f1945479258e41a39a9027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "02ba9b0a63e19af69ff07d43a7eaafdbfe9e29471fb36c4e7cca8b8959af30983603ee6796b014e9a87b3cf5d160d1c94e8a6ffdfa25b06e37c4ed5aa82ac1eef3d5", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800334000000000000000451024e7362841e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2aea117a000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530140332ec47b81166975156ae9900f6c06d44699d47d5394f9fb58d187f8632178ed06a13ca16506eb830fc318121affc7026295bfbeb1c459fc670c6f9279c4ec9ec50fbb20", + "signed_htlc_success_txs": [], + "signed_htlc_timeout_txs": [] + }, + { + "name": "Commitment transaction with millisatoshi dust HTLCs adding to 1 satoshi", + "dust_limit_satoshis": 330, + "to_local_msat": 7999978525, + "to_remote_msat": 1999970475, + "incoming_htlcs": [ + { + "id": 0, + "amount_msat": 29525, + "payment_hash": "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f", + "cltv_expiry": 920125 + } + ], + "outgoing_htlcs": [ + { + "id": 0, + "amount_msat": 21475, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920125 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "d36abbab76a943a1f307c0f270a4e0e1b8956538ccf07cf3b5b62bb68fe2e5cdb843eaf2aa5449b601d9a3431f8ec61176eb5b46d54227d013a54e29a2340efa027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "02329b83e213ced5719408918847408287d1f24b57d114dec24a39d0a2398143c502d8daa025101353095807d66155175a7f0ae36012d422b973c0a526ccabe8234f", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800334000000000000000451024e7362841e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2aea117a000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f5301408be3f42feec38926431b98a5583689545af6841681e4b29311acef275bed30127f89d23b68ad10b0139e36f642d854de0a620641de9f165430ec501b57a35562c50fbb20", + "signed_htlc_success_txs": [], + "signed_htlc_timeout_txs": [] + }, + { + "name": "Commitment transaction with millisatoshi dust HTLCs adding to more than 1 satoshi", + "dust_limit_satoshis": 330, + "to_local_msat": 7999978288, + "to_remote_msat": 1999970247, + "incoming_htlcs": [ + { + "id": 0, + "amount_msat": 29753, + "payment_hash": "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f", + "cltv_expiry": 920125 + } + ], + "outgoing_htlcs": [ + { + "id": 0, + "amount_msat": 21712, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920125 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "987b96702ae094d46f9a0d3a00d3b25063c43a8ce8d18c27d41b3562ce0c03d2bdc8921e5f28ee941c868c639a81c880f7ba28c348c7c85a39b3d700ac35d711027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "024be6701b144d18a4bcbd4294c7bc9625ad067d80317cd17e4800ea9a5d99a37503087d19735d801be40c77150922f6d7b58c381ffca47147d7e5f76b117cba47e7", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800334000000000000000451024e7362841e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2aea117a000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530140c82267fc4fd1ed73368eb4f962e236053d94f6ae8867f6b16d785eacb40b82f96c4e6d5cf430cda8098ecf5e1c83550f1ee6413dcf9eea940604a9e1a411459cc50fbb20", + "signed_htlc_success_txs": [], + "signed_htlc_timeout_txs": [] + }, + { + "name": "Commitment transaction with dust HTLCs above maximum anchor amount", + "dust_limit_satoshis": 2500, + "to_local_msat": 7988000000, + "to_remote_msat": 1988000000, + "incoming_htlcs": [ + { + "id": 0, + "amount_msat": 2000000, + "payment_hash": "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f", + "cltv_expiry": 920125 + }, + { + "id": 1, + "amount_msat": 5000000, + "payment_hash": "ffa4f37b6d7dc03fecaaed8d36ebbea6d199e820e386e4549a69ce733f39f29f", + "cltv_expiry": 920130 + }, + { + "id": 2, + "amount_msat": 5000000, + "payment_hash": "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a", + "cltv_expiry": 920130 + } + ], + "outgoing_htlcs": [ + { + "id": 0, + "amount_msat": 1000000, + "payment_hash": "1a04764fd402b5557cba89ec3c4d8931b0225d6436923c65c079ce64a55084c4", + "cltv_expiry": 920125 + }, + { + "id": 1, + "amount_msat": 1000000, + "payment_hash": "29a74a69c5941d402838f7e1a95c2b2ec534d79524b2582f48df7bc519ebaecf", + "cltv_expiry": 920130 + }, + { + "id": 2, + "amount_msat": 10000000, + "payment_hash": "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1", + "cltv_expiry": 920130 + } + ], + "local_secret_nonce": "bd251bece9032bf3c1edd509d9bbb781b9c07c98247161be7259f33d8916bcfd1028e195791de8665c5dab04d6c5a724429cc55f944435dd3fa6ec308d456ce003bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed08070", + "local_public_nonce": "02f71acd38454262c1fcb339c4529fd514154171668dd77aae17905ab6b36650cb03bf5198bbb8292bc35d8dab27a92f0fb58ebbeb2c4d5e31bbdcbe05897bdc97f3", + "remote_secret_nonce": "992b140611a061530517b1a63b2906641e99773a7dfee8ae0ce809dec61b8e3b193dc2115ec43f784a95f9e86c9f13b4ae6725e71b72817c899ea22499f42db3027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd6", + "remote_public_nonce": "02a1908758bc1a0ba91da4a84cd1d19fde5a569d25a53e130832bf33463efaeb3c02d4272ba3017f007d1f98a5cf2d787a473b1419a63f8767d9f7d73364bb6b7345", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef8006f0000000000000000451024e73881300000000000022512016681bb995a8d3205eeb0574b5a5d1141005c5e9aaed40ce4b1040af38c983cf8813000000000000225120699fea589ad3b219262947cab5e2b46a47593a1f5e36a068fbc16c4b5ebbc68a1027000000000000225120f70c636cef59ed56b5412473fc4324f20ec0f960d5d6a5950c5f376de5b28ddda0551e0000000000225120fb5308fc3509a62bc04d87710a8dce5ce623f129e3605278f2438bc3fcc39f2a20e379000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530140daa8e02bbe5e9c369b779a605a1a8a94832aefd1652ae9d4583078a28f8c7ad687a5e5e88e51ed13cdae245e5359d6676b54e3cea8b447e625b918b468a1e81dc50fbb20", + "signed_htlc_success_txs": [ + "030000000001015084a94f3e337ff13526d0a616de355b0854e0001d826f8d118686e704651cad01000000000000000001881300000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530541aafc9e30eeda528afa1a7b2f36faca60339440753d379f401d7803cf49bc7d322d4c4eb5788f54b16fc21e4d241bf8da62fd3b1b795be92f9c8c11cd8545d3028340fcf34e1a7935d56a0f0a04e58c80f30c587b734db9fb7f5200266fcad5e4b23e11057aa4aa50b429960d8c07eb93f7b1bbacb0c8f3cd97ed02699346139f6b6a20108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa5f82012088a914f4c8e88504a23ed3e390ea80300c834f0eb79a6c8820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c170308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc1811bd57f81e3e9d9c3876ead4c2968781a679ed93313cfd0300e391ed7e367300000000", + "030000000001015084a94f3e337ff13526d0a616de355b0854e0001d826f8d118686e704651cad02000000000000000001881300000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f5305414a8b12525a8684120df95b5014d371f6b0e5d3f0022adcc677147874cac732c16b42a27289af54cb7a729cc2eca17d6efd89dcc39d066337d61587bba8e245198340e34d1c4e07c0e3fe8e23243caa2feab76c4363eb6bdd88bbb396698ec926834f34017f92c357e36abb824ef0b2b0260c7fd8821009d2b40ae2f48d17f3ab7b9420d3ad493d19860e4744491cf0795c0bc96a8e2a49ebb30afadae7a7d077aa93b25f82012088a91416a189e9fcfe9edc8c6930da3dd87cebf44045a38820c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc1811bd57f81e3e9d9c3876ead4c2968781a679ed93313cfd0300e391ed7e367300000000" + ], + "signed_htlc_timeout_txs": [ + "030000000001015084a94f3e337ff13526d0a616de355b0854e0001d826f8d118686e704651cad03000000000000000001102700000000000022512071c8a92d73aab6c7eceba0331fe37358d67cfb7d46b07be448128c8afa554f530441f13bd0f4a9e75a1c2dd0529fe7022e1b6a1867350d6fb7492ff1d13f40eaaeb60a6253c48d62885960ff6b960e7444bca9144ec0eb64645c56c1c4e490476bd38340a419d5ce4067047f1c4481cee67d2e75efe60f33a36c5ec7af5befabf8e3412d9a6c492c8cd90526d490c586ab54e40dfa286cda5c037ae74ea72122e99341f44420c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac41c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdc855bf017f54352853790e29cd747dbd6d11f72fcc7d5620b3be0e55c9b20fff8420a0e00" + ] + } + ] +} \ No newline at end of file diff --git a/taproot_channel_open.jpg b/taproot_channel_open.jpg new file mode 100644 index 000000000..ea4753087 Binary files /dev/null and b/taproot_channel_open.jpg differ diff --git a/taproot_channel_operation.jpg b/taproot_channel_operation.jpg new file mode 100644 index 000000000..a50e832d9 Binary files /dev/null and b/taproot_channel_operation.jpg differ