@@ -178,10 +178,6 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
178
178
// In case of reorg we may have htlc outputs solved in a different way so
179
179
// we prefer to keep claims but don't store duplicate updates for a given
180
180
// (payment_hash, HTLCSource) pair.
181
- // TODO: Note that we currently don't really use this as ChannelManager
182
- // will fail/claim backwards after the first block. We really should delay
183
- // a few blocks before failing backwards (but can claim backwards
184
- // immediately) as long as we have a few blocks of headroom.
185
181
let mut existing_claim = false ;
186
182
e. get_mut ( ) . retain ( |htlc_data| {
187
183
if htlc. 0 == htlc_data. 0 {
@@ -306,7 +302,6 @@ pub(crate) const HTLC_FAIL_TIMEOUT_BLOCKS: u32 = 3;
306
302
/// Number of blocks we wait on seeing a confirmed HTLC-Timeout or previous revoked commitment
307
303
/// transaction before we fail corresponding inbound HTLCs. This prevents us from failing backwards
308
304
/// and then getting a reorg resulting in us losing money.
309
- //TODO: We currently don't actually use this...we should
310
305
pub ( crate ) const HTLC_FAIL_ANTI_REORG_DELAY : u32 = 6 ;
311
306
312
307
#[ derive( Clone , PartialEq ) ]
@@ -401,6 +396,8 @@ pub struct ChannelMonitor {
401
396
402
397
destination_script : Script ,
403
398
399
+ htlc_updated_waiting_threshold_conf : HashMap < u32 , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > > ,
400
+
404
401
// We simply modify last_block_hash in Channel's block_connected so that serialization is
405
402
// consistent but hopefully the users' copy handles block_connected in a consistent way.
406
403
// (we do *not*, however, update them in insert_combine to ensure any local user copies keep
@@ -462,7 +459,8 @@ impl PartialEq for ChannelMonitor {
462
459
self . current_remote_commitment_number != other. current_remote_commitment_number ||
463
460
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
464
461
self . payment_preimages != other. payment_preimages ||
465
- self . destination_script != other. destination_script
462
+ self . destination_script != other. destination_script ||
463
+ self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
466
464
{
467
465
false
468
466
} else {
@@ -512,6 +510,8 @@ impl ChannelMonitor {
512
510
payment_preimages : HashMap :: new ( ) ,
513
511
destination_script : destination_script,
514
512
513
+ htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
514
+
515
515
last_block_hash : Default :: default ( ) ,
516
516
secp_ctx : Secp256k1 :: new ( ) ,
517
517
logger,
@@ -1019,6 +1019,17 @@ impl ChannelMonitor {
1019
1019
self . last_block_hash . write ( writer) ?;
1020
1020
self . destination_script . write ( writer) ?;
1021
1021
1022
+ writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
1023
+ for ( ref target, ref updates) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
1024
+ writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
1025
+ writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
1026
+ for ref update in updates. iter ( ) {
1027
+ update. 0 . write ( writer) ?;
1028
+ update. 1 . write ( writer) ?;
1029
+ update. 2 . write ( writer) ?;
1030
+ }
1031
+ }
1032
+
1022
1033
Ok ( ( ) )
1023
1034
}
1024
1035
@@ -1082,13 +1093,12 @@ impl ChannelMonitor {
1082
1093
/// HTLC-Success/HTLC-Timeout transactions.
1083
1094
/// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
1084
1095
/// revoked remote commitment tx
1085
- fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 , fee_estimator : & FeeEstimator ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > ) {
1096
+ fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 , fee_estimator : & FeeEstimator ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > ) {
1086
1097
// Most secp and related errors trying to create keys means we have no hope of constructing
1087
1098
// a spend transaction...so we return no transactions to broadcast
1088
1099
let mut txn_to_broadcast = Vec :: new ( ) ;
1089
1100
let mut watch_outputs = Vec :: new ( ) ;
1090
1101
let mut spendable_outputs = Vec :: new ( ) ;
1091
- let mut htlc_updated = Vec :: new ( ) ;
1092
1102
1093
1103
let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
1094
1104
let per_commitment_option = self . remote_claimable_outpoints . get ( & commitment_txid) ;
@@ -1097,7 +1107,7 @@ impl ChannelMonitor {
1097
1107
( $thing : expr ) => {
1098
1108
match $thing {
1099
1109
Ok ( a) => a,
1100
- Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1110
+ Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1101
1111
}
1102
1112
} ;
1103
1113
}
@@ -1122,7 +1132,7 @@ impl ChannelMonitor {
1122
1132
} ;
1123
1133
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( ) ) ) ;
1124
1134
let a_htlc_key = match self . their_htlc_base_key {
1125
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1135
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1126
1136
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) ) ,
1127
1137
} ;
1128
1138
@@ -1204,7 +1214,7 @@ impl ChannelMonitor {
1204
1214
if transaction_output_index as usize >= tx. output . len ( ) ||
1205
1215
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1206
1216
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1207
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1217
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1208
1218
}
1209
1219
let input = TxIn {
1210
1220
previous_output : BitcoinOutPoint {
@@ -1249,16 +1259,22 @@ impl ChannelMonitor {
1249
1259
watch_outputs. append ( & mut tx. output . clone ( ) ) ;
1250
1260
self . remote_commitment_txn_on_chain . insert ( commitment_txid, ( commitment_number, tx. output . iter ( ) . map ( |output| { output. script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
1251
1261
1252
- // TODO: We really should only fail backwards after our revocation claims have been
1253
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1254
- // on-chain claims, so we can do that at the same time.
1255
1262
macro_rules! check_htlc_fails {
1256
1263
( $txid: expr, $commitment_tx: expr) => {
1257
1264
if let Some ( ref outpoints) = self . remote_claimable_outpoints. get( $txid) {
1258
1265
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1259
1266
if let & Some ( ref source) = source_option {
1260
- 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) ;
1261
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1267
+ log_info!( self , "Failing HTLC with payment_hash {} from {} remote commitment tx due to broadcast of revoked remote commitment transaction, waiting for confirmation (at height {})" , log_bytes!( htlc. payment_hash. 0 ) , $commitment_tx, height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
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
+ }
1262
1278
}
1263
1279
}
1264
1280
}
@@ -1274,7 +1290,7 @@ impl ChannelMonitor {
1274
1290
}
1275
1291
// No need to check local commitment txn, symmetric HTLCSource must be present as per-htlc data on remote commitment tx
1276
1292
}
1277
- 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
1293
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1278
1294
1279
1295
let outputs = vec ! ( TxOut {
1280
1296
script_pubkey: self . destination_script. clone( ) ,
@@ -1289,7 +1305,7 @@ impl ChannelMonitor {
1289
1305
let predicted_weight = spend_tx. get_weight ( ) + Self :: get_witnesses_weight ( & input_descriptors[ ..] ) ;
1290
1306
1291
1307
if !subtract_high_prio_fee ! ( self , fee_estimator, spend_tx. output[ 0 ] . value, predicted_weight, tx. txid( ) ) {
1292
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ;
1308
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ;
1293
1309
}
1294
1310
1295
1311
let mut values_drain = values. drain ( ..) ;
@@ -1319,9 +1335,6 @@ impl ChannelMonitor {
1319
1335
1320
1336
log_trace ! ( self , "Got broadcast of non-revoked remote commitment transaction {}" , commitment_txid) ;
1321
1337
1322
- // TODO: We really should only fail backwards after our revocation claims have been
1323
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1324
- // on-chain claims, so we can do that at the same time.
1325
1338
macro_rules! check_htlc_fails {
1326
1339
( $txid: expr, $commitment_tx: expr, $id: tt) => {
1327
1340
if let Some ( ref latest_outpoints) = self . remote_claimable_outpoints. get( $txid) {
@@ -1342,7 +1355,16 @@ impl ChannelMonitor {
1342
1355
}
1343
1356
}
1344
1357
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) ;
1345
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1358
+ match self . htlc_updated_waiting_threshold_conf. entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1359
+ hash_map:: Entry :: Occupied ( mut entry) => {
1360
+ let e = entry. get_mut( ) ;
1361
+ e. retain( |ref update| update. 0 != * * source) ;
1362
+ e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1363
+ }
1364
+ hash_map:: Entry :: Vacant ( entry) => {
1365
+ entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1366
+ }
1367
+ }
1346
1368
}
1347
1369
}
1348
1370
}
@@ -1375,7 +1397,7 @@ impl ChannelMonitor {
1375
1397
} ,
1376
1398
} ;
1377
1399
let a_htlc_key = match self . their_htlc_base_key {
1378
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1400
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1379
1401
Some ( their_htlc_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, revocation_point, & their_htlc_base_key) ) ,
1380
1402
} ;
1381
1403
@@ -1431,7 +1453,7 @@ impl ChannelMonitor {
1431
1453
if transaction_output_index as usize >= tx. output . len ( ) ||
1432
1454
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1433
1455
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1434
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1456
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1435
1457
}
1436
1458
if let Some ( payment_preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
1437
1459
let input = TxIn {
@@ -1499,7 +1521,7 @@ impl ChannelMonitor {
1499
1521
}
1500
1522
}
1501
1523
1502
- 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
1524
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1503
1525
1504
1526
let outputs = vec ! ( TxOut {
1505
1527
script_pubkey: self . destination_script. clone( ) ,
@@ -1513,7 +1535,7 @@ impl ChannelMonitor {
1513
1535
} ;
1514
1536
let predicted_weight = spend_tx. get_weight ( ) + Self :: get_witnesses_weight ( & input_descriptors[ ..] ) ;
1515
1537
if !subtract_high_prio_fee ! ( self , fee_estimator, spend_tx. output[ 0 ] . value, predicted_weight, tx. txid( ) ) {
1516
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ;
1538
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ;
1517
1539
}
1518
1540
1519
1541
let mut values_drain = values. drain ( ..) ;
@@ -1534,7 +1556,7 @@ impl ChannelMonitor {
1534
1556
}
1535
1557
}
1536
1558
1537
- ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1559
+ ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1538
1560
}
1539
1561
1540
1562
/// Attempts to claim a remote HTLC-Success/HTLC-Timeout's outputs using the revocation key
@@ -1811,7 +1833,7 @@ impl ChannelMonitor {
1811
1833
}
1812
1834
} ;
1813
1835
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 ) {
1814
- let ( remote_txn, new_outputs, mut spendable_output, mut updated ) = self . check_spend_remote_transaction ( tx, height, fee_estimator) ;
1836
+ let ( remote_txn, new_outputs, mut spendable_output) = self . check_spend_remote_transaction ( tx, height, fee_estimator) ;
1815
1837
txn = remote_txn;
1816
1838
spendable_outputs. append ( & mut spendable_output) ;
1817
1839
if !new_outputs. 1 . is_empty ( ) {
@@ -1830,9 +1852,6 @@ impl ChannelMonitor {
1830
1852
spendable_outputs. push ( spendable_output) ;
1831
1853
}
1832
1854
}
1833
- if updated. len ( ) > 0 {
1834
- htlc_updated. append ( & mut updated) ;
1835
- }
1836
1855
} else {
1837
1856
if let Some ( & ( commitment_number, _) ) = self . remote_commitment_txn_on_chain . get ( & prevout. txid ) {
1838
1857
let ( tx, spendable_output) = self . check_spend_remote_htlc ( tx, commitment_number, fee_estimator) ;
@@ -1883,6 +1902,12 @@ impl ChannelMonitor {
1883
1902
}
1884
1903
}
1885
1904
}
1905
+ if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1906
+ for update in updates {
1907
+ log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1908
+ htlc_updated. push ( update) ;
1909
+ }
1910
+ }
1886
1911
self . last_block_hash = block_hash. clone ( ) ;
1887
1912
( watch_outputs, spendable_outputs, htlc_updated)
1888
1913
}
@@ -2283,6 +2308,21 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2283
2308
let last_block_hash: Sha256dHash = Readable :: read ( reader) ?;
2284
2309
let destination_script = Readable :: read ( reader) ?;
2285
2310
2311
+ let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2312
+ let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2313
+ for _ in 0 ..waiting_threshold_conf_len {
2314
+ let height_target = Readable :: read ( reader) ?;
2315
+ let updates_len: u64 = Readable :: read ( reader) ?;
2316
+ let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2317
+ for _ in 0 ..updates_len {
2318
+ let htlc_source = Readable :: read ( reader) ?;
2319
+ let preimage = Readable :: read ( reader) ?;
2320
+ let hash = Readable :: read ( reader) ?;
2321
+ updates. push ( ( htlc_source, preimage, hash) ) ;
2322
+ }
2323
+ htlc_updated_waiting_threshold_conf. insert ( height_target, updates) ;
2324
+ }
2325
+
2286
2326
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
2287
2327
commitment_transaction_number_obscure_factor,
2288
2328
@@ -2306,6 +2346,9 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2306
2346
payment_preimages,
2307
2347
2308
2348
destination_script,
2349
+
2350
+ htlc_updated_waiting_threshold_conf,
2351
+
2309
2352
last_block_hash,
2310
2353
secp_ctx,
2311
2354
logger,
0 commit comments