Put ChainsSpecs in Arc<> (#3075)

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
This commit is contained in:
Waylon Jepsen
2023-06-09 11:58:11 -06:00
committed by GitHub
parent 1ff26dd2fd
commit 6ef3e12fac
9 changed files with 141 additions and 128 deletions

View File

@ -19,7 +19,7 @@ pub fn parse_duration_from_secs(arg: &str) -> eyre::Result<Duration, std::num::P
/// Clap value parser for [ChainSpec]s that takes either a built-in chainspec or the path
/// to a custom one.
pub fn chain_spec_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Error> {
Ok(Arc::new(match s {
Ok(match s {
"mainnet" => MAINNET.clone(),
"goerli" => GOERLI.clone(),
"sepolia" => SEPOLIA.clone(),
@ -27,22 +27,25 @@ pub fn chain_spec_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Er
let raw = std::fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
serde_json::from_str(&raw)?
}
}))
})
}
/// Clap value parser for [ChainSpec]s that takes either a built-in genesis format or the path
/// to a custom one.
pub fn genesis_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Error> {
Ok(Arc::new(match s {
Ok(match s {
"mainnet" => MAINNET.clone(),
"goerli" => GOERLI.clone(),
"sepolia" => SEPOLIA.clone(),
_ => {
let raw = std::fs::read_to_string(PathBuf::from(shellexpand::full(s)?.into_owned()))?;
let genesis: AllGenesisFormats = serde_json::from_str(&raw)?;
genesis.into()
match genesis {
AllGenesisFormats::Reth(chain_spec) => Arc::new(chain_spec),
_ => return Err(eyre::eyre!("Unexpected genesis format")),
}
}
}))
})
}
/// Parse [BlockHashOrNumber]

View File

@ -7,7 +7,7 @@ use reth_db::{
use reth_primitives::{stage::StageCheckpoint, MAINNET};
use reth_provider::Transaction;
use reth_stages::{stages::ExecutionStage, Stage, UnwindInput};
use std::{ops::DerefMut, path::PathBuf, sync::Arc};
use std::{ops::DerefMut, path::PathBuf};
use tracing::info;
pub(crate) async fn dump_execution_stage<DB: Database>(
@ -95,8 +95,7 @@ async fn unwind_and_copy<DB: Database>(
) -> eyre::Result<()> {
let mut unwind_tx = Transaction::new(db_tool.db)?;
let mut exec_stage =
ExecutionStage::new_with_factory(reth_revm::Factory::new(Arc::new(MAINNET.clone())));
let mut exec_stage = ExecutionStage::new_with_factory(reth_revm::Factory::new(MAINNET.clone()));
exec_stage
.unwind(
@ -129,8 +128,7 @@ async fn dry_run(
info!(target: "reth::cli", "Executing stage. [dry-run]");
let mut tx = Transaction::new(&output_db)?;
let mut exec_stage =
ExecutionStage::new_with_factory(reth_revm::Factory::new(Arc::new(MAINNET.clone())));
let mut exec_stage = ExecutionStage::new_with_factory(reth_revm::Factory::new(MAINNET.clone()));
exec_stage
.execute(

View File

@ -11,7 +11,7 @@ use reth_stages::{
},
Stage, UnwindInput,
};
use std::{ops::DerefMut, path::PathBuf, sync::Arc};
use std::{ops::DerefMut, path::PathBuf};
use tracing::info;
pub(crate) async fn dump_merkle_stage<DB: Database>(
@ -65,7 +65,7 @@ async fn unwind_and_copy<DB: Database>(
// Bring Plainstate to TO (hashing stage execution requires it)
let mut exec_stage = ExecutionStage::new(
reth_revm::Factory::new(Arc::new(MAINNET.clone())),
reth_revm::Factory::new(MAINNET.clone()),
ExecutionStageThresholds { max_blocks: Some(u64::MAX), max_changes: None },
);

View File

@ -160,7 +160,7 @@ impl NetworkConfigBuilder {
listener_addr: None,
peers_config: None,
sessions_config: None,
chain_spec: Arc::new(MAINNET.clone()),
chain_spec: MAINNET.clone(),
network_mode: Default::default(),
executor: None,
hello_message: None,
@ -456,11 +456,10 @@ mod tests {
#[test]
fn test_network_fork_filter_default() {
let mut chain_spec = MAINNET.clone();
let mut chain_spec = Arc::clone(&MAINNET);
// remove any `next` fields we would have by removing all hardforks
chain_spec.hardforks = BTreeMap::new();
let chain_spec = Arc::new(chain_spec);
Arc::make_mut(&mut chain_spec).hardforks = BTreeMap::new();
// check that the forkid is initialized with the genesis and no other forks
let genesis_fork_hash = ForkHash::from(chain_spec.genesis_hash());

View File

@ -10,112 +10,124 @@ use ethers_core::utils::Genesis as EthersGenesis;
use hex_literal::hex;
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap};
use std::{
collections::{BTreeMap, HashMap},
sync::Arc,
};
/// The Ethereum mainnet spec
pub static MAINNET: Lazy<ChainSpec> = Lazy::new(|| ChainSpec {
chain: Chain::mainnet(),
genesis: serde_json::from_str(include_str!("../../res/genesis/mainnet.json"))
.expect("Can't deserialize Mainnet genesis json"),
genesis_hash: Some(H256(hex!(
"d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
))),
// <https://etherscan.io/block/15537394>
paris_block_and_final_difficulty: Some((
15537394,
U256::from(58_750_003_716_598_352_816_469u128),
)),
fork_timestamps: ForkTimestamps::default().shanghai(1681338455),
hardforks: BTreeMap::from([
(Hardfork::Frontier, ForkCondition::Block(0)),
(Hardfork::Homestead, ForkCondition::Block(1150000)),
(Hardfork::Dao, ForkCondition::Block(1920000)),
(Hardfork::Tangerine, ForkCondition::Block(2463000)),
(Hardfork::SpuriousDragon, ForkCondition::Block(2675000)),
(Hardfork::Byzantium, ForkCondition::Block(4370000)),
(Hardfork::Constantinople, ForkCondition::Block(7280000)),
(Hardfork::Petersburg, ForkCondition::Block(7280000)),
(Hardfork::Istanbul, ForkCondition::Block(9069000)),
(Hardfork::MuirGlacier, ForkCondition::Block(9200000)),
(Hardfork::Berlin, ForkCondition::Block(12244000)),
(Hardfork::London, ForkCondition::Block(12965000)),
(Hardfork::ArrowGlacier, ForkCondition::Block(13773000)),
(Hardfork::GrayGlacier, ForkCondition::Block(15050000)),
(
Hardfork::Paris,
ForkCondition::TTD {
fork_block: None,
total_difficulty: U256::from(58_750_000_000_000_000_000_000_u128),
},
),
(Hardfork::Shanghai, ForkCondition::Timestamp(1681338455)),
]),
pub static MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
ChainSpec {
chain: Chain::mainnet(),
genesis: serde_json::from_str(include_str!("../../res/genesis/mainnet.json"))
.expect("Can't deserialize Mainnet genesis json"),
genesis_hash: Some(H256(hex!(
"d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3"
))),
// <https://etherscan.io/block/15537394>
paris_block_and_final_difficulty: Some((
15537394,
U256::from(58_750_003_716_598_352_816_469u128),
)),
fork_timestamps: ForkTimestamps::default().shanghai(1681338455),
hardforks: BTreeMap::from([
(Hardfork::Frontier, ForkCondition::Block(0)),
(Hardfork::Homestead, ForkCondition::Block(1150000)),
(Hardfork::Dao, ForkCondition::Block(1920000)),
(Hardfork::Tangerine, ForkCondition::Block(2463000)),
(Hardfork::SpuriousDragon, ForkCondition::Block(2675000)),
(Hardfork::Byzantium, ForkCondition::Block(4370000)),
(Hardfork::Constantinople, ForkCondition::Block(7280000)),
(Hardfork::Petersburg, ForkCondition::Block(7280000)),
(Hardfork::Istanbul, ForkCondition::Block(9069000)),
(Hardfork::MuirGlacier, ForkCondition::Block(9200000)),
(Hardfork::Berlin, ForkCondition::Block(12244000)),
(Hardfork::London, ForkCondition::Block(12965000)),
(Hardfork::ArrowGlacier, ForkCondition::Block(13773000)),
(Hardfork::GrayGlacier, ForkCondition::Block(15050000)),
(
Hardfork::Paris,
ForkCondition::TTD {
fork_block: None,
total_difficulty: U256::from(58_750_000_000_000_000_000_000_u128),
},
),
(Hardfork::Shanghai, ForkCondition::Timestamp(1681338455)),
]),
}
.into()
});
/// The Goerli spec
pub static GOERLI: Lazy<ChainSpec> = Lazy::new(|| ChainSpec {
chain: Chain::goerli(),
genesis: serde_json::from_str(include_str!("../../res/genesis/goerli.json"))
.expect("Can't deserialize Goerli genesis json"),
genesis_hash: Some(H256(hex!(
"bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a"
))),
// <https://goerli.etherscan.io/block/7382818>
paris_block_and_final_difficulty: Some((7382818, U256::from(10_790_000))),
fork_timestamps: ForkTimestamps::default().shanghai(1678832736),
hardforks: BTreeMap::from([
(Hardfork::Frontier, ForkCondition::Block(0)),
(Hardfork::Homestead, ForkCondition::Block(0)),
(Hardfork::Dao, ForkCondition::Block(0)),
(Hardfork::Tangerine, ForkCondition::Block(0)),
(Hardfork::SpuriousDragon, ForkCondition::Block(0)),
(Hardfork::Byzantium, ForkCondition::Block(0)),
(Hardfork::Constantinople, ForkCondition::Block(0)),
(Hardfork::Petersburg, ForkCondition::Block(0)),
(Hardfork::Istanbul, ForkCondition::Block(1561651)),
(Hardfork::Berlin, ForkCondition::Block(4460644)),
(Hardfork::London, ForkCondition::Block(5062605)),
(
Hardfork::Paris,
ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(10_790_000) },
),
(Hardfork::Shanghai, ForkCondition::Timestamp(1678832736)),
]),
pub static GOERLI: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
ChainSpec {
chain: Chain::goerli(),
genesis: serde_json::from_str(include_str!("../../res/genesis/goerli.json"))
.expect("Can't deserialize Goerli genesis json"),
genesis_hash: Some(H256(hex!(
"bf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a"
))),
// <https://goerli.etherscan.io/block/7382818>
paris_block_and_final_difficulty: Some((7382818, U256::from(10_790_000))),
fork_timestamps: ForkTimestamps::default().shanghai(1678832736),
hardforks: BTreeMap::from([
(Hardfork::Frontier, ForkCondition::Block(0)),
(Hardfork::Homestead, ForkCondition::Block(0)),
(Hardfork::Dao, ForkCondition::Block(0)),
(Hardfork::Tangerine, ForkCondition::Block(0)),
(Hardfork::SpuriousDragon, ForkCondition::Block(0)),
(Hardfork::Byzantium, ForkCondition::Block(0)),
(Hardfork::Constantinople, ForkCondition::Block(0)),
(Hardfork::Petersburg, ForkCondition::Block(0)),
(Hardfork::Istanbul, ForkCondition::Block(1561651)),
(Hardfork::Berlin, ForkCondition::Block(4460644)),
(Hardfork::London, ForkCondition::Block(5062605)),
(
Hardfork::Paris,
ForkCondition::TTD { fork_block: None, total_difficulty: U256::from(10_790_000) },
),
(Hardfork::Shanghai, ForkCondition::Timestamp(1678832736)),
]),
}
.into()
});
/// The Sepolia spec
pub static SEPOLIA: Lazy<ChainSpec> = Lazy::new(|| ChainSpec {
chain: Chain::sepolia(),
genesis: serde_json::from_str(include_str!("../../res/genesis/sepolia.json"))
.expect("Can't deserialize Sepolia genesis json"),
genesis_hash: Some(H256(hex!(
"25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9"
))),
// <https://sepolia.etherscan.io/block/1450409>
paris_block_and_final_difficulty: Some((1450409, U256::from(17_000_018_015_853_232u128))),
fork_timestamps: ForkTimestamps::default().shanghai(1677557088),
hardforks: BTreeMap::from([
(Hardfork::Frontier, ForkCondition::Block(0)),
(Hardfork::Homestead, ForkCondition::Block(0)),
(Hardfork::Dao, ForkCondition::Block(0)),
(Hardfork::Tangerine, ForkCondition::Block(0)),
(Hardfork::SpuriousDragon, ForkCondition::Block(0)),
(Hardfork::Byzantium, ForkCondition::Block(0)),
(Hardfork::Constantinople, ForkCondition::Block(0)),
(Hardfork::Petersburg, ForkCondition::Block(0)),
(Hardfork::Istanbul, ForkCondition::Block(0)),
(Hardfork::MuirGlacier, ForkCondition::Block(0)),
(Hardfork::Berlin, ForkCondition::Block(0)),
(Hardfork::London, ForkCondition::Block(0)),
(
Hardfork::Paris,
ForkCondition::TTD {
fork_block: Some(1735371),
total_difficulty: U256::from(17_000_000_000_000_000u64),
},
),
(Hardfork::Shanghai, ForkCondition::Timestamp(1677557088)),
]),
pub static SEPOLIA: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
ChainSpec {
chain: Chain::sepolia(),
genesis: serde_json::from_str(include_str!("../../res/genesis/sepolia.json"))
.expect("Can't deserialize Sepolia genesis json"),
genesis_hash: Some(H256(hex!(
"25a5cc106eea7138acab33231d7160d69cb777ee0c2c553fcddf5138993e6dd9"
))),
// <https://sepolia.etherscan.io/block/1450409>
paris_block_and_final_difficulty: Some((1450409, U256::from(17_000_018_015_853_232u128))),
fork_timestamps: ForkTimestamps::default().shanghai(1677557088),
hardforks: BTreeMap::from([
(Hardfork::Frontier, ForkCondition::Block(0)),
(Hardfork::Homestead, ForkCondition::Block(0)),
(Hardfork::Dao, ForkCondition::Block(0)),
(Hardfork::Tangerine, ForkCondition::Block(0)),
(Hardfork::SpuriousDragon, ForkCondition::Block(0)),
(Hardfork::Byzantium, ForkCondition::Block(0)),
(Hardfork::Constantinople, ForkCondition::Block(0)),
(Hardfork::Petersburg, ForkCondition::Block(0)),
(Hardfork::Istanbul, ForkCondition::Block(0)),
(Hardfork::MuirGlacier, ForkCondition::Block(0)),
(Hardfork::Berlin, ForkCondition::Block(0)),
(Hardfork::London, ForkCondition::Block(0)),
(
Hardfork::Paris,
ForkCondition::TTD {
fork_block: Some(1735371),
total_difficulty: U256::from(17_000_000_000_000_000u64),
},
),
(Hardfork::Shanghai, ForkCondition::Timestamp(1677557088)),
]),
}
.into()
});
/// An Ethereum chain specification.
@ -416,9 +428,10 @@ impl From<EthersGenesis> for AllGenesisFormats {
}
}
impl From<ChainSpec> for AllGenesisFormats {
fn from(genesis: ChainSpec) -> Self {
Self::Reth(genesis)
impl From<Arc<ChainSpec>> for AllGenesisFormats {
fn from(mut genesis: Arc<ChainSpec>) -> Self {
let cloned_genesis = Arc::make_mut(&mut genesis).clone();
Self::Reth(cloned_genesis)
}
}
@ -574,8 +587,8 @@ impl ChainSpecBuilder {
}
}
impl From<&ChainSpec> for ChainSpecBuilder {
fn from(value: &ChainSpec) -> Self {
impl From<&Arc<ChainSpec>> for ChainSpecBuilder {
fn from(value: &Arc<ChainSpec>) -> Self {
Self {
chain: Some(value.chain),
genesis: Some(value.genesis.clone()),

View File

@ -30,7 +30,7 @@ pub async fn launch_auth(secret: JwtSecret) -> AuthServerHandle {
let beacon_engine_handle = BeaconConsensusEngineHandle::new(tx);
let engine_api = EngineApi::new(
NoopProvider::default(),
Arc::new(MAINNET.clone()),
MAINNET.clone(),
beacon_engine_handle,
spawn_test_payload_service().into(),
);

View File

@ -443,7 +443,7 @@ mod tests {
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver};
fn setup_engine_api() -> (EngineApiTestHandle, EngineApi<Arc<MockEthProvider>>) {
let chain_spec = Arc::new(MAINNET.clone());
let chain_spec: Arc<ChainSpec> = MAINNET.clone();
let client = Arc::new(MockEthProvider::default());
let payload_store = spawn_test_payload_service();
let (to_engine, engine_rx) = unbounded_channel();

View File

@ -168,7 +168,7 @@ mod tests {
#[test]
fn success_init_genesis_mainnet() {
let db = create_test_rw_db();
let genesis_hash = init_genesis(db, Arc::new(MAINNET.clone())).unwrap();
let genesis_hash = init_genesis(db, MAINNET.clone()).unwrap();
// actual, expected
assert_eq!(genesis_hash, MAINNET_GENESIS);
@ -177,7 +177,7 @@ mod tests {
#[test]
fn success_init_genesis_goerli() {
let db = create_test_rw_db();
let genesis_hash = init_genesis(db, Arc::new(GOERLI.clone())).unwrap();
let genesis_hash = init_genesis(db, GOERLI.clone()).unwrap();
// actual, expected
assert_eq!(genesis_hash, GOERLI_GENESIS);
@ -186,7 +186,7 @@ mod tests {
#[test]
fn success_init_genesis_sepolia() {
let db = create_test_rw_db();
let genesis_hash = init_genesis(db, Arc::new(SEPOLIA.clone())).unwrap();
let genesis_hash = init_genesis(db, SEPOLIA.clone()).unwrap();
// actual, expected
assert_eq!(genesis_hash, SEPOLIA_GENESIS);
@ -195,10 +195,10 @@ mod tests {
#[test]
fn fail_init_inconsistent_db() {
let db = create_test_rw_db();
init_genesis(db.clone(), Arc::new(SEPOLIA.clone())).unwrap();
init_genesis(db.clone(), SEPOLIA.clone()).unwrap();
// Try to init db with a different genesis block
let genesis_hash = init_genesis(db, Arc::new(MAINNET.clone()));
let genesis_hash = init_genesis(db, MAINNET.clone());
assert_eq!(
genesis_hash.unwrap_err(),

View File

@ -1458,7 +1458,7 @@ mod test {
tables,
};
use reth_primitives::{ChainSpecBuilder, IntegerList, H160, MAINNET, U256};
use std::{ops::DerefMut, sync::Arc};
use std::ops::DerefMut;
#[test]
fn insert_block_and_hashes_get_take() {
@ -1535,7 +1535,7 @@ mod test {
// Check that transactions map onto blocks correctly.
{
let provider = ShareableDatabase::new(tx.db, Arc::new(MAINNET.clone()));
let provider = ShareableDatabase::new(tx.db, MAINNET.clone());
assert_eq!(
provider.transaction_block(0).unwrap(),
Some(1),