builder refactor

This commit is contained in:
Andreas Bigger 2023-03-17 09:51:40 -04:00
parent f679a7c5c8
commit 4279c65cda
3 changed files with 84 additions and 200 deletions

View File

@ -1,21 +1,27 @@
use std::path::PathBuf; use eyre::{eyre, Result};
use config::{Config, Network}; use config::{Config, Network};
use execution::rpc::WsRpc; use execution::rpc::WsRpc;
use crate::{database::FileDB, Client}; use crate::{database::FileDB, Client};
#[cfg(not(target_arch = "wasm32"))]
use std::path::PathBuf;
#[derive(Default)] #[derive(Default)]
pub struct ClientBuilder { pub struct ClientBuilder {
pub network: Option<Network>, pub network: Option<Network>,
pub consensus_rpc: Option<String>, pub consensus_rpc: Option<String>,
pub execution_rpc: Option<String>, pub execution_rpc: Option<String>,
pub checkpoint: Option<Vec<u8>>, pub checkpoint: Option<Vec<u8>>,
#[cfg(not(target_arch = "wasm32"))]
pub rpc_port: Option<u16>, pub rpc_port: Option<u16>,
#[cfg(not(target_arch = "wasm32"))]
pub data_dir: Option<PathBuf>, pub data_dir: Option<PathBuf>,
pub config: Option<Config>, pub config: Option<Config>,
pub fallback: Option<String>, pub fallback: Option<String>,
pub load_external_fallback: bool, pub load_external_fallback: bool,
pub strict_checkpoint_age: bool,
pub with_ws: bool, pub with_ws: bool,
pub with_http: bool, pub with_http: bool,
} }
@ -56,6 +62,7 @@ impl ClientBuilder {
/// client_builder = client_builder.with_ws(false); /// client_builder = client_builder.with_ws(false);
/// assert_eq!(client_builder.with_ws, false); /// assert_eq!(client_builder.with_ws, false);
/// ``` /// ```
#[cfg(not(target_arch = "wasm32"))]
pub fn with_ws(mut self, option: bool) -> Self { pub fn with_ws(mut self, option: bool) -> Self {
self.with_ws = option; self.with_ws = option;
self self
@ -70,16 +77,20 @@ impl ClientBuilder {
/// client_builder = client_builder.with_http(false); /// client_builder = client_builder.with_http(false);
/// assert_eq!(client_builder.with_http, false); /// assert_eq!(client_builder.with_http, false);
/// ``` /// ```
#[cfg(not(target_arch = "wasm32"))]
pub fn with_http(mut self, option: bool) -> Self { pub fn with_http(mut self, option: bool) -> Self {
self.with_http = option; self.with_http = option;
self self
} }
/// Sets the port for the client to serve an RPC server.
#[cfg(not(target_arch = "wasm32"))]
pub fn rpc_port(mut self, port: u16) -> Self { pub fn rpc_port(mut self, port: u16) -> Self {
self.rpc_port = Some(port); self.rpc_port = Some(port);
self self
} }
#[cfg(not(target_arch = "wasm32"))]
pub fn data_dir(mut self, data_dir: PathBuf) -> Self { pub fn data_dir(mut self, data_dir: PathBuf) -> Self {
self.data_dir = Some(data_dir); self.data_dir = Some(data_dir);
self self
@ -100,14 +111,19 @@ impl ClientBuilder {
self self
} }
fn build_base_config(&self) -> eyre::Result<Config> { pub fn strict_checkpoint_age(mut self) -> Self {
self.strict_checkpoint_age = true;
self
}
fn build_config(&self) -> Result<Config> {
let base_config = if let Some(network) = self.network { let base_config = if let Some(network) = self.network {
network.to_base_config() network.to_base_config()
} else { } else {
let config = self let config = self
.config .config
.as_ref() .as_ref()
.ok_or(eyre::eyre!("missing network config"))?; .ok_or(eyre!("missing network config"))?;
config.to_base_config() config.to_base_config()
}; };
@ -127,14 +143,21 @@ impl ClientBuilder {
.clone() .clone()
}); });
let checkpoint = if let Some(checkpoint) = &self.checkpoint { let checkpoint = if let Some(checkpoint) = self.checkpoint {
checkpoint.clone() Some(checkpoint)
} else if let Some(config) = &self.config { } else if let Some(config) = &self.config {
config.checkpoint.clone() config.checkpoint.clone()
} else { } else {
base_config.checkpoint None
}; };
let default_checkpoint = if let Some(config) = &self.config {
config.default_checkpoint.clone()
} else {
base_config.default_checkpoint.clone()
};
#[cfg(not(target_arch = "wasm32"))]
let rpc_port = if self.rpc_port.is_some() { let rpc_port = if self.rpc_port.is_some() {
self.rpc_port self.rpc_port
} else if let Some(config) = &self.config { } else if let Some(config) = &self.config {
@ -143,6 +166,7 @@ impl ClientBuilder {
None None
}; };
#[cfg(not(target_arch = "wasm32"))]
let data_dir = if self.data_dir.is_some() { let data_dir = if self.data_dir.is_some() {
self.data_dir.clone() self.data_dir.clone()
} else if let Some(config) = &self.config { } else if let Some(config) = &self.config {
@ -177,17 +201,27 @@ impl ClientBuilder {
self.with_http self.with_http
}; };
let strict_checkpoint_age = if let Some(config) = &self.config {
self.strict_checkpoint_age || config.strict_checkpoint_age
} else {
self.strict_checkpoint_age
};
Ok(Config { Ok(Config {
consensus_rpc, consensus_rpc,
execution_rpc, execution_rpc,
checkpoint, checkpoint,
default_checkpoint,
#[cfg(not(target_arch = "wasm32"))]
rpc_port, rpc_port,
#[cfg(not(target_arch = "wasm32"))]
data_dir, data_dir,
chain: base_config.chain, chain: base_config.chain,
forks: base_config.forks, forks: base_config.forks,
max_checkpoint_age: base_config.max_checkpoint_age, max_checkpoint_age: base_config.max_checkpoint_age,
fallback, fallback,
load_external_fallback, load_external_fallback,
strict_checkpoint_age,
with_ws, with_ws,
with_http, with_http,
}) })
@ -195,8 +229,8 @@ impl ClientBuilder {
} }
impl ClientBuilder { impl ClientBuilder {
pub fn build(self) -> eyre::Result<Client<FileDB, WsRpc>> { pub fn build(self) -> Result<Client<FileDB, WsRpc>> {
let config = self.build_base_config()?; let config = self.build_config()?;
Client::new(config) Client::new(config)
} }
} }

View File

@ -1,5 +1,4 @@
use std::process::exit; use std::sync::Arc;
use std::sync::{Arc, Mutex};
use config::networks::Network; use config::networks::Network;
use consensus::errors::ConsensusError; use consensus::errors::ConsensusError;
@ -7,20 +6,17 @@ use ethers::prelude::{Address, U256};
use ethers::types::{ use ethers::types::{
FeeHistory, Filter, Log, SyncingStatus, Transaction, TransactionReceipt, H256, FeeHistory, Filter, Log, SyncingStatus, Transaction, TransactionReceipt, H256,
}; };
use eyre::{eyre, Result}; use eyre::Result;
use common::types::BlockTag; use common::types::BlockTag;
use config::{CheckpointFallback, Config}; use config::{CheckpointFallback, Config};
use consensus::{types::Header, ConsensusClient}; use consensus::{types::Header, ConsensusClient};
use execution::rpc::{ExecutionRpc, WsRpc}; use execution::rpc::ExecutionRpc;
use execution::types::{CallOpts, ExecutionBlock}; use execution::types::{CallOpts, ExecutionBlock};
use futures::executor::block_on;
use log::{error, info, warn}; use log::{error, info, warn};
use tokio::spawn; use tokio::spawn;
use tokio::sync::RwLock; use tokio::sync::RwLock;
#[cfg(not(target_arch = "wasm32"))]
use std::path::PathBuf;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use tokio::spawn; use tokio::spawn;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -38,189 +34,10 @@ use crate::node::Node;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use crate::rpc::Rpc; use crate::rpc::Rpc;
#[derive(Default)] pub struct Client<DB: Database, R: ExecutionRpc> {
pub struct ClientBuilder { node: Arc<RwLock<Node<R>>>,
network: Option<Network>,
consensus_rpc: Option<String>,
execution_rpc: Option<String>,
checkpoint: Option<Vec<u8>>,
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
rpc_port: Option<u16>, rpc: Option<Rpc<R>>,
#[cfg(not(target_arch = "wasm32"))]
data_dir: Option<PathBuf>,
config: Option<Config>,
fallback: Option<String>,
load_external_fallback: bool,
strict_checkpoint_age: bool,
}
impl ClientBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn network(mut self, network: Network) -> Self {
self.network = Some(network);
self
}
pub fn consensus_rpc(mut self, consensus_rpc: &str) -> Self {
self.consensus_rpc = Some(consensus_rpc.to_string());
self
}
pub fn execution_rpc(mut self, execution_rpc: &str) -> Self {
self.execution_rpc = Some(execution_rpc.to_string());
self
}
pub fn checkpoint(mut self, checkpoint: &str) -> Self {
let checkpoint = hex::decode(checkpoint.strip_prefix("0x").unwrap_or(checkpoint))
.expect("cannot parse checkpoint");
self.checkpoint = Some(checkpoint);
self
}
#[cfg(not(target_arch = "wasm32"))]
pub fn rpc_port(mut self, port: u16) -> Self {
self.rpc_port = Some(port);
self
}
#[cfg(not(target_arch = "wasm32"))]
pub fn data_dir(mut self, data_dir: PathBuf) -> Self {
self.data_dir = Some(data_dir);
self
}
pub fn config(mut self, config: Config) -> Self {
self.config = Some(config);
self
}
pub fn fallback(mut self, fallback: &str) -> Self {
self.fallback = Some(fallback.to_string());
self
}
pub fn load_external_fallback(mut self) -> Self {
self.load_external_fallback = true;
self
}
pub fn strict_checkpoint_age(mut self) -> Self {
self.strict_checkpoint_age = true;
self
}
pub fn build<DB: Database>(self) -> Result<Client<DB>> {
let base_config = if let Some(network) = self.network {
network.to_base_config()
} else {
let config = self
.config
.as_ref()
.ok_or(eyre!("missing network config"))?;
config.to_base_config()
};
let consensus_rpc = self.consensus_rpc.unwrap_or_else(|| {
self.config
.as_ref()
.expect("missing consensus rpc")
.consensus_rpc
.clone()
});
let execution_rpc = self.execution_rpc.unwrap_or_else(|| {
self.config
.as_ref()
.expect("missing execution rpc")
.execution_rpc
.clone()
});
let checkpoint = if let Some(checkpoint) = self.checkpoint {
Some(checkpoint)
} else if let Some(config) = &self.config {
config.checkpoint.clone()
} else {
None
};
let default_checkpoint = if let Some(config) = &self.config {
config.default_checkpoint.clone()
} else {
base_config.default_checkpoint.clone()
};
#[cfg(not(target_arch = "wasm32"))]
let rpc_port = if self.rpc_port.is_some() {
self.rpc_port
} else if let Some(config) = &self.config {
config.rpc_port
} else {
None
};
#[cfg(not(target_arch = "wasm32"))]
let data_dir = if self.data_dir.is_some() {
self.data_dir
} else if let Some(config) = &self.config {
config.data_dir.clone()
} else {
None
};
let fallback = if self.fallback.is_some() {
self.fallback
} else if let Some(config) = &self.config {
config.fallback.clone()
} else {
None
};
let load_external_fallback = if let Some(config) = &self.config {
self.load_external_fallback || config.load_external_fallback
} else {
self.load_external_fallback
};
let strict_checkpoint_age = if let Some(config) = &self.config {
self.strict_checkpoint_age || config.strict_checkpoint_age
} else {
self.strict_checkpoint_age
};
let config = Config {
consensus_rpc,
execution_rpc,
checkpoint,
default_checkpoint,
#[cfg(not(target_arch = "wasm32"))]
rpc_port,
#[cfg(target_arch = "wasm32")]
rpc_port: None,
#[cfg(not(target_arch = "wasm32"))]
data_dir,
#[cfg(target_arch = "wasm32")]
data_dir: None,
chain: base_config.chain,
forks: base_config.forks,
max_checkpoint_age: base_config.max_checkpoint_age,
fallback,
load_external_fallback,
strict_checkpoint_age,
};
Client::new(config)
}
}
pub struct Client<DB: Database> {
node: Arc<RwLock<Node>>,
#[cfg(not(target_arch = "wasm32"))]
rpc: Option<Rpc>,
db: DB, db: DB,
fallback: Option<String>, fallback: Option<String>,
load_external_fallback: bool, load_external_fallback: bool,
@ -228,8 +45,8 @@ pub struct Client<DB: Database> {
http: bool, http: bool,
} }
impl<DB: Database> Client<DB> { impl<DB: Database, R: ExecutionRpc> Client<DB, R> {
fn new(mut config: Config) -> Result<Self> { pub fn new(mut config: Config) -> Result<Self> {
let db = DB::new(&config)?; let db = DB::new(&config)?;
if config.checkpoint.is_none() { if config.checkpoint.is_none() {
let checkpoint = db.load_checkpoint()?; let checkpoint = db.load_checkpoint()?;

View File

@ -61,7 +61,7 @@ impl ExecutionRpc for WsRpc {
let block = Some(BlockId::from(block)); let block = Some(BlockId::from(block));
let mut raw_tx = Eip1559TransactionRequest::new(); let mut raw_tx = Eip1559TransactionRequest::new();
raw_tx.to = Some(opts.to.into()); raw_tx.to = opts.to.map(Into::into);
raw_tx.from = opts.from; raw_tx.from = opts.from;
raw_tx.value = opts.value; raw_tx.value = opts.value;
raw_tx.gas = Some(opts.gas.unwrap_or(U256::from(100_000_000))); raw_tx.gas = Some(opts.gas.unwrap_or(U256::from(100_000_000)));
@ -159,4 +159,37 @@ impl ExecutionRpc for WsRpc {
.await .await
.map_err(|e| RpcError::new("get_logs", e))?) .map_err(|e| RpcError::new("get_logs", e))?)
} }
async fn chain_id(&self) -> Result<u64> {
Ok(self
.provider
.as_ref()
.ok_or(RpcError::new(
"get_chainid",
eyre::eyre!("Provider not connected!"),
))?
.get_chainid()
.await
.map_err(|e| RpcError::new("chain_id", e))?
.as_u64())
}
async fn get_fee_history(
&self,
block_count: u64,
last_block: u64,
reward_percentiles: &[f64],
) -> Result<FeeHistory> {
let block = BlockNumber::from(last_block);
Ok(self
.provider
.as_ref()
.ok_or(RpcError::new(
"fee_history",
eyre::eyre!("Provider not connected!"),
))?
.fee_history(block_count, block, reward_percentiles)
.await
.map_err(|e| RpcError::new("fee_history", e))?)
}
} }