@@ -6157,7 +6157,7 @@ mod tests {
6157
6157
_ => panic ! ( "Unexpected event" ) ,
6158
6158
} ;
6159
6159
{
6160
- let mut node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ; ; // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 (timeout tx) * 2 (block-rescan)
6160
+ let mut node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ; // ChannelManager : 2 (commitment tx, HTLC-Timeout tx), ChannelMonitor : 1 (timeout tx) * 2 (block-rescan)
6161
6161
assert_eq ! ( node_txn. len( ) , 4 ) ;
6162
6162
assert_eq ! ( node_txn[ 0 ] , node_txn[ 3 ] ) ;
6163
6163
check_spends ! ( node_txn[ 0 ] , commitment_tx[ 0 ] . clone( ) ) ;
@@ -6168,7 +6168,7 @@ mod tests {
6168
6168
check_spends ! ( node_txn[ 2 ] , node_txn[ 1 ] . clone( ) ) ;
6169
6169
assert_eq ! ( node_txn[ 1 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , 71 ) ;
6170
6170
assert_eq ! ( node_txn[ 2 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
6171
- node_txn. clear ( )
6171
+ node_txn. clear ( ) ;
6172
6172
}
6173
6173
6174
6174
// Broadcast legit commitment tx from A on B's chain
@@ -8371,6 +8371,104 @@ mod tests {
8371
8371
check_spends ! ( spend_txn[ 4 ] , node_txn[ 3 ] . clone( ) ) ; // spending justice tx output on htlc success tx
8372
8372
}
8373
8373
8374
+ #[ test]
8375
+ fn test_onchain_to_onchain_claim ( ) {
8376
+ // Test that in case of channel closure, we detect the state of output thanks to
8377
+ // ChainWatchInterface and claim HTLC on downstream peer's remote commitment tx.
8378
+
8379
+ let nodes = create_network ( 3 ) ;
8380
+
8381
+ // Create some initial channels
8382
+ let chan_1 = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
8383
+ let chan_2 = create_announced_chan_between_nodes ( & nodes, 1 , 2 ) ;
8384
+
8385
+ // Rebalance the network a bit by relaying one payment through all the channels ...
8386
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
8387
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
8388
+
8389
+ let ( payment_preimage, _payment_hash) = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) , 3000000 ) ;
8390
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
8391
+ let commitment_tx = nodes[ 2 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_2. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
8392
+ check_spends ! ( commitment_tx[ 0 ] , chan_2. 3 . clone( ) ) ;
8393
+ nodes[ 2 ] . node . claim_funds ( payment_preimage) ;
8394
+ {
8395
+ let mut added_monitors = nodes[ 2 ] . chan_monitor . added_monitors . lock ( ) . unwrap ( ) ;
8396
+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
8397
+ added_monitors. clear ( ) ;
8398
+ }
8399
+ let events = nodes[ 2 ] . node . get_and_clear_pending_msg_events ( ) ;
8400
+ assert_eq ! ( events. len( ) , 1 ) ;
8401
+ match events[ 0 ] {
8402
+ MessageSendEvent :: UpdateHTLCs { ref node_id, updates : msgs:: CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, .. } } => {
8403
+ assert ! ( update_add_htlcs. is_empty( ) ) ;
8404
+ assert ! ( update_fail_htlcs. is_empty( ) ) ;
8405
+ assert ! ( !update_fulfill_htlcs. is_empty( ) ) ;
8406
+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
8407
+ assert_eq ! ( nodes[ 1 ] . node. get_our_node_id( ) , * node_id) ;
8408
+ } ,
8409
+ _ => panic ! ( "Unexpected event" ) ,
8410
+ } ;
8411
+ nodes[ 2 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ commitment_tx[ 0 ] . clone( ) ] } , 1 ) ;
8412
+ let events = nodes[ 2 ] . node . get_and_clear_pending_msg_events ( ) ;
8413
+ assert_eq ! ( events. len( ) , 1 ) ;
8414
+ match events[ 0 ] {
8415
+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
8416
+ _ => panic ! ( "Unexpected event" ) ,
8417
+ }
8418
+
8419
+ let c_txn = nodes[ 2 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clone ( ) ; // ChannelManager : 2 (commitment tx, HTLC-Success tx), ChannelMonitor : 1 (HTLC-Success tx)
8420
+ assert_eq ! ( c_txn. len( ) , 3 ) ;
8421
+ check_spends ! ( c_txn[ 0 ] , commitment_tx[ 0 ] . clone( ) ) ;
8422
+ assert_eq ! ( c_txn[ 0 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
8423
+ check_spends ! ( c_txn[ 1 ] , chan_2. 3 . clone( ) ) ;
8424
+ check_spends ! ( c_txn[ 2 ] , c_txn[ 1 ] . clone( ) ) ;
8425
+ assert_eq ! ( c_txn[ 1 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , 71 ) ;
8426
+ assert_eq ! ( c_txn[ 2 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
8427
+
8428
+ // So we broadcast C's commitment tx and HTLC-Success on B's chain, we should successfully be able to extract preimage and update downstream monitor
8429
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ c_txn[ 1 ] . clone( ) , c_txn[ 2 ] . clone( ) ] } , 1 ) ;
8430
+ {
8431
+ let mut b_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
8432
+ assert_eq ! ( b_txn. len( ) , 4 ) ;
8433
+ assert_eq ! ( b_txn[ 0 ] , b_txn[ 3 ] ) ;
8434
+ check_spends ! ( b_txn[ 1 ] , chan_2. 3 ) ; // B local commitment tx, issued by ChannelManager
8435
+ check_spends ! ( b_txn[ 2 ] , b_txn[ 1 ] . clone( ) ) ; // HTLC-Timeout on B local commitment tx, issued by ChannelManager
8436
+ assert_eq ! ( b_txn[ 2 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
8437
+ check_spends ! ( b_txn[ 0 ] , c_txn[ 1 ] . clone( ) ) ; // timeout tx on C remote commitment tx, issued by ChannelMonitor, * 2 due to block rescan
8438
+ assert_eq ! ( b_txn[ 0 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , ACCEPTED_HTLC_SCRIPT_WEIGHT ) ;
8439
+ b_txn. clear ( ) ;
8440
+ }
8441
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
8442
+ let msg_events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
8443
+ match msg_events[ 0 ] {
8444
+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
8445
+ _ => panic ! ( "Unexpected event" ) ,
8446
+ }
8447
+ match msg_events[ 1 ] {
8448
+ MessageSendEvent :: UpdateHTLCs { ref node_id, updates : msgs:: CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, .. } } => {
8449
+ assert ! ( update_add_htlcs. is_empty( ) ) ;
8450
+ assert ! ( update_fail_htlcs. is_empty( ) ) ;
8451
+ assert ! ( !update_fulfill_htlcs. is_empty( ) ) ;
8452
+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
8453
+ assert_eq ! ( nodes[ 0 ] . node. get_our_node_id( ) , * node_id) ;
8454
+ } ,
8455
+ _ => panic ! ( "Unexpected event" ) ,
8456
+ } ;
8457
+ // Broadcast A's commitment tx on B's chain to see if we are able to claim inbound HTLC with our HTLC-Success tx
8458
+ let commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_1. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
8459
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ commitment_tx[ 0 ] . clone( ) ] } , 1 ) ;
8460
+ let b_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
8461
+ check_spends ! ( b_txn[ 1 ] , chan_1. 3 ) ; // Local commitment tx, issued by ChannelManager
8462
+ assert_eq ! ( b_txn[ 0 ] , b_txn[ 2 ] ) ; // HTLC-Success tx, issued by ChannelMonitor, * 2 due to block rescan
8463
+ check_spends ! ( b_txn[ 0 ] , commitment_tx[ 0 ] . clone( ) ) ;
8464
+ assert_eq ! ( b_txn[ 0 ] . input[ 0 ] . witness. clone( ) . last( ) . unwrap( ) . len( ) , OFFERED_HTLC_SCRIPT_WEIGHT ) ;
8465
+ let msg_events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
8466
+ match msg_events[ 0 ] {
8467
+ MessageSendEvent :: BroadcastChannelUpdate { .. } => { } ,
8468
+ _ => panic ! ( "Unexpected event" ) ,
8469
+ }
8470
+ }
8471
+
8374
8472
#[ test]
8375
8473
fn test_dynamic_spendable_outputs_local_htlc_success_tx ( ) {
8376
8474
let nodes = create_network ( 2 ) ;
0 commit comments