feat(error): add wrappers for std::fs methods to track path for errors (#3367)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Thomas Coratger
2023-07-01 13:49:26 +02:00
committed by GitHub
parent e468e15e9c
commit 2126c01a42
14 changed files with 155 additions and 54 deletions

View File

@ -1,8 +1,8 @@
use hex::encode as hex_encode; use hex::encode as hex_encode;
use reth_network::config::rng_secret_key; use reth_network::config::rng_secret_key;
use reth_primitives::{fs, fs::FsPathError};
use secp256k1::{Error as SecretKeyBaseError, SecretKey}; use secp256k1::{Error as SecretKeyBaseError, SecretKey};
use std::{ use std::{
fs::read_to_string,
io, io,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
@ -14,12 +14,8 @@ use thiserror::Error;
pub enum SecretKeyError { pub enum SecretKeyError {
#[error(transparent)] #[error(transparent)]
SecretKeyDecodeError(#[from] SecretKeyBaseError), SecretKeyDecodeError(#[from] SecretKeyBaseError),
#[error("Failed to create parent directory {dir:?} for secret key: {error}")] #[error(transparent)]
FailedToCreateSecretParentDir { error: io::Error, dir: PathBuf }, SecretKeyFsPathError(#[from] FsPathError),
#[error("Failed to write secret key file {secret_file:?}: {error}")]
FailedToWriteSecretKeyFile { error: io::Error, secret_file: PathBuf },
#[error("Failed to read secret key file {secret_file:?}: {error}")]
FailedToReadSecretKeyFile { error: io::Error, secret_file: PathBuf },
#[error("Failed to access key file {secret_file:?}: {error}")] #[error("Failed to access key file {secret_file:?}: {error}")]
FailedToAccessKeyFile { error: io::Error, secret_file: PathBuf }, FailedToAccessKeyFile { error: io::Error, secret_file: PathBuf },
} }
@ -32,30 +28,19 @@ pub fn get_secret_key(secret_key_path: &Path) -> Result<SecretKey, SecretKeyErro
match exists { match exists {
Ok(true) => { Ok(true) => {
let contents = read_to_string(secret_key_path).map_err(|error| { let contents = fs::read_to_string(secret_key_path)?;
SecretKeyError::FailedToReadSecretKeyFile { Ok((contents.as_str().parse::<SecretKey>())
error, .map_err(SecretKeyError::SecretKeyDecodeError)?)
secret_file: secret_key_path.to_path_buf(),
}
})?;
(contents.as_str().parse::<SecretKey>()).map_err(SecretKeyError::SecretKeyDecodeError)
} }
Ok(false) => { Ok(false) => {
if let Some(dir) = secret_key_path.parent() { if let Some(dir) = secret_key_path.parent() {
// Create parent directory // Create parent directory
std::fs::create_dir_all(dir).map_err(|error| { fs::create_dir_all(dir)?;
SecretKeyError::FailedToCreateSecretParentDir { error, dir: dir.to_path_buf() }
})?;
} }
let secret = rng_secret_key(); let secret = rng_secret_key();
let hex = hex_encode(secret.as_ref()); let hex = hex_encode(secret.as_ref());
std::fs::write(secret_key_path, hex).map_err(|error| { fs::write(secret_key_path, hex)?;
SecretKeyError::FailedToWriteSecretKeyFile {
error,
secret_file: secret_key_path.to_path_buf(),
}
})?;
Ok(secret) Ok(secret)
} }
Err(error) => Err(SecretKeyError::FailedToAccessKeyFile { Err(error) => Err(SecretKeyError::FailedToAccessKeyFile {

View File

@ -1,6 +1,8 @@
//! Clap parser utilities //! Clap parser utilities
use reth_primitives::{AllGenesisFormats, BlockHashOrNumber, ChainSpec, GOERLI, MAINNET, SEPOLIA}; use reth_primitives::{
fs, AllGenesisFormats, BlockHashOrNumber, ChainSpec, GOERLI, MAINNET, SEPOLIA,
};
use reth_revm::primitives::B256 as H256; use reth_revm::primitives::B256 as H256;
use std::{ use std::{
net::{IpAddr, Ipv4Addr, SocketAddr, ToSocketAddrs}, net::{IpAddr, Ipv4Addr, SocketAddr, ToSocketAddrs},
@ -24,7 +26,7 @@ pub fn chain_spec_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Er
"goerli" => GOERLI.clone(), "goerli" => GOERLI.clone(),
"sepolia" => SEPOLIA.clone(), "sepolia" => SEPOLIA.clone(),
_ => { _ => {
let raw = std::fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?; let raw = fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
serde_json::from_str(&raw)? serde_json::from_str(&raw)?
} }
}) })
@ -38,7 +40,7 @@ pub fn genesis_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Error
"goerli" => GOERLI.clone(), "goerli" => GOERLI.clone(),
"sepolia" => SEPOLIA.clone(), "sepolia" => SEPOLIA.clone(),
_ => { _ => {
let raw = std::fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?; let raw = fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
let genesis: AllGenesisFormats = serde_json::from_str(&raw)?; let genesis: AllGenesisFormats = serde_json::from_str(&raw)?;
Arc::new(genesis.into()) Arc::new(genesis.into())
} }

View File

@ -22,7 +22,7 @@ use reth_interfaces::{
}; };
use reth_network::NetworkHandle; use reth_network::NetworkHandle;
use reth_network_api::NetworkInfo; use reth_network_api::NetworkInfo;
use reth_primitives::{stage::StageId, BlockHashOrNumber, BlockNumber, ChainSpec, H256}; use reth_primitives::{fs, stage::StageId, BlockHashOrNumber, BlockNumber, ChainSpec, H256};
use reth_provider::{BlockExecutionWriter, ProviderFactory, StageCheckpointReader}; use reth_provider::{BlockExecutionWriter, ProviderFactory, StageCheckpointReader};
use reth_staged_sync::utils::init::init_genesis; use reth_staged_sync::utils::init::init_genesis;
use reth_stages::{ use reth_stages::{
@ -200,7 +200,7 @@ impl Command {
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain); let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path(); let db_path = data_dir.db_path();
std::fs::create_dir_all(&db_path)?; fs::create_dir_all(&db_path)?;
let db = Arc::new(init_db(db_path)?); let db = Arc::new(init_db(db_path)?);
debug!(target: "reth::cli", chain=%self.chain.chain, genesis=?self.chain.genesis_hash(), "Initializing genesis"); debug!(target: "reth::cli", chain=%self.chain.chain, genesis=?self.chain.genesis_hash(), "Initializing genesis");

View File

@ -6,6 +6,7 @@ use crate::{
use clap::Parser; use clap::Parser;
use reth_db::{cursor::DbCursorRO, init_db, tables, transaction::DbTx}; use reth_db::{cursor::DbCursorRO, init_db, tables, transaction::DbTx};
use reth_primitives::{ use reth_primitives::{
fs,
stage::{StageCheckpoint, StageId}, stage::{StageCheckpoint, StageId},
ChainSpec, ChainSpec,
}; };
@ -64,7 +65,7 @@ impl Command {
// add network name to data dir // add network name to data dir
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain); let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path(); let db_path = data_dir.db_path();
std::fs::create_dir_all(&db_path)?; fs::create_dir_all(&db_path)?;
let db = Arc::new(init_db(db_path)?); let db = Arc::new(init_db(db_path)?);
let factory = ProviderFactory::new(&db, self.chain.clone()); let factory = ProviderFactory::new(&db, self.chain.clone());

View File

@ -6,7 +6,7 @@ use crate::{
}; };
use clap::Parser; use clap::Parser;
use reth_db::{database::Database, open_db, tables, transaction::DbTxMut, DatabaseEnv}; use reth_db::{database::Database, open_db, tables, transaction::DbTxMut, DatabaseEnv};
use reth_primitives::{stage::StageId, ChainSpec}; use reth_primitives::{fs, stage::StageId, ChainSpec};
use reth_staged_sync::utils::init::{insert_genesis_header, insert_genesis_state}; use reth_staged_sync::utils::init::{insert_genesis_header, insert_genesis_state};
use std::sync::Arc; use std::sync::Arc;
use tracing::info; use tracing::info;
@ -50,7 +50,7 @@ impl Command {
// add network name to data dir // add network name to data dir
let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain); let data_dir = self.datadir.unwrap_or_chain_default(self.chain.chain);
let db_path = data_dir.db_path(); let db_path = data_dir.db_path();
std::fs::create_dir_all(&db_path)?; fs::create_dir_all(&db_path)?;
let db = open_db(db_path.as_ref())?; let db = open_db(db_path.as_ref())?;

View File

@ -11,6 +11,7 @@ use reth_db::{
table::{DupSort, Table}, table::{DupSort, Table},
tables, tables,
}; };
use reth_primitives::fs;
use tracing::error; use tracing::error;
const VECTORS_FOLDER: &str = "testdata/micro/db"; const VECTORS_FOLDER: &str = "testdata/micro/db";
@ -19,7 +20,7 @@ const PER_TABLE: usize = 1000;
/// Generates test vectors for specified `tables`. If list is empty, then generate for all tables. /// Generates test vectors for specified `tables`. If list is empty, then generate for all tables.
pub(crate) fn generate_vectors(mut tables: Vec<String>) -> Result<()> { pub(crate) fn generate_vectors(mut tables: Vec<String>) -> Result<()> {
let mut runner = TestRunner::new(ProptestConfig::default()); let mut runner = TestRunner::new(ProptestConfig::default());
std::fs::create_dir_all(VECTORS_FOLDER)?; fs::create_dir_all(VECTORS_FOLDER)?;
macro_rules! generate_vector { macro_rules! generate_vector {
($table_type:ident, $per_table:expr, TABLE) => { ($table_type:ident, $per_table:expr, TABLE) => {

View File

@ -1,6 +1,6 @@
//! Common CLI utility functions. //! Common CLI utility functions.
use eyre::{Result, WrapErr}; use eyre::Result;
use reth_db::{ use reth_db::{
cursor::DbCursorRO, cursor::DbCursorRO,
database::Database, database::Database,
@ -11,7 +11,7 @@ use reth_interfaces::p2p::{
headers::client::{HeadersClient, HeadersRequest}, headers::client::{HeadersClient, HeadersRequest},
priority::Priority, priority::Priority,
}; };
use reth_primitives::{BlockHashOrNumber, ChainSpec, HeadersDirection, SealedHeader}; use reth_primitives::{fs, BlockHashOrNumber, ChainSpec, HeadersDirection, SealedHeader};
use std::{ use std::{
env::VarError, env::VarError,
path::{Path, PathBuf}, path::{Path, PathBuf},
@ -98,7 +98,7 @@ impl<'a, DB: Database> DbTool<'a, DB> {
pub fn drop(&mut self, path: impl AsRef<Path>) -> Result<()> { pub fn drop(&mut self, path: impl AsRef<Path>) -> Result<()> {
let path = path.as_ref(); let path = path.as_ref();
info!(target: "reth::cli", "Dropping database at {:?}", path); info!(target: "reth::cli", "Dropping database at {:?}", path);
std::fs::remove_dir_all(path).wrap_err("Dropping the database failed")?; fs::remove_dir_all(path)?;
Ok(()) Ok(())
} }

110
crates/primitives/src/fs.rs Normal file
View File

@ -0,0 +1,110 @@
//! Wrapper for `std::fs` methods
use std::{
fs, io,
path::{Path, PathBuf},
};
/// Various error variants for `std::fs` operations that serve as an addition to the io::Error which
/// does not provide any information about the path.
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum FsPathError {
/// Provides additional path context for [`std::fs::write`].
#[error("failed to write to {path:?}: {source}")]
Write { source: io::Error, path: PathBuf },
/// Provides additional path context for [`std::fs::read`].
#[error("failed to read from {path:?}: {source}")]
Read { source: io::Error, path: PathBuf },
/// Provides additional path context for [`std::fs::read_link`].
#[error("failed to read from {path:?}: {source}")]
ReadLink { source: io::Error, path: PathBuf },
/// Provides additional path context for [`std::fs::File::create`].
#[error("failed to create file {path:?}: {source}")]
CreateFile { source: io::Error, path: PathBuf },
/// Provides additional path context for [`std::fs::remove_file`].
#[error("failed to remove file {path:?}: {source}")]
RemoveFile { source: io::Error, path: PathBuf },
/// Provides additional path context for [`std::fs::create_dir`].
#[error("failed to create dir {path:?}: {source}")]
CreateDir { source: io::Error, path: PathBuf },
/// Provides additional path context for [`std::fs::remove_dir`].
#[error("failed to remove dir {path:?}: {source}")]
RemoveDir { source: io::Error, path: PathBuf },
/// Provides additional path context for [`std::fs::File::open`].
#[error("failed to open file {path:?}: {source}")]
Open { source: io::Error, path: PathBuf },
/// Provides additional path context for the file whose contents should be parsed as JSON.
#[error("failed to parse json file: {path:?}: {source}")]
ReadJson { source: serde_json::Error, path: PathBuf },
/// Provides additional path context for the new JSON file.
#[error("failed to write to json file: {path:?}: {source}")]
WriteJson { source: serde_json::Error, path: PathBuf },
}
impl FsPathError {
/// Returns the complementary error variant for [`std::fs::write`].
pub fn write(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::Write { source, path: path.into() }
}
/// Returns the complementary error variant for [`std::fs::read`].
pub fn read(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::Read { source, path: path.into() }
}
/// Returns the complementary error variant for [`std::fs::read_link`].
pub fn read_link(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::ReadLink { source, path: path.into() }
}
/// Returns the complementary error variant for [`std::fs::File::create`].
pub fn create_file(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::CreateFile { source, path: path.into() }
}
/// Returns the complementary error variant for [`std::fs::remove_file`].
pub fn remove_file(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::RemoveFile { source, path: path.into() }
}
/// Returns the complementary error variant for [`std::fs::create_dir`].
pub fn create_dir(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::CreateDir { source, path: path.into() }
}
/// Returns the complementary error variant for [`std::fs::remove_dir`].
pub fn remove_dir(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::RemoveDir { source, path: path.into() }
}
/// Returns the complementary error variant for [`std::fs::File::open`].
pub fn open(source: io::Error, path: impl Into<PathBuf>) -> Self {
FsPathError::Open { source, path: path.into() }
}
}
type Result<T> = std::result::Result<T, FsPathError>;
/// Wrapper for `std::fs::read_to_string`
pub fn read_to_string(path: impl AsRef<Path>) -> Result<String> {
let path = path.as_ref();
fs::read_to_string(path).map_err(|err| FsPathError::read(err, path))
}
/// Wrapper for `std::fs::write`
pub fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
let path = path.as_ref();
fs::write(path, contents).map_err(|err| FsPathError::write(err, path))
}
/// Wrapper for `std::fs::remove_dir_all`
pub fn remove_dir_all(path: impl AsRef<Path>) -> Result<()> {
let path = path.as_ref();
fs::remove_dir_all(path).map_err(|err| FsPathError::remove_dir(err, path))
}
/// Wrapper for `std::fs::create_dir_all`
pub fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {
let path = path.as_ref();
fs::create_dir_all(path).map_err(|err| FsPathError::create_dir(err, path))
}

View File

@ -30,6 +30,7 @@ mod compression;
pub mod constants; pub mod constants;
pub mod contract; pub mod contract;
mod forkid; mod forkid;
pub mod fs;
mod genesis; mod genesis;
mod hardfork; mod hardfork;
mod header; mod header;

View File

@ -64,4 +64,4 @@ futures = { workspace = true }
jsonrpsee = { version = "0.18", features = ["client"] } jsonrpsee = { version = "0.18", features = ["client"] }
assert_matches = "1.5.0" assert_matches = "1.5.0"
tempfile = "3.5.0" tempfile = "3.5.0"
reth-interfaces = { workspace = true, features = ["test-utils"] } reth-interfaces = { workspace = true, features = ["test-utils"] }

View File

@ -1,9 +1,10 @@
use hex::encode as hex_encode; use hex::encode as hex_encode;
use jsonwebtoken::{decode, errors::ErrorKind, Algorithm, DecodingKey, Validation}; use jsonwebtoken::{decode, errors::ErrorKind, Algorithm, DecodingKey, Validation};
use rand::Rng; use rand::Rng;
use reth_primitives::{fs, fs::FsPathError};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
path::{Path, PathBuf}, path::Path,
time::{Duration, SystemTime, UNIX_EPOCH}, time::{Duration, SystemTime, UNIX_EPOCH},
}; };
use thiserror::Error; use thiserror::Error;
@ -26,10 +27,8 @@ pub enum JwtError {
MissingOrInvalidAuthorizationHeader, MissingOrInvalidAuthorizationHeader,
#[error("JWT decoding error {0}")] #[error("JWT decoding error {0}")]
JwtDecodingError(String), JwtDecodingError(String),
#[error("IO error occurred while reading {path}: {err}")] #[error(transparent)]
IORead { err: std::io::Error, path: PathBuf }, JwtFsPathError(#[from] FsPathError),
#[error("IO error occurred while writing {path}: {err}")]
IOWrite { err: std::io::Error, path: PathBuf },
#[error("An I/O error occurred: {0}")] #[error("An I/O error occurred: {0}")]
IOError(#[from] std::io::Error), IOError(#[from] std::io::Error),
} }
@ -80,8 +79,7 @@ impl JwtSecret {
/// I/O or secret validation errors might occur during read operations in the form of /// I/O or secret validation errors might occur during read operations in the form of
/// a [`JwtError`]. /// a [`JwtError`].
pub fn from_file(fpath: &Path) -> Result<Self, JwtError> { pub fn from_file(fpath: &Path) -> Result<Self, JwtError> {
let hex = std::fs::read_to_string(fpath) let hex = fs::read_to_string(fpath)?;
.map_err(|err| JwtError::IORead { err, path: fpath.to_path_buf() })?;
let secret = JwtSecret::from_hex(hex)?; let secret = JwtSecret::from_hex(hex)?;
Ok(secret) Ok(secret)
} }
@ -91,14 +89,13 @@ impl JwtSecret {
pub fn try_create(fpath: &Path) -> Result<Self, JwtError> { pub fn try_create(fpath: &Path) -> Result<Self, JwtError> {
if let Some(dir) = fpath.parent() { if let Some(dir) = fpath.parent() {
// Create parent directory // Create parent directory
std::fs::create_dir_all(dir)? fs::create_dir_all(dir)?
} }
let secret = JwtSecret::random(); let secret = JwtSecret::random();
let bytes = &secret.0; let bytes = &secret.0;
let hex = hex::encode(bytes); let hex = hex::encode(bytes);
std::fs::write(fpath, hex) fs::write(fpath, hex)?;
.map_err(|err| JwtError::IOWrite { err, path: fpath.to_path_buf() })?;
Ok(secret) Ok(secret)
} }
} }
@ -204,6 +201,7 @@ mod tests {
use assert_matches::assert_matches; use assert_matches::assert_matches;
use hex::encode as hex_encode; use hex::encode as hex_encode;
use jsonwebtoken::{encode, Algorithm, EncodingKey, Header}; use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
use reth_primitives::fs::FsPathError;
use std::{ use std::{
path::Path, path::Path,
time::{Duration, SystemTime, UNIX_EPOCH}, time::{Duration, SystemTime, UNIX_EPOCH},
@ -375,7 +373,9 @@ mod tests {
fn provided_file_not_exists() { fn provided_file_not_exists() {
let fpath = Path::new("secret3.hex"); let fpath = Path::new("secret3.hex");
let result = JwtSecret::from_file(fpath); let result = JwtSecret::from_file(fpath);
assert_matches!(result, Err(JwtError::IORead {err: _, path}) if path == fpath.to_path_buf()); assert_matches!(result,
Err(JwtError::JwtFsPathError(FsPathError::Read { source: _, path })) if path == fpath.to_path_buf()
);
assert!(!exists(fpath)); assert!(!exists(fpath));
} }
@ -383,7 +383,7 @@ mod tests {
fn provided_file_is_a_directory() { fn provided_file_is_a_directory() {
let dir = tempdir().unwrap(); let dir = tempdir().unwrap();
let result = JwtSecret::from_file(dir.path()); let result = JwtSecret::from_file(dir.path());
assert_matches!(result, Err(JwtError::IORead {err: _, path}) if path == dir.into_path()); assert_matches!(result, Err(JwtError::JwtFsPathError(FsPathError::Read { source: _, path })) if path == dir.into_path());
} }
fn hex(secret: &JwtSecret) -> String { fn hex(secret: &JwtSecret) -> String {

View File

@ -130,7 +130,7 @@ where
b.iter_with_setup( b.iter_with_setup(
|| { || {
// Reset DB // Reset DB
let _ = std::fs::remove_dir_all(bench_db_path); let _ = fs::remove_dir_all(bench_db_path);
( (
input.clone(), input.clone(),
Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap(), Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap(),
@ -156,7 +156,7 @@ where
b.iter_with_setup( b.iter_with_setup(
|| { || {
// Reset DB // Reset DB
let _ = std::fs::remove_dir_all(bench_db_path); let _ = fs::remove_dir_all(bench_db_path);
(input, Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap()) (input, Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap())
}, },
|(input, db)| { |(input, db)| {
@ -227,7 +227,7 @@ where
b.iter_with_setup( b.iter_with_setup(
|| { || {
// Reset DB // Reset DB
let _ = std::fs::remove_dir_all(bench_db_path); let _ = fs::remove_dir_all(bench_db_path);
( (
input.clone(), input.clone(),
Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap(), Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap(),
@ -253,7 +253,7 @@ where
b.iter_with_setup( b.iter_with_setup(
|| { || {
// Reset DB // Reset DB
let _ = std::fs::remove_dir_all(bench_db_path); let _ = fs::remove_dir_all(bench_db_path);
(input, Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap()) (input, Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap())
}, },

View File

@ -84,7 +84,7 @@ where
// Setup phase before each benchmark iteration // Setup phase before each benchmark iteration
let setup = || { let setup = || {
// Reset DB // Reset DB
let _ = std::fs::remove_dir_all(bench_db_path); let _ = fs::remove_dir_all(bench_db_path);
let db = Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap(); let db = Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap();
let mut unsorted_input = unsorted_input.clone(); let mut unsorted_input = unsorted_input.clone();

View File

@ -6,6 +6,7 @@ use reth_db::{
transaction::{DbTx, DbTxMut}, transaction::{DbTx, DbTxMut},
DatabaseEnv, DatabaseEnv,
}; };
use reth_primitives::fs;
use std::{path::Path, sync::Arc}; use std::{path::Path, sync::Arc};
/// Path where the DB is initialized for benchmarks. /// Path where the DB is initialized for benchmarks.
@ -59,7 +60,7 @@ where
T::Value: Default + Clone, T::Value: Default + Clone,
{ {
// Reset DB // Reset DB
let _ = std::fs::remove_dir_all(bench_db_path); let _ = fs::remove_dir_all(bench_db_path);
let db = Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap(); let db = Arc::try_unwrap(create_test_rw_db_with_path(bench_db_path)).unwrap();
{ {