@@ -2517,7 +2517,6 @@ impl ChainListener for ChannelManager {
2517
2517
fn block_connected ( & self , header : & BlockHeader , height : u32 , txn_matched : & [ & Transaction ] , indexes_of_txn_matched : & [ u32 ] ) {
2518
2518
let _ = self . total_consistency_lock . read ( ) . unwrap ( ) ;
2519
2519
let mut failed_channels = Vec :: new ( ) ;
2520
- let mut hash_to_remove = Vec :: new ( ) ;
2521
2520
{
2522
2521
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
2523
2522
let channel_state = channel_lock. borrow_parts ( ) ;
@@ -2586,32 +2585,24 @@ impl ChainListener for ChannelManager {
2586
2585
true
2587
2586
} ) ;
2588
2587
2589
- for tx in txn_matched {
2590
- if let Some ( payments_data) = self . monitor . is_resolving_output ( & tx) {
2591
- for payment_data in payments_data {
2592
- hash_to_remove. push ( ( payment_data. 0 , payment_data. 1 ) ) ;
2593
- }
2594
- }
2595
- }
2596
2588
}
2597
2589
for failure in failed_channels. drain ( ..) {
2598
2590
self . finish_force_close_channel ( failure) ;
2599
2591
}
2600
2592
{
2601
2593
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
2602
- for ( payment_preimage, payment_hash) in hash_to_remove {
2603
- if let Some ( preimage) = payment_preimage {
2604
- if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2605
- if let Some ( mut entry) = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) {
2606
- for source in entry. drain ( ..) {
2607
- self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , preimage) ;
2608
- }
2609
- }
2610
- } else {
2611
- if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2612
- if let Some ( mut entry) = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) {
2613
- for source in entry. drain ( ..) {
2614
- self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , & payment_hash, HTLCFailReason :: Reason { failure_code : 0x1000 | 14 , data : Vec :: new ( ) } ) ;
2594
+ for tx in txn_matched {
2595
+ if let Some ( payments_data) = self . monitor . is_resolving_output ( & tx) {
2596
+ for payment_data in payments_data {
2597
+ if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2598
+ if let Some ( mut entry) = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_data. 1 ) {
2599
+ for source in entry. drain ( ..) {
2600
+ if let Some ( preimage) = payment_data. 0 {
2601
+ self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , preimage) ;
2602
+ } else {
2603
+ self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , & payment_data. 1 , HTLCFailReason :: Reason { failure_code : 0x1000 | 14 , data : Vec :: new ( ) } ) ;
2604
+ }
2605
+ }
2615
2606
}
2616
2607
}
2617
2608
}
@@ -6276,6 +6267,54 @@ mod tests {
6276
6267
assert_eq ! ( node_txn[ 2 ] . clone( ) . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , 133 ) ;
6277
6268
}
6278
6269
6270
+ #[ test]
6271
+ fn test_commitment_revoked_fail_backward ( ) {
6272
+ // Test that in case of a revoked commitment tx, we detect the resolution of output by justice tx
6273
+ // and fail backward accordingly.
6274
+
6275
+ let nodes = create_network ( 3 ) ;
6276
+
6277
+ // Create some initial channels
6278
+ create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
6279
+ let chan_2 = create_announced_chan_between_nodes ( & nodes, 1 , 2 ) ;
6280
+
6281
+ // Rebalance the network a bit by relaying one payment through all the channels...
6282
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
6283
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
6284
+
6285
+ let ( payment_preimage, _payment_hash) = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 3000000 ) ;
6286
+ // Get the will-be-revoked local txn from nodes[2]
6287
+ let revoked_local_txn = nodes[ 2 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_2. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
6288
+ // Revoke the old state
6289
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , payment_preimage) ;
6290
+
6291
+ route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 3000000 ) ;
6292
+
6293
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
6294
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 1 ) ;
6295
+ {
6296
+ let mut added_monitors = nodes[ 1 ] . chan_monitor . added_monitors . lock ( ) . unwrap ( ) ;
6297
+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
6298
+ added_monitors. clear ( ) ;
6299
+ }
6300
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
6301
+ assert_eq ! ( events. len( ) , 2 ) ;
6302
+ match events[ 0 ] {
6303
+ MessageSendEvent :: BroadcastChannelUpdate { msg : msgs:: ChannelUpdate { .. } } => { } ,
6304
+ _ => panic ! ( "Unexpected event" ) ,
6305
+ }
6306
+ match events[ 1 ] {
6307
+ MessageSendEvent :: UpdateHTLCs { ref node_id, updates : msgs:: CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, .. } } => {
6308
+ assert ! ( update_add_htlcs. is_empty( ) ) ;
6309
+ assert ! ( !update_fail_htlcs. is_empty( ) ) ;
6310
+ assert ! ( update_fulfill_htlcs. is_empty( ) ) ;
6311
+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
6312
+ assert_eq ! ( nodes[ 0 ] . node. get_our_node_id( ) , * node_id) ;
6313
+ } ,
6314
+ _ => panic ! ( "Unexpected event" ) ,
6315
+ }
6316
+ }
6317
+
6279
6318
#[ test]
6280
6319
fn test_htlc_ignore_latest_remote_commitment ( ) {
6281
6320
// Test that HTLC transactions spending the latest remote commitment transaction are simply
0 commit comments