fix(core): fix geth --init temp dir race condition (#2068)
* 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
This commit is contained in:
parent
b8fa524e8e
commit
e9a808e84f
|
@ -44,8 +44,10 @@ syn = { version = "1.0.107", optional = true }
|
||||||
proc-macro2 = { version = "1.0.50", optional = true }
|
proc-macro2 = { version = "1.0.50", optional = true }
|
||||||
num_enum = "0.5.7"
|
num_enum = "0.5.7"
|
||||||
|
|
||||||
[dev-dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
tempfile = { version = "3.3.0", default-features = false }
|
tempfile = { version = "3.3.0", default-features = false }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
serde_json = { version = "1.0.64", default-features = false }
|
serde_json = { version = "1.0.64", default-features = false }
|
||||||
bincode = { version = "1.3.3", default-features = false }
|
bincode = { version = "1.3.3", default-features = false }
|
||||||
once_cell = { version = "1.17.0" }
|
once_cell = { version = "1.17.0" }
|
||||||
|
|
|
@ -6,13 +6,13 @@ use crate::{
|
||||||
utils::secret_key_to_address,
|
utils::secret_key_to_address,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
env::temp_dir,
|
|
||||||
fs::{create_dir, File},
|
fs::{create_dir, File},
|
||||||
io::{BufRead, BufReader},
|
io::{BufRead, BufReader},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
process::{Child, ChildStderr, Command, Stdio},
|
process::{Child, ChildStderr, Command, Stdio},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
use tempfile::tempdir;
|
||||||
|
|
||||||
/// How long we will wait for geth to indicate that it is ready.
|
/// How long we will wait for geth to indicate that it is ready.
|
||||||
const GETH_STARTUP_TIMEOUT_MILLIS: u64 = 10_000;
|
const GETH_STARTUP_TIMEOUT_MILLIS: u64 = 10_000;
|
||||||
|
@ -402,7 +402,11 @@ impl Geth {
|
||||||
|
|
||||||
if let Some(ref genesis) = self.genesis {
|
if let Some(ref genesis) = self.genesis {
|
||||||
// create a temp dir to store the genesis file
|
// 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
|
// create the genesis file
|
||||||
let mut file = File::create(&temp_genesis_path).expect("could not create genesis file");
|
let mut file = File::create(&temp_genesis_path).expect("could not create genesis file");
|
||||||
|
@ -425,6 +429,10 @@ impl Geth {
|
||||||
.expect("failed to spawn geth init")
|
.expect("failed to spawn geth init")
|
||||||
.wait()
|
.wait()
|
||||||
.expect("failed to wait for geth init to exit");
|
.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 {
|
if let Some(ref data_dir) = self.data_dir {
|
||||||
|
|
Loading…
Reference in New Issue