@@ -2573,6 +2573,9 @@ impl ChainListener for ChannelManager {
2573
2573
if let Some ( preimage) = htlc_data. 0 {
2574
2574
if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2575
2575
self . claim_funds_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc_source) , preimage) ;
2576
+ } else {
2577
+ if channel_state. is_none ( ) { channel_state = Some ( self . channel_state . lock ( ) . unwrap ( ) ) ; }
2578
+ self . fail_htlc_backwards_internal ( channel_state. take ( ) . unwrap ( ) , HTLCSource :: PreviousHopData ( htlc_source) , & htlc_data. 1 , HTLCFailReason :: Reason { failure_code : 0x1000 | 14 , data : Vec :: new ( ) } ) ;
2576
2579
}
2577
2580
}
2578
2581
}
@@ -6066,6 +6069,117 @@ mod tests {
6066
6069
}
6067
6070
}
6068
6071
6072
+ #[ test]
6073
+ fn test_htlc_on_chain_timeout ( ) {
6074
+ // Test that in case of an unilateral close onchain, we detect the state of output thanks to
6075
+ // ChainWatchInterface and timeout the HTLC bacward accordingly. So here we test that ChannelManager is
6076
+ // broadcasting the right event to other nodes in payment path.
6077
+ // A ------------------> B ----------------------> C (timeout)
6078
+ // A's commitment tx C's commitment tx
6079
+ // \ \
6080
+ // B's HTLC timeout tx B's timeout tx
6081
+
6082
+ let nodes = create_network ( 3 ) ;
6083
+
6084
+ // Create some intial channels
6085
+ let chan_1 = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
6086
+ let chan_2 = create_announced_chan_between_nodes ( & nodes, 1 , 2 ) ;
6087
+
6088
+ // Rebalance the network a bit by relaying one payment thorugh all the channels...
6089
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
6090
+ send_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) [ ..] , 8000000 ) ;
6091
+
6092
+ let ( _payment_preimage, payment_hash) = route_payment ( & nodes[ 0 ] , & vec ! ( & nodes[ 1 ] , & nodes[ 2 ] ) , 3000000 ) ;
6093
+ let header = BlockHeader { version : 0x20000000 , prev_blockhash : Default :: default ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ;
6094
+
6095
+ // Brodacast legit commitment tx from C on B's chain
6096
+ let commitment_tx = nodes[ 2 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_2. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
6097
+ nodes[ 2 ] . node . fail_htlc_backwards ( & payment_hash, PaymentFailReason :: PreimageUnknown ) ;
6098
+ {
6099
+ let mut added_monitors = nodes[ 2 ] . chan_monitor . added_monitors . lock ( ) . unwrap ( ) ;
6100
+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
6101
+ added_monitors. clear ( ) ;
6102
+ }
6103
+ let events = nodes[ 2 ] . node . get_and_clear_pending_msg_events ( ) ;
6104
+ assert_eq ! ( events. len( ) , 1 ) ;
6105
+ match events[ 0 ] {
6106
+ 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, .. } } => {
6107
+ assert ! ( update_add_htlcs. is_empty( ) ) ;
6108
+ assert ! ( !update_fail_htlcs. is_empty( ) ) ;
6109
+ assert ! ( update_fulfill_htlcs. is_empty( ) ) ;
6110
+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
6111
+ assert_eq ! ( nodes[ 1 ] . node. get_our_node_id( ) , * node_id) ;
6112
+ } ,
6113
+ _ => panic ! ( "Unexpected event" ) ,
6114
+ } ;
6115
+ nodes[ 2 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ commitment_tx[ 0 ] . clone( ) ] } , 1 ) ;
6116
+ let events = nodes[ 2 ] . node . get_and_clear_pending_msg_events ( ) ;
6117
+ assert_eq ! ( events. len( ) , 1 ) ;
6118
+ match events[ 0 ] {
6119
+ MessageSendEvent :: BroadcastChannelUpdate { msg : msgs:: ChannelUpdate { .. } } => { } ,
6120
+ _ => panic ! ( "Unexpected event" ) ,
6121
+ }
6122
+ let mut funding_tx_map = HashMap :: new ( ) ;
6123
+ funding_tx_map. insert ( chan_2. 3 . txid ( ) , chan_2. 3 . clone ( ) ) ;
6124
+ commitment_tx[ 0 ] . verify ( & funding_tx_map) . unwrap ( ) ;
6125
+
6126
+ // Broadcast timeout transaction by B on received output fron C's commitment tx on B's chain
6127
+ // Verify that B's ChannelManager is able to detect that HTLC is timeout by its own tx and react backward in consequence
6128
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ commitment_tx[ 0 ] . clone( ) ] } , 200 ) ;
6129
+ let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clone ( ) ;
6130
+ assert_eq ! ( node_txn. len( ) , 8 ) ; // ChannelManager : 2 (commitment tx, HTLC-Timeout), ChannelMonitor : 6 (commitment tx, HTLC-Timeout, timeout tx) * 2 (block-rescan)
6131
+ assert_eq ! ( node_txn[ 2 ] . input[ 0 ] . previous_output. txid, node_txn[ 1 ] . txid( ) ) ;
6132
+ assert_eq ! ( node_txn[ 2 ] . clone( ) . input[ 0 ] . witness. last( ) . unwrap( ) . len( ) , 133 ) ;
6133
+
6134
+ let mut commitment_tx_map = HashMap :: new ( ) ;
6135
+ commitment_tx_map. insert ( commitment_tx[ 0 ] . txid ( ) , commitment_tx[ 0 ] . clone ( ) ) ;
6136
+ node_txn[ 0 ] . verify ( & commitment_tx_map) . unwrap ( ) ;
6137
+
6138
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ node_txn[ 0 ] . clone( ) ] } , 1 ) ;
6139
+ {
6140
+ let mut added_monitors = nodes[ 1 ] . chan_monitor . added_monitors . lock ( ) . unwrap ( ) ;
6141
+ assert_eq ! ( added_monitors. len( ) , 1 ) ;
6142
+ added_monitors. clear ( ) ;
6143
+ }
6144
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
6145
+ assert_eq ! ( events. len( ) , 2 ) ;
6146
+ match events[ 0 ] {
6147
+ MessageSendEvent :: BroadcastChannelUpdate { msg : msgs:: ChannelUpdate { .. } } => { } ,
6148
+ _ => panic ! ( "Unexpected event" ) ,
6149
+ }
6150
+ match events[ 1 ] {
6151
+ 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, .. } } => {
6152
+ assert ! ( update_add_htlcs. is_empty( ) ) ;
6153
+ assert ! ( !update_fail_htlcs. is_empty( ) ) ;
6154
+ assert ! ( update_fulfill_htlcs. is_empty( ) ) ;
6155
+ assert ! ( update_fail_malformed_htlcs. is_empty( ) ) ;
6156
+ assert_eq ! ( nodes[ 0 ] . node. get_our_node_id( ) , * node_id) ;
6157
+ } ,
6158
+ _ => panic ! ( "Unexpected event" ) ,
6159
+ } ;
6160
+
6161
+ // Broadcast legit commitment tx from A on B's chain
6162
+ // Broadcast HTLC Timeout tx by B on offered output from A commitment tx on A's chain
6163
+ let commitment_tx = nodes[ 0 ] . node . channel_state . lock ( ) . unwrap ( ) . by_id . get ( & chan_1. 2 ) . unwrap ( ) . last_local_commitment_txn . clone ( ) ;
6164
+ nodes[ 1 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : vec ! [ commitment_tx[ 0 ] . clone( ) ] } , 1 ) ;
6165
+ let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
6166
+ assert_eq ! ( events. len( ) , 1 ) ;
6167
+ match events[ 0 ] {
6168
+ MessageSendEvent :: BroadcastChannelUpdate { msg : msgs:: ChannelUpdate { .. } } => { } ,
6169
+ _ => panic ! ( "Unexpected event" ) ,
6170
+ }
6171
+ let node_txn = nodes[ 1 ] . tx_broadcaster . txn_broadcasted . lock ( ) . unwrap ( ) . clone ( ) ;
6172
+
6173
+ // Verify that A's ChannelManager is able to detect that HTLC is timeout by a HTLC Timeout tx and react backward in consequence
6174
+ nodes[ 0 ] . chain_monitor . block_connected_with_filtering ( & Block { header, txdata : node_txn } , 1 ) ;
6175
+ let events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
6176
+ assert_eq ! ( events. len( ) , 1 ) ;
6177
+ match events[ 0 ] {
6178
+ MessageSendEvent :: BroadcastChannelUpdate { msg : msgs:: ChannelUpdate { .. } } => { } ,
6179
+ _ => panic ! ( "Unexpected event" ) ,
6180
+ }
6181
+ }
6182
+
6069
6183
#[ test]
6070
6184
fn test_htlc_ignore_latest_remote_commitment ( ) {
6071
6185
// Test that HTLC transactions spending the latest remote commitment transaction are simply
0 commit comments