mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
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:
@ -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 {
|
||||||
|
|||||||
@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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());
|
||||||
|
|||||||
@ -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())?;
|
||||||
|
|
||||||
|
|||||||
@ -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) => {
|
||||||
|
|||||||
@ -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
110
crates/primitives/src/fs.rs
Normal 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))
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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"] }
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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())
|
||||||
},
|
},
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user