@@ -169,25 +169,7 @@ impl<Key : Send + cmp::Eq + hash::Hash> ChainListener for SimpleManyChannelMonit
169
169
for htlc in htlc_updated_infos. drain ( ..) {
170
170
match pending_htlc_updated. entry ( htlc. 2 ) {
171
171
hash_map:: Entry :: Occupied ( mut e) => {
172
- // In case of reorg we may have htlc outputs solved in a different way so
173
- // we prefer to keep claims but don't store duplicate updates for a given
174
- // (payment_hash, HTLCSource) pair.
175
- // TODO: Note that we currently don't really use this as ChannelManager
176
- // will fail/claim backwards after the first block. We really should delay
177
- // a few blocks before failing backwards (but can claim backwards
178
- // immediately) as long as we have a few blocks of headroom.
179
- let mut existing_claim = false ;
180
- e. get_mut ( ) . retain ( |htlc_data| {
181
- if htlc. 0 == htlc_data. 0 {
182
- if htlc_data. 1 . is_some ( ) {
183
- existing_claim = true ;
184
- true
185
- } else { false }
186
- } else { true }
187
- } ) ;
188
- if !existing_claim {
189
- e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
190
- }
172
+ e. get_mut ( ) . push ( ( htlc. 0 , htlc. 1 ) ) ;
191
173
}
192
174
hash_map:: Entry :: Vacant ( e) => {
193
175
e. insert ( vec ! [ ( htlc. 0 , htlc. 1 ) ] ) ;
@@ -299,7 +281,6 @@ pub(crate) const HTLC_FAIL_TIMEOUT_BLOCKS: u32 = 3;
299
281
/// Number of blocks we wait on seeing a confirmed HTLC-Timeout or previous revoked commitment
300
282
/// transaction before we fail corresponding inbound HTLCs. This prevents us from failing backwards
301
283
/// and then getting a reorg resulting in us losing money.
302
- //TODO: We currently don't actually use this...we should
303
284
pub ( crate ) const HTLC_FAIL_ANTI_REORG_DELAY : u32 = 6 ;
304
285
305
286
#[ derive( Clone , PartialEq ) ]
@@ -385,6 +366,8 @@ pub struct ChannelMonitor {
385
366
386
367
destination_script : Script ,
387
368
369
+ htlc_updated_waiting_threshold_conf : HashMap < u32 , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > > ,
370
+
388
371
// We simply modify last_block_hash in Channel's block_connected so that serialization is
389
372
// consistent but hopefully the users' copy handles block_connected in a consistent way.
390
373
// (we do *not*, however, update them in insert_combine to ensure any local user copies keep
@@ -414,7 +397,8 @@ impl PartialEq for ChannelMonitor {
414
397
self . current_remote_commitment_number != other. current_remote_commitment_number ||
415
398
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
416
399
self . payment_preimages != other. payment_preimages ||
417
- self . destination_script != other. destination_script
400
+ self . destination_script != other. destination_script ||
401
+ self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
418
402
{
419
403
false
420
404
} else {
@@ -464,6 +448,8 @@ impl ChannelMonitor {
464
448
payment_preimages : HashMap :: new ( ) ,
465
449
destination_script : destination_script,
466
450
451
+ htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
452
+
467
453
last_block_hash : Default :: default ( ) ,
468
454
secp_ctx : Secp256k1 :: new ( ) ,
469
455
logger,
@@ -951,6 +937,17 @@ impl ChannelMonitor {
951
937
self . last_block_hash . write ( writer) ?;
952
938
self . destination_script . write ( writer) ?;
953
939
940
+ writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
941
+ for ( ref target, ref updates) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
942
+ writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
943
+ writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
944
+ for ref update in updates. iter ( ) {
945
+ update. 0 . write ( writer) ?;
946
+ update. 1 . write ( writer) ?;
947
+ update. 2 . write ( writer) ?;
948
+ }
949
+ }
950
+
954
951
Ok ( ( ) )
955
952
}
956
953
@@ -1014,13 +1011,12 @@ impl ChannelMonitor {
1014
1011
/// HTLC-Success/HTLC-Timeout transactions.
1015
1012
/// Return updates for HTLC pending in the channel and failed automatically by the broadcast of
1016
1013
/// revoked remote commitment tx
1017
- fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > ) {
1014
+ fn check_spend_remote_transaction ( & mut self , tx : & Transaction , height : u32 ) -> ( Vec < Transaction > , ( Sha256dHash , Vec < TxOut > ) , Vec < SpendableOutputDescriptor > ) {
1018
1015
// Most secp and related errors trying to create keys means we have no hope of constructing
1019
1016
// a spend transaction...so we return no transactions to broadcast
1020
1017
let mut txn_to_broadcast = Vec :: new ( ) ;
1021
1018
let mut watch_outputs = Vec :: new ( ) ;
1022
1019
let mut spendable_outputs = Vec :: new ( ) ;
1023
- let mut htlc_updated = Vec :: new ( ) ;
1024
1020
1025
1021
let commitment_txid = tx. txid ( ) ; //TODO: This is gonna be a performance bottleneck for watchtowers!
1026
1022
let per_commitment_option = self . remote_claimable_outpoints . get ( & commitment_txid) ;
@@ -1029,7 +1025,7 @@ impl ChannelMonitor {
1029
1025
( $thing : expr ) => {
1030
1026
match $thing {
1031
1027
Ok ( a) => a,
1032
- Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1028
+ Err ( _) => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1033
1029
}
1034
1030
} ;
1035
1031
}
@@ -1054,7 +1050,7 @@ impl ChannelMonitor {
1054
1050
} ;
1055
1051
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( ) ) ) ;
1056
1052
let a_htlc_key = match self . their_htlc_base_key {
1057
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1053
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1058
1054
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) ) ,
1059
1055
} ;
1060
1056
@@ -1134,7 +1130,7 @@ impl ChannelMonitor {
1134
1130
if transaction_output_index as usize >= tx. output . len ( ) ||
1135
1131
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1136
1132
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1137
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1133
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1138
1134
}
1139
1135
let input = TxIn {
1140
1136
previous_output : BitcoinOutPoint {
@@ -1174,16 +1170,22 @@ impl ChannelMonitor {
1174
1170
watch_outputs. append ( & mut tx. output . clone ( ) ) ;
1175
1171
self . remote_commitment_txn_on_chain . insert ( commitment_txid, ( commitment_number, tx. output . iter ( ) . map ( |output| { output. script_pubkey . clone ( ) } ) . collect ( ) ) ) ;
1176
1172
1177
- // TODO: We really should only fail backwards after our revocation claims have been
1178
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1179
- // on-chain claims, so we can do that at the same time.
1180
1173
macro_rules! check_htlc_fails {
1181
1174
( $txid: expr, $commitment_tx: expr) => {
1182
1175
if let Some ( ref outpoints) = self . remote_claimable_outpoints. get( & $txid) {
1183
1176
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1184
1177
if let & Some ( ref source) = source_option {
1185
- 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) ;
1186
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1178
+ 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 ) ;
1179
+ match self . htlc_updated_waiting_threshold_conf. entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1180
+ hash_map:: Entry :: Occupied ( mut entry) => {
1181
+ let e = entry. get_mut( ) ;
1182
+ e. retain( |ref update| update. 0 != * * source) ;
1183
+ e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1184
+ }
1185
+ hash_map:: Entry :: Vacant ( entry) => {
1186
+ entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1187
+ }
1188
+ }
1187
1189
}
1188
1190
}
1189
1191
}
@@ -1199,7 +1201,7 @@ impl ChannelMonitor {
1199
1201
}
1200
1202
// No need to check local commitment txn, symmetric HTLCSource must be present as per-htlc data on remote commitment tx
1201
1203
}
1202
- 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
1204
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1203
1205
1204
1206
let outputs = vec ! ( TxOut {
1205
1207
script_pubkey: self . destination_script. clone( ) ,
@@ -1238,9 +1240,6 @@ impl ChannelMonitor {
1238
1240
1239
1241
log_trace ! ( self , "Got broadcast of non-revoked remote commitment transaction {}" , commitment_txid) ;
1240
1242
1241
- // TODO: We really should only fail backwards after our revocation claims have been
1242
- // confirmed, but we also need to do more other tracking of in-flight pre-confirm
1243
- // on-chain claims, so we can do that at the same time.
1244
1243
macro_rules! check_htlc_fails {
1245
1244
( $txid: expr, $commitment_tx: expr, $id: tt) => {
1246
1245
if let Some ( ref latest_outpoints) = self . remote_claimable_outpoints. get( & $txid) {
@@ -1261,7 +1260,16 @@ impl ChannelMonitor {
1261
1260
}
1262
1261
}
1263
1262
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) ;
1264
- htlc_updated. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1263
+ match self . htlc_updated_waiting_threshold_conf. entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1264
+ hash_map:: Entry :: Occupied ( mut entry) => {
1265
+ let e = entry. get_mut( ) ;
1266
+ e. retain( |ref update| update. 0 != * * source) ;
1267
+ e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1268
+ }
1269
+ hash_map:: Entry :: Vacant ( entry) => {
1270
+ entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1271
+ }
1272
+ }
1265
1273
}
1266
1274
}
1267
1275
}
@@ -1294,7 +1302,7 @@ impl ChannelMonitor {
1294
1302
} ,
1295
1303
} ;
1296
1304
let a_htlc_key = match self . their_htlc_base_key {
1297
- None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ,
1305
+ None => return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ,
1298
1306
Some ( their_htlc_base_key) => ignore_error ! ( chan_utils:: derive_public_key( & self . secp_ctx, revocation_point, & their_htlc_base_key) ) ,
1299
1307
} ;
1300
1308
@@ -1349,7 +1357,7 @@ impl ChannelMonitor {
1349
1357
if transaction_output_index as usize >= tx. output . len ( ) ||
1350
1358
tx. output [ transaction_output_index as usize ] . value != htlc. amount_msat / 1000 ||
1351
1359
tx. output [ transaction_output_index as usize ] . script_pubkey != expected_script. to_v0_p2wsh ( ) {
1352
- return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated ) ; // Corrupted per_commitment_data, fuck this user
1360
+ return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; // Corrupted per_commitment_data, fuck this user
1353
1361
}
1354
1362
if let Some ( payment_preimage) = self . payment_preimages . get ( & htlc. payment_hash ) {
1355
1363
let input = TxIn {
@@ -1412,7 +1420,7 @@ impl ChannelMonitor {
1412
1420
}
1413
1421
}
1414
1422
1415
- 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
1423
+ if inputs. is_empty ( ) { return ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs) ; } // Nothing to be done...probably a false positive/local tx
1416
1424
1417
1425
let outputs = vec ! ( TxOut {
1418
1426
script_pubkey: self . destination_script. clone( ) ,
@@ -1442,7 +1450,7 @@ impl ChannelMonitor {
1442
1450
}
1443
1451
}
1444
1452
1445
- ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs, htlc_updated )
1453
+ ( txn_to_broadcast, ( commitment_txid, watch_outputs) , spendable_outputs)
1446
1454
}
1447
1455
1448
1456
/// Attempts to claim a remote HTLC-Success/HTLC-Timeout's outputs using the revocation key
@@ -1714,7 +1722,7 @@ impl ChannelMonitor {
1714
1722
}
1715
1723
} ;
1716
1724
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 ) {
1717
- let ( remote_txn, new_outputs, mut spendable_output, mut updated ) = self . check_spend_remote_transaction ( tx, height) ;
1725
+ let ( remote_txn, new_outputs, mut spendable_output) = self . check_spend_remote_transaction ( tx, height) ;
1718
1726
txn = remote_txn;
1719
1727
spendable_outputs. append ( & mut spendable_output) ;
1720
1728
if !new_outputs. 1 . is_empty ( ) {
@@ -1733,9 +1741,6 @@ impl ChannelMonitor {
1733
1741
spendable_outputs. push ( spendable_output) ;
1734
1742
}
1735
1743
}
1736
- if updated. len ( ) > 0 {
1737
- htlc_updated. append ( & mut updated) ;
1738
- }
1739
1744
} else {
1740
1745
if let Some ( & ( commitment_number, _) ) = self . remote_commitment_txn_on_chain . get ( & prevout. txid ) {
1741
1746
let ( tx, spendable_output) = self . check_spend_remote_htlc ( tx, commitment_number) ;
@@ -1786,6 +1791,12 @@ impl ChannelMonitor {
1786
1791
}
1787
1792
}
1788
1793
}
1794
+ if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1795
+ for update in updates {
1796
+ log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1797
+ htlc_updated. push ( update) ;
1798
+ }
1799
+ }
1789
1800
self . last_block_hash = block_hash. clone ( ) ;
1790
1801
( watch_outputs, spendable_outputs, htlc_updated)
1791
1802
}
@@ -2159,6 +2170,21 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2159
2170
let last_block_hash: Sha256dHash = Readable :: read ( reader) ?;
2160
2171
let destination_script = Readable :: read ( reader) ?;
2161
2172
2173
+ let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2174
+ let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2175
+ for _ in 0 ..waiting_threshold_conf_len {
2176
+ let height_target = Readable :: read ( reader) ?;
2177
+ let updates_len: u64 = Readable :: read ( reader) ?;
2178
+ let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2179
+ for _ in 0 ..updates_len {
2180
+ let htlc_source = Readable :: read ( reader) ?;
2181
+ let preimage = Readable :: read ( reader) ?;
2182
+ let hash = Readable :: read ( reader) ?;
2183
+ updates. push ( ( htlc_source, preimage, hash) ) ;
2184
+ }
2185
+ htlc_updated_waiting_threshold_conf. insert ( height_target, updates) ;
2186
+ }
2187
+
2162
2188
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
2163
2189
commitment_transaction_number_obscure_factor,
2164
2190
@@ -2182,6 +2208,9 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2182
2208
payment_preimages,
2183
2209
2184
2210
destination_script,
2211
+
2212
+ htlc_updated_waiting_threshold_conf,
2213
+
2185
2214
last_block_hash,
2186
2215
secp_ctx,
2187
2216
logger,
0 commit comments