Merge pull request #2876 from TheBlueMatt/2024-02-2863-doc-nits
[rust-lightning] / lightning / src / chain / onchaintx.rs
index 2871abbc22312d5f9e4f31aa5b9ec4fd49ddbf9d..05d59431fc3a815585554eae7ffd5323d72b4112 100644 (file)
@@ -374,13 +374,13 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
                signer.provide_channel_parameters(&channel_parameters);
 
                let pending_claim_requests_len: u64 = Readable::read(reader)?;
-               let mut pending_claim_requests = HashMap::with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
+               let mut pending_claim_requests = hash_map_with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
                for _ in 0..pending_claim_requests_len {
                        pending_claim_requests.insert(Readable::read(reader)?, Readable::read(reader)?);
                }
 
                let claimable_outpoints_len: u64 = Readable::read(reader)?;
-               let mut claimable_outpoints = HashMap::with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
+               let mut claimable_outpoints = hash_map_with_capacity(cmp::min(pending_claim_requests_len as usize, MAX_ALLOC_SIZE / 128));
                for _ in 0..claimable_outpoints_len {
                        let outpoint = Readable::read(reader)?;
                        let ancestor_claim_txid = Readable::read(reader)?;
@@ -445,8 +445,8 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
                        prev_holder_commitment: None,
                        signer,
                        channel_transaction_parameters: channel_parameters,
-                       pending_claim_requests: HashMap::new(),
-                       claimable_outpoints: HashMap::new(),
+                       pending_claim_requests: new_hash_map(),
+                       claimable_outpoints: new_hash_map(),
                        locktimed_packages: BTreeMap::new(),
                        onchain_events_awaiting_threshold_conf: Vec::new(),
                        pending_claim_events: Vec::new(),
@@ -473,14 +473,13 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
        /// feerate changes between blocks, and ensuring reliability if broadcasting fails. We recommend
        /// invoking this every 30 seconds, or lower if running in an environment with spotty
        /// connections, like on mobile.
-       pub(crate) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Deref>(
+       pub(super) fn rebroadcast_pending_claims<B: Deref, F: Deref, L: Logger>(
                &mut self, current_height: u32, broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator<F>,
                logger: &L,
        )
        where
                B::Target: BroadcasterInterface,
                F::Target: FeeEstimator,
-               L::Target: Logger,
        {
                let mut bump_requests = Vec::with_capacity(self.pending_claim_requests.len());
                for (claim_id, request) in self.pending_claim_requests.iter() {
@@ -528,13 +527,11 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
        ///
        /// Panics if there are signing errors, because signing operations in reaction to on-chain
        /// events are not expected to fail, and if they do, we may lose funds.
-       fn generate_claim<F: Deref, L: Deref>(
+       fn generate_claim<F: Deref, L: Logger>(
                &mut self, cur_height: u32, cached_request: &PackageTemplate, force_feerate_bump: bool,
                fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L,
        ) -> Option<(u32, u64, OnchainClaim)>
-       where
-               F::Target: FeeEstimator,
-               L::Target: Logger,
+       where F::Target: FeeEstimator,
        {
                let request_outpoints = cached_request.outpoints();
                if request_outpoints.is_empty() {
@@ -679,6 +676,25 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
                None
        }
 
+       pub fn abandon_claim(&mut self, outpoint: &BitcoinOutPoint) {
+               let claim_id = self.claimable_outpoints.get(outpoint).map(|(claim_id, _)| *claim_id)
+                       .or_else(|| {
+                               self.pending_claim_requests.iter()
+                                       .find(|(_, claim)| claim.outpoints().iter().any(|claim_outpoint| *claim_outpoint == outpoint))
+                                       .map(|(claim_id, _)| *claim_id)
+                       });
+               if let Some(claim_id) = claim_id {
+                       if let Some(claim) = self.pending_claim_requests.remove(&claim_id) {
+                               for outpoint in claim.outpoints() {
+                                       self.claimable_outpoints.remove(outpoint);
+                               }
+                       }
+               } else {
+                       self.locktimed_packages.values_mut().for_each(|claims|
+                               claims.retain(|claim| !claim.outpoints().iter().any(|claim_outpoint| *claim_outpoint == outpoint)));
+               }
+       }
+
        /// Upon channelmonitor.block_connected(..) or upon provision of a preimage on the forward link
        /// for this channel, provide new relevant on-chain transactions and/or new claim requests.
        /// Together with `update_claims_view_from_matched_txn` this used to be named
@@ -688,13 +704,12 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
        /// `conf_height` represents the height at which the request was generated. This
        /// does not need to equal the current blockchain tip height, which should be provided via
        /// `cur_height`, however it must never be higher than `cur_height`.
-       pub(crate) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Deref>(
+       pub(super) fn update_claims_view_from_requests<B: Deref, F: Deref, L: Logger>(
                &mut self, requests: Vec<PackageTemplate>, conf_height: u32, cur_height: u32,
                broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L
        ) where
                B::Target: BroadcasterInterface,
                F::Target: FeeEstimator,
-               L::Target: Logger,
        {
                log_debug!(logger, "Updating claims view at height {} with {} claim requests", cur_height, requests.len());
                let mut preprocessed_requests = Vec::with_capacity(requests.len());
@@ -791,7 +806,9 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
                                                claim_id
                                        },
                                };
-                               debug_assert!(self.pending_claim_requests.get(&claim_id).is_none());
+                               // Because fuzzing can cause hash collisions, we can end up with conflicting claim
+                               // ids here, so we only assert when not fuzzing.
+                               debug_assert!(cfg!(fuzzing) || self.pending_claim_requests.get(&claim_id).is_none());
                                for k in req.outpoints() {
                                        log_info!(logger, "Registering claiming request for {}:{}", k.txid, k.vout);
                                        self.claimable_outpoints.insert(k.clone(), (claim_id, conf_height));
@@ -809,16 +826,15 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
        /// `conf_height` represents the height at which the transactions in `txn_matched` were
        /// confirmed. This does not need to equal the current blockchain tip height, which should be
        /// provided via `cur_height`, however it must never be higher than `cur_height`.
-       pub(crate) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Deref>(
+       pub(super) fn update_claims_view_from_matched_txn<B: Deref, F: Deref, L: Logger>(
                &mut self, txn_matched: &[&Transaction], conf_height: u32, conf_hash: BlockHash,
                cur_height: u32, broadcaster: &B, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L
        ) where
                B::Target: BroadcasterInterface,
                F::Target: FeeEstimator,
-               L::Target: Logger,
        {
                log_debug!(logger, "Updating claims view at height {} with {} matched transactions in block {}", cur_height, txn_matched.len(), conf_height);
-               let mut bump_candidates = HashMap::new();
+               let mut bump_candidates = new_hash_map();
                for tx in txn_matched {
                        // Scan all input to verify is one of the outpoint spent is of interest for us
                        let mut claimed_outputs_material = Vec::new();
@@ -977,16 +993,15 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
                }
        }
 
-       pub(crate) fn transaction_unconfirmed<B: Deref, F: Deref, L: Deref>(
+       pub(super) fn transaction_unconfirmed<B: Deref, F: Deref, L: Logger>(
                &mut self,
                txid: &Txid,
                broadcaster: B,
                fee_estimator: &LowerBoundedFeeEstimator<F>,
-               logger: L,
+               logger: &L,
        ) where
                B::Target: BroadcasterInterface,
                F::Target: FeeEstimator,
-               L::Target: Logger,
        {
                let mut height = None;
                for entry in self.onchain_events_awaiting_threshold_conf.iter() {
@@ -1001,12 +1016,11 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
                }
        }
 
-       pub(crate) fn block_disconnected<B: Deref, F: Deref, L: Deref>(&mut self, height: u32, broadcaster: B, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: L)
+       pub(super) fn block_disconnected<B: Deref, F: Deref, L: Logger>(&mut self, height: u32, broadcaster: B, fee_estimator: &LowerBoundedFeeEstimator<F>, logger: &L)
                where B::Target: BroadcasterInterface,
-                     F::Target: FeeEstimator,
-                                       L::Target: Logger,
+                       F::Target: FeeEstimator,
        {
-               let mut bump_candidates = HashMap::new();
+               let mut bump_candidates = new_hash_map();
                let onchain_events_awaiting_threshold_conf =
                        self.onchain_events_awaiting_threshold_conf.drain(..).collect::<Vec<_>>();
                for entry in onchain_events_awaiting_threshold_conf {
@@ -1034,7 +1048,7 @@ impl<ChannelSigner: WriteableEcdsaChannelSigner> OnchainTxHandler<ChannelSigner>
                        // `height` is the height being disconnected, so our `current_height` is 1 lower.
                        let current_height = height - 1;
                        if let Some((new_timer, new_feerate, bump_claim)) = self.generate_claim(
-                               current_height, &request, true /* force_feerate_bump */, fee_estimator, &&*logger
+                               current_height, &request, true /* force_feerate_bump */, fee_estimator, logger
                        ) {
                                request.set_timer(new_timer);
                                request.set_feerate(new_feerate);