@@ -2058,7 +2058,6 @@ impl ChainListener for ChannelManager {
2058
2058
fn block_connected ( & self , header : & BlockHeader , height : u32 , txn_matched : & [ & Transaction ] , indexes_of_txn_matched : & [ u32 ] ) {
2059
2059
let mut new_events = Vec :: new ( ) ;
2060
2060
let mut failed_channels = Vec :: new ( ) ;
2061
- let mut hash_to_remove = Vec :: new ( ) ;
2062
2061
{
2063
2062
let mut channel_lock = self . channel_state . lock ( ) . unwrap ( ) ;
2064
2063
let channel_state = channel_lock. borrow_parts ( ) ;
@@ -2122,33 +2121,25 @@ impl ChainListener for ChannelManager {
2122
2121
true
2123
2122
} ) ;
2124
2123
2125
- for tx in txn_matched {
2126
- if let Some ( payments_data) = self . monitor . is_resolving_output ( & tx) {
2127
- for payment_data in payments_data {
2128
- hash_to_remove. push ( ( payment_data. 0 , payment_data. 1 ) ) ;
2129
- }
2130
- }
2131
- }
2132
2124
}
2133
2125
for failure in failed_channels. drain ( ..) {
2134
2126
self . finish_force_close_channel ( failure) ;
2135
2127
}
2136
2128
2137
2129
{
2138
2130
let mut channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ;
2139
- for ( payment_preimage, payment_hash) in hash_to_remove {
2140
- if let Some ( preimage) = payment_preimage {
2141
- if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2142
- if let Some ( mut entry) = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) {
2143
- for source in entry. drain ( ..) {
2144
- self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , preimage) ;
2145
- }
2146
- }
2147
- } else {
2148
- if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2149
- if let Some ( mut entry) = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_hash) {
2150
- for source in entry. drain ( ..) {
2151
- self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , & payment_hash, HTLCFailReason :: Reason { failure_code : 0x1000 | 14 , data : Vec :: new ( ) } ) ;
2131
+ for tx in txn_matched {
2132
+ if let Some ( payments_data) = self . monitor . is_resolving_output ( & tx) {
2133
+ for payment_data in payments_data {
2134
+ if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2135
+ if let Some ( mut entry) = channel_state. as_mut ( ) . unwrap ( ) . claimable_htlcs . remove ( & payment_data. 1 ) {
2136
+ for source in entry. drain ( ..) {
2137
+ if let Some ( preimage) = payment_data. 0 {
2138
+ self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , preimage) ;
2139
+ } else {
2140
+ self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( source) , & payment_data. 1 , HTLCFailReason :: Reason { failure_code : 0x1000 | 14 , data : Vec :: new ( ) } ) ;
2141
+ }
2142
+ }
2152
2143
}
2153
2144
}
2154
2145
}
@@ -4523,6 +4514,54 @@ mod tests {
4523
4514
assert_eq ! ( node_txn[ 2 ] . clone( ) . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , 133 ) ;
4524
4515
}
4525
4516
4517
+ #[ test]
4518
+ fn test_commitment_revoked_fail_backward ( ) {
4519
+ // Test that in case of a revoked commitment tx, we detect the resolution of output by justice tx
4520
+ // and fail backward accordingly.
4521
+
4522
+ let nodes = create_network ( 3 ) ;
4523
+
4524
+ // Create some initial channels
4525
+ create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
4526
+ let chan_2 = create_announced_chan_between_nodes ( & nodes, 1 , 2 ) ;
4527
+
4528
+ // Rebalance the network a bit by relaying one payment through all the channels...
4529
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
4530
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
4531
+
4532
+ let ( payment_preimage, _payment_hash) = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 3000000 ) ;
4533
+ // Get the will-be-revoked local txn from nodes[2]
4534
+ let revoked_local_txn = nodes[ 2 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_2. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
4535
+ // Revoke the old state
4536
+ claim_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , payment_preimage) ;
4537
+
4538
+ route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 3000000 ) ;
4539
+
4540
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
4541
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ revoked_local_txn[ 0 ] . clone( ) ] } , 1 ) ;
4542
+ {
4543
+ let mut added_monitors = nodes[ 1 ] . chan_monitor . added_monitors . lock ( ) . unwrap ( ) ;
4544
+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
4545
+ added_monitors. clear ( ) ;
4546
+ }
4547
+ let events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
4548
+ assert_eq ! ( events. len( ) , 2 ) ;
4549
+ match events[ 0 ] {
4550
+ Event :: UpdateHTLCs { ref node_id, updates : msgs:: CommitmentUpdate { ref update_add_htlcs, ref update_fail_htlcs, ref update_fulfill_htlcs, ref update_fail_malformed_htlcs, .. } } => {
4551
+ assert ! ( update_add_htlcs. is_empty( ) ) ;
4552
+ assert ! ( !update_fail_htlcs. is_empty( ) ) ;
4553
+ assert ! ( update_fulfill_htlcs. is_empty( ) ) ;
4554
+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
4555
+ assert_eq ! ( nodes[ 0 ] . node. get_our_node_id( ) , * node_id) ;
4556
+ } ,
4557
+ _ => panic ! ( "Unexpected event" ) ,
4558
+ }
4559
+ match events[ 1 ] {
4560
+ Event :: BroadcastChannelUpdate { msg : msgs:: ChannelUpdate { .. } } => { } ,
4561
+ _ => panic ! ( "Unexpected event" ) ,
4562
+ }
4563
+ }
4564
+
4526
4565
#[ test]
4527
4566
fn test_htlc_ignore_latest_remote_commitment ( ) {
4528
4567
// Test that HTLC transactions spending the latest remote commitment transaction are simply
0 commit comments