@@ -327,6 +327,22 @@ struct LocalSignedTx {
327
327
htlc_outputs : Vec < ( HTLCOutputInCommitment , Option < ( Signature , Signature ) > , Option < HTLCSource > ) > ,
328
328
}
329
329
330
+ /// Upon discovering of some classes of onchain tx by ChannelMonitor, we may have to take actions on it
331
+ /// once they mature to enough confirmations (HTLC_FAIL_ANTI_REORG_DELAY)
332
+ #[ derive( Clone , PartialEq ) ]
333
+ enum OnchainEvent {
334
+ /// Outpoint under claim process by our own tx, at maturation we remote it from our_claim_txn_waiting_first_conf
335
+ Claim {
336
+ outpoint : BitcoinOutPoint ,
337
+ } ,
338
+ /// HTLC output getting solved by a timeout, at maturation we pass upstream payment source information to solve
339
+ /// inbound HTLC in backward channel. Note, in case of preimage, we pass info to upstream without delay as we can
340
+ /// only win from it, so it's never an OnchainEvent
341
+ HTLCUpdate {
342
+ htlc_update : ( HTLCSource , PaymentHash ) ,
343
+ } ,
344
+ }
345
+
330
346
const SERIALIZATION_VERSION : u8 = 1 ;
331
347
const MIN_SERIALIZATION_VERSION : u8 = 1 ;
332
348
@@ -377,7 +393,8 @@ pub struct ChannelMonitor {
377
393
378
394
destination_script : Script ,
379
395
380
- htlc_updated_waiting_threshold_conf : HashMap < u32 , Vec < ( HTLCSource , Option < PaymentPreimage > , PaymentHash ) > > ,
396
+
397
+ onchain_events_waiting_threshold_conf : HashMap < u32 , Vec < OnchainEvent > > ,
381
398
382
399
// We simply modify last_block_hash in Channel's block_connected so that serialization is
383
400
// consistent but hopefully the users' copy handles block_connected in a consistent way.
@@ -409,7 +426,7 @@ impl PartialEq for ChannelMonitor {
409
426
self . current_local_signed_commitment_tx != other. current_local_signed_commitment_tx ||
410
427
self . payment_preimages != other. payment_preimages ||
411
428
self . destination_script != other. destination_script ||
412
- self . htlc_updated_waiting_threshold_conf != other. htlc_updated_waiting_threshold_conf
429
+ self . onchain_events_waiting_threshold_conf != other. onchain_events_waiting_threshold_conf
413
430
{
414
431
false
415
432
} else {
@@ -459,7 +476,7 @@ impl ChannelMonitor {
459
476
payment_preimages : HashMap :: new ( ) ,
460
477
destination_script : destination_script,
461
478
462
- htlc_updated_waiting_threshold_conf : HashMap :: new ( ) ,
479
+ onchain_events_waiting_threshold_conf : HashMap :: new ( ) ,
463
480
464
481
last_block_hash : Default :: default ( ) ,
465
482
secp_ctx : Secp256k1 :: new ( ) ,
@@ -938,14 +955,22 @@ impl ChannelMonitor {
938
955
self . last_block_hash . write ( writer) ?;
939
956
self . destination_script . write ( writer) ?;
940
957
941
- writer. write_all ( & byte_utils:: be64_to_array ( self . htlc_updated_waiting_threshold_conf . len ( ) as u64 ) ) ?;
942
- for ( ref target, ref updates ) in self . htlc_updated_waiting_threshold_conf . iter ( ) {
958
+ writer. write_all ( & byte_utils:: be64_to_array ( self . onchain_events_waiting_threshold_conf . len ( ) as u64 ) ) ?;
959
+ for ( ref target, ref events ) in self . onchain_events_waiting_threshold_conf . iter ( ) {
943
960
writer. write_all ( & byte_utils:: be32_to_array ( * * target) ) ?;
944
- writer. write_all ( & byte_utils:: be64_to_array ( updates. len ( ) as u64 ) ) ?;
945
- for ref update in updates. iter ( ) {
946
- update. 0 . write ( writer) ?;
947
- update. 1 . write ( writer) ?;
948
- update. 2 . write ( writer) ?;
961
+ writer. write_all ( & byte_utils:: be64_to_array ( events. len ( ) as u64 ) ) ?;
962
+ for ev in events. iter ( ) {
963
+ match * ev {
964
+ OnchainEvent :: Claim { ref outpoint } => {
965
+ writer. write_all ( & [ 0 ; 1 ] ) ?;
966
+ outpoint. write ( writer) ?;
967
+ } ,
968
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
969
+ writer. write_all ( & [ 1 ; 1 ] ) ?;
970
+ htlc_update. 0 . write ( writer) ?;
971
+ htlc_update. 1 . write ( writer) ?;
972
+ }
973
+ }
949
974
}
950
975
}
951
976
@@ -1177,14 +1202,21 @@ impl ChannelMonitor {
1177
1202
for & ( ref htlc, ref source_option) in outpoints. iter( ) {
1178
1203
if let & Some ( ref source) = source_option {
1179
1204
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 ) ;
1180
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1205
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1181
1206
hash_map:: Entry :: Occupied ( mut entry) => {
1182
1207
let e = entry. get_mut( ) ;
1183
- e. retain( |ref update| update. 0 != * * source) ;
1184
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1208
+ e. retain( |ref event| {
1209
+ match * * event {
1210
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1211
+ return htlc_update. 0 != * * source
1212
+ } ,
1213
+ _ => return true
1214
+ }
1215
+ } ) ;
1216
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1185
1217
}
1186
1218
hash_map:: Entry :: Vacant ( entry) => {
1187
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1219
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1188
1220
}
1189
1221
}
1190
1222
}
@@ -1261,14 +1293,21 @@ impl ChannelMonitor {
1261
1293
}
1262
1294
}
1263
1295
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
- match self . htlc_updated_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1296
+ match self . onchain_events_waiting_threshold_conf . entry( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1265
1297
hash_map:: Entry :: Occupied ( mut entry) => {
1266
1298
let e = entry. get_mut( ) ;
1267
- e. retain( |ref update| update. 0 != * * source) ;
1268
- e. push( ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ) ;
1299
+ e. retain( |ref event| {
1300
+ match * * event {
1301
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1302
+ return htlc_update. 0 != * * source
1303
+ } ,
1304
+ _ => return true
1305
+ }
1306
+ } ) ;
1307
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ) ;
1269
1308
}
1270
1309
hash_map:: Entry :: Vacant ( entry) => {
1271
- entry. insert( vec![ ( ( * * source) . clone( ) , None , htlc. payment_hash. clone( ) ) ] ) ;
1310
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( ( * * source) . clone( ) , htlc. payment_hash. clone( ) ) } ] ) ;
1272
1311
}
1273
1312
}
1274
1313
}
@@ -1629,16 +1668,23 @@ impl ChannelMonitor {
1629
1668
let mut watch_outputs = Vec :: new ( ) ;
1630
1669
1631
1670
macro_rules! wait_threshold_conf {
1632
- ( $height: expr, $source: expr, $update : expr , $ commitment_tx: expr, $payment_hash: expr) => {
1671
+ ( $height: expr, $source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1633
1672
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 ) ;
1634
- match self . htlc_updated_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1673
+ match self . onchain_events_waiting_threshold_conf . entry( $height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
1635
1674
hash_map:: Entry :: Occupied ( mut entry) => {
1636
1675
let e = entry. get_mut( ) ;
1637
- e. retain( |ref update| update. 0 != $source) ;
1638
- e. push( ( $source, $update, $payment_hash) ) ;
1676
+ e. retain( |ref event| {
1677
+ match * * event {
1678
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1679
+ return htlc_update. 0 != $source
1680
+ } ,
1681
+ _ => return true
1682
+ }
1683
+ } ) ;
1684
+ e. push( OnchainEvent :: HTLCUpdate { htlc_update: ( $source, $payment_hash) } ) ;
1639
1685
}
1640
1686
hash_map:: Entry :: Vacant ( entry) => {
1641
- entry. insert( vec![ ( $source, $update , $ payment_hash) ] ) ;
1687
+ entry. insert( vec![ OnchainEvent :: HTLCUpdate { htlc_update : ( $source, $payment_hash) } ] ) ;
1642
1688
}
1643
1689
}
1644
1690
}
@@ -1656,7 +1702,7 @@ impl ChannelMonitor {
1656
1702
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1657
1703
if htlc. transaction_output_index . is_none ( ) {
1658
1704
if let & Some ( ref source) = source {
1659
- wait_threshold_conf ! ( height, source. clone( ) , None , "lastest" , htlc. payment_hash. clone( ) ) ;
1705
+ wait_threshold_conf ! ( height, source. clone( ) , "lastest" , htlc. payment_hash. clone( ) ) ;
1660
1706
}
1661
1707
}
1662
1708
}
@@ -1676,7 +1722,7 @@ impl ChannelMonitor {
1676
1722
for & ( ref htlc, _, ref source) in & local_tx. htlc_outputs {
1677
1723
if htlc. transaction_output_index . is_none ( ) {
1678
1724
if let & Some ( ref source) = source {
1679
- wait_threshold_conf ! ( height, source. clone( ) , None , "previous" , htlc. payment_hash. clone( ) ) ;
1725
+ wait_threshold_conf ! ( height, source. clone( ) , "previous" , htlc. payment_hash. clone( ) ) ;
1680
1726
}
1681
1727
}
1682
1728
}
@@ -1827,19 +1873,29 @@ impl ChannelMonitor {
1827
1873
}
1828
1874
}
1829
1875
}
1830
- if let Some ( updates) = self . htlc_updated_waiting_threshold_conf . remove ( & height) {
1831
- for update in updates {
1832
- log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( update. 2 ) . 0 ) ) ;
1833
- htlc_updated. push ( update) ;
1876
+ if let Some ( events) = self . onchain_events_waiting_threshold_conf . remove ( & height) {
1877
+ for ev in events {
1878
+ match ev {
1879
+ OnchainEvent :: Claim { outpoint } => {
1880
+ } ,
1881
+ OnchainEvent :: HTLCUpdate { htlc_update } => {
1882
+ log_trace ! ( self , "HTLC {} failure update has get enough confirmation to be pass upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
1883
+ htlc_updated. push ( ( htlc_update. 0 , None , htlc_update. 1 ) ) ;
1884
+ } ,
1885
+ }
1886
+ }
1887
+ }
1834
1888
}
1835
1889
}
1836
1890
self . last_block_hash = block_hash. clone ( ) ;
1837
1891
( watch_outputs, spendable_outputs, htlc_updated)
1838
1892
}
1839
1893
1840
1894
fn block_disconnected ( & mut self , height : u32 , block_hash : & Sha256dHash ) {
1841
- if let Some ( _) = self . htlc_updated_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1842
- //We discard htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
1895
+ if let Some ( _) = self . onchain_events_waiting_threshold_conf . remove ( & ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) ) {
1896
+ //We may discard:
1897
+ //- htlc update there as failure-trigger tx (revoked commitment tx, non-revoked commitment tx, HTLC-timeout tx) has been disconnected
1898
+ //- our claim tx on a commitment tx output
1843
1899
}
1844
1900
self . last_block_hash = block_hash. clone ( ) ;
1845
1901
}
@@ -2021,14 +2077,21 @@ impl ChannelMonitor {
2021
2077
htlc_updated. push ( ( source, Some ( payment_preimage) , payment_hash) ) ;
2022
2078
} else {
2023
2079
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 ) ;
2024
- match self . htlc_updated_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2080
+ match self . onchain_events_waiting_threshold_conf . entry ( height + HTLC_FAIL_ANTI_REORG_DELAY - 1 ) {
2025
2081
hash_map:: Entry :: Occupied ( mut entry) => {
2026
2082
let e = entry. get_mut ( ) ;
2027
- e. retain ( |ref update| update. 0 != source) ;
2028
- e. push ( ( source, None , payment_hash. clone ( ) ) ) ;
2083
+ e. retain ( |ref event| {
2084
+ match * * event {
2085
+ OnchainEvent :: HTLCUpdate { ref htlc_update } => {
2086
+ return htlc_update. 0 != source
2087
+ } ,
2088
+ _ => return true
2089
+ }
2090
+ } ) ;
2091
+ e. push ( OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ) ;
2029
2092
}
2030
2093
hash_map:: Entry :: Vacant ( entry) => {
2031
- entry. insert ( vec ! [ ( source, None , payment_hash) ] ) ;
2094
+ entry. insert ( vec ! [ OnchainEvent :: HTLCUpdate { htlc_update : ( source, payment_hash) } ] ) ;
2032
2095
}
2033
2096
}
2034
2097
}
@@ -2251,18 +2314,31 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2251
2314
let destination_script = Readable :: read ( reader) ?;
2252
2315
2253
2316
let waiting_threshold_conf_len: u64 = Readable :: read ( reader) ?;
2254
- let mut htlc_updated_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2317
+ let mut onchain_events_waiting_threshold_conf = HashMap :: with_capacity ( cmp:: min ( waiting_threshold_conf_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2255
2318
for _ in 0 ..waiting_threshold_conf_len {
2256
2319
let height_target = Readable :: read ( reader) ?;
2257
- let updates_len: u64 = Readable :: read ( reader) ?;
2258
- let mut updates = Vec :: with_capacity ( cmp:: min ( updates_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2259
- for _ in 0 ..updates_len {
2260
- let htlc_source = Readable :: read ( reader) ?;
2261
- let preimage = Readable :: read ( reader) ?;
2262
- let hash = Readable :: read ( reader) ?;
2263
- updates. push ( ( htlc_source, preimage, hash) ) ;
2320
+ let events_len: u64 = Readable :: read ( reader) ?;
2321
+ let mut events = Vec :: with_capacity ( cmp:: min ( events_len as usize , MAX_ALLOC_SIZE / 128 ) ) ;
2322
+ for _ in 0 ..events_len {
2323
+ let ev = match <u8 as Readable < R > >:: read ( reader) ? {
2324
+ 0 => {
2325
+ let outpoint = Readable :: read ( reader) ?;
2326
+ OnchainEvent :: Claim {
2327
+ outpoint
2328
+ }
2329
+ } ,
2330
+ 1 => {
2331
+ let htlc_source = Readable :: read ( reader) ?;
2332
+ let hash = Readable :: read ( reader) ?;
2333
+ OnchainEvent :: HTLCUpdate {
2334
+ htlc_update : ( htlc_source, hash)
2335
+ }
2336
+ } ,
2337
+ _ => return Err ( DecodeError :: InvalidValue ) ,
2338
+ } ;
2339
+ events. push ( ev) ;
2264
2340
}
2265
- htlc_updated_waiting_threshold_conf . insert ( height_target, updates ) ;
2341
+ onchain_events_waiting_threshold_conf . insert ( height_target, events ) ;
2266
2342
}
2267
2343
2268
2344
Ok ( ( last_block_hash. clone ( ) , ChannelMonitor {
@@ -2289,7 +2365,7 @@ impl<R: ::std::io::Read> ReadableArgs<R, Arc<Logger>> for (Sha256dHash, ChannelM
2289
2365
2290
2366
destination_script,
2291
2367
2292
- htlc_updated_waiting_threshold_conf ,
2368
+ onchain_events_waiting_threshold_conf ,
2293
2369
2294
2370
last_block_hash,
2295
2371
secp_ctx,
0 commit comments