@@ -3422,6 +3422,12 @@ mod tests {
3422
3422
let payment_preimage_3 = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 3000000 ) . 0 ;
3423
3423
// Get the will-be-revoked local txn from nodes[0]
3424
3424
let revoked_local_txn = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . iter ( ) . next ( ) . unwrap ( ) . 1 . last_local_commitment_txn . clone ( ) ;
3425
+ assert_eq ! ( revoked_local_txn. len( ) , 2 ) ; // First commitment tx, then HTLC tx
3426
+ assert_eq ! ( revoked_local_txn[ 0 ] . input. len( ) , 1 ) ;
3427
+ assert_eq ! ( revoked_local_txn[ 0 ] . input[ 0 ] . previous_output. txid, chan_5. 3 . txid( ) ) ;
3428
+ assert_eq ! ( revoked_local_txn[ 0 ] . output. len( ) , 2 ) ; // Only HTLC and output back to 0 are present
3429
+ assert_eq ! ( revoked_local_txn[ 1 ] . input. len( ) , 1 ) ;
3430
+ assert_eq ! ( revoked_local_txn[ 1 ] . input[ 0 ] . previous_output. txid, revoked_local_txn[ 0 ] . txid( ) ) ;
3425
3431
// Revoke the old state
3426
3432
claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , payment_preimage_3) ;
3427
3433
@@ -3432,7 +3438,7 @@ mod tests {
3432
3438
let mut node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
3433
3439
assert_eq ! ( node_txn. len( ) , 3 ) ;
3434
3440
assert_eq ! ( node_txn. pop( ) . unwrap( ) , node_txn[ 0 ] ) ; // An outpoint registration will result in a 2nd block_connected
3435
- assert_eq ! ( node_txn[ 0 ] . input. len( ) , 1 ) ;
3441
+ assert_eq ! ( node_txn[ 0 ] . input. len( ) , 2 ) ; // We should claim the revoked output and the HTLC output
3436
3442
3437
3443
let mut funding_tx_map = HashMap :: new ( ) ;
3438
3444
funding_tx_map. insert ( revoked_local_txn[ 0 ] . txid ( ) , revoked_local_txn[ 0 ] . clone ( ) ) ;
@@ -3453,6 +3459,40 @@ mod tests {
3453
3459
}
3454
3460
3455
3461
#[ test]
3462
+ fn revoked_output_claim ( ) {
3463
+ // Simple test to ensure a node will claim a revoked output when a stale remote commitment
3464
+ // transaction is broadcast by its counterparty
3465
+ let nodes = create_network ( 2 ) ;
3466
+ let chan_1 = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
3467
+ // node[0] is gonna to revoke an old state thus node[1] should be able to claim the revoked output
3468
+ let revoked_local_txn = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_1. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
3469
+ assert_eq ! ( revoked_local_txn. len( ) , 1 ) ;
3470
+ // Only output is the full channel value back to nodes[0]:
3471
+ assert_eq ! ( revoked_local_txn[ 0 ] . output. len( ) , 1 ) ;
3472
+ // Send a payment through, updating everyone's latest commitment txn
3473
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] ) [ ..] , 5000000 ) ;
3474
+
3475
+ // Inform nodes[1] that nodes[0] broadcast a stale tx
3476
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
3477
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 1 ) ;
3478
+ let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) ;
3479
+ assert_eq ! ( node_txn. len( ) , 3 ) ; // nodes[1] will broadcast justice tx twice, and its own local state once
3480
+
3481
+ assert_eq ! ( node_txn[ 0 ] , node_txn[ 2 ] ) ;
3482
+
3483
+ let mut revoked_tx_map = HashMap :: new ( ) ;
3484
+ revoked_tx_map. insert ( revoked_local_txn[ 0 ] . txid ( ) , revoked_local_txn[ 0 ] . clone ( ) ) ;
3485
+ node_txn[ 0 ] . verify ( & revoked_tx_map) . unwrap ( ) ;
3486
+
3487
+ revoked_tx_map. clear ( ) ;
3488
+ revoked_tx_map. insert ( chan_1. 3 . txid ( ) , chan_1. 3 . clone ( ) ) ;
3489
+ node_txn[ 1 ] . verify ( & revoked_tx_map) . unwrap ( ) ;
3490
+
3491
+ // Inform nodes[0] that a watchtower cheated on its behalf, so it will force-close the chan
3492
+ nodes[ 0 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 1 ) ;
3493
+ get_announce_close_broadcast_events ( & nodes, 0 , 1 ) ;
3494
+ }
3495
+
3456
3496
fn test_htlc_ignore_latest_remote_commitment ( ) {
3457
3497
// Test that HTLC transactions spending the latest remote commitment transaction are simply
3458
3498
// ignored if we cannot claim them. This originally tickled an invalid unwrap().
0 commit comments