From 79b001793f82ec2c49f36abc2fc2dff49039d5b1 Mon Sep 17 00:00:00 2001 From: grandizzy Date: Tue, 24 Sep 2024 13:24:05 +0300 Subject: [PATCH 1/6] chore: add anvil NodeHandle.fire_shutdown_signal --- crates/anvil/src/lib.rs | 49 +++++++++++++++++------------- crates/anvil/tests/it/anvil_api.rs | 4 +-- crates/anvil/tests/it/gas.rs | 4 +-- crates/anvil/tests/it/proof.rs | 4 +-- crates/anvil/tests/it/traces.rs | 4 +-- 5 files changed, 32 insertions(+), 33 deletions(-) diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index c800131d26bd..ed4735ade7f3 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -253,32 +253,32 @@ pub async fn try_spawn(mut config: NodeConfig) -> io::Result<(EthApi, NodeHandle type IpcTask = JoinHandle<()>; -/// A handle to the spawned node and server tasks +/// A handle to the spawned node and server tasks. /// /// This future will resolve if either the node or server task resolve/fail. pub struct NodeHandle { config: NodeConfig, - /// The address of the running rpc server + /// The address of the running rpc server. addresses: Vec, - /// Join handle for the Node Service + /// Join handle for the Node Service. pub node_service: JoinHandle>, /// Join handles (one per socket) for the Anvil server. pub servers: Vec>>, - // The future that joins the ipc server, if any + /// The future that joins the ipc server, if any. ipc_task: Option, /// A signal that fires the shutdown, fired on drop. _signal: Option, - /// A task manager that can be used to spawn additional tasks + /// A task manager that can be used to spawn additional tasks. task_manager: TaskManager, } impl NodeHandle { - /// The [NodeConfig] the node was launched with + /// The [NodeConfig] the node was launched with. pub fn config(&self) -> &NodeConfig { &self.config } - /// Prints the launch info + /// Prints the launch info. pub(crate) fn print(&self, fork: Option<&ClientFork>) { self.config.print(fork); if !self.config.silent { @@ -296,25 +296,25 @@ impl NodeHandle { } } - /// The address of the launched server + /// The address of the launched server. /// /// **N.B.** this may not necessarily be the same `host + port` as configured in the - /// `NodeConfig`, if port was set to 0, then the OS auto picks an available port + /// `NodeConfig`, if port was set to 0, then the OS auto picks an available port. pub fn socket_address(&self) -> &SocketAddr { &self.addresses[0] } - /// Returns the http endpoint + /// Returns the http endpoint. pub fn http_endpoint(&self) -> String { format!("http://{}", self.socket_address()) } - /// Returns the websocket endpoint + /// Returns the websocket endpoint. pub fn ws_endpoint(&self) -> String { format!("ws://{}", self.socket_address()) } - /// Returns the path of the launched ipc server, if any + /// Returns the path of the launched ipc server, if any. pub fn ipc_path(&self) -> Option { self.config.get_ipc_path() } @@ -334,44 +334,51 @@ impl NodeHandle { ProviderBuilder::new(&self.config.get_ipc_path()?).build().ok() } - /// Signer accounts that can sign messages/transactions from the EVM node + /// Signer accounts that can sign messages/transactions from the EVM node. pub fn dev_accounts(&self) -> impl Iterator + '_ { self.config.signer_accounts.iter().map(|wallet| wallet.address()) } - /// Signer accounts that can sign messages/transactions from the EVM node + /// Signer accounts that can sign messages/transactions from the EVM node. pub fn dev_wallets(&self) -> impl Iterator + '_ { self.config.signer_accounts.iter().cloned() } - /// Accounts that will be initialised with `genesis_balance` in the genesis block + /// Accounts that will be initialised with `genesis_balance` in the genesis block. pub fn genesis_accounts(&self) -> impl Iterator + '_ { self.config.genesis_accounts.iter().map(|w| w.address()) } - /// Native token balance of every genesis account in the genesis block + /// Native token balance of every genesis account in the genesis block. pub fn genesis_balance(&self) -> U256 { self.config.genesis_balance } - /// Default gas price for all txs + /// Default gas price for all txs. pub fn gas_price(&self) -> u128 { self.config.get_gas_price() } - /// Returns the shutdown signal + /// Returns the shutdown signal. pub fn shutdown_signal(&self) -> &Option { &self._signal } - /// Returns mutable access to the shutdown signal + /// Returns mutable access to the shutdown signal. /// - /// This can be used to extract the Signal + /// This can be used to extract the Signal. pub fn shutdown_signal_mut(&mut self) -> &mut Option { &mut self._signal } - /// Returns the task manager that can be used to spawn new tasks + /// Fires shutdown signal. + /// + /// Called by long-running tests to make sure anvil instance is terminated. + pub fn fire_shutdown_signal(&mut self) { + self._signal.take().map(|signal| signal.fire()); + } + + /// Returns the task manager that can be used to spawn new tasks. /// /// ``` /// use anvil::NodeHandle; diff --git a/crates/anvil/tests/it/anvil_api.rs b/crates/anvil/tests/it/anvil_api.rs index 8038023130db..06b896845f33 100644 --- a/crates/anvil/tests/it/anvil_api.rs +++ b/crates/anvil/tests/it/anvil_api.rs @@ -793,7 +793,5 @@ async fn test_reorg() { .await; assert!(res.is_err()); - if let Some(signal) = handle.shutdown_signal_mut().take() { - signal.fire().unwrap(); - } + handle.fire_shutdown_signal(); } diff --git a/crates/anvil/tests/it/gas.rs b/crates/anvil/tests/it/gas.rs index be9f206d730c..6f349c71de0d 100644 --- a/crates/anvil/tests/it/gas.rs +++ b/crates/anvil/tests/it/gas.rs @@ -201,7 +201,5 @@ async fn test_can_use_fee_history() { assert_eq!(latest_fee_history_fee, next_base_fee); } - if let Some(signal) = handle.shutdown_signal_mut().take() { - signal.fire().unwrap(); - } + handle.fire_shutdown_signal(); } diff --git a/crates/anvil/tests/it/proof.rs b/crates/anvil/tests/it/proof.rs index 33c51b2e0b47..470e773eb109 100644 --- a/crates/anvil/tests/it/proof.rs +++ b/crates/anvil/tests/it/proof.rs @@ -131,7 +131,5 @@ async fn can_get_random_account_proofs() { .unwrap_or_else(|_| panic!("Failed to get proof for {acc:?}")); } - if let Some(signal) = handle.shutdown_signal_mut().take() { - signal.fire().unwrap(); - } + handle.fire_shutdown_signal(); } diff --git a/crates/anvil/tests/it/traces.rs b/crates/anvil/tests/it/traces.rs index 9ab3045412c5..f2d68d9e825e 100644 --- a/crates/anvil/tests/it/traces.rs +++ b/crates/anvil/tests/it/traces.rs @@ -860,7 +860,5 @@ async fn test_trace_filter() { let traces = api.trace_filter(tracer).await.unwrap(); assert_eq!(traces.len(), 5); - if let Some(signal) = handle.shutdown_signal_mut().take() { - signal.fire().unwrap(); - } + handle.fire_shutdown_signal(); } From 98873ec74891ab28bc24341ed7275f6662b8a852 Mon Sep 17 00:00:00 2001 From: grandizzy Date: Tue, 24 Sep 2024 13:55:23 +0300 Subject: [PATCH 2/6] Remove DAPP remappings from env vars from cli tests. --- crates/forge/tests/cli/config.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/crates/forge/tests/cli/config.rs b/crates/forge/tests/cli/config.rs index 3d3feba6766b..42a2b5142815 100644 --- a/crates/forge/tests/cli/config.rs +++ b/crates/forge/tests/cli/config.rs @@ -204,18 +204,6 @@ forgetest_init!(can_override_config, |prj, cmd| { Remapping::from(config.remappings[0].clone()).to_string() ); - // env vars work - std::env::remove_var("DAPP_REMAPPINGS"); - std::env::set_var("DAPP_REMAPPINGS", "ds-test/=lib/forge-std/lib/ds-test/from-env/"); - let config = forge_utils::load_config_with_root(Some(prj.root())); - assert_eq!( - format!( - "ds-test/={}/", - prj.root().join("lib/forge-std/lib/ds-test/from-env").to_slash_lossy() - ), - Remapping::from(config.remappings[0].clone()).to_string() - ); - let config = prj.config_from_output(["--remappings", "ds-test/=lib/forge-std/lib/ds-test/from-cli"]); assert_eq!( @@ -234,7 +222,6 @@ forgetest_init!(can_override_config, |prj, cmd| { Remapping::from(config.remappings[0].clone()).to_string() ); - std::env::remove_var("DAPP_REMAPPINGS"); pretty_err(&remappings_txt, fs::remove_file(&remappings_txt)); let expected = profile.into_basic().to_string_pretty().unwrap().trim().to_string(); @@ -506,7 +493,6 @@ forgetest!(can_set_gas_price, |prj, cmd| { // test that we can detect remappings from foundry.toml forgetest_init!(can_detect_lib_foundry_toml, |prj, cmd| { - std::env::remove_var("DAPP_REMAPPINGS"); let config = cmd.config(); let remappings = config.remappings.iter().cloned().map(Remapping::from).collect::>(); similar_asserts::assert_eq!( @@ -518,7 +504,6 @@ forgetest_init!(can_detect_lib_foundry_toml, |prj, cmd| { ); // create a new lib directly in the `lib` folder with a remapping - std::env::remove_var("DAPP_REMAPPINGS"); let mut config = config; config.remappings = vec![Remapping::from_str("nested/=lib/nested").unwrap().into()]; let nested = prj.paths().libraries[0].join("nested-lib"); @@ -526,7 +511,6 @@ forgetest_init!(can_detect_lib_foundry_toml, |prj, cmd| { let toml_file = nested.join("foundry.toml"); pretty_err(&toml_file, fs::write(&toml_file, config.to_string_pretty().unwrap())); - std::env::remove_var("DAPP_REMAPPINGS"); let config = cmd.config(); let remappings = config.remappings.iter().cloned().map(Remapping::from).collect::>(); similar_asserts::assert_eq!( @@ -549,7 +533,6 @@ forgetest_init!(can_detect_lib_foundry_toml, |prj, cmd| { let toml_file = nested.join("foundry.toml"); pretty_err(&toml_file, fs::write(&toml_file, config.to_string_pretty().unwrap())); - std::env::remove_var("DAPP_REMAPPINGS"); let another_config = cmd.config(); let remappings = another_config.remappings.iter().cloned().map(Remapping::from).collect::>(); @@ -569,7 +552,6 @@ forgetest_init!(can_detect_lib_foundry_toml, |prj, cmd| { config.src = "custom-source-dir".into(); pretty_err(&toml_file, fs::write(&toml_file, config.to_string_pretty().unwrap())); - std::env::remove_var("DAPP_REMAPPINGS"); let config = cmd.config(); let remappings = config.remappings.iter().cloned().map(Remapping::from).collect::>(); similar_asserts::assert_eq!( From 654b1590c4cbfb17b78b8a51e79668787bdc0421 Mon Sep 17 00:00:00 2001 From: grandizzy Date: Tue, 24 Sep 2024 14:00:24 +0300 Subject: [PATCH 3/6] Unwrap fire shutdown --- crates/anvil/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index ed4735ade7f3..d35a23336448 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -375,7 +375,7 @@ impl NodeHandle { /// /// Called by long-running tests to make sure anvil instance is terminated. pub fn fire_shutdown_signal(&mut self) { - self._signal.take().map(|signal| signal.fire()); + self._signal.take().map(|signal| signal.fire().unwrap()); } /// Returns the task manager that can be used to spawn new tasks. From e86f1520694d50a0c6784cce2c63cb0ac2b21a0b Mon Sep 17 00:00:00 2001 From: grandizzy Date: Tue, 24 Sep 2024 14:11:54 +0300 Subject: [PATCH 4/6] Fix clippy --- crates/anvil/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index d35a23336448..a960be4a1d2a 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -375,7 +375,9 @@ impl NodeHandle { /// /// Called by long-running tests to make sure anvil instance is terminated. pub fn fire_shutdown_signal(&mut self) { - self._signal.take().map(|signal| signal.fire().unwrap()); + if let Some(signal) = self._signal.take() { + signal.fire().unwrap() + } } /// Returns the task manager that can be used to spawn new tasks. From f66e499919d1424df1876f2994e36648eb373479 Mon Sep 17 00:00:00 2001 From: grandizzy Date: Tue, 24 Sep 2024 14:26:49 +0300 Subject: [PATCH 5/6] track_caller on fire shutdown --- crates/anvil/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index a960be4a1d2a..f23f0fbacc80 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -374,6 +374,7 @@ impl NodeHandle { /// Fires shutdown signal. /// /// Called by long-running tests to make sure anvil instance is terminated. + #[track_caller] pub fn fire_shutdown_signal(&mut self) { if let Some(signal) = self._signal.take() { signal.fire().unwrap() From 277d62c22a3bcc2484825c3d633517d7df8ac0ca Mon Sep 17 00:00:00 2001 From: grandizzy Date: Wed, 25 Sep 2024 09:30:21 +0300 Subject: [PATCH 6/6] fire shutdown signal on drop --- crates/anvil/src/lib.rs | 19 +++++++++---------- crates/anvil/tests/it/anvil_api.rs | 4 +--- crates/anvil/tests/it/gas.rs | 4 +--- crates/anvil/tests/it/proof.rs | 4 +--- crates/anvil/tests/it/traces.rs | 4 +--- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/crates/anvil/src/lib.rs b/crates/anvil/src/lib.rs index bdbe3343d254..ee66caa672ba 100644 --- a/crates/anvil/src/lib.rs +++ b/crates/anvil/src/lib.rs @@ -274,6 +274,15 @@ pub struct NodeHandle { task_manager: TaskManager, } +impl Drop for NodeHandle { + fn drop(&mut self) { + // Fire shutdown signal to make sure anvil instance is terminated. + if let Some(signal) = self._signal.take() { + signal.fire().unwrap() + } + } +} + impl NodeHandle { /// The [NodeConfig] the node was launched with. pub fn config(&self) -> &NodeConfig { @@ -373,16 +382,6 @@ impl NodeHandle { &mut self._signal } - /// Fires shutdown signal. - /// - /// Called by long-running tests to make sure anvil instance is terminated. - #[track_caller] - pub fn fire_shutdown_signal(&mut self) { - if let Some(signal) = self._signal.take() { - signal.fire().unwrap() - } - } - /// Returns the task manager that can be used to spawn new tasks. /// /// ``` diff --git a/crates/anvil/tests/it/anvil_api.rs b/crates/anvil/tests/it/anvil_api.rs index 06b896845f33..0e8001853a95 100644 --- a/crates/anvil/tests/it/anvil_api.rs +++ b/crates/anvil/tests/it/anvil_api.rs @@ -667,7 +667,7 @@ async fn can_remove_pool_transactions() { #[tokio::test(flavor = "multi_thread")] async fn test_reorg() { - let (api, mut handle) = spawn(NodeConfig::test()).await; + let (api, handle) = spawn(NodeConfig::test()).await; let provider = handle.ws_provider(); let accounts = handle.dev_wallets().collect::>(); @@ -792,6 +792,4 @@ async fn test_reorg() { }) .await; assert!(res.is_err()); - - handle.fire_shutdown_signal(); } diff --git a/crates/anvil/tests/it/gas.rs b/crates/anvil/tests/it/gas.rs index eed5387d1309..e80a52462875 100644 --- a/crates/anvil/tests/it/gas.rs +++ b/crates/anvil/tests/it/gas.rs @@ -190,7 +190,7 @@ async fn test_tip_above_fee_cap() { #[tokio::test(flavor = "multi_thread")] async fn test_can_use_fee_history() { let base_fee = 50u128; - let (_api, mut handle) = spawn(NodeConfig::test().with_base_fee(Some(base_fee))).await; + let (_api, handle) = spawn(NodeConfig::test().with_base_fee(Some(base_fee))).await; let provider = handle.http_provider(); for _ in 0..10 { @@ -215,6 +215,4 @@ async fn test_can_use_fee_history() { assert_eq!(latest_block.header.base_fee_per_gas.unwrap(), *latest_fee_history_fee); assert_eq!(latest_fee_history_fee, next_base_fee); } - - handle.fire_shutdown_signal(); } diff --git a/crates/anvil/tests/it/proof.rs b/crates/anvil/tests/it/proof.rs index 470e773eb109..757d36082696 100644 --- a/crates/anvil/tests/it/proof.rs +++ b/crates/anvil/tests/it/proof.rs @@ -122,7 +122,7 @@ async fn test_storage_proof() { #[tokio::test(flavor = "multi_thread")] async fn can_get_random_account_proofs() { - let (api, mut handle) = spawn(NodeConfig::test()).await; + let (api, _handle) = spawn(NodeConfig::test()).await; for acc in std::iter::repeat_with(Address::random).take(10) { let _ = api @@ -130,6 +130,4 @@ async fn can_get_random_account_proofs() { .await .unwrap_or_else(|_| panic!("Failed to get proof for {acc:?}")); } - - handle.fire_shutdown_signal(); } diff --git a/crates/anvil/tests/it/traces.rs b/crates/anvil/tests/it/traces.rs index f2d68d9e825e..aaa2ca298d14 100644 --- a/crates/anvil/tests/it/traces.rs +++ b/crates/anvil/tests/it/traces.rs @@ -722,7 +722,7 @@ async fn test_trace_address_fork2() { #[tokio::test(flavor = "multi_thread")] async fn test_trace_filter() { - let (api, mut handle) = spawn(NodeConfig::test()).await; + let (api, handle) = spawn(NodeConfig::test()).await; let provider = handle.ws_provider(); let accounts = handle.dev_wallets().collect::>(); @@ -859,6 +859,4 @@ async fn test_trace_filter() { let traces = api.trace_filter(tracer).await.unwrap(); assert_eq!(traces.len(), 5); - - handle.fire_shutdown_signal(); }