@@ -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.
@@ -434,7 +453,7 @@ impl PartialEq for ChannelMonitor {
434
453
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
435
454
self . payment_preimages != other. payment_preimages ||
436
455
self . destination_script != other. destination_script ||
437
- self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
456
+ self . onchain_events_waiting_threshold_conf != other. onchain_events_waiting_threshold_conf
438
457
{
439
458
false
440
459
} else {
@@ -484,7 +503,7 @@ impl ChannelMonitor {
484
503
payment_preimages : HashMap :: new ( ) ,
485
504
destination_script : destination_script,
486
505
487
- htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
506
+ onchain_events_waiting_threshold_conf : HashMap :: new ( ) ,
488
507
489
508
last_block_hash : Default :: default ( ) ,
490
509
secp_ctx : Secp256k1 :: new ( ) ,
@@ -993,14 +1012,22 @@ impl ChannelMonitor {
993
1012
self . last_block_hash . write ( writer) ?;
994
1013
self . destination_script . write ( writer) ?;
995
1014
996
- writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
997
- for ( ref target, ref updates ) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
1015
+ writer. write_all ( & byte_utils:: be64_to_array ( self . onchain_events_waiting_threshold_conf . len ( ) as u64 ) ) ?;
1016
+ for ( ref target, ref events ) in self . onchain_events_waiting_threshold_conf . iter ( ) {
998
1017
writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
999
- writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
1000
- for ref update in updates. iter ( ) {
1001
- update. 0 . write ( writer) ?;
1002
- update. 1 . write ( writer) ?;
1003
- update. 2 . write ( writer) ?;
1018
+ writer. write_all ( & byte_utils:: be64_to_array ( events. len ( ) as u64 ) ) ?;
1019
+ for ev in events. iter ( ) {
1020
+ match * ev {
1021
+ OnchainEvent :: Claim { ref outpoint } => {
1022
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
1023
+ outpoint. write ( writer) ?;
1024
+ } ,
1025
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1026
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
1027
+ htlc_update. 0 . write ( writer) ?;
1028
+ htlc_update. 1 . write ( writer) ?;
1029
+ }
1030
+ }
1004
1031
}
1005
1032
}
1006
1033
@@ -1238,14 +1265,21 @@ impl ChannelMonitor {
1238
1265
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1239
1266
if let & Some ( ref source) = source_option {
1240
1267
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 ) ;
1241
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1268
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1242
1269
hash_map:: Entry :: Occupied ( mut entry) => {
1243
1270
let e = entry. get_mut( ) ;
1244
- e. retain( |ref update| update. 0 != * * source) ;
1245
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1271
+ e. retain( |ref event| {
1272
+ match * * event {
1273
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1274
+ return htlc_update. 0 != * * source
1275
+ } ,
1276
+ _ => return true
1277
+ }
1278
+ } ) ;
1279
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1246
1280
}
1247
1281
hash_map:: Entry :: Vacant ( entry) => {
1248
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1282
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1249
1283
}
1250
1284
}
1251
1285
}
@@ -1325,14 +1359,21 @@ impl ChannelMonitor {
1325
1359
}
1326
1360
}
1327
1361
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) ;
1328
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1362
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1329
1363
hash_map:: Entry :: Occupied ( mut entry) => {
1330
1364
let e = entry. get_mut( ) ;
1331
- e. retain( |ref update| update. 0 != * * source) ;
1332
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1365
+ e. retain( |ref event| {
1366
+ match * * event {
1367
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1368
+ return htlc_update. 0 != * * source
1369
+ } ,
1370
+ _ => return true
1371
+ }
1372
+ } ) ;
1373
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1333
1374
}
1334
1375
hash_map:: Entry :: Vacant ( entry) => {
1335
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1376
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1336
1377
}
1337
1378
}
1338
1379
}
@@ -1704,16 +1745,23 @@ impl ChannelMonitor {
1704
1745
let mut watch_outputs = Vec :: new ( ) ;
1705
1746
1706
1747
macro_rules! wait_threshold_conf {
1707
- ( $height: expr, $source: expr, $update : expr , $ commitment_tx: expr, $payment_hash: expr) => {
1748
+ ( $height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1708
1749
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 ) ;
1709
- match self . htlc_updated_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1750
+ match self . onchain_events_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1710
1751
hash_map:: Entry :: Occupied ( mut entry) => {
1711
1752
let e = entry. get_mut( ) ;
1712
- e. retain( |ref update| update. 0 != $source) ;
1713
- e. push( ( $source, $update, $payment_hash) ) ;
1753
+ e. retain( |ref event| {
1754
+ match * * event {
1755
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1756
+ return htlc_update. 0 != $source
1757
+ } ,
1758
+ _ => return true
1759
+ }
1760
+ } ) ;
1761
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( $source, $payment_hash) } ) ;
1714
1762
}
1715
1763
hash_map:: Entry :: Vacant ( entry) => {
1716
- entry. insert( vec![ ( $source, $update , $ payment_hash) ] ) ;
1764
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( $source, $payment_hash) } ] ) ;
1717
1765
}
1718
1766
}
1719
1767
}
@@ -1731,7 +1779,7 @@ impl ChannelMonitor {
1731
1779
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1732
1780
if htlc. transaction_output_index . is_none ( ) {
1733
1781
if let & Some ( ref source) = source {
1734
- wait_threshold_conf ! ( height, source. clone( ) , None , "lastest" , htlc. payment_hash. clone( ) ) ;
1782
+ wait_threshold_conf ! ( height, source. clone( ) , "lastest" , htlc. payment_hash. clone( ) ) ;
1735
1783
}
1736
1784
}
1737
1785
}
@@ -1751,7 +1799,7 @@ impl ChannelMonitor {
1751
1799
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1752
1800
if htlc. transaction_output_index . is_none ( ) {
1753
1801
if let & Some ( ref source) = source {
1754
- wait_threshold_conf ! ( height, source. clone( ) , None , "previous" , htlc. payment_hash. clone( ) ) ;
1802
+ wait_threshold_conf ! ( height, source. clone( ) , "previous" , htlc. payment_hash. clone( ) ) ;
1755
1803
}
1756
1804
}
1757
1805
}
@@ -1874,6 +1922,27 @@ impl ChannelMonitor {
1874
1922
if updated. len ( ) > 0 {
1875
1923
htlc_updated. append ( & mut updated) ;
1876
1924
}
1925
+ for inp in & tx. input {
1926
+ if self . our_claim_txn_waiting_first_conf . contains_key ( & inp. previous_output ) {
1927
+ match self . onchain_events_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY ) {
1928
+ hash_map:: Entry :: Occupied ( mut entry) => {
1929
+ let e = entry. get_mut ( ) ;
1930
+ e. retain ( |ref event| {
1931
+ match * * event {
1932
+ OnchainEvent :: Claim { outpoint } => {
1933
+ return outpoint != inp. previous_output
1934
+ } ,
1935
+ _ => return true
1936
+ }
1937
+ } ) ;
1938
+ e. push ( OnchainEvent :: Claim { outpoint : inp. previous_output . clone ( ) } ) ;
1939
+ }
1940
+ hash_map:: Entry :: Vacant ( entry) => {
1941
+ entry. insert ( vec ! [ OnchainEvent :: Claim { outpoint: inp. previous_output. clone( ) } ] ) ;
1942
+ }
1943
+ }
1944
+ }
1945
+ }
1877
1946
}
1878
1947
if let Some ( ref cur_local_tx) = self . current_local_signed_commitment_tx {
1879
1948
if self . would_broadcast_at_height ( height) {
@@ -1902,19 +1971,27 @@ impl ChannelMonitor {
1902
1971
}
1903
1972
}
1904
1973
}
1905
- if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1906
- for update in updates {
1907
- log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1908
- htlc_updated. push ( update) ;
1974
+ if let Some ( events) = self . onchain_events_waiting_threshold_conf . remove ( & height) {
1975
+ for ev in events {
1976
+ match ev {
1977
+ OnchainEvent :: Claim { outpoint } => {
1978
+ } ,
1979
+ OnchainEvent :: HTLCUpdate { htlc_update } => {
1980
+ log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
1981
+ htlc_updated. push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
1982
+ } ,
1983
+ }
1909
1984
}
1910
1985
}
1911
1986
self . last_block_hash = block_hash. clone ( ) ;
1912
1987
( watch_outputs, spendable_outputs, htlc_updated)
1913
1988
}
1914
1989
1915
1990
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash ) {
1916
- if let Some ( _) = self . htlc_updated_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1917
- //We discard htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
1991
+ if let Some ( _) = self . onchain_events_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1992
+ //We may discard:
1993
+ //- htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
1994
+ //- our claim tx on a commitment tx output
1918
1995
}
1919
1996
self . last_block_hash = block_hash. clone ( ) ;
1920
1997
}
@@ -2096,14 +2173,21 @@ impl ChannelMonitor {
2096
2173
htlc_updated. push ( ( source, Some ( payment_preimage) , payment_hash) ) ;
2097
2174
} else {
2098
2175
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 ) ;
2099
- match self . htlc_updated_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2176
+ match self . onchain_events_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2100
2177
hash_map:: Entry :: Occupied ( mut entry) => {
2101
2178
let e = entry. get_mut ( ) ;
2102
- e. retain ( |ref update| update. 0 != source) ;
2103
- e. push ( ( source, None , payment_hash. clone ( ) ) ) ;
2179
+ e. retain ( |ref event| {
2180
+ match * * event {
2181
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
2182
+ return htlc_update. 0 != source
2183
+ } ,
2184
+ _ => return true
2185
+ }
2186
+ } ) ;
2187
+ e. push ( OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ) ;
2104
2188
}
2105
2189
hash_map:: Entry :: Vacant ( entry) => {
2106
- entry. insert ( vec ! [ ( source, None , payment_hash) ] ) ;
2190
+ entry. insert ( vec ! [ OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ] ) ;
2107
2191
}
2108
2192
}
2109
2193
}
@@ -2326,18 +2410,31 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2326
2410
let destination_script = Readable :: read ( reader) ?;
2327
2411
2328
2412
let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2329
- let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2413
+ let mut onchain_events_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2330
2414
for _ in 0 ..waiting_threshold_conf_len {
2331
2415
let height_target = Readable :: read ( reader) ?;
2332
- let updates_len: u64 = Readable :: read ( reader) ?;
2333
- let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2334
- for _ in 0 ..updates_len {
2335
- let htlc_source = Readable :: read ( reader) ?;
2336
- let preimage = Readable :: read ( reader) ?;
2337
- let hash = Readable :: read ( reader) ?;
2338
- updates. push ( ( htlc_source, preimage, hash) ) ;
2416
+ let events_len: u64 = Readable :: read ( reader) ?;
2417
+ let mut events = Vec :: with_capacity ( cmp:: min ( events_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2418
+ for _ in 0 ..events_len {
2419
+ let ev = match <u8 as Readable < R > >:: read ( reader) ? {
2420
+ 0 => {
2421
+ let outpoint = Readable :: read ( reader) ?;
2422
+ OnchainEvent :: Claim {
2423
+ outpoint
2424
+ }
2425
+ } ,
2426
+ 1 => {
2427
+ let htlc_source = Readable :: read ( reader) ?;
2428
+ let hash = Readable :: read ( reader) ?;
2429
+ OnchainEvent :: HTLCUpdate {
2430
+ htlc_update : ( htlc_source, hash)
2431
+ }
2432
+ } ,
2433
+ _ => return Err ( DecodeError :: InvalidValue ) ,
2434
+ } ;
2435
+ events. push ( ev) ;
2339
2436
}
2340
- htlc_updated_waiting_threshold_conf . insert ( height_target, updates ) ;
2437
+ onchain_events_waiting_threshold_conf . insert ( height_target, events ) ;
2341
2438
}
2342
2439
2343
2440
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
@@ -2364,7 +2461,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2364
2461
2365
2462
destination_script,
2366
2463
2367
- htlc_updated_waiting_threshold_conf ,
2464
+ onchain_events_waiting_threshold_conf ,
2368
2465
2369
2466
last_block_hash,
2370
2467
secp_ctx,
0 commit comments