@@ -3441,6 +3441,71 @@ mod tests {
3441
3441
assert_eq ! ( nodes[ 1 ] . node. list_channels( ) . len( ) , 0 ) ;
3442
3442
}
3443
3443
3444
+ #[ test]
3445
+ fn claim_htlc_outputs_shared_tx ( ) {
3446
+ // Node revoked old state, htlcs haven't time out yet, claim them in shared justice tx
3447
+
3448
+ let nodes = create_network ( 2 ) ;
3449
+
3450
+ // Create some new channel:
3451
+ let chan_1 = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
3452
+
3453
+ // Rebalance the network to generate htlc in the two directions
3454
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 8000000 ) ;
3455
+ // node[0] is gonna to revoke an old state thus node[1] should be able to claim both offered/received HTLC outputs on top of commitment tx
3456
+ let payment_preimage_1 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 3000000 ) . 0 ;
3457
+ let _payment_preimage_2 = route_payment ( & nodes[ 1 ] , & vec ! ( & nodes[ 0 ] ) [ ..] , 3000000 ) . 0 ;
3458
+
3459
+ // Get the will-be-revoked local txn from node[0]
3460
+ let revoked_local_txn = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_1. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
3461
+
3462
+ //Revoke the old state
3463
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_1) ;
3464
+
3465
+ {
3466
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
3467
+
3468
+ nodes[ 0 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 1 ) ;
3469
+
3470
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 1 ) ;
3471
+ let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
3472
+ assert_eq ! ( node_txn. len( ) , 4 ) ;
3473
+
3474
+ let mut revoked_tx_map = HashMap :: new ( ) ;
3475
+ revoked_tx_map. insert ( revoked_local_txn[ 0 ] . txid ( ) , revoked_local_txn[ 0 ] . clone ( ) ) ;
3476
+
3477
+ assert_eq ! ( node_txn[ 0 ] . input. len( ) , 2 ) ;
3478
+ node_txn[ 0 ] . verify ( & revoked_tx_map) . unwrap ( ) ;
3479
+
3480
+ assert_eq ! ( node_txn[ 3 ] . input. len( ) , 2 ) ;
3481
+ node_txn[ 3 ] . verify ( & revoked_tx_map) . unwrap ( ) ;
3482
+
3483
+ assert_eq ! ( node_txn[ 0 ] . txid( ) , node_txn[ 3 ] . txid( ) ) ; // justice tx is duplicated due to block re-scanning
3484
+
3485
+ let witness_script_1 = node_txn[ 0 ] . clone ( ) . input [ 0 ] . witness . pop ( ) . unwrap ( ) ;
3486
+ let witness_script_2 = node_txn[ 0 ] . clone ( ) . input [ 1 ] . witness . pop ( ) . unwrap ( ) ;
3487
+ if witness_script_1. len ( ) > 133 {
3488
+ assert_eq ! ( witness_script_1. len( ) , 138 ) ;
3489
+ assert_eq ! ( witness_script_2. len( ) , 133 ) ;
3490
+ } else {
3491
+ assert_eq ! ( witness_script_1. len( ) , 133 ) ;
3492
+ assert_eq ! ( witness_script_2. len( ) , 138 ) ;
3493
+ }
3494
+
3495
+ assert_eq ! ( node_txn[ 1 ] . input. len( ) , 1 ) ;
3496
+ let witness_script = node_txn[ 1 ] . clone ( ) . input [ 0 ] . witness . pop ( ) . unwrap ( ) ;
3497
+ assert_eq ! ( witness_script. len( ) , 71 ) ; // Spending funding tx unique txoutput, tx broadcasted by ChannelManager
3498
+
3499
+ assert_eq ! ( node_txn[ 2 ] . input. len( ) , 1 ) ;
3500
+ let witness_script = node_txn[ 2 ] . clone ( ) . input [ 0 ] . witness . pop ( ) . unwrap ( ) ;
3501
+ assert_eq ! ( witness_script. len( ) , 133 ) ; //Spending a offered htlc output
3502
+
3503
+ }
3504
+ get_announce_close_broadcast_events ( & nodes, 0 , 1 ) ;
3505
+ assert_eq ! ( nodes[ 0 ] . node. list_channels( ) . len( ) , 0 ) ;
3506
+ assert_eq ! ( nodes[ 1 ] . node. list_channels( ) . len( ) , 0 ) ;
3507
+ }
3508
+
3444
3509
#[ test]
3445
3510
fn test_htlc_ignore_latest_remote_commitment ( ) {
3446
3511
// Test that HTLC transactions spending the latest remote commitment transaction are simply
0 commit comments