@@ -19,20 +19,34 @@ use crate::chain::chaininterface::LowerBoundedFeeEstimator;
19
19
use crate :: ln:: channel;
20
20
#[ cfg( anchors) ]
21
21
use crate :: ln:: chan_utils;
22
+ #[ cfg( anchors) ]
23
+ use crate :: ln:: channelmanager:: ChannelManager ;
22
24
use crate :: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , PaymentId } ;
23
25
use crate :: ln:: msgs:: ChannelMessageHandler ;
24
26
#[ cfg( anchors) ]
25
27
use crate :: util:: config:: UserConfig ;
26
28
#[ cfg( anchors) ]
29
+ use crate :: util:: crypto:: sign;
30
+ #[ cfg( anchors) ]
27
31
use crate :: util:: events:: BumpTransactionEvent ;
28
32
use 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;
29
37
38
+ #[ cfg( anchors) ]
39
+ use bitcoin:: blockdata:: transaction:: EcdsaSighashType ;
30
40
use bitcoin:: blockdata:: script:: Builder ;
31
41
use bitcoin:: blockdata:: opcodes;
32
42
use bitcoin:: secp256k1:: Secp256k1 ;
33
43
#[ 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 } ;
35
47
use bitcoin:: Transaction ;
48
+ #[ cfg( anchors) ]
49
+ use bitcoin:: util:: sighash:: SighashCache ;
36
50
37
51
use crate :: prelude:: * ;
38
52
@@ -1749,7 +1763,7 @@ fn test_yield_anchors_events() {
1749
1763
1750
1764
let mut holder_events = nodes[ 0 ] . chain_monitor . chain_monitor . get_and_clear_pending_events ( ) ;
1751
1765
// 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 .
1753
1767
match * nodes[ 0 ] . connect_style . borrow ( ) {
1754
1768
ConnectStyle :: BestBlockFirst |ConnectStyle :: BestBlockFirstReorgsOnlyTip |ConnectStyle :: BestBlockFirstSkippingBlocks => {
1755
1769
assert_eq ! ( holder_events. len( ) , 3 ) ;
@@ -1816,3 +1830,290 @@ fn test_yield_anchors_events() {
1816
1830
// Clear the remaining events as they're not relevant to what we're testing.
1817
1831
nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
1818
1832
}
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