From c24c7b8fca6ec391b96d1be22de8159a06529ea2 Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 12 Dec 2023 22:02:16 +0800 Subject: [PATCH] fix: use PathBuf instead of String to compatible different platforms and non-Unicode sequences in filepath (#65) * fix: use PathBuf and Path for compatibility * fix: use PathBuf as cache path type --- host/src/bin/op-info.rs | 13 +++++++++---- host/src/main.rs | 15 +++++++++++---- host/tests/blocks.rs | 5 ++++- lib/src/host/preflight.rs | 6 +++--- lib/src/host/provider/cached_rpc_provider.rs | 4 +++- lib/src/host/provider/file_provider.rs | 9 +++++---- lib/src/host/provider/mod.rs | 8 ++++---- 7 files changed, 39 insertions(+), 21 deletions(-) diff --git a/host/src/bin/op-info.rs b/host/src/bin/op-info.rs index 8cc77415..c5f392c0 100644 --- a/host/src/bin/op-info.rs +++ b/host/src/bin/op-info.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::path::{Path, PathBuf}; + use alloy_sol_types::{sol, SolInterface}; use anyhow::Result; use clap::Parser; @@ -43,18 +45,21 @@ struct Args { #[clap(short, long, require_equals = true, num_args = 0..=1, default_missing_value = "host/testdata")] /// Use a local directory as a cache for RPC calls. Accepts a custom directory. /// [default: host/testdata] - cache: Option, + cache: Option, #[clap(long, require_equals = true)] /// L2 block number to begin from block_no: u64, } -fn cache_file_path(cache_path: &String, network: &str, block_no: u64, ext: &str) -> String { - format!("{}/{}/{}.{}", cache_path, network, block_no, ext) +fn cache_file_path(cache_path: &Path, network: &str, block_no: u64, ext: &str) -> PathBuf { + cache_path + .join(network) + .join(block_no.to_string()) + .with_extension(ext) } -fn op_cache_path(args: &Args, block_no: u64) -> Option { +fn op_cache_path(args: &Args, block_no: u64) -> Option { args.cache .as_ref() .map(|dir| cache_file_path(dir, "optimism", block_no, "json.gz")) diff --git a/host/src/main.rs b/host/src/main.rs index 13c887a6..f4be9049 100644 --- a/host/src/main.rs +++ b/host/src/main.rs @@ -14,7 +14,11 @@ extern crate core; -use std::{fmt::Debug, time::Instant}; +use std::{ + fmt::Debug, + path::{Path, PathBuf}, + time::Instant, +}; use anyhow::{Context, Result}; use bonsai_sdk::alpha as bonsai_sdk; @@ -47,7 +51,7 @@ struct Args { #[clap(short, long, require_equals = true, num_args = 0..=1, default_missing_value = "host/testdata")] /// Use a local directory as a cache for RPC calls. Accepts a custom directory. /// [default: host/testdata] - cache: Option, + cache: Option, #[clap( short, @@ -81,8 +85,11 @@ struct Args { profile: bool, } -fn cache_file_path(cache_path: &String, network: &String, block_no: u64, ext: &str) -> String { - format!("{}/{}/{}.{}", cache_path, network, block_no, ext) +fn cache_file_path(cache_path: &Path, network: &str, block_no: u64, ext: &str) -> PathBuf { + cache_path + .join(network) + .join(block_no.to_string()) + .with_extension(ext) } #[tokio::main] diff --git a/host/tests/blocks.rs b/host/tests/blocks.rs index 34510f1d..978a3ddd 100644 --- a/host/tests/blocks.rs +++ b/host/tests/blocks.rs @@ -40,7 +40,10 @@ fn block_cli_ethereum(#[files("testdata/ethereum/*.json.gz")] path: PathBuf) { fn empty_blocks(#[files("testdata/ethereum/*.json.gz")] path: PathBuf) { let block_no = u64::from_str(file_prefix(&path)).unwrap(); // Set block cache directory - let rpc_cache = Some(format!("testdata/ethereum/{}.json.gz", block_no)); + let rpc_cache = Some(PathBuf::from(format!( + "testdata/ethereum/{}.json.gz", + block_no + ))); // Fetch all of the preflight data let init = EthereumStrategy::run_preflight(ETH_MAINNET_CHAIN_SPEC.clone(), rpc_cache, None, block_no) diff --git a/lib/src/host/preflight.rs b/lib/src/host/preflight.rs index 2eef73b6..91c1aff1 100644 --- a/lib/src/host/preflight.rs +++ b/lib/src/host/preflight.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::fmt::Debug; +use std::{fmt::Debug, path::PathBuf}; use anyhow::{anyhow, Context, Result}; use ethers_core::types::{ @@ -60,7 +60,7 @@ pub trait Preflight { /// It returns all the data required to build and validate the block. fn run_preflight( chain_spec: ChainSpec, - cache_path: Option, + cache_path: Option, rpc_url: Option, block_no: u64, ) -> Result>; @@ -74,7 +74,7 @@ where { fn run_preflight( chain_spec: ChainSpec, - cache_path: Option, + cache_path: Option, rpc_url: Option, block_no: u64, ) -> Result> { diff --git a/lib/src/host/provider/cached_rpc_provider.rs b/lib/src/host/provider/cached_rpc_provider.rs index 762d74bf..a6a59be3 100644 --- a/lib/src/host/provider/cached_rpc_provider.rs +++ b/lib/src/host/provider/cached_rpc_provider.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::path::PathBuf; + use anyhow::Result; use ethers_core::types::{Block, Bytes, EIP1186ProofResponse, Transaction, H256, U256}; @@ -26,7 +28,7 @@ pub struct CachedRpcProvider { } impl CachedRpcProvider { - pub fn new(cache_path: String, rpc_url: String) -> Result { + pub fn new(cache_path: PathBuf, rpc_url: String) -> Result { let cache = match FileProvider::read_from_file(cache_path.clone()) { Ok(provider) => provider, Err(_) => FileProvider::empty(cache_path), diff --git a/lib/src/host/provider/file_provider.rs b/lib/src/host/provider/file_provider.rs index c927f290..dc7d411e 100644 --- a/lib/src/host/provider/file_provider.rs +++ b/lib/src/host/provider/file_provider.rs @@ -16,6 +16,7 @@ use std::{ collections::HashMap, fs::File, io::{Read, Write}, + path::{Path, PathBuf}, }; use anyhow::{anyhow, Result}; @@ -29,7 +30,7 @@ use super::{AccountQuery, BlockQuery, MutProvider, ProofQuery, Provider, Storage #[derive(Deserialize, Serialize)] pub struct FileProvider { #[serde(skip)] - file_path: String, + file_path: PathBuf, #[serde(skip)] dirty: bool, #[serde_as(as = "Vec<(_, _)>")] @@ -49,7 +50,7 @@ pub struct FileProvider { } impl FileProvider { - pub fn empty(file_path: String) -> Self { + pub fn empty(file_path: PathBuf) -> Self { FileProvider { file_path, dirty: false, @@ -63,7 +64,7 @@ impl FileProvider { } } - pub fn read_from_file(file_path: String) -> Result { + pub fn read_from_file(file_path: PathBuf) -> Result { let mut buf = vec![]; let mut decoder = flate2::read::GzDecoder::new(File::open(&file_path)?); decoder.read_to_end(&mut buf)?; @@ -75,7 +76,7 @@ impl FileProvider { Ok(out) } - pub fn save_to_file(&self, file_path: &String) -> Result<()> { + pub fn save_to_file(&self, file_path: &Path) -> Result<()> { if self.dirty { let mut encoder = flate2::write::GzEncoder::new( File::create(file_path)?, diff --git a/lib/src/host/provider/mod.rs b/lib/src/host/provider/mod.rs index 8500ffa5..9bc6aa29 100644 --- a/lib/src/host/provider/mod.rs +++ b/lib/src/host/provider/mod.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::collections::BTreeSet; +use std::{collections::BTreeSet, path::PathBuf}; use anyhow::{anyhow, Result}; use ethers_core::types::{Block, Bytes, EIP1186ProofResponse, Transaction, H160, H256, U256}; @@ -69,7 +69,7 @@ pub trait MutProvider: Provider { fn insert_storage(&mut self, query: StorageQuery, val: H256); } -pub fn new_file_provider(file_path: String) -> Result> { +pub fn new_file_provider(file_path: PathBuf) -> Result> { let provider = file_provider::FileProvider::read_from_file(file_path)?; Ok(Box::new(provider)) @@ -81,14 +81,14 @@ pub fn new_rpc_provider(rpc_url: String) -> Result> { Ok(Box::new(provider)) } -pub fn new_cached_rpc_provider(cache_path: String, rpc_url: String) -> Result> { +pub fn new_cached_rpc_provider(cache_path: PathBuf, rpc_url: String) -> Result> { let provider = cached_rpc_provider::CachedRpcProvider::new(cache_path, rpc_url)?; Ok(Box::new(provider)) } pub fn new_provider( - cache_path: Option, + cache_path: Option, rpc_url: Option, ) -> Result> { match (cache_path, rpc_url) {