@@ -480,7 +480,7 @@ impl OnchainEventEntry {
480
480
}
481
481
482
482
fn has_reached_confirmation_threshold ( & self , height : u32 ) -> bool {
483
- self . confirmation_threshold ( ) == height
483
+ height >= self . confirmation_threshold ( )
484
484
}
485
485
}
486
486
@@ -1874,9 +1874,9 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
1874
1874
let mut watch_outputs = Vec :: new ( ) ;
1875
1875
1876
1876
macro_rules! wait_threshold_conf {
1877
- ( $height : expr , $ source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1877
+ ( $source: expr, $commitment_tx: expr, $payment_hash: expr) => {
1878
1878
self . onchain_events_waiting_threshold_conf. retain( |ref entry| {
1879
- if entry. height != $ height { return true ; }
1879
+ if entry. height != height { return true ; }
1880
1880
match entry. event {
1881
1881
OnchainEvent :: HTLCUpdate { ref htlc_update } => {
1882
1882
htlc_update. 0 != $source
@@ -1925,7 +1925,7 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
1925
1925
for & ( ref htlc, _, ref source) in & $holder_tx. htlc_outputs {
1926
1926
if htlc. transaction_output_index. is_none( ) {
1927
1927
if let & Some ( ref source) = source {
1928
- wait_threshold_conf!( height , source. clone( ) , "lastest" , htlc. payment_hash. clone( ) ) ;
1928
+ wait_threshold_conf!( source. clone( ) , "lastest" , htlc. payment_hash. clone( ) ) ;
1929
1929
}
1930
1930
}
1931
1931
}
@@ -2065,31 +2065,66 @@ impl<Signer: Sign> ChannelMonitorImpl<Signer> {
2065
2065
claimable_outpoints. append ( & mut new_outpoints) ;
2066
2066
}
2067
2067
2068
+ // Find which on-chain events have reached their confirmation threshold.
2068
2069
let onchain_events_waiting_threshold_conf =
2069
2070
self . onchain_events_waiting_threshold_conf . drain ( ..) . collect :: < Vec < _ > > ( ) ;
2071
+ let mut onchain_events_reaching_threshold_conf = Vec :: new ( ) ;
2070
2072
for entry in onchain_events_waiting_threshold_conf {
2071
2073
if entry. has_reached_confirmation_threshold ( height) {
2072
- match entry. event {
2073
- OnchainEvent :: HTLCUpdate { htlc_update } => {
2074
- log_trace ! ( logger, "HTLC {} failure update has got enough confirmations to be passed upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
2075
- self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
2076
- payment_hash : htlc_update. 1 ,
2077
- payment_preimage : None ,
2078
- source : htlc_update. 0 ,
2079
- } ) ) ;
2080
- } ,
2081
- OnchainEvent :: MaturingOutput { descriptor } => {
2082
- log_trace ! ( logger, "Descriptor {} has got enough confirmations to be passed upstream" , log_spendable!( descriptor) ) ;
2083
- self . pending_events . push ( Event :: SpendableOutputs {
2084
- outputs : vec ! [ descriptor]
2085
- } ) ;
2086
- }
2087
- }
2074
+ onchain_events_reaching_threshold_conf. push ( entry) ;
2088
2075
} else {
2089
2076
self . onchain_events_waiting_threshold_conf . push ( entry) ;
2090
2077
}
2091
2078
}
2092
2079
2080
+ // Used to check for duplicate HTLC resolutions.
2081
+ #[ cfg( debug_assertions) ]
2082
+ let unmatured_htlcs: Vec < _ > = self . onchain_events_waiting_threshold_conf
2083
+ . iter ( )
2084
+ . filter_map ( |entry| match & entry. event {
2085
+ OnchainEvent :: HTLCUpdate { htlc_update } => Some ( htlc_update. 0 . clone ( ) ) ,
2086
+ OnchainEvent :: MaturingOutput { .. } => None ,
2087
+ } )
2088
+ . collect ( ) ;
2089
+ #[ cfg( debug_assertions) ]
2090
+ let mut matured_htlcs = Vec :: new ( ) ;
2091
+
2092
+ // Produce actionable events from on-chain events having reached their threshold.
2093
+ for entry in onchain_events_reaching_threshold_conf. drain ( ..) {
2094
+ match entry. event {
2095
+ OnchainEvent :: HTLCUpdate { htlc_update } => {
2096
+ // Check for duplicate HTLC resolutions.
2097
+ #[ cfg( debug_assertions) ]
2098
+ {
2099
+ debug_assert ! (
2100
+ unmatured_htlcs. iter( ) . find( |& htlc| htlc == & htlc_update. 0 ) . is_none( ) ,
2101
+ "An unmature HTLC transaction conflicts with a maturing one; failed to \
2102
+ call block_disconnected for a block containing the conflicting \
2103
+ transaction.") ;
2104
+ debug_assert ! (
2105
+ matured_htlcs. iter( ) . find( |& htlc| htlc == & htlc_update. 0 ) . is_none( ) ,
2106
+ "A matured HTLC transaction conflicts with a maturing one; failed to \
2107
+ call block_disconnected for a block containing the conflicting \
2108
+ transaction.") ;
2109
+ matured_htlcs. push ( htlc_update. 0 . clone ( ) ) ;
2110
+ }
2111
+
2112
+ log_trace ! ( logger, "HTLC {} failure update has got enough confirmations to be passed upstream" , log_bytes!( ( htlc_update. 1 ) . 0 ) ) ;
2113
+ self . pending_monitor_events . push ( MonitorEvent :: HTLCEvent ( HTLCUpdate {
2114
+ payment_hash : htlc_update. 1 ,
2115
+ payment_preimage : None ,
2116
+ source : htlc_update. 0 ,
2117
+ } ) ) ;
2118
+ } ,
2119
+ OnchainEvent :: MaturingOutput { descriptor } => {
2120
+ log_trace ! ( logger, "Descriptor {} has got enough confirmations to be passed upstream" , log_spendable!( descriptor) ) ;
2121
+ self . pending_events . push ( Event :: SpendableOutputs {
2122
+ outputs : vec ! [ descriptor]
2123
+ } ) ;
2124
+ }
2125
+ }
2126
+ }
2127
+
2093
2128
self . onchain_tx_handler . update_claims_view ( & txn_matched, claimable_outpoints, Some ( height) , & & * broadcaster, & & * fee_estimator, & & * logger) ;
2094
2129
self . last_block_hash = block_hash;
2095
2130
0 commit comments