Skip to content

Commit

Permalink
fix(core): fix geth --init temp dir race condition (#2068)
Browse files Browse the repository at this point in the history
* fix(core): fix geth --init temp dir race condition

 * previously, if multiple instances of geth were spawned concurrently,
   only one directory would be used to populate geth's genesis.json.
   this can lead to a race condition where the genesis.json would be
   re-written by a second instance, before the first instance reads the
   genesis.json for populating its db and genesis block with the geth
   --init command. this was possible because directory returned by
   std::env::temp_dir() is often shared
 * fixes the race condition by using tempfile::tempdir(), which creates
   a unique directory per call to tempdir()

* only use tempfile on non-wasm32
  • Loading branch information
Rjected committed Jan 22, 2023
1 parent b8fa524 commit e9a808e
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
4 changes: 3 additions & 1 deletion ethers-core/Cargo.toml
Expand Up @@ -44,8 +44,10 @@ syn = { version = "1.0.107", optional = true }
proc-macro2 = { version = "1.0.50", optional = true }
num_enum = "0.5.7"

[dev-dependencies]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tempfile = { version = "3.3.0", default-features = false }

[dev-dependencies]
serde_json = { version = "1.0.64", default-features = false }
bincode = { version = "1.3.3", default-features = false }
once_cell = { version = "1.17.0" }
Expand Down
12 changes: 10 additions & 2 deletions ethers-core/src/utils/geth.rs
Expand Up @@ -6,13 +6,13 @@ use crate::{
utils::secret_key_to_address,
};
use std::{
env::temp_dir,
fs::{create_dir, File},
io::{BufRead, BufReader},
path::PathBuf,
process::{Child, ChildStderr, Command, Stdio},
time::{Duration, Instant},
};
use tempfile::tempdir;

/// How long we will wait for geth to indicate that it is ready.
const GETH_STARTUP_TIMEOUT_MILLIS: u64 = 10_000;
Expand Down Expand Up @@ -402,7 +402,11 @@ impl Geth {

if let Some(ref genesis) = self.genesis {
// create a temp dir to store the genesis file
let temp_genesis_path = temp_dir().join("genesis.json");
let temp_genesis_dir_path =
tempdir().expect("should be able to create temp dir for genesis init").into_path();

// create a temp dir to store the genesis file
let temp_genesis_path = temp_genesis_dir_path.join("genesis.json");

// create the genesis file
let mut file = File::create(&temp_genesis_path).expect("could not create genesis file");
Expand All @@ -425,6 +429,10 @@ impl Geth {
.expect("failed to spawn geth init")
.wait()
.expect("failed to wait for geth init to exit");

// clean up the temp dir which is now persisted
std::fs::remove_dir_all(temp_genesis_dir_path)
.expect("could not remove genesis temp dir");
}

if let Some(ref data_dir) = self.data_dir {
Expand Down

0 comments on commit e9a808e

Please sign in to comment.