From e6ca25ae04febd78df045c12dedf838ccdba5f92 Mon Sep 17 00:00:00 2001 From: Randy Grok Date: Fri, 6 Mar 2026 23:05:24 +0100 Subject: [PATCH 1/2] init commit --- Cargo.lock | 1 + bin/ev-reth/src/main.rs | 4 +- crates/node/Cargo.toml | 1 + crates/node/src/args.rs | 8 +- crates/node/src/builder.rs | 7 +- crates/node/src/executor.rs | 31 +- crates/node/src/hardfork.rs | 467 +++++++++++++++++++++++++++++ crates/node/src/lib.rs | 3 + crates/node/src/node.rs | 14 +- crates/node/src/payload_service.rs | 6 +- crates/tests/src/common.rs | 5 +- 11 files changed, 522 insertions(+), 25 deletions(-) create mode 100644 crates/node/src/hardfork.rs diff --git a/Cargo.lock b/Cargo.lock index 318aaf1f..2ff4e2b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2927,6 +2927,7 @@ dependencies = [ "reth-tracing", "reth-transaction-pool", "reth-trie-db", + "revm", "serde", "serde_json", "tempfile", diff --git a/bin/ev-reth/src/main.rs b/bin/ev-reth/src/main.rs index e2d9ac9b..b26e4286 100644 --- a/bin/ev-reth/src/main.rs +++ b/bin/ev-reth/src/main.rs @@ -48,10 +48,10 @@ fn main() { } if let Err(err) = - Cli::::parse().run(|builder, _evolve_args| async move { + Cli::::parse().run(|builder, evolve_args| async move { log_startup(); let handle = builder - .node(EvolveNode::new()) + .node(EvolveNode::new(evolve_args.eden_hardfork_height)) .extend_rpc_modules(move |ctx| { // Build custom txpool RPC with config + optional CLI/env override let evolve_cfg = EvolveConfig::default(); diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 635ec38c..6933c20c 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -45,6 +45,7 @@ reth-rpc-api.workspace = true reth-rpc-engine-api.workspace = true reth-engine-primitives.workspace = true reth-ethereum-primitives.workspace = true +revm.workspace = true # Alloy dependencies alloy-rpc-types.workspace = true diff --git a/crates/node/src/args.rs b/crates/node/src/args.rs index 65f45a2d..fcb913c3 100644 --- a/crates/node/src/args.rs +++ b/crates/node/src/args.rs @@ -1,5 +1,9 @@ use clap::Args; -/// Evolve CLI arguments (currently empty; reserved for future toggles). +/// Evolve CLI arguments. #[derive(Debug, Clone, Default, Args)] -pub struct EvolveArgs {} +pub struct EvolveArgs { + /// Block height at which the Eden WTIA storage hardfork activates. + #[arg(long)] + pub eden_hardfork_height: Option, +} diff --git a/crates/node/src/builder.rs b/crates/node/src/builder.rs index c29c3d6c..320c083e 100644 --- a/crates/node/src/builder.rs +++ b/crates/node/src/builder.rs @@ -1,8 +1,6 @@ use crate::config::EvolvePayloadBuilderConfig; use alloy_consensus::transaction::Transaction; -use alloy_evm::eth::EthEvmFactory; use alloy_primitives::Address; -use ev_revm::EvEvmFactory; use evolve_ev_reth::EvolvePayloadAttributes; use reth_chainspec::{ChainSpec, ChainSpecProvider}; use reth_errors::RethError; @@ -10,7 +8,6 @@ use reth_evm::{ execute::{BlockBuilder, BlockBuilderOutcome}, ConfigureEvm, NextBlockEnvAttributes, }; -use reth_evm_ethereum::EthEvmConfig; use reth_payload_builder_primitives::PayloadBuilderError; use reth_primitives::{transaction::SignedTransaction, Header, SealedBlock, SealedHeader}; use reth_provider::{HeaderProvider, StateProviderFactory}; @@ -18,7 +15,9 @@ use reth_revm::{database::StateProviderDatabase, State}; use std::sync::Arc; use tracing::{debug, info}; -type EvolveEthEvmConfig = EthEvmConfig>; +use crate::hardfork::EdenEvmConfig; + +type EvolveEthEvmConfig = EdenEvmConfig; /// Payload builder for Evolve Reth node #[derive(Debug)] diff --git a/crates/node/src/executor.rs b/crates/node/src/executor.rs index 5c136b9d..aaaaa85c 100644 --- a/crates/node/src/executor.rs +++ b/crates/node/src/executor.rs @@ -18,9 +18,9 @@ use reth_ethereum_forks::Hardforks; use reth_node_builder::PayloadBuilderConfig; use tracing::info; -use crate::{config::EvolvePayloadBuilderConfig, EvolveNode}; +use crate::{config::EvolvePayloadBuilderConfig, hardfork::EdenEvmConfig, EvolveNode}; -/// Type alias for the EV-aware EVM config we install into the node. +/// Type alias for the EV-aware EVM config (without Eden hardfork wrapper). pub type EvolveEvmConfig = EthEvmConfig>; /// Builds the EV-aware EVM configuration by wrapping the default config with the EV handler. @@ -88,18 +88,35 @@ where } /// Thin wrapper so we can plug the EV executor into the node components builder. -#[derive(Debug, Default, Clone, Copy)] -#[non_exhaustive] -pub struct EvolveExecutorBuilder; +#[derive(Debug, Clone, Copy)] +pub struct EvolveExecutorBuilder { + eden_hardfork_height: Option, +} + +impl EvolveExecutorBuilder { + /// Creates a new executor builder with the given hardfork height. + pub const fn new(eden_hardfork_height: Option) -> Self { + Self { + eden_hardfork_height, + } + } +} + +impl Default for EvolveExecutorBuilder { + fn default() -> Self { + Self::new(None) + } +} impl RethExecutorBuilder for EvolveExecutorBuilder where Node: FullNodeTypes, ChainSpec: Hardforks + EthExecutorSpec + EthereumHardforks, { - type EVM = EvolveEvmConfig; + type EVM = EdenEvmConfig; async fn build_evm(self, ctx: &BuilderContext) -> eyre::Result { - build_evm_config(ctx) + let inner = build_evm_config(ctx)?; + Ok(EdenEvmConfig::new(inner, self.eden_hardfork_height)) } } diff --git a/crates/node/src/hardfork.rs b/crates/node/src/hardfork.rs new file mode 100644 index 00000000..7c593167 --- /dev/null +++ b/crates/node/src/hardfork.rs @@ -0,0 +1,467 @@ +use alloy_consensus::Header; +use alloy_evm::{ + block::{BlockExecutorFactory, BlockExecutorFor, ExecutableTx}, + Database as EvmDatabase, + eth::EthBlockExecutionCtx, + Evm, EvmFactory, +}; +use alloy_primitives::{address, Address, U256}; +use alloy_rpc_types::engine::ExecutionData; +use reth_evm::{ + execute::BlockExecutionError, ConfigureEngineEvm, ConfigureEvm, EvmEnv, EvmEnvFor, + ExecutableTxIterator, ExecutionCtxFor, NextBlockEnvAttributes, +}; +use reth_evm_ethereum::EthBlockAssembler; +use reth_execution_types::BlockExecutionResult; +use reth_primitives_traits::{SealedBlock, SealedHeader}; +use reth_revm::{ + database_interface::{Database, DatabaseCommit}, + inspector::Inspector, + state::{Account, AccountStatus, EvmStorageSlot}, + State, +}; +use revm::context::result::ResultAndState; +use tracing::info; + +use crate::executor::EvolveEvmConfig; + +pub const WTIA_ADDRESS: Address = address!("00000000000000000000000000000000Ce1e571A"); + +pub const NAME_SLOT: U256 = U256::ZERO; +pub const SYMBOL_SLOT: U256 = U256::from_limbs([1, 0, 0, 0]); +pub const DECIMALS_SLOT: U256 = U256::from_limbs([2, 0, 0, 0]); + +pub const NAME_VALUE: U256 = U256::from_be_bytes([ + 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x20, + 0x54, 0x49, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, +]); + +pub const SYMBOL_VALUE: U256 = U256::from_be_bytes([ + 0x57, 0x54, 0x49, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, +]); + +pub const DECIMALS_VALUE: U256 = U256::from_limbs([18, 0, 0, 0]); + +pub fn maybe_apply_eden_hardfork( + db: &mut DB, + block_number: U256, + hardfork_height: Option, +) -> Result<(), BlockExecutionError> { + if let Some(h) = hardfork_height { + if block_number == U256::from(h) { + apply_eden_storage_changes(db)?; + } + } + Ok(()) +} + +pub fn apply_eden_storage_changes( + db: &mut DB, +) -> Result<(), BlockExecutionError> { + use alloy_primitives::map::HashMap; + + let info = db + .basic(WTIA_ADDRESS) + .map_err(|_| BlockExecutionError::msg("failed to load WTIA account"))? + .unwrap_or_default(); + + let storage = HashMap::from_iter([ + (NAME_SLOT, EvmStorageSlot::new_changed(U256::ZERO, NAME_VALUE, 0)), + (SYMBOL_SLOT, EvmStorageSlot::new_changed(U256::ZERO, SYMBOL_VALUE, 0)), + (DECIMALS_SLOT, EvmStorageSlot::new_changed(U256::ZERO, DECIMALS_VALUE, 0)), + ]); + + let account = Account { + info, + transaction_id: 0, + storage, + status: AccountStatus::Touched, + }; + + db.commit(HashMap::from_iter([(WTIA_ADDRESS, account)])); + + info!( + target: "ev-reth::hardfork", + address = ?WTIA_ADDRESS, + "Applied Eden WTIA storage hardfork" + ); + + Ok(()) +} + +#[derive(Debug)] +pub struct EdenBlockExecutor { + inner: E, + hardfork_height: Option, +} + +impl alloy_evm::block::BlockExecutor for EdenBlockExecutor +where + E: alloy_evm::block::BlockExecutor, + E::Evm: Evm, + ::DB: Database + DatabaseCommit, +{ + type Transaction = E::Transaction; + type Receipt = E::Receipt; + type Evm = E::Evm; + + fn apply_pre_execution_changes(&mut self) -> Result<(), BlockExecutionError> { + self.inner.apply_pre_execution_changes() + } + + fn execute_transaction_without_commit( + &mut self, + tx: impl ExecutableTx, + ) -> Result< + ResultAndState<::HaltReason>, + BlockExecutionError, + > { + self.inner.execute_transaction_without_commit(tx) + } + + fn commit_transaction( + &mut self, + output: ResultAndState<::HaltReason>, + tx: impl ExecutableTx, + ) -> Result { + self.inner.commit_transaction(output, tx) + } + + fn finish( + mut self, + ) -> Result<(Self::Evm, BlockExecutionResult), BlockExecutionError> { + let block_number = self.inner.evm().block().number; + maybe_apply_eden_hardfork( + self.inner.evm_mut().db_mut(), + block_number, + self.hardfork_height, + )?; + self.inner.finish() + } + + fn set_state_hook(&mut self, hook: Option>) { + self.inner.set_state_hook(hook); + } + + fn evm_mut(&mut self) -> &mut Self::Evm { + self.inner.evm_mut() + } + + fn evm(&self) -> &Self::Evm { + self.inner.evm() + } +} + +#[derive(Debug, Clone)] +pub struct EdenBlockExecutorFactory { + inner: F, + hardfork_height: Option, +} + +impl EdenBlockExecutorFactory { + pub const fn new(inner: F, hardfork_height: Option) -> Self { + Self { + inner, + hardfork_height, + } + } +} + +impl BlockExecutorFactory for EdenBlockExecutorFactory +where + F: BlockExecutorFactory, +{ + type EvmFactory = F::EvmFactory; + type ExecutionCtx<'a> = F::ExecutionCtx<'a>; + type Transaction = F::Transaction; + type Receipt = F::Receipt; + + fn evm_factory(&self) -> &Self::EvmFactory { + self.inner.evm_factory() + } + + fn create_executor<'a, DB, I>( + &'a self, + evm: ::Evm<&'a mut State, I>, + ctx: Self::ExecutionCtx<'a>, + ) -> impl BlockExecutorFor<'a, Self, DB, I> + where + DB: EvmDatabase + 'a, + I: Inspector<::Context<&'a mut State>> + 'a, + { + EdenBlockExecutor { + inner: self.inner.create_executor(evm, ctx), + hardfork_height: self.hardfork_height, + } + } +} + +type InnerExecutorFactory = + ::BlockExecutorFactory; + +#[derive(Debug, Clone)] +pub struct EdenEvmConfig { + inner: EvolveEvmConfig, + eden_factory: EdenBlockExecutorFactory, +} + +impl EdenEvmConfig { + pub fn new(inner: EvolveEvmConfig, hardfork_height: Option) -> Self { + let eden_factory = + EdenBlockExecutorFactory::new(inner.executor_factory.clone(), hardfork_height); + Self { + inner, + eden_factory, + } + } +} + +impl ConfigureEvm for EdenEvmConfig { + type Primitives = ::Primitives; + type Error = ::Error; + type NextBlockEnvCtx = NextBlockEnvAttributes; + type BlockExecutorFactory = EdenBlockExecutorFactory; + type BlockAssembler = EthBlockAssembler; + + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { + &self.eden_factory + } + + fn block_assembler(&self) -> &Self::BlockAssembler { + self.inner.block_assembler() + } + + fn evm_env(&self, header: &Header) -> Result { + self.inner.evm_env(header) + } + + fn next_evm_env( + &self, + parent: &Header, + attributes: &NextBlockEnvAttributes, + ) -> Result { + self.inner.next_evm_env(parent, attributes) + } + + fn context_for_block<'a>( + &self, + block: &'a SealedBlock, + ) -> Result, Self::Error> { + self.inner.context_for_block(block) + } + + fn context_for_next_block( + &self, + parent: &SealedHeader, + attributes: Self::NextBlockEnvCtx, + ) -> Result, Self::Error> { + self.inner.context_for_next_block(parent, attributes) + } +} + +impl ConfigureEngineEvm for EdenEvmConfig { + fn evm_env_for_payload(&self, payload: &ExecutionData) -> EvmEnvFor { + self.inner.evm_env_for_payload(payload) + } + + fn context_for_payload<'a>(&self, payload: &'a ExecutionData) -> ExecutionCtxFor<'a, Self> { + self.inner.context_for_payload(payload) + } + + fn tx_iterator_for_payload(&self, payload: &ExecutionData) -> impl ExecutableTxIterator { + self.inner.tx_iterator_for_payload(payload) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use revm::database::CacheDB; + use revm::database_interface::EmptyDB; + + #[test] + fn apply_eden_storage_changes_writes_correct_values() { + let mut db = CacheDB::::default(); + + apply_eden_storage_changes(&mut db).expect("should succeed"); + + let name = Database::storage(&mut db, WTIA_ADDRESS, NAME_SLOT) + .expect("storage read should succeed"); + assert_eq!(name, NAME_VALUE); + + let symbol = Database::storage(&mut db, WTIA_ADDRESS, SYMBOL_SLOT) + .expect("storage read should succeed"); + assert_eq!(symbol, SYMBOL_VALUE); + + let decimals = Database::storage(&mut db, WTIA_ADDRESS, DECIMALS_SLOT) + .expect("storage read should succeed"); + assert_eq!(decimals, DECIMALS_VALUE); + } + + #[test] + fn apply_eden_storage_changes_works_on_missing_account() { + let mut db = CacheDB::::default(); + + apply_eden_storage_changes(&mut db).expect("should succeed"); + + let name = Database::storage(&mut db, WTIA_ADDRESS, NAME_SLOT) + .expect("storage read should succeed"); + assert_eq!(name, NAME_VALUE); + } + + #[test] + fn hardfork_applies_at_exact_height() { + let mut db = CacheDB::::default(); + + maybe_apply_eden_hardfork(&mut db, U256::from(100), Some(100)).expect("should succeed"); + + let name = Database::storage(&mut db, WTIA_ADDRESS, NAME_SLOT) + .expect("storage read should succeed"); + assert_eq!(name, NAME_VALUE); + + let symbol = Database::storage(&mut db, WTIA_ADDRESS, SYMBOL_SLOT) + .expect("storage read should succeed"); + assert_eq!(symbol, SYMBOL_VALUE); + + let decimals = Database::storage(&mut db, WTIA_ADDRESS, DECIMALS_SLOT) + .expect("storage read should succeed"); + assert_eq!(decimals, DECIMALS_VALUE); + } + + #[test] + fn hardfork_does_not_apply_at_wrong_height() { + let mut db = CacheDB::::default(); + + maybe_apply_eden_hardfork(&mut db, U256::from(99), Some(100)).expect("should succeed"); + + let name = Database::storage(&mut db, WTIA_ADDRESS, NAME_SLOT) + .expect("storage read should succeed"); + assert_eq!(name, U256::ZERO, "storage should be empty at height 99"); + + maybe_apply_eden_hardfork(&mut db, U256::from(101), Some(100)).expect("should succeed"); + + let name = Database::storage(&mut db, WTIA_ADDRESS, NAME_SLOT) + .expect("storage read should succeed"); + assert_eq!(name, U256::ZERO, "storage should be empty at height 101"); + } + + #[test] + fn hardfork_skipped_when_height_is_none() { + let mut db = CacheDB::::default(); + + maybe_apply_eden_hardfork(&mut db, U256::from(100), None).expect("should succeed"); + + let name = Database::storage(&mut db, WTIA_ADDRESS, NAME_SLOT) + .expect("storage read should succeed"); + assert_eq!(name, U256::ZERO, "storage should be empty when hardfork is disabled"); + } + + fn run_executor_at_height(hardfork_height: Option, parent_number: u64) -> bool { + use std::sync::Arc; + + use alloy_evm::block::BlockExecutor as _; + use ev_revm::with_ev_handler; + use reth_chainspec::ChainSpecBuilder; + use reth_evm::{execute::BlockBuilder as _, ConfigureEvm, NextBlockEnvAttributes}; + use reth_evm_ethereum::EthEvmConfig; + use reth_revm::state::AccountInfo; + + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(reth_chainspec::Chain::from_id(1234)) + .genesis(Default::default()) + .cancun_activated() + .build(), + ); + + let base_config = EthEvmConfig::new(chain_spec); + let evolve_config = with_ev_handler(base_config, None, None, None, None); + let eden_config = EdenEvmConfig::new(evolve_config, hardfork_height); + + let mut db = CacheDB::::default(); + db.insert_account_info( + WTIA_ADDRESS, + AccountInfo { + nonce: 1, + ..Default::default() + }, + ); + let mut state = State::builder().with_database(db).with_bundle_update().build(); + + let mut parent = alloy_consensus::Header::default(); + parent.number = parent_number; + parent.timestamp = 1000; + parent.gas_limit = 30_000_000; + parent.base_fee_per_gas = Some(0); + parent.excess_blob_gas = Some(0); + parent.blob_gas_used = Some(0); + parent.parent_beacon_block_root = Some(alloy_primitives::B256::ZERO); + let sealed_parent = + reth_primitives_traits::SealedHeader::new(parent, alloy_primitives::B256::ZERO); + + let attrs = NextBlockEnvAttributes { + timestamp: 2000, + suggested_fee_recipient: Address::ZERO, + prev_randao: alloy_primitives::B256::ZERO, + gas_limit: 30_000_000, + parent_beacon_block_root: Some(alloy_primitives::B256::ZERO), + withdrawals: Some(Default::default()), + }; + + { + let mut builder = eden_config + .builder_for_next_block(&mut state, &sealed_parent, attrs) + .expect("builder creation should succeed"); + + builder + .apply_pre_execution_changes() + .expect("pre-execution should succeed"); + + let executor = builder.into_executor(); + let _ = executor.finish().expect("finish should succeed"); + } + + state.merge_transitions(revm::database::states::bundle_state::BundleRetention::Reverts); + + state + .bundle_state + .state + .get(&WTIA_ADDRESS) + .and_then(|acc| acc.storage.get(&NAME_SLOT)) + .map(|slot| slot.present_value == NAME_VALUE) + .unwrap_or(false) + } + + #[test] + fn executor_injects_storage_at_hardfork_height() { + assert!( + run_executor_at_height(Some(5), 4), + "WTIA storage should be injected at hardfork height" + ); + } + + #[test] + fn executor_skips_injection_at_other_heights() { + assert!( + !run_executor_at_height(Some(5), 3), + "WTIA storage should NOT be injected one block early" + ); + assert!( + !run_executor_at_height(Some(5), 5), + "WTIA storage should NOT be injected one block late" + ); + } + + #[test] + fn executor_skips_injection_when_disabled() { + assert!( + !run_executor_at_height(None, 4), + "WTIA storage should NOT be injected when hardfork is disabled" + ); + } +} diff --git a/crates/node/src/lib.rs b/crates/node/src/lib.rs index b25d5d09..016d54b2 100644 --- a/crates/node/src/lib.rs +++ b/crates/node/src/lib.rs @@ -19,6 +19,8 @@ pub mod config; pub mod error; /// Executor wiring for EV aware execution. pub mod executor; +/// Eden mainnet hardfork: WTIA storage injection. +pub mod hardfork; /// Node composition and payload types. pub mod node; /// Payload service integration. @@ -34,6 +36,7 @@ pub use chainspec::EvolveChainSpecParser; pub use config::{ConfigError, EvolvePayloadBuilderConfig}; pub use error::EvolveEngineError; pub use executor::{build_evm_config, EvolveEvmConfig, EvolveExecutorBuilder}; +pub use hardfork::EdenEvmConfig; pub use node::{log_startup, EvolveEngineTypes, EvolveNode, EvolveNodeAddOns}; pub use payload_service::{EvolveEnginePayloadBuilder, EvolvePayloadBuilderBuilder}; pub use validator::{EvolveEngineValidator, EvolveEngineValidatorBuilder}; diff --git a/crates/node/src/node.rs b/crates/node/src/node.rs index 6a3cbfb1..add388cd 100644 --- a/crates/node/src/node.rs +++ b/crates/node/src/node.rs @@ -64,13 +64,17 @@ impl EngineTypes for EvolveEngineTypes { /// Evolve node type. #[derive(Debug, Clone, Default)] -#[non_exhaustive] -pub struct EvolveNode {} +pub struct EvolveNode { + /// Block height at which the Eden WTIA storage hardfork activates. + pub eden_hardfork_height: Option, +} impl EvolveNode { /// Create a new evolve node with the given arguments. - pub const fn new() -> Self { - Self {} + pub const fn new(eden_hardfork_height: Option) -> Self { + Self { + eden_hardfork_height, + } } } @@ -102,7 +106,7 @@ where ComponentsBuilder::default() .node_types::() .pool(EthereumPoolBuilder::default()) - .executor(EvolveExecutorBuilder::default()) + .executor(EvolveExecutorBuilder::new(self.eden_hardfork_height)) .payload(BasicPayloadServiceBuilder::new( EvolvePayloadBuilderBuilder::new(), )) diff --git a/crates/node/src/payload_service.rs b/crates/node/src/payload_service.rs index d9667767..a9e65c33 100644 --- a/crates/node/src/payload_service.rs +++ b/crates/node/src/payload_service.rs @@ -25,7 +25,7 @@ use tracing::info; use crate::{ attributes::EvolveEnginePayloadBuilderAttributes, builder::EvolvePayloadBuilder, - config::EvolvePayloadBuilderConfig, executor::EvolveEvmConfig, node::EvolveEngineTypes, + config::EvolvePayloadBuilderConfig, hardfork::EdenEvmConfig, node::EvolveEngineTypes, }; use evolve_ev_reth::config::set_current_block_gas_limit; @@ -62,7 +62,7 @@ where pub(crate) config: EvolvePayloadBuilderConfig, } -impl PayloadBuilderBuilder for EvolvePayloadBuilderBuilder +impl PayloadBuilderBuilder for EvolvePayloadBuilderBuilder where Node: FullNodeTypes< Types: NodeTypes< @@ -81,7 +81,7 @@ where self, ctx: &BuilderContext, _pool: Pool, - evm_config: EvolveEvmConfig, + evm_config: EdenEvmConfig, ) -> eyre::Result { let chain_spec = ctx.chain_spec(); let mut config = EvolvePayloadBuilderConfig::from_chain_spec(&chain_spec) diff --git a/crates/tests/src/common.rs b/crates/tests/src/common.rs index 328ff55e..06f81adf 100644 --- a/crates/tests/src/common.rs +++ b/crates/tests/src/common.rs @@ -21,7 +21,7 @@ use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; use serde_json::json; use tempfile::TempDir; -use ev_node::{EvolvePayloadBuilder, EvolvePayloadBuilderConfig}; +use ev_node::{EdenEvmConfig, EvolvePayloadBuilder, EvolvePayloadBuilderConfig}; use evolve_ev_reth::EvolvePayloadAttributes; // Test constants @@ -165,7 +165,8 @@ impl EvolveTestFixture { contract_size_limit, ); - let builder = EvolvePayloadBuilder::new(Arc::new(provider.clone()), wrapped_evm, config); + let eden_evm = EdenEvmConfig::new(wrapped_evm, None); + let builder = EvolvePayloadBuilder::new(Arc::new(provider.clone()), eden_evm, config); let fixture = Self { builder, From 7ed3527c81ef746db5e3415409ae138cecc53e70 Mon Sep 17 00:00:00 2001 From: Randy Grok Date: Mon, 9 Mar 2026 18:53:23 +0100 Subject: [PATCH 2/2] test migration --- scripts/eden-genesis.json | 85 ++++++ scripts/test-eden-upgrade.sh | 483 +++++++++++++++++++++++++++++++++++ 2 files changed, 568 insertions(+) create mode 100644 scripts/eden-genesis.json create mode 100755 scripts/test-eden-upgrade.sh diff --git a/scripts/eden-genesis.json b/scripts/eden-genesis.json new file mode 100644 index 00000000..e7eb4438 --- /dev/null +++ b/scripts/eden-genesis.json @@ -0,0 +1,85 @@ +{ + "config": { + "chainId": 714, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "parisBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "pragueTime": 0, + "osakaTime": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "evolve": { + "baseFeeSink": "0x0337d738074c83B6133940051490c7c6080a5094", + "baseFeeRedirectActivationHeight": 0, + "baseFeeMaxChangeDenominator": 5000, + "baseFeeElasticityMultiplier": 10, + "initialBaseFeePerGas": 100000000000000000, + "mintAdmin": "0x000000000000000000000000000000000000Ad00", + "mintPrecompileActivationHeight": 0, + "contractSizeLimit": 131072, + "contractSizeLimitActivationHeight": 0 + } + }, + "difficulty": "0x1", + "gasLimit": "0x2faf080", + "baseFeePerGas": "0x16345785d8a0000", + "alloc": { + "5243f000f7d8ea0dc11428da4ce8f1db002d44fb": { + "balance": "0x8ac7230489e80000" + }, + "00000000000000000000000000000000Ce1e571A": { + "balance": "0", + "code": "0x60806040818152600480361015610029575b505050361561001f57600080fd5b610027610697565b005b600092833560e01c90816306fdde03146103f557508063095ea7b31461038757806318160ddd1461036c57806323b872dd1461033a5780632e1a7d4d146102a8578063313ce5671461028657806370a082311461024e57806395d89b4114610147578063a9059cbb14610110578063d0e30db0146100f65763dd62ed3e0361001157346100f257816003193601126100f25760209282916100c8610516565b6100d0610531565b6001600160a01b03918216845291865283832091168252845220549051908152f35b8280fd5b838060031936011261010d5761010a610697565b80f35b80fd5b50503461014357806003193601126101435760209061013a610130610516565b6024359033610577565b90519015158152f35b5080fd5b509190346101435781600319360112610143578051908260018054908160011c9060018316928315610244575b60209384841081146102315783885290811561021557506001146101dc575b505050829003601f01601f191682019267ffffffffffffffff8411838510176101c957508291826101c59252826104cd565b0390f35b634e487b7160e01b815260418552602490fd5b91925060018652828620918387935b8385106102015750505050830101388080610193565b8054888601830152930192849082016101eb565b60ff1916878501525050151560051b8401019050388080610193565b634e487b7160e01b895260228a52602489fd5b91607f1691610174565b5050346101435760203660031901126101435760209181906001600160a01b03610276610516565b1681526003845220549051908152f35b50503461014357816003193601126101435760209060ff600254169051908152f35b50346100f25760203660031901126100f25735903383526003602052808320805483811061033657836102da91610547565b9055828083801561032c575b8280929181923390f11561032157519081527f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b6560203392a280f35b51913d9150823e3d90fd5b6108fc91506102e6565b8480fd5b5050346101435760603660031901126101435760209061013a61035b610516565b610363610531565b60443591610577565b50503461014357816003193601126101435751478152602090f35b50346100f257816003193601126100f2576020926103a3610516565b918360243592839233825287528181209460018060a01b0316948582528752205582519081527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925843392a35160018152f35b84915083346100f257826003193601126100f25782835460018160011c90600183169283156104c3575b6020938484108114610231578388529081156104a7575060011461046f57505050829003601f01601f191682019267ffffffffffffffff8411838510176101c957508291826101c59252826104cd565b919250858052828620918387935b8385106104935750505050830101858080610193565b80548886018301529301928490820161047d565b60ff1916878501525050151560051b8401019050858080610193565b91607f169161041f565b6020808252825181830181905290939260005b82811061050257505060409293506000838284010152601f8019910116010190565b8181018601518482016040015285016104e0565b600435906001600160a01b038216820361052c57565b600080fd5b602435906001600160a01b038216820361052c57565b9190820391821161055457565b634e487b7160e01b600052601160045260246000fd5b9190820180921161055457565b91909160018060a01b03809116916000938385526020926003845260409183838820541061067857338614158061067c575b61060d575b9180917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef959493878952600386528289206105ea868254610547565b90551696878152600385522061060183825461056a565b905551908152a3600190565b858752600485528287203388528552838388205410610678579180917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef95949387895260048652828920338a52865282892061066a868254610547565b9055915091929394506105ae565b8680fd5b506004855282872033885285528287205460001914156105a9565b33600052600360205260406000206106b034825461056a565b90556040513481527fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c60203392a256fea26469706673582212208ed4a9c90accc30f77d08b9799b0f8bf9ddfbe90273a7abb51f6d2f8e7f3aee464736f6c63430008180033" + }, + "cA11bde05977b3631167028862bE2a173976CA11": { + "balance": "0", + "code": "0x6080604052600436106100f35760003560e01c80634d2301cc1161008a578063a8b0574e11610059578063a8b0574e1461025a578063bce38bd714610275578063c3077fa914610288578063ee82ac5e1461029b57600080fd5b80634d2301cc146101ec57806372425d9d1461022157806382ad56cb1461023457806386d516e81461024757600080fd5b80633408e470116100c65780633408e47014610191578063399542e9146101a45780633e64a696146101c657806342cbb15c146101d957600080fd5b80630f28c97d146100f8578063174dea711461011a578063252dba421461013a57806327e86d6e1461015b575b600080fd5b34801561010457600080fd5b50425b6040519081526020015b60405180910390f35b61012d610128366004610a85565b6102ba565b6040516101119190610bbe565b61014d610148366004610a85565b6104ef565b604051610111929190610bd8565b34801561016757600080fd5b50437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0140610107565b34801561019d57600080fd5b5046610107565b6101b76101b2366004610c60565b610690565b60405161011193929190610cba565b3480156101d257600080fd5b5048610107565b3480156101e557600080fd5b5043610107565b3480156101f857600080fd5b50610107610207366004610ce2565b73ffffffffffffffffffffffffffffffffffffffff163190565b34801561022d57600080fd5b5044610107565b61012d610242366004610a85565b6106ab565b34801561025357600080fd5b5045610107565b34801561026657600080fd5b50604051418152602001610111565b61012d610283366004610c60565b61085a565b6101b7610296366004610a85565b610a1a565b3480156102a757600080fd5b506101076102b6366004610d18565b4090565b60606000828067ffffffffffffffff8111156102d8576102d8610d31565b60405190808252806020026020018201604052801561031e57816020015b6040805180820190915260008152606060208201528152602001906001900390816102f65790505b5092503660005b8281101561047757600085828151811061034157610341610d60565b6020026020010151905087878381811061035d5761035d610d60565b905060200281019061036f9190610d8f565b6040810135958601959093506103886020850185610ce2565b73ffffffffffffffffffffffffffffffffffffffff16816103ac6060870187610dcd565b6040516103ba929190610e32565b60006040518083038185875af1925050503d80600081146103f7576040519150601f19603f3d011682016040523d82523d6000602084013e6103fc565b606091505b50602080850191909152901515808452908501351761046d577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260846000fd5b5050600101610325565b508234146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f4d756c746963616c6c333a2076616c7565206d69736d6174636800000000000060448201526064015b60405180910390fd5b50505092915050565b436060828067ffffffffffffffff81111561050c5761050c610d31565b60405190808252806020026020018201604052801561053f57816020015b606081526020019060019003908161052a5790505b5091503660005b8281101561068657600087878381811061056257610562610d60565b90506020028101906105749190610e42565b92506105836020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166105a66020850185610dcd565b6040516105b4929190610e32565b6000604051808303816000865af19150503d80600081146105f1576040519150601f19603f3d011682016040523d82523d6000602084013e6105f6565b606091505b5086848151811061060957610609610d60565b602090810291909101015290508061067d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b50600101610546565b5050509250929050565b43804060606106a086868661085a565b905093509350939050565b6060818067ffffffffffffffff8111156106c7576106c7610d31565b60405190808252806020026020018201604052801561070d57816020015b6040805180820190915260008152606060208201528152602001906001900390816106e55790505b5091503660005b828110156104e657600084828151811061073057610730610d60565b6020026020010151905086868381811061074c5761074c610d60565b905060200281019061075e9190610e76565b925061076d6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff166107906040850185610dcd565b60405161079e929190610e32565b6000604051808303816000865af19150503d80600081146107db576040519150601f19603f3d011682016040523d82523d6000602084013e6107e0565b606091505b506020808401919091529015158083529084013517610851577f08c379a000000000000000000000000000000000000000000000000000000000600052602060045260176024527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060445260646000fd5b50600101610714565b6060818067ffffffffffffffff81111561087657610876610d31565b6040519080825280602002602001820160405280156108bc57816020015b6040805180820190915260008152606060208201528152602001906001900390816108945790505b5091503660005b82811015610a105760008482815181106108df576108df610d60565b602002602001015190508686838181106108fb576108fb610d60565b905060200281019061090d9190610e42565b925061091c6020840184610ce2565b73ffffffffffffffffffffffffffffffffffffffff1661093f6020850185610dcd565b60405161094d929190610e32565b6000604051808303816000865af19150503d806000811461098a576040519150601f19603f3d011682016040523d82523d6000602084013e61098f565b606091505b506020830152151581528715610a07578051610a07576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4d756c746963616c6c333a2063616c6c206661696c656400000000000000000060448201526064016104dd565b506001016108c3565b5050509392505050565b6000806060610a2b60018686610690565b919790965090945092505050565b60008083601f840112610a4b57600080fd5b50813567ffffffffffffffff811115610a6357600080fd5b6020830191508360208260051b8501011115610a7e57600080fd5b9250929050565b60008060208385031215610a9857600080fd5b823567ffffffffffffffff811115610aaf57600080fd5b610abb85828601610a39565b90969095509350505050565b6000815180845260005b81811015610aed57602081850181015186830182015201610ad1565b81811115610aff576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082825180855260208086019550808260051b84010181860160005b84811015610bb1578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001895281518051151584528401516040858501819052610b9d81860183610ac7565b9a86019a9450505090830190600101610b4f565b5090979650505050505050565b602081526000610bd16020830184610b32565b9392505050565b600060408201848352602060408185015281855180845260608601915060608160051b870101935082870160005b82811015610c52577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0888703018452610c40868351610ac7565b95509284019290840190600101610c06565b509398975050505050505050565b600080600060408486031215610c7557600080fd5b83358015158114610c8557600080fd5b9250602084013567ffffffffffffffff811115610ca157600080fd5b610cad86828701610a39565b9497909650939450505050565b838152826020820152606060408201526000610cd96060830184610b32565b95945050505050565b600060208284031215610cf457600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610bd157600080fd5b600060208284031215610d2a57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112610dc357600080fd5b9190910192915050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112610e0257600080fd5b83018035915067ffffffffffffffff821115610e1d57600080fd5b602001915036819003821315610a7e57600080fd5b8183823760009101908152919050565b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc1833603018112610dc357600080fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112610dc357600080fdfea2646970667358221220bb2b5c71a328032f97c676ae39a1ec2148d3e5d6f73d95e9b17910152d61f16264736f6c634300080c0033" + }, + "ba5Ed099633D3B313e4D5F7bdc1305d3c28ba5Ed": { + "balance": "0", + "code": "0x60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed8361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed6119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed1631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed73ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ba5ed099633d3b313e4d5f7bdc1305d3c28ba5ed16600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a" + }, + "4e59b44847b379578588920cA78FbF26c0B4956C": { + "balance": "0", + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + }, + "ce0042B868300000d44A59004Da54A005ffdcf9f": { + "balance": "0", + "code": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c80634af63f0214602d575b600080fd5b60cf60048036036040811015604157600080fd5b810190602081018135640100000000811115605b57600080fd5b820183602082011115606c57600080fd5b80359060200191846001830284011164010000000083111715608d57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550509135925060eb915050565b604080516001600160a01b039092168252519081900360200190f35b6000818351602085016000f5939250505056fea26469706673582212206b44f8a82cb6b156bfcc3dc6aadd6df4eefd204bc928a4397fd15dacf6d5320564736f6c63430006020033" + }, + "914d7Fec6aaC8cd542e72Bca78B30650d45643d7": { + "balance": "0", + "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3" + }, + "000000000000000000000000000000000000ad00": { + "balance": "0x0", + "code": "0x60806040526004361061007e575f3560e01c80638da5cb5b1161004d5780638da5cb5b1461012d578063e30c397814610157578063f2fde38b14610181578063fa4bb79d146101a957610085565b806318dfb3c7146100895780631cff79cd146100c557806379ba5097146101015780638b5298541461011757610085565b3661008557005b5f5ffd5b348015610094575f5ffd5b506100af60048036038101906100aa9190610cf8565b6101e5565b6040516100bc9190610ea1565b60405180910390f35b3480156100d0575f5ffd5b506100eb60048036038101906100e69190610f70565b6104d9565b6040516100f89190611015565b60405180910390f35b34801561010c575f5ffd5b5061011561066c565b005b348015610122575f5ffd5b5061012b6107ed565b005b348015610138575f5ffd5b506101416108b4565b60405161014e9190611044565b60405180910390f35b348015610162575f5ffd5b5061016b6108d8565b6040516101789190611044565b60405180910390f35b34801561018c575f5ffd5b506101a760048036038101906101a2919061105d565b6108fd565b005b3480156101b4575f5ffd5b506101cf60048036038101906101ca91906110bb565b610aa4565b6040516101dc9190611015565b60405180910390f35b60605f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461026c576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8282905085859050146102ab576040517fff633a3800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8484905067ffffffffffffffff8111156102c8576102c761112c565b5b6040519080825280602002602001820160405280156102fb57816020015b60608152602001906001900390816102e65790505b5090505f5f90505b858590508110156104d0575f5f87878481811061032357610322611159565b5b9050602002016020810190610338919061105d565b73ffffffffffffffffffffffffffffffffffffffff1686868581811061036157610360611159565b5b90506020028101906103739190611192565b604051610381929190611230565b5f604051808303815f865af19150503d805f81146103ba576040519150601f19603f3d011682016040523d82523d5f602084013e6103bf565b606091505b50915091508161040657806040517fa5fa8d2b0000000000000000000000000000000000000000000000000000000081526004016103fd9190611015565b60405180910390fd5b87878481811061041957610418611159565b5b905060200201602081019061042e919061105d565b73ffffffffffffffffffffffffffffffffffffffff167fc96720f35dd524e76ea92971ce13d08e9a17816bf3b0008a7083e6032354ebb587878681811061047857610477611159565b5b905060200281019061048a9190611192565b8460405161049a93929190611274565b60405180910390a2808484815181106104b6576104b5611159565b5b602002602001018190525050508080600101915050610303565b50949350505050565b60605f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610560576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8573ffffffffffffffffffffffffffffffffffffffff168585604051610589929190611230565b5f604051808303815f865af19150503d805f81146105c2576040519150601f19603f3d011682016040523d82523d5f602084013e6105c7565b606091505b50915091508161060e57806040517fa5fa8d2b0000000000000000000000000000000000000000000000000000000081526004016106059190611015565b60405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff167fc96720f35dd524e76ea92971ce13d08e9a17816bf3b0008a7083e6032354ebb586868460405161065893929190611274565b60405180910390a280925050509392505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106f2576040517f1853971c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff165f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3335f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f60015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610872576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f60015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610982576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036109e7576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff165f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b60605f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b2b576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f8673ffffffffffffffffffffffffffffffffffffffff16848787604051610b55929190611230565b5f6040518083038185875af1925050503d805f8114610b8f576040519150601f19603f3d011682016040523d82523d5f602084013e610b94565b606091505b509150915081610bdb57806040517fa5fa8d2b000000000000000000000000000000000000000000000000000000008152600401610bd29190611015565b60405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff167fc96720f35dd524e76ea92971ce13d08e9a17816bf3b0008a7083e6032354ebb5878784604051610c2593929190611274565b60405180910390a28092505050949350505050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f840112610c6357610c62610c42565b5b8235905067ffffffffffffffff811115610c8057610c7f610c46565b5b602083019150836020820283011115610c9c57610c9b610c4a565b5b9250929050565b5f5f83601f840112610cb857610cb7610c42565b5b8235905067ffffffffffffffff811115610cd557610cd4610c46565b5b602083019150836020820283011115610cf157610cf0610c4a565b5b9250929050565b5f5f5f5f60408587031215610d1057610d0f610c3a565b5b5f85013567ffffffffffffffff811115610d2d57610d2c610c3e565b5b610d3987828801610c4e565b9450945050602085013567ffffffffffffffff811115610d5c57610d5b610c3e565b5b610d6887828801610ca3565b925092505092959194509250565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f610de182610d9f565b610deb8185610da9565b9350610dfb818560208601610db9565b610e0481610dc7565b840191505092915050565b5f610e1a8383610dd7565b905092915050565b5f602082019050919050565b5f610e3882610d76565b610e428185610d80565b935083602082028501610e5485610d90565b805f5b85811015610e8f5784840389528151610e708582610e0f565b9450610e7b83610e22565b925060208a01995050600181019050610e57565b50829750879550505050505092915050565b5f6020820190508181035f830152610eb98184610e2e565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610eea82610ec1565b9050919050565b610efa81610ee0565b8114610f04575f5ffd5b50565b5f81359050610f1581610ef1565b92915050565b5f5f83601f840112610f3057610f2f610c42565b5b8235905067ffffffffffffffff811115610f4d57610f4c610c46565b5b602083019150836001820283011115610f6957610f68610c4a565b5b9250929050565b5f5f5f60408486031215610f8757610f86610c3a565b5b5f610f9486828701610f07565b935050602084013567ffffffffffffffff811115610fb557610fb4610c3e565b5b610fc186828701610f1b565b92509250509250925092565b5f82825260208201905092915050565b5f610fe782610d9f565b610ff18185610fcd565b9350611001818560208601610db9565b61100a81610dc7565b840191505092915050565b5f6020820190508181035f83015261102d8184610fdd565b905092915050565b61103e81610ee0565b82525050565b5f6020820190506110575f830184611035565b92915050565b5f6020828403121561107257611071610c3a565b5b5f61107f84828501610f07565b91505092915050565b5f819050919050565b61109a81611088565b81146110a4575f5ffd5b50565b5f813590506110b581611091565b92915050565b5f5f5f5f606085870312156110d3576110d2610c3a565b5b5f6110e087828801610f07565b945050602085013567ffffffffffffffff81111561110157611100610c3e565b5b61110d87828801610f1b565b93509350506040611120878288016110a7565b91505092959194509250565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f833560016020038436030381126111ae576111ad611186565b5b80840192508235915067ffffffffffffffff8211156111d0576111cf61118a565b5b6020830192506001820236038313156111ec576111eb61118e565b5b509250929050565b5f81905092915050565b828183375f83830152505050565b5f61121783856111f4565b93506112248385846111fe565b82840190509392505050565b5f61123c82848661120c565b91508190509392505050565b5f6112538385610fcd565b93506112608385846111fe565b61126983610dc7565b840190509392505050565b5f6040820190508181035f83015261128d818587611248565b905081810360208301526112a18184610fdd565b905094935050505056fea26469706673582212201029704c8e76cc8133cedd39a8adbebfe979b8809644c7f5e9cff417e23119d464736f6c634300081e0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000005243f000f7d8ea0dc11428da4ce8f1db002d44fb" + } + }, + "0337d738074c83b6133940051490c7c6080a5094": { + "balance": "0x0", + "code": "0x608060405260043610610101575f3560e01c80636cb53e1611610094578063bb0c829811610063578063bb0c8298146102dc578063c3f909d414610306578063eeb4a9c814610337578063f2fde38b1461035f578063f63188b71461038757610108565b80636cb53e16146102565780637d57d97a1461027e5780638da5cb5b1461028857806390321e1a146102b257610108565b806339bb1c5b116100d057806339bb1c5b146101ae5780634cebdc49146101d85780635aff5999146102025780635c4a6d841461022c57610108565b80631636b3681461010c57806326465826146101345780632858c55a1461015c5780632c2d80891461018657610108565b3661010857005b5f5ffd5b348015610117575f5ffd5b50610132600480360381019061012d919061117f565b6103af565b005b34801561013f575f5ffd5b5061015a600480360381019061015591906111dd565b610526565b005b348015610167575f5ffd5b506101706105f6565b60405161017d9190611226565b60405180910390f35b348015610191575f5ffd5b506101ac60048036038101906101a7919061129c565b61060c565b005b3480156101b9575f5ffd5b506101c2610700565b6040516101cf9190611335565b60405180910390f35b3480156101e3575f5ffd5b506101ec610724565b6040516101f9919061135d565b60405180910390f35b34801561020d575f5ffd5b50610216610749565b6040516102239190611385565b60405180910390f35b348015610237575f5ffd5b5061024061074f565b60405161024d91906113ad565b60405180910390f35b348015610261575f5ffd5b5061027c6004803603810190610277919061117f565b610755565b005b6102866108cb565b005b348015610293575f5ffd5b5061029c610caa565b6040516102a9919061135d565b60405180910390f35b3480156102bd575f5ffd5b506102c6610ccf565b6040516102d391906113ad565b60405180910390f35b3480156102e7575f5ffd5b506102f0610cd5565b6040516102fd91906113ad565b60405180910390f35b348015610311575f5ffd5b5061031a610cdb565b60405161032e9897969594939291906113c6565b60405180910390f35b348015610342575f5ffd5b5061035d600480360381019061035891906111dd565b610d81565b005b34801561036a575f5ffd5b506103856004803603810190610380919061117f565b610e51565b005b348015610392575f5ffd5b506103ad60048036038101906103a891906111dd565b61100c565b005b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461043e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610435906114c2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036104ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104a39061152a565b60405180910390fd5b8060055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fa50c88d04012de3892b47d81943c983dc2690cfb81f0428eaa7d382f95683e4a8160405161051b919061135d565b60405180910390a150565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105ac906114c2565b60405180910390fd5b806004819055507f63a8f7442c91b7117b3f235d24793c034fd752a01266bef3ef1d051efb56ca3d816040516105eb91906113ad565b60405180910390a150565b600160149054906101000a900463ffffffff1681565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461069b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610692906114c2565b60405180910390fd5b81600160146101000a81548163ffffffff021916908363ffffffff160217905550806002819055507fcac2c3add78f132121267d80a684a62d521a9799fd8434bd0da1a27c491b044982826040516106f4929190611548565b60405180910390a15050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60025481565b60065481565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107db906114c2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610852576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108499061152a565b60405180910390fd5b805f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f6eedba6e0a60268e3d78633f8822cea5dc75430d531f96fb46a29333834665c6816040516108c0919061135d565b60405180910390a150565b5f73ffffffffffffffffffffffffffffffffffffffff165f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610959576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610950906115b9565b60405180910390fd5b60045434101561099e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099590611621565b60405180910390fd5b5f4790505f612710600654836109b4919061166c565b6109be91906116da565b90505f81836109cd919061170a565b9050600354821015610a14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0b90611787565b60405180910390fd5b7f50ecfcc47f2c5b2a26f91422abf650476ec7f701c48b1cf6d1d6d4d51a872ed6838383604051610a47939291906117a5565b60405180910390a15f811115610bb1575f73ffffffffffffffffffffffffffffffffffffffff1660055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610ae6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610add9061184a565b60405180910390fd5b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1682604051610b2c90611895565b5f6040518083038185875af1925050503d805f8114610b66576040519150601f19603f3d011682016040523d82523d5f602084013e610b6b565b606091505b5050905080610baf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba6906118f3565b60405180910390fd5b505b5f5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381b4e8b484600160149054906101000a900463ffffffff16600254876040518563ffffffff1660e01b8152600401610c2493929190611911565b60206040518083038185885af1158015610c40573d5f5f3e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610c65919061195a565b90507f301fb78c068680a9fb5daa4ebadf5914ddc3a317f1fdc2c97f32740374d61e748360025483604051610c9c93929190611985565b60405180910390a150505050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60045481565b60035481565b5f5f5f5f5f5f5f5f60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600160149054906101000a900463ffffffff1660025460035460045460065460055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff165f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16975097509750975097509750975097509091929394959697565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e07906114c2565b60405180910390fd5b806003819055507f6ea576632a91ef2f8d4ee43600561b386f3c0254692977f0d33e17742bc5355881604051610e4691906113ad565b60405180910390a150565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ee0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed7906114c2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610f4e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4590611a2a565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a38060015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461109b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611092906114c2565b60405180910390fd5b6127108111156110e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d790611a92565b60405180910390fd5b806006819055507fa8da92ecf88f6d9f058e5f86d614520d5f20a3ecf87914deb605f649bd63de878160405161111691906113ad565b60405180910390a150565b5f5ffd5b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f61114e82611125565b9050919050565b61115e81611144565b8114611168575f5ffd5b50565b5f8135905061117981611155565b92915050565b5f6020828403121561119457611193611121565b5b5f6111a18482850161116b565b91505092915050565b5f819050919050565b6111bc816111aa565b81146111c6575f5ffd5b50565b5f813590506111d7816111b3565b92915050565b5f602082840312156111f2576111f1611121565b5b5f6111ff848285016111c9565b91505092915050565b5f63ffffffff82169050919050565b61122081611208565b82525050565b5f6020820190506112395f830184611217565b92915050565b61124881611208565b8114611252575f5ffd5b50565b5f813590506112638161123f565b92915050565b5f819050919050565b61127b81611269565b8114611285575f5ffd5b50565b5f8135905061129681611272565b92915050565b5f5f604083850312156112b2576112b1611121565b5b5f6112bf85828601611255565b92505060206112d085828601611288565b9150509250929050565b5f819050919050565b5f6112fd6112f86112f384611125565b6112da565b611125565b9050919050565b5f61130e826112e3565b9050919050565b5f61131f82611304565b9050919050565b61132f81611315565b82525050565b5f6020820190506113485f830184611326565b92915050565b61135781611144565b82525050565b5f6020820190506113705f83018461134e565b92915050565b61137f81611269565b82525050565b5f6020820190506113985f830184611376565b92915050565b6113a7816111aa565b82525050565b5f6020820190506113c05f83018461139e565b92915050565b5f610100820190506113da5f83018b61134e565b6113e7602083018a611217565b6113f46040830189611376565b611401606083018861139e565b61140e608083018761139e565b61141b60a083018661139e565b61142860c083018561134e565b61143560e083018461134e565b9998505050505050505050565b5f82825260208201905092915050565b7f4665655661756c743a2063616c6c6572206973206e6f7420746865206f776e655f8201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b5f6114ac602183611442565b91506114b782611452565b604082019050919050565b5f6020820190508181035f8301526114d9816114a0565b9050919050565b7f4665655661756c743a207a65726f2061646472657373000000000000000000005f82015250565b5f611514601683611442565b915061151f826114e0565b602082019050919050565b5f6020820190508181035f83015261154181611508565b9050919050565b5f60408201905061155b5f830185611217565b6115686020830184611376565b9392505050565b7f4665655661756c743a206d696e746572206e6f742073657400000000000000005f82015250565b5f6115a3601883611442565b91506115ae8261156f565b602082019050919050565b5f6020820190508181035f8301526115d081611597565b9050919050565b7f4665655661756c743a20696e73756666696369656e74206665650000000000005f82015250565b5f61160b601a83611442565b9150611616826115d7565b602082019050919050565b5f6020820190508181035f830152611638816115ff565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f611676826111aa565b9150611681836111aa565b925082820261168f816111aa565b915082820484148315176116a6576116a561163f565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6116e4826111aa565b91506116ef836111aa565b9250826116ff576116fe6116ad565b5b828204905092915050565b5f611714826111aa565b915061171f836111aa565b92508282039050818111156117375761173661163f565b5b92915050565b7f4665655661756c743a206d696e696d756d20616d6f756e74206e6f74206d65745f82015250565b5f611771602083611442565b915061177c8261173d565b602082019050919050565b5f6020820190508181035f83015261179e81611765565b9050919050565b5f6060820190506117b85f83018661139e565b6117c5602083018561139e565b6117d2604083018461139e565b949350505050565b7f4665655661756c743a206f7468657220726563697069656e74206e6f742073655f8201527f7400000000000000000000000000000000000000000000000000000000000000602082015250565b5f611834602183611442565b915061183f826117da565b604082019050919050565b5f6020820190508181035f83015261186181611828565b9050919050565b5f81905092915050565b50565b5f6118805f83611868565b915061188b82611872565b5f82019050919050565b5f61189f82611875565b9150819050919050565b7f4665655661756c743a207472616e73666572206661696c6564000000000000005f82015250565b5f6118dd601983611442565b91506118e8826118a9565b602082019050919050565b5f6020820190508181035f83015261190a816118d1565b9050919050565b5f6060820190506119245f830186611217565b6119316020830185611376565b61193e604083018461139e565b949350505050565b5f8151905061195481611272565b92915050565b5f6020828403121561196f5761196e611121565b5b5f61197c84828501611946565b91505092915050565b5f6060820190506119985f83018661139e565b6119a56020830185611376565b6119b26040830184611376565b949350505050565b7f4665655661756c743a206e6577206f776e657220697320746865207a65726f205f8201527f6164647265737300000000000000000000000000000000000000000000000000602082015250565b5f611a14602783611442565b9150611a1f826119ba565b604082019050919050565b5f6020820190508181035f830152611a4181611a08565b9050919050565b7f4665655661756c743a20696e76616c69642062707300000000000000000000005f82015250565b5f611a7c601583611442565b9150611a8782611a48565b602082019050919050565b5f6020820190508181035f830152611aa981611a70565b905091905056fea26469706673582212206974a9d1b940d399bb1bd1ddcd316e0d19c3991922f1fc167ddfb56cc8b70b1164736f6c634300081e0033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000000000000000000000000000000000000000Ad00", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000004": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000000000000000000000000000000000000000002710" + } + } + } +} diff --git a/scripts/test-eden-upgrade.sh b/scripts/test-eden-upgrade.sh new file mode 100755 index 00000000..21c88a1f --- /dev/null +++ b/scripts/test-eden-upgrade.sh @@ -0,0 +1,483 @@ +#!/usr/bin/env bash +set -euo pipefail + +# =============================================================== +# Test Eden Hardfork Upgrade Path +# =============================================================== +# Tests that upgrading from the main binary to the eden binary +# properly applies WTIA storage changes at the hardfork height. +# +# Flow: +# 1. Build binary from current branch (eden hardfork support) +# 2. Build binary from main (no eden hardfork) +# 3. Start main binary, produce 3 blocks +# 4. Verify WTIA storage is empty +# 5. Stop node +# 6. Start eden binary with --eden-hardfork-height 5 +# 7. Produce blocks 4 and 5 +# 8. Verify WTIA storage has NAME, SYMBOL, DECIMALS +# =============================================================== + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +CURRENT_BRANCH=$(git -C "$PROJECT_DIR" rev-parse --abbrev-ref HEAD) + +# Test configuration +HARDFORK_HEIGHT=5 +BLOCKS_BEFORE_UPGRADE=3 +BLOCKS_AFTER_UPGRADE=2 + +# Network ports (non-standard to avoid conflicts) +HTTP_PORT=28545 +AUTH_PORT=28551 +P2P_PORT=30304 + +# WTIA Contract +WTIA_ADDRESS="0x00000000000000000000000000000000Ce1e571A" + +# Expected storage values (Solidity short string encoding) +EXPECTED_NAME="0x5772617070656420544941000000000000000000000000000000000000000016" +EXPECTED_SYMBOL="0x5754494100000000000000000000000000000000000000000000000000000008" +EXPECTED_DECIMALS="0x0000000000000000000000000000000000000000000000000000000000000012" + +# Temp directories +WORK_DIR=$(mktemp -d) +DATADIR="$WORK_DIR/data" +JWT_SECRET_FILE="$WORK_DIR/jwt.hex" +GENESIS="$SCRIPT_DIR/eden-genesis.json" + +# Binary paths +MAIN_BINARY="$WORK_DIR/ev-reth-main" +EDEN_BINARY="$WORK_DIR/ev-reth-eden" + +NODE_PID="" +MAIN_WORKTREE="" + +# Block tracking (global state) +HEAD_HASH="" +HEAD_NUMBER=0 +HEAD_TIMESTAMP=0 + +# Colors +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +cleanup() { + echo "" + echo -e "${YELLOW}Cleaning up...${NC}" + if [ -n "$NODE_PID" ] && kill -0 "$NODE_PID" 2>/dev/null; then + kill "$NODE_PID" 2>/dev/null || true + wait "$NODE_PID" 2>/dev/null || true + fi + # Remove temp worktree if it was created + if [ -n "$MAIN_WORKTREE" ] && [ -d "$MAIN_WORKTREE" ]; then + git -C "$PROJECT_DIR" worktree remove "$MAIN_WORKTREE" --force 2>/dev/null || true + fi + echo "Work dir: $WORK_DIR (not deleted - check node.log if needed)" + echo "To clean up: rm -rf $WORK_DIR" +} +trap cleanup EXIT + +log() { echo -e "${GREEN}>>>${NC} $1"; } +info() { echo -e "${BLUE} $1${NC}"; } +fail() { echo -e "${RED}[FAIL]${NC} $1"; } + +die() { + echo -e "${RED}[ERROR]${NC} $1" + if [ -f "$WORK_DIR/node.log" ]; then + echo -e "${YELLOW}Last 20 lines of node log:${NC}" + tail -20 "$WORK_DIR/node.log" + fi + exit 1 +} + +# --------------- JWT & RPC helpers --------------- + +generate_jwt() { + python3 -c " +import hmac, hashlib, base64, json, time +secret = bytes.fromhex(open('$JWT_SECRET_FILE').read().strip()) +header = base64.urlsafe_b64encode(json.dumps({'alg':'HS256','typ':'JWT'}).encode()).rstrip(b'=').decode() +payload = base64.urlsafe_b64encode(json.dumps({'iat':int(time.time())}).encode()).rstrip(b'=').decode() +unsigned = f'{header}.{payload}' +sig = base64.urlsafe_b64encode(hmac.new(secret, unsigned.encode(), hashlib.sha256).digest()).rstrip(b'=').decode() +print(f'{unsigned}.{sig}') +" +} + +engine_call() { + local method="$1" + local params="$2" + local jwt + jwt=$(generate_jwt) + curl -s -X POST \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $jwt" \ + -d "{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"params\":$params,\"id\":1}" \ + "http://localhost:$AUTH_PORT" +} + +rpc_call() { + local method="$1" + local params="$2" + curl -s -X POST \ + -H "Content-Type: application/json" \ + -d "{\"jsonrpc\":\"2.0\",\"method\":\"$method\",\"params\":$params,\"id\":1}" \ + "http://localhost:$HTTP_PORT" +} + +# --------------- Node lifecycle --------------- + +wait_for_node() { + local max=60 + local i=0 + while [ $i -lt $max ]; do + if rpc_call "eth_blockNumber" "[]" 2>/dev/null | jq -e '.result' >/dev/null 2>&1; then + return 0 + fi + sleep 1 + i=$((i + 1)) + done + die "Node failed to become ready after ${max}s" +} + +start_node() { + local binary="$1" + shift + + mkdir -p "$DATADIR" + + RUST_LOG="info,ev_reth=debug,ev_node=debug" \ + "$binary" node \ + --chain "$GENESIS" \ + --datadir "$DATADIR" \ + --http \ + --http.port "$HTTP_PORT" \ + --authrpc.port "$AUTH_PORT" \ + --authrpc.jwtsecret "$JWT_SECRET_FILE" \ + --port "$P2P_PORT" \ + "$@" \ + >> "$WORK_DIR/node.log" 2>&1 & + NODE_PID=$! + + log "Node started (PID: $NODE_PID, binary: $(basename "$binary"))" + # Quick check: if the process died immediately, show the log + sleep 2 + if ! kill -0 "$NODE_PID" 2>/dev/null; then + fail "Node process died immediately!" + echo -e "${YELLOW}Last 30 lines of node log:${NC}" + tail -30 "$WORK_DIR/node.log" + die "Node crashed on startup" + fi + wait_for_node + log "Node is ready" +} + +stop_node() { + if [ -n "$NODE_PID" ] && kill -0 "$NODE_PID" 2>/dev/null; then + log "Stopping node (PID: $NODE_PID)..." + kill "$NODE_PID" + wait "$NODE_PID" 2>/dev/null || true + NODE_PID="" + sleep 2 + log "Node stopped" + fi +} + +# --------------- Block production via Engine API --------------- + +load_head() { + local block + block=$(rpc_call "eth_getBlockByNumber" "[\"latest\", false]" | jq -r '.result') + HEAD_HASH=$(echo "$block" | jq -r '.hash') + HEAD_NUMBER=$(printf "%d" "$(echo "$block" | jq -r '.number')") + HEAD_TIMESTAMP=$(printf "%d" "$(echo "$block" | jq -r '.timestamp')") +} + +build_block() { + local next_ts=$((HEAD_TIMESTAMP + 12)) + local next_ts_hex + next_ts_hex=$(printf "0x%x" $next_ts) + local prev_randao="0x$(openssl rand -hex 32)" + local fee_recipient="0x0000000000000000000000000000000000000000" + local beacon_root="0x0000000000000000000000000000000000000000000000000000000000000000" + + info "Building block $((HEAD_NUMBER + 1))..." + + # 1) forkchoiceUpdatedV3 — request new payload + local fcu_resp + fcu_resp=$(engine_call "engine_forkchoiceUpdatedV3" "[ + {\"headBlockHash\":\"$HEAD_HASH\",\"safeBlockHash\":\"$HEAD_HASH\",\"finalizedBlockHash\":\"$HEAD_HASH\"}, + {\"timestamp\":\"$next_ts_hex\",\"prevRandao\":\"$prev_randao\",\"suggestedFeeRecipient\":\"$fee_recipient\",\"withdrawals\":[],\"parentBeaconBlockRoot\":\"$beacon_root\"} + ]") + + local status + status=$(echo "$fcu_resp" | jq -r '.result.payloadStatus.status') + local payload_id + payload_id=$(echo "$fcu_resp" | jq -r '.result.payloadId') + + if [ "$status" != "VALID" ]; then + echo "$fcu_resp" | jq . + die "forkchoiceUpdatedV3 status=$status (expected VALID)" + fi + [ "$payload_id" != "null" ] && [ -n "$payload_id" ] || die "No payloadId returned" + + # 2) getPayload — try V5 (Osaka), V4 (Prague), V3 (Cancun) in order + sleep 1 + local gp_resp gp_error gp_version + for gp_version in 5 4 3; do + gp_resp=$(engine_call "engine_getPayloadV${gp_version}" "[\"$payload_id\"]") + gp_error=$(echo "$gp_resp" | jq -r '.error.message // empty') + if [ -z "$gp_error" ]; then + break + fi + info "getPayloadV${gp_version} failed ($gp_error), trying next..." + done + [ -z "$gp_error" ] || die "All getPayload versions failed: $gp_error" + + local block_hash + block_hash=$(echo "$gp_resp" | jq -r '.result.executionPayload.blockHash') + [ "$block_hash" != "null" ] && [ -n "$block_hash" ] || { + echo "$gp_resp" | jq . + die "No blockHash in getPayloadV${gp_version} response" + } + + local exec_payload + exec_payload=$(echo "$gp_resp" | jq '.result.executionPayload') + + # Extract executionRequests if present (Prague/Osaka V4+) + local exec_requests + exec_requests=$(echo "$gp_resp" | jq '.result.executionRequests // empty') + + # 3) newPayload — match the version from getPayload + local np_resp np_error np_version + if [ -n "$exec_requests" ] && [ "$exec_requests" != "null" ]; then + # Try V5, V4 with executionRequests + for np_version in 5 4; do + np_resp=$(engine_call "engine_newPayloadV${np_version}" "[$exec_payload, [], \"$beacon_root\", $exec_requests]") + np_error=$(echo "$np_resp" | jq -r '.error.message // empty') + if [ -z "$np_error" ]; then + break + fi + info "newPayloadV${np_version} failed ($np_error), trying next..." + done + else + np_resp=$(engine_call "engine_newPayloadV3" "[$exec_payload, [], \"$beacon_root\"]") + np_error=$(echo "$np_resp" | jq -r '.error.message // empty') + fi + + local np_status + np_status=$(echo "$np_resp" | jq -r '.result.status') + if [ "$np_status" != "VALID" ]; then + echo "$np_resp" | jq . + die "newPayload status=$np_status (expected VALID)" + fi + + # 4) forkchoiceUpdatedV3 — finalize + local fin_resp + fin_resp=$(engine_call "engine_forkchoiceUpdatedV3" "[ + {\"headBlockHash\":\"$block_hash\",\"safeBlockHash\":\"$block_hash\",\"finalizedBlockHash\":\"$block_hash\"}, + null + ]") + + local fin_status + fin_status=$(echo "$fin_resp" | jq -r '.result.payloadStatus.status') + if [ "$fin_status" != "VALID" ]; then + echo "$fin_resp" | jq . + die "Finalize forkchoiceUpdatedV3 status=$fin_status" + fi + + # Update head + HEAD_HASH="$block_hash" + HEAD_NUMBER=$((HEAD_NUMBER + 1)) + HEAD_TIMESTAMP=$next_ts + + info "Block $HEAD_NUMBER ok (${HEAD_HASH:0:18}...)" +} + +# --------------- Storage checks --------------- + +get_storage() { + local slot="$1" + rpc_call "eth_getStorageAt" "[\"$WTIA_ADDRESS\", \"$slot\", \"latest\"]" | jq -r '.result' +} + +# Normalize hex to 66-char (0x + 64 hex digits) +normalize_hex() { + local val="$1" + # Remove 0x prefix + val="${val#0x}" + # Pad to 64 chars + printf "0x%064s" "$val" | tr ' ' '0' +} + +# =============================================================== +# MAIN +# =============================================================== + +echo "" +echo "============================================" +echo " Eden Hardfork Upgrade Path Test" +echo "============================================" +echo "" +log "Branch: $CURRENT_BRANCH" +log "Hardfork height: $HARDFORK_HEIGHT" +log "Work dir: $WORK_DIR" +echo "" + +# --- Step 1: Build binaries --- +log "STEP 1: Building binaries" + +log "Building eden binary ($CURRENT_BRANCH)..." +cd "$PROJECT_DIR" +cargo build --release --bin ev-reth 2>&1 | tail -5 +cp "$PROJECT_DIR/target/release/ev-reth" "$EDEN_BINARY" +info "Saved: $EDEN_BINARY" + +log "Building main binary (via temporary worktree)..." +MAIN_WORKTREE="$WORK_DIR/main-worktree" +# Use --detach to avoid conflicts when 'main' is checked out in another worktree +git -C "$PROJECT_DIR" worktree add --detach "$MAIN_WORKTREE" main --quiet +# Share CARGO_TARGET_DIR so we reuse the compilation cache +CARGO_TARGET_DIR="$PROJECT_DIR/target" cargo build --release --bin ev-reth \ + --manifest-path "$MAIN_WORKTREE/Cargo.toml" 2>&1 | tail -5 +cp "$PROJECT_DIR/target/release/ev-reth" "$MAIN_BINARY" +info "Saved: $MAIN_BINARY" +# Clean up worktree immediately +git -C "$PROJECT_DIR" worktree remove "$MAIN_WORKTREE" --force 2>/dev/null || true +MAIN_WORKTREE="" +echo "" + +# --- Step 2: Setup --- +log "STEP 2: Setup" +openssl rand -hex 32 > "$JWT_SECRET_FILE" +info "JWT secret: $JWT_SECRET_FILE" +info "Genesis: $GENESIS" +info "Datadir: $DATADIR" +echo "" + +# --- Step 3: Run main binary, produce blocks --- +log "STEP 3: Start main binary, produce $BLOCKS_BEFORE_UPGRADE blocks" +start_node "$MAIN_BINARY" +load_head +info "Genesis: block=$HEAD_NUMBER hash=${HEAD_HASH:0:18}..." + +for _ in $(seq 1 "$BLOCKS_BEFORE_UPGRADE"); do + build_block +done +echo "" + +# --- Step 4: Verify storage empty --- +log "STEP 4: Verify WTIA storage is empty (before hardfork)" +NAME_VAL=$(normalize_hex "$(get_storage '0x0')") +SYMBOL_VAL=$(normalize_hex "$(get_storage '0x1')") +DECIMALS_VAL=$(normalize_hex "$(get_storage '0x2')") +ZERO="0x0000000000000000000000000000000000000000000000000000000000000000" + +if [ "$NAME_VAL" = "$ZERO" ] && [ "$SYMBOL_VAL" = "$ZERO" ] && [ "$DECIMALS_VAL" = "$ZERO" ]; then + log "PASS: WTIA storage is empty before hardfork" +else + fail "WTIA storage is NOT empty before hardfork!" + info "name=$NAME_VAL symbol=$SYMBOL_VAL decimals=$DECIMALS_VAL" + die "Pre-hardfork check failed" +fi +echo "" + +# --- Step 5: Stop node --- +log "STEP 5: Stop main binary" +stop_node +echo "" + +# --- Step 6: Start eden binary --- +log "STEP 6: Start eden binary with --eden-hardfork-height $HARDFORK_HEIGHT" +start_node "$EDEN_BINARY" "--eden-hardfork-height" "$HARDFORK_HEIGHT" + +# After restart, the consensus engine doesn't remember the head. +# Blocks are in the DB, but we must tell the engine via forkchoiceUpdatedV3. +info "Restoring chain head to block $HEAD_NUMBER (${HEAD_HASH:0:18}...)..." +local_beacon_root="0x0000000000000000000000000000000000000000000000000000000000000000" +restore_resp=$(engine_call "engine_forkchoiceUpdatedV3" "[ + {\"headBlockHash\":\"$HEAD_HASH\",\"safeBlockHash\":\"$HEAD_HASH\",\"finalizedBlockHash\":\"$HEAD_HASH\"}, + null +]") +restore_status=$(echo "$restore_resp" | jq -r '.result.payloadStatus.status') +if [ "$restore_status" != "VALID" ]; then + echo "$restore_resp" | jq . + die "Failed to restore chain head after restart (status=$restore_status)" +fi + +# Verify head is correct now +load_head +info "Resumed at block $HEAD_NUMBER" + +if [ "$HEAD_NUMBER" -ne "$BLOCKS_BEFORE_UPGRADE" ]; then + die "Expected block $BLOCKS_BEFORE_UPGRADE, got $HEAD_NUMBER" +fi +echo "" + +# --- Step 7: Produce blocks to reach hardfork --- +log "STEP 7: Produce $BLOCKS_AFTER_UPGRADE blocks (reaching hardfork at block $HARDFORK_HEIGHT)" +for _ in $(seq 1 "$BLOCKS_AFTER_UPGRADE"); do + build_block +done +info "Current head: block $HEAD_NUMBER" +echo "" + +# --- Step 8: Verify storage after hardfork --- +log "STEP 8: Verify WTIA storage AFTER hardfork" +NAME_VAL=$(normalize_hex "$(get_storage '0x0')") +SYMBOL_VAL=$(normalize_hex "$(get_storage '0x1')") +DECIMALS_VAL=$(normalize_hex "$(get_storage '0x2')") + +info "NAME (slot 0): $NAME_VAL" +info "SYMBOL (slot 1): $SYMBOL_VAL" +info "DECIMALS (slot 2): $DECIMALS_VAL" +echo "" + +ALL_PASS=true + +if [ "$NAME_VAL" = "$EXPECTED_NAME" ]; then + log "PASS: NAME = 'Wrapped TIA'" +else + fail "NAME mismatch" + info "expected: $EXPECTED_NAME" + info "got: $NAME_VAL" + ALL_PASS=false +fi + +if [ "$SYMBOL_VAL" = "$EXPECTED_SYMBOL" ]; then + log "PASS: SYMBOL = 'WTIA'" +else + fail "SYMBOL mismatch" + info "expected: $EXPECTED_SYMBOL" + info "got: $SYMBOL_VAL" + ALL_PASS=false +fi + +if [ "$DECIMALS_VAL" = "$EXPECTED_DECIMALS" ]; then + log "PASS: DECIMALS = 18" +else + fail "DECIMALS mismatch" + info "expected: $EXPECTED_DECIMALS" + info "got: $DECIMALS_VAL" + ALL_PASS=false +fi + +# --- Cleanup --- +stop_node + +echo "" +echo "============================================" +if [ "$ALL_PASS" = true ]; then + echo -e " ${GREEN}ALL TESTS PASSED${NC}" + echo "============================================" + exit 0 +else + echo -e " ${RED}SOME TESTS FAILED${NC}" + echo "============================================" + echo "Check node log: $WORK_DIR/node.log" + exit 1 +fi