diff --git a/crates/anvil/core/src/eth/mod.rs b/crates/anvil/core/src/eth/mod.rs index 7a2a153e8ed8..a8a07ba928d5 100644 --- a/crates/anvil/core/src/eth/mod.rs +++ b/crates/anvil/core/src/eth/mod.rs @@ -371,6 +371,17 @@ pub enum EthRequest { )] DropTransaction(B256), + /// Removes transactions from the pool + #[cfg_attr( + feature = "serde", + serde( + rename = "anvil_dropAllTransactions", + alias = "hardhat_dropAllTransactions", + with = "empty_params" + ) + )] + DropAllTransactions(), + /// Reset the fork to a fresh forked state, and optionally update the fork config #[cfg_attr(feature = "serde", serde(rename = "anvil_reset", alias = "hardhat_reset"))] Reset(#[cfg_attr(feature = "serde", serde(default))] Option>>), diff --git a/crates/anvil/src/eth/api.rs b/crates/anvil/src/eth/api.rs index d21ed852feee..1ed664a349b5 100644 --- a/crates/anvil/src/eth/api.rs +++ b/crates/anvil/src/eth/api.rs @@ -296,6 +296,9 @@ impl EthApi { EthRequest::DropTransaction(tx) => { self.anvil_drop_transaction(tx).await.to_rpc_result() } + EthRequest::DropAllTransactions() => { + self.anvil_drop_all_transactions().await.to_rpc_result() + } EthRequest::Reset(fork) => { self.anvil_reset(fork.and_then(|p| p.params)).await.to_rpc_result() } @@ -1572,6 +1575,15 @@ impl EthApi { Ok(self.pool.drop_transaction(tx_hash).map(|tx| tx.hash())) } + /// Removes all transactions from the pool + /// + /// Handler for RPC call: `anvil_dropAllTransactions` + pub async fn anvil_drop_all_transactions(&self) -> Result<()> { + node_info!("anvil_dropAllTransactions"); + self.pool.clear(); + Ok(()) + } + /// Reset the fork to a fresh forked state, and optionally update the fork config. /// /// If `forking` is `None` then this will disable forking entirely. diff --git a/crates/anvil/src/eth/pool/mod.rs b/crates/anvil/src/eth/pool/mod.rs index 34a75c205ade..6748855008c3 100644 --- a/crates/anvil/src/eth/pool/mod.rs +++ b/crates/anvil/src/eth/pool/mod.rs @@ -166,6 +166,12 @@ impl Pool { dropped } + /// Removes all transactions from the pool + pub fn clear(&self) { + let mut pool = self.inner.write(); + pool.clear(); + } + /// notifies all listeners about the transaction fn notify_listener(&self, hash: TxHash) { let mut listener = self.transaction_listener.lock(); @@ -211,6 +217,12 @@ impl PoolInner { self.ready_transactions.get_transactions() } + /// Clears + fn clear(&mut self) { + self.ready_transactions.clear(); + self.pending_transactions.clear(); + } + /// checks both pools for the matching transaction /// /// Returns `None` if the transaction does not exist in the pool diff --git a/crates/anvil/src/eth/pool/transactions.rs b/crates/anvil/src/eth/pool/transactions.rs index a88bc369cd94..9a229001d405 100644 --- a/crates/anvil/src/eth/pool/transactions.rs +++ b/crates/anvil/src/eth/pool/transactions.rs @@ -134,6 +134,13 @@ impl PendingTransactions { self.waiting_queue.is_empty() } + /// Clears internal state + pub fn clear(&mut self) { + self.required_markers.clear(); + self.waiting_markers.clear(); + self.waiting_queue.clear(); + } + /// Returns an iterator over all transactions in the waiting pool pub fn transactions(&self) -> impl Iterator> + '_ { self.waiting_queue.values().map(|tx| tx.transaction.clone()) @@ -377,6 +384,13 @@ impl ReadyTransactions { } } + /// Clears the internal state + pub fn clear(&mut self) { + self.provided_markers.clear(); + self.ready_tx.write().clear(); + self.independent_transactions.clear(); + } + /// Returns true if the transaction is part of the queue. pub fn contains(&self, hash: &TxHash) -> bool { self.ready_tx.read().contains_key(hash)