@@ -338,6 +338,23 @@ enum InputDescriptors {
338
338
RevokedOutput , // either a revoked to_local output on commitment tx, a revoked HTLC-Timeout output or a revoked HTLC-Success output
339
339
}
340
340
341
+ /// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it
342
+ /// once they mature to enough confirmations (HTLC_FAIL_ANTI_REORG_DELAY)
343
+ #[ derive( Clone , PartialEq ) ]
344
+ enum OnchainEvent {
345
+ /// Outpoint under claim process by our own tx, once this one get enough confirmations, we remove it from
346
+ /// bump-txn candidate buffer.
347
+ Claim {
348
+ outpoint : BitcoinOutPoint ,
349
+ } ,
350
+ /// HTLC output getting solved by a timeout, at maturation we pass upstream payment source information to solve
351
+ /// inbound HTLC in backward channel. Note, in case of preimage, we pass info to upstream without delay as we can
352
+ /// only win from it, so it's never an OnchainEvent
353
+ HTLCUpdate {
354
+ htlc_update : ( HTLCSource , PaymentHash ) ,
355
+ } ,
356
+ }
357
+
341
358
const SERIALIZATION_VERSION : u8 = 1 ;
342
359
const MIN_SERIALIZATION_VERSION : u8 = 1 ;
343
360
@@ -388,7 +405,9 @@ pub struct ChannelMonitor {
388
405
389
406
destination_script : Script ,
390
407
391
- htlc_updated_waiting_threshold_conf : HashMap < u32 , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > > ,
408
+ // Used to track onchain events, i.e transactions parts of channels confirmed on chain, on which
409
+ // we have to take actions once they reach enough confs. Actions depend on OnchainEvent type.
410
+ onchain_events_waiting_threshold_conf : HashMap < u32 , Vec < OnchainEvent > > ,
392
411
393
412
// We simply modify last_block_hash in Channel's block_connected so that serialization is
394
413
// consistent but hopefully the users' copy handles block_connected in a consistent way.
@@ -420,7 +439,7 @@ impl PartialEq for ChannelMonitor {
420
439
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
421
440
self . payment_preimages != other. payment_preimages ||
422
441
self . destination_script != other. destination_script ||
423
- self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
442
+ self . onchain_events_waiting_threshold_conf != other. onchain_events_waiting_threshold_conf
424
443
{
425
444
false
426
445
} else {
@@ -470,7 +489,7 @@ impl ChannelMonitor {
470
489
payment_preimages : HashMap :: new ( ) ,
471
490
destination_script : destination_script,
472
491
473
- htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
492
+ onchain_events_waiting_threshold_conf : HashMap :: new ( ) ,
474
493
475
494
last_block_hash : Default :: default ( ) ,
476
495
secp_ctx : Secp256k1 :: new ( ) ,
@@ -979,14 +998,22 @@ impl ChannelMonitor {
979
998
self . last_block_hash . write ( writer) ?;
980
999
self . destination_script . write ( writer) ?;
981
1000
982
- writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
983
- for ( ref target, ref updates ) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
1001
+ writer. write_all ( & byte_utils:: be64_to_array ( self . onchain_events_waiting_threshold_conf . len ( ) as u64 ) ) ?;
1002
+ for ( ref target, ref events ) in self . onchain_events_waiting_threshold_conf . iter ( ) {
984
1003
writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
985
- writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
986
- for ref update in updates. iter ( ) {
987
- update. 0 . write ( writer) ?;
988
- update. 1 . write ( writer) ?;
989
- update. 2 . write ( writer) ?;
1004
+ writer. write_all ( & byte_utils:: be64_to_array ( events. len ( ) as u64 ) ) ?;
1005
+ for ev in events. iter ( ) {
1006
+ match * ev {
1007
+ OnchainEvent :: Claim { ref outpoint } => {
1008
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
1009
+ outpoint. write ( writer) ?;
1010
+ } ,
1011
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1012
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
1013
+ htlc_update. 0 . write ( writer) ?;
1014
+ htlc_update. 1 . write ( writer) ?;
1015
+ }
1016
+ }
990
1017
}
991
1018
}
992
1019
@@ -1224,14 +1251,21 @@ impl ChannelMonitor {
1224
1251
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1225
1252
if let & Some ( ref source) = source_option {
1226
1253
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 ) ;
1227
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1254
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1228
1255
hash_map:: Entry :: Occupied ( mut entry) => {
1229
1256
let e = entry. get_mut( ) ;
1230
- e. retain( |ref update| update. 0 != * * source) ;
1231
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1257
+ e. retain( |ref event| {
1258
+ match * * event {
1259
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1260
+ return htlc_update. 0 != * * source
1261
+ } ,
1262
+ _ => return true
1263
+ }
1264
+ } ) ;
1265
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1232
1266
}
1233
1267
hash_map:: Entry :: Vacant ( entry) => {
1234
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1268
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1235
1269
}
1236
1270
}
1237
1271
}
@@ -1311,14 +1345,21 @@ impl ChannelMonitor {
1311
1345
}
1312
1346
}
1313
1347
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) ;
1314
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1348
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1315
1349
hash_map:: Entry :: Occupied ( mut entry) => {
1316
1350
let e = entry. get_mut( ) ;
1317
- e. retain( |ref update| update. 0 != * * source) ;
1318
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1351
+ e. retain( |ref event| {
1352
+ match * * event {
1353
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1354
+ return htlc_update. 0 != * * source
1355
+ } ,
1356
+ _ => return true
1357
+ }
1358
+ } ) ;
1359
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1319
1360
}
1320
1361
hash_map:: Entry :: Vacant ( entry) => {
1321
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1362
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1322
1363
}
1323
1364
}
1324
1365
}
@@ -1690,16 +1731,23 @@ impl ChannelMonitor {
1690
1731
let mut watch_outputs = Vec :: new ( ) ;
1691
1732
1692
1733
macro_rules! wait_threshold_conf {
1693
- ( $height: expr, $source: expr, $update : expr , $ commitment_tx: expr, $payment_hash: expr) => {
1734
+ ( $height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1694
1735
log_trace!( self , "Failing HTLC with payment_hash {} from {} local commitment tx due to broadcast of transaction, waiting confirmation until {} height" , log_bytes!( $payment_hash. 0 ) , $commitment_tx, height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
1695
- match self . htlc_updated_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1736
+ match self . onchain_events_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1696
1737
hash_map:: Entry :: Occupied ( mut entry) => {
1697
1738
let e = entry. get_mut( ) ;
1698
- e. retain( |ref update| update. 0 != $source) ;
1699
- e. push( ( $source, $update, $payment_hash) ) ;
1739
+ e. retain( |ref event| {
1740
+ match * * event {
1741
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1742
+ return htlc_update. 0 != $source
1743
+ } ,
1744
+ _ => return true
1745
+ }
1746
+ } ) ;
1747
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( $source, $payment_hash) } ) ;
1700
1748
}
1701
1749
hash_map:: Entry :: Vacant ( entry) => {
1702
- entry. insert( vec![ ( $source, $update , $ payment_hash) ] ) ;
1750
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( $source, $payment_hash) } ] ) ;
1703
1751
}
1704
1752
}
1705
1753
}
@@ -1717,7 +1765,7 @@ impl ChannelMonitor {
1717
1765
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1718
1766
if htlc. transaction_output_index . is_none ( ) {
1719
1767
if let & Some ( ref source) = source {
1720
- wait_threshold_conf ! ( height, source. clone( ) , None , "lastest" , htlc. payment_hash. clone( ) ) ;
1768
+ wait_threshold_conf ! ( height, source. clone( ) , "lastest" , htlc. payment_hash. clone( ) ) ;
1721
1769
}
1722
1770
}
1723
1771
}
@@ -1737,7 +1785,7 @@ impl ChannelMonitor {
1737
1785
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1738
1786
if htlc. transaction_output_index . is_none ( ) {
1739
1787
if let & Some ( ref source) = source {
1740
- wait_threshold_conf ! ( height, source. clone( ) , None , "previous" , htlc. payment_hash. clone( ) ) ;
1788
+ wait_threshold_conf ! ( height, source. clone( ) , "previous" , htlc. payment_hash. clone( ) ) ;
1741
1789
}
1742
1790
}
1743
1791
}
@@ -1888,19 +1936,27 @@ impl ChannelMonitor {
1888
1936
}
1889
1937
}
1890
1938
}
1891
- if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1892
- for update in updates {
1893
- log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1894
- htlc_updated. push ( update) ;
1939
+ if let Some ( events) = self . onchain_events_waiting_threshold_conf . remove ( & height) {
1940
+ for ev in events {
1941
+ match ev {
1942
+ OnchainEvent :: Claim { outpoint } => {
1943
+ } ,
1944
+ OnchainEvent :: HTLCUpdate { htlc_update } => {
1945
+ log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
1946
+ htlc_updated. push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
1947
+ } ,
1948
+ }
1895
1949
}
1896
1950
}
1897
1951
self . last_block_hash = block_hash. clone ( ) ;
1898
1952
( watch_outputs, spendable_outputs, htlc_updated)
1899
1953
}
1900
1954
1901
1955
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash ) {
1902
- if let Some ( _) = self . htlc_updated_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1903
- //We discard htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
1956
+ if let Some ( _) = self . onchain_events_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1957
+ //We may discard:
1958
+ //- htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
1959
+ //- our claim tx on a commitment tx output
1904
1960
}
1905
1961
self . last_block_hash = block_hash. clone ( ) ;
1906
1962
}
@@ -2082,14 +2138,21 @@ impl ChannelMonitor {
2082
2138
htlc_updated. push ( ( source, Some ( payment_preimage) , payment_hash) ) ;
2083
2139
} else {
2084
2140
log_trace ! ( self , "Failing HTLC with payment_hash {} timeout by a spend tx, waiting confirmation until {} height" , log_bytes!( payment_hash. 0 ) , height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ;
2085
- match self . htlc_updated_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2141
+ match self . onchain_events_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2086
2142
hash_map:: Entry :: Occupied ( mut entry) => {
2087
2143
let e = entry. get_mut ( ) ;
2088
- e. retain ( |ref update| update. 0 != source) ;
2089
- e. push ( ( source, None , payment_hash. clone ( ) ) ) ;
2144
+ e. retain ( |ref event| {
2145
+ match * * event {
2146
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
2147
+ return htlc_update. 0 != source
2148
+ } ,
2149
+ _ => return true
2150
+ }
2151
+ } ) ;
2152
+ e. push ( OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ) ;
2090
2153
}
2091
2154
hash_map:: Entry :: Vacant ( entry) => {
2092
- entry. insert ( vec ! [ ( source, None , payment_hash) ] ) ;
2155
+ entry. insert ( vec ! [ OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ] ) ;
2093
2156
}
2094
2157
}
2095
2158
}
@@ -2312,18 +2375,31 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2312
2375
let destination_script = Readable :: read ( reader) ?;
2313
2376
2314
2377
let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2315
- let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2378
+ let mut onchain_events_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2316
2379
for _ in 0 ..waiting_threshold_conf_len {
2317
2380
let height_target = Readable :: read ( reader) ?;
2318
- let updates_len: u64 = Readable :: read ( reader) ?;
2319
- let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2320
- for _ in 0 ..updates_len {
2321
- let htlc_source = Readable :: read ( reader) ?;
2322
- let preimage = Readable :: read ( reader) ?;
2323
- let hash = Readable :: read ( reader) ?;
2324
- updates. push ( ( htlc_source, preimage, hash) ) ;
2381
+ let events_len: u64 = Readable :: read ( reader) ?;
2382
+ let mut events = Vec :: with_capacity ( cmp:: min ( events_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2383
+ for _ in 0 ..events_len {
2384
+ let ev = match <u8 as Readable < R > >:: read ( reader) ? {
2385
+ 0 => {
2386
+ let outpoint = Readable :: read ( reader) ?;
2387
+ OnchainEvent :: Claim {
2388
+ outpoint
2389
+ }
2390
+ } ,
2391
+ 1 => {
2392
+ let htlc_source = Readable :: read ( reader) ?;
2393
+ let hash = Readable :: read ( reader) ?;
2394
+ OnchainEvent :: HTLCUpdate {
2395
+ htlc_update : ( htlc_source, hash)
2396
+ }
2397
+ } ,
2398
+ _ => return Err ( DecodeError :: InvalidValue ) ,
2399
+ } ;
2400
+ events. push ( ev) ;
2325
2401
}
2326
- htlc_updated_waiting_threshold_conf . insert ( height_target, updates ) ;
2402
+ onchain_events_waiting_threshold_conf . insert ( height_target, events ) ;
2327
2403
}
2328
2404
2329
2405
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
@@ -2350,7 +2426,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2350
2426
2351
2427
destination_script,
2352
2428
2353
- htlc_updated_waiting_threshold_conf ,
2429
+ onchain_events_waiting_threshold_conf ,
2354
2430
2355
2431
last_block_hash,
2356
2432
secp_ctx,
0 commit comments