@@ -352,6 +352,23 @@ enum InputDescriptors {
352
352
RevokedOutput , // either a revoked to_local output on commitment tx, a revoked HTLC-Timeout output or a revoked HTLC-Success output
353
353
}
354
354
355
+ /// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it
356
+ /// once they mature to enough confirmations (HTLC_FAIL_ANTI_REORG_DELAY)
357
+ #[ derive( Clone , PartialEq ) ]
358
+ enum OnchainEvent {
359
+ /// Outpoint under claim process by our own tx, once this one get enough confirmations, we remove it from
360
+ /// bump-txn candidate buffer.
361
+ Claim {
362
+ outpoint : BitcoinOutPoint ,
363
+ } ,
364
+ /// HTLC output getting solved by a timeout, at maturation we pass upstream payment source information to solve
365
+ /// inbound HTLC in backward channel. Note, in case of preimage, we pass info to upstream without delay as we can
366
+ /// only win from it, so it's never an OnchainEvent
367
+ HTLCUpdate {
368
+ htlc_update : ( HTLCSource , PaymentHash ) ,
369
+ } ,
370
+ }
371
+
355
372
const SERIALIZATION_VERSION : u8 = 1 ;
356
373
const MIN_SERIALIZATION_VERSION : u8 = 1 ;
357
374
@@ -402,7 +419,10 @@ pub struct ChannelMonitor {
402
419
403
420
destination_script : Script ,
404
421
405
- htlc_updated_waiting_threshold_conf : HashMap < u32 , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > > ,
422
+ // Used to track onchain events, i.e transactions parts of channels confirmed on chain, on which
423
+ // we have to take actions once they reach enough confs. Key is a block height timer, i.e we enforce
424
+ // actions when we receive a block with given height. Actions depend on OnchainEvent type.
425
+ onchain_events_waiting_threshold_conf : HashMap < u32 , Vec < OnchainEvent > > ,
406
426
407
427
// We simply modify last_block_hash in Channel's block_connected so that serialization is
408
428
// consistent but hopefully the users' copy handles block_connected in a consistent way.
@@ -466,7 +486,7 @@ impl PartialEq for ChannelMonitor {
466
486
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
467
487
self . payment_preimages != other. payment_preimages ||
468
488
self . destination_script != other. destination_script ||
469
- self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
489
+ self . onchain_events_waiting_threshold_conf != other. onchain_events_waiting_threshold_conf
470
490
{
471
491
false
472
492
} else {
@@ -516,7 +536,7 @@ impl ChannelMonitor {
516
536
payment_preimages : HashMap :: new ( ) ,
517
537
destination_script : destination_script,
518
538
519
- htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
539
+ onchain_events_waiting_threshold_conf : HashMap :: new ( ) ,
520
540
521
541
last_block_hash : Default :: default ( ) ,
522
542
secp_ctx : Secp256k1 :: new ( ) ,
@@ -1025,14 +1045,22 @@ impl ChannelMonitor {
1025
1045
self . last_block_hash . write ( writer) ?;
1026
1046
self . destination_script . write ( writer) ?;
1027
1047
1028
- writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
1029
- for ( ref target, ref updates ) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
1048
+ writer. write_all ( & byte_utils:: be64_to_array ( self . onchain_events_waiting_threshold_conf . len ( ) as u64 ) ) ?;
1049
+ for ( ref target, ref events ) in self . onchain_events_waiting_threshold_conf . iter ( ) {
1030
1050
writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
1031
- writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
1032
- for ref update in updates. iter ( ) {
1033
- update. 0 . write ( writer) ?;
1034
- update. 1 . write ( writer) ?;
1035
- update. 2 . write ( writer) ?;
1051
+ writer. write_all ( & byte_utils:: be64_to_array ( events. len ( ) as u64 ) ) ?;
1052
+ for ev in events. iter ( ) {
1053
+ match * ev {
1054
+ OnchainEvent :: Claim { ref outpoint } => {
1055
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
1056
+ outpoint. write ( writer) ?;
1057
+ } ,
1058
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1059
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
1060
+ htlc_update. 0 . write ( writer) ?;
1061
+ htlc_update. 1 . write ( writer) ?;
1062
+ }
1063
+ }
1036
1064
}
1037
1065
}
1038
1066
@@ -1271,14 +1299,21 @@ impl ChannelMonitor {
1271
1299
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1272
1300
if let & Some ( ref source) = source_option {
1273
1301
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 ) ;
1274
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1302
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1275
1303
hash_map:: Entry :: Occupied ( mut entry) => {
1276
1304
let e = entry. get_mut( ) ;
1277
- e. retain( |ref update| update. 0 != * * source) ;
1278
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1305
+ e. retain( |ref event| {
1306
+ match * * event {
1307
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1308
+ return htlc_update. 0 != * * source
1309
+ } ,
1310
+ _ => return true
1311
+ }
1312
+ } ) ;
1313
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1279
1314
}
1280
1315
hash_map:: Entry :: Vacant ( entry) => {
1281
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1316
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1282
1317
}
1283
1318
}
1284
1319
}
@@ -1361,14 +1396,21 @@ impl ChannelMonitor {
1361
1396
}
1362
1397
}
1363
1398
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) ;
1364
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1399
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1365
1400
hash_map:: Entry :: Occupied ( mut entry) => {
1366
1401
let e = entry. get_mut( ) ;
1367
- e. retain( |ref update| update. 0 != * * source) ;
1368
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1402
+ e. retain( |ref event| {
1403
+ match * * event {
1404
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1405
+ return htlc_update. 0 != * * source
1406
+ } ,
1407
+ _ => return true
1408
+ }
1409
+ } ) ;
1410
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1369
1411
}
1370
1412
hash_map:: Entry :: Vacant ( entry) => {
1371
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1413
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1372
1414
}
1373
1415
}
1374
1416
}
@@ -1745,16 +1787,23 @@ impl ChannelMonitor {
1745
1787
let mut watch_outputs = Vec :: new ( ) ;
1746
1788
1747
1789
macro_rules! wait_threshold_conf {
1748
- ( $height: expr, $source: expr, $update : expr , $ commitment_tx: expr, $payment_hash: expr) => {
1749
- log_info !( self , "Failing HTLC with payment_hash {} from {} local commitment tx due to broadcast of transaction, waiting confirmation (at height{})" , log_bytes!( $payment_hash. 0 ) , $commitment_tx, height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
1750
- match self . htlc_updated_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1790
+ ( $height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1791
+ log_trace !( self , "Failing HTLC with payment_hash {} from {} local commitment tx due to broadcast of transaction, waiting confirmation (at height{})" , log_bytes!( $payment_hash. 0 ) , $commitment_tx, height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
1792
+ match self . onchain_events_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1751
1793
hash_map:: Entry :: Occupied ( mut entry) => {
1752
1794
let e = entry. get_mut( ) ;
1753
- e. retain( |ref update| update. 0 != $source) ;
1754
- e. push( ( $source, $update, $payment_hash) ) ;
1795
+ e. retain( |ref event| {
1796
+ match * * event {
1797
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1798
+ return htlc_update. 0 != $source
1799
+ } ,
1800
+ _ => return true
1801
+ }
1802
+ } ) ;
1803
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( $source, $payment_hash) } ) ;
1755
1804
}
1756
1805
hash_map:: Entry :: Vacant ( entry) => {
1757
- entry. insert( vec![ ( $source, $update , $ payment_hash) ] ) ;
1806
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( $source, $payment_hash) } ] ) ;
1758
1807
}
1759
1808
}
1760
1809
}
@@ -1805,7 +1854,7 @@ impl ChannelMonitor {
1805
1854
for & ( ref htlc, _, ref source) in & $local_tx. htlc_outputs {
1806
1855
if htlc. transaction_output_index. is_none( ) {
1807
1856
if let & Some ( ref source) = source {
1808
- wait_threshold_conf!( height, source. clone( ) , None , "lastest" , htlc. payment_hash. clone( ) ) ;
1857
+ wait_threshold_conf!( height, source. clone( ) , "lastest" , htlc. payment_hash. clone( ) ) ;
1809
1858
}
1810
1859
}
1811
1860
}
@@ -1956,19 +2005,27 @@ impl ChannelMonitor {
1956
2005
}
1957
2006
}
1958
2007
}
1959
- if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1960
- for update in updates {
1961
- log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1962
- htlc_updated. push ( update) ;
2008
+ if let Some ( events) = self . onchain_events_waiting_threshold_conf . remove ( & height) {
2009
+ for ev in events {
2010
+ match ev {
2011
+ OnchainEvent :: Claim { outpoint : _ } => {
2012
+ } ,
2013
+ OnchainEvent :: HTLCUpdate { htlc_update } => {
2014
+ log_trace ! ( self , "HTLC {} failure update has got enough confirmations to be passed upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
2015
+ htlc_updated. push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
2016
+ } ,
2017
+ }
1963
2018
}
1964
2019
}
1965
2020
self . last_block_hash = block_hash. clone ( ) ;
1966
2021
( watch_outputs, spendable_outputs, htlc_updated)
1967
2022
}
1968
2023
1969
2024
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash ) {
1970
- if let Some ( _) = self . htlc_updated_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1971
- //We discard htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
2025
+ if let Some ( _) = self . onchain_events_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
2026
+ //We may discard:
2027
+ //- htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
2028
+ //- our claim tx on a commitment tx output
1972
2029
}
1973
2030
self . last_block_hash = block_hash. clone ( ) ;
1974
2031
}
@@ -2150,14 +2207,21 @@ impl ChannelMonitor {
2150
2207
htlc_updated. push ( ( source, Some ( payment_preimage) , payment_hash) ) ;
2151
2208
} else {
2152
2209
log_info ! ( self , "Failing HTLC with payment_hash {} timeout by a spend tx, waiting for confirmation (at height{})" , log_bytes!( payment_hash. 0 ) , height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
2153
- match self . htlc_updated_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2210
+ match self . onchain_events_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2154
2211
hash_map:: Entry :: Occupied ( mut entry) => {
2155
2212
let e = entry. get_mut ( ) ;
2156
- e. retain ( |ref update| update. 0 != source) ;
2157
- e. push ( ( source, None , payment_hash. clone ( ) ) ) ;
2213
+ e. retain ( |ref event| {
2214
+ match * * event {
2215
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
2216
+ return htlc_update. 0 != source
2217
+ } ,
2218
+ _ => return true
2219
+ }
2220
+ } ) ;
2221
+ e. push ( OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ) ;
2158
2222
}
2159
2223
hash_map:: Entry :: Vacant ( entry) => {
2160
- entry. insert ( vec ! [ ( source, None , payment_hash) ] ) ;
2224
+ entry. insert ( vec ! [ OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ] ) ;
2161
2225
}
2162
2226
}
2163
2227
}
@@ -2380,18 +2444,31 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2380
2444
let destination_script = Readable :: read ( reader) ?;
2381
2445
2382
2446
let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2383
- let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2447
+ let mut onchain_events_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2384
2448
for _ in 0 ..waiting_threshold_conf_len {
2385
2449
let height_target = Readable :: read ( reader) ?;
2386
- let updates_len: u64 = Readable :: read ( reader) ?;
2387
- let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2388
- for _ in 0 ..updates_len {
2389
- let htlc_source = Readable :: read ( reader) ?;
2390
- let preimage = Readable :: read ( reader) ?;
2391
- let hash = Readable :: read ( reader) ?;
2392
- updates. push ( ( htlc_source, preimage, hash) ) ;
2450
+ let events_len: u64 = Readable :: read ( reader) ?;
2451
+ let mut events = Vec :: with_capacity ( cmp:: min ( events_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2452
+ for _ in 0 ..events_len {
2453
+ let ev = match <u8 as Readable < R > >:: read ( reader) ? {
2454
+ 0 => {
2455
+ let outpoint = Readable :: read ( reader) ?;
2456
+ OnchainEvent :: Claim {
2457
+ outpoint
2458
+ }
2459
+ } ,
2460
+ 1 => {
2461
+ let htlc_source = Readable :: read ( reader) ?;
2462
+ let hash = Readable :: read ( reader) ?;
2463
+ OnchainEvent :: HTLCUpdate {
2464
+ htlc_update : ( htlc_source, hash)
2465
+ }
2466
+ } ,
2467
+ _ => return Err ( DecodeError :: InvalidValue ) ,
2468
+ } ;
2469
+ events. push ( ev) ;
2393
2470
}
2394
- htlc_updated_waiting_threshold_conf . insert ( height_target, updates ) ;
2471
+ onchain_events_waiting_threshold_conf . insert ( height_target, events ) ;
2395
2472
}
2396
2473
2397
2474
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
@@ -2418,7 +2495,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2418
2495
2419
2496
destination_script,
2420
2497
2421
- htlc_updated_waiting_threshold_conf ,
2498
+ onchain_events_waiting_threshold_conf ,
2422
2499
2423
2500
last_block_hash,
2424
2501
secp_ctx,
0 commit comments