mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor: phase out ether genesis in primitives (#2311)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -3,17 +3,13 @@ use crate::{
|
||||
forkid::ForkFilterKey,
|
||||
header::Head,
|
||||
proofs::genesis_state_root,
|
||||
BlockNumber, Chain, ForkFilter, ForkHash, ForkId, Genesis, GenesisAccount, Hardfork, Header,
|
||||
SealedHeader, H160, H256, U256,
|
||||
BlockNumber, Chain, ForkFilter, ForkHash, ForkId, Genesis, Hardfork, Header, SealedHeader,
|
||||
H256, U256,
|
||||
};
|
||||
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},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{collections::BTreeMap, sync::Arc};
|
||||
|
||||
/// The Ethereum mainnet spec
|
||||
pub static MAINNET: Lazy<Arc<ChainSpec>> = Lazy::new(|| {
|
||||
@ -316,25 +312,8 @@ impl ChainSpec {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<EthersGenesis> for ChainSpec {
|
||||
fn from(genesis: EthersGenesis) -> Self {
|
||||
let alloc = genesis
|
||||
.alloc
|
||||
.iter()
|
||||
.map(|(addr, account)| (addr.0.into(), account.clone().into()))
|
||||
.collect::<HashMap<H160, GenesisAccount>>();
|
||||
|
||||
let genesis_block = Genesis {
|
||||
nonce: genesis.nonce.as_u64(),
|
||||
timestamp: genesis.timestamp.as_u64(),
|
||||
gas_limit: genesis.gas_limit.as_u64(),
|
||||
difficulty: genesis.difficulty.into(),
|
||||
mix_hash: genesis.mix_hash.0.into(),
|
||||
coinbase: genesis.coinbase.0.into(),
|
||||
extra_data: genesis.extra_data.0.into(),
|
||||
alloc,
|
||||
};
|
||||
|
||||
impl From<Genesis> for ChainSpec {
|
||||
fn from(genesis: Genesis) -> Self {
|
||||
// Block-based hardforks
|
||||
let hardfork_opts = vec![
|
||||
(Hardfork::Homestead, genesis.config.homestead_block),
|
||||
@ -361,7 +340,7 @@ impl From<EthersGenesis> for ChainSpec {
|
||||
hardforks.insert(
|
||||
Hardfork::Paris,
|
||||
ForkCondition::TTD {
|
||||
total_difficulty: ttd.into(),
|
||||
total_difficulty: ttd,
|
||||
fork_block: genesis.config.merge_netsplit_block,
|
||||
},
|
||||
);
|
||||
@ -379,7 +358,7 @@ impl From<EthersGenesis> for ChainSpec {
|
||||
|
||||
Self {
|
||||
chain: genesis.config.chain_id.into(),
|
||||
genesis: genesis_block,
|
||||
genesis,
|
||||
genesis_hash: None,
|
||||
fork_timestamps: ForkTimestamps::from_hardforks(&hardforks),
|
||||
hardforks,
|
||||
@ -417,21 +396,26 @@ impl ForkTimestamps {
|
||||
#[serde(untagged)]
|
||||
pub enum AllGenesisFormats {
|
||||
/// The geth genesis format
|
||||
Geth(EthersGenesis),
|
||||
Geth(Genesis),
|
||||
/// The reth genesis format
|
||||
Reth(ChainSpec),
|
||||
}
|
||||
|
||||
impl From<EthersGenesis> for AllGenesisFormats {
|
||||
fn from(genesis: EthersGenesis) -> Self {
|
||||
impl From<Genesis> for AllGenesisFormats {
|
||||
fn from(genesis: Genesis) -> Self {
|
||||
Self::Geth(genesis)
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
fn from(genesis: Arc<ChainSpec>) -> Self {
|
||||
Arc::try_unwrap(genesis).unwrap_or_else(|arc| (*arc).clone()).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1195,7 +1179,7 @@ mod tests {
|
||||
}
|
||||
"#;
|
||||
|
||||
let genesis: ethers_core::utils::Genesis = serde_json::from_str(geth_genesis).unwrap();
|
||||
let genesis: Genesis = serde_json::from_str(geth_genesis).unwrap();
|
||||
let chainspec = ChainSpec::from(genesis);
|
||||
|
||||
// assert a bunch of hardforks that should be set
|
||||
@ -1334,6 +1318,8 @@ mod tests {
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let _genesis = serde_json::from_str::<Genesis>(hive_json).unwrap();
|
||||
let genesis = serde_json::from_str::<AllGenesisFormats>(hive_json).unwrap();
|
||||
let chainspec: ChainSpec = genesis.into();
|
||||
assert_eq!(chainspec.genesis_hash, None);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,7 +5,7 @@ use serde::{
|
||||
};
|
||||
use std::{fmt, str::FromStr};
|
||||
|
||||
/// Wrapper around primitive U256 type to handle edge cases of json parser
|
||||
/// Wrapper around primitive U256 type that also supports deserializing numbers
|
||||
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub struct JsonU256(pub U256);
|
||||
|
||||
@ -90,6 +90,15 @@ where
|
||||
Ok(num.into())
|
||||
}
|
||||
|
||||
/// Supports parsing `U256` numbers as strings via [JsonU256]
|
||||
pub fn deserialize_json_u256_opt<'de, D>(deserializer: D) -> Result<Option<U256>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let num = Option::<JsonU256>::deserialize(deserializer)?;
|
||||
Ok(num.map(Into::into))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::JsonU256;
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
//! Various serde utilities
|
||||
|
||||
mod storage_key;
|
||||
mod storage;
|
||||
|
||||
use serde::Serializer;
|
||||
pub use storage_key::*;
|
||||
pub use storage::*;
|
||||
|
||||
mod jsonu256;
|
||||
use crate::H256;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use crate::{H256, U256};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Write;
|
||||
use crate::{Bytes, H256, U256};
|
||||
use serde::{Deserialize, Deserializer, Serialize};
|
||||
use std::{collections::HashMap, fmt::Write};
|
||||
|
||||
/// A storage key type that can be serialized to and from a hex string up to 32 bytes. Used for
|
||||
/// `eth_getStorageAt` and `eth_getProof` RPCs.
|
||||
@ -53,3 +53,50 @@ impl From<JsonStorageKey> for String {
|
||||
hex
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a Bytes value into a H256, accepting inputs that are less than 32 bytes long. These
|
||||
/// inputs will be left padded with zeros.
|
||||
pub fn from_bytes_to_h256<'de, D>(bytes: Bytes) -> Result<H256, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
if bytes.0.len() > 32 {
|
||||
return Err(serde::de::Error::custom("input too long to be a H256"))
|
||||
}
|
||||
|
||||
// left pad with zeros to 32 bytes
|
||||
let mut padded = [0u8; 32];
|
||||
padded[32 - bytes.0.len()..].copy_from_slice(&bytes.0);
|
||||
|
||||
// then convert to H256 without a panic
|
||||
Ok(H256::from_slice(&padded))
|
||||
}
|
||||
|
||||
/// Deserializes the input into an Option<HashMap<H256, H256>>, using [from_bytes_to_h256] which
|
||||
/// allows cropped values:
|
||||
///
|
||||
/// ```json
|
||||
/// {
|
||||
/// "0x0000000000000000000000000000000000000000000000000000000000000001": "0x22"
|
||||
/// }
|
||||
/// ```
|
||||
pub fn deserialize_storage_map<'de, D>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<HashMap<H256, H256>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let map = Option::<HashMap<Bytes, Bytes>>::deserialize(deserializer)?;
|
||||
match map {
|
||||
Some(mut map) => {
|
||||
let mut res_map = HashMap::with_capacity(map.len());
|
||||
for (k, v) in map.drain() {
|
||||
let k_deserialized = from_bytes_to_h256::<'de, D>(k)?;
|
||||
let v_deserialized = from_bytes_to_h256::<'de, D>(v)?;
|
||||
res_map.insert(k_deserialized, v_deserialized);
|
||||
}
|
||||
Ok(Some(res_map))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user