@@ -8736,3 +8736,115 @@ fn test_update_err_monitor_lockdown() {
8736
8736
let events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
8737
8737
assert_eq ! ( events. len( ) , 1 ) ;
8738
8738
}
8739
+
8740
+ #[ test]
8741
+ fn test_concurrent_monitor_claim ( ) {
8742
+ // Watchtower A receives block, broadcasts state N, then channel receives new state N+1,
8743
+ // sending it to both watchtowers, Bob accepts N+1, then receives block and broadcasts
8744
+ // the latest state N+1, Alice rejects state N+1, but Bob has already broadcast it,
8745
+ // state N+1 confirms. Alice claims output from state N+1.
8746
+
8747
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
8748
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
8749
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
8750
+ let mut nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
8751
+
8752
+ // Create some initial channel
8753
+ let chan_1 = create_announced_chan_between_nodes ( & nodes, 0 , 1 , InitFeatures :: known ( ) , InitFeatures :: known ( ) ) ;
8754
+ let outpoint = OutPoint { txid : chan_1. 3 . txid ( ) , index : 0 } ;
8755
+
8756
+ // Rebalance the network to generate htlc in the two directions
8757
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 10_000_000 , 10_000_000 ) ;
8758
+
8759
+ // Route a HTLC from node 0 to node 1 (but don't settle)
8760
+ route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 9_000_000 ) . 0 ;
8761
+
8762
+ // Copy SimpleManyChannelMonitor to simulate watchtower Alice and update block height her ChannelMonitor timeout HTLC onchain
8763
+ let logger = test_utils:: TestLogger :: with_id ( format ! ( "node {}" , "Alice" ) ) ;
8764
+ let chain_monitor = chaininterface:: ChainWatchInterfaceUtil :: new ( Network :: Testnet ) ;
8765
+ let watchtower_alice = {
8766
+ let monitors = nodes[ 0 ] . chan_monitor . simple_monitor . monitors . lock ( ) . unwrap ( ) ;
8767
+ let monitor = monitors. get ( & outpoint) . unwrap ( ) ;
8768
+ let mut w = test_utils:: TestVecWriter ( Vec :: new ( ) ) ;
8769
+ monitor. write_for_disk ( & mut w) . unwrap ( ) ;
8770
+ let new_monitor = <( BlockHash , channelmonitor:: ChannelMonitor < EnforcingChannelKeys > ) >:: read (
8771
+ & mut :: std:: io:: Cursor :: new ( & w. 0 ) ) . unwrap ( ) . 1 ;
8772
+ assert ! ( new_monitor == * monitor) ;
8773
+ let watchtower = test_utils:: TestChannelMonitor :: new ( & chain_monitor, & chanmon_cfgs[ 0 ] . tx_broadcaster , & logger, & chanmon_cfgs[ 0 ] . fee_estimator ) ;
8774
+ assert ! ( watchtower. add_monitor( outpoint, new_monitor) . is_ok( ) ) ;
8775
+ watchtower
8776
+ } ;
8777
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
8778
+ watchtower_alice. simple_monitor . block_connected ( & header, 135 , & vec ! [ ] , & vec ! [ ] ) ;
8779
+
8780
+ // Watchtower Alice should have broadcast a commitment/HTLC-timeout
8781
+ {
8782
+ let mut txn = chanmon_cfgs[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
8783
+ assert_eq ! ( txn. len( ) , 2 ) ;
8784
+ txn. clear ( ) ;
8785
+ }
8786
+
8787
+ // Copy SimpleManyChannelMonitor to simulate watchtower Bob and make it receive a commitment update first.
8788
+ let logger = test_utils:: TestLogger :: with_id ( format ! ( "node {}" , "Bob" ) ) ;
8789
+ let chain_monitor = chaininterface:: ChainWatchInterfaceUtil :: new ( Network :: Testnet ) ;
8790
+ let watchtower_bob = {
8791
+ let monitors = nodes[ 0 ] . chan_monitor . simple_monitor . monitors . lock ( ) . unwrap ( ) ;
8792
+ let monitor = monitors. get ( & outpoint) . unwrap ( ) ;
8793
+ let mut w = test_utils:: TestVecWriter ( Vec :: new ( ) ) ;
8794
+ monitor. write_for_disk ( & mut w) . unwrap ( ) ;
8795
+ let new_monitor = <( BlockHash , channelmonitor:: ChannelMonitor < EnforcingChannelKeys > ) >:: read (
8796
+ & mut :: std:: io:: Cursor :: new ( & w. 0 ) ) . unwrap ( ) . 1 ;
8797
+ assert ! ( new_monitor == * monitor) ;
8798
+ let watchtower = test_utils:: TestChannelMonitor :: new ( & chain_monitor, & chanmon_cfgs[ 0 ] . tx_broadcaster , & logger, & chanmon_cfgs[ 0 ] . fee_estimator ) ;
8799
+ assert ! ( watchtower. add_monitor( outpoint, new_monitor) . is_ok( ) ) ;
8800
+ watchtower
8801
+ } ;
8802
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
8803
+ watchtower_bob. simple_monitor . block_connected ( & header, 134 , & vec ! [ ] , & vec ! [ ] ) ;
8804
+
8805
+ // Route another payment to generate another update with still previous HTLC pending
8806
+ let ( _, payment_hash) = get_payment_preimage_hash ! ( nodes[ 0 ] ) ;
8807
+ {
8808
+ let net_graph_msg_handler = & nodes[ 1 ] . net_graph_msg_handler ;
8809
+ let route = get_route ( & nodes[ 1 ] . node . get_our_node_id ( ) , & net_graph_msg_handler. network_graph . read ( ) . unwrap ( ) , & nodes[ 0 ] . node . get_our_node_id ( ) , None , & Vec :: new ( ) , 3000000 , TEST_FINAL_CLTV , & logger) . unwrap ( ) ;
8810
+ nodes[ 1 ] . node . send_payment ( & route, payment_hash, & None ) . unwrap ( ) ;
8811
+ }
8812
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
8813
+
8814
+ let updates = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
8815
+ assert_eq ! ( updates. update_add_htlcs. len( ) , 1 ) ;
8816
+ nodes[ 0 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & updates. update_add_htlcs [ 0 ] ) ;
8817
+ if let Some ( ref mut channel) = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get_mut ( & chan_1. 2 ) {
8818
+ if let Ok ( ( _, _, _, update) ) = channel. commitment_signed ( & updates. commitment_signed , & node_cfgs[ 0 ] . fee_estimator , & node_cfgs[ 0 ] . logger ) {
8819
+ // Watchtower Alice should already have seen the block and reject the update
8820
+ if let Err ( _) = watchtower_alice. simple_monitor . update_monitor ( outpoint, update. clone ( ) ) { } else { assert ! ( false ) ; }
8821
+ if let Ok ( _) = watchtower_bob. simple_monitor . update_monitor ( outpoint, update. clone ( ) ) { } else { assert ! ( false ) ; }
8822
+ if let Ok ( _) = nodes[ 0 ] . chan_monitor . update_monitor ( outpoint, update) { } else { assert ! ( false ) ; }
8823
+ } else { assert ! ( false ) ; }
8824
+ } else { assert ! ( false ) ; } ;
8825
+ // Our local monitor is in-sync and hasn't processed yet timeout
8826
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
8827
+
8828
+ //// Provide one more block to watchtower Bob, expect broadcast of commitment and HTLC-Timeout
8829
+ watchtower_bob. simple_monitor . block_connected ( & header, 135 , & vec ! [ ] , & vec ! [ ] ) ;
8830
+
8831
+ // Watchtower Bob should have broadcast a commitment/HTLC-timeout
8832
+ let bob_state_y;
8833
+ {
8834
+ let mut txn = chanmon_cfgs[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
8835
+ assert_eq ! ( txn. len( ) , 2 ) ;
8836
+ bob_state_y = txn[ 0 ] . clone ( ) ;
8837
+ txn. clear ( ) ;
8838
+ } ;
8839
+
8840
+ // We confirm Bob's state Y on Alice, she should broadcast a HTLC-timeout
8841
+ watchtower_alice. simple_monitor . block_connected ( & header, 136 , & vec ! [ & bob_state_y] [ ..] , & vec ! [ ] ) ;
8842
+ {
8843
+ let htlc_txn = chanmon_cfgs[ 0 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
8844
+ // We broadcast twice the transaction, once due to the HTLC-timeout, once due
8845
+ // the onchain detection of the HTLC output
8846
+ assert_eq ! ( htlc_txn. len( ) , 2 ) ;
8847
+ check_spends ! ( htlc_txn[ 0 ] , bob_state_y) ;
8848
+ check_spends ! ( htlc_txn[ 1 ] , bob_state_y) ;
8849
+ }
8850
+ }
0 commit comments