diff --git a/03-transactions.md b/03-transactions.md index 4463ea36d..30ae9eeb4 100644 --- a/03-transactions.md +++ b/03-transactions.md @@ -18,6 +18,7 @@ This details the exact format of on-chain transactions, which both sides need to * [Received HTLC Outputs](#received-htlc-outputs) * [Trimmed Outputs](#trimmed-outputs) * [HTLC-timeout and HTLC-success Transactions](#htlc-timeout-and-htlc-success-transactions) + * [HTLC Claim Transaction (`option_htlcs_claim_tx`)](#htlc-claim-transaction-option_htlcs_claim_tx) * [Legacy Closing Transaction](#legacy-closing-transaction) * [Closing Transaction](#closing-transaction) * [Fees](#fees) @@ -198,7 +199,7 @@ Spending of the output requires the following (empty) witness: #### Offered HTLC Outputs -This output sends funds to either an HTLC-timeout transaction after the HTLC-timeout or to the remote node using the payment preimage or the revocation key. The output is a P2WSH, with a witness script (no `option_anchors`): +This output sends funds to either an HTLC-timeout transaction after the HTLC-timeout or to the remote node using the payment preimage or the revocation key. Unless `option_htlcs_claim_tx` applies, the output is a P2WSH with a witness script (no `option_anchors`): # To remote node with revocation key OP_DUP OP_HASH160 OP_EQUAL @@ -235,13 +236,33 @@ Or, with `option_anchors`: 1 OP_CHECKSEQUENCEVERIFY OP_DROP OP_ENDIF -The remote node can redeem the HTLC with the witness: +Unless `option_htlcs_claim_tx` applies, the remote node can redeem the HTLC with the witness: Note that if `option_anchors` applies, the nSequence field of the spending input must be `1`. +If `option_htlcs_claim_tx` applies, the output is a P2TR output with 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`: + ``` + OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 OP_EQUALVERIFY + OP_TEMPLATEHASH OP_EQUAL + ``` + +If `option_htlcs_claim_tx` applies, the remote node can redeem the HTLC with the [HTLC Claim Transaction](#htlc-claim-transaction-option_htlcs_claim_tx) specified below and witness: + + + If a revoked commitment transaction is published, the remote node can spend this output immediately with the following witness: @@ -383,6 +404,19 @@ The witness script for the output is: To spend this via penalty, the remote node uses a witness stack ` 1`, and to collect the output, the local node uses an input with nSequence `to_self_delay` and a witness stack ` 0`. +## HTLC Claim Transaction (`option_htlcs_claim_tx`) + +* version: 3 +* locktime: 0 +* txin count: 1 + * `txin[0]` outpoint: `txid` of the commitment transaction and `output_index` of the matching offered HTLC output + * `txin[0]` sequence: `0` + * `txin[0]` script bytes: `0` + * `txin[0]` witness stack: ` ` +* txout count: 1 + * `txout[0]` amount: the offered HTLC output amount (the HTLC `amount_msat` divided by 1000, rounding down); the transaction pays zero fees + * `txout[0]` script: a P2WPKH to `remotepubkey`, as for the [`to_remote` Output](#to_remote-output) + ## Legacy Closing Transaction This variant is used for `closing_signed` messages (i.e. where `option_simple_close` is not negotiated). @@ -2427,6 +2461,12 @@ Test vectors [are provided](./bolt03/zero-fee-commitments-test.json) that detail transactions created using `zero_fee_commitments` in various scenarios. All parameters are provided to ensure that implementations generate exactly the same signed transactions. +# Appendix I: Commitment and HTLC Transaction Test Vectors (htlcs_claim_tx) + +Test vectors [are provided](./bolt03/htlcs-claim-tx-test.json) that detail commitment and HTLC +transactions created using `option_htlcs_claim_tx` in various scenarios. All parameters are provided +to ensure that implementations generate exactly the same signed transactions. + # References # Authors diff --git a/05-onchain.md b/05-onchain.md index 3b781b651..2a0219a25 100644 --- a/05-onchain.md +++ b/05-onchain.md @@ -499,7 +499,11 @@ A local node: - if it receives (or already possesses) a payment preimage for an unresolved HTLC output that it was offered AND for which it has committed to an outgoing HTLC: - - MUST *resolve* the output by spending it to a convenient address. + - if `option_htlcs_claim_tx` applies: + - MUST *resolve* the output by broadcasting the [HTLC claim + transaction](03-transactions.md#htlc-claim-transaction-option_htlcs_claim_tx). + - otherwise: + - MUST *resolve* the output by spending it to a convenient address. - otherwise: - if the remote node is NOT irrevocably committed to the HTLC: - MUST NOT *resolve* the output by spending it. diff --git a/09-features.md b/09-features.md index 1e68c03c7..72f82ea7a 100644 --- a/09-features.md +++ b/09-features.md @@ -57,6 +57,7 @@ The Context column decodes as follows: | 50/51 | `option_zeroconf` | Understands zeroconf channel types | INT | `option_scid_alias` | [BOLT #2][bolt02-channel-ready] | | 60/61 | `option_simple_close` | Simplified closing negotiation | IN | `option_shutdown_anysegwit` | [BOLT #2][bolt02-simple-close] | | 62/63 | `option_splice` | Allows replacing the funding transaction with a new one | IN | | [BOLT #2](02-peer-protocol.md#channel-splicing) | +| 110/111 | `option_htlcs_claim_tx` | V3 claim transaction for offered HTLCs preimage spends | IN | `zero_fee_commitments` | [BOLT #3][bolt03-templated-offered-htlcs] | ## Requirements @@ -104,6 +105,7 @@ This work is licensed under a [Creative Commons Attribution 4.0 International Li [bolt02-simple-close]: 02-peer-protocol.md#closing-negotiation-closing_complete-and-closing_sig [bolt03-htlc-tx]: 03-transactions.md#htlc-timeout-and-htlc-success-transactions [bolt03-shared-anchor]: 03-transactions.md#shared_anchor-output-zero_fee_commitments +[bolt03-templated-offered-htlcs]: 03-transactions.md#offered-htlc-outputs [bolt02-shutdown]: 02-peer-protocol.md#closing-initiation-shutdown [bolt02-quiescence]: 02-peer-protocol.md#channel-quiescence [bolt02-channel-ready]: 02-peer-protocol.md#the-channel_ready-message diff --git a/bolt03/htlcs-claim-tx-test.json b/bolt03/htlcs-claim-tx-test.json new file mode 100644 index 000000000..e010797ae --- /dev/null +++ b/bolt03/htlcs-claim-tx-test.json @@ -0,0 +1,119 @@ +{ + "comment": "Test vectors for the option_htlcs_claim_tx feature. Channel parameters reuse the same keys as zero-fee-commitments-test.json. Alice (local) is the commitment broadcaster; Bob (remote) can claim offered HTLCs via the htlc_success tapscript path using the HTLC claim transaction.", + "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": { + "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983": "5591b96c0a6a03f51c27bfa658149260bd2fe5e2ce83130ce50d0229a3a947c5", + "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1": "c916e086a4cd7d40f198708aefadd31149da628f820ca2fc213af10f7668501c", + "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a": "108cd7067c8ed6f3734b7b67ec153cfa83c40755b75c65e414e934099e6993aa" + }, + "tests": [ + { + "name": "Commitment transaction with a single outgoing HTLC above dust", + "comment": "Alice has one offered (outgoing) HTLC. The offered HTLC output is a P2TR; the remote (Bob) can claim it via the htlc_success tapscript path using the HTLC claim transaction.", + "dust_limit_satoshis": 5000, + "to_local_msat": 7925000000, + "to_remote_msat": 2075000000, + "outgoing_htlcs": [ + { + "id": 5, + "amount_msat": 25000000, + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "cltv_expiry": 920141 + } + ], + "counterparty_sig": "30450221008751c005679210d03024acbc9b7d48fcc4fdef4705ccc57e807d08b03ac7195002201d7dad4dd5175ab45989ec1ba73027b43d731168c527a001c3461010a5c9e094", + "holder_sig": "304402207f0326a70ede1f74e48c139d917f0088d31761512247ef616e9ea892789ef8dc022062ef129647840952bb5a6512d56d56615b43fddd0372a40737bed33673548ccd", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800400000000000000000451024e73a861000000000000225120ac5217e5ac3039da7f479095f44d7058470dc146583c7412bcef9f4b6c820db878a91f0000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea608b780000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a04004830450221008751c005679210d03024acbc9b7d48fcc4fdef4705ccc57e807d08b03ac7195002201d7dad4dd5175ab45989ec1ba73027b43d731168c527a001c3461010a5c9e0940147304402207f0326a70ede1f74e48c139d917f0088d31761512247ef616e9ea892789ef8dc022062ef129647840952bb5a6512d56d56615b43fddd0372a40737bed33673548ccd01475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", + "htlc_claim_txs": [ + { + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "output_index": 1, + "htlc_timeout_script": "20c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac", + "htlc_success_script": "82012088a914488ed834d26f1a1dc5e3428e1e1a214f743e6a2488204f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17fce87", + "template_hash": "4f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17f", + "htlc_claim_tx": "030000000104430f5dfcde134fc4f7e5b6c345d8ea47d3bf2cad01fa3efa27a757296b165201000000000000000001a861000000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea00000000", + "htlc_claim_tx_with_witness": "0300000000010104430f5dfcde134fc4f7e5b6c345d8ea47d3bf2cad01fa3efa27a757296b165201000000000000000001a861000000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea03205591b96c0a6a03f51c27bfa658149260bd2fe5e2ce83130ce50d0229a3a947c53e82012088a914488ed834d26f1a1dc5e3428e1e1a214f743e6a2488204f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17fce8741c170308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdcd23dd8e923d3880bee23a2b95d54c89c8a4d82a5903e96be5f0e99c262bb126300000000" + } + ] + }, + { + "name": "Commitment transaction with millisatoshi truncation in HTLC claim transaction", + "comment": "The offered HTLC has 25000821 msat. The claim transaction output is truncated to 25000 sat (821 msat dropped, zero-fee transaction). The template hash commits to the 25000 sat output, which is identical to the non-truncated 25000000 msat case.", + "dust_limit_satoshis": 5000, + "to_local_msat": 7900000000, + "to_remote_msat": 2100000000, + "outgoing_htlcs": [ + { + "id": 8, + "amount_msat": 25000821, + "payment_hash": "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1", + "cltv_expiry": 920141 + } + ], + "counterparty_sig": "30440220397404d3725e7dd53116c4a4bbfa33e0c2bf9cd141ef798273d5bbdd9cddcd6f02202169308d71911d2e44bda9c3da1c03faaf854b72b274bce9253e24ba108ccb23", + "holder_sig": "304402207363d0a8b6e86b8c1a7b5e249d7c1ae1633433dc4cd741b760a9f37999c50bcd02200a14d835b77d2204554337320da5fd099462d24af836ac818bdf00e04967ebef", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800401000000000000000451024e73a8610000000000002251208b74ecccf0ec6463d625e6bf7f5e2161fc34e3110f894fe9189e6a9c5317d367200b200000000000160014f2123f1a4b67887f2e5f02eda73e6327010152eab729780000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a04004730440220397404d3725e7dd53116c4a4bbfa33e0c2bf9cd141ef798273d5bbdd9cddcd6f02202169308d71911d2e44bda9c3da1c03faaf854b72b274bce9253e24ba108ccb230147304402207363d0a8b6e86b8c1a7b5e249d7c1ae1633433dc4cd741b760a9f37999c50bcd02200a14d835b77d2204554337320da5fd099462d24af836ac818bdf00e04967ebef01475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", + "htlc_claim_txs": [ + { + "payment_hash": "10b879729e8ddd44f2cfcf3cad6d62be535ca74e293c5ed4a59bd0dcbdad7ca1", + "output_index": 1, + "htlc_timeout_script": "20c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac", + "htlc_success_script": "82012088a914504170790db95d43716b136806e6a0fdf06e39e488204f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17fce87", + "template_hash": "4f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17f", + "htlc_claim_tx": "030000000100886fcf3999d07f5a886f193db5f1d004daa960235f303726accf3bb20bc04d01000000000000000001a861000000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea00000000", + "htlc_claim_tx_with_witness": "0300000000010100886fcf3999d07f5a886f193db5f1d004daa960235f303726accf3bb20bc04d01000000000000000001a861000000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea0320c916e086a4cd7d40f198708aefadd31149da628f820ca2fc213af10f7668501c3e82012088a914504170790db95d43716b136806e6a0fdf06e39e488204f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17fce8741c070308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdcd23dd8e923d3880bee23a2b95d54c89c8a4d82a5903e96be5f0e99c262bb126300000000" + } + ] + }, + { + "name": "Commitment transaction with one outgoing (offered, P2TR) and one incoming (received, P2WSH) HTLC", + "comment": "Offered HTLC output is P2TR with the two-leaf tapscript tree; received HTLC output is unchanged P2WSH. The htlc_success leaf in the offered output commits to the HTLC claim transaction via OP_TEMPLATEHASH.", + "dust_limit_satoshis": 5000, + "to_local_msat": 7000000000, + "to_remote_msat": 2995000000, + "incoming_htlcs": [ + { + "id": 1, + "amount_msat": 5000000, + "payment_hash": "23877c9093799487a8d49c7d6aaff7e06b9831c547400605252e7b07f7ae638a", + "cltv_expiry": 920150 + } + ], + "outgoing_htlcs": [ + { + "id": 5, + "amount_msat": 25000000, + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "cltv_expiry": 920141 + } + ], + "counterparty_sig": "304402205f818e459e0ec72dc00eba606eca389af4726c39d7f16a3570c64d26cbad665f02201333cefd527c771135fff156043f9429e2228c981f42cf54bcad3bf45805b599", + "holder_sig": "30440220195dfbc8eaef5e18212c268f6d5d9a251463ef52334bd1f8f3ecdff263e7a42102200c6faa6b316d7bb16246cc30553fd53e2731e45f190fb84dedc0220f907f4fc3", + "signed_commit_tx": "03000000000101ae1e3c841378cf9e4c383bfdd033d4b3c6945e0587ff16635a00b347eea2704b0100000000340fef800500000000000000000451024e73881300000000000022002075254560bb02c207015847abfda36d3a1b882e78c3f04b08325aac21c53989dca861000000000000225120ac5217e5ac3039da7f479095f44d7058470dc146583c7412bcef9f4b6c820db838b32d0000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea186e6a0000000000220020f2d298ffcfd6d899a3abada37bfc6f42ce0b7b66f3e39e903e8419ac97dca75a040047304402205f818e459e0ec72dc00eba606eca389af4726c39d7f16a3570c64d26cbad665f02201333cefd527c771135fff156043f9429e2228c981f42cf54bcad3bf45805b599014730440220195dfbc8eaef5e18212c268f6d5d9a251463ef52334bd1f8f3ecdff263e7a42102200c6faa6b316d7bb16246cc30553fd53e2731e45f190fb84dedc0220f907f4fc301475221027eb9596a68740445fb151ff37d5422e7f65f2c497c90fda63e738eb606c15bd62103bbc16dc8851bece603322f06b3c8da329401b7be7e9fdd3f3090ad19aed0807052aec50fbb20", + "htlc_claim_txs": [ + { + "payment_hash": "72c9386ba5a9d97b821d855930236d39c48dab5b1c2efe9ada44e2fbadcff983", + "output_index": 2, + "htlc_timeout_script": "20c26117339025855b87deda5e138d438b2098881a5e6f81f72a60310faef473c6ad20d8507a026fb30bcd48ee9c765c7346470d0d397661d43dd2eb601f661ab92a0bac", + "htlc_success_script": "82012088a914488ed834d26f1a1dc5e3428e1e1a214f743e6a2488204f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17fce87", + "template_hash": "4f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17f", + "htlc_claim_tx": "03000000013d08505cc774eb835f4f655a12f1ae4f8338b4af2638c875057cee69d2e890b002000000000000000001a861000000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea00000000", + "htlc_claim_tx_with_witness": "030000000001013d08505cc774eb835f4f655a12f1ae4f8338b4af2638c875057cee69d2e890b002000000000000000001a861000000000000160014f2123f1a4b67887f2e5f02eda73e6327010152ea03205591b96c0a6a03f51c27bfa658149260bd2fe5e2ce83130ce50d0229a3a947c53e82012088a914488ed834d26f1a1dc5e3428e1e1a214f743e6a2488204f46273b2c989d2183e1379c396f5b575b859862c20938318418f31b6cedd17fce8741c170308d9e9b4846a1b51accdae500e43383b11e906d0fab0a1e0f5ba203d3ccdcd23dd8e923d3880bee23a2b95d54c89c8a4d82a5903e96be5f0e99c262bb126300000000" + } + ] + } + ] +}