@@ -174,25 +174,7 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
174
174
for htlc in htlc_updated_infos. drain ( ..) {
175
175
match pending_htlc_updated. entry ( htlc. 2 ) {
176
176
hash_map:: Entry :: Occupied ( mut e) => {
177
- // In case of reorg we may have htlc outputs solved in a different way so
178
- // we prefer to keep claims but don't store duplicate updates for a given
179
- // (payment_hash, HTLCSource) pair.
180
- // TODO: Note that we currently don't really use this as ChannelManager
181
- // will fail/claim backwards after the first block. We really should delay
182
- // a few blocks before failing backwards (but can claim backwards
183
- // immediately) as long as we have a few blocks of headroom.
184
- let mut existing_claim = false ;
185
- e. get_mut ( ) . retain ( |htlc_data| {
186
- if htlc. 0 == htlc_data. 0 {
187
- if htlc_data. 1 . is_some ( ) {
188
- existing_claim = true ;
189
- true
190
- } else { false }
191
- } else { true }
192
- } ) ;
193
- if !existing_claim {
194
- e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
195
- }
177
+ e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
196
178
}
197
179
hash_map:: Entry :: Vacant ( e) => {
198
180
e. insert ( vec ! [ ( htlc. 0 , htlc. 1 ) ] ) ;
@@ -304,7 +286,6 @@ pub(crate) const HTLC_FAIL_TIMEOUT_BLOCKS: u32 = 3;
304
286
/// Number of blocks we wait on seeing a confirmed HTLC-Timeout or previous revoked commitment
305
287
/// transaction before we fail corresponding inbound HTLCs. This prevents us from failing backwards
306
288
/// and then getting a reorg resulting in us losing money.
307
- //TODO: We currently don't actually use this...we should
308
289
pub ( crate ) const HTLC_FAIL_ANTI_REORG_DELAY : u32 = 6 ;
309
290
310
291
#[ derive( Clone , PartialEq ) ]
@@ -390,6 +371,8 @@ pub struct ChannelMonitor {
390
371
391
372
destination_script : Script ,
392
373
374
+ htlc_updated_waiting_threshold_conf : HashMap < u32 , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > > ,
375
+
393
376
// We simply modify last_block_hash in Channel's block_connected so that serialization is
394
377
// consistent but hopefully the users' copy handles block_connected in a consistent way.
395
378
// (we do *not*, however, update them in insert_combine to ensure any local user copies keep
@@ -419,7 +402,8 @@ impl PartialEq for ChannelMonitor {
419
402
self . current_remote_commitment_number != other. current_remote_commitment_number ||
420
403
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
421
404
self . payment_preimages != other. payment_preimages ||
422
- self . destination_script != other. destination_script
405
+ self . destination_script != other. destination_script ||
406
+ self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
423
407
{
424
408
false
425
409
} else {
@@ -469,6 +453,8 @@ impl ChannelMonitor {
469
453
payment_preimages : HashMap :: new ( ) ,
470
454
destination_script : destination_script,
471
455
456
+ htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
457
+
472
458
last_block_hash : Default :: default ( ) ,
473
459
secp_ctx : Secp256k1 :: new ( ) ,
474
460
logger,
@@ -956,6 +942,17 @@ impl ChannelMonitor {
956
942
self . last_block_hash . write ( writer) ?;
957
943
self . destination_script . write ( writer) ?;
958
944
945
+ writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
946
+ for ( ref target, ref updates) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
947
+ writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
948
+ writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
949
+ for ref update in updates. iter ( ) {
950
+ update. 0 . write ( writer) ?;
951
+ update. 1 . write ( writer) ?;
952
+ update. 2 . write ( writer) ?;
953
+ }
954
+ }
955
+
959
956
Ok ( ( ) )
960
957
}
961
958
@@ -1019,13 +1016,12 @@ impl ChannelMonitor {
1019
1016
/// HTLC-Success/HTLC-Timeout transactions.
1020
1017
/// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
1021
1018
/// revoked remote commitment tx
1022
- fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > ) {
1019
+ fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > ) {
1023
1020
// Most secp and related errors trying to create keys means we have no hope of constructing
1024
1021
// a spend transaction...so we return no transactions to broadcast
1025
1022
let mut txn_to_broadcast = Vec :: new ( ) ;
1026
1023
let mut watch_outputs = Vec :: new ( ) ;
1027
1024
let mut spendable_outputs = Vec :: new ( ) ;
1028
- let mut htlc_updated = Vec :: new ( ) ;
1029
1025
1030
1026
let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
1031
1027
let per_commitment_option = self . remote_claimable_outpoints . get ( & commitment_txid) ;
@@ -1034,7 +1030,7 @@ impl ChannelMonitor {
1034
1030
( $thing : expr ) => {
1035
1031
match $thing {
1036
1032
Ok ( a) => a,
1037
- Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1033
+ Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1038
1034
}
1039
1035
} ;
1040
1036
}
@@ -1059,7 +1055,7 @@ impl ChannelMonitor {
1059
1055
} ;
1060
1056
let delayed_key = ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, & PublicKey :: from_secret_key( & self . secp_ctx, & per_commitment_key) , & self . their_delayed_payment_base_key. unwrap( ) ) ) ;
1061
1057
let a_htlc_key = match self . their_htlc_base_key {
1062
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1058
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1063
1059
Some ( their_htlc_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, & PublicKey :: from_secret_key( & self . secp_ctx, & per_commitment_key) , & their_htlc_base_key) ) ,
1064
1060
} ;
1065
1061
@@ -1139,7 +1135,7 @@ impl ChannelMonitor {
1139
1135
if transaction_output_index as usize >= tx. output . len ( ) ||
1140
1136
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1141
1137
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1142
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1138
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1143
1139
}
1144
1140
let input = TxIn {
1145
1141
previous_output : BitcoinOutPoint {
@@ -1179,16 +1175,22 @@ impl ChannelMonitor {
1179
1175
watch_outputs. append ( & mut tx. output . clone ( ) ) ;
1180
1176
self . remote_commitment_txn_on_chain . insert ( commitment_txid, ( commitment_number, tx. output . iter ( ) . map ( |output| { output. script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
1181
1177
1182
- // TODO: We really should only fail backwards after our revocation claims have been
1183
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1184
- // on-chain claims, so we can do that at the same time.
1185
1178
macro_rules! check_htlc_fails {
1186
1179
( $txid: expr, $commitment_tx: expr) => {
1187
1180
if let Some ( ref outpoints) = self . remote_claimable_outpoints. get( $txid) {
1188
1181
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1189
1182
if let & Some ( ref source) = source_option {
1190
- log_trace!( self , "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of revoked remote commitment transaction" , log_bytes!( htlc. payment_hash. 0 ) , $commitment_tx) ;
1191
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1183
+ log_trace!( self , "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of revoked remote commitment transaction, waiting confirmation until {} height" , log_bytes!( htlc. payment_hash. 0 ) , $commitment_tx, height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
1184
+ match self . htlc_updated_waiting_threshold_conf. entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1185
+ hash_map:: Entry :: Occupied ( mut entry) => {
1186
+ let e = entry. get_mut( ) ;
1187
+ e. retain( |ref update| update. 0 != * * source) ;
1188
+ e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1189
+ }
1190
+ hash_map:: Entry :: Vacant ( entry) => {
1191
+ entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1192
+ }
1193
+ }
1192
1194
}
1193
1195
}
1194
1196
}
@@ -1204,7 +1206,7 @@ impl ChannelMonitor {
1204
1206
}
1205
1207
// No need to check local commitment txn, symmetric HTLCSource must be present as per-htlc data on remote commitment tx
1206
1208
}
1207
- if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; } // Nothing to be done...probably a false positive/local tx
1209
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1208
1210
1209
1211
let outputs = vec ! ( TxOut {
1210
1212
script_pubkey: self . destination_script. clone( ) ,
@@ -1243,9 +1245,6 @@ impl ChannelMonitor {
1243
1245
1244
1246
log_trace ! ( self , "Got broadcast of non-revoked remote commitment transaction {}" , commitment_txid) ;
1245
1247
1246
- // TODO: We really should only fail backwards after our revocation claims have been
1247
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1248
- // on-chain claims, so we can do that at the same time.
1249
1248
macro_rules! check_htlc_fails {
1250
1249
( $txid: expr, $commitment_tx: expr, $id: tt) => {
1251
1250
if let Some ( ref latest_outpoints) = self . remote_claimable_outpoints. get( $txid) {
@@ -1266,7 +1265,16 @@ impl ChannelMonitor {
1266
1265
}
1267
1266
}
1268
1267
log_trace!( self , "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of remote commitment transaction" , log_bytes!( htlc. payment_hash. 0 ) , $commitment_tx) ;
1269
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1268
+ match self . htlc_updated_waiting_threshold_conf. entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1269
+ hash_map:: Entry :: Occupied ( mut entry) => {
1270
+ let e = entry. get_mut( ) ;
1271
+ e. retain( |ref update| update. 0 != * * source) ;
1272
+ e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1273
+ }
1274
+ hash_map:: Entry :: Vacant ( entry) => {
1275
+ entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1276
+ }
1277
+ }
1270
1278
}
1271
1279
}
1272
1280
}
@@ -1299,7 +1307,7 @@ impl ChannelMonitor {
1299
1307
} ,
1300
1308
} ;
1301
1309
let a_htlc_key = match self . their_htlc_base_key {
1302
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1310
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1303
1311
Some ( their_htlc_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, revocation_point, & their_htlc_base_key) ) ,
1304
1312
} ;
1305
1313
@@ -1354,7 +1362,7 @@ impl ChannelMonitor {
1354
1362
if transaction_output_index as usize >= tx. output . len ( ) ||
1355
1363
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1356
1364
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1357
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1365
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1358
1366
}
1359
1367
if let Some ( payment_preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
1360
1368
let input = TxIn {
@@ -1417,7 +1425,7 @@ impl ChannelMonitor {
1417
1425
}
1418
1426
}
1419
1427
1420
- if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; } // Nothing to be done...probably a false positive/local tx
1428
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1421
1429
1422
1430
let outputs = vec ! ( TxOut {
1423
1431
script_pubkey: self . destination_script. clone( ) ,
@@ -1447,7 +1455,7 @@ impl ChannelMonitor {
1447
1455
}
1448
1456
}
1449
1457
1450
- ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1458
+ ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1451
1459
}
1452
1460
1453
1461
/// Attempts to claim a remote HTLC-Success/HTLC-Timeout's outputs using the revocation key
@@ -1719,7 +1727,7 @@ impl ChannelMonitor {
1719
1727
}
1720
1728
} ;
1721
1729
if funding_txo. is_none ( ) || ( prevout. txid == funding_txo. as_ref ( ) . unwrap ( ) . 0 . txid && prevout. vout == funding_txo. as_ref ( ) . unwrap ( ) . 0 . index as u32 ) {
1722
- let ( remote_txn, new_outputs, mut spendable_output, mut updated ) = self . check_spend_remote_transaction ( tx, height) ;
1730
+ let ( remote_txn, new_outputs, mut spendable_output) = self . check_spend_remote_transaction ( tx, height) ;
1723
1731
txn = remote_txn;
1724
1732
spendable_outputs. append ( & mut spendable_output) ;
1725
1733
if !new_outputs. 1 . is_empty ( ) {
@@ -1738,9 +1746,6 @@ impl ChannelMonitor {
1738
1746
spendable_outputs. push ( spendable_output) ;
1739
1747
}
1740
1748
}
1741
- if updated. len ( ) > 0 {
1742
- htlc_updated. append ( & mut updated) ;
1743
- }
1744
1749
} else {
1745
1750
if let Some ( & ( commitment_number, _) ) = self . remote_commitment_txn_on_chain . get ( & prevout. txid ) {
1746
1751
let ( tx, spendable_output) = self . check_spend_remote_htlc ( tx, commitment_number) ;
@@ -1791,6 +1796,12 @@ impl ChannelMonitor {
1791
1796
}
1792
1797
}
1793
1798
}
1799
+ if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1800
+ for update in updates {
1801
+ log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1802
+ htlc_updated. push ( update) ;
1803
+ }
1804
+ }
1794
1805
self . last_block_hash = block_hash. clone ( ) ;
1795
1806
( watch_outputs, spendable_outputs, htlc_updated)
1796
1807
}
@@ -2191,6 +2202,21 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2191
2202
let last_block_hash: Sha256dHash = Readable :: read ( reader) ?;
2192
2203
let destination_script = Readable :: read ( reader) ?;
2193
2204
2205
+ let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2206
+ let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2207
+ for _ in 0 ..waiting_threshold_conf_len {
2208
+ let height_target = Readable :: read ( reader) ?;
2209
+ let updates_len: u64 = Readable :: read ( reader) ?;
2210
+ let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2211
+ for _ in 0 ..updates_len {
2212
+ let htlc_source = Readable :: read ( reader) ?;
2213
+ let preimage = Readable :: read ( reader) ?;
2214
+ let hash = Readable :: read ( reader) ?;
2215
+ updates. push ( ( htlc_source, preimage, hash) ) ;
2216
+ }
2217
+ htlc_updated_waiting_threshold_conf. insert ( height_target, updates) ;
2218
+ }
2219
+
2194
2220
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
2195
2221
commitment_transaction_number_obscure_factor,
2196
2222
@@ -2214,6 +2240,9 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2214
2240
payment_preimages,
2215
2241
2216
2242
destination_script,
2243
+
2244
+ htlc_updated_waiting_threshold_conf,
2245
+
2217
2246
last_block_hash,
2218
2247
secp_ctx,
2219
2248
logger,
0 commit comments