@@ -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,9 @@ 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. Actions depend on OnchainEvent type.
424
+ onchain_events_waiting_threshold_conf : HashMap < u32 , Vec < OnchainEvent > > ,
406
425
407
426
// We simply modify last_block_hash in Channel's block_connected so that serialization is
408
427
// consistent but hopefully the users' copy handles block_connected in a consistent way.
@@ -466,7 +485,7 @@ impl PartialEq for ChannelMonitor {
466
485
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
467
486
self . payment_preimages != other. payment_preimages ||
468
487
self . destination_script != other. destination_script ||
469
- self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
488
+ self . onchain_events_waiting_threshold_conf != other. onchain_events_waiting_threshold_conf
470
489
{
471
490
false
472
491
} else {
@@ -516,7 +535,7 @@ impl ChannelMonitor {
516
535
payment_preimages : HashMap :: new ( ) ,
517
536
destination_script : destination_script,
518
537
519
- htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
538
+ onchain_events_waiting_threshold_conf : HashMap :: new ( ) ,
520
539
521
540
last_block_hash : Default :: default ( ) ,
522
541
secp_ctx : Secp256k1 :: new ( ) ,
@@ -1025,14 +1044,22 @@ impl ChannelMonitor {
1025
1044
self . last_block_hash . write ( writer) ?;
1026
1045
self . destination_script . write ( writer) ?;
1027
1046
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 ( ) {
1047
+ writer. write_all ( & byte_utils:: be64_to_array ( self . onchain_events_waiting_threshold_conf . len ( ) as u64 ) ) ?;
1048
+ for ( ref target, ref events ) in self . onchain_events_waiting_threshold_conf . iter ( ) {
1030
1049
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) ?;
1050
+ writer. write_all ( & byte_utils:: be64_to_array ( events. len ( ) as u64 ) ) ?;
1051
+ for ev in events. iter ( ) {
1052
+ match * ev {
1053
+ OnchainEvent :: Claim { ref outpoint } => {
1054
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
1055
+ outpoint. write ( writer) ?;
1056
+ } ,
1057
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1058
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
1059
+ htlc_update. 0 . write ( writer) ?;
1060
+ htlc_update. 1 . write ( writer) ?;
1061
+ }
1062
+ }
1036
1063
}
1037
1064
}
1038
1065
@@ -1271,14 +1298,21 @@ impl ChannelMonitor {
1271
1298
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1272
1299
if let & Some ( ref source) = source_option {
1273
1300
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 ) {
1301
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1275
1302
hash_map:: Entry :: Occupied ( mut entry) => {
1276
1303
let e = entry. get_mut( ) ;
1277
- e. retain( |ref update| update. 0 != * * source) ;
1278
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1304
+ e. retain( |ref event| {
1305
+ match * * event {
1306
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1307
+ return htlc_update. 0 != * * source
1308
+ } ,
1309
+ _ => return true
1310
+ }
1311
+ } ) ;
1312
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1279
1313
}
1280
1314
hash_map:: Entry :: Vacant ( entry) => {
1281
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1315
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1282
1316
}
1283
1317
}
1284
1318
}
@@ -1361,14 +1395,21 @@ impl ChannelMonitor {
1361
1395
}
1362
1396
}
1363
1397
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 ) {
1398
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1365
1399
hash_map:: Entry :: Occupied ( mut entry) => {
1366
1400
let e = entry. get_mut( ) ;
1367
- e. retain( |ref update| update. 0 != * * source) ;
1368
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1401
+ e. retain( |ref event| {
1402
+ match * * event {
1403
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1404
+ return htlc_update. 0 != * * source
1405
+ } ,
1406
+ _ => return true
1407
+ }
1408
+ } ) ;
1409
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1369
1410
}
1370
1411
hash_map:: Entry :: Vacant ( entry) => {
1371
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1412
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1372
1413
}
1373
1414
}
1374
1415
}
@@ -1745,16 +1786,23 @@ impl ChannelMonitor {
1745
1786
let mut watch_outputs = Vec :: new ( ) ;
1746
1787
1747
1788
macro_rules! wait_threshold_conf {
1748
- ( $height: expr, $source: expr, $update : expr , $ commitment_tx: expr, $payment_hash: expr) => {
1789
+ ( $height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1749
1790
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 ) {
1791
+ match self . onchain_events_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1751
1792
hash_map:: Entry :: Occupied ( mut entry) => {
1752
1793
let e = entry. get_mut( ) ;
1753
- e. retain( |ref update| update. 0 != $source) ;
1754
- e. push( ( $source, $update, $payment_hash) ) ;
1794
+ e. retain( |ref event| {
1795
+ match * * event {
1796
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1797
+ return htlc_update. 0 != $source
1798
+ } ,
1799
+ _ => return true
1800
+ }
1801
+ } ) ;
1802
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( $source, $payment_hash) } ) ;
1755
1803
}
1756
1804
hash_map:: Entry :: Vacant ( entry) => {
1757
- entry. insert( vec![ ( $source, $update , $ payment_hash) ] ) ;
1805
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( $source, $payment_hash) } ] ) ;
1758
1806
}
1759
1807
}
1760
1808
}
@@ -1776,7 +1824,7 @@ impl ChannelMonitor {
1776
1824
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1777
1825
if htlc. transaction_output_index . is_none ( ) {
1778
1826
if let & Some ( ref source) = source {
1779
- wait_threshold_conf ! ( height, source. clone( ) , None , "lastest" , htlc. payment_hash. clone( ) ) ;
1827
+ wait_threshold_conf ! ( height, source. clone( ) , "lastest" , htlc. payment_hash. clone( ) ) ;
1780
1828
}
1781
1829
}
1782
1830
}
@@ -1798,7 +1846,7 @@ impl ChannelMonitor {
1798
1846
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1799
1847
if htlc. transaction_output_index . is_none ( ) {
1800
1848
if let & Some ( ref source) = source {
1801
- wait_threshold_conf ! ( height, source. clone( ) , None , "previous" , htlc. payment_hash. clone( ) ) ;
1849
+ wait_threshold_conf ! ( height, source. clone( ) , "previous" , htlc. payment_hash. clone( ) ) ;
1802
1850
}
1803
1851
}
1804
1852
}
@@ -1950,19 +1998,27 @@ impl ChannelMonitor {
1950
1998
}
1951
1999
}
1952
2000
}
1953
- if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1954
- for update in updates {
1955
- log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1956
- htlc_updated. push ( update) ;
2001
+ if let Some ( events) = self . onchain_events_waiting_threshold_conf . remove ( & height) {
2002
+ for ev in events {
2003
+ match ev {
2004
+ OnchainEvent :: Claim { outpoint : _ } => {
2005
+ } ,
2006
+ OnchainEvent :: HTLCUpdate { htlc_update } => {
2007
+ log_trace ! ( self , "HTLC {} failure update has got enough confirmations to be passed upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
2008
+ htlc_updated. push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
2009
+ } ,
2010
+ }
1957
2011
}
1958
2012
}
1959
2013
self . last_block_hash = block_hash. clone ( ) ;
1960
2014
( watch_outputs, spendable_outputs, htlc_updated)
1961
2015
}
1962
2016
1963
2017
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash ) {
1964
- if let Some ( _) = self . htlc_updated_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1965
- //We discard htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
2018
+ if let Some ( _) = self . onchain_events_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
2019
+ //We may discard:
2020
+ //- htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
2021
+ //- our claim tx on a commitment tx output
1966
2022
}
1967
2023
self . last_block_hash = block_hash. clone ( ) ;
1968
2024
}
@@ -2144,14 +2200,21 @@ impl ChannelMonitor {
2144
2200
htlc_updated. push ( ( source, Some ( payment_preimage) , payment_hash) ) ;
2145
2201
} else {
2146
2202
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 ) ;
2147
- match self . htlc_updated_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2203
+ match self . onchain_events_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2148
2204
hash_map:: Entry :: Occupied ( mut entry) => {
2149
2205
let e = entry. get_mut ( ) ;
2150
- e. retain ( |ref update| update. 0 != source) ;
2151
- e. push ( ( source, None , payment_hash. clone ( ) ) ) ;
2206
+ e. retain ( |ref event| {
2207
+ match * * event {
2208
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
2209
+ return htlc_update. 0 != source
2210
+ } ,
2211
+ _ => return true
2212
+ }
2213
+ } ) ;
2214
+ e. push ( OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ) ;
2152
2215
}
2153
2216
hash_map:: Entry :: Vacant ( entry) => {
2154
- entry. insert ( vec ! [ ( source, None , payment_hash) ] ) ;
2217
+ entry. insert ( vec ! [ OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ] ) ;
2155
2218
}
2156
2219
}
2157
2220
}
@@ -2374,18 +2437,31 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2374
2437
let destination_script = Readable :: read ( reader) ?;
2375
2438
2376
2439
let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2377
- let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2440
+ let mut onchain_events_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2378
2441
for _ in 0 ..waiting_threshold_conf_len {
2379
2442
let height_target = Readable :: read ( reader) ?;
2380
- let updates_len: u64 = Readable :: read ( reader) ?;
2381
- let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2382
- for _ in 0 ..updates_len {
2383
- let htlc_source = Readable :: read ( reader) ?;
2384
- let preimage = Readable :: read ( reader) ?;
2385
- let hash = Readable :: read ( reader) ?;
2386
- updates. push ( ( htlc_source, preimage, hash) ) ;
2443
+ let events_len: u64 = Readable :: read ( reader) ?;
2444
+ let mut events = Vec :: with_capacity ( cmp:: min ( events_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2445
+ for _ in 0 ..events_len {
2446
+ let ev = match <u8 as Readable < R > >:: read ( reader) ? {
2447
+ 0 => {
2448
+ let outpoint = Readable :: read ( reader) ?;
2449
+ OnchainEvent :: Claim {
2450
+ outpoint
2451
+ }
2452
+ } ,
2453
+ 1 => {
2454
+ let htlc_source = Readable :: read ( reader) ?;
2455
+ let hash = Readable :: read ( reader) ?;
2456
+ OnchainEvent :: HTLCUpdate {
2457
+ htlc_update : ( htlc_source, hash)
2458
+ }
2459
+ } ,
2460
+ _ => return Err ( DecodeError :: InvalidValue ) ,
2461
+ } ;
2462
+ events. push ( ev) ;
2387
2463
}
2388
- htlc_updated_waiting_threshold_conf . insert ( height_target, updates ) ;
2464
+ onchain_events_waiting_threshold_conf . insert ( height_target, events ) ;
2389
2465
}
2390
2466
2391
2467
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
@@ -2412,7 +2488,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2412
2488
2413
2489
destination_script,
2414
2490
2415
- htlc_updated_waiting_threshold_conf ,
2491
+ onchain_events_waiting_threshold_conf ,
2416
2492
2417
2493
last_block_hash,
2418
2494
secp_ctx,
0 commit comments