@@ -19,20 +19,34 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
1919use crate :: ln:: channel;
2020#[ cfg( anchors) ]
2121use crate :: ln:: chan_utils;
22+ #[ cfg( anchors) ]
23+ use crate :: ln:: channelmanager:: ChannelManager ;
2224use crate :: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , PaymentId } ;
2325use crate :: ln:: msgs:: ChannelMessageHandler ;
2426#[ cfg( anchors) ]
2527use crate :: util:: config:: UserConfig ;
2628#[ cfg( anchors) ]
29+ use crate :: util:: crypto:: sign;
30+ #[ cfg( anchors) ]
2731use crate :: util:: events:: BumpTransactionEvent ;
2832use crate :: util:: events:: { Event , MessageSendEvent , MessageSendEventsProvider , ClosureReason , HTLCDestination } ;
33+ #[ cfg( anchors) ]
34+ use crate :: util:: ser:: Writeable ;
35+ #[ cfg( anchors) ]
36+ use crate :: util:: test_utils;
2937
38+ #[ cfg( anchors) ]
39+ use bitcoin:: blockdata:: transaction:: EcdsaSighashType ;
3040use bitcoin:: blockdata:: script:: Builder ;
3141use bitcoin:: blockdata:: opcodes;
3242use bitcoin:: secp256k1:: Secp256k1 ;
3343#[ cfg( anchors) ]
34- use bitcoin:: { Amount , Script , TxIn , TxOut , PackedLockTime } ;
44+ use bitcoin:: secp256k1:: SecretKey ;
45+ #[ cfg( anchors) ]
46+ use bitcoin:: { Amount , PublicKey , Script , TxIn , TxOut , PackedLockTime , Witness } ;
3547use bitcoin:: Transaction ;
48+ #[ cfg( anchors) ]
49+ use bitcoin:: util:: sighash:: SighashCache ;
3650
3751use crate :: prelude:: * ;
3852
@@ -1749,7 +1763,7 @@ fn test_yield_anchors_events() {
17491763
17501764 let mut holder_events = nodes[ 0 ] . chain_monitor . chain_monitor . get_and_clear_pending_events ( ) ;
17511765 // Certain block `ConnectStyle`s cause an extra `ChannelClose` event to be emitted since the
1752- // best block is being updated prior to the confirmed transactions.
1766+ // best block is updated before the confirmed transactions are notified .
17531767 match * nodes[ 0 ] . connect_style . borrow ( ) {
17541768 ConnectStyle :: BestBlockFirst |ConnectStyle :: BestBlockFirstReorgsOnlyTip |ConnectStyle :: BestBlockFirstSkippingBlocks => {
17551769 assert_eq ! ( holder_events. len( ) , 3 ) ;
@@ -1816,3 +1830,290 @@ fn test_yield_anchors_events() {
18161830 // Clear the remaining events as they're not relevant to what we're testing.
18171831 nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
18181832}
1833+
1834+ #[ cfg( anchors) ]
1835+ #[ test]
1836+ fn test_anchors_aggregated_revoked_htlc_tx ( ) {
1837+ // Test that `ChannelMonitor`s can properly detect and claim funds from a counterparty claiming
1838+ // multiple HTLCs in a single transaction via the success path from a revoked commitment.
1839+ let secp = Secp256k1 :: new ( ) ;
1840+ let mut chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
1841+ // Required to sign a revoked commitment transaction
1842+ chanmon_cfgs[ 1 ] . keys_manager . disable_revocation_policy_check = true ;
1843+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
1844+ let mut anchors_config = UserConfig :: default ( ) ;
1845+ anchors_config. channel_handshake_config . announced_channel = true ;
1846+ anchors_config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = true ;
1847+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( anchors_config) , Some ( anchors_config) ] ) ;
1848+
1849+ let bob_persister: test_utils:: TestPersister ;
1850+ let bob_chain_monitor: test_utils:: TestChainMonitor ;
1851+ let bob_deserialized: ChannelManager <
1852+ & test_utils:: TestChainMonitor , & test_utils:: TestBroadcaster , & test_utils:: TestKeysInterface ,
1853+ & test_utils:: TestKeysInterface , & test_utils:: TestKeysInterface , & test_utils:: TestFeeEstimator ,
1854+ & test_utils:: TestRouter , & test_utils:: TestLogger ,
1855+ > ;
1856+
1857+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
1858+
1859+ let chan_id = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 1_000_000 ) . 2 ;
1860+
1861+ // Route two payments from Alice to Bob to lock in the HTLCs.
1862+ let ( payment_preimage_a, payment_hash_a, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 100_000_000 ) ;
1863+ let ( payment_preimage_b, payment_hash_b, _) = route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , 100_000_000 ) ;
1864+
1865+ // Serialize Bob with the HTLCs locked in. We'll restart Bob later on with the state at this
1866+ // point such that he broadcasts a revoked commitment transaction.
1867+ let bob_serialized = nodes[ 1 ] . node . encode ( ) ;
1868+ let bob_serialized_monitor = get_monitor ! ( nodes[ 1 ] , chan_id) . encode ( ) ;
1869+
1870+ // Bob claims both HTLCs...
1871+ claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , payment_preimage_a) ;
1872+ claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , payment_preimage_b) ;
1873+
1874+ // ...and sends one back such that he has a motive to broadcast his revoked state.
1875+ send_payment ( & nodes[ 1 ] , & [ & nodes[ 0 ] ] , 30_000_000 ) ;
1876+
1877+ // Restart Bob with the revoked state and provide the HTLC preimages he claimed.
1878+ reload_node ! ( nodes[ 1 ] , anchors_config, bob_serialized, & [ & bob_serialized_monitor] , bob_persister, bob_chain_monitor, bob_deserialized) ;
1879+ get_monitor ! ( nodes[ 1 ] , chan_id) . provide_payment_preimage (
1880+ & payment_hash_a, & payment_preimage_a, & node_cfgs[ 1 ] . tx_broadcaster ,
1881+ & LowerBoundedFeeEstimator :: new ( node_cfgs[ 1 ] . fee_estimator ) , & nodes[ 1 ] . logger
1882+ ) ;
1883+ get_monitor ! ( nodes[ 1 ] , chan_id) . provide_payment_preimage (
1884+ & payment_hash_b, & payment_preimage_b, & node_cfgs[ 1 ] . tx_broadcaster ,
1885+ & LowerBoundedFeeEstimator :: new ( node_cfgs[ 1 ] . fee_estimator ) , & nodes[ 1 ] . logger
1886+ ) ;
1887+
1888+ // Bob force closes by broadcasting his revoked state.
1889+ nodes[ 1 ] . node . force_close_broadcasting_latest_txn ( & chan_id, & nodes[ 0 ] . node . get_our_node_id ( ) ) . unwrap ( ) ;
1890+ {
1891+ let mut txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
1892+ assert_eq ! ( txn. len( ) , 1 ) ;
1893+ let revoked_commitment = txn. pop ( ) . unwrap ( ) ;
1894+ assert_eq ! ( revoked_commitment. output. len( ) , 6 ) ; // 2 HTLC outputs + 1 to_self output + 1 to_remote output + 2 anchor outputs
1895+ }
1896+
1897+ // Bob should now receive an event to bump his revoked commitment transaction's fee.
1898+ assert ! ( nodes[ 0 ] . chain_monitor. chain_monitor. get_and_clear_pending_events( ) . is_empty( ) ) ;
1899+ let events = nodes[ 1 ] . chain_monitor . chain_monitor . get_and_clear_pending_events ( ) ;
1900+ assert_eq ! ( events. len( ) , 1 ) ;
1901+ let ( revoked_commitment, anchor_tx) = match & events[ 0 ] {
1902+ Event :: BumpTransaction ( BumpTransactionEvent :: ChannelClose { commitment_tx, anchor_descriptor, .. } ) => {
1903+ let secret_key = SecretKey :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ;
1904+ let public_key = PublicKey :: new ( secret_key. public_key ( & secp) ) ;
1905+ let fee_utxo_script = Script :: new_v0_p2wpkh ( & public_key. wpubkey_hash ( ) . unwrap ( ) ) ;
1906+ let coinbase_tx = Transaction {
1907+ version : 2 ,
1908+ lock_time : PackedLockTime :: ZERO ,
1909+ input : vec ! [ TxIn { ..Default :: default ( ) } ] ,
1910+ output : vec ! [ TxOut { // UTXO to attach fees to `anchor_tx`
1911+ value: Amount :: ONE_BTC . to_sat( ) ,
1912+ script_pubkey: fee_utxo_script. clone( ) ,
1913+ } ] ,
1914+ } ;
1915+ let mut anchor_tx = Transaction {
1916+ version : 2 ,
1917+ lock_time : PackedLockTime :: ZERO ,
1918+ input : vec ! [
1919+ TxIn { // Anchor input
1920+ previous_output: anchor_descriptor. outpoint,
1921+ ..Default :: default ( )
1922+ } ,
1923+ TxIn { // Fee input
1924+ previous_output: bitcoin:: OutPoint { txid: coinbase_tx. txid( ) , vout: 0 } ,
1925+ ..Default :: default ( )
1926+ } ,
1927+ ] ,
1928+ output : vec ! [ TxOut { // Fee input change
1929+ value: coinbase_tx. output[ 0 ] . value / 2 ,
1930+ script_pubkey: Script :: new_op_return( & [ ] ) ,
1931+ } ] ,
1932+ } ;
1933+ let signer = nodes[ 1 ] . keys_manager . derive_channel_keys (
1934+ anchor_descriptor. channel_value_satoshis , & anchor_descriptor. channel_keys_id ,
1935+ ) ;
1936+ let funding_sig = signer. sign_holder_anchor_input ( & mut anchor_tx, 0 , & secp) . unwrap ( ) ;
1937+ anchor_tx. input [ 0 ] . witness = chan_utils:: build_anchor_input_witness (
1938+ & signer. pubkeys ( ) . funding_pubkey , & funding_sig
1939+ ) ;
1940+ anchor_tx. input [ 0 ] . witness = chan_utils:: build_anchor_input_witness (
1941+ & signer. pubkeys ( ) . funding_pubkey , & funding_sig
1942+ ) ;
1943+ let fee_utxo_sig = {
1944+ let witness_script = Script :: new_p2pkh ( & public_key. pubkey_hash ( ) ) ;
1945+ let sighash = hash_to_message ! ( & SighashCache :: new( & anchor_tx) . segwit_signature_hash(
1946+ 1 , & witness_script, coinbase_tx. output[ 0 ] . value, EcdsaSighashType :: All
1947+ ) . unwrap( ) [ ..] ) ;
1948+ let sig = sign ( & secp, & sighash, & secret_key) ;
1949+ let mut sig = sig. serialize_der ( ) . to_vec ( ) ;
1950+ sig. push ( EcdsaSighashType :: All as u8 ) ;
1951+ sig
1952+ } ;
1953+ anchor_tx. input [ 1 ] . witness = Witness :: from_vec ( vec ! [ fee_utxo_sig, public_key. to_bytes( ) ] ) ;
1954+ check_spends ! ( anchor_tx, commitment_tx, coinbase_tx) ;
1955+ ( commitment_tx, anchor_tx)
1956+ } ,
1957+ _ => panic ! ( "Unexpected event" ) ,
1958+ } ;
1959+
1960+ for node in & nodes {
1961+ mine_transactions ( node, & [ & revoked_commitment, & anchor_tx] ) ;
1962+ check_added_monitors ! ( node, 1 ) ;
1963+ check_closed_broadcast ! ( node, true ) ;
1964+ }
1965+ check_closed_event ! ( & nodes[ 0 ] , 1 , ClosureReason :: CommitmentTxConfirmed ) ;
1966+ check_closed_event ! ( & nodes[ 1 ] , 1 , ClosureReason :: HolderForceClosed ) ;
1967+
1968+ // Alice should detect the confirmed revoked commitment, and attempts to claim all of the
1969+ // revoked outputs.
1970+ {
1971+ let mut txn = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
1972+ assert_eq ! ( txn. len( ) , 1 ) ;
1973+ let tx = txn. pop ( ) . unwrap ( ) ;
1974+ // TODO: to_self claim must be separate from HTLC claims
1975+ assert_eq ! ( tx. input. len( ) , 3 ) ; // Spends both HTLC outputs and to_self output
1976+ assert_eq ! ( tx. output. len( ) , 1 ) ;
1977+ check_spends ! ( tx, revoked_commitment) ;
1978+ }
1979+
1980+ // Since Bob was able to confirm his revoked commitment, he'll now try to claim the HTLCs
1981+ // through the success path.
1982+ assert ! ( nodes[ 0 ] . chain_monitor. chain_monitor. get_and_clear_pending_events( ) . is_empty( ) ) ;
1983+ let mut events = nodes[ 1 ] . chain_monitor . chain_monitor . get_and_clear_pending_events ( ) ;
1984+ // Certain block `ConnectStyle`s cause an extra `ChannelClose` event to be emitted since the
1985+ // best block is updated before the confirmed transactions are notified.
1986+ match * nodes[ 1 ] . connect_style . borrow ( ) {
1987+ ConnectStyle :: BestBlockFirst |ConnectStyle :: BestBlockFirstReorgsOnlyTip |ConnectStyle :: BestBlockFirstSkippingBlocks => {
1988+ assert_eq ! ( events. len( ) , 2 ) ;
1989+ if let Event :: BumpTransaction ( BumpTransactionEvent :: ChannelClose { .. } ) = events. remove ( 0 ) { }
1990+ else { panic ! ( "unexpected event" ) ; }
1991+
1992+ } ,
1993+ _ => assert_eq ! ( events. len( ) , 1 ) ,
1994+ } ;
1995+ let htlc_tx = {
1996+ let secret_key = SecretKey :: from_slice ( & [ 1 ; 32 ] ) . unwrap ( ) ;
1997+ let public_key = PublicKey :: new ( secret_key. public_key ( & secp) ) ;
1998+ let fee_utxo_script = Script :: new_v0_p2wpkh ( & public_key. wpubkey_hash ( ) . unwrap ( ) ) ;
1999+ let coinbase_tx = Transaction {
2000+ version : 2 ,
2001+ lock_time : PackedLockTime :: ZERO ,
2002+ input : vec ! [ TxIn { ..Default :: default ( ) } ] ,
2003+ output : vec ! [ TxOut { // UTXO to attach fees to `htlc_tx`
2004+ value: Amount :: ONE_BTC . to_sat( ) ,
2005+ script_pubkey: fee_utxo_script. clone( ) ,
2006+ } ] ,
2007+ } ;
2008+ let mut htlc_tx = Transaction {
2009+ version : 2 ,
2010+ lock_time : PackedLockTime :: ZERO ,
2011+ input : vec ! [ TxIn { // Fee input
2012+ previous_output: bitcoin:: OutPoint { txid: coinbase_tx. txid( ) , vout: 0 } ,
2013+ ..Default :: default ( )
2014+ } ] ,
2015+ output : vec ! [ TxOut { // Fee input change
2016+ value: coinbase_tx. output[ 0 ] . value / 2 ,
2017+ script_pubkey: Script :: new_op_return( & [ ] ) ,
2018+ } ] ,
2019+ } ;
2020+ if let Event :: BumpTransaction ( BumpTransactionEvent :: HTLCResolution { htlc_descriptors, .. } ) = & events[ 0 ] {
2021+ assert_eq ! ( htlc_descriptors. len( ) , 2 ) ;
2022+ for htlc_descriptor in htlc_descriptors {
2023+ assert ! ( !htlc_descriptor. htlc. offered) ;
2024+ let signer = nodes[ 1 ] . keys_manager . derive_channel_keys (
2025+ htlc_descriptor. channel_value_satoshis , & htlc_descriptor. channel_keys_id
2026+ ) ;
2027+ let per_commitment_point = signer. get_per_commitment_point ( htlc_descriptor. per_commitment_number , & secp) ;
2028+ htlc_tx. input . push ( htlc_descriptor. unsigned_tx_input ( ) ) ;
2029+ htlc_tx. output . push ( htlc_descriptor. tx_output ( & per_commitment_point, & secp) ) ;
2030+ }
2031+ for ( idx, htlc_descriptor) in htlc_descriptors. iter ( ) . enumerate ( ) {
2032+ let htlc_input_idx = idx + 1 ;
2033+ let signer = nodes[ 1 ] . keys_manager . derive_channel_keys (
2034+ htlc_descriptor. channel_value_satoshis , & htlc_descriptor. channel_keys_id
2035+ ) ;
2036+ let our_sig = signer. sign_holder_htlc_transaction ( & htlc_tx, htlc_input_idx, htlc_descriptor, & secp) . unwrap ( ) ;
2037+ let per_commitment_point = signer. get_per_commitment_point ( htlc_descriptor. per_commitment_number , & secp) ;
2038+ let witness_script = htlc_descriptor. witness_script ( & per_commitment_point, & secp) ;
2039+ htlc_tx. input [ htlc_input_idx] . witness = htlc_descriptor. tx_input_witness ( & our_sig, & witness_script) ;
2040+ }
2041+ } else {
2042+ panic ! ( "Unexpected event" ) ;
2043+ }
2044+ let fee_utxo_sig = {
2045+ let witness_script = Script :: new_p2pkh ( & public_key. pubkey_hash ( ) ) ;
2046+ let sighash = hash_to_message ! ( & SighashCache :: new( & htlc_tx) . segwit_signature_hash(
2047+ 0 , & witness_script, coinbase_tx. output[ 0 ] . value, EcdsaSighashType :: All
2048+ ) . unwrap( ) [ ..] ) ;
2049+ let sig = sign ( & secp, & sighash, & secret_key) ;
2050+ let mut sig = sig. serialize_der ( ) . to_vec ( ) ;
2051+ sig. push ( EcdsaSighashType :: All as u8 ) ;
2052+ sig
2053+ } ;
2054+ htlc_tx. input [ 0 ] . witness = Witness :: from_vec ( vec ! [ fee_utxo_sig, public_key. to_bytes( ) ] ) ;
2055+ check_spends ! ( htlc_tx, coinbase_tx, revoked_commitment) ;
2056+ htlc_tx
2057+ } ;
2058+
2059+ for node in & nodes {
2060+ mine_transaction ( node, & htlc_tx) ;
2061+ }
2062+
2063+ // Alice should see that Bob is trying to claim to HTLCs, so she should now try to claim them at
2064+ // the second level instead.
2065+ let ( revoked_to_self_claim, revoked_htlc_claim) = {
2066+ let mut txn = nodes[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . split_off ( 0 ) ;
2067+ assert_eq ! ( txn. len( ) , 2 ) ;
2068+
2069+ let revoked_to_self_claim = txn. pop ( ) . unwrap ( ) ;
2070+ assert_eq ! ( revoked_to_self_claim. input. len( ) , 1 ) ;
2071+ assert_eq ! ( revoked_to_self_claim. output. len( ) , 1 ) ;
2072+ check_spends ! ( revoked_to_self_claim, revoked_commitment) ;
2073+
2074+ let revoked_htlc_claim = txn. pop ( ) . unwrap ( ) ;
2075+ assert_eq ! ( revoked_htlc_claim. input. len( ) , 2 ) ;
2076+ assert_eq ! ( revoked_htlc_claim. output. len( ) , 1 ) ;
2077+ check_spends ! ( revoked_htlc_claim, htlc_tx) ;
2078+
2079+ ( revoked_to_self_claim, revoked_htlc_claim)
2080+ } ;
2081+ for node in & nodes {
2082+ mine_transactions ( node, & [ & revoked_to_self_claim, & revoked_htlc_claim] ) ;
2083+ }
2084+
2085+
2086+ // Connect one block to make sure the HTLC events are not yielded while ANTI_REORG_DELAY has not
2087+ // been reached.
2088+ connect_blocks ( & nodes[ 0 ] , 1 ) ;
2089+ connect_blocks ( & nodes[ 1 ] , 1 ) ;
2090+
2091+ assert ! ( nodes[ 0 ] . chain_monitor. chain_monitor. get_and_clear_pending_events( ) . is_empty( ) ) ;
2092+ assert ! ( nodes[ 1 ] . chain_monitor. chain_monitor. get_and_clear_pending_events( ) . is_empty( ) ) ;
2093+
2094+ // Connect the remaining blocks to reach ANTI_REORG_DELAY.
2095+ connect_blocks ( & nodes[ 0 ] , ANTI_REORG_DELAY - 2 ) ;
2096+ connect_blocks ( & nodes[ 1 ] , ANTI_REORG_DELAY - 2 ) ;
2097+
2098+ assert ! ( nodes[ 1 ] . chain_monitor. chain_monitor. get_and_clear_pending_events( ) . is_empty( ) ) ;
2099+ let spendable_output_events = nodes[ 0 ] . chain_monitor . chain_monitor . get_and_clear_pending_events ( ) ;
2100+ for ( idx, event) in spendable_output_events. iter ( ) . enumerate ( ) {
2101+ if let Event :: SpendableOutputs { outputs } = event {
2102+ assert_eq ! ( outputs. len( ) , 1 ) ;
2103+ let spend_tx = nodes[ 0 ] . keys_manager . backing . spend_spendable_outputs (
2104+ & [ & outputs[ 0 ] ] , Vec :: new ( ) , Script :: new_op_return ( & [ ] ) , 253 , & Secp256k1 :: new ( ) ,
2105+ ) . unwrap ( ) ;
2106+ check_spends ! ( spend_tx, if idx == 0 { & revoked_to_self_claim } else { & revoked_htlc_claim } ) ;
2107+ } else {
2108+ panic ! ( "unexpected event" ) ;
2109+ }
2110+ }
2111+
2112+ assert ! ( nodes[ 0 ] . node. list_channels( ) . is_empty( ) ) ;
2113+ assert ! ( nodes[ 1 ] . node. list_channels( ) . is_empty( ) ) ;
2114+ assert ! ( nodes[ 0 ] . chain_monitor. chain_monitor. get_claimable_balances( & [ ] ) . is_empty( ) ) ;
2115+ // TODO: From Bob's PoV, he still thinks he can claim the outputs from his revoked commitment.
2116+ // This needs to be fixed before we enable pruning `ChannelMonitor`s once they don't have any
2117+ // balances to claim.
2118+ assert_eq ! ( nodes[ 1 ] . chain_monitor. chain_monitor. get_claimable_balances( & [ ] ) . len( ) , 3 ) ;
2119+ }
0 commit comments