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