@@ -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
@@ -430,7 +427,8 @@ impl PartialEq for ChannelMonitor {
430
427
self . current_remote_commitment_number != other. current_remote_commitment_number ||
431
428
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
432
429
self . payment_preimages != other. payment_preimages ||
433
- self . destination_script != other. destination_script
430
+ self . destination_script != other. destination_script ||
431
+ self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
434
432
{
435
433
false
436
434
} else {
@@ -480,6 +478,8 @@ impl ChannelMonitor {
480
478
payment_preimages : HashMap :: new ( ) ,
481
479
destination_script : destination_script,
482
480
481
+ htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
482
+
483
483
last_block_hash : Default :: default ( ) ,
484
484
secp_ctx : Secp256k1 :: new ( ) ,
485
485
logger,
@@ -987,6 +987,17 @@ impl ChannelMonitor {
987
987
self . last_block_hash . write ( writer) ?;
988
988
self . destination_script . write ( writer) ?;
989
989
990
+ writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
991
+ for ( ref target, ref updates) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
992
+ writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
993
+ writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
994
+ for ref update in updates. iter ( ) {
995
+ update. 0 . write ( writer) ?;
996
+ update. 1 . write ( writer) ?;
997
+ update. 2 . write ( writer) ?;
998
+ }
999
+ }
1000
+
990
1001
Ok ( ( ) )
991
1002
}
992
1003
@@ -1050,13 +1061,12 @@ impl ChannelMonitor {
1050
1061
/// HTLC-Success/HTLC-Timeout transactions.
1051
1062
/// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
1052
1063
/// revoked remote commitment tx
1053
- 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 ) > ) {
1064
+ fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 , fee_estimator : & FeeEstimator ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > ) {
1054
1065
// Most secp and related errors trying to create keys means we have no hope of constructing
1055
1066
// a spend transaction...so we return no transactions to broadcast
1056
1067
let mut txn_to_broadcast = Vec :: new ( ) ;
1057
1068
let mut watch_outputs = Vec :: new ( ) ;
1058
1069
let mut spendable_outputs = Vec :: new ( ) ;
1059
- let mut htlc_updated = Vec :: new ( ) ;
1060
1070
1061
1071
let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
1062
1072
let per_commitment_option = self . remote_claimable_outpoints . get ( & commitment_txid) ;
@@ -1065,7 +1075,7 @@ impl ChannelMonitor {
1065
1075
( $thing : expr ) => {
1066
1076
match $thing {
1067
1077
Ok ( a) => a,
1068
- Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1078
+ Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1069
1079
}
1070
1080
} ;
1071
1081
}
@@ -1090,7 +1100,7 @@ impl ChannelMonitor {
1090
1100
} ;
1091
1101
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( ) ) ) ;
1092
1102
let a_htlc_key = match self . their_htlc_base_key {
1093
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1103
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1094
1104
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) ) ,
1095
1105
} ;
1096
1106
@@ -1172,7 +1182,7 @@ impl ChannelMonitor {
1172
1182
if transaction_output_index as usize >= tx. output . len ( ) ||
1173
1183
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1174
1184
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1175
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1185
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1176
1186
}
1177
1187
let input = TxIn {
1178
1188
previous_output : BitcoinOutPoint {
@@ -1216,16 +1226,22 @@ impl ChannelMonitor {
1216
1226
watch_outputs. append ( & mut tx. output . clone ( ) ) ;
1217
1227
self . remote_commitment_txn_on_chain . insert ( commitment_txid, ( commitment_number, tx. output . iter ( ) . map ( |output| { output. script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
1218
1228
1219
- // TODO: We really should only fail backwards after our revocation claims have been
1220
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1221
- // on-chain claims, so we can do that at the same time.
1222
1229
macro_rules! check_htlc_fails {
1223
1230
( $txid: expr, $commitment_tx: expr) => {
1224
1231
if let Some ( ref outpoints) = self . remote_claimable_outpoints. get( $txid) {
1225
1232
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1226
1233
if let & Some ( ref source) = source_option {
1227
- 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) ;
1228
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1234
+ 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 ) ;
1235
+ match self . htlc_updated_waiting_threshold_conf. entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1236
+ hash_map:: Entry :: Occupied ( mut entry) => {
1237
+ let e = entry. get_mut( ) ;
1238
+ e. retain( |ref update| update. 0 != * * source) ;
1239
+ e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1240
+ }
1241
+ hash_map:: Entry :: Vacant ( entry) => {
1242
+ entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1243
+ }
1244
+ }
1229
1245
}
1230
1246
}
1231
1247
}
@@ -1241,7 +1257,7 @@ impl ChannelMonitor {
1241
1257
}
1242
1258
// No need to check local commitment txn, symmetric HTLCSource must be present as per-htlc data on remote commitment tx
1243
1259
}
1244
- 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
1260
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1245
1261
1246
1262
let outputs = vec ! ( TxOut {
1247
1263
script_pubkey: self . destination_script. clone( ) ,
@@ -1283,9 +1299,6 @@ impl ChannelMonitor {
1283
1299
1284
1300
log_trace ! ( self , "Got broadcast of non-revoked remote commitment transaction {}" , commitment_txid) ;
1285
1301
1286
- // TODO: We really should only fail backwards after our revocation claims have been
1287
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1288
- // on-chain claims, so we can do that at the same time.
1289
1302
macro_rules! check_htlc_fails {
1290
1303
( $txid: expr, $commitment_tx: expr, $id: tt) => {
1291
1304
if let Some ( ref latest_outpoints) = self . remote_claimable_outpoints. get( $txid) {
@@ -1306,7 +1319,16 @@ impl ChannelMonitor {
1306
1319
}
1307
1320
}
1308
1321
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) ;
1309
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1322
+ match self . htlc_updated_waiting_threshold_conf. entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1323
+ hash_map:: Entry :: Occupied ( mut entry) => {
1324
+ let e = entry. get_mut( ) ;
1325
+ e. retain( |ref update| update. 0 != * * source) ;
1326
+ e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1327
+ }
1328
+ hash_map:: Entry :: Vacant ( entry) => {
1329
+ entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1330
+ }
1331
+ }
1310
1332
}
1311
1333
}
1312
1334
}
@@ -1339,7 +1361,7 @@ impl ChannelMonitor {
1339
1361
} ,
1340
1362
} ;
1341
1363
let a_htlc_key = match self . their_htlc_base_key {
1342
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1364
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1343
1365
Some ( their_htlc_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, revocation_point, & their_htlc_base_key) ) ,
1344
1366
} ;
1345
1367
@@ -1395,7 +1417,7 @@ impl ChannelMonitor {
1395
1417
if transaction_output_index as usize >= tx. output . len ( ) ||
1396
1418
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1397
1419
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1398
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1420
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1399
1421
}
1400
1422
if let Some ( payment_preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
1401
1423
let input = TxIn {
@@ -1462,7 +1484,7 @@ impl ChannelMonitor {
1462
1484
}
1463
1485
}
1464
1486
1465
- 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
1487
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1466
1488
1467
1489
let outputs = vec ! ( TxOut {
1468
1490
script_pubkey: self . destination_script. clone( ) ,
@@ -1495,7 +1517,7 @@ impl ChannelMonitor {
1495
1517
}
1496
1518
}
1497
1519
1498
- ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1520
+ ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1499
1521
}
1500
1522
1501
1523
/// Attempts to claim a remote HTLC-Success/HTLC-Timeout's outputs using the revocation key
@@ -1770,7 +1792,7 @@ impl ChannelMonitor {
1770
1792
}
1771
1793
} ;
1772
1794
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 ) {
1773
- let ( remote_txn, new_outputs, mut spendable_output, mut updated ) = self . check_spend_remote_transaction ( tx, height, fee_estimator) ;
1795
+ let ( remote_txn, new_outputs, mut spendable_output) = self . check_spend_remote_transaction ( tx, height, fee_estimator) ;
1774
1796
txn = remote_txn;
1775
1797
spendable_outputs. append ( & mut spendable_output) ;
1776
1798
if !new_outputs. 1 . is_empty ( ) {
@@ -1789,9 +1811,6 @@ impl ChannelMonitor {
1789
1811
spendable_outputs. push ( spendable_output) ;
1790
1812
}
1791
1813
}
1792
- if updated. len ( ) > 0 {
1793
- htlc_updated. append ( & mut updated) ;
1794
- }
1795
1814
} else {
1796
1815
if let Some ( & ( commitment_number, _) ) = self . remote_commitment_txn_on_chain . get ( & prevout. txid ) {
1797
1816
let ( tx, spendable_output) = self . check_spend_remote_htlc ( tx, commitment_number, fee_estimator) ;
@@ -1842,6 +1861,12 @@ impl ChannelMonitor {
1842
1861
}
1843
1862
}
1844
1863
}
1864
+ if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1865
+ for update in updates {
1866
+ log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1867
+ htlc_updated. push ( update) ;
1868
+ }
1869
+ }
1845
1870
self . last_block_hash = block_hash. clone ( ) ;
1846
1871
( watch_outputs, spendable_outputs, htlc_updated)
1847
1872
}
@@ -2242,6 +2267,21 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2242
2267
let last_block_hash: Sha256dHash = Readable :: read ( reader) ?;
2243
2268
let destination_script = Readable :: read ( reader) ?;
2244
2269
2270
+ let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2271
+ let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2272
+ for _ in 0 ..waiting_threshold_conf_len {
2273
+ let height_target = Readable :: read ( reader) ?;
2274
+ let updates_len: u64 = Readable :: read ( reader) ?;
2275
+ let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2276
+ for _ in 0 ..updates_len {
2277
+ let htlc_source = Readable :: read ( reader) ?;
2278
+ let preimage = Readable :: read ( reader) ?;
2279
+ let hash = Readable :: read ( reader) ?;
2280
+ updates. push ( ( htlc_source, preimage, hash) ) ;
2281
+ }
2282
+ htlc_updated_waiting_threshold_conf. insert ( height_target, updates) ;
2283
+ }
2284
+
2245
2285
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
2246
2286
commitment_transaction_number_obscure_factor,
2247
2287
@@ -2265,6 +2305,9 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2265
2305
payment_preimages,
2266
2306
2267
2307
destination_script,
2308
+
2309
+ htlc_updated_waiting_threshold_conf,
2310
+
2268
2311
last_block_hash,
2269
2312
secp_ctx,
2270
2313
logger,
0 commit comments