@@ -252,8 +252,10 @@ pub struct OnchainTxHandler<ChannelSigner: WriteableEcdsaChannelSigner> {
252
252
pub ( crate ) pending_claim_requests : HashMap < PackageID , PackageTemplate > ,
253
253
#[ cfg( not( test) ) ]
254
254
pending_claim_requests : HashMap < PackageID , PackageTemplate > ,
255
+
256
+ // Used to track external events that need to be forwarded to the `ChainMonitor`.
255
257
#[ cfg( anchors) ]
256
- pending_claim_events : HashMap < PackageID , ClaimEvent > ,
258
+ pending_claim_events : Vec < ( PackageID , ClaimEvent ) > ,
257
259
258
260
// Used to link outpoints claimed in a connected block to a pending claim request. The keys
259
261
// represent the outpoints that our `ChannelMonitor` has detected we have keys/scripts to claim.
@@ -430,7 +432,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
430
432
pending_claim_requests,
431
433
onchain_events_awaiting_threshold_conf,
432
434
#[ cfg( anchors) ]
433
- pending_claim_events : HashMap :: new ( ) ,
435
+ pending_claim_events : Vec :: new ( ) ,
434
436
secp_ctx,
435
437
} )
436
438
}
@@ -451,8 +453,7 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
451
453
locktimed_packages : BTreeMap :: new ( ) ,
452
454
onchain_events_awaiting_threshold_conf : Vec :: new ( ) ,
453
455
#[ cfg( anchors) ]
454
- pending_claim_events : HashMap :: new ( ) ,
455
-
456
+ pending_claim_events : Vec :: new ( ) ,
456
457
secp_ctx,
457
458
}
458
459
}
@@ -467,9 +468,9 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
467
468
468
469
#[ cfg( anchors) ]
469
470
pub ( crate ) fn get_and_clear_pending_claim_events ( & mut self ) -> Vec < ClaimEvent > {
470
- let mut ret = HashMap :: new ( ) ;
471
- swap ( & mut ret , & mut self . pending_claim_events ) ;
472
- ret . into_iter ( ) . map ( |( _, event) | event) . collect :: < Vec < _ > > ( )
471
+ let mut events = Vec :: new ( ) ;
472
+ swap ( & mut events , & mut self . pending_claim_events ) ;
473
+ events . into_iter ( ) . map ( |( _, event) | event) . collect ( )
473
474
}
474
475
475
476
/// Lightning security model (i.e being able to redeem/timeout HTLC or penalize counterparty
@@ -713,7 +714,8 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
713
714
package_id
714
715
} ,
715
716
} ;
716
- self . pending_claim_events . insert ( package_id, claim_event) ;
717
+ debug_assert_eq ! ( self . pending_claim_events. iter( ) . filter( |entry| entry. 0 == package_id) . count( ) , 0 ) ;
718
+ self . pending_claim_events . push ( ( package_id, claim_event) ) ;
717
719
package_id
718
720
} ,
719
721
} ;
@@ -798,6 +800,12 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
798
800
//TODO: recompute soonest_timelock to avoid wasting a bit on fees
799
801
if at_least_one_drop {
800
802
bump_candidates. insert ( * package_id, request. clone ( ) ) ;
803
+ // If we have any pending claim events for the request being updated
804
+ // that have yet to be consumed, we'll remove them since they will
805
+ // end up producing an invalid transaction by double spending
806
+ // conflicting input(s).
807
+ #[ cfg( anchors) ]
808
+ self . pending_claim_events . retain ( |entry| entry. 0 != * package_id) ;
801
809
}
802
810
}
803
811
break ; //No need to iterate further, either tx is our or their
@@ -833,9 +841,9 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
833
841
log_debug ! ( logger, "Removing claim tracking for {} due to maturation of claim package {}." ,
834
842
outpoint, log_bytes!( package_id) ) ;
835
843
self . claimable_outpoints . remove ( outpoint) ;
836
- #[ cfg( anchors) ]
837
- self . pending_claim_events . remove ( & package_id) ;
838
844
}
845
+ #[ cfg( anchors) ]
846
+ self . pending_claim_events . retain ( |( id, _) | * id != package_id) ;
839
847
}
840
848
} ,
841
849
OnchainEvent :: ContentiousOutpoint { package } => {
@@ -870,7 +878,12 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
870
878
#[ cfg( anchors) ]
871
879
OnchainClaim :: Event ( claim_event) => {
872
880
log_info ! ( logger, "Yielding RBF-bumped onchain event to spend inputs {:?}" , request. outpoints( ) ) ;
873
- self . pending_claim_events . insert ( * package_id, claim_event) ;
881
+ if let Some ( ( existing_claim_idx, _) ) = self . pending_claim_events . iter ( ) . enumerate ( )
882
+ . find ( |( _, entry) | entry. 0 == * package_id)
883
+ {
884
+ self . pending_claim_events . remove ( existing_claim_idx) ;
885
+ }
886
+ self . pending_claim_events . push ( ( * package_id, claim_event) ) ;
874
887
} ,
875
888
}
876
889
if let Some ( request) = self . pending_claim_requests . get_mut ( package_id) {
@@ -934,7 +947,7 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
934
947
self . onchain_events_awaiting_threshold_conf . push ( entry) ;
935
948
}
936
949
}
937
- for ( ( _package_id, _) , request) in bump_candidates. iter_mut ( ) {
950
+ for ( ( _package_id, _) , ref mut request) in bump_candidates. iter_mut ( ) {
938
951
if let Some ( ( new_timer, new_feerate, bump_claim) ) = self . generate_claim ( height, & request, fee_estimator, & & * logger) {
939
952
request. set_timer ( new_timer) ;
940
953
request. set_feerate ( new_feerate) ;
@@ -946,7 +959,12 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
946
959
#[ cfg( anchors) ]
947
960
OnchainClaim :: Event ( claim_event) => {
948
961
log_info ! ( logger, "Yielding onchain event after reorg to spend inputs {:?}" , request. outpoints( ) ) ;
949
- self . pending_claim_events . insert ( _package_id, claim_event) ;
962
+ if let Some ( ( existing_claim_idx, _) ) = self . pending_claim_events . iter ( ) . enumerate ( )
963
+ . find ( |( _, entry) | entry. 0 == * _package_id)
964
+ {
965
+ self . pending_claim_events . remove ( existing_claim_idx) ;
966
+ }
967
+ self . pending_claim_events . push ( ( * _package_id, claim_event) ) ;
950
968
} ,
951
969
}
952
970
}
0 commit comments