Seismic-Reth fork diff

diff: ignored:
+49034
-1794
+2330
-2902

TODO

diff --git reth/crates/seismic/evm/Cargo.toml seismic-reth/crates/seismic/evm/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..98bb7d6efc976da720325bb514b1ccebabc437cd --- /dev/null +++ seismic-reth/crates/seismic/evm/Cargo.toml @@ -0,0 +1,97 @@ +[package] +name = "reth-seismic-evm" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# seismic +seismic-enclave.workspace = true +seismic-alloy-genesis.workspace = true + +# Reth +reth-chainspec.workspace = true +reth-ethereum-forks.workspace = true +reth-evm = { workspace = true } +reth-primitives-traits.workspace = true +reth-execution-errors.workspace = true +reth-execution-types.workspace = true +reth-storage-errors.workspace = true +reth-consensus.workspace = true +reth-consensus-common.workspace = true + +# ethereum +alloy-eips.workspace = true +alloy-evm.workspace = true +alloy-seismic-evm.workspace = true +alloy-primitives.workspace = true +alloy-rpc-types-engine.workspace = true +seismic-alloy-consensus.workspace = true +alloy-consensus.workspace = true + +reth-seismic-chainspec.workspace = true +reth-seismic-forks.workspace = true +reth-seismic-primitives = { workspace = true } +reth-ethereum-primitives = { workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"]} + +# revm +revm = { workspace = true} +seismic-revm.workspace = true + +# misc +derive_more.workspace = true +tracing.workspace = true +thiserror.workspace = true +schnorrkel.workspace = true + +[dev-dependencies] +reth-evm = { workspace = true, features = ["test-utils"] } +reth-revm = { workspace = true, features = ["test-utils"] } +reth-seismic-chainspec.workspace = true +alloy-genesis.workspace = true +alloy-consensus.workspace = true +reth-seismic-primitives = { workspace = true, features = ["arbitrary"] } +reth-testing-utils.workspace = true +secp256k1.workspace = true +revm-state.workspace = true +k256.workspace = true + +[features] +default = ["std"] +timestamp-in-seconds = [ + "revm/timestamp-in-seconds", + "seismic-revm/timestamp-in-seconds", + "reth-seismic-chainspec/timestamp-in-seconds", + "alloy-evm/timestamp-in-seconds", + "alloy-seismic-evm/timestamp-in-seconds" +] +std = [ + "reth-consensus/std", + "reth-revm/std", + "alloy-consensus/std", + "alloy-eips/std", + "alloy-genesis/std", + "alloy-primitives/std", + "reth-primitives-traits/std", + "revm/std", + "reth-seismic-primitives/std", + "reth-ethereum-forks/std", + "derive_more/std", + "thiserror/std", + "seismic-alloy-consensus/std", + "reth-chainspec/std", + "reth-consensus-common/std", + "reth-seismic-chainspec/std", + "reth-execution-errors/std", + "reth-execution-types/std", + "alloy-evm/std", + "reth-evm/std", + "tracing/std", +] +portable = ["reth-revm/portable"]
diff --git reth/crates/seismic/evm/src/build.rs seismic-reth/crates/seismic/evm/src/build.rs new file mode 100644 index 0000000000000000000000000000000000000000..29e9e4a97361d743d3893f8a6b65a10f4eeeb8bc --- /dev/null +++ seismic-reth/crates/seismic/evm/src/build.rs @@ -0,0 +1,135 @@ +//! The `SeismicBlockAssembler`. Nearly identical to the `EthBlockAssembler`, except with seismic +//! types + +use alloc::sync::Arc; +use alloy_consensus::{ + proofs, Block, BlockBody, BlockHeader, Header, Transaction, TxReceipt, EMPTY_OMMER_ROOT_HASH, +}; +use alloy_eips::merge::BEACON_NONCE; +use alloy_evm::block::BlockExecutorFactory; +use alloy_primitives::{logs_bloom, Bytes}; +use reth_chainspec::{EthChainSpec, EthereumHardforks}; +use reth_evm::{ + eth::EthBlockExecutionCtx, + execute::{BlockAssembler, BlockAssemblerInput}, +}; +use reth_execution_errors::BlockExecutionError; +use reth_execution_types::BlockExecutionResult; +use reth_seismic_primitives::{SeismicReceipt, SeismicTransactionSigned}; + +/// Block builder for Seismic. +#[derive(Debug, Clone)] +pub struct SeismicBlockAssembler<ChainSpec> { + /// The chainspec. + pub chain_spec: Arc<ChainSpec>, + /// Extra data to use for the blocks. + pub extra_data: Bytes, +} + +impl<ChainSpec> SeismicBlockAssembler<ChainSpec> { + /// Creates a new [`SeismicBlockAssembler`]. + pub fn new(chain_spec: Arc<ChainSpec>) -> Self { + Self { chain_spec, extra_data: Default::default() } + } +} + +impl<F, ChainSpec> BlockAssembler<F> for SeismicBlockAssembler<ChainSpec> +where + F: for<'a> BlockExecutorFactory< + ExecutionCtx<'a> = EthBlockExecutionCtx<'a>, + Transaction = SeismicTransactionSigned, + Receipt = SeismicReceipt, + >, + ChainSpec: EthChainSpec + EthereumHardforks, +{ + type Block = Block<SeismicTransactionSigned>; + + fn assemble_block( + &self, + input: BlockAssemblerInput<'_, '_, F>, + ) -> Result<Block<SeismicTransactionSigned>, BlockExecutionError> { + let BlockAssemblerInput { + evm_env, + execution_ctx: ctx, + parent, + transactions, + output: BlockExecutionResult { receipts, requests, gas_used }, + state_root, + .. + } = input; + + // EVM block env timestamp is in milliseconds when feature is disabled, seconds when enabled + let timestamp = evm_env.block_env.timestamp.saturating_to(); + + // For fork activation checks, we always need seconds + let timestamp_seconds = + if cfg!(feature = "timestamp-in-seconds") { timestamp } else { timestamp / 1000 }; + + let transactions_root = proofs::calculate_transaction_root(&transactions); + let receipts_root = SeismicReceipt::calculate_receipt_root_no_memo(receipts); + let logs_bloom = logs_bloom(receipts.iter().flat_map(|r| r.logs())); + + let withdrawals = self + .chain_spec + .is_shanghai_active_at_timestamp(timestamp_seconds) + .then(|| ctx.withdrawals.map(|w| w.into_owned()).unwrap_or_default()); + + let withdrawals_root = + withdrawals.as_deref().map(|w| proofs::calculate_withdrawals_root(w)); + let requests_hash = self + .chain_spec + .is_prague_active_at_timestamp(timestamp_seconds) + .then(|| requests.requests_hash()); + + let mut excess_blob_gas = None; + let mut blob_gas_used = None; + + // only determine cancun fields when active + if self.chain_spec.is_cancun_active_at_timestamp(timestamp_seconds) { + blob_gas_used = + Some(transactions.iter().map(|tx| tx.blob_gas_used().unwrap_or_default()).sum()); + excess_blob_gas = + if self.chain_spec.is_cancun_active_at_timestamp(parent.timestamp_seconds()) { + parent.maybe_next_block_excess_blob_gas( + self.chain_spec.blob_params_at_timestamp(timestamp_seconds), + ) + } else { + // for the first post-fork block, both parent.blob_gas_used and + // parent.excess_blob_gas are evaluated as 0 + Some( + alloy_eips::eip7840::BlobParams::cancun() + .next_block_excess_blob_gas_osaka(0, 0, 0), + ) + }; + } + + let header = Header { + parent_hash: ctx.parent_hash, + ommers_hash: EMPTY_OMMER_ROOT_HASH, + beneficiary: evm_env.block_env.beneficiary, + state_root, + transactions_root, + receipts_root, + withdrawals_root, + logs_bloom, + timestamp, + mix_hash: evm_env.block_env.prevrandao.unwrap_or_default(), + nonce: BEACON_NONCE.into(), + base_fee_per_gas: Some(evm_env.block_env.basefee), + number: evm_env.block_env.number.saturating_to(), + gas_limit: evm_env.block_env.gas_limit, + difficulty: evm_env.block_env.difficulty, + gas_used: *gas_used, + extra_data: self.extra_data.clone(), + parent_beacon_block_root: ctx.parent_beacon_block_root, + blob_gas_used, + excess_blob_gas, + requests_hash, + }; + + Ok(Block { + header, + body: BlockBody { transactions, ommers: Default::default(), withdrawals }, + }) + } +}
diff --git reth/crates/seismic/evm/src/config.rs seismic-reth/crates/seismic/evm/src/config.rs new file mode 100644 index 0000000000000000000000000000000000000000..c04d5e171d6f98be76dbe7786705873ce54a1c2f --- /dev/null +++ seismic-reth/crates/seismic/evm/src/config.rs @@ -0,0 +1,22 @@ +//! Helpers for configuring the `SeismicSpecId` for the evm + +use crate::Header; +use alloy_consensus::BlockHeader; +use reth_chainspec::ChainSpec as SeismicChainSpec; +use seismic_revm::SeismicSpecId; + +/// Map the latest active hardfork at the given header to a revm [`SeismicSpecId`]. +pub fn revm_spec(chain_spec: &SeismicChainSpec, header: &Header) -> SeismicSpecId { + revm_spec_by_timestamp_seismic(chain_spec, header.timestamp()) +} + +/// Map the latest active hardfork at the given timestamp or block number to a revm +/// [`SeismicSpecId`]. +/// +/// For now our only hardfork is MERCURY, so we only return MERCURY +const fn revm_spec_by_timestamp_seismic( + _chain_spec: &SeismicChainSpec, + _timestamp: u64, +) -> SeismicSpecId { + SeismicSpecId::MERCURY +}
diff --git reth/crates/seismic/evm/src/lib.rs seismic-reth/crates/seismic/evm/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..7cc3d23dd76c1b56d121ecbfc3765eb1962aa546 --- /dev/null +++ seismic-reth/crates/seismic/evm/src/lib.rs @@ -0,0 +1,936 @@ +//! EVM config for vanilla seismic. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" +)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +use alloc::{borrow::Cow, sync::Arc}; +use alloy_consensus::{BlockHeader, Header}; +use alloy_eips::{eip1559::INITIAL_BASE_FEE, Decodable2718}; +use alloy_evm::{eth::EthBlockExecutionCtx, EvmFactory}; +use alloy_primitives::{Bytes, U256}; +use alloy_rpc_types_engine::ExecutionData; +pub use alloy_seismic_evm::{block::SeismicBlockExecutorFactory, SeismicEvm, SeismicEvmFactory}; +use build::SeismicBlockAssembler; +use core::fmt::Debug; +use reth_chainspec::{ChainSpec, EthChainSpec}; +use reth_ethereum_forks::EthereumHardfork; +use reth_evm::{ + ConfigureEngineEvm, ConfigureEvm, EvmEnv, EvmEnvFor, ExecutableTxIterator, ExecutionCtxFor, + NextBlockEnvAttributes, +}; +use reth_primitives_traits::{SealedBlock, SealedHeader, SignedTransaction, TxTy}; +use reth_seismic_primitives::{SeismicBlock, SeismicPrimitives}; +use reth_storage_errors::any::AnyError; +use revm::{ + context::{BlockEnv, CfgEnv}, + context_interface::block::BlobExcessGasAndPrice, +}; +use seismic_revm::SeismicSpecId; +use std::convert::Infallible; + +mod receipts; +pub use receipts::*; +mod build; + +pub mod config; +use config::revm_spec; + +/// Seismic EVM configuration. +#[derive(Debug, Clone)] +pub struct SeismicEvmConfig { + /// Inner [`SeismicBlockExecutorFactory`]. + pub executor_factory: + SeismicBlockExecutorFactory<SeismicRethReceiptBuilder, Arc<ChainSpec>, SeismicEvmFactory>, + /// Seismic block assembler. + pub block_assembler: SeismicBlockAssembler<ChainSpec>, +} + +impl SeismicEvmConfig { + /// Creates a new Seismic EVM configuration with the given chain spec and purpose keys. + pub fn new( + chain_spec: Arc<ChainSpec>, + purpose_keys: &'static seismic_enclave::GetPurposeKeysResponse, + ) -> Self { + Self::new_with_evm_factory( + chain_spec, + SeismicEvmFactory::new_with_purpose_keys(purpose_keys), + purpose_keys, + ) + } + + /// Creates a new Ethereum EVM configuration with the given chain spec and EVM factory. + pub fn new_with_evm_factory( + chain_spec: Arc<ChainSpec>, + evm_factory: SeismicEvmFactory, + purpose_keys: &'static seismic_enclave::GetPurposeKeysResponse, + ) -> Self { + Self { + block_assembler: SeismicBlockAssembler::new(chain_spec.clone()), + executor_factory: SeismicBlockExecutorFactory::new( + SeismicRethReceiptBuilder::default(), + chain_spec, + evm_factory, + purpose_keys, + ), + } + } + + /// Returns the chain spec associated with this configuration. + pub const fn chain_spec(&self) -> &Arc<ChainSpec> { + self.executor_factory.spec() + } + + /// Sets the extra data for the block assembler. + pub fn with_extra_data(mut self, extra_data: Bytes) -> Self { + self.block_assembler.extra_data = extra_data; + self + } + + /// Creates an EVM with the pre-fetched purpose keys + pub fn evm_with_env_and_live_key<DB>( + &self, + db: DB, + evm_env: EvmEnv<SeismicSpecId>, + ) -> SeismicEvm<DB, revm::inspector::NoOpInspector> + where + DB: alloy_evm::Database, + { + self.executor_factory.evm_factory().create_evm(db, evm_env) + } +} + +impl ConfigureEvm for SeismicEvmConfig { + type Primitives = SeismicPrimitives; + type Error = Infallible; + type NextBlockEnvCtx = NextBlockEnvAttributes; + type BlockExecutorFactory = + SeismicBlockExecutorFactory<SeismicRethReceiptBuilder, Arc<ChainSpec>, SeismicEvmFactory>; + type BlockAssembler = SeismicBlockAssembler<ChainSpec>; + + fn block_executor_factory(&self) -> &Self::BlockExecutorFactory { + &self.executor_factory + } + + fn block_assembler(&self) -> &Self::BlockAssembler { + &self.block_assembler + } + + fn evm_env(&self, header: &Header) -> EvmEnv<SeismicSpecId> { + // TODO: use the correct spec id + let spec = SeismicSpecId::MERCURY; + + // configure evm env based on parent block + let cfg_env = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec); + + let block_env = BlockEnv { + number: U256::from(header.number()), + beneficiary: header.beneficiary(), + timestamp: U256::from(header.timestamp()), + difficulty: U256::ZERO, + prevrandao: header.mix_hash(), /* Seismic genesis spec (Mercury) starts after Paris, + * so we always use header.mix_hash() */ + gas_limit: header.gas_limit(), + basefee: header.base_fee_per_gas().unwrap_or_default(), + // EIP-4844 excess blob gas of this block, introduced in Cancun + blob_excess_gas_and_price: header.excess_blob_gas.map(|excess_blob_gas| { + BlobExcessGasAndPrice::new_with_spec(excess_blob_gas, spec.into_eth_spec()) + }), + }; + + EvmEnv { cfg_env, block_env } + } + + fn next_evm_env( + &self, + parent: &Header, + attributes: &NextBlockEnvAttributes, + ) -> Result<EvmEnv<SeismicSpecId>, Self::Error> { + let spec_id = revm_spec(self.chain_spec(), parent); + + // configure evm env based on parent block + let cfg = CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec_id); + + // if the parent block did not have excess blob gas (i.e. it was pre-cancun), but it is + // cancun now, we need to set the excess blob gas to the default value(0) + let blob_excess_gas_and_price = parent + .maybe_next_block_excess_blob_gas( + self.chain_spec().blob_params_at_timestamp(attributes.timestamp_seconds()), + ) + .map(|gas| BlobExcessGasAndPrice::new_with_spec(gas, spec_id.into_eth_spec())); + + let mut basefee = parent.next_block_base_fee( + self.chain_spec().base_fee_params_at_timestamp(attributes.timestamp_seconds()), + ); + + let mut gas_limit = attributes.gas_limit; + + // If we are on the London fork boundary, we need to multiply the parent's gas limit by the + // elasticity multiplier to get the new gas limit. + if self.chain_spec().fork(EthereumHardfork::London).transitions_at_block(parent.number + 1) + { + let elasticity_multiplier = self + .chain_spec() + .base_fee_params_at_timestamp(attributes.timestamp_seconds()) + .elasticity_multiplier; + + // multiply the gas limit by the elasticity multiplier + gas_limit *= elasticity_multiplier as u64; + + // set the base fee to the initial base fee from the EIP-1559 spec + basefee = Some(INITIAL_BASE_FEE) + } + + let block_env = BlockEnv { + number: U256::from(parent.number + 1), + beneficiary: attributes.suggested_fee_recipient, + // When timestamp-in-seconds is disabled, EVM should use milliseconds + timestamp: U256::from(attributes.timestamp), + difficulty: U256::ZERO, + prevrandao: Some(attributes.prev_randao), + gas_limit, + // calculate basefee based on parent block's gas usage + basefee: basefee.unwrap_or_default(), + // calculate excess gas based on parent block's blob gas usage + blob_excess_gas_and_price, + }; + + Ok((cfg, block_env).into()) + } + + fn context_for_block<'a>( + &self, + block: &'a SealedBlock<SeismicBlock>, + ) -> EthBlockExecutionCtx<'a> { + EthBlockExecutionCtx { + parent_hash: block.header().parent_hash, + parent_beacon_block_root: block.header().parent_beacon_block_root, + ommers: &block.body().ommers, + withdrawals: block.body().withdrawals.as_ref().map(Cow::Borrowed), + } + } + + fn context_for_next_block( + &self, + parent: &SealedHeader, + attributes: Self::NextBlockEnvCtx, + ) -> EthBlockExecutionCtx<'_> { + EthBlockExecutionCtx { + parent_hash: parent.hash(), + parent_beacon_block_root: attributes.parent_beacon_block_root, + ommers: &[], + withdrawals: attributes.withdrawals.map(Cow::Owned), + } + } + + /// Override to use pre-fetched live RNG key + fn evm_with_env<DB: alloy_evm::Database>( + &self, + db: DB, + evm_env: EvmEnv<SeismicSpecId>, + ) -> SeismicEvm<DB, revm::inspector::NoOpInspector> { + self.evm_with_env_and_live_key(db, evm_env) + } +} + +impl ConfigureEngineEvm<ExecutionData> for SeismicEvmConfig { + fn evm_env_for_payload(&self, payload: &ExecutionData) -> EvmEnvFor<Self> { + // Create a temporary header with the payload information to determine the spec + let temp_header = Header { + number: payload.payload.block_number(), + timestamp: payload.payload.timestamp(), + gas_limit: payload.payload.gas_limit(), + beneficiary: payload.payload.fee_recipient(), + ..Default::default() + }; + let spec_id = revm_spec(self.chain_spec(), &temp_header); + + let cfg_env = + CfgEnv::new().with_chain_id(self.chain_spec().chain().id()).with_spec(spec_id); + + let blob_excess_gas_and_price = payload + .payload + .blob_gas_used() + .map(|_gas| BlobExcessGasAndPrice::new_with_spec(0, spec_id.into_eth_spec())); + + let block_env = BlockEnv { + number: U256::from(payload.payload.block_number()), + beneficiary: payload.payload.fee_recipient(), + timestamp: U256::from(payload.payload.timestamp()), + difficulty: U256::ZERO, + prevrandao: Some(payload.payload.prev_randao()), + gas_limit: payload.payload.gas_limit(), + basefee: payload.payload.saturated_base_fee_per_gas(), + blob_excess_gas_and_price, + }; + + (cfg_env, block_env).into() + } + + fn context_for_payload<'a>(&self, payload: &'a ExecutionData) -> ExecutionCtxFor<'a, Self> { + EthBlockExecutionCtx { + parent_hash: payload.payload.parent_hash(), + parent_beacon_block_root: payload.sidecar.parent_beacon_block_root(), + ommers: &[], + withdrawals: payload.payload.withdrawals().map(|w| Cow::Owned(w.clone().into())), + } + } + + fn tx_iterator_for_payload(&self, payload: &ExecutionData) -> impl ExecutableTxIterator<Self> { + payload.payload.transactions().clone().into_iter().map(|tx| { + let mut tx_data = tx.as_ref(); + let tx = TxTy::<Self::Primitives>::decode_2718(&mut tx_data).map_err(AnyError::new)?; + let signer = tx.try_recover().map_err(AnyError::new)?; + Ok::<_, AnyError>(tx.with_signer(signer)) + }) + } +} + +#[cfg(test)] +#[allow(clippy::expect_used)] // Test code - expect on failure is acceptable +#[allow(clippy::unwrap_used)] // Test code - unwrap on failure is acceptable +#[allow(clippy::panic)] // Test code - panic on failure is acceptable +mod tests { + use super::*; + use alloy_consensus::{Header, Receipt}; + use alloy_eips::eip7685::Requests; + use alloy_evm::Evm; + use alloy_genesis::Genesis; + use alloy_primitives::{bytes, map::HashMap, Address, LogData, B256}; + use reth_chainspec::ChainSpec; + use reth_evm::execute::ProviderError; + use reth_execution_types::{ + AccountRevertInit, BundleStateInit, Chain, ExecutionOutcome, RevertsInit, + }; + use reth_primitives_traits::{Account, RecoveredBlock}; + use reth_seismic_chainspec::SEISMIC_MAINNET; + use reth_seismic_primitives::{SeismicBlock, SeismicPrimitives, SeismicReceipt}; + use revm::{ + database::{BundleState, CacheDB}, + database_interface::EmptyDBTyped, + handler::PrecompileProvider, + inspector::NoOpInspector, + precompile::u64_to_address, + primitives::Log, + state::AccountInfo, + }; + use seismic_enclave::{ + get_unsecure_sample_schnorrkel_keypair, get_unsecure_sample_secp256k1_pk, + get_unsecure_sample_secp256k1_sk, GetPurposeKeysResponse, + }; + use std::sync::Arc; + + fn test_evm_config() -> SeismicEvmConfig { + // Get mock purpose keys for testing + let mock_keys = Box::leak(Box::new(get_mock_keys())); + + SeismicEvmConfig::new(SEISMIC_MAINNET.clone(), mock_keys) + } + + fn get_mock_keys() -> GetPurposeKeysResponse { + GetPurposeKeysResponse { + tx_io_sk: get_unsecure_sample_secp256k1_sk(), + tx_io_pk: get_unsecure_sample_secp256k1_pk(), + snapshot_key_bytes: [0u8; 32], + rng_keypair: get_unsecure_sample_schnorrkel_keypair(), + } + } + + #[test] + fn test_fill_cfg_and_block_env() { + // Create a default header + let header = Header::default(); + + // Build the ChainSpec for Ethereum mainnet, activating London, Paris, and Shanghai + // hardforks + let chain_spec = ChainSpec::builder() + .chain(0.into()) + .genesis(Genesis::default()) + .london_activated() + .paris_activated() + .shanghai_activated() + .build(); + + // Use the `SeismicEvmConfig` to create the `cfg_env` and `block_env` based on the + // ChainSpec, Header, and total difficulty + let mock_keys = Box::leak(Box::new(get_mock_keys())); + let EvmEnv { cfg_env, .. } = + SeismicEvmConfig::new(Arc::new(chain_spec.clone()), mock_keys).evm_env(&header); + + // Assert that the chain ID in the `cfg_env` is correctly set to the chain ID of the + // ChainSpec + assert_eq!(cfg_env.chain_id, chain_spec.chain().id()); + } + + #[test] + fn test_seismic_evm_with_env_default_spec() { + // Setup the EVM with test config and environment + let evm_config = test_evm_config(); // Provides SeismicEvm config with Seismic mainnet spec + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + let evm_env = EvmEnv::default(); + let evm: SeismicEvm<_, NoOpInspector> = evm_config.evm_with_env(db, evm_env.clone()); + let precompiles = evm.precompiles().clone(); + + // Check that the EVM environment is correctly set + assert_eq!(evm.cfg, evm_env.cfg_env); + assert_eq!(evm.cfg.spec, SeismicSpecId::MERCURY); + + // Check that the expected number of precompiles is set + let precompile_addresses = + [u64_to_address(101), u64_to_address(102), u64_to_address(103), u64_to_address(104)]; + for &addr in &precompile_addresses { + let is_contained = precompiles.contains(&addr); + assert!( + is_contained, + "Expected Precompile at address for RETH evm generation {addr:?}" + ); + } + } + + #[test] + fn test_evm_with_env_custom_cfg() { + let evm_config = test_evm_config(); + + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + + // Create a custom configuration environment with a chain ID of 111 + let cfg = CfgEnv::new().with_chain_id(111).with_spec(SeismicSpecId::default()); + + let evm_env = EvmEnv { cfg_env: cfg.clone(), ..Default::default() }; + + let evm = evm_config.evm_with_env(db, evm_env); + + // Check that the EVM environment is initialized with the custom environment + assert_eq!(evm.cfg, cfg); + } + + #[test] + fn test_evm_with_env_custom_block_and_tx() { + let evm_config = test_evm_config(); + + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + + // Create customs block and tx env + let block = BlockEnv { + basefee: 1000, + gas_limit: 10_000_000, + number: U256::from(42), + ..Default::default() + }; + + let evm_env = EvmEnv { block_env: block, ..Default::default() }; + + let evm = evm_config.evm_with_env(db, evm_env.clone()); + + // Verify that the block and transaction environments are set correctly + assert_eq!(evm.block, evm_env.block_env); + } + + #[test] + fn test_evm_with_spec_id() { + let evm_config = test_evm_config(); + + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + + let evm_env = EvmEnv { + cfg_env: CfgEnv::new().with_spec(SeismicSpecId::MERCURY), + ..Default::default() + }; + + let evm = evm_config.evm_with_env(db, evm_env.clone()); + + assert_eq!(evm.cfg, evm_env.cfg_env); + } + + #[test] + fn test_evm_with_env_and_default_inspector() { + let evm_config = test_evm_config(); + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + + let evm_env = EvmEnv { cfg_env: Default::default(), ..Default::default() }; + + let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector {}); + + // Check that the EVM environment is set to default values + assert_eq!(*evm.block(), evm_env.block_env); + assert_eq!(evm.cfg, evm_env.cfg_env); + } + + #[test] + fn test_evm_with_env_inspector_and_custom_cfg() { + let evm_config = test_evm_config(); + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + + let cfg = CfgEnv::new().with_chain_id(111).with_spec(SeismicSpecId::MERCURY); + let block = BlockEnv::default(); + let evm_env = EvmEnv { block_env: block, cfg_env: cfg.clone() }; + + let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector {}); + + // Check that the EVM environment is set with custom configuration + assert_eq!(evm.cfg, cfg); + assert_eq!(evm.block, evm_env.block_env); + } + + #[test] + fn test_evm_with_env_inspector_and_custom_block_tx() { + let evm_config = test_evm_config(); + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + + // Create custom block and tx environment + let block = BlockEnv { + basefee: 1000, + gas_limit: 10_000_000, + number: U256::from(42), + ..Default::default() + }; + let evm_env = EvmEnv { block_env: block, ..Default::default() }; + + let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector {}); + + // Verify that the block and transaction environments are set correctly + assert_eq!(evm.block, evm_env.block_env); + } + + #[test] + fn test_evm_with_env_inspector_and_spec_id() { + let evm_config = test_evm_config(); + let db = CacheDB::<EmptyDBTyped<ProviderError>>::default(); + + let evm_env = EvmEnv { + cfg_env: CfgEnv::new().with_spec(SeismicSpecId::MERCURY), + ..Default::default() + }; + + let evm = evm_config.evm_with_env_and_inspector(db, evm_env.clone(), NoOpInspector {}); + + // Check that the spec ID is set properly + assert_eq!(evm.cfg, evm_env.cfg_env); + assert_eq!(evm.block, evm_env.block_env); + } + + #[test] + fn receipts_by_block_hash() { + // Create a default recovered block + let block: RecoveredBlock<SeismicBlock> = Default::default(); + + // Define block hashes for block1 and block2 + let block1_hash = B256::new([0x01; 32]); + let block2_hash = B256::new([0x02; 32]); + + // Clone the default block into block1 and block2 + let mut block1 = block.clone(); + let mut block2 = block; + + // Set the hashes of block1 and block2 + block1.set_block_number(10); + block1.set_hash(block1_hash); + + block2.set_block_number(11); + block2.set_hash(block2_hash); + + // Create a random receipt object, receipt1 + let receipt1 = SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![], + status: true.into(), + }); + + // Create another random receipt object, receipt2 + let receipt2 = SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 1325345, + logs: vec![], + status: true.into(), + }); + + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![vec![receipt1.clone()], vec![receipt2]]; + + // Create an ExecutionOutcome object with the created bundle, receipts, an empty requests + // vector, and first_block set to 10 + let execution_outcome = ExecutionOutcome::<SeismicReceipt> { + bundle: Default::default(), + receipts, + requests: vec![], + first_block: 10, + }; + + // Create a Chain object with a BTreeMap of blocks mapped to their block numbers, + // including block1_hash and block2_hash, and the execution_outcome + let chain: Chain<SeismicPrimitives> = + Chain::new([block1, block2], execution_outcome.clone(), None); + + // Assert that the proper receipt vector is returned for block1_hash + assert_eq!(chain.receipts_by_block_hash(block1_hash), Some(vec![&receipt1])); + + // Create an ExecutionOutcome object with a single receipt vector containing receipt1 + let execution_outcome1 = ExecutionOutcome { + bundle: Default::default(), + receipts: vec![vec![receipt1]], + requests: vec![], + first_block: 10, + }; + + // Assert that the execution outcome at the first block contains only the first receipt + assert_eq!(chain.execution_outcome_at_block(10), Some(execution_outcome1)); + + // Assert that the execution outcome at the tip block contains the whole execution outcome + assert_eq!(chain.execution_outcome_at_block(11), Some(execution_outcome)); + } + + #[test] + fn test_initialisation() { + // Create a new BundleState object with initial data + let bundle = BundleState::new( + vec![(Address::new([2; 20]), None, Some(AccountInfo::default()), HashMap::default())], + vec![vec![(Address::new([2; 20]), None, vec![])]], + vec![], + ); + + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![vec![Some(SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![], + status: true.into(), + }))]]; + + // Create a Requests object with a vector of requests + let requests = vec![Requests::new(vec![bytes!("dead"), bytes!("beef"), bytes!("beebee")])]; + + // Define the first block number + let first_block = 123; + + // Create a ExecutionOutcome object with the created bundle, receipts, requests, and + // first_block + let exec_res = ExecutionOutcome { + bundle: bundle.clone(), + receipts: receipts.clone(), + requests: requests.clone(), + first_block, + }; + + // Assert that creating a new ExecutionOutcome using the constructor matches exec_res + assert_eq!( + ExecutionOutcome::new(bundle, receipts.clone(), first_block, requests.clone()), + exec_res + ); + + // Create a BundleStateInit object and insert initial data + let mut state_init: BundleStateInit = HashMap::default(); + state_init + .insert(Address::new([2; 20]), (None, Some(Account::default()), HashMap::default())); + + // Create a HashMap for account reverts and insert initial data + let mut revert_inner: HashMap<Address, AccountRevertInit> = HashMap::default(); + revert_inner.insert(Address::new([2; 20]), (None, vec![])); + + // Create a RevertsInit object and insert the revert_inner data + let mut revert_init: RevertsInit = HashMap::default(); + revert_init.insert(123, revert_inner); + + // Assert that creating a new ExecutionOutcome using the new_init method matches + // exec_res + assert_eq!( + ExecutionOutcome::new_init( + state_init, + revert_init, + vec![], + receipts, + first_block, + requests, + ), + exec_res + ); + } + + #[test] + fn test_block_number_to_index() { + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![vec![Some(SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![], + status: true.into(), + }))]]; + + // Define the first block number + let first_block = 123; + + // Create a ExecutionOutcome object with the created bundle, receipts, requests, and + // first_block + let exec_res = ExecutionOutcome { + bundle: Default::default(), + receipts, + requests: vec![], + first_block, + }; + + // Test before the first block + assert_eq!(exec_res.block_number_to_index(12), None); + + // Test after after the first block but index larger than receipts length + assert_eq!(exec_res.block_number_to_index(133), None); + + // Test after the first block + assert_eq!(exec_res.block_number_to_index(123), Some(0)); + } + + #[test] + fn test_get_logs() { + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![vec![SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![Log::<LogData>::default()], + status: true.into(), + })]]; + + // Define the first block number + let first_block = 123; + + // Create a ExecutionOutcome object with the created bundle, receipts, requests, and + // first_block + let exec_res = ExecutionOutcome { + bundle: Default::default(), + receipts, + requests: vec![], + first_block, + }; + + // Get logs for block number 123 + let logs: Vec<&Log> = exec_res.logs(123).unwrap().collect(); + + // Assert that the logs match the expected logs + assert_eq!(logs, vec![&Log::<LogData>::default()]); + } + + #[test] + fn test_receipts_by_block() { + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![vec![Some(SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![Log::<LogData>::default()], + status: true.into(), + }))]]; + + // Define the first block number + let first_block = 123; + + // Create a ExecutionOutcome object with the created bundle, receipts, requests, and + // first_block + let exec_res = ExecutionOutcome { + bundle: Default::default(), // Default value for bundle + receipts, // Include the created receipts + requests: vec![], // Empty vector for requests + first_block, // Set the first block number + }; + + // Get receipts for block number 123 and convert the result into a vector + let receipts_by_block: Vec<_> = exec_res.receipts_by_block(123).iter().collect(); + + // Assert that the receipts for block number 123 match the expected receipts + assert_eq!( + receipts_by_block, + vec![&Some(SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![Log::<LogData>::default()], + status: true.into(), + }))] + ); + } + + #[test] + fn test_receipts_len() { + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![vec![Some(SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![Log::<LogData>::default()], + status: true.into(), + }))]]; + + // Create an empty Receipts object + let receipts_empty = vec![]; + + // Define the first block number + let first_block = 123; + + // Create a ExecutionOutcome object with the created bundle, receipts, requests, and + // first_block + let exec_res = ExecutionOutcome { + bundle: Default::default(), // Default value for bundle + receipts, // Include the created receipts + requests: vec![], // Empty vector for requests + first_block, // Set the first block number + }; + + // Assert that the length of receipts in exec_res is 1 + assert_eq!(exec_res.len(), 1); + + // Assert that exec_res is not empty + assert!(!exec_res.is_empty()); + + // Create a ExecutionOutcome object with an empty Receipts object + let exec_res_empty_receipts: ExecutionOutcome<SeismicReceipt> = ExecutionOutcome { + bundle: Default::default(), // Default value for bundle + receipts: receipts_empty, // Include the empty receipts + requests: vec![], // Empty vector for requests + first_block, // Set the first block number + }; + + // Assert that the length of receipts in exec_res_empty_receipts is 0 + assert_eq!(exec_res_empty_receipts.len(), 0); + + // Assert that exec_res_empty_receipts is empty + assert!(exec_res_empty_receipts.is_empty()); + } + + #[test] + fn test_revert_to() { + // Create a random receipt object + let receipt = SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![], + status: true.into(), + }); + + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![vec![Some(receipt.clone())], vec![Some(receipt.clone())]]; + + // Define the first block number + let first_block = 123; + + // Create a request. + let request = bytes!("deadbeef"); + + // Create a vector of Requests containing the request. + let requests = + vec![Requests::new(vec![request.clone()]), Requests::new(vec![request.clone()])]; + + // Create a ExecutionOutcome object with the created bundle, receipts, requests, and + // first_block + let mut exec_res = + ExecutionOutcome { bundle: Default::default(), receipts, requests, first_block }; + + // Assert that the revert_to method returns true when reverting to the initial block number. + assert!(exec_res.revert_to(123)); + + // Assert that the receipts are properly cut after reverting to the initial block number. + assert_eq!(exec_res.receipts, vec![vec![Some(receipt)]]); + + // Assert that the requests are properly cut after reverting to the initial block number. + assert_eq!(exec_res.requests, vec![Requests::new(vec![request])]); + + // Assert that the revert_to method returns false when attempting to revert to a block + // number greater than the initial block number. + assert!(!exec_res.revert_to(133)); + + // Assert that the revert_to method returns false when attempting to revert to a block + // number less than the initial block number. + assert!(!exec_res.revert_to(10)); + } + + #[test] + fn test_extend_execution_outcome() { + // Create a Receipt object with specific attributes. + let receipt = SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![], + status: true.into(), + }); + + // Create a Receipts object containing the receipt. + let receipts = vec![vec![Some(receipt.clone())]]; + + // Create a request. + let request = bytes!("deadbeef"); + + // Create a vector of Requests containing the request. + let requests = vec![Requests::new(vec![request.clone()])]; + + // Define the initial block number. + let first_block = 123; + + // Create an ExecutionOutcome object. + let mut exec_res = + ExecutionOutcome { bundle: Default::default(), receipts, requests, first_block }; + + // Extend the ExecutionOutcome object by itself. + exec_res.extend(exec_res.clone()); + + // Assert the extended ExecutionOutcome matches the expected outcome. + assert_eq!( + exec_res, + ExecutionOutcome { + bundle: Default::default(), + receipts: vec![vec![Some(receipt.clone())], vec![Some(receipt)]], + requests: vec![Requests::new(vec![request.clone()]), Requests::new(vec![request])], + first_block: 123, + } + ); + } + + #[test] + fn test_split_at_execution_outcome() { + // Create a random receipt object + let receipt = SeismicReceipt::Legacy(Receipt { + cumulative_gas_used: 46913, + logs: vec![], + status: true.into(), + }); + + // Create a Receipts object with a vector of receipt vectors + let receipts = vec![ + vec![Some(receipt.clone())], + vec![Some(receipt.clone())], + vec![Some(receipt.clone())], + ]; + + // Define the first block number + let first_block = 123; + + // Create a request. + let request = bytes!("deadbeef"); + + // Create a vector of Requests containing the request. + let requests = vec![ + Requests::new(vec![request.clone()]), + Requests::new(vec![request.clone()]), + Requests::new(vec![request.clone()]), + ]; + + // Create a ExecutionOutcome object with the created bundle, receipts, requests, and + // first_block + let exec_res = + ExecutionOutcome { bundle: Default::default(), receipts, requests, first_block }; + + // Split the ExecutionOutcome at block number 124 + let result = exec_res.clone().split_at(124); + + // Define the expected lower ExecutionOutcome after splitting + let lower_execution_outcome = ExecutionOutcome { + bundle: Default::default(), + receipts: vec![vec![Some(receipt.clone())]], + requests: vec![Requests::new(vec![request.clone()])], + first_block, + }; + + // Define the expected higher ExecutionOutcome after splitting + let higher_execution_outcome = ExecutionOutcome { + bundle: Default::default(), + receipts: vec![vec![Some(receipt.clone())], vec![Some(receipt)]], + requests: vec![Requests::new(vec![request.clone()]), Requests::new(vec![request])], + first_block: 124, + }; + + // Assert that the split result matches the expected lower and higher outcomes + assert_eq!(result.0, Some(lower_execution_outcome)); + assert_eq!(result.1, higher_execution_outcome); + + // Assert that splitting at the first block number returns None for the lower outcome + assert_eq!(exec_res.clone().split_at(123), (None, exec_res)); + } +}
diff --git reth/crates/seismic/evm/src/receipts.rs seismic-reth/crates/seismic/evm/src/receipts.rs new file mode 100644 index 0000000000000000000000000000000000000000..92f0ccbe5354f63dbb9aa088a6cd1f91a353f7a6 --- /dev/null +++ seismic-reth/crates/seismic/evm/src/receipts.rs @@ -0,0 +1,39 @@ +use alloy_consensus::{Eip658Value, Receipt}; +use alloy_evm::eth::receipt_builder::{ReceiptBuilder, ReceiptBuilderCtx}; +use reth_evm::Evm; +use reth_seismic_primitives::{SeismicReceipt, SeismicTransactionSigned}; +use seismic_alloy_consensus::SeismicTxType; + +/// A builder that operates on seismic-reth primitive types, specifically +/// [`SeismicTransactionSigned`] and [`SeismicReceipt`]. +/// +/// Why is this different than `SeismicAlloyReceiptBuilder` in seismic-evm? Can we reuse code? +#[derive(Debug, Default, Clone, Copy)] +#[non_exhaustive] +pub struct SeismicRethReceiptBuilder; + +impl ReceiptBuilder for SeismicRethReceiptBuilder { + type Transaction = SeismicTransactionSigned; + type Receipt = SeismicReceipt; + + fn build_receipt<E: Evm>( + &self, + ctx: ReceiptBuilderCtx<'_, SeismicTransactionSigned, E>, + ) -> Self::Receipt { + let ty = ctx.tx.tx_type(); + let receipt = Receipt { + status: Eip658Value::Eip658(ctx.result.is_success()), + cumulative_gas_used: ctx.cumulative_gas_used, + logs: ctx.result.into_logs(), + }; + + match ty { + SeismicTxType::Legacy => SeismicReceipt::Legacy(receipt), + SeismicTxType::Eip1559 => SeismicReceipt::Eip1559(receipt), + SeismicTxType::Eip2930 => SeismicReceipt::Eip2930(receipt), + SeismicTxType::Eip4844 => SeismicReceipt::Eip4844(receipt), + SeismicTxType::Eip7702 => SeismicReceipt::Eip7702(receipt), + SeismicTxType::Seismic => SeismicReceipt::Seismic(receipt), + } + } +}
diff --git reth/crates/seismic/node/Cargo.toml seismic-reth/crates/seismic/node/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..6d5e4be027042dec4332e83079d925e71f53a8e5 --- /dev/null +++ seismic-reth/crates/seismic/node/Cargo.toml @@ -0,0 +1,166 @@ +[package] +name = "reth-seismic-node" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +seismic-enclave.workspace = true + +# seismic-reth +reth-seismic-payload-builder.workspace = true +reth-seismic-evm.workspace = true +reth-seismic-rpc.workspace = true +reth-seismic-txpool.workspace = true +reth-seismic-chainspec = { workspace = true, optional = true } +reth-seismic-primitives = { workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"] } + +# reth +reth-chainspec.workspace = true +reth-primitives-traits.workspace = true +reth-payload-builder.workspace = true +# reth-codecs.workspace = true +reth-consensus.workspace = true +reth-node-api.workspace = true +reth-node-core.workspace = true +reth-node-builder.workspace = true +reth-provider.workspace = true +reth-transaction-pool.workspace = true +reth-network.workspace = true +reth-evm.workspace = true +reth-rpc-server-types.workspace = true +reth-rpc-eth-api.workspace = true +reth-rpc-eth-types.workspace = true +reth-rpc-api.workspace = true +reth-node-ethereum.workspace = true +reth-payload-primitives.workspace = true +reth-engine-primitives.workspace = true +reth-engine-local.workspace = true +reth-eth-wire-types.workspace = true +reth-rpc.workspace = true +reth-rpc-builder.workspace = true +reth-ethereum-payload-builder.workspace = true + +# revm +revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] } + +# alloy +alloy-consensus.workspace = true +alloy-eips.workspace = true +alloy-primitives.workspace = true +alloy-rpc-types-engine.workspace = true +alloy-rpc-types-eth.workspace = true + +seismic-alloy-consensus.workspace = true +seismic-alloy-rpc-types.workspace = true +seismic-revm = { workspace = true } + +# misc +serde.workspace = true +eyre.workspace = true +tracing.workspace = true + +# rpc +jsonrpsee-http-client.workspace = true + +# test-utils dependencies +alloy-rpc-types = { workspace = true } +tokio = { workspace = true } +jsonrpsee = { workspace = true } +reth-e2e-test-utils = { workspace = true, optional = true } +reth-tasks = { workspace = true, optional = true } +seismic-alloy-genesis = { workspace = true, optional = true } + +[dev-dependencies] +reth-seismic-node = { workspace = true, features = ["test-utils"] } +serde_json.workspace = true +reth-db.workspace = true +reth-node-core.workspace = true +reth-node-builder = { workspace = true, features = ["test-utils"] } +reth-provider = { workspace = true, features = ["test-utils"] } +reth-revm = { workspace = true, features = ["test-utils"] } +reth-tasks.workspace = true +reth-tracing.workspace = true +reth-trie-db.workspace = true +alloy-primitives.workspace = true +seismic-alloy-consensus.workspace = true +alloy-consensus.workspace = true +futures.workspace = true +reth-e2e-test-utils = { workspace = true } +reth-rpc-e2e-tests.workspace = true +reth-seismic-evm.workspace = true +reth-seismic-chainspec.workspace = true +alloy-network = { workspace = true } +alloy-chains.workspace = true +alloy-signer-local = { workspace = true } +alloy-genesis = { workspace = true } +reth-seismic-forks.workspace = true +seismic-alloy-network = { workspace = true } +seismic-alloy-provider = { workspace = true } +alloy-dyn-abi.workspace = true +alloy-sol-types.workspace = true +alloy-json-abi.workspace = true +alloy-provider.workspace = true +seismic-alloy-rpc-types.workspace = true +reth-exex.workspace = true +reqwest.workspace = true +secp256k1.workspace = true +k256.workspace = true +rand.workspace = true +alloy-signer.workspace = true +alloy-eips.workspace = true +reth-chainspec.workspace = true +reth-rpc-layer.workspace = true +reth-rpc-builder.workspace = true +reth-payload-builder.workspace = true +reth-primitives-traits.workspace = true +alloy-rpc-types-engine.workspace = true + +[features] +default = ["reth-codec"] +timestamp-in-seconds = [ + "seismic-revm/timestamp-in-seconds", + "reth-node-builder/timestamp-in-seconds", + "reth-primitives-traits/timestamp-in-seconds", + "reth-seismic-evm/timestamp-in-seconds", + "reth-seismic-payload-builder/timestamp-in-seconds", + "reth-seismic-primitives/timestamp-in-seconds", + "reth-seismic-rpc/timestamp-in-seconds", + "reth-seismic-chainspec/timestamp-in-seconds", +] +asm-keccak = [ + "alloy-primitives/asm-keccak", + "revm/asm-keccak", + "reth-seismic-node/asm-keccak", + "reth-node-core/asm-keccak", +] +js-tracer = [ + "reth-node-builder/js-tracer", +] +test-utils = [ + "reth-tasks", + "reth-e2e-test-utils", + "reth-seismic-chainspec", + "reth-node-builder/test-utils", + "reth-chainspec/test-utils", + "reth-consensus/test-utils", + "reth-evm/test-utils", + "reth-network/test-utils", + "reth-payload-builder/test-utils", + "reth-revm/test-utils", + "reth-provider/test-utils", + "reth-transaction-pool/test-utils", + "reth-trie-db/test-utils", + "reth-seismic-node/test-utils", + "reth-seismic-primitives/arbitrary", + "reth-primitives-traits/test-utils", +] +reth-codec = [ + "reth-seismic-primitives/reth-codec", +]
diff --git reth/crates/seismic/node/src/enclave.rs seismic-reth/crates/seismic/node/src/enclave.rs new file mode 100644 index 0000000000000000000000000000000000000000..83374ac093179d86c037e21280a1d616714f9ac8 --- /dev/null +++ seismic-reth/crates/seismic/node/src/enclave.rs @@ -0,0 +1,56 @@ +//! Tools to communicate with the seismic-enclave-server's RPC +use std::net::SocketAddr; + +use jsonrpsee_http_client::HttpClientBuilder; +use reth_node_core::args::EnclaveArgs; +use seismic_enclave::{ + api::TdxQuoteRpcClient as _, mock::start_mock_server, GetPurposeKeysResponse, +}; +use tracing::{info, warn}; + +/// Boot the enclave (or mock server) and fetch purpose keys. +/// This must be called before building the node components. +/// Panics if the enclave cannot be booted or purpose keys cannot be fetched. +#[allow(clippy::expect_used)] // Intentional panic on startup failure - enclave is required +#[allow(clippy::panic)] // Intentional panic on fetching keys failure - enclave keys are required +pub async fn boot_enclave_and_fetch_keys<T>(config: &T) -> GetPurposeKeysResponse +where + T: AsRef<EnclaveArgs>, +{ + let config = config.as_ref(); + // Boot enclave or start mock server + if config.mock_server { + info!(target: "reth::cli", "Starting mock enclave server"); + let addr = config.enclave_server_addr; + let port = config.enclave_server_port; + tokio::spawn(async move { + start_mock_server(SocketAddr::new(addr, port)) + .await + .expect("Failed to start mock enclave server"); + }); + // Give the mock server time to start + tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; + } + let enclave_client = HttpClientBuilder::default() + .build(format!("http://{}:{}", config.enclave_server_addr, config.enclave_server_port)) + .expect("Failed to build enclave client"); + + // Fetch purpose keys from enclave - this must succeed or we panic + info!(target: "reth::cli", "Fetching purpose keys from enclave"); + let mut failures = 0; + while failures <= config.retries { + match enclave_client.get_purpose_keys(0).await { + Ok(purpose_keys) => { + info!(target: "reth::cli", "Successfully fetched purpose keys from enclave"); + return purpose_keys; + } + Err(e) => { + warn!(target: "reth::cli", "Failure to fetch purpose keys {}/{}: {}", failures, config.retries, e); + tokio::time::sleep(tokio::time::Duration::from_secs(config.retry_seconds.into())) + .await; + failures += 1; + } + } + } + panic!("FATAL: Failed to fetch purpose keys from enclave on boot after {} failures", failures); +}
diff --git reth/crates/seismic/node/src/engine.rs seismic-reth/crates/seismic/node/src/engine.rs new file mode 100644 index 0000000000000000000000000000000000000000..d1a5664a68e39109ef86ebc051b9f3e453b1a69b --- /dev/null +++ seismic-reth/crates/seismic/node/src/engine.rs @@ -0,0 +1,152 @@ +//! Ethereum specific engine API types and impls. + +use std::sync::Arc; + +use alloy_rpc_types_engine::{ExecutionData, ExecutionPayload, ExecutionPayloadEnvelopeV5}; +pub use alloy_rpc_types_engine::{ + ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadEnvelopeV4, + ExecutionPayloadV1, PayloadAttributes, +}; +use reth_chainspec::ChainSpec; +use reth_engine_primitives::{EngineTypes, PayloadValidator}; +use reth_ethereum_payload_builder::EthereumExecutionPayloadValidator; +use reth_node_api::{ + validate_execution_requests, validate_version_specific_fields, EngineApiMessageVersion, + EngineApiValidator, EngineObjectValidationError, NewPayloadError, PayloadOrAttributes, +}; +use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; +use reth_payload_primitives::{BuiltPayload, PayloadTypes}; +use reth_primitives_traits::{NodePrimitives, RecoveredBlock, SealedBlock}; +use reth_seismic_primitives::SeismicPrimitives; + +/// The types used in the default mainnet ethereum beacon consensus engine. +#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)] +#[non_exhaustive] +pub struct SeismicEngineTypes<T: PayloadTypes = SeismicPayloadTypes> { + _marker: core::marker::PhantomData<T>, +} + +impl< + T: PayloadTypes< + ExecutionData = ExecutionData, + BuiltPayload: BuiltPayload< + Primitives: NodePrimitives<Block = reth_seismic_primitives::SeismicBlock>, + >, + >, + > PayloadTypes for SeismicEngineTypes<T> +{ + type ExecutionData = T::ExecutionData; + type BuiltPayload = T::BuiltPayload; + type PayloadAttributes = T::PayloadAttributes; + type PayloadBuilderAttributes = T::PayloadBuilderAttributes; + + fn block_to_payload( + block: SealedBlock< + <<Self::BuiltPayload as BuiltPayload>::Primitives as NodePrimitives>::Block, + >, + ) -> Self::ExecutionData { + let (payload, sidecar) = + ExecutionPayload::from_block_unchecked(block.hash(), &block.into_block()); + ExecutionData { payload, sidecar } + } +} + +impl<T> EngineTypes for SeismicEngineTypes<T> +where + T: PayloadTypes<ExecutionData = ExecutionData>, + T::BuiltPayload: BuiltPayload<Primitives: NodePrimitives<Block = reth_seismic_primitives::SeismicBlock>> + + TryInto<ExecutionPayloadV1> + + TryInto<ExecutionPayloadEnvelopeV2> + + TryInto<ExecutionPayloadEnvelopeV3> + + TryInto<ExecutionPayloadEnvelopeV4> + + TryInto<ExecutionPayloadEnvelopeV5>, +{ + type ExecutionPayloadEnvelopeV1 = ExecutionPayloadV1; + type ExecutionPayloadEnvelopeV2 = ExecutionPayloadEnvelopeV2; + type ExecutionPayloadEnvelopeV3 = ExecutionPayloadEnvelopeV3; + type ExecutionPayloadEnvelopeV4 = ExecutionPayloadEnvelopeV4; + type ExecutionPayloadEnvelopeV5 = ExecutionPayloadEnvelopeV5; +} + +/// A default payload type for [`EthEngineTypes`] +#[derive(Debug, Default, Clone, serde::Deserialize, serde::Serialize)] +#[non_exhaustive] +pub struct SeismicPayloadTypes; + +impl PayloadTypes for SeismicPayloadTypes { + type BuiltPayload = EthBuiltPayload<SeismicPrimitives>; + type PayloadAttributes = PayloadAttributes; + type PayloadBuilderAttributes = EthPayloadBuilderAttributes; + type ExecutionData = ExecutionData; + + fn block_to_payload( + block: SealedBlock< + <<Self::BuiltPayload as BuiltPayload>::Primitives as NodePrimitives>::Block, + >, + ) -> Self::ExecutionData { + let (payload, sidecar) = + ExecutionPayload::from_block_unchecked(block.hash(), &block.into_block()); + ExecutionData { payload, sidecar } + } +} + +/// Validator for the ethereum engine API. +#[derive(Debug, Clone)] +pub struct SeismicEngineValidator { + inner: EthereumExecutionPayloadValidator<ChainSpec>, +} + +impl SeismicEngineValidator { + /// Instantiates a new validator. + pub const fn new(chain_spec: Arc<ChainSpec>) -> Self { + Self { inner: EthereumExecutionPayloadValidator::new(chain_spec) } + } + + /// Returns the chain spec used by the validator. + #[inline] + fn chain_spec(&self) -> &ChainSpec { + self.inner.chain_spec() + } +} + +impl PayloadValidator<SeismicEngineTypes> for SeismicEngineValidator { + type Block = reth_seismic_primitives::SeismicBlock; + + fn ensure_well_formed_payload( + &self, + payload: ExecutionData, + ) -> Result<RecoveredBlock<Self::Block>, NewPayloadError> { + let sealed_block = self.inner.ensure_well_formed_payload(payload)?; + sealed_block.try_recover().map_err(|e| NewPayloadError::Other(e.into())) + } +} + +impl<Types> EngineApiValidator<Types> for SeismicEngineValidator +where + Types: PayloadTypes<PayloadAttributes = PayloadAttributes, ExecutionData = ExecutionData>, +{ + fn validate_version_specific_fields( + &self, + version: EngineApiMessageVersion, + payload_or_attrs: PayloadOrAttributes<'_, ExecutionData, PayloadAttributes>, + ) -> Result<(), EngineObjectValidationError> { + payload_or_attrs + .execution_requests() + .map(|requests| validate_execution_requests(requests)) + .transpose()?; + + validate_version_specific_fields(self.chain_spec(), version, payload_or_attrs) + } + + fn ensure_well_formed_attributes( + &self, + version: EngineApiMessageVersion, + attributes: &PayloadAttributes, + ) -> Result<(), EngineObjectValidationError> { + validate_version_specific_fields( + self.chain_spec(), + version, + PayloadOrAttributes::<ExecutionData, PayloadAttributes>::PayloadAttributes(attributes), + ) + } +}
diff --git reth/crates/seismic/node/src/evm.rs seismic-reth/crates/seismic/node/src/evm.rs new file mode 100644 index 0000000000000000000000000000000000000000..4585ce0979457abdb5efa85dcfb37bff894bb58a --- /dev/null +++ seismic-reth/crates/seismic/node/src/evm.rs @@ -0,0 +1,8 @@ +//! Ethereum EVM support + +#[doc(inline)] +pub use reth_evm::execute::BasicBlockExecutorProvider; +#[doc(inline)] +pub use reth_evm_ethereum::execute::EthExecutorProvider; +#[doc(inline)] +pub use reth_evm_ethereum::{EthEvm, SeismicEvmConfig};
diff --git reth/crates/seismic/node/src/lib.rs seismic-reth/crates/seismic/node/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..31d82055f023bd0c6670eb9f938d707d828cffc5 --- /dev/null +++ seismic-reth/crates/seismic/node/src/lib.rs @@ -0,0 +1,35 @@ +//! Standalone crate for Seismic-specific Reth configuration and builder types. +//! +//! # features +//! - `js-tracer`: Enable the `JavaScript` tracer for the `debug_trace` endpoints + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" +)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +// #![cfg_attr(not(feature = "std"), no_std)] + +pub mod enclave; +pub mod engine; +pub mod node; +pub mod purpose_keys; +pub use reth_seismic_txpool as txpool; +pub mod utils; + +pub use reth_seismic_payload_builder::SeismicPayloadBuilder; + +pub use reth_seismic_evm::*; + +use reth_chainspec::ChainSpec; +use std::sync::Arc; + +/// Creates a Seismic EVM configuration with the given chain spec and purpose keys. +pub fn seismic_evm_config( + spec: Arc<ChainSpec>, + purpose_keys: &'static seismic_enclave::GetPurposeKeysResponse, +) -> SeismicEvmConfig { + SeismicEvmConfig::new(spec, purpose_keys) +}
diff --git reth/crates/seismic/node/src/node.rs seismic-reth/crates/seismic/node/src/node.rs new file mode 100644 index 0000000000000000000000000000000000000000..c032fb1fbdd026770598710d715e22002c2fc9b1 --- /dev/null +++ seismic-reth/crates/seismic/node/src/node.rs @@ -0,0 +1,758 @@ +//! Seismic Node types config. + +use crate::{ + engine::{SeismicEngineTypes, SeismicEngineValidator}, + txpool::SeismicTransactionPool, +}; +use alloy_eips::merge::EPOCH_SLOTS; +use alloy_rpc_types_engine::ExecutionData; +use reth_chainspec::{ChainSpec, EthChainSpec}; +use reth_consensus::{ConsensusError, FullConsensus}; +use reth_engine_primitives::{NoopInvalidBlockHook, TreeConfig}; +use reth_eth_wire_types::NewBlock; +use reth_evm::{ + ConfigureEngineEvm, ConfigureEvm, EvmFactory, EvmFactoryFor, NextBlockEnvAttributes, +}; +use reth_network::{NetworkHandle, NetworkPrimitives}; +use reth_node_api::{AddOnsContext, FullNodeComponents, NodeAddOns, PrimitivesTy, TxTy}; +use reth_node_builder::{ + components::{ + BasicPayloadServiceBuilder, ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, + NetworkBuilder, PayloadBuilderBuilder, PoolBuilder, + }, + node::{FullNodeTypes, NodeTypes}, + rpc::{ + BasicEngineApiBuilder, BasicEngineValidator, BasicEngineValidatorBuilder, EngineApiBuilder, + EngineValidatorAddOn, EngineValidatorBuilder, EthApiBuilder, PayloadValidatorBuilder, + RethRpcAddOns, RethRpcMiddleware, RpcAddOns, RpcHandle, RpcModuleContainer, + }, + BuilderContext, DebugNode, Node, NodeAdapter, NodeComponentsBuilder, PayloadBuilderConfig, +}; +use reth_node_ethereum::consensus::EthBeaconConsensus; +use reth_payload_primitives::PayloadAttributesBuilder; +use reth_provider::{providers::ProviderFactoryBuilder, CanonStateSubscriptions, EthStorage}; +use reth_rpc::ValidationApi; +use reth_rpc_api::BlockSubmissionValidationApiServer; +use reth_rpc_builder::{config::RethRpcServerConfig, Identity}; +use reth_rpc_eth_api::helpers::config::{EthConfigApiServer, EthConfigHandler}; +use reth_rpc_eth_types::{ + error::{api::FromEvmHalt, FromEvmError}, + EthApiError, +}; +use reth_rpc_server_types::RethRpcModule; +use reth_seismic_evm::SeismicEvmConfig; +use reth_seismic_payload_builder::SeismicBuilderConfig; +use reth_seismic_primitives::{SeismicPrimitives, SeismicReceipt, SeismicTransactionSigned}; +use reth_seismic_rpc::{ + ext::{EthApiExt, EthApiOverrideServer, SeismicApi, SeismicApiServer}, + SeismicEthApiBuilder, SeismicEthApiError, SeismicRethWithSignable, +}; +use reth_transaction_pool::{ + blobstore::{DiskFileBlobStore, DiskFileBlobStoreConfig}, + CoinbaseTipOrdering, PoolTransaction, TransactionPool, TransactionValidationTaskExecutor, +}; +use revm::context::TxEnv; +use seismic_alloy_consensus::SeismicTxEnvelope; +use std::{sync::Arc, time::SystemTime}; + +use crate::{purpose_keys::get_purpose_keys, seismic_evm_config}; + +/// Storage implementation for Seismic. +pub type SeismicStorage = EthStorage<SeismicTransactionSigned>; + +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +/// Type configuration for a regular Seismic node. +pub struct SeismicNode; + +impl SeismicNode { + /// Returns the components for the given [`EnclaveArgs`]. + pub fn components<Node>( + &self, + ) -> ComponentsBuilder< + Node, + SeismicPoolBuilder, + BasicPayloadServiceBuilder<SeismicPayloadBuilder>, + SeismicNetworkBuilder, + SeismicExecutorBuilder, + SeismicConsensusBuilder, + > + where + Node: FullNodeTypes< + Types: NodeTypes< + Payload = SeismicEngineTypes, + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + >, + >, + { + ComponentsBuilder::default() + .node_types::<Node>() + .pool(SeismicPoolBuilder::default()) + .executor(SeismicExecutorBuilder::default()) + .payload(BasicPayloadServiceBuilder::<SeismicPayloadBuilder>::default()) + .network(SeismicNetworkBuilder::default()) + .executor(SeismicExecutorBuilder::default()) + .consensus(SeismicConsensusBuilder::default()) + } + + /// Instantiates the [`ProviderFactoryBuilder`] for an opstack node. + /// + /// # Open a Providerfactory in read-only mode from a datadir + /// + /// See also: [`ProviderFactoryBuilder`] and + /// [`ReadOnlyConfig`](reth_provider::providers::ReadOnlyConfig). + /// + /// ```no_run + /// use reth_chainspec::BASE_MAINNET; + /// use reth_seismic_node::SeismicNode; + /// + /// let factory = SeismicNode::provider_factory_builder() + /// .open_read_only(BASE_MAINNET.clone(), "datadir") + /// .unwrap(); + /// ``` + /// + /// # Open a Providerfactory manually with with all required components + /// + /// ```no_run + /// use reth_chainspec::ChainSpecBuilder; + /// use reth_db::open_db_read_only; + /// use reth_provider::providers::StaticFileProvider; + /// use reth_seismic_node::SeismicNode; + /// use std::sync::Arc; + /// + /// let factory = SeismicNode::provider_factory_builder() + /// .db(Arc::new(open_db_read_only("db", Default::default()).unwrap())) + /// .chainspec(ChainSpecBuilder::base_mainnet().build().into()) + /// .static_file(StaticFileProvider::read_only("db/static_files", false).unwrap()) + /// .build_provider_factory(); + /// ``` + pub fn provider_factory_builder() -> ProviderFactoryBuilder<Self> { + ProviderFactoryBuilder::default() + } +} + +impl<N> Node<N> for SeismicNode +where + N: FullNodeTypes< + Types: NodeTypes< + Payload = SeismicEngineTypes, + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + Storage = SeismicStorage, + >, + >, +{ + type ComponentsBuilder = ComponentsBuilder< + N, + SeismicPoolBuilder, + BasicPayloadServiceBuilder<SeismicPayloadBuilder>, + SeismicNetworkBuilder, + SeismicExecutorBuilder, + SeismicConsensusBuilder, + >; + + type AddOns = SeismicAddOns< + NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>, + SeismicEthApiBuilder<SeismicRethWithSignable>, + SeismicEngineValidatorBuilder, + BasicEngineApiBuilder<SeismicEngineValidatorBuilder>, + BasicEngineValidatorBuilder<SeismicEngineValidatorBuilder>, + Identity, + >; + + fn components_builder(&self) -> Self::ComponentsBuilder { + Self::components(self) + } + + fn add_ons(&self) -> Self::AddOns { + Self::AddOns::builder().build::< + NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>, + SeismicEthApiBuilder<SeismicRethWithSignable>, + SeismicEngineValidatorBuilder, + BasicEngineApiBuilder<SeismicEngineValidatorBuilder>, + BasicEngineValidatorBuilder<SeismicEngineValidatorBuilder>, + Identity + >() + } +} + +impl NodeTypes for SeismicNode { + type Primitives = SeismicPrimitives; + type ChainSpec = ChainSpec; + type Storage = SeismicStorage; + type Payload = SeismicEngineTypes; +} + +impl<N> DebugNode<N> for SeismicNode +where + N: FullNodeComponents<Types = Self>, +{ + type RpcBlock = alloy_rpc_types_eth::Block<seismic_alloy_consensus::SeismicTxEnvelope>; + + fn rpc_to_primitive_block(rpc_block: Self::RpcBlock) -> reth_node_api::BlockTy<Self> { + let alloy_rpc_types_eth::Block { header, transactions, .. } = rpc_block; + reth_seismic_primitives::SeismicBlock { + header: header.inner, + body: reth_seismic_primitives::SeismicBlockBody { + transactions: transactions.into_transactions().map(Into::into).collect(), + ..Default::default() + }, + } + } + + fn local_payload_attributes_builder( + chain_spec: &Self::ChainSpec, + ) -> impl PayloadAttributesBuilder< + <<Self as reth_node_api::NodeTypes>::Payload as reth_node_api::PayloadTypes>::PayloadAttributes, + >{ + reth_engine_local::LocalPayloadAttributesBuilder::new(Arc::new(chain_spec.clone())) + } +} + +/// Helper trait alias that bundles the common `FullNodeComponents` bounds required by Seismic +/// add-ons. This avoids repeating the verbose `NodeTypes` and `Evm` constraints across every +/// `impl` block. +pub trait SeismicFullNode: + FullNodeComponents< + Types: NodeTypes< + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + Storage = SeismicStorage, + Payload = SeismicEngineTypes, + >, + Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>, +> +{ +} + +impl<N> SeismicFullNode for N where + N: FullNodeComponents< + Types: NodeTypes< + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + Storage = SeismicStorage, + Payload = SeismicEngineTypes, + >, + Evm: ConfigureEvm<NextBlockEnvCtx = NextBlockEnvAttributes>, + > +{ +} + +/// Add-ons w.r.t. seismic +#[derive(Debug)] +pub struct SeismicAddOns< + N: FullNodeComponents, + EthB: EthApiBuilder<N> = SeismicEthApiBuilder<SeismicRethWithSignable>, + PVB = SeismicEngineValidatorBuilder, + EB = BasicEngineApiBuilder<SeismicEngineValidatorBuilder>, + EVB = BasicEngineValidatorBuilder<SeismicEngineValidatorBuilder>, + RpcMiddleware = Identity, +> { + inner: RpcAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware>, +} + +impl<N, EthB, PVB, EB, EVB, RpcMiddleware> SeismicAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware> +where + N: SeismicFullNode, + EthB: EthApiBuilder<N>, +{ + /// Build a [`SeismicAddOns`] using [`SeismicAddOnsBuilder`]. + pub fn builder() -> SeismicAddOnsBuilder { + SeismicAddOnsBuilder::default() + } +} + +/// A regular seismic evm and executor builder. +#[derive(Debug, Default, Clone)] +pub struct SeismicAddOnsBuilder {} + +impl SeismicAddOnsBuilder { + /// Builds an instance of [`SeismicAddOns`]. + pub fn build<N, EthB, PVB, EB, EVB, RpcMiddleware>( + self, + ) -> SeismicAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware> + where + N: SeismicFullNode, + EthB: EthApiBuilder<N> + Default, + PVB: Default, + EB: Default, + EVB: Default, + RpcMiddleware: Default, + { + SeismicAddOns { + inner: RpcAddOns::new( + EthB::default(), + PVB::default(), + EB::default(), + EVB::default(), + RpcMiddleware::default(), + ), + } + } +} + +impl<N> Default for SeismicAddOns<N> +where + N: SeismicFullNode, + SeismicEthApiBuilder<SeismicRethWithSignable>: EthApiBuilder<N>, +{ + fn default() -> Self { + Self::builder().build::< + N, + SeismicEthApiBuilder<SeismicRethWithSignable>, + SeismicEngineValidatorBuilder, + BasicEngineApiBuilder<SeismicEngineValidatorBuilder>, + BasicEngineValidatorBuilder<SeismicEngineValidatorBuilder>, + Identity + >() + } +} + +impl<N, EthB, PVB, EB, EVB, RpcMiddleware> NodeAddOns<N> + for SeismicAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware> +where + N: SeismicFullNode, + EthB: EthApiBuilder<N>, + EthB::EthApi: reth_seismic_rpc::FullSeismicApi + Send + Sync + 'static, + <EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::Error: Send + Sync + 'static, + jsonrpsee::types::ErrorObject<'static>: + From<<EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::Error>, + <<EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::NetworkTypes as reth_rpc_eth_api::RpcTypes>::TransactionRequest: + From<alloy_rpc_types::TransactionRequest> + + AsRef<alloy_rpc_types::TransactionRequest> + + Send + + Sync + + 'static, + PVB: PayloadValidatorBuilder<N>, + EB: EngineApiBuilder<N>, + EVB: EngineValidatorBuilder<N>, + RpcMiddleware: RethRpcMiddleware, + EthApiError: FromEvmError<N::Evm>, + SeismicEthApiError: + FromEvmError<N::Evm> + FromEvmHalt<<EvmFactoryFor<N::Evm> as EvmFactory>::HaltReason>, + EvmFactoryFor<N::Evm>: EvmFactory<Tx = seismic_revm::SeismicTransaction<TxEnv>>, +{ + type Handle = RpcHandle<N, EthB::EthApi>; + + async fn launch_add_ons( + self, + ctx: reth_node_api::AddOnsContext<'_, N>, + ) -> eyre::Result<Self::Handle> { + let validation_api = ValidationApi::new( + ctx.node.provider().clone(), + Arc::new(ctx.node.consensus().clone()), + ctx.node.evm_config().clone(), + ctx.config.rpc.flashbots_config(), + Box::new(ctx.node.task_executor().clone()), + Arc::new(SeismicEngineValidator::new(ctx.config.chain.clone())), + ); + + let eth_config = + EthConfigHandler::new(ctx.node.provider().clone(), ctx.node.evm_config().clone()); + + let purpose_keys = get_purpose_keys().clone(); + + self.inner + .launch_add_ons_with(ctx, move |container| { + let RpcModuleContainer { modules, registry, .. } = container; + modules.merge_if_module_configured( + RethRpcModule::Flashbots, + validation_api.into_rpc(), + )?; + + modules.merge_if_module_configured(RethRpcModule::Eth, eth_config.into_rpc())?; + + // Register Seismic eth_ overrides (sendRawTransaction, call, estimateGas, etc.) + modules.replace_configured( + EthApiExt::new(registry.eth_api().clone(), purpose_keys.clone()).into_rpc(), + )?; + + // Register seismic_ namespace (getTeePublicKey) + modules.merge_configured(SeismicApi::new(purpose_keys).into_rpc())?; + + Ok(()) + }) + .await + } +} + +impl<N, EthB, PVB, EB, EVB, RpcMiddleware> RethRpcAddOns<N> + for SeismicAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware> +where + N: SeismicFullNode, + EthB: EthApiBuilder<N>, + EthB::EthApi: reth_seismic_rpc::FullSeismicApi + Send + Sync + 'static, + <EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::Error: Send + Sync + 'static, + jsonrpsee::types::ErrorObject<'static>: + From<<EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::Error>, + <<EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::NetworkTypes as reth_rpc_eth_api::RpcTypes>::TransactionRequest: + From<alloy_rpc_types::TransactionRequest> + + AsRef<alloy_rpc_types::TransactionRequest> + + Send + + Sync + + 'static, + PVB: PayloadValidatorBuilder<N>, + EB: EngineApiBuilder<N>, + EVB: EngineValidatorBuilder<N>, + RpcMiddleware: RethRpcMiddleware, + EthApiError: FromEvmError<N::Evm>, + SeismicEthApiError: FromEvmError<N::Evm>, + EvmFactoryFor<N::Evm>: EvmFactory<Tx = seismic_revm::SeismicTransaction<TxEnv>>, +{ + type EthApi = EthB::EthApi; + + fn hooks_mut(&mut self) -> &mut reth_node_builder::rpc::RpcHooks<N, Self::EthApi> { + self.inner.hooks_mut() + } +} + +impl<N, EthB, PVB, EB, EVB, RpcMiddleware> EngineValidatorAddOn<N> + for SeismicAddOns<N, EthB, PVB, EB, EVB, RpcMiddleware> +where + N: SeismicFullNode<Evm: ConfigureEngineEvm<ExecutionData>>, + EthB: EthApiBuilder<N>, + EthB::EthApi: reth_seismic_rpc::FullSeismicApi + Send + Sync + 'static, + <EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::Error: Send + Sync + 'static, + jsonrpsee::types::ErrorObject<'static>: + From<<EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::Error>, + <<EthB::EthApi as reth_rpc_eth_api::EthApiTypes>::NetworkTypes as reth_rpc_eth_api::RpcTypes>::TransactionRequest: + From<alloy_rpc_types::TransactionRequest> + + AsRef<alloy_rpc_types::TransactionRequest> + + Send + + Sync + + 'static, + PVB: PayloadValidatorBuilder<N>, + EB: EngineApiBuilder<N>, + EVB: EngineValidatorBuilder<N> + Send, + RpcMiddleware: Send, +{ + type ValidatorBuilder = EVB; + + fn engine_validator_builder(&self) -> Self::ValidatorBuilder { + EngineValidatorAddOn::engine_validator_builder(&self.inner) + } +} + +/// A regular seismic evm and executor builder. +#[derive(Debug, Default, Clone, Copy)] +#[non_exhaustive] +pub struct SeismicExecutorBuilder; + +impl<Node> ExecutorBuilder<Node> for SeismicExecutorBuilder +where + Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = SeismicPrimitives>>, +{ + type EVM = SeismicEvmConfig; + + async fn build_evm(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::EVM> { + let purpose_keys = crate::purpose_keys::get_purpose_keys(); + let evm_config = seismic_evm_config(ctx.chain_spec(), purpose_keys); + + Ok(evm_config) + } +} + +/// A basic ethereum transaction pool. +/// +/// This contains various settings that can be configured and take precedence over the node's +/// config. +#[derive(Debug, Default, Clone, Copy)] +#[non_exhaustive] +pub struct SeismicPoolBuilder; + +impl<Node> PoolBuilder<Node> for SeismicPoolBuilder +where + Node: FullNodeTypes< + Types: NodeTypes< + Payload = SeismicEngineTypes, + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + >, + >, + // T: EthPoolTransaction<Consensus = TxTy<Node::Types>> + // + MaybeConditionalTransaction + // + MaybeInteropTransaction, +{ + type Pool = SeismicTransactionPool<Node::Provider, DiskFileBlobStore>; + + async fn build_pool(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Pool> { + let data_dir = ctx.config().datadir(); + let pool_config = ctx.pool_config(); + + let blob_cache_size = if let Some(blob_cache_size) = pool_config.blob_cache_size { + blob_cache_size + } else { + // get the current blob params for the current timestamp + let current_timestamp = + SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?.as_secs(); + let blob_params = ctx + .chain_spec() + .blob_params_at_timestamp(current_timestamp) + .unwrap_or(ctx.chain_spec().blob_params.cancun); + + // Derive the blob cache size from the target blob count, to auto scale it by + // multiplying it with the slot count for 2 epochs: 384 for pectra + (blob_params.target_blob_count * EPOCH_SLOTS * 2) as u32 + }; + + let custom_config = + DiskFileBlobStoreConfig::default().with_max_cached_entries(blob_cache_size); + + let blob_store = DiskFileBlobStore::open(data_dir.blobstore(), custom_config)?; + let head_timestamp_seconds = if cfg!(feature = "timestamp-in-seconds") { + ctx.head().timestamp + } else { + ctx.head().timestamp / 1000 + }; + let eth_validator = TransactionValidationTaskExecutor::eth_builder(ctx.provider().clone()) + .with_head_timestamp(head_timestamp_seconds) + .kzg_settings(ctx.kzg_settings()?) + .with_local_transactions_config(pool_config.local_transactions_config.clone()) + .with_additional_tasks(ctx.config().txpool.additional_validation_tasks) + // Gas is paid in USDC on Seismic, not native ETH. Disable the native balance check + // so transactions from accounts with zero ETH are not rejected. Actual gas payment + // is enforced by the Seismic revm implementation at execution time. + .disable_balance_check() + .build_with_tasks(ctx.task_executor().clone(), blob_store.clone()); + + // Wrap the eth validator with seismic-specific validation + let validator = eth_validator.map(reth_seismic_txpool::SeismicTransactionValidator::new); + + let transaction_pool = reth_transaction_pool::Pool::new( + validator, + CoinbaseTipOrdering::default(), + blob_store, + pool_config, + ); + // info!(target: "reth::cli", "Transaction pool initialized"); + let transactions_path = data_dir.txpool_transactions(); + + // spawn txpool maintenance task + { + let pool = transaction_pool.clone(); + let chain_events = ctx.provider().canonical_state_stream(); + let client = ctx.provider().clone(); + let transactions_backup_config = + +reth_transaction_pool::maintain::LocalTransactionBackupConfig::with_local_txs_backup(transactions_path); + + ctx.task_executor().spawn_critical_with_graceful_shutdown_signal( + "local transactions backup task", + |shutdown| { + reth_transaction_pool::maintain::backup_local_transactions_task( + shutdown, + pool.clone(), + transactions_backup_config, + ) + }, + ); + + // spawn the maintenance task with USDC balance augmentation + let balance_hook = reth_seismic_txpool::SeismicBalanceHook; + ctx.task_executor().spawn_critical( + "txpool maintenance task", + reth_transaction_pool::maintain::maintain_transaction_pool_future_with_hook( + client, + pool, + chain_events, + ctx.task_executor().clone(), + reth_transaction_pool::maintain::MaintainPoolConfig { + max_tx_lifetime: transaction_pool.config().max_queued_lifetime, + ..Default::default() + }, + balance_hook, + ), + ); + // debug!(target: "reth::cli", "Spawned txpool maintenance task"); + } + + Ok(transaction_pool) + } +} + +/// A basic seismic payload service builder +#[derive(Debug, Default, Clone)] +pub struct SeismicPayloadBuilder; + +impl SeismicPayloadBuilder { + /// A helper method initializing [`reth_ethereum_payload_builder::EthereumPayloadBuilder`] + /// with the given EVM config. + pub fn build<Types, Node, Evm, Pool>( + self, + evm_config: Evm, + ctx: &BuilderContext<Node>, + pool: Pool, + ) -> eyre::Result<reth_seismic_payload_builder::SeismicPayloadBuilder<Pool, Node::Provider, Evm>> + where + Node: FullNodeTypes< + Types: NodeTypes< + Payload = SeismicEngineTypes, + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + >, + >, + Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>> + + Unpin + + 'static, + Evm: ConfigureEvm<Primitives = PrimitivesTy<Node::Types>>, + // Txs: SeismicPayloadTransactions<Pool::Transaction>, + { + let conf = ctx.payload_builder_config(); + let chain = ctx.chain_spec().chain(); + let gas_limit = conf.gas_limit_for(chain); + + Ok(reth_seismic_payload_builder::SeismicPayloadBuilder::new( + ctx.provider().clone(), + pool, + evm_config, + SeismicBuilderConfig::new().with_gas_limit(gas_limit), + )) + } +} + +impl<Node, Pool> PayloadBuilderBuilder<Node, Pool, SeismicEvmConfig> for SeismicPayloadBuilder +where + Node: FullNodeTypes< + Types: NodeTypes< + Payload = SeismicEngineTypes, + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + >, + >, + Pool: TransactionPool<Transaction: PoolTransaction<Consensus = TxTy<Node::Types>>> + + Unpin + + 'static, +{ + type PayloadBuilder = + reth_seismic_payload_builder::SeismicPayloadBuilder<Pool, Node::Provider, SeismicEvmConfig>; + + async fn build_payload_builder( + self, + ctx: &BuilderContext<Node>, + pool: Pool, + evm_config: SeismicEvmConfig, + ) -> eyre::Result<Self::PayloadBuilder> { + let conf = ctx.payload_builder_config(); + let chain = ctx.chain_spec().chain(); + let gas_limit = conf.gas_limit_for(chain); + + let payload_builder = reth_seismic_payload_builder::SeismicPayloadBuilder::new( + ctx.provider().clone(), + pool, + evm_config, + SeismicBuilderConfig::new().with_gas_limit(gas_limit), + ); + Ok(payload_builder) + } +} + +/// A basic ethereum payload service. +#[derive(Debug, Default, Clone, Copy)] +pub struct SeismicNetworkBuilder { + // TODO add closure to modify network +} + +impl<Node, Pool> NetworkBuilder<Node, Pool> for SeismicNetworkBuilder +where + Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = SeismicPrimitives>>, + Pool: TransactionPool< + Transaction: PoolTransaction<Consensus = TxTy<Node::Types>, Pooled = SeismicTxEnvelope>, /* equiv to op_alloy_consensus::OpPooledTransaction>, */ + > + Unpin + + 'static, +{ + type Network = NetworkHandle<SeismicNetworkPrimitives>; + + async fn build_network( + self, + ctx: &BuilderContext<Node>, + pool: Pool, + ) -> eyre::Result<NetworkHandle<SeismicNetworkPrimitives>> { + let network = ctx.network_builder().await?; + let handle = ctx.start_network(network, pool); + // info!(target: "reth::cli", enode=%handle.local_node_record(), "P2P networking + // initialized"); + Ok(handle) + } +} + +/// A basic seismic consensus builder. +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct SeismicConsensusBuilder; + +impl<Node> ConsensusBuilder<Node> for SeismicConsensusBuilder +where + Node: FullNodeTypes<Types: NodeTypes<ChainSpec = ChainSpec, Primitives = SeismicPrimitives>>, +{ + type Consensus = Arc<dyn FullConsensus<SeismicPrimitives, Error = ConsensusError>>; + + async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> { + Ok(Arc::new(EthBeaconConsensus::new(ctx.chain_spec()))) + } +} + +/// Builder for [`EthereumEngineValidator`]. +#[derive(Debug, Default, Clone)] +#[non_exhaustive] +pub struct SeismicEngineValidatorBuilder; + +impl<Node, Types> EngineValidatorBuilder<Node> for SeismicEngineValidatorBuilder +where + Types: NodeTypes< + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + Payload = SeismicEngineTypes, + >, + Node: FullNodeComponents<Types = Types>, + Node::Evm: ConfigureEngineEvm<ExecutionData>, +{ + type EngineValidator = BasicEngineValidator<Node::Provider, Node::Evm, SeismicEngineValidator>; + + async fn build_tree_validator( + self, + ctx: &AddOnsContext<'_, Node>, + tree_config: TreeConfig, + ) -> eyre::Result<Self::EngineValidator> { + let seismic_validator = SeismicEngineValidator::new(ctx.config.chain.clone()); + Ok(BasicEngineValidator::new( + ctx.node.provider().clone(), + Arc::new(ctx.node.consensus().clone()), + ctx.node.evm_config().clone(), + seismic_validator, + tree_config, + Box::new(NoopInvalidBlockHook::default()), + )) + } +} + +impl<Node> PayloadValidatorBuilder<Node> for SeismicEngineValidatorBuilder +where + Node: FullNodeComponents< + Types: NodeTypes< + ChainSpec = ChainSpec, + Primitives = SeismicPrimitives, + Payload = SeismicEngineTypes, + >, + >, +{ + type Validator = SeismicEngineValidator; + + async fn build(self, ctx: &AddOnsContext<'_, Node>) -> eyre::Result<Self::Validator> { + Ok(SeismicEngineValidator::new(ctx.config.chain.clone())) + } +} +/// Network primitive types used by Seismic network. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +#[non_exhaustive] +pub struct SeismicNetworkPrimitives; + +impl NetworkPrimitives for SeismicNetworkPrimitives { + type BlockHeader = alloy_consensus::Header; + type BlockBody = alloy_consensus::BlockBody<SeismicTransactionSigned>; + type Block = alloy_consensus::Block<SeismicTransactionSigned>; + type BroadcastedTransaction = SeismicTransactionSigned; + type PooledTransaction = SeismicTxEnvelope; + type Receipt = SeismicReceipt; + type NewBlockPayload = NewBlock<Self::Block>; +}
diff --git reth/crates/seismic/node/src/purpose_keys.rs seismic-reth/crates/seismic/node/src/purpose_keys.rs new file mode 100644 index 0000000000000000000000000000000000000000..d2bb08b4f4e0b3f2aa17ea924266a9aaa87050b8 --- /dev/null +++ seismic-reth/crates/seismic/node/src/purpose_keys.rs @@ -0,0 +1,30 @@ +//! Global storage for purpose keys fetched from enclave on boot. +//! +//! This module provides thread-safe access to purpose keys that are fetched once +//! during node startup and then used throughout the application lifetime. + +use seismic_enclave::GetPurposeKeysResponse; +use std::sync::OnceLock; + +/// Global storage for purpose keys. +/// These keys are fetched once from the enclave during node startup. +static PURPOSE_KEYS: OnceLock<GetPurposeKeysResponse> = OnceLock::new(); + +/// Initialize the global purpose keys. +/// This should be called once during node startup, after the enclave is booted. +/// +/// # Panics +/// Panics if called more than once. +#[allow(clippy::expect_used)] // Documented panic behavior +pub fn init_purpose_keys(keys: GetPurposeKeysResponse) { + PURPOSE_KEYS.set(keys).expect("Purpose keys already initialized"); +} + +/// Get a reference to the purpose keys. +/// +/// # Panics +/// Panics if the keys haven't been initialized yet. +#[allow(clippy::expect_used)] // Documented panic behavior +pub fn get_purpose_keys() -> &'static GetPurposeKeysResponse { + PURPOSE_KEYS.get().expect("Purpose keys not initialized") +}
diff --git reth/crates/seismic/node/src/utils.rs seismic-reth/crates/seismic/node/src/utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..449a6a2b33bcd10bdaabcf7b156e9ae12521e2d6 --- /dev/null +++ seismic-reth/crates/seismic/node/src/utils.rs @@ -0,0 +1,135 @@ +//! Test utilities for Seismic E2E tests. + +#![allow(clippy::unwrap_used, clippy::expect_used)] // Test utilities - panics are acceptable + +/// E2E test helpers: node setup, chain advancement, payload attributes. +#[cfg(feature = "test-utils")] +pub mod e2e { + use crate::{node::SeismicNode, purpose_keys::init_purpose_keys}; + use alloy_primitives::{Address, B256}; + use alloy_rpc_types_engine::PayloadAttributes; + use reth_e2e_test_utils::{ + transaction::TransactionTestContext, wallet::Wallet, NodeHelperType, TmpDB, + }; + use reth_node_api::NodeTypesWithDBAdapter; + use reth_payload_builder::{EthBuiltPayload, EthPayloadBuilderAttributes}; + use reth_provider::providers::BlockchainProvider; + use reth_seismic_chainspec::SEISMIC_DEV; + use reth_seismic_primitives::SeismicPrimitives; + use reth_tasks::TaskManager; + use seismic_enclave::{ + get_unsecure_sample_schnorrkel_keypair, get_unsecure_sample_secp256k1_pk, + get_unsecure_sample_secp256k1_sk, GetPurposeKeysResponse, + }; + use std::sync::{Arc, Once}; + use tokio::sync::Mutex; + + /// Seismic returns times in milliseconds + pub const SEISMIC_TIMESTAMP_MULTIPLIER: u64 = 1000; + + static INIT_KEYS: Once = Once::new(); + + /// Initializes mock purpose keys for tests. Safe to call multiple times. + pub fn ensure_mock_purpose_keys() { + INIT_KEYS.call_once(|| { + init_purpose_keys(GetPurposeKeysResponse { + tx_io_sk: get_unsecure_sample_secp256k1_sk(), + tx_io_pk: get_unsecure_sample_secp256k1_pk(), + snapshot_key_bytes: [0u8; 32], + rng_keypair: get_unsecure_sample_schnorrkel_keypair(), + }); + }); + } + + /// Seismic Node Helper type + pub type SeismicTestNode = + NodeHelperType<SeismicNode, BlockchainProvider<NodeTypesWithDBAdapter<SeismicNode, TmpDB>>>; + + /// Creates the initial setup with `num_nodes` of the seismic node config, started and + /// connected. + pub async fn setup( + num_nodes: usize, + ) -> eyre::Result<(Vec<SeismicTestNode>, TaskManager, Wallet)> { + reth_e2e_test_utils::setup_engine( + num_nodes, + SEISMIC_DEV.clone(), + false, + Default::default(), + seismic_payload_attributes, + ) + .await + } + + /// Advance the chain with sequential payloads returning them in the end. + pub async fn advance_chain( + length: usize, + node: &mut SeismicTestNode, + wallet: Arc<Mutex<Wallet>>, + ) -> eyre::Result<Vec<EthBuiltPayload<SeismicPrimitives>>> { + node.advance(length as u64, |_| { + let wallet = wallet.clone(); + Box::pin(async move { + let mut wallet = wallet.lock().await; + let nonce = wallet.inner_nonce; + wallet.inner_nonce += 1; + let tx = alloy_rpc_types_eth::TransactionRequest { + nonce: Some(nonce), + value: Some(alloy_primitives::U256::from(100)), + to: Some(alloy_primitives::TxKind::Call(Address::random())), + gas: Some(21000), + max_fee_per_gas: Some(20e9 as u128), + max_priority_fee_per_gas: Some(20e9 as u128), + chain_id: Some(wallet.chain_id), + ..Default::default() + }; + let signed = TransactionTestContext::sign_tx(wallet.inner.clone(), tx).await; + alloy_eips::eip2718::Encodable2718::encoded_2718(&signed).into() + }) + }) + .await + } + + /// Helper function to create a new eth payload attributes for seismic + pub fn seismic_payload_attributes(timestamp: u64) -> EthPayloadBuilderAttributes { + let attributes = PayloadAttributes { + timestamp: timestamp * SEISMIC_TIMESTAMP_MULTIPLIER, + prev_randao: B256::ZERO, + suggested_fee_recipient: Address::ZERO, + withdrawals: Some(vec![]), + parent_beacon_block_root: Some(B256::ZERO), + }; + EthPayloadBuilderAttributes::new(B256::ZERO, attributes) + } +} + +/// RPC test utilities: nonce helpers, re-exported test helpers. +pub mod test_utils { + use alloy_primitives::Address; + use alloy_rpc_types::{Block, Header, Transaction, TransactionReceipt}; + use jsonrpsee::http_client::HttpClient; + use reth_rpc_eth_api::EthApiClient; + use seismic_alloy_rpc_types::SeismicTransactionRequest; + + pub use reth_seismic_primitives::test_utils::{ + client_decrypt, client_encrypt, get_ciphertext, get_client_io_sk, get_encryption_nonce, + get_network_public_key, get_plaintext, get_seismic_elements, get_seismic_metadata, + get_seismic_tx, get_signed_seismic_tx, get_signed_seismic_tx_bytes, + get_signed_seismic_tx_encoding, get_signed_seismic_tx_typed_data, get_signing_private_key, + get_unsigned_seismic_tx_request, get_unsigned_seismic_tx_typed_data, get_wrong_private_key, + sign_seismic_tx, sign_tx, + }; + + /// Get the nonce from the client + pub async fn get_nonce(client: &HttpClient, address: Address) -> u64 { + let nonce = EthApiClient::< + SeismicTransactionRequest, + Transaction, + Block, + TransactionReceipt, + Header, + >::transaction_count(client, address, None) + .await + .unwrap(); + nonce.wrapping_to::<u64>() + } +}
diff --git reth/crates/seismic/node/tests/assets/genesis.json seismic-reth/crates/seismic/node/tests/assets/genesis.json new file mode 100644 index 0000000000000000000000000000000000000000..e59d90f4ff10ea3f4c49903080a63c47973fd8d0 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/assets/genesis.json @@ -0,0 +1 @@ +{"config":{"chainId":8453,"homesteadBlock":0,"eip150Block":0,"eip155Block":0,"eip158Block":0,"byzantiumBlock":0,"constantinopleBlock":0,"petersburgBlock":0,"istanbulBlock":0,"muirGlacierBlock":0,"berlinBlock":0,"londonBlock":0,"arrowGlacierBlock":0,"grayGlacierBlock":0,"mergeNetsplitBlock":0,"bedrockBlock":0,"regolithTime":0,"terminalTotalDifficulty":0,"terminalTotalDifficultyPassed":true,"optimism":{"eip1559Elasticity":6,"eip1559Denominator":50}},"nonce":"0x0","timestamp":"0x0","extraData":"0x00","gasLimit":"0x1c9c380","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","alloc":{"0x14dc79964da2c08b23698b3d3cc7ca32193d9955":{"balance":"0xd3c21bcecceda1000000"},"0x15d34aaf54267db7d7c367839aaf71a00a2c6a65":{"balance":"0xd3c21bcecceda1000000"},"0x1cbd3b2770909d4e10f157cabc84c7264073c9ec":{"balance":"0xd3c21bcecceda1000000"},"0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f":{"balance":"0xd3c21bcecceda1000000"},"0x2546bcd3c84621e976d8185a91a922ae77ecec30":{"balance":"0xd3c21bcecceda1000000"},"0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc":{"balance":"0xd3c21bcecceda1000000"},"0x70997970c51812dc3a010c7d01b50e0d17dc79c8":{"balance":"0xd3c21bcecceda1000000"},"0x71be63f3384f5fb98995898a86b02fb2426c5788":{"balance":"0xd3c21bcecceda1000000"},"0x8626f6940e2eb28930efb4cef49b2d1f2c9c1199":{"balance":"0xd3c21bcecceda1000000"},"0x90f79bf6eb2c4f870365e785982e1f101e93b906":{"balance":"0xd3c21bcecceda1000000"},"0x976ea74026e726554db657fa54763abd0c3a0aa9":{"balance":"0xd3c21bcecceda1000000"},"0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc":{"balance":"0xd3c21bcecceda1000000"},"0x9c41de96b2088cdc640c6182dfcf5491dc574a57":{"balance":"0xd3c21bcecceda1000000"},"0xa0ee7a142d267c1f36714e4a8f75612f20a79720":{"balance":"0xd3c21bcecceda1000000"},"0xbcd4042de499d14e55001ccbb24a551f3b954096":{"balance":"0xd3c21bcecceda1000000"},"0xbda5747bfd65f08deb54cb465eb87d40e51b197e":{"balance":"0xd3c21bcecceda1000000"},"0xcd3b766ccdd6ae721141f452c550ca635964ce71":{"balance":"0xd3c21bcecceda1000000"},"0xdd2fd4581271e230360230f9337d5c0430bf44c0":{"balance":"0xd3c21bcecceda1000000"},"0xdf3e18d64bc6a983f673ab319ccae4f1a57c7097":{"balance":"0xd3c21bcecceda1000000"},"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266":{"balance":"0xd3c21bcecceda1000000"},"0xfabb0ac9d68b0b445fb7357272ff202c5651694a":{"balance":"0xd3c21bcecceda1000000"}},"number":"0x0"} \ No newline at end of file
diff --git reth/crates/seismic/node/tests/e2e/blobs.rs seismic-reth/crates/seismic/node/tests/e2e/blobs.rs new file mode 100644 index 0000000000000000000000000000000000000000..69e4a9d18db1163e7c45f9fc52e0d60dfdb24f56 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/blobs.rs @@ -0,0 +1,84 @@ +use crate::utils::eth_payload_attributes; +use alloy_genesis::Genesis; +use reth_chainspec::{ChainSpecBuilder, MAINNET}; +use reth_e2e_test_utils::{ + node::NodeTestContext, transaction::TransactionTestContext, wallet::Wallet, +}; +use reth_node_builder::{NodeBuilder, NodeHandle}; +use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; +use reth_node_ethereum::EthereumNode; +use reth_tasks::TaskManager; +use reth_transaction_pool::TransactionPool; +use std::sync::Arc; + +#[tokio::test(flavor = "multi_thread")] +async fn can_handle_blobs() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + let tasks = TaskManager::current(); + let exec = tasks.executor(); + + let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(MAINNET.chain) + .genesis(genesis) + .cancun_activated() + .build(), + ); + let genesis_hash = chain_spec.genesis_hash(); + let node_config = NodeConfig::test() + .with_chain(chain_spec) + .with_unused_ports() + .with_rpc(RpcServerArgs::default().with_unused_ports().with_http()); + let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone()) + .testing_node(exec.clone()) + .node(EthereumNode::default()) + .launch() + .await?; + + let mut node = NodeTestContext::new(node, eth_payload_attributes).await?; + + let wallets = Wallet::new(2).gen(); + let blob_wallet = wallets.first().unwrap(); + let second_wallet = wallets.last().unwrap(); + + // inject normal tx + let raw_tx = TransactionTestContext::transfer_tx_bytes(1, second_wallet.clone()).await; + let tx_hash = node.rpc.inject_tx(raw_tx).await?; + // build payload with normal tx + let payload = node.new_payload().await?; + + // clean the pool + node.inner.pool.remove_transactions(vec![tx_hash]); + + // build blob tx + let blob_tx = TransactionTestContext::tx_with_blobs_bytes(1, blob_wallet.clone()).await?; + + // inject blob tx to the pool + let blob_tx_hash = node.rpc.inject_tx(blob_tx).await?; + // fetch it from rpc + let envelope = node.rpc.envelope_by_hash(blob_tx_hash).await?; + // validate sidecar + TransactionTestContext::validate_sidecar(envelope); + + // build a payload + let blob_payload = node.new_payload().await?; + + // submit the blob payload + let blob_block_hash = node.submit_payload(blob_payload).await?; + + node.update_forkchoice(genesis_hash, blob_block_hash).await?; + + // submit normal payload (reorg) + let block_hash = node.submit_payload(payload).await?; + node.update_forkchoice(genesis_hash, block_hash).await?; + + tokio::time::sleep(std::time::Duration::from_secs(3)).await; + + // expects the blob tx to be back in the pool + let envelope = node.rpc.envelope_by_hash(blob_tx_hash).await?; + // make sure the sidecar is present + TransactionTestContext::validate_sidecar(envelope); + + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/dev.rs seismic-reth/crates/seismic/node/tests/e2e/dev.rs new file mode 100644 index 0000000000000000000000000000000000000000..7231d4f77a5970d950523d982e08b68d174dc30c --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/dev.rs @@ -0,0 +1,113 @@ +use alloy_eips::eip2718::Encodable2718; +use alloy_genesis::Genesis; +use alloy_primitives::{b256, hex}; +use futures::StreamExt; +use reth_chainspec::ChainSpec; +use reth_node_api::{BlockBody, FullNodeComponents, FullNodePrimitives, NodeTypes}; +use reth_node_builder::{ + rpc::RethRpcAddOns, EngineNodeLauncher, FullNode, NodeBuilder, NodeConfig, NodeHandle, +}; +use reth_node_core::args::DevArgs; +use reth_node_ethereum::{node::EthereumAddOns, EthereumNode}; +use reth_provider::{providers::BlockchainProvider, CanonStateSubscriptions}; +use reth_rpc_eth_api::helpers::EthTransactions; +use reth_tasks::TaskManager; +use std::sync::Arc; + +#[tokio::test(flavor = "multi_thread")] +async fn can_run_dev_node() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + let tasks = TaskManager::current(); + let exec = tasks.executor(); + + let node_config = NodeConfig::test() + .with_chain(custom_chain()) + .with_dev(DevArgs { dev: true, ..Default::default() }); + let NodeHandle { node, .. } = NodeBuilder::new(node_config.clone()) + .testing_node(exec.clone()) + .with_types_and_provider::<EthereumNode, BlockchainProvider<_>>() + .with_components(EthereumNode::components()) + .with_add_ons(EthereumAddOns::default()) + .launch_with_fn(|builder| { + let launcher = EngineNodeLauncher::new( + builder.task_executor().clone(), + builder.config().datadir(), + Default::default(), + ); + builder.launch_with(launcher) + }) + .await?; + + assert_chain_advances(node).await; + + Ok(()) +} + +async fn assert_chain_advances<N, AddOns>(node: FullNode<N, AddOns>) +where + N: FullNodeComponents<Provider: CanonStateSubscriptions>, + AddOns: RethRpcAddOns<N, EthApi: EthTransactions>, + N::Types: NodeTypes<Primitives: FullNodePrimitives>, +{ + let mut notifications = node.provider.canonical_state_stream(); + + // submit tx through rpc + let raw_tx = hex!("02f876820a28808477359400847735940082520894ab0840c0e43688012c1adb0f5e3fc665188f83d28a029d394a5d630544000080c080a0a044076b7e67b5deecc63f61a8d7913fab86ca365b344b5759d1fe3563b4c39ea019eab979dd000da04dfc72bb0377c092d30fd9e1cab5ae487de49586cc8b0090"); + + let eth_api = node.rpc_registry.eth_api(); + + let hash = eth_api.send_raw_transaction(raw_tx.into()).await.unwrap(); + + let expected = b256!("0xb1c6512f4fc202c04355fbda66755e0e344b152e633010e8fd75ecec09b63398"); + + assert_eq!(hash, expected); + println!("submitted transaction: {hash}"); + + let head = notifications.next().await.unwrap(); + + let tx = &head.tip().body().transactions()[0]; + assert_eq!(tx.trie_hash(), hash); + println!("mined transaction: {hash}"); +} + +fn custom_chain() -> Arc<ChainSpec> { + let custom_genesis = r#" +{ + + "nonce": "0x42", + "timestamp": "0x0", + "extraData": "0x5343", + "gasLimit": "0x13880", + "difficulty": "0x400000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "alloc": { + "0x6Be02d1d3665660d22FF9624b7BE0551ee1Ac91b": { + "balance": "0x4a47e3c12448f4ad000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "config": { + "ethash": {}, + "chainId": 2600, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true, + "shanghaiTime": 0 + } +} +"#; + let genesis: Genesis = serde_json::from_str(custom_genesis).unwrap(); + Arc::new(genesis.into()) +}
diff --git reth/crates/seismic/node/tests/e2e/eth.rs seismic-reth/crates/seismic/node/tests/e2e/eth.rs new file mode 100644 index 0000000000000000000000000000000000000000..f925183ec931f5d2e209cf26f65aabdedda3ae53 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/eth.rs @@ -0,0 +1,129 @@ +use crate::utils::eth_payload_attributes; +use alloy_genesis::Genesis; +use reth_chainspec::{ChainSpecBuilder, MAINNET}; +use reth_e2e_test_utils::{ + node::NodeTestContext, setup, transaction::TransactionTestContext, wallet::Wallet, +}; +use reth_node_builder::{NodeBuilder, NodeHandle}; +use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig}; +use reth_node_ethereum::EthereumNode; +use reth_tasks::TaskManager; +use std::sync::Arc; + +#[tokio::test(flavor = "multi_thread")] +async fn can_run_eth_node() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + + let (mut nodes, _tasks, wallet) = setup::<EthereumNode>( + 1, + Arc::new( + ChainSpecBuilder::default() + .chain(MAINNET.chain) + .genesis(serde_json::from_str(include_str!("../assets/genesis.json")).unwrap()) + .cancun_activated() + .build(), + ), + false, + eth_payload_attributes, + ) + .await?; + + let mut node = nodes.pop().unwrap(); + let raw_tx = TransactionTestContext::transfer_tx_bytes(1, wallet.inner).await; + + // make the node advance + let tx_hash = node.rpc.inject_tx(raw_tx).await?; + + // make the node advance + let payload = node.advance_block().await?; + + let block_hash = payload.block().hash(); + let block_number = payload.block().number; + + // assert the block has been committed to the blockchain + node.assert_new_block(tx_hash, block_hash, block_number).await?; + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +#[cfg(unix)] +async fn can_run_eth_node_with_auth_engine_api_over_ipc() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + let exec = TaskManager::current(); + let exec = exec.executor(); + + // Chain spec with test allocs + let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(MAINNET.chain) + .genesis(genesis) + .cancun_activated() + .build(), + ); + + // Node setup + let node_config = NodeConfig::test() + .with_chain(chain_spec) + .with_rpc(RpcServerArgs::default().with_unused_ports().with_http().with_auth_ipc()); + + let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config) + .testing_node(exec) + .node(EthereumNode::default()) + .launch() + .await?; + let mut node = NodeTestContext::new(node, eth_payload_attributes).await?; + + // Configure wallet from test mnemonic and create dummy transfer tx + let wallet = Wallet::default(); + let raw_tx = TransactionTestContext::transfer_tx_bytes(1, wallet.inner).await; + + // make the node advance + let tx_hash = node.rpc.inject_tx(raw_tx).await?; + + // make the node advance + let payload = node.advance_block().await?; + + let block_hash = payload.block().hash(); + let block_number = payload.block().number; + + // assert the block has been committed to the blockchain + node.assert_new_block(tx_hash, block_hash, block_number).await?; + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +#[cfg(unix)] +async fn test_failed_run_eth_node_with_no_auth_engine_api_over_ipc_opts() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + let exec = TaskManager::current(); + let exec = exec.executor(); + + // Chain spec with test allocs + let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(MAINNET.chain) + .genesis(genesis) + .cancun_activated() + .build(), + ); + + // Node setup + let node_config = NodeConfig::test().with_chain(chain_spec); + let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config) + .testing_node(exec) + .node(EthereumNode::default()) + .launch() + .await?; + + let node = NodeTestContext::new(node, eth_payload_attributes).await?; + + // Ensure that the engine api client is not available + let client = node.inner.engine_ipc_client().await; + assert!(client.is_none(), "ipc auth should be disabled by default"); + + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/fuzz.rs seismic-reth/crates/seismic/node/tests/e2e/fuzz.rs new file mode 100644 index 0000000000000000000000000000000000000000..5dcd963691ce86240bdbc476455adae0967a21bf --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/fuzz.rs @@ -0,0 +1,519 @@ +//! E2E fuzz tests for adversarial transaction handling. +//! +//! Spins up a dev node and bombards it with malformed, adversarial, and +//! signature-corrupted transactions across all tx types. Verifies the node +//! stays healthy after each batch. +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::indexing_slicing, clippy::panic)] + +use alloy_consensus::TxEnvelope; +use alloy_eips::eip2718::Encodable2718; +use alloy_network::{EthereumWallet, TransactionBuilder}; +use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; +use alloy_rpc_types::{Block, TransactionInput, TransactionRequest}; +use alloy_signer_local::PrivateKeySigner; +use core::str::FromStr; +use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder, rpc_params}; +use rand::{rngs::SmallRng, Rng, SeedableRng}; +use reth_seismic_node::utils::{ + e2e::{ensure_mock_purpose_keys, setup}, + test_utils::{get_nonce, get_signed_seismic_tx_bytes}, +}; +use reth_seismic_rpc::ext::EthApiOverrideClient; +use tracing::{info, trace}; + +/// Number of random payloads per fuzz batch +const RANDOM_CASES: usize = 50; + +async fn get_recent_block_hash(client: &jsonrpsee::http_client::HttpClient) -> B256 { + let result: serde_json::Value = client + .request("eth_getBlockByNumber", rpc_params!["latest", false]) + .await + .expect("Failed to get latest block"); + let hash_str = result["hash"].as_str().expect("Block hash not found"); + B256::from_str(hash_str).expect("Failed to parse block hash") +} + +async fn assert_node_alive(client: &jsonrpsee::http_client::HttpClient, wallet_addr: Address) { + get_nonce(client, wallet_addr).await; +} + +/// Sends raw bytes to the node. Logs the outcome at trace level so accidental +/// acceptances are visible in CI logs when run with `--nocapture` or `RUST_LOG=trace`. +async fn send_raw(client: &jsonrpsee::http_client::HttpClient, raw: Bytes) { + match EthApiOverrideClient::<Block>::send_raw_transaction(client, raw.into()).await { + Ok(hash) => trace!(?hash, "tx accepted"), + Err(e) => trace!(%e, "tx rejected"), + } +} + +/// Sends raw bytes and asserts the node rejects them. Use for deterministic +/// hardcoded cases where acceptance would indicate a validation bug. +async fn assert_rejected(client: &jsonrpsee::http_client::HttpClient, raw: Bytes) { + assert!( + EthApiOverrideClient::<Block>::send_raw_transaction(client, raw.into()).await.is_err(), + "expected rejection for known-invalid payload" + ); +} + +/// Builds a signed EIP-1559 transaction with sensible defaults, then applies +/// field-level overrides so callers can target individual validation paths. +async fn build_signed_1559( + wallet: &EthereumWallet, + nonce: u64, + chain_id: u64, + overrides: TransactionRequest, +) -> Bytes { + let mut tx = TransactionRequest { + nonce: Some(nonce), + chain_id: Some(chain_id), + gas: Some(21_000), + max_fee_per_gas: Some(20_000_000_000u128), + max_priority_fee_per_gas: Some(1_000_000_000u128), + to: Some(TxKind::Call(Address::ZERO)), + value: Some(U256::ZERO), + input: TransactionInput::default(), + ..Default::default() + }; + + if overrides.gas.is_some() { + tx.gas = overrides.gas; + } + if overrides.max_fee_per_gas.is_some() { + tx.max_fee_per_gas = overrides.max_fee_per_gas; + } + if overrides.max_priority_fee_per_gas.is_some() { + tx.max_priority_fee_per_gas = overrides.max_priority_fee_per_gas; + } + if overrides.to.is_some() { + tx.to = overrides.to; + } + if overrides.value.is_some() { + tx.value = overrides.value; + } + if overrides.input.input.is_some() { + tx.input = overrides.input; + } + + let envelope = tx.build(wallet).await.expect("Failed to build tx"); + TxEnvelope::encoded_2718(&envelope).into() +} + +/// Replaces the last `n` bytes of `src` using a per-byte transform. +fn corrupt_last_n(src: &[u8], n: usize, f: impl Fn(u8) -> u8) -> Bytes { + let mut buf = src.to_vec(); + for b in buf.iter_mut().rev().take(n) { + *b = f(*b); + } + Bytes::from(buf) +} + +/// Replaces the last `n` bytes of `src` with random values. +fn corrupt_tail_random(src: &[u8], n: usize, rng: &mut impl Rng) -> Bytes { + let mut buf = src.to_vec(); + for b in buf.iter_mut().rev().take(n) { + *b = rng.random(); + } + Bytes::from(buf) +} + +// Sends hardcoded and randomly-generated malformed raw byte payloads. +// Exercises the RLP decoder and EIP-2718 type-prefix handling. +async fn send_malformed_raw_bytes( + client: &jsonrpsee::http_client::HttpClient, + addr: Address, + rng: &mut SmallRng, +) { + // empty payload + assert_rejected(client, Bytes::new()).await; + // bare EIP-4844 type prefix + assert_rejected(client, Bytes::from(vec![0x03])).await; + // bare seismic type prefix + assert_rejected(client, Bytes::from(vec![0x4A])).await; + // 1 KB of 0xFF + assert_rejected(client, Bytes::from(vec![0xFF; 1024])).await; + // truncated EIP-1559 RLP + assert_rejected(client, Bytes::from(vec![0x02, 0xF8, 0x50, 0x01])).await; + // truncated EIP-4844 RLP + assert_rejected(client, Bytes::from(vec![0x03, 0xF8, 0x50, 0x01, 0x02, 0x03])).await; + // truncated seismic RLP + assert_rejected(client, Bytes::from(vec![0x4A, 0xF8, 0x50, 0x01])).await; + // 256 sequential bytes (0x00..0xFF) + assert_rejected(client, Bytes::from((0u8..=255).collect::<Vec<u8>>())).await; + + let type_prefixes: &[u8] = &[0x00, 0x01, 0x02, 0x03, 0x04, 0x4A, 0x7F, 0x80, 0xFE, 0xFF]; + + for _ in 0..RANDOM_CASES { + let len = rng.random_range(1..4096); + let mut bytes: Vec<u8> = (0..len).map(|_| rng.random()).collect(); + // 50% chance of using a real type prefix + if rng.random_bool(0.5) { + bytes[0] = type_prefixes[rng.random_range(0..type_prefixes.len())]; + } + send_raw(client, Bytes::from(bytes)).await; + } + + assert_node_alive(client, addr).await; + info!("Node alive after malformed raw bytes (8 hardcoded + {RANDOM_CASES} random)"); +} + +// Sends hardcoded and randomly-generated adversarial EIP-1559 transactions. +// Tests validation of gas limits, fee parameters, value, and nonce bounds. +async fn send_adversarial_eip1559_txs( + client: &jsonrpsee::http_client::HttpClient, + eth_wallet: &EthereumWallet, + addr: Address, + chain_id: u64, + rng: &mut SmallRng, +) { + let nonce = get_nonce(client, addr).await; + + // gas_limit = 0 + assert_rejected( + client, + build_signed_1559( + eth_wallet, + nonce, + chain_id, + TransactionRequest { gas: Some(0), ..Default::default() }, + ) + .await, + ) + .await; + + // priority_fee > max_fee + assert_rejected( + client, + build_signed_1559( + eth_wallet, + nonce, + chain_id, + TransactionRequest { + max_fee_per_gas: Some(1_000), + max_priority_fee_per_gas: Some(1_000_000), + ..Default::default() + }, + ) + .await, + ) + .await; + + // value exceeds balance + assert_rejected( + client, + build_signed_1559( + eth_wallet, + nonce, + chain_id, + TransactionRequest { value: Some(U256::from(10u128.pow(30))), ..Default::default() }, + ) + .await, + ) + .await; + + // 128 KB input data (use u64::MAX nonce to ensure rejection — with valid gas + // and chain_id this would otherwise be a valid mempool tx) + assert_rejected( + client, + build_signed_1559( + eth_wallet, + u64::MAX, + chain_id, + TransactionRequest { + gas: Some(30_000_000), + input: TransactionInput { + input: Some(Bytes::from(vec![0xDE; 128_000])), + data: None, + }, + ..Default::default() + }, + ) + .await, + ) + .await; + + // nonce = u64::MAX + assert_rejected( + client, + build_signed_1559(eth_wallet, u64::MAX, chain_id, Default::default()).await, + ) + .await; + + // wrong chain_id + assert_rejected(client, build_signed_1559(eth_wallet, nonce, 999999, Default::default()).await) + .await; + + for _ in 0..RANDOM_CASES { + let overrides = TransactionRequest { + gas: Some(rng.random_range(0..30_000_000)), + max_fee_per_gas: Some(rng.random_range(0..u128::from(u64::MAX))), + max_priority_fee_per_gas: Some(rng.random_range(0..u128::from(u64::MAX))), + value: Some(U256::from(rng.random::<u128>())), + input: TransactionInput { + input: Some(Bytes::from( + (0..rng.random_range(0..1024)).map(|_| rng.random::<u8>()).collect::<Vec<u8>>(), + )), + data: None, + }, + ..Default::default() + }; + send_raw(client, build_signed_1559(eth_wallet, rng.random(), chain_id, overrides).await) + .await; + } + + assert_node_alive(client, addr).await; + info!("Node alive after adversarial EIP-1559 txs (6 hardcoded + {RANDOM_CASES} random)"); +} + +// Sends hardcoded and randomly-generated adversarial seismic transactions. +// Tests encryption metadata, block-hash validation, and calldata handling. +// +// TODO: add cases that corrupt seismic-specific fields (encryption_pubkey, +// encryption_nonce) post-encoding, similar to the signature corruption approach. +async fn send_adversarial_seismic_txs( + client: &jsonrpsee::http_client::HttpClient, + signer: &PrivateKeySigner, + addr: Address, + chain_id: u64, + rng: &mut SmallRng, +) { + let nonce = get_nonce(client, addr).await; + let recent_block_hash = get_recent_block_hash(client).await; + + // zero block hash + assert_rejected( + client, + get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Call(Address::ZERO), + chain_id, + Bytes::from(vec![0x01]), + B256::ZERO, + ) + .await, + ) + .await; + + // random block hash + assert_rejected( + client, + get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Call(Address::ZERO), + chain_id, + Bytes::from(vec![0x01]), + B256::from([0xFF; 32]), + ) + .await, + ) + .await; + + // nonce = u64::MAX + assert_rejected( + client, + get_signed_seismic_tx_bytes( + signer, + u64::MAX, + TxKind::Call(Address::ZERO), + chain_id, + Bytes::from(vec![0x01]), + recent_block_hash, + ) + .await, + ) + .await; + + // wrong chain_id + assert_rejected( + client, + get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Call(Address::ZERO), + 999999, + Bytes::from(vec![0x01]), + recent_block_hash, + ) + .await, + ) + .await; + + // garbage calldata + send_raw( + client, + get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Call(Address::ZERO), + chain_id, + Bytes::from(vec![0xDE, 0xAD, 0xBE, 0xEF]), + recent_block_hash, + ) + .await, + ) + .await; + + // contract creation + send_raw( + client, + get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Create, + chain_id, + Bytes::from(vec![0x60, 0x00, 0x60, 0x00, 0xF3]), + recent_block_hash, + ) + .await, + ) + .await; + + // empty calldata + send_raw( + client, + get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Call(Address::ZERO), + chain_id, + Bytes::new(), + recent_block_hash, + ) + .await, + ) + .await; + + // 64 KB calldata + send_raw( + client, + get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Call(Address::ZERO), + chain_id, + Bytes::from(vec![0xAB; 64_000]), + recent_block_hash, + ) + .await, + ) + .await; + + for _ in 0..RANDOM_CASES { + let calldata_len = rng.random_range(0..4096); + let calldata = + Bytes::from((0..calldata_len).map(|_| rng.random::<u8>()).collect::<Vec<u8>>()); + + let block_hash = match rng.random_range(0..3) { + 0 => recent_block_hash, + 1 => B256::ZERO, + _ => B256::from(rng.random::<[u8; 32]>()), + }; + + let to = if rng.random_bool(0.2) { + TxKind::Create + } else { + TxKind::Call(Address::from(rng.random::<[u8; 20]>())) + }; + + send_raw( + client, + get_signed_seismic_tx_bytes(signer, rng.random(), to, chain_id, calldata, block_hash) + .await, + ) + .await; + } + + assert_node_alive(client, addr).await; + info!("Node alive after adversarial seismic txs (8 hardcoded + {RANDOM_CASES} random)"); +} + +// Builds valid signed transactions, then corrupts parts of their signatures. +// Tests ecrecover / signer-recovery resilience for both EIP-1559 and seismic txs. +async fn send_signature_corrupted_txs( + client: &jsonrpsee::http_client::HttpClient, + eth_wallet: &EthereumWallet, + signer: &PrivateKeySigner, + addr: Address, + chain_id: u64, + rng: &mut SmallRng, +) { + let nonce = get_nonce(client, addr).await; + let recent_block_hash = get_recent_block_hash(client).await; + + let valid_bytes = + build_signed_1559(eth_wallet, nonce, chain_id, Default::default()).await.to_vec(); + + // corrupt last byte (part of signature s value) + send_raw(client, corrupt_last_n(&valid_bytes, 1, |b| b ^ 0xFF)).await; + // randomize entire s value + send_raw(client, corrupt_tail_random(&valid_bytes, 32, rng)).await; + // randomize entire r + s + send_raw(client, corrupt_tail_random(&valid_bytes, 64, rng)).await; + // zero out the entire signature + send_raw(client, corrupt_last_n(&valid_bytes, 65, |_| 0x00)).await; + // all-0xFF signature + send_raw(client, corrupt_last_n(&valid_bytes, 65, |_| 0xFF)).await; + + let seismic_bytes = get_signed_seismic_tx_bytes( + signer, + nonce, + TxKind::Call(Address::ZERO), + chain_id, + Bytes::from(vec![0x01]), + recent_block_hash, + ) + .await + .to_vec(); + + // corrupt last byte of seismic tx signature + send_raw(client, corrupt_last_n(&seismic_bytes, 1, |b| b ^ 0xFF)).await; + // randomize seismic r + s + send_raw(client, corrupt_tail_random(&seismic_bytes, 64, rng)).await; + + // random single-byte signature corruption across many txs + for _ in 0..RANDOM_CASES { + let raw = build_signed_1559(eth_wallet, rng.random(), chain_id, Default::default()).await; + let mut bytes = raw.to_vec(); + let len = bytes.len(); + let offset = rng.random_range(len.saturating_sub(65)..len); + bytes[offset] = rng.random(); + send_raw(client, Bytes::from(bytes)).await; + } + + assert_node_alive(client, addr).await; + info!("Node alive after signature-corrupted txs (7 hardcoded + {RANDOM_CASES} random)"); +} + +#[tokio::test(flavor = "multi_thread")] +async fn fuzz_adversarial_transactions() { + reth_tracing::init_test_tracing(); + ensure_mock_purpose_keys(); + + let (mut nodes, _tasks, wallet) = + tokio::spawn(setup(1)).await.expect("node setup task panicked").expect("setup failed"); + let mut node = nodes.pop().unwrap(); + let rpc_url = node.rpc_url().to_string(); + let chain_id = wallet.chain_id; + let client = HttpClientBuilder::default().build(&rpc_url).unwrap(); + + // Advance one block so that `get_recent_block_hash` returns a real hash + // for seismic tx tests that require a valid recent block hash. + node.advance_block().await.expect("failed to advance initial block"); + + let seed: u64 = + std::env::var("FUZZ_SEED").ok().and_then(|s| s.parse().ok()).unwrap_or_else(rand::random); + info!(%seed, "RNG seed — re-run with FUZZ_SEED={seed} to reproduce"); + let mut rng = SmallRng::seed_from_u64(seed); + + let eth_wallet: EthereumWallet = wallet.inner.clone().into(); + let addr = wallet.inner.address(); + + send_malformed_raw_bytes(&client, addr, &mut rng).await; + send_adversarial_eip1559_txs(&client, &eth_wallet, addr, chain_id, &mut rng).await; + send_adversarial_seismic_txs(&client, &wallet.inner, addr, chain_id, &mut rng).await; + send_signature_corrupted_txs(&client, &eth_wallet, &wallet.inner, addr, chain_id, &mut rng) + .await; + + info!("All batches passed — node remained healthy throughout"); +}
diff --git reth/crates/seismic/node/tests/e2e/hardfork_config.rs seismic-reth/crates/seismic/node/tests/e2e/hardfork_config.rs new file mode 100644 index 0000000000000000000000000000000000000000..030c24f8168ccc1a722efaf9d12cf3760cddfb45 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/hardfork_config.rs @@ -0,0 +1,127 @@ +//! Tests that Seismic hardfork configuration (Mercury) is correctly reported via RPC. +//! +//! This is the Seismic equivalent of `test_eth_config` in `crates/ethereum/node/tests/e2e/rpc.rs`, +//! which was disabled with `#[ignore = "We disabled fork activations"]`. +//! +//! Instead of testing fork scheduling (past/current/next at different timestamps), we verify +//! that the Seismic chain spec with Mercury hardfork active at genesis is correctly reflected +//! in the `eth_config` RPC response. + +use alloy_eips::eip7910::EthConfig; +use alloy_primitives::{Address, B256}; +use alloy_provider::{network::EthereumWallet, Provider, ProviderBuilder}; +use alloy_rpc_types_engine::PayloadAttributes; +use alloy_rpc_types_eth::TransactionRequest; +use reth_chainspec::{EthChainSpec, Hardforks, Head}; +use reth_e2e_test_utils::setup; +use reth_payload_builder::EthPayloadBuilderAttributes; +use reth_seismic_chainspec::SEISMIC_DEV; +use reth_seismic_node::{node::SeismicNode, purpose_keys::init_purpose_keys}; +use seismic_enclave::{ + get_unsecure_sample_schnorrkel_keypair, get_unsecure_sample_secp256k1_pk, + get_unsecure_sample_secp256k1_sk, GetPurposeKeysResponse, +}; +use std::sync::Once; + +/// Ensure mock purpose keys are initialized exactly once per test binary. +static INIT_KEYS: Once = Once::new(); +fn ensure_mock_purpose_keys() { + INIT_KEYS.call_once(|| { + init_purpose_keys(GetPurposeKeysResponse { + tx_io_sk: get_unsecure_sample_secp256k1_sk(), + tx_io_pk: get_unsecure_sample_secp256k1_pk(), + snapshot_key_bytes: [0u8; 32], + rng_keypair: get_unsecure_sample_schnorrkel_keypair(), + }); + }); +} + +/// Helper function to create a new eth payload attributes +fn eth_payload_attributes(timestamp: u64) -> EthPayloadBuilderAttributes { + let attributes = PayloadAttributes { + timestamp, + prev_randao: B256::ZERO, + suggested_fee_recipient: Address::ZERO, + withdrawals: Some(vec![]), + parent_beacon_block_root: Some(B256::ZERO), + }; + EthPayloadBuilderAttributes::new(B256::ZERO, attributes) +} + +/// Validates that the Mercury hardfork is correctly configured and reported via `eth_config` RPC. +/// +/// This test: +/// 1. Starts a Seismic node with the dev chain spec (all forks including Mercury at timestamp 0) +/// 2. Advances a block so the node has chain state +/// 3. Calls `eth_config` RPC ([EIP-7910](https://eips.ethereum.org/EIPS/eip-7910)) and verifies the +/// response +/// 4. Asserts that the current fork `activation_time` is 0 (Mercury active at genesis) +/// 5. Asserts that the `chain_id` matches the Seismic dev chain +/// 6. Asserts there is no next fork scheduled +#[tokio::test(flavor = "multi_thread")] +async fn test_mercury_hardfork_config() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + ensure_mock_purpose_keys(); + + let chain_spec = SEISMIC_DEV.clone(); + + let (mut nodes, _tasks, wallet) = + setup::<SeismicNode>(1, chain_spec.clone(), false, eth_payload_attributes).await?; + let mut node = nodes.pop().unwrap(); + let provider = ProviderBuilder::new() + .wallet(EthereumWallet::new(wallet.wallet_gen().swap_remove(0))) + .connect_http(node.rpc_url()); + + // Send a transaction and advance a block so the node has chain state beyond genesis + let _ = provider.send_transaction(TransactionRequest::default().to(Address::ZERO)).await?; + node.advance_block().await?; + + // Get the latest block timestamp for fork_id verification + let latest_block = provider.get_block_number().await?; + let latest_timestamp = provider + .get_block_by_number(latest_block.into()) + .await? + .expect("latest block should exist") + .header + .timestamp; + + // Query the eth_config RPC endpoint (EIP-7910) + let config: EthConfig = provider.client().request_noparams::<EthConfig>("eth_config").await?; + + // All Seismic forks (including Mercury) are activated at timestamp 0, so the current fork + // should have activation_time = 0. + assert_eq!( + config.current.activation_time, 0, + "Mercury hardfork should be active at timestamp 0" + ); + + // The chain_id in the config should match the Seismic dev chain id + assert_eq!( + config.current.chain_id, + chain_spec.chain().id(), + "chain_id should match Seismic dev chain" + ); + + // The fork_id should be non-empty and match the Seismic dev chain's fork hash, + // which is derived from the genesis hash and all fork block/timestamp activations. + // This is a stronger check than just activation_time — it proves the full fork + // schedule is Seismic-specific. + assert!(!config.current.fork_id.is_empty(), "fork_id should be set"); + + // Verify the fork_id matches what we compute from the chain spec directly. + // The fork_id is derived from genesis hash + all fork activations, so this proves + // the node is running with the correct Seismic fork schedule. + let fork_id = chain_spec.fork_id(&Head { timestamp: latest_timestamp, ..Default::default() }); + let expected_fork_hash = fork_id.hash.0; + let reported_fork_hash = config.current.fork_id.get(..4); + assert_eq!( + reported_fork_hash, + Some(expected_fork_hash.as_slice()), + "fork_id should match the Seismic dev chain fork hash" + ); + + // Since all forks are at timestamp 0, there should be no next fork scheduled + assert!(config.next.is_none(), "no next fork should be scheduled"); + + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/integration.rs seismic-reth/crates/seismic/node/tests/e2e/integration.rs new file mode 100644 index 0000000000000000000000000000000000000000..9af4db9b1f3f99bcb17f5443d8eb86a2688b4cc1 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/integration.rs @@ -0,0 +1,1117 @@ +//! Integration tests for the Seismic node RPC. +//! +//! Each test spawns its own in-process Seismic node via `setup(1)`, eliminating +//! the previous subprocess-based approach (`cargo run --bin seismic-reth`). +//! Blocks are produced explicitly via `node.advance_block()` instead of relying +//! on dev-mode auto-mining with `thread::sleep`. +#![allow(clippy::unwrap_used, clippy::expect_used, clippy::indexing_slicing, clippy::panic)] // Test file - panics are acceptable + +use alloy_consensus::TxEnvelope; +use alloy_dyn_abi::EventExt; +use alloy_eips::eip2718::Encodable2718; +use alloy_json_abi::{Event, EventParam}; +use alloy_network::{EthereumWallet, ReceiptResponse, TransactionBuilder}; +use alloy_primitives::{ + aliases::{B96, U96}, + hex, + hex::FromHex, + Address, Bytes, IntoLogData, TxKind, B256, U256, +}; +use alloy_provider::{Provider, SendableTx}; +use alloy_rpc_types::{ + state::{AccountOverride, StateOverride}, + Block, Header, TransactionInput, TransactionRequest, +}; +use alloy_sol_types::{sol, SolCall, SolValue}; +use core::str::FromStr; +use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder, rpc_params}; +use reth_e2e_test_utils::wallet::Wallet; +use reth_rpc_eth_api::EthApiClient; +use reth_seismic_node::utils::{ + e2e::{ensure_mock_purpose_keys, setup, SeismicTestNode}, + test_utils::{ + client_decrypt, get_nonce, get_seismic_metadata, get_signed_seismic_tx_bytes, + get_signed_seismic_tx_typed_data, get_unsigned_seismic_tx_request, + }, +}; +use reth_seismic_primitives::{ + test_utils::get_unsigned_legacy_tx_request, SeismicBlock, SeismicTransactionSigned, +}; +use reth_seismic_rpc::ext::EthApiOverrideClient; +use seismic_alloy_network::{ + reth::builder::seismic_reth_tx_builder, wallet::SeismicWallet, SeismicReth, +}; +use seismic_alloy_provider::{ + test_utils::ContractTestContext, SeismicProviderBuilder, SignedProviderExt, +}; +use seismic_alloy_rpc_types::{ + SeismicCallRequest, SeismicTransactionReceipt, SeismicTransactionRequest, SimBlock, + SimulatePayload, +}; +use seismic_enclave::aes_decrypt; + +const PRECOMPILES_TEST_SET_AES_KEY_SELECTOR: &str = "a0619040"; // setAESKey(suint256) +const PRECOMPILES_TEST_ENCRYPTED_LOG_SELECTOR: &str = "28696e36"; // submitMessage(bytes) + +/// Helper function to get a recent block hash from the client +async fn get_recent_block_hash(client: &jsonrpsee::http_client::HttpClient) -> B256 { + let result: serde_json::Value = client + .request("eth_getBlockByNumber", rpc_params!["latest", false]) + .await + .expect("Failed to get latest block"); + + let hash_str = result["hash"].as_str().expect("Block hash not found in response"); + + B256::from_str(hash_str).expect("Failed to parse block hash") +} + +/// Helper function to create a regular (non-seismic) deployment transaction +async fn get_signed_deploy_tx_bytes( + wallet: impl Into<EthereumWallet> + Clone, + nonce: u64, + chain_id: u64, + deploy_bytecode: Bytes, +) -> Bytes { + let tx = TransactionRequest { + from: None, + to: Some(TxKind::Create), + gas: Some(6000000), + max_fee_per_gas: Some(20e9 as u128), + max_priority_fee_per_gas: Some(1e9 as u128), + value: Some(U256::ZERO), + input: TransactionInput { input: Some(deploy_bytecode), data: None }, + nonce: Some(nonce), + chain_id: Some(chain_id), + ..Default::default() + }; + + let eth_wallet: EthereumWallet = wallet.into(); + let tx_envelope = tx.build(&eth_wallet).await.expect("Failed to build transaction"); + + TxEnvelope::encoded_2718(&tx_envelope).into() +} + +/// Sets up a single in-process Seismic node for testing and returns the node, +/// an HTTP RPC client, `chain_id`, wallet, and task manager. +/// +/// The `TaskManager` must be held alive for the test duration — dropping it +/// cancels background tasks that power the node. +async fn setup_test_node() -> eyre::Result<( + SeismicTestNode, + jsonrpsee::http_client::HttpClient, + u64, + Wallet, + reth_tasks::TaskManager, +)> { + reth_tracing::init_test_tracing(); + ensure_mock_purpose_keys(); + // Spawn node setup on a separate task to move the large async state machine + // (node + engine + RPC + EVM) onto the heap, avoiding stack overflow on + // x86_64 CI where stack frames are larger than on ARM64. + let (mut nodes, tasks, wallet) = + tokio::spawn(setup(1)).await.expect("node setup task panicked")?; + let node = nodes.pop().unwrap(); + let rpc_url = node.rpc_url().to_string(); + let chain_id = wallet.chain_id; + let client = HttpClientBuilder::default().build(&rpc_url)?; + Ok((node, client, chain_id, wallet, tasks)) +} + +/// Deploy contract, verify receipt and code, then return the contract address + block hash. +async fn rpc_test_deploy_contract( + node: &mut SeismicTestNode, + client: &jsonrpsee::http_client::HttpClient, + chain_id: u64, + wallet: &Wallet, +) -> eyre::Result<(alloy_primitives::Address, B256)> { + let tx_hash = EthApiOverrideClient::<Block>::send_raw_transaction( + client, + get_signed_deploy_tx_bytes( + wallet.inner.clone(), + get_nonce(client, wallet.inner.address()).await, + chain_id, + ContractTestContext::get_deploy_input_plaintext(), + ) + .await + .into(), + ) + .await + .unwrap(); + node.advance_block().await?; + + let receipt = EthApiClient::< + SeismicTransactionRequest, + SeismicTransactionSigned, + SeismicBlock, + SeismicTransactionReceipt, + Header, + >::transaction_receipt(client, tx_hash) + .await + .unwrap() + .unwrap(); + let contract_addr = receipt.contract_address.unwrap(); + assert!(receipt.status()); + + let code = EthApiClient::< + SeismicTransactionRequest, + SeismicTransactionSigned, + SeismicBlock, + SeismicTransactionReceipt, + Header, + >::get_code(client, contract_addr, None) + .await + .unwrap(); + assert_eq!(ContractTestContext::get_code(), code); + + let recent_block_hash = get_recent_block_hash(client).await; + Ok((contract_addr, recent_block_hash)) +} + +/// Verify parity via encrypted `eth_call`, returning the decrypted result as `U256`. +async fn rpc_test_check_parity( + client: &jsonrpsee::http_client::HttpClient, + chain_id: u64, + wallet: &Wallet, + contract_addr: alloy_primitives::Address, + recent_block_hash: B256, +) -> eyre::Result<U256> { + let nonce = get_nonce(client, wallet.inner.address()).await; + let to = TxKind::Call(contract_addr); + let output = EthApiOverrideClient::<Block>::call( + client, + get_signed_seismic_tx_bytes( + &wallet.inner, + nonce, + to, + chain_id, + ContractTestContext::get_is_odd_input_plaintext(), + recent_block_hash, + ) + .await + .into(), + None, + None, + None, + ) + .await + .unwrap(); + let metadata = get_seismic_metadata( + wallet.inner.address(), + chain_id, + nonce, + to, + U256::ZERO, + recent_block_hash, + ); + let decrypted = client_decrypt(metadata, &output).unwrap(); + Ok(U256::from_be_slice(&decrypted)) +} + +/// Send `set_number` transaction and advance block. +async fn rpc_test_set_number( + node: &mut SeismicTestNode, + client: &jsonrpsee::http_client::HttpClient, + chain_id: u64, + wallet: &Wallet, + contract_addr: alloy_primitives::Address, + recent_block_hash: B256, +) -> eyre::Result<()> { + let tx_hash = EthApiClient::< + SeismicTransactionRequest, + SeismicTransactionSigned, + SeismicBlock, + SeismicTransactionReceipt, + Header, + >::send_raw_transaction( + client, + get_signed_seismic_tx_bytes( + &wallet.inner, + get_nonce(client, wallet.inner.address()).await, + TxKind::Call(contract_addr), + chain_id, + ContractTestContext::get_set_number_input_plaintext(), + recent_block_hash, + ) + .await, + ) + .await + .unwrap(); + node.advance_block().await?; + + let receipt = EthApiClient::< + SeismicTransactionRequest, + SeismicTransactionSigned, + SeismicBlock, + SeismicTransactionReceipt, + Header, + >::transaction_receipt(client, tx_hash) + .await + .unwrap() + .unwrap(); + assert!(receipt.status()); + Ok(()) +} + +/// Test estimateGas, createAccessList, legacy call, and no-type call. +async fn rpc_test_gas_and_call_variants( + client: &jsonrpsee::http_client::HttpClient, + chain_id: u64, + wallet: &Wallet, + contract_addr: alloy_primitives::Address, + recent_block_hash: B256, +) -> eyre::Result<()> { + let simulate_tx_request = get_unsigned_seismic_tx_request( + &wallet.inner, + get_nonce(client, wallet.inner.address()).await, + TxKind::Call(contract_addr), + chain_id, + ContractTestContext::get_is_odd_input_plaintext(), + recent_block_hash, + ) + .await; + + // test eth_estimateGas with signed bytes (unsigned requests have `from` sanitized) + let gas = EthApiOverrideClient::<Block>::estimate_gas( + client, + get_signed_seismic_tx_bytes( + &wallet.inner, + get_nonce(client, wallet.inner.address()).await, + TxKind::Call(contract_addr), + chain_id, + ContractTestContext::get_is_odd_input_plaintext(), + recent_block_hash, + ) + .await + .into(), + None, + None, + ) + .await + .unwrap(); + assert!(gas > U256::ZERO); + + // test eth_estimateGas sanitizes unsigned seismic requests (clears `from` and + // seismic_elements to prevent caller spoofing, same as eth_call) + let unsigned_seismic_result = EthApiOverrideClient::<Block>::estimate_gas( + client, + SeismicCallRequest::TransactionRequest(simulate_tx_request.clone()), + None, + None, + ) + .await; + // Sanitized request simulates ciphertext as address(0) — expected to fail + assert!( + unsigned_seismic_result.is_err(), + "unsigned seismic estimateGas should fail after sanitization" + ); + + // test eth_estimateGas works for plain unsigned requests (standard Ethereum behavior) + let plain_unsigned_result = EthApiOverrideClient::<Block>::estimate_gas( + client, + SeismicCallRequest::TransactionRequest(SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(wallet.inner.address()), + to: Some(TxKind::Call(contract_addr)), + input: TransactionInput { + data: Some(ContractTestContext::get_is_odd_input_plaintext()), + ..Default::default() + }, + ..Default::default() + }, + seismic_elements: None, + }), + None, + None, + ) + .await + .unwrap(); + println!("eth_estimateGas for plain unsigned is_odd() gas: {:?}", plain_unsigned_result); + assert!(plain_unsigned_result > U256::ZERO); + + // TODO: should remove this functionality from seismic tx (audit) + let _access_list = + EthApiClient::< + SeismicTransactionRequest, + SeismicTransactionSigned, + SeismicBlock, + SeismicTransactionReceipt, + Header, + >::create_access_list(client, simulate_tx_request.inner.clone().into(), None, None) + .await + .unwrap(); + + let is_odd_tx_request = get_unsigned_legacy_tx_request( + &wallet.inner, + get_nonce(client, wallet.inner.address()).await, + TxKind::Call(contract_addr), + chain_id, + ContractTestContext::get_is_odd_input_plaintext(), + ) + .await; + + let _output = EthApiOverrideClient::<Block>::call( + client, + is_odd_tx_request.clone().into(), + None, + None, + None, + ) + .await + .unwrap(); + + // call with no transaction type + let _output = EthApiOverrideClient::<Block>::call( + client, + SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(wallet.inner.address()), + input: TransactionInput { + data: Some(ContractTestContext::get_is_odd_input_plaintext()), + ..Default::default() + }, + to: Some(TxKind::Call(contract_addr)), + ..Default::default() + }, + seismic_elements: None, + } + .into(), + None, + None, + None, + ) + .await + .unwrap(); + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_seismic_reth_rpc() -> eyre::Result<()> { + let (mut node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let (contract_addr, recent_block_hash) = + rpc_test_deploy_contract(&mut node, &client, chain_id, &wallet).await?; + + // parity should be 0 before set_number + let parity = + rpc_test_check_parity(&client, chain_id, &wallet, contract_addr, recent_block_hash).await?; + assert_eq!(parity, U256::ZERO); + + rpc_test_set_number(&mut node, &client, chain_id, &wallet, contract_addr, recent_block_hash) + .await?; + + // parity should be 1 after set_number + let parity = + rpc_test_check_parity(&client, chain_id, &wallet, contract_addr, recent_block_hash).await?; + assert_eq!(parity, U256::from(1)); + + rpc_test_gas_and_call_variants(&client, chain_id, &wallet, contract_addr, recent_block_hash) + .await?; + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_seismic_reth_rpc_with_typed_data() -> eyre::Result<()> { + let (mut node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let (contract_addr, recent_block_hash) = + rpc_test_deploy_contract(&mut node, &client, chain_id, &wallet).await?; + + let nonce = get_nonce(&client, wallet.inner.address()).await; + let to = TxKind::Call(contract_addr); + let output = EthApiOverrideClient::<Block>::call( + &client, + get_signed_seismic_tx_typed_data( + &wallet.inner, + nonce, + to, + chain_id, + ContractTestContext::get_is_odd_input_plaintext(), + recent_block_hash, + ) + .await + .into(), + None, + None, + None, + ) + .await + .unwrap(); + let metadata = get_seismic_metadata( + wallet.inner.address(), + chain_id, + nonce, + to, + U256::ZERO, + recent_block_hash, + ); + let decrypted_output = client_decrypt(metadata, &output).unwrap(); + assert_eq!(U256::from_be_slice(&decrypted_output), U256::ZERO); + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_seismic_reth_rpc_with_rust_client() -> eyre::Result<()> { + let (mut node, _client, chain_id, _wallet, _tasks) = setup_test_node().await?; + let reth_rpc_url = node.rpc_url().to_string(); + + let _wallet = Wallet::default().with_chain_id(chain_id); + let wallet: SeismicWallet<SeismicReth> = SeismicWallet::from(_wallet.inner); + + let provider = SeismicProviderBuilder::new() + .wallet(wallet) + .connect_http(reqwest::Url::parse(&reth_rpc_url).unwrap()) + .await + .unwrap(); + + let req = TransactionBuilder::<SeismicReth>::with_kind( + TransactionBuilder::<SeismicReth>::with_input( + SeismicTransactionRequest::default(), + ContractTestContext::get_deploy_input_plaintext(), + ), + TxKind::Create, + ); + let pending_transaction = provider.send_transaction(req).await.unwrap(); + let tx_hash = *pending_transaction.tx_hash(); + node.advance_block().await?; + + let receipt = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap(); + let contract_addr = receipt.contract_address.unwrap(); + assert!(receipt.status()); + + let code = provider.get_code_at(contract_addr).await.unwrap(); + assert_eq!(ContractTestContext::get_code(), code); + + let output = provider + .seismic_call_raw(SendableTx::Builder(TransactionBuilder::<SeismicReth>::with_to( + TransactionBuilder::<SeismicReth>::with_input( + SeismicTransactionRequest::default(), + ContractTestContext::get_is_odd_input_plaintext(), + ), + contract_addr, + ))) + .await + .unwrap(); + assert_eq!(U256::from_be_slice(&output), U256::ZERO); + + let set_num_tx = seismic_reth_tx_builder() + .with_input(ContractTestContext::get_set_number_input_plaintext()) + .with_to(contract_addr) + .into(); + let pending_transaction = provider.send_transaction(set_num_tx).await.unwrap(); + let tx_hash = *pending_transaction.tx_hash(); + node.advance_block().await?; + + let receipt = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap(); + assert!(receipt.status()); + + let output = provider + .seismic_call_raw(SendableTx::Builder(TransactionBuilder::<SeismicReth>::with_to( + TransactionBuilder::<SeismicReth>::with_input( + SeismicTransactionRequest::default(), + ContractTestContext::get_is_odd_input_plaintext(), + ), + contract_addr, + ))) + .await + .unwrap(); + assert_eq!(U256::from_be_slice(&output), U256::from(1)); + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_seismic_precompiles_end_to_end() -> eyre::Result<()> { + let (mut node, _client, chain_id, _wallet, _tasks) = setup_test_node().await?; + let reth_rpc_url = node.rpc_url().to_string(); + + let _wallet = Wallet::default().with_chain_id(chain_id); + let from = _wallet.inner.address(); + let wallet: SeismicWallet<SeismicReth> = SeismicWallet::from(_wallet.inner); + + let provider = SeismicProviderBuilder::new() + .wallet(wallet) + .connect_http(reqwest::Url::parse(&reth_rpc_url).unwrap()) + .await + .unwrap(); + let req = TransactionBuilder::<SeismicReth>::with_kind( + TransactionBuilder::<SeismicReth>::with_input( + SeismicTransactionRequest::default(), + get_encryption_precompiles_contracts(), + ), + TxKind::Create, + ); + let pending_transaction = provider.send_transaction(req).await.unwrap(); + let tx_hash = *pending_transaction.tx_hash(); + node.advance_block().await?; + + let receipt = provider.get_transaction_receipt(tx_hash).await.unwrap().unwrap(); + let contract_addr = receipt.contract_address.unwrap(); + assert!(receipt.status()); + + let code = provider.get_code_at(contract_addr).await.unwrap(); + assert!(!code.is_empty(), "contract should have runtime code after deployment"); + + let private_key = + B256::from_hex("7e34abdcd62eade2e803e0a8123a0015ce542b380537eff288d6da420bcc2d3b").unwrap(); + + // Tx #1: Set AES key in the contract + let unencrypted_aes_key = get_input_data(PRECOMPILES_TEST_SET_AES_KEY_SELECTOR, private_key); + let pending = provider + .send_transaction( + seismic_reth_tx_builder() + .with_from(from) + .with_to(contract_addr) + .with_input(unencrypted_aes_key) + .into(), + ) + .await + .unwrap(); + let set_key_tx_hash = *pending.tx_hash(); + node.advance_block().await?; + let receipt = provider.get_transaction_receipt(set_key_tx_hash).await.unwrap().unwrap(); + assert!(receipt.status()); + + // Tx #2: Encrypt & send "hello world" + let raw_message = "hello world"; + let message = Bytes::from(raw_message); + type PlaintextType = Bytes; + + let encoded_message = PlaintextType::abi_encode(&message); + let unencrypted_input = + concat_input_data(PRECOMPILES_TEST_ENCRYPTED_LOG_SELECTOR, encoded_message.into()); + + let pending = provider + .send_transaction( + seismic_reth_tx_builder() + .with_from(from) + .with_to(contract_addr) + .with_input(unencrypted_input) + .into(), + ) + .await + .unwrap(); + let encrypt_tx_hash = *pending.tx_hash(); + node.advance_block().await?; + let receipt = provider.get_transaction_receipt(encrypt_tx_hash).await.unwrap().unwrap(); + + // Verify the encrypted log event + let logs = receipt.inner.logs(); + assert_eq!(logs.len(), 1); + assert_eq!(logs[0].inner.address, contract_addr); + + let log_data = logs[0].inner.data.clone(); + let event = Event { + name: "EncryptedMessage".into(), + inputs: vec![ + EventParam { ty: "uint96".into(), indexed: true, ..Default::default() }, + EventParam { ty: "bytes".into(), indexed: false, ..Default::default() }, + ], + anonymous: false, + }; + let decoded = event.decode_log(&log_data.into_log_data()).unwrap(); + + sol! { + #[derive(Debug, PartialEq, Eq)] + interface Encryption { + function decrypt(uint96 nonce, bytes calldata ciphertext) + external + view + onlyOwner + returns (bytes memory plaintext); + } + } + + let nonce: U96 = + U96::from_be_bytes(B96::from_slice(&decoded.indexed[0].abi_encode_packed()).into()); + let ciphertext = Bytes::from(decoded.body[0].abi_encode_packed()); + + let call = Encryption::decryptCall { nonce, ciphertext: ciphertext.clone() }; + let unencrypted_decrypt_call = Bytes::from(call.abi_encode()); + + let tx_req = seismic_reth_tx_builder() + .with_from(from) + .with_to(contract_addr) + .with_input(unencrypted_decrypt_call) + .into() + .seismic(); + + let output = provider.seismic_call_raw(SendableTx::Builder(tx_req)).await.unwrap(); + + // Locally decrypt to cross-check + let secp_private = secp256k1::SecretKey::from_slice(private_key.as_ref()).unwrap(); + let aes_key: &[u8; 32] = &secp_private.secret_bytes()[0..32].try_into().unwrap(); + let nonce: [u8; 12] = decoded.indexed[0].abi_encode_packed().try_into().unwrap(); + let decrypted_locally = + aes_decrypt(aes_key.into(), &ciphertext, nonce).expect("AES decryption failed"); + assert_eq!(decrypted_locally, message); + + let result_bytes = PlaintextType::abi_decode(&output).expect("failed to decode the bytes"); + let final_string = + String::from_utf8(result_bytes.to_vec()).expect("invalid utf8 in decrypted bytes"); + assert_eq!(final_string, raw_message); + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_eth_call_rejects_sload_on_private_storage() -> eyre::Result<()> { + let (mut node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let contract_addr = flagged_storage_deploy_and_write( + &mut node, + &client, + chain_id, + &wallet, + FLAGGED_STORAGE_SET_PRIVATE, + U256::from(42), + ) + .await?; + + // Raw SLOAD on private storage via eth_call - should FAIL + let read_calldata: Bytes = hex::decode(FLAGGED_STORAGE_READ_PRIVATE_SLOAD_RAW).unwrap().into(); + let result = EthApiOverrideClient::<Block>::call( + &client, + SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(wallet.inner.address()), + to: Some(TxKind::Call(contract_addr)), + input: TransactionInput { data: Some(read_calldata), ..Default::default() }, + ..Default::default() + }, + seismic_elements: None, + } + .into(), + None, + None, + None, + ) + .await; + + match &result { + Ok(output) => panic!("SLOAD on private storage should fail, but got Ok: {:?}", output), + Err(e) => { + let err_msg = e.to_string().to_lowercase(); + assert!( + err_msg.contains("invalidprivatestorageaccess"), + "Expected 'InvalidPrivateStorageAccess' revert, got: {}", + err_msg + ); + } + } + + Ok(()) +} + +/// Deploy flagged storage contract and write a value, returning contract address. +async fn flagged_storage_deploy_and_write( + node: &mut SeismicTestNode, + client: &jsonrpsee::http_client::HttpClient, + chain_id: u64, + wallet: &Wallet, + selector: &str, + value: U256, +) -> eyre::Result<alloy_primitives::Address> { + let tx_hash = EthApiOverrideClient::<Block>::send_raw_transaction( + client, + get_signed_deploy_tx_bytes( + wallet.inner.clone(), + get_nonce(client, wallet.inner.address()).await, + chain_id, + Bytes::from_static(FLAGGED_STORAGE_TEST_BYTECODE), + ) + .await + .into(), + ) + .await + .unwrap(); + node.advance_block().await?; + + let receipt = EthApiClient::< + SeismicTransactionRequest, + SeismicTransactionSigned, + SeismicBlock, + SeismicTransactionReceipt, + Header, + >::transaction_receipt(client, tx_hash) + .await + .unwrap() + .unwrap(); + let contract_addr = receipt.contract_address.unwrap(); + assert!(receipt.status()); + + // Write value via seismic tx + let block_hash = get_recent_block_hash(client).await; + let set_data = get_input_data(selector, B256::from(value)); + EthApiClient::< + SeismicTransactionRequest, + SeismicTransactionSigned, + SeismicBlock, + SeismicTransactionReceipt, + Header, + >::send_raw_transaction( + client, + get_signed_seismic_tx_bytes( + &wallet.inner, + get_nonce(client, wallet.inner.address()).await, + TxKind::Call(contract_addr), + chain_id, + set_data, + block_hash, + ) + .await, + ) + .await + .unwrap(); + node.advance_block().await?; + + Ok(contract_addr) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_eth_call_allows_cload_on_public_storage() -> eyre::Result<()> { + let (mut node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let contract_addr = flagged_storage_deploy_and_write( + &mut node, + &client, + chain_id, + &wallet, + FLAGGED_STORAGE_SET_PUBLIC, + U256::from(123), + ) + .await?; + + let block_hash = get_recent_block_hash(&client).await; + let read_calldata: Bytes = hex::decode(FLAGGED_STORAGE_READ_PUBLIC_CLOAD).unwrap().into(); + let nonce = get_nonce(&client, wallet.inner.address()).await; + let result = EthApiOverrideClient::<Block>::call( + &client, + get_signed_seismic_tx_bytes( + &wallet.inner, + nonce, + TxKind::Call(contract_addr), + chain_id, + read_calldata, + block_hash, + ) + .await + .into(), + None, + None, + None, + ) + .await; + + assert!(result.is_ok(), "CLOAD on public storage should succeed, got: {:?}", result.err()); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_eth_call_allows_cload_on_private_storage() -> eyre::Result<()> { + let (mut node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let contract_addr = flagged_storage_deploy_and_write( + &mut node, + &client, + chain_id, + &wallet, + FLAGGED_STORAGE_SET_PRIVATE, + U256::from(42), + ) + .await?; + + let block_hash = get_recent_block_hash(&client).await; + let read_calldata: Bytes = hex::decode(FLAGGED_STORAGE_READ_PRIVATE_CLOAD).unwrap().into(); + let nonce = get_nonce(&client, wallet.inner.address()).await; + let to = TxKind::Call(contract_addr); + let output = EthApiOverrideClient::<Block>::call( + &client, + get_signed_seismic_tx_bytes(&wallet.inner, nonce, to, chain_id, read_calldata, block_hash) + .await + .into(), + None, + None, + None, + ) + .await + .expect("CLOAD on private storage should succeed"); + + let metadata = + get_seismic_metadata(wallet.inner.address(), chain_id, nonce, to, U256::ZERO, block_hash); + let decrypted = client_decrypt(metadata, &output).unwrap(); + assert_eq!(U256::from_be_slice(&decrypted), U256::from(42)); + Ok(()) +} + +/// Test that Solidity-level `readPublicSload()` succeeds. +/// (compiler uses regular SLOAD on public slot — should work) +#[tokio::test(flavor = "multi_thread")] +async fn test_solidity_read_public_sload_succeeds() -> eyre::Result<()> { + let (mut node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let contract_addr = flagged_storage_deploy_and_write( + &mut node, + &client, + chain_id, + &wallet, + FLAGGED_STORAGE_SET_PUBLIC, + U256::from(123), + ) + .await?; + + let read_calldata: Bytes = hex::decode(FLAGGED_STORAGE_READ_PUBLIC_SLOAD).unwrap().into(); + let result = EthApiOverrideClient::<Block>::call( + &client, + SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(wallet.inner.address()), + to: Some(TxKind::Call(contract_addr)), + input: TransactionInput { data: Some(read_calldata), ..Default::default() }, + ..Default::default() + }, + seismic_elements: None, + } + .into(), + None, + None, + None, + ) + .await + .expect("Solidity readPublicSload() should succeed"); + + assert_eq!( + U256::from_be_slice(&result), + U256::from(123), + "readPublicSload() should return 123" + ); + Ok(()) +} + +/// Test that Solidity-level `readPrivateSload()` succeeds. +/// (compiler uses CLOAD internally for suint256 types, so this passes) +#[tokio::test(flavor = "multi_thread")] +async fn test_solidity_read_private_succeeds() -> eyre::Result<()> { + let (mut node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let contract_addr = flagged_storage_deploy_and_write( + &mut node, + &client, + chain_id, + &wallet, + FLAGGED_STORAGE_SET_PRIVATE, + U256::from(42), + ) + .await?; + + let read_calldata: Bytes = hex::decode(FLAGGED_STORAGE_READ_PRIVATE_SLOAD).unwrap().into(); + let result = EthApiOverrideClient::<Block>::call( + &client, + SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(wallet.inner.address()), + to: Some(TxKind::Call(contract_addr)), + input: TransactionInput { data: Some(read_calldata), ..Default::default() }, + ..Default::default() + }, + seismic_elements: None, + } + .into(), + None, + None, + None, + ) + .await + .expect("Solidity readPrivateSload() should succeed (compiler uses CLOAD)"); + + assert_eq!(U256::from_be_slice(&result), U256::from(42), "readPrivateSload() should return 42"); + Ok(()) +} + +// FlaggedStorageTestContract bytecode and selectors +const FLAGGED_STORAGE_TEST_BYTECODE: &[u8] = &hex!("6080604052348015600e575f5ffd5b506103048061001c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610086575f3560e01c8063717d5de311610059578063717d5de3146100fe57806394193f111461011c5780639ad95ef81461013a578063ef5617921461015857610086565b806331845f7d1461008a578063420f38f8146100a65780634e0d898c146100c25780635d5b397f146100e0575b5f5ffd5b6100a4600480360381019061009f91906101f6565b610176565b005b6100c060048036038101906100bb9190610254565b61017f565b005b6100ca610189565b6040516100d7919061028e565b60405180910390f35b6100e8610192565b6040516100f5919061028e565b60405180910390f35b610106610197565b604051610113919061028e565b60405180910390f35b61012461019f565b604051610131919061028e565b60405180910390f35b6101426101aa565b60405161014f919061028e565b60405180910390f35b6101606101b6565b60405161016d919061028e565b60405180910390f35b805f8190555050565b8060018190b15050565b5f600154905090565b5f5481565b5f5f54905090565b5f5fb0805f5260205ff35b5f6001b0805f5260205ff35b5f6001b0905090565b5f5ffd5b5f819050919050565b6101d5816101c3565b81146101df575f5ffd5b50565b5f813590506101f0816101cc565b92915050565b5f6020828403121561020b5761020a6101bf565b5b5f610218848285016101e2565b91505092915050565b5f819050919050565b61023381610221565b811461023d575f5ffd5b50565b5f8135905061024e8161022a565b92915050565b5f60208284031215610269576102686101bf565b5b5f61027684828501610240565b91505092915050565b610288816101c3565b82525050565b5f6020820190506102a15f83018461027f565b9291505056fea2646970667358221220bed26217d42178260b773a5edf5b427f93dde38ce69f366f5ac8ace37b09e4fd64736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a"); +const FLAGGED_STORAGE_SET_PUBLIC: &str = "31845f7d"; // setPublic(uint256) +const FLAGGED_STORAGE_SET_PRIVATE: &str = "420f38f8"; // setPrivate(suint256) +const FLAGGED_STORAGE_READ_PUBLIC_SLOAD: &str = "717d5de3"; // readPublicSload() +const FLAGGED_STORAGE_READ_PRIVATE_SLOAD: &str = "ef561792"; // readPrivateSload() +const FLAGGED_STORAGE_READ_PRIVATE_SLOAD_RAW: &str = "4e0d898c"; // readPrivateSloadRaw() +const FLAGGED_STORAGE_READ_PRIVATE_CLOAD: &str = "9ad95ef8"; // readPrivateCload() +const FLAGGED_STORAGE_READ_PUBLIC_CLOAD: &str = "94193f11"; // readPublicCload() + +const fn get_encryption_precompiles_contracts() -> Bytes { + Bytes::from_static(&hex!("6080604052348015600e575f5ffd5b50335f5f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610dce8061005b5f395ff3fe608060405234801561000f575f5ffd5b506004361061004a575f3560e01c806328696e361461004e5780638da5cb5b1461006a578063a061904014610088578063ce75255b146100a4575b5f5ffd5b61006860048036038101906100639190610687565b6100d4565b005b61007261019a565b60405161007f9190610711565b60405180910390f35b6100a2600480360381019061009d919061075d565b6101be565b005b6100be60048036038101906100b991906107c9565b610256565b6040516100cb9190610896565b60405180910390f35b5f6100dd610412565b90505f61012d8285858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f81840152601f19601f820116905080830192505050505050506104f5565b9050816bffffffffffffffffffffffff167f093a34a48cc07b4bf1355d9c15ec71077c85342d872753188302f99341f961008260405160200161017091906108f0565b60405160208183030381529060405260405161018c9190610896565b60405180910390a250505050565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461024c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161024390610986565b60405180910390fd5b8060018190b15050565b60605f5f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102dd90610986565b60405180910390fd5b5f838390501161032b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610322906109ee565b60405180910390fd5b5f606790505f6001b086868660405160200161034a9493929190610a92565b60405160208183030381529060405290505f5f8373ffffffffffffffffffffffffffffffffffffffff168360405161038291906108f0565b5f60405180830381855afa9150503d805f81146103ba576040519150601f19603f3d011682016040523d82523d5f602084013e6103bf565b606091505b509150915081610404576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103fb90610b3c565b60405180910390fd5b809450505050509392505050565b5f5f606490505f5f8273ffffffffffffffffffffffffffffffffffffffff1660206040516020016104439190610b9d565b60405160208183030381529060405260405161045f91906108f0565b5f60405180830381855afa9150503d805f8114610497576040519150601f19603f3d011682016040523d82523d5f602084013e61049c565b606091505b5091509150816104e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104d890610c01565b60405180910390fd5b5f60208201519050805f1c94505050505090565b60605f606690505f6001b0858560405160200161051493929190610c1f565b60405160208183030381529060405290505f5f8373ffffffffffffffffffffffffffffffffffffffff168360405161054c91906108f0565b5f60405180830381855afa9150503d805f8114610584576040519150601f19603f3d011682016040523d82523d5f602084013e610589565b606091505b5091509150816105ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105c590610cc7565b60405180910390fd5b5f815111610611576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161060890610d55565b60405180910390fd5b8094505050505092915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f84011261064757610646610626565b5b8235905067ffffffffffffffff8111156106645761066361062a565b5b6020830191508360018202830111156106805761067f61062e565b5b9250929050565b5f5f6020838503121561069d5761069c61061e565b5b5f83013567ffffffffffffffff8111156106ba576106b9610622565b5b6106c685828601610632565b92509250509250929050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6106fb826106d2565b9050919050565b61070b816106f1565b82525050565b5f6020820190506107245f830184610702565b92915050565b5f819050919050565b61073c8161072a565b8114610746575f5ffd5b50565b5f8135905061075781610733565b92915050565b5f602082840312156107725761077161061e565b5b5f61077f84828501610749565b91505092915050565b5f6bffffffffffffffffffffffff82169050919050565b6107a881610788565b81146107b2575f5ffd5b50565b5f813590506107c38161079f565b92915050565b5f5f5f604084860312156107e0576107df61061e565b5b5f6107ed868287016107b5565b935050602084013567ffffffffffffffff81111561080e5761080d610622565b5b61081a86828701610632565b92509250509250925092565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f61086882610826565b6108728185610830565b9350610882818560208601610840565b61088b8161084e565b840191505092915050565b5f6020820190508181035f8301526108ae818461085e565b905092915050565b5f81905092915050565b5f6108ca82610826565b6108d481856108b6565b93506108e4818560208601610840565b80840191505092915050565b5f6108fb82846108c0565b915081905092915050565b5f82825260208201905092915050565b7f4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f5f8201527f6e00000000000000000000000000000000000000000000000000000000000000602082015250565b5f610970602183610906565b915061097b82610916565b604082019050919050565b5f6020820190508181035f83015261099d81610964565b9050919050565b7f436970686572746578742063616e6e6f7420626520656d7074790000000000005f82015250565b5f6109d8601a83610906565b91506109e3826109a4565b602082019050919050565b5f6020820190508181035f830152610a05816109cc565b9050919050565b5f819050919050565b610a26610a218261072a565b610a0c565b82525050565b5f8160a01b9050919050565b5f610a4282610a2c565b9050919050565b610a5a610a5582610788565b610a38565b82525050565b828183375f83830152505050565b5f610a7983856108b6565b9350610a86838584610a60565b82840190509392505050565b5f610a9d8287610a15565b602082019150610aad8286610a49565b600c82019150610abe828486610a6e565b915081905095945050505050565b7f414553206465637279707420707265636f6d70696c652063616c6c206661696c5f8201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b5f610b26602283610906565b9150610b3182610acc565b604082019050919050565b5f6020820190508181035f830152610b5381610b1a565b9050919050565b5f63ffffffff82169050919050565b5f8160e01b9050919050565b5f610b7f82610b69565b9050919050565b610b97610b9282610b5a565b610b75565b82525050565b5f610ba88284610b86565b60048201915081905092915050565b7f524e4720507265636f6d70696c652063616c6c206661696c65640000000000005f82015250565b5f610beb601a83610906565b9150610bf682610bb7565b602082019050919050565b5f6020820190508181035f830152610c1881610bdf565b9050919050565b5f610c2a8286610a15565b602082019150610c3a8285610a49565b600c82019150610c4a82846108c0565b9150819050949350505050565b7f41455320656e637279707420707265636f6d70696c652063616c6c206661696c5f8201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b5f610cb1602283610906565b9150610cbc82610c57565b604082019050919050565b5f6020820190508181035f830152610cde81610ca5565b9050919050565b7f456e6372797074696f6e2063616c6c2072657475726e6564206e6f206f7574705f8201527f7574000000000000000000000000000000000000000000000000000000000000602082015250565b5f610d3f602283610906565b9150610d4a82610ce5565b604082019050919050565b5f6020820190508181035f830152610d6c81610d33565b905091905056fea2646970667358221220cdc3edd7891930a1ad58becbe2b3f7679ecfc78a3b1f8a803d4c381c8318287864736f6c637827302e382e32382d63692e323032342e31312e342b636f6d6d69742e32306261666332392e6d6f640058")) +} + +fn get_input_data(selector: &str, value: B256) -> Bytes { + let selector_bytes: Vec<u8> = hex::decode(&selector[0..8]).expect("Invalid selector"); + let value_bytes: Bytes = value.into(); + let mut input_data = Vec::new(); + input_data.extend_from_slice(&selector_bytes); + input_data.extend_from_slice(&value_bytes); + input_data.into() +} + +fn concat_input_data(selector: &str, value: Bytes) -> Bytes { + let selector_bytes: Vec<u8> = hex::decode(&selector[0..8]).expect("Invalid selector"); + let value_bytes: Bytes = value; + let mut input_data = Vec::new(); + input_data.extend_from_slice(&selector_bytes); + input_data.extend_from_slice(&value_bytes); + input_data.into() +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_eth_call_rejects_code_override() -> eyre::Result<()> { + let (_node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let victim_addr = Address::from_hex("0x0000000000000000000000000000000000001234").unwrap(); + + let mut state_overrides = StateOverride::default(); + state_overrides.insert( + victim_addr, + AccountOverride { + code: Some(Bytes::from_static(&hex!( + "7f0000000000000000000000000000000000000000000000000000000000000001b060005260206000f3" + ))), + ..Default::default() + }, + ); + + let result = EthApiOverrideClient::<Block>::call( + &client, + SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(wallet.inner.address()), + to: Some(TxKind::Call(victim_addr)), + gas: Some(1_000_000), + chain_id: Some(chain_id), + ..Default::default() + }, + seismic_elements: None, + } + .into(), + None, + Some(state_overrides), + None, + ) + .await; + + match &result { + Ok(output) => panic!( + "eth_call with code override should be rejected, but got Ok: 0x{}", + hex::encode(output) + ), + Err(e) => { + let err_msg = e.to_string(); + assert!( + err_msg.to_lowercase().contains("code overrides are not permitted"), + "Expected code override rejection error, got: {}", + err_msg + ); + } + } + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_eth_estimate_gas_rejects_code_override() -> eyre::Result<()> { + let (_node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let victim_addr = Address::from_hex("0x0000000000000000000000000000000000001234").unwrap(); + + let mut state_overrides = StateOverride::default(); + state_overrides.insert( + victim_addr, + AccountOverride { + code: Some(Bytes::from_static(&hex!("6001b060005260206000f3"))), + ..Default::default() + }, + ); + + let result = EthApiOverrideClient::<Block>::estimate_gas( + &client, + SeismicCallRequest::TransactionRequest(SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(wallet.inner.address()), + to: Some(TxKind::Call(victim_addr)), + gas: Some(1_000_000), + chain_id: Some(chain_id), + ..Default::default() + }, + seismic_elements: None, + }), + None, + Some(state_overrides), + ) + .await; + + match &result { + Ok(gas) => { + panic!("eth_estimateGas with code override should be rejected, but got Ok: {}", gas) + } + Err(e) => { + let err_msg = e.to_string(); + assert!( + err_msg.to_lowercase().contains("code overrides are not permitted"), + "Expected code override rejection error, got: {}", + err_msg + ); + } + } + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_eth_simulate_v1_rejects_code_override() -> eyre::Result<()> { + let (_node, client, chain_id, wallet, _tasks) = setup_test_node().await?; + + let victim_addr = Address::from_hex("0x0000000000000000000000000000000000001234").unwrap(); + + let mut state_overrides = StateOverride::default(); + state_overrides.insert( + victim_addr, + AccountOverride { + code: Some(Bytes::from_static(&hex!("6001b060005260206000f3"))), + ..Default::default() + }, + ); + + let nonce = get_nonce(&client, wallet.inner.address()).await; + let tx_bytes = get_signed_deploy_tx_bytes( + wallet.inner.clone(), + nonce, + chain_id, + ContractTestContext::get_deploy_input_plaintext(), + ) + .await; + + let block_with_code_override = SimBlock { + block_overrides: None, + state_overrides: Some(state_overrides), + calls: vec![SeismicCallRequest::Bytes(tx_bytes)], + }; + + let simulate_payload = SimulatePayload::<SeismicCallRequest> { + block_state_calls: vec![block_with_code_override], + trace_transfers: false, + validation: false, + return_full_transactions: false, + }; + + let result = EthApiOverrideClient::<Block>::simulate_v1(&client, simulate_payload, None).await; + + match &result { + Ok(_) => panic!("eth_simulateV1 with code override should be rejected"), + Err(e) => { + let err_msg = e.to_string(); + assert!( + err_msg.to_lowercase().contains("code overrides are not permitted"), + "Expected code override rejection error, got: {}", + err_msg + ); + } + } + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/main.rs seismic-reth/crates/seismic/node/tests/e2e/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..8c9653854e36e422c160534b3f6454a970cf2c9c --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/main.rs @@ -0,0 +1,12 @@ +#![allow(missing_docs, clippy::unwrap_used, clippy::expect_used, clippy::indexing_slicing)] + +mod fuzz; +mod hardfork_config; +mod integration; +mod ops; +mod p2p; +//mod rpc_compat; // todo: disabling for now we need a more sustainable way to generate state +// roots. Currently broken from stable coin gas update not burning gas +mod testsuite; + +const fn main() {}
diff --git reth/crates/seismic/node/tests/e2e/ops.rs seismic-reth/crates/seismic/node/tests/e2e/ops.rs new file mode 100644 index 0000000000000000000000000000000000000000..85efd5b0e52f34b9200c5b23f29b6a7fa38da3c9 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/ops.rs @@ -0,0 +1,285 @@ +//! E2E tests for ops whitelist/revoke via sentinel transactions in `eth_sendRawTransaction`. + +use alloy_consensus::SignableTransaction; +use alloy_eips::eip2718::Encodable2718; +use alloy_primitives::{address, Address, Bytes, TxKind, U256}; +use alloy_signer::{Signer, SignerSync}; +use alloy_signer_local::PrivateKeySigner; +use alloy_sol_types::{sol, SolCall}; +use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder, rpc_params}; +use reth_chainspec::{make_genesis_header, Chain, ChainSpec}; +use reth_e2e_test_utils::wallet::Wallet; +use reth_node_builder::{EngineNodeLauncher, Node, NodeBuilder, NodeConfig, NodeHandle}; +use reth_node_core::args::{DevArgs, RpcServerArgs}; +use reth_primitives_traits::SealedHeader; +use reth_rpc_builder::RpcModuleSelection; +use reth_rpc_layer::{eip712_signing_hash, WHITELIST_TX_SENTINEL}; +use reth_seismic_node::{ + node::SeismicNode, + utils::e2e::{ensure_mock_purpose_keys, SEISMIC_TIMESTAMP_MULTIPLIER}, +}; +use reth_tasks::TaskManager; +use std::sync::Arc; + +sol! { + interface OpsWhitelistTxAuth { + function whitelistKey(address target, uint64 expiresAt) external; + function revokeKey(address target) external; + } +} + +/// The Params contract address. +const PARAMS_CONTRACT: Address = address!("0x0000000000000000000000000000506172616d73"); + +/// Build a Seismic dev chain spec with a custom governance address in the Params contract. +fn dev_chain_spec_with_governance(governance_address: Address) -> Arc<ChainSpec> { + let mut genesis: alloy_genesis::Genesis = + serde_json::from_str(include_str!("../../../chainspec/res/genesis/dev.json")) + .expect("deserialize dev genesis"); + + #[cfg(not(feature = "timestamp-in-seconds"))] + { + genesis.timestamp *= 1000; + } + + // Overwrite slot 0 of the Params contract with the governance address. + let mut value = [0u8; 32]; + value[12..].copy_from_slice(governance_address.as_slice()); + if let Some(account) = genesis.alloc.get_mut(&PARAMS_CONTRACT) { + if let Some(ref mut storage) = account.storage { + storage.insert(alloy_primitives::B256::ZERO, alloy_primitives::B256::from(value)); + } + } + + let hardforks = reth_seismic_forks::SEISMIC_DEV_HARDFORKS.clone(); + Arc::new(ChainSpec { + chain: Chain::from_id(5124), + genesis_header: SealedHeader::seal_slow(make_genesis_header(&genesis, &hardforks)), + genesis, + paris_block_and_final_difficulty: Some((0, U256::from(0))), + hardforks, + ..Default::default() + }) +} + +fn seismic_payload_attributes(timestamp: u64) -> reth_payload_builder::EthPayloadBuilderAttributes { + use alloy_primitives::B256; + use alloy_rpc_types_engine::PayloadAttributes; + reth_payload_builder::EthPayloadBuilderAttributes::new( + B256::ZERO, + PayloadAttributes { + timestamp: timestamp * SEISMIC_TIMESTAMP_MULTIPLIER, + prev_randao: B256::ZERO, + suggested_fee_recipient: Address::ZERO, + withdrawals: Some(vec![]), + parent_beacon_block_root: Some(B256::ZERO), + }, + ) +} + +/// Build and sign a legacy transaction targeting the sentinel address with the given calldata. +fn build_sentinel_tx(signer: &PrivateKeySigner, chain_id: u64, calldata: Bytes) -> Bytes { + let tx = alloy_consensus::TxLegacy { + chain_id: Some(chain_id), + nonce: 0, + gas_limit: 100_000, + gas_price: 0, + to: TxKind::Call(WHITELIST_TX_SENTINEL), + value: U256::ZERO, + input: calldata, + }; + + let sig = signer.sign_hash_sync(&tx.signature_hash()).expect("sign sentinel tx"); + let signed = tx.into_signed(sig); + let envelope = alloy_consensus::TxEnvelope::Legacy(signed); + Encodable2718::encoded_2718(&envelope).into() +} + +fn whitelist_calldata(target: Address, expires_at: u64) -> Bytes { + OpsWhitelistTxAuth::whitelistKeyCall { target, expiresAt: expires_at }.abi_encode().into() +} + +fn revoke_calldata(target: Address) -> Bytes { + OpsWhitelistTxAuth::revokeKeyCall { target }.abi_encode().into() +} + +fn current_unix_timestamp() -> u64 { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .expect("system clock before unix epoch") + .as_secs() +} + +/// Send a signed request to the ops RPC server. +async fn send_ops_signed_request( + url: &str, + body: &str, + signer: &PrivateKeySigner, + nonce: Option<&str>, + chain_id: u64, +) -> reqwest::Response { + let signing_nonce = nonce.unwrap_or(""); + let hash = eip712_signing_hash(body.as_bytes(), signing_nonce, chain_id); + let signature = signer.sign_hash(&hash).await.unwrap(); + let sig_hex = alloy_primitives::hex::encode(signature.as_bytes()); + + let mut req = reqwest::Client::new() + .post(url) + .header("Content-Type", "application/json") + .header("X-Signature", &sig_hex); + if let Some(nonce) = nonce { + req = req.header("X-Nonce", nonce); + } + req.body(body.to_string()).send().await.unwrap() +} + +fn ops_get_storage_request(address: Address, slot: alloy_primitives::B256, id: u64) -> String { + serde_json::json!({ + "jsonrpc": "2.0", + "method": "ops_getStorageAt", + "params": [format!("{address:?}"), format!("{slot:?}"), "latest"], + "id": id + }) + .to_string() +} + +/// Launch a Seismic node with ops enabled and a custom governance address. +async fn launch_ops_node( + governance_signer: &PrivateKeySigner, +) -> eyre::Result<( + reth_e2e_test_utils::NodeHelperType< + SeismicNode, + reth_provider::providers::BlockchainProvider< + reth_node_api::NodeTypesWithDBAdapter<SeismicNode, reth_e2e_test_utils::TmpDB>, + >, + >, + TaskManager, + Wallet, +)> { + let chain_spec = dev_chain_spec_with_governance(governance_signer.address()); + let tasks = TaskManager::current(); + let exec = tasks.executor(); + + ensure_mock_purpose_keys(); + + let mut rpc_args = RpcServerArgs::default() + .with_unused_ports() + .with_http() + .with_http_api(RpcModuleSelection::All); + rpc_args.ops_enable = true; + rpc_args.ops_port = 0; // random unused port + + let node_config = NodeConfig::new(chain_spec) + .with_unused_ports() + .with_dev(DevArgs { dev: true, ..Default::default() }) + .with_rpc(rpc_args); + + let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config) + .testing_node(exec) + .with_types_and_provider::<SeismicNode, reth_provider::providers::BlockchainProvider<_>>() + .with_components(SeismicNode::default().components_builder()) + .with_add_ons(SeismicNode::default().add_ons()) + .launch_with_fn(|builder| { + let launcher = EngineNodeLauncher::new( + builder.task_executor().clone(), + builder.config().datadir(), + Default::default(), + ); + builder.launch_with(launcher) + }) + .await?; + + let node = + reth_e2e_test_utils::node::NodeTestContext::new(node, seismic_payload_attributes).await?; + let wallet = Wallet::default().with_chain_id(5124); + + Ok((node, tasks, wallet)) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_sentinel_whitelist_from_governance_key() { + reth_tracing::init_test_tracing(); + let governance = PrivateKeySigner::random(); + let reader = PrivateKeySigner::random(); + + let (node, _tasks, _wallet) = launch_ops_node(&governance).await.unwrap(); + let rpc_url = node.rpc_url().to_string(); + let client = HttpClientBuilder::default().build(&rpc_url).unwrap(); + let chain_id = 5124u64; + + // Send a whitelist sentinel tx from governance key. + let expires_at = current_unix_timestamp() + 3600; + let raw_tx = + build_sentinel_tx(&governance, chain_id, whitelist_calldata(reader.address(), expires_at)); + let result: serde_json::Value = client + .request( + "eth_sendRawTransaction", + rpc_params![format!("0x{}", alloy_primitives::hex::encode(&raw_tx))], + ) + .await + .expect("whitelist sentinel tx should succeed"); + assert!(result.is_string(), "should return a tx hash"); + + // Now verify the reader is whitelisted by querying the ops server. + let ops_url = format!( + "http://{}", + node.inner + .rpc_server_handles() + .ops + .as_ref() + .expect("ops server should be running") + .local_addr() + ); + let body = ops_get_storage_request(PARAMS_CONTRACT, alloy_primitives::B256::ZERO, 1); + let resp = send_ops_signed_request(&ops_url, &body, &reader, Some("0"), chain_id).await; + assert_eq!( + resp.status(), + reqwest::StatusCode::OK, + "whitelisted reader should be able to read storage" + ); + + // Send a revoke sentinel tx. + let raw_tx = build_sentinel_tx(&governance, chain_id, revoke_calldata(reader.address())); + let result: serde_json::Value = client + .request( + "eth_sendRawTransaction", + rpc_params![format!("0x{}", alloy_primitives::hex::encode(&raw_tx))], + ) + .await + .expect("revoke sentinel tx should succeed"); + assert!(result.is_string(), "should return a tx hash"); + + // Reader should no longer be whitelisted. + let body = ops_get_storage_request(PARAMS_CONTRACT, alloy_primitives::B256::ZERO, 2); + let resp = send_ops_signed_request(&ops_url, &body, &reader, Some("1"), chain_id).await; + assert_eq!( + resp.status(), + reqwest::StatusCode::UNAUTHORIZED, + "revoked reader should be rejected" + ); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_sentinel_whitelist_from_non_governance_key_fails() { + reth_tracing::init_test_tracing(); + let governance = PrivateKeySigner::random(); + let attacker = PrivateKeySigner::random(); + let target = PrivateKeySigner::random(); + + let (node, _tasks, _wallet) = launch_ops_node(&governance).await.unwrap(); + let rpc_url = node.rpc_url().to_string(); + let client = HttpClientBuilder::default().build(&rpc_url).unwrap(); + let chain_id = 5124u64; + + // Attacker tries to send a whitelist sentinel tx — should fail. + let expires_at = current_unix_timestamp() + 3600; + let raw_tx = + build_sentinel_tx(&attacker, chain_id, whitelist_calldata(target.address(), expires_at)); + let result = client + .request::<serde_json::Value, _>( + "eth_sendRawTransaction", + rpc_params![format!("0x{}", alloy_primitives::hex::encode(&raw_tx))], + ) + .await; + assert!(result.is_err(), "non-governance sentinel tx should be rejected"); +}
diff --git reth/crates/seismic/node/tests/e2e/p2p.rs seismic-reth/crates/seismic/node/tests/e2e/p2p.rs new file mode 100644 index 0000000000000000000000000000000000000000..c342d9fe43f43990ee8b5d31a214eeca878f2e15 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/p2p.rs @@ -0,0 +1,77 @@ +use futures::StreamExt; +use reth_seismic_node::utils::e2e::{advance_chain, ensure_mock_purpose_keys, setup}; +use std::sync::Arc; +use tokio::sync::Mutex; + +#[tokio::test] +async fn can_sync() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + ensure_mock_purpose_keys(); + + let (mut nodes, _tasks, wallet) = setup(3).await?; + let wallet = Arc::new(Mutex::new(wallet)); + + let third_node = nodes.pop().unwrap(); + let mut second_node = nodes.pop().unwrap(); + let mut first_node = nodes.pop().unwrap(); + + let tip: usize = 90; + let tip_index: usize = tip - 1; + let reorg_depth = 2; + + // On first node, create a chain up to block number 90a + let canonical_payload_chain = advance_chain(tip, &mut first_node, wallet.clone()).await?; + let canonical_chain = + canonical_payload_chain.iter().map(|p| p.block().hash()).collect::<Vec<_>>(); + + // On second node, sync optimistically up to block number 88a + second_node.update_optimistic_forkchoice(canonical_chain[tip_index - reorg_depth - 1]).await?; + second_node + .wait_block( + (tip - reorg_depth - 1) as u64, + canonical_chain[tip_index - reorg_depth - 1], + true, + ) + .await?; + // We send FCU twice to ensure that pool receives canonical chain update on the second FCU + // This is required because notifications are not sent during backfill sync + second_node.update_optimistic_forkchoice(canonical_chain[tip_index - reorg_depth]).await?; + second_node + .wait_block((tip - reorg_depth) as u64, canonical_chain[tip_index - reorg_depth], false) + .await?; + second_node.canonical_stream.next().await.unwrap(); + + // Trigger backfill sync until block 80 + third_node + .update_forkchoice(canonical_chain[tip_index - 10], canonical_chain[tip_index - 10]) + .await?; + third_node.wait_block((tip - 10) as u64, canonical_chain[tip_index - 10], true).await?; + // Trigger live sync to block 90 + third_node.update_optimistic_forkchoice(canonical_chain[tip_index]).await?; + third_node.wait_block(tip as u64, canonical_chain[tip_index], false).await?; + + // On second node, create a side chain: 88a -> 89b -> 90b + wallet.lock().await.inner_nonce -= reorg_depth as u64; + second_node.payload.timestamp = first_node.payload.timestamp - reorg_depth as u64; // TODO: probably want to make it node agnostic + let side_payload_chain = advance_chain(reorg_depth, &mut second_node, wallet.clone()).await?; + let side_chain = side_payload_chain.iter().map(|p| p.block().hash()).collect::<Vec<_>>(); + + // Creates fork chain by submitting 89b payload. + // By returning Valid here, op-node will finally return a finalized hash + let _ = third_node.submit_payload(side_payload_chain[0].clone()).await; + + // It will issue a pipeline reorg to 88a, and then make 89b canonical AND finalized. + third_node.update_forkchoice(side_chain[0], side_chain[0]).await?; + + // Make sure we have the updated block + third_node.wait_unwind((tip - reorg_depth) as u64).await?; + third_node + .wait_block( + side_payload_chain[0].block().number, + side_payload_chain[0].block().hash(), + false, + ) + .await?; + + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/rpc.rs seismic-reth/crates/seismic/node/tests/e2e/rpc.rs new file mode 100644 index 0000000000000000000000000000000000000000..cbede6189eda8e80b3743e7f52c3379feba1d0e3 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/rpc.rs @@ -0,0 +1,268 @@ +use crate::utils::eth_payload_attributes; +use alloy_eips::{calc_next_block_base_fee, eip2718::Encodable2718}; +use alloy_primitives::{Address, B256, U256}; +use alloy_provider::{network::EthereumWallet, Provider, ProviderBuilder, SendableTx}; +use alloy_rpc_types_beacon::relay::{ + BidTrace, BuilderBlockValidationRequestV3, BuilderBlockValidationRequestV4, + SignedBidSubmissionV3, SignedBidSubmissionV4, +}; +use alloy_rpc_types_engine::{BlobsBundleV1, ExecutionPayloadV3}; +use alloy_rpc_types_eth::TransactionRequest; +use rand::{rngs::StdRng, Rng, SeedableRng}; +use reth_chainspec::{ChainSpecBuilder, MAINNET}; +use reth_e2e_test_utils::setup_engine; +use reth_node_ethereum::EthereumNode; +use reth_payload_primitives::BuiltPayload; +use std::sync::Arc; + +alloy_sol_types::sol! { + #[sol(rpc, bytecode = "6080604052348015600f57600080fd5b5060405160db38038060db833981016040819052602a91607a565b60005b818110156074576040805143602082015290810182905260009060600160408051601f19818403018152919052805160209091012080555080606d816092565b915050602d565b505060b8565b600060208284031215608b57600080fd5b5051919050565b60006001820160b157634e487b7160e01b600052601160045260246000fd5b5060010190565b60168060c56000396000f3fe6080604052600080fdfea164736f6c6343000810000a")] + contract GasWaster { + constructor(uint256 iterations) { + for (uint256 i = 0; i < iterations; i++) { + bytes32 slot = keccak256(abi.encode(block.number, i)); + assembly { + sstore(slot, slot) + } + } + } + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_fee_history() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + + let seed: [u8; 32] = rand::thread_rng().gen(); + let mut rng = StdRng::from_seed(seed); + println!("Seed: {:?}", seed); + + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(MAINNET.chain) + .genesis(serde_json::from_str(include_str!("../assets/genesis.json")).unwrap()) + .cancun_activated() + .build(), + ); + + let (mut nodes, _tasks, wallet) = + setup_engine::<EthereumNode>(1, chain_spec.clone(), false, eth_payload_attributes).await?; + let mut node = nodes.pop().unwrap(); + let provider = ProviderBuilder::new() + .wallet(EthereumWallet::new(wallet.gen().swap_remove(0))) + .on_http(node.rpc_url()); + + let fee_history = provider.get_fee_history(10, 0_u64.into(), &[]).await?; + + let genesis_base_fee = chain_spec.initial_base_fee().unwrap() as u128; + let expected_first_base_fee = genesis_base_fee - + genesis_base_fee / chain_spec.base_fee_params_at_block(0).max_change_denominator; + assert_eq!(fee_history.base_fee_per_gas[0], genesis_base_fee); + assert_eq!(fee_history.base_fee_per_gas[1], expected_first_base_fee,); + + // Spend some gas + let builder = GasWaster::deploy_builder(&provider, U256::from(500)).send().await?; + node.advance_block().await?; + let receipt = builder.get_receipt().await?; + assert!(receipt.status()); + + let block = provider.get_block_by_number(1.into()).await?.unwrap(); + assert_eq!(block.header.gas_used, receipt.gas_used,); + assert_eq!(block.header.base_fee_per_gas.unwrap(), expected_first_base_fee as u64); + + for _ in 0..100 { + let _ = + GasWaster::deploy_builder(&provider, U256::from(rng.gen_range(0..1000))).send().await?; + + node.advance_block().await?; + } + + let latest_block = provider.get_block_number().await?; + + for _ in 0..100 { + let latest_block = rng.gen_range(0..=latest_block); + let block_count = rng.gen_range(1..=(latest_block + 1)); + + let fee_history = provider.get_fee_history(block_count, latest_block.into(), &[]).await?; + + let mut prev_header = provider + .get_block_by_number((latest_block + 1 - block_count).into()) + .await? + .unwrap() + .header; + for block in (latest_block + 2 - block_count)..=latest_block { + let expected_base_fee = calc_next_block_base_fee( + prev_header.gas_used, + prev_header.gas_limit, + prev_header.base_fee_per_gas.unwrap(), + chain_spec.base_fee_params_at_block(block), + ); + + let header = provider.get_block_by_number(block.into()).await?.unwrap().header; + + assert_eq!(header.base_fee_per_gas.unwrap(), expected_base_fee); + assert_eq!( + header.base_fee_per_gas.unwrap(), + fee_history.base_fee_per_gas[(block + block_count - 1 - latest_block) as usize] + as u64 + ); + + prev_header = header; + } + } + + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_flashbots_validate_v3() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(MAINNET.chain) + .genesis(serde_json::from_str(include_str!("../assets/genesis.json")).unwrap()) + .cancun_activated() + .build(), + ); + + let (mut nodes, _tasks, wallet) = + setup_engine::<EthereumNode>(1, chain_spec.clone(), false, eth_payload_attributes).await?; + let mut node = nodes.pop().unwrap(); + let provider = ProviderBuilder::new() + .wallet(EthereumWallet::new(wallet.gen().swap_remove(0))) + .on_http(node.rpc_url()); + + node.advance(100, |_| { + let provider = provider.clone(); + Box::pin(async move { + let SendableTx::Envelope(tx) = + provider.fill(TransactionRequest::default().to(Address::ZERO)).await.unwrap() + else { + unreachable!() + }; + + tx.encoded_2718().into() + }) + }) + .await?; + + let _ = provider.send_transaction(TransactionRequest::default().to(Address::ZERO)).await?; + let payload = node.new_payload().await?; + + let mut request = BuilderBlockValidationRequestV3 { + request: SignedBidSubmissionV3 { + message: BidTrace { + parent_hash: payload.block().parent_hash, + block_hash: payload.block().hash(), + gas_used: payload.block().gas_used, + gas_limit: payload.block().gas_limit, + ..Default::default() + }, + execution_payload: ExecutionPayloadV3::from_block_unchecked( + payload.block().hash(), + &payload.block().clone().into_block(), + ), + blobs_bundle: BlobsBundleV1::new([]), + signature: Default::default(), + }, + parent_beacon_block_root: payload.block().parent_beacon_block_root.unwrap(), + registered_gas_limit: payload.block().gas_limit, + }; + + assert!(provider + .raw_request::<_, ()>("flashbots_validateBuilderSubmissionV3".into(), (&request,)) + .await + .is_ok()); + + request.registered_gas_limit -= 1; + assert!(provider + .raw_request::<_, ()>("flashbots_validateBuilderSubmissionV3".into(), (&request,)) + .await + .is_err()); + request.registered_gas_limit += 1; + + request.request.execution_payload.payload_inner.payload_inner.state_root = B256::ZERO; + assert!(provider + .raw_request::<_, ()>("flashbots_validateBuilderSubmissionV3".into(), (&request,)) + .await + .is_err()); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_flashbots_validate_v4() -> eyre::Result<()> { + reth_tracing::init_test_tracing(); + + let chain_spec = Arc::new( + ChainSpecBuilder::default() + .chain(MAINNET.chain) + .genesis(serde_json::from_str(include_str!("../assets/genesis.json")).unwrap()) + .prague_activated() + .build(), + ); + + let (mut nodes, _tasks, wallet) = + setup_engine::<EthereumNode>(1, chain_spec.clone(), false, eth_payload_attributes).await?; + let mut node = nodes.pop().unwrap(); + let provider = ProviderBuilder::new() + .wallet(EthereumWallet::new(wallet.gen().swap_remove(0))) + .on_http(node.rpc_url()); + + node.advance(100, |_| { + let provider = provider.clone(); + Box::pin(async move { + let SendableTx::Envelope(tx) = + provider.fill(TransactionRequest::default().to(Address::ZERO)).await.unwrap() + else { + unreachable!() + }; + + tx.encoded_2718().into() + }) + }) + .await?; + + let _ = provider.send_transaction(TransactionRequest::default().to(Address::ZERO)).await?; + let payload = node.new_payload().await?; + + let mut request = BuilderBlockValidationRequestV4 { + request: SignedBidSubmissionV4 { + message: BidTrace { + parent_hash: payload.block().parent_hash, + block_hash: payload.block().hash(), + gas_used: payload.block().gas_used, + gas_limit: payload.block().gas_limit, + ..Default::default() + }, + execution_payload: ExecutionPayloadV3::from_block_unchecked( + payload.block().hash(), + &payload.block().clone().into_block(), + ), + blobs_bundle: BlobsBundleV1::new([]), + execution_requests: payload.requests().unwrap().try_into().unwrap(), + signature: Default::default(), + }, + parent_beacon_block_root: payload.block().parent_beacon_block_root.unwrap(), + registered_gas_limit: payload.block().gas_limit, + }; + + provider + .raw_request::<_, ()>("flashbots_validateBuilderSubmissionV4".into(), (&request,)) + .await + .expect("request should validate"); + + request.registered_gas_limit -= 1; + assert!(provider + .raw_request::<_, ()>("flashbots_validateBuilderSubmissionV4".into(), (&request,)) + .await + .is_err()); + request.registered_gas_limit += 1; + + request.request.execution_payload.payload_inner.payload_inner.state_root = B256::ZERO; + assert!(provider + .raw_request::<_, ()>("flashbots_validateBuilderSubmissionV4".into(), (&request,)) + .await + .is_err()); + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/rpc_compat.rs seismic-reth/crates/seismic/node/tests/e2e/rpc_compat.rs new file mode 100644 index 0000000000000000000000000000000000000000..07a5e43ff1789a0f6d0ab1c18fdd60ed42b59a1c --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/rpc_compat.rs @@ -0,0 +1,86 @@ +//! Seismic RPC compatibility tests using test data from a Summit testnet. +//! +//! These tests import a chain produced by a Summit testnet (real consensus, chain ID 5124) +//! and verify RPC responses against captured `.io` test files. + +use alloy_chains::Chain; +use alloy_genesis::Genesis; +use alloy_primitives::U256; +use eyre::Result; +use reth_chainspec::{make_genesis_header, ChainSpec}; +use reth_e2e_test_utils::testsuite::{ + actions::{MakeCanonical, UpdateBlockInfo}, + setup::{NetworkSetup, Setup}, + TestBuilder, +}; +use reth_primitives_traits::SealedHeader; +use reth_rpc_e2e_tests::rpc_compat::{InitializeFromExecutionApis, RunRpcCompatTests}; +use reth_seismic_evm::SeismicEvmConfig; +use reth_seismic_node::{ + engine::SeismicEngineTypes, node::SeismicNode, purpose_keys::get_purpose_keys, +}; +use std::{path::PathBuf, sync::Arc}; +use tracing::info; + +#[tokio::test(flavor = "multi_thread")] +async fn test_seismic_rpc_compat() -> Result<()> { + reth_tracing::init_test_tracing(); + reth_seismic_node::utils::e2e::ensure_mock_purpose_keys(); + + let test_data_path = + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/e2e/testdata/rpc-compat"); + assert!(test_data_path.exists(), "Test data path missing: {}", test_data_path.display()); + info!("Using Seismic test data from: {}", test_data_path.display()); + + let chain_rlp_path = test_data_path.join("chain.rlp"); + let fcu_json_path = test_data_path.join("headfcu.json"); + let genesis_path = test_data_path.join("genesis.json"); + + assert!(chain_rlp_path.exists(), "chain.rlp not found"); + assert!(fcu_json_path.exists(), "headfcu.json not found"); + assert!(genesis_path.exists(), "genesis.json not found"); + + // Load genesis from testdata so this test is decoupled from SEISMIC_DEV. + let genesis_json = + std::fs::read_to_string(&genesis_path).expect("failed to read genesis.json from testdata"); + let mut genesis: Genesis = serde_json::from_str(&genesis_json).expect("invalid genesis JSON"); + + // Genesis JSON timestamps are in seconds, but when timestamp-in-seconds feature is disabled, + // we store timestamps internally as milliseconds. + #[cfg(not(feature = "timestamp-in-seconds"))] + { + genesis.timestamp *= 1000; + } + + let hardforks = reth_seismic_forks::SEISMIC_DEV_HARDFORKS.clone(); + let chain_spec: Arc<ChainSpec> = ChainSpec { + chain: Chain::from_id(genesis.config.chain_id), + genesis_header: SealedHeader::seal_slow(make_genesis_header(&genesis, &hardforks)), + genesis, + paris_block_and_final_difficulty: Some((0, U256::from(0))), + hardforks, + ..Default::default() + } + .into(); + + let setup = Setup::<SeismicEngineTypes>::default() + .with_chain_spec(chain_spec.clone()) + .with_network(NetworkSetup::single_node()); + + let test = TestBuilder::new() + .with_setup_and_import(setup, chain_rlp_path) + .with_action(UpdateBlockInfo::default()) + .with_action( + InitializeFromExecutionApis::new().with_fcu_json(fcu_json_path.to_string_lossy()), + ) + .with_action(MakeCanonical::new()) + .with_action(RunRpcCompatTests::new( + vec!["eth_getLogs".to_string(), "eth_syncing".to_string()], + test_data_path.to_string_lossy(), + )); + + let evm_config = SeismicEvmConfig::new(chain_spec, get_purpose_keys()); + test.run_with_evm::<SeismicNode>(evm_config).await?; + + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/chain.rlp seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/chain.rlp new file mode 100644 index 0000000000000000000000000000000000000000..09afc6cf44afc6ada5afd38f68aa0e8eb6409da9 Binary files /dev/null and seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/chain.rlp differ
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/contract-addr.io seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/contract-addr.io new file mode 100644 index 0000000000000000000000000000000000000000..3e8cd4450d8e41278c2adcc44406634bdb8a33bc --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/contract-addr.io @@ -0,0 +1,3 @@ +// queries for logs from a specific contract across a range of blocks +>> {"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"address":["0x5fbdb2315678afecb367f032d93f642f64180aa3"],"fromBlock":"0x15b","toBlock":"0x189","topics":null}]} +<< {"jsonrpc":"2.0","id":1,"result":[{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x0","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x1","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x2","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x3","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x4","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x5","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x6","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x7","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x8","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x9","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0x3aec5faba1c57465e0e66983f19b0f342f2afcd301ffc9fb021c4c3a07ce6984","blockNumber":"0x16f","blockTimestamp":"0x19d20f0a8b4","transactionHash":"0xfbb33943150d4407132c2ed152db37e284fcf6bbca1d487fcc57c65187e53186","transactionIndex":"0x0","logIndex":"0x0","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x54ce699289354829d667bc6b9d53bf7762254b99c8d6d72c3c4034a85859a4cb","0x0000000000000000000000000000000000000000000000000000000000000001","0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658"],"data":"0x","blockHash":"0x69686993ee74db804ccb5ee8f76d702bc52393056c40a0269840e8c24f0ab1cd","blockNumber":"0x17b","blockTimestamp":"0x19d20f0b9f3","transactionHash":"0x4ada27a2fd478ac1b1397689a90110b19a1c51a567fa04800dc13bf4410db5b3","transactionIndex":"0x0","logIndex":"0x0","removed":false}]}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/no-topics.io seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/no-topics.io new file mode 100644 index 0000000000000000000000000000000000000000..2ce81e4d20a76b525d11b49587913b2b04cd4b73 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/no-topics.io @@ -0,0 +1,3 @@ +// queries for all logs across a range of blocks +>> {"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"address":null,"fromBlock":"0x15b","toBlock":"0x17b","topics":null}]} +<< {"jsonrpc":"2.0","id":1,"result":[{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x0","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x1","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x2","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x3","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x4","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x5","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x6","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x7","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x8","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x9","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0x3aec5faba1c57465e0e66983f19b0f342f2afcd301ffc9fb021c4c3a07ce6984","blockNumber":"0x16f","blockTimestamp":"0x19d20f0a8b4","transactionHash":"0xfbb33943150d4407132c2ed152db37e284fcf6bbca1d487fcc57c65187e53186","transactionIndex":"0x0","logIndex":"0x0","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x54ce699289354829d667bc6b9d53bf7762254b99c8d6d72c3c4034a85859a4cb","0x0000000000000000000000000000000000000000000000000000000000000001","0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658"],"data":"0x","blockHash":"0x69686993ee74db804ccb5ee8f76d702bc52393056c40a0269840e8c24f0ab1cd","blockNumber":"0x17b","blockTimestamp":"0x19d20f0b9f3","transactionHash":"0x4ada27a2fd478ac1b1397689a90110b19a1c51a567fa04800dc13bf4410db5b3","transactionIndex":"0x0","logIndex":"0x0","removed":false}]}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/topic-exact-match.io seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/topic-exact-match.io new file mode 100644 index 0000000000000000000000000000000000000000..7b488ee20379665246b50acde62f355e66b4e88f --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/topic-exact-match.io @@ -0,0 +1,3 @@ +// queries for logs with a specific topic +>> {"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"address":null,"fromBlock":"0x15b","toBlock":"0x189","topics":[["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"]]}]} +<< {"jsonrpc":"2.0","id":1,"result":[{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x0","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x1","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x2","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x3","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x4","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x5","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x6","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x7","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x8","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0xd6cd93b02476170483f6ab723f1ba5a282a30979bfd9b930f9e7ec531584673e","blockNumber":"0x167","blockTimestamp":"0x19d20f09cf2","transactionHash":"0xbd57265e3b975299238f73cb658d5b62c6f86e4010f7ae5f0ddddd10d4cce28c","transactionIndex":"0x0","logIndex":"0x9","removed":false},{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x4bbf2a95b8a1b0106078ab03fae6e70488f9b23dfd9c007e7e9f6058cc55233c"],"data":"0x","blockHash":"0x3aec5faba1c57465e0e66983f19b0f342f2afcd301ffc9fb021c4c3a07ce6984","blockNumber":"0x16f","blockTimestamp":"0x19d20f0a8b4","transactionHash":"0xfbb33943150d4407132c2ed152db37e284fcf6bbca1d487fcc57c65187e53186","transactionIndex":"0x0","logIndex":"0x0","removed":false}]}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/topic-wildcard.io seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/topic-wildcard.io new file mode 100644 index 0000000000000000000000000000000000000000..6f88f20146dea730dd669a257bf674e78451eb52 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_getLogs/topic-wildcard.io @@ -0,0 +1,3 @@ +// queries for logs with two topics, performing a wildcard match in topic position zero +>> {"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"address":null,"fromBlock":"0x15b","toBlock":"0x189","topics":[[],["0x0000000000000000000000000000000000000000000000000000000000000001"]]}]} +<< {"jsonrpc":"2.0","id":1,"result":[{"address":"0x5fbdb2315678afecb367f032d93f642f64180aa3","topics":["0x54ce699289354829d667bc6b9d53bf7762254b99c8d6d72c3c4034a85859a4cb","0x0000000000000000000000000000000000000000000000000000000000000001","0x9c22ff5f21f0b81b113e63f7db6da94fedef11b2119b4088b89664fb9a3cb658"],"data":"0x","blockHash":"0x69686993ee74db804ccb5ee8f76d702bc52393056c40a0269840e8c24f0ab1cd","blockNumber":"0x17b","blockTimestamp":"0x19d20f0b9f3","transactionHash":"0x4ada27a2fd478ac1b1397689a90110b19a1c51a567fa04800dc13bf4410db5b3","transactionIndex":"0x0","logIndex":"0x0","removed":false}]}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_syncing/eth_syncing.io seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_syncing/eth_syncing.io new file mode 100644 index 0000000000000000000000000000000000000000..4e2cef489e62a6aaf303dbe809556528e98be125 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/eth_syncing/eth_syncing.io @@ -0,0 +1,3 @@ +// checks client syncing status +>> {"jsonrpc":"2.0","id":1,"method":"eth_syncing","params":[]} +<< {"jsonrpc":"2.0","id":1,"result":false}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/forkenv.json seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/forkenv.json new file mode 100644 index 0000000000000000000000000000000000000000..06c526b62c4b6f60cb55860ee4d679549148fea9 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/forkenv.json @@ -0,0 +1,4 @@ +{ + "HIVE_CHAIN_ID": "5124", + "HIVE_NETWORK_ID": "5124" +}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/genesis.json seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/genesis.json new file mode 100644 index 0000000000000000000000000000000000000000..cad3eac93656056a2a6373a1a8630fd18a7da443 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/genesis.json @@ -0,0 +1,93 @@ +{ + "config": { + "berlinBlock": 0, + "byzantiumBlock": 0, + "cancunTime": 0, + "chainId": 5124, + "constantinopleBlock": 0, + "daoForkSupport": true, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "ethash": {}, + "homesteadBlock": 0, + "istanbulBlock": 0, + "londonBlock": 0, + "osakaTime": 0, + "petersburgBlock": 0, + "pragueTime": 0, + "shanghaiTime": 0, + "terminalTotalDifficulty": 0 + }, + "alloc": { + "0x0000000000000000000000000000000000002001": { + "balance": "0x0", + "code": "0x60806040526004361015610015575b36610a3057005b61001f5f356100de565b80630e292a29146100d95780632cc06b1e146100d45780632f1d7903146100cf57806331b00e46146100ca5780635e677dd0146100c557806368eddae7146100c05780638730d33b146100bb5780638d80ff0a146100b6578063a85f5c37146100b1578063c9e6db8e146100ac578063ed24911d146100a75763fac750e00361000e576109fb565b6109c6565b61096c565b610917565b6108df565b610876565b610800565b610726565b6105cd565b6104e4565b61032c565b6101ff565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b63ffffffff1690565b610108816100f6565b0361010f57565b5f80fd5b90503590610120826100ff565b565b5f80fd5b5f80fd5b5f80fd5b909182601f830112156101685781359167ffffffffffffffff831161016357602001926001830284011161015e57565b61012a565b610126565b610122565b6060818303126101d357610183825f8301610113565b92602082013567ffffffffffffffff81116101ce57836101a491840161012e565b929093604082013567ffffffffffffffff81116101c9576101c5920161012e565b9091565b6100f2565b6100f2565b6100ee565b151590565b6101e6906101d8565b9052565b91906101fd905f602085019401906101dd565b565b346102335761022f61021e61021536600461016d565b93929092610e9f565b6102266100e4565b918291826101ea565b0390f35b6100ea565b6003111561024257565b5f80fd5b9050359061025382610238565b565b64ffffffffff1690565b61026881610255565b0361026f57565b5f80fd5b905035906102808261025f565b565b90565b61028e81610282565b0361029557565b5f80fd5b905035906102a682610285565b565b91608083830312610305576102bf825f8501610246565b9260208101359167ffffffffffffffff8311610300576102e4846102fd94840161012e565b9390946102f48160408601610273565b93606001610299565b90565b6100f2565b6100ee565b610313906100f6565b9052565b919061032a905f6020850194019061030a565b565b346103605761035c61034b6103423660046102a8565b939290926117ca565b6103536100e4565b91829182610317565b0390f35b6100ea565b9060208282031261037e5761037b915f01610113565b90565b6100ee565b61038c90610255565b9052565b634e487b7160e01b5f52602160045260245ffd5b600311156103ae57565b610390565b906103bd826103a4565b565b6103c8906103b3565b90565b6103d4906103bf565b9052565b6103e1906101d8565b9052565b5190565b60209181520190565b90825f9392825e0152565b601f801991011690565b61042661042f6020936104349361041d816103e5565b938480936103e9565b958691016103f2565b6103fd565b0190565b61044190610282565b9052565b906104c99060c08061049a60e084016104645f8801515f870190610383565b610476602088015160208701906103cb565b610488604088015160408701906103d8565b60608701518582036060870152610407565b946104ad60808201516080860190610438565b6104bf60a082015160a0860190610438565b0151910190610438565b90565b6104e19160208201915f818403910152610445565b90565b34610514576105106104ff6104fa366004610365565b611959565b6105076100e4565b918291826104cc565b0390f35b6100ea565b9060208282031261054a575f82013567ffffffffffffffff811161054557610541920161012e565b9091565b6100f2565b6100ee565b6bffffffffffffffffffffffff1690565b6105699061054f565b9052565b60209181520190565b61059561059e6020936105a39361058c816103e5565b9384809361056d565b958691016103f2565b6103fd565b0190565b916105ca926105bd60408201935f830190610560565b6020818403910152610576565b90565b346105ff576105e66105e0366004610519565b906119e0565b906105fb6105f26100e4565b928392836105a7565b0390f35b6100ea565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b90610626906103fd565b810190811067ffffffffffffffff82111761064057604052565b610608565b906106586106516100e4565b928361061c565b565b67ffffffffffffffff8111610678576106746020916103fd565b0190565b610608565b90825f939282370152565b9092919261069d6106988261065a565b610645565b938185526020850190828401116106b9576106b79261067d565b565b610604565b9080601f830112156106dc578160206106d993359101610688565b90565b610122565b919091604081840312610721576106fa835f8301610246565b92602082013567ffffffffffffffff811161071c5761071992016106be565b90565b6100f2565b6100ee565b346107575761075361074261073c3660046106e1565b90611b9f565b61074a6100e4565b91829182610317565b0390f35b6100ea565b6107658161054f565b0361076c57565b5f80fd5b9050359061077d8261075c565b565b91906080838203126107f657610797815f8501610770565b92602081013567ffffffffffffffff81116107f157826107b891830161012e565b929093604083013567ffffffffffffffff81116107ec576107de836107e992860161012e565b939094606001610113565b90565b6100f2565b6100f2565b6100ee565b5f0190565b61081a61080e36600461077f565b94939093929192611ddb565b6108226100e4565b8061082c816107fb565b0390f35b91909160408184031261087157610849835f8301610246565b92602082013567ffffffffffffffff811161086c57610868920161012e565b9091565b6100f2565b6100ee565b346108a55761088f610889366004610830565b916124e2565b6108976100e4565b806108a1816107fb565b0390f35b6100ea565b906020828203126108da575f82013567ffffffffffffffff81116108d5576108d292016106be565b90565b6100f2565b6100ee565b6108f26108ed3660046108aa565b6124ef565b6108fa6100e4565b80610904816107fb565b0390f35b5f91031261091257565b6100ee565b3461094557610927366004610908565b61092f612713565b6109376100e4565b80610941816107fb565b0390f35b6100ea565b61095390610282565b9052565b919061096a905f6020850194019061094a565b565b3461099c57610998610987610982366004610365565b61271d565b61098f6100e4565b91829182610957565b0390f35b6100ea565b90565b6109ad906109a1565b9052565b91906109c4905f602085019401906109a4565b565b346109f6576109d6366004610908565b6109f26109e1612762565b6109e96100e4565b918291826109b1565b0390f35b6100ea565b34610a2b57610a0b366004610908565b610a27610a1661278f565b610a1e6100e4565b91829182610957565b0390f35b6100ea565b5f80fd5b5f90565b90565b90565b610a52610a4d610a5792610a38565b610a3b565b6100f6565b90565b634e487b7160e01b5f52601160045260245ffd5b610a7a610a80916100f6565b916100f6565b90039063ffffffff8211610a9057565b610a5a565b634e487b7160e01b5f52603260045260245ffd5b5490565b5f5260205f2090565b610abf81610aa9565b821015610ad957610ad1600591610aad565b910201905f90565b610a95565b90565b5f1c90565b64ffffffffff1690565b610afc610b0191610ae1565b610ae6565b90565b610b0e9054610af0565b90565b610b25610b20610b2a92610255565b610a3b565b610282565b90565b60209181520190565b5f7f6b65792065787069726564000000000000000000000000000000000000000000910152565b610b6a600b602092610b2d565b610b7381610b36565b0190565b610b8c9060208101905f818303910152610b5d565b90565b15610b9657565b610b9e6100e4565b62461bcd60e51b815280610bb460048201610b77565b0390fd5b60281c90565b60ff1690565b610bd0610bd591610bb8565b610bbe565b90565b610be29054610bc4565b90565b634e487b7160e01b5f52602260045260245ffd5b9060016002830492168015610c19575b6020831014610c1457565b610be5565b91607f1691610c09565b5f5260205f2090565b905f9291805490610c46610c3f83610bf9565b80946103e9565b916001811690815f14610c9d5750600114610c61575b505050565b610c6e9192939450610c23565b915f925b818410610c8557505001905f8080610c5c565b60018160209295939554848601520191019290610c72565b92949550505060ff19168252151560200201905f8080610c5c565b90610cc291610c2c565b90565b90610ce5610cde92610cd56100e4565b93848092610cb8565b038361061c565b565b610cf090610cc5565b90565b5f7f6b6579207265766f6b6564000000000000000000000000000000000000000000910152565b610d27600b602092610b2d565b610d3081610cf3565b0190565b610d499060208101905f818303910152610d1a565b90565b15610d5357565b610d5b6100e4565b62461bcd60e51b815280610d7160048201610d34565b0390fd5b90565b610d84610d8991610ae1565b610d75565b90565b610d969054610d78565b90565b610da4913691610688565b90565b5f7f696e76616c696420736967000000000000000000000000000000000000000000910152565b610ddb600b602092610b2d565b610de481610da7565b0190565b610dfd9060208101905f818303910152610dce565b90565b15610e0757565b610e0f6100e4565b62461bcd60e51b815280610e2560048201610de8565b0390fd5b610e3290610282565b5f198114610e405760010190565b610a5a565b5f1b90565b90610e565f1991610e45565b9181191691161790565b610e74610e6f610e7992610282565b610a3b565b610282565b90565b90565b90610e94610e8f610e9b92610e60565b610e7c565b8254610e4a565b9055565b91600493610fb295610f73610f9593610f9a95610eba610a34565b50610f4e610eef610ee96002610ece61282b565b01610ee38c610edd6001610a3e565b90610a6e565b90610ab6565b50610ade565b98610f16610efe5f8c01610b04565b610f10610f0a42610282565b91610b11565b11610b8f565b610f48610f42610f3d8c610f376001610f305f8401610bd8565b9201610ce7565b90611b9f565b6100f6565b916100f6565b14610d4c565b610f6d610f59612762565b610f648b8b01610d8c565b92939093610d99565b90612902565b91610f7f5f8701610bd8565b610f8f6001880194929394610ce7565b90612a18565b610e00565b01610fac610fa782610d8c565b610e29565b90610e7f565b600190565b5f90565b60018060a01b031690565b610fda610fd5610fdf92610fbb565b610a3b565b610fbb565b90565b610feb90610fc6565b90565b610ff790610fe2565b90565b61100390610fbb565b90565b5f7f6f6e6c792073656c660000000000000000000000000000000000000000000000910152565b61103a6009602092610b2d565b61104381611006565b0190565b61105c9060208101905f81830391015261102d565b90565b1561106657565b61106e6100e4565b62461bcd60e51b81528061108460048201611047565b0390fd5b906110ba95949392916110b5336110af6110a96110a430610fee565b610ffa565b91610ffa565b1461105f565b611665565b90565b6110c760e0610645565b90565b906110d490610255565b9052565b906110e2906103b3565b9052565b906110f0906101d8565b9052565b52565b9061110190610282565b9052565b90565b61111c61111761112192611105565b610a3b565b610282565b90565b61113861113361113d92610282565b610a3b565b6100f6565b90565b90565b5f5260205f2090565b5490565b6111598161114c565b8210156111735761116b600591611143565b910201905f90565b610a95565b634e487b7160e01b5f525f60045260245ffd5b6111959051610255565b90565b906111a864ffffffffff91610e45565b9181191691161790565b6111c66111c16111cb92610255565b610a3b565b610255565b90565b90565b906111e66111e16111ed926111b2565b6111ce565b8254611198565b9055565b6111fb90516103b3565b90565b60281b90565b9061121565ff0000000000916111fe565b9181191691161790565b611228906103b3565b90565b90565b9061124361123e61124a9261121f565b61122b565b8254611204565b9055565b61125890516101d8565b90565b60301b90565b9061127366ff0000000000009161125b565b9181191691161790565b611286906101d8565b90565b90565b906112a161129c6112a89261127d565b611289565b8254611261565b9055565b5190565b601f602091010490565b1b90565b919060086112d99102916112d35f19846112ba565b926112ba565b9181191691161790565b91906112f96112f461130193610e60565b610e7c565b9083546112be565b9055565b5f90565b61131b91611315611305565b916112e3565b565b5b818110611329575050565b806113365f600193611309565b0161131e565b9190601f811161134c575b505050565b61135861137d93610c23565b906020611364846112b0565b83019310611385575b611376906112b0565b019061131d565b5f8080611347565b91506113768192905061136d565b1c90565b906113a7905f1990600802611393565b191690565b816113b691611397565b906002021790565b906113c8816103e5565b9067ffffffffffffffff8211611488576113ec826113e68554610bf9565b8561133c565b602090601f83116001146114205791809161140f935f92611414575b50506113ac565b90555b565b90915001515f80611408565b601f1983169161142f85610c23565b925f5b81811061147057509160029391856001969410611456575b50505002019055611412565b611466910151601f841690611397565b90555f808061144a565b91936020600181928787015181550195019201611432565b610608565b90611497916113be565b565b6114a39051610282565b90565b9061154c60c06004611552946114c95f82016114c35f880161118b565b906111d1565b6114e15f82016114db602088016111f1565b9061122e565b6114f95f82016114f36040880161124e565b9061128c565b6115126001820161150c606088016112ac565b9061148d565b61152b6002820161152560808801611499565b90610e7f565b6115446003820161153e60a08801611499565b90610e7f565b019201611499565b90610e7f565b565b919061156557611563916114a6565b565b611178565b908154916801000000000000000083101561159a578261159291600161159895018155611150565b90611554565b565b610608565b6115ab6115b1916100f6565b916100f6565b019063ffffffff82116115c057565b610a5a565b6115ce906109a1565b90565b906115db906115c5565b5f5260205260405f2090565b906115f663ffffffff91610e45565b9181191691161790565b61161461160f611619926100f6565b610a3b565b6100f6565b90565b90565b9061163461162f61163b92611600565b61161c565b82546115e7565b9055565b916116629261165560408201935f8301906109a4565b6020818403910152610445565b90565b9490949392935061167461282b565b92859083869193905f925f9460019061168b6110bd565b975f890190611699916110ca565b60208801906116a7916110d8565b60408701906116b5916110e6565b6116be91610d99565b60608501906116cc916110f4565b60808401906116da916110f7565b6116e390611108565b60a08301906116f1916110f7565b6116fa90611108565b60c0820190611708916110f7565b928260020161171690610aa9565b61171f90611124565b948360020161172d90611140565b856117379161156a565b919061174291610d99565b61174b91612b9c565b9083600161175890610a3e565b6117619161159f565b906003018261176f916115d1565b906117799161161f565b7f4ea58b0cfbd7dbef4ca1db95d39abfddd4b9a1614dbd63cfb36d3b132e4589d7916117a36100e4565b9182916117b0918361163f565b0390a160016117be90610a3e565b6117c79161159f565b90565b906117df949392916117da610fb7565b611088565b90565b6117ec60e0610645565b90565b5f90565b5f90565b5f90565b606090565b5f90565b61180c6117e2565b9060208080808080808861181e6117ef565b8152016118296117f3565b8152016118346117f7565b81520161183f6117fb565b81520161184a611800565b815201611855611800565b815201611860611800565b81525050565b61186e611804565b90565b60301c90565b60ff1690565b61188961188e91611871565b611877565b90565b61189b905461187d565b90565b9061194b61194260046118af6117e2565b946118c66118be5f8301610b04565b5f88016110ca565b6118dd6118d45f8301610bd8565b602088016110d8565b6118f46118eb5f8301611891565b604088016110e6565b61190c61190360018301610cc5565b606088016110f4565b61192461191b60028301610d8c565b608088016110f7565b61193c61193360038301610d8c565b60a088016110f7565b01610d8c565b60c084016110f7565b565b6119569061189e565b90565b61198e61199491611968611866565b50611988600261197661282b565b01916119826001610a3e565b90610a6e565b90610ab6565b5061194d565b90565b5f90565b606090565b6119b46119af6119b992611105565b610a3b565b61054f565b90565b90565b6119cb6119d091610ae1565b6119bc565b90565b6119dd90b06119bf565b90565b9190916119eb611997565b506119f461199b565b506119fd612d82565b5b80611a11611a0b5f6119a0565b9161054f565b03611a245750611a1f612d82565b6119fe565b92611a4c91611a46611a3e5f611a3861282b565b016119d3565b928692610d99565b9161301c565b90565b63ffffffff1690565b611a64611a6991610ae1565b611a4f565b90565b611a769054611a58565b90565b611a8d611a88611a9292611105565b610a3b565b6100f6565b90565b5f7f6b6579206e6f7420666f756e6400000000000000000000000000000000000000910152565b611ac9600d602092610b2d565b611ad281611a95565b0190565b611aeb9060208101905f818303910152611abc565b90565b15611af557565b611afd6100e4565b62461bcd60e51b815280611b1360048201611ad6565b0390fd5b60200190565b5f7f696e76616c6964206b6579206d617070696e6700000000000000000000000000910152565b611b516013602092610b2d565b611b5a81611b1d565b0190565b611b739060208101905f818303910152611b44565b90565b15611b7d57565b611b856100e4565b62461bcd60e51b815280611b9b60048201611b5e565b0390fd5b90611c4090611bac610fb7565b50611bb561282b565b90611bd5611bd0611bc7868490612b9c565b600385016115d1565b611a6c565b93611bf385611bec611be65f611a79565b916100f6565b1415611aee565b611c31611c2b611c255f611c1e60028801611c188b611c126001610a3e565b90610a6e565b90610ab6565b5001610bd8565b926103b3565b916103b3565b149182611c43575b5050611b76565b90565b611caa919250611c786001611c716002611ca49401611c6b89611c6585610a3e565b90610a6e565b90610ab6565b5001610ce7565b611c8a611c84826103e5565b91611b17565b2092611c9e611c98826103e5565b91611b17565b206109a1565b916109a1565b145f80611c39565b5f7f696e76616c6964207369676e6174757265000000000000000000000000000000910152565b611ce66011602092610b2d565b611cef81611cb2565b0190565b611d089060208101905f818303910152611cd9565b90565b15611d1257565b611d1a6100e4565b62461bcd60e51b815280611d3060048201611cf3565b0390fd5b611d43611d4991939293610282565b92610282565b8201809211611d5457565b610a5a565b5f7f7370656e64206c696d6974206578636565646564000000000000000000000000910152565b611d8d6014602092610b2d565b611d9681611d59565b0190565b611daf9060208101905f818303910152611d80565b90565b15611db957565b611dc16100e4565b62461bcd60e51b815280611dd760048201611d9a565b0390fd5b91949092611de761282b565b94611df061199b565b5033611e0c611e06611e0130610fee565b610ffa565b91610ffa565b145f14611e68575050509081611e479492611e2f611e295f6119a0565b9161054f565b145f14611e4a5750611e419250610d99565b5b6124ef565b5b565b9190611e5a5f611e6395016119d3565b9290919261324a565b611e42565b859295600201866001611e7a90610a3e565b611e8391610a6e565b611e8c91610ab6565b50611e9690610ade565b95865f01611ea390610b04565b42611ead90610282565b90611eb790610b11565b11611ec190610b8f565b83600301875f01611ed190610bd8565b88600101611ede90610ce7565b611ee791612b9c565b611ef0916115d1565b611ef990611a6c565b611f02906100f6565b90611f0c906100f6565b14611f1690610d4c565b85600401611f2390610d8c565b8588907f000000000000000000000000000000000000000000000000000000000000000091611f5191610d99565b611f5a92612902565b90865f01611f6790610bd8565b928760010192909192611f7990610ce7565b611f8294612a18565b611f8b90611d0b565b815f611f96906119a0565b90611fa09061054f565b145f14946120069360049361200b9761207a5750611fbe9250610d99565b925b611fc95f611108565b50611fd660028201610d8c565b611fe8611fe25f611108565b91610282565b03612010575b01612000611ffb82610d8c565b610e29565b90610e7f565b6124ef565b611e48565b61207561201c85613504565b61205961203561202e60038601610d8c565b8390611d34565b61205261204c61204760028801610d8c565b610282565b91610282565b1115611db2565b61206f600384019161206a83610d8c565b611d34565b90610e7f565b611fee565b919061208a5f61209395016119d3565b9290919261324a565b92611fc0565b906120c892916120c3336120bd6120b76120b230610fee565b610ffa565b91610ffa565b1461105f565b61236e565b565b634e487b7160e01b5f52603160045260245ffd5b906120f1905f1990602003600802611393565b8154169055565b905f9161210f61210782610c23565b9283546113ac565b905555565b919290602082105f1461216d57601f841160011461213d576121379293506113ac565b90555b5b565b509061216361216893600161215a61215485610c23565b926112b0565b8201910161131d565b6120f8565b61213a565b506121a4829361217e600194610c23565b61219d61218a856112b0565b820192601f8616806121af575b506112b0565b019061131d565b60020217905561213b565b6121bb908886036120de565b5f612197565b929091680100000000000000008211612221576020115f1461221257602081105f146121f6576121f0916113ac565b90555b5b565b60019160ff191661220684610c23565b556002020190556121f3565b600191506002020190556121f4565b610608565b90815461223281610bf9565b9081831161225b575b818310612249575b50505050565b61225293612114565b5f808080612243565b612267838383876121c1565b61223b565b5f61227691612226565b565b905f0361228a576122889061226c565b565b611178565b5f60046122c89282808201556122a88360018301612278565b6122b58360028301611309565b6122c28360038301611309565b01611309565b565b905f036122dc576122da9061228f565b565b611178565b6122ea8161114c565b801561230b5760019003906123086123028383611150565b906122ca565b55565b6120ca565b9190600861232e91029161232863ffffffff846112ba565b926112ba565b9181191691161790565b919061234e61234961235693611600565b61161c565b908354612310565b9055565b61236c91612366610fb7565b91612338565b565b9161241460036123956124199461238f5f9561238861282b565b9892610d99565b90612b9c565b946123ab6123a683830188906115d1565b611a6c565b6123c8816123c16123bb88611a79565b916100f6565b1415611aee565b6123dc6123d760028401610aa9565b611124565b90806123f06123ea846100f6565b916100f6565b03612454575b505061240c61240760028301611140565b6122e1565b0184906115d1565b61235a565b61244f7fd76dbee353f8817df12bf008d3fec1c2f26c9afc1e832f74757756b060b25f82916124466100e4565b918291826109b1565b0390a1565b6124d661248561247f6124db9461247960028801916124736001610a3e565b90610a6e565b90610ab6565b5061194d565b916124b1836124ab600288016124a58561249f6001610a3e565b90610a6e565b90610ab6565b90611554565b916124d08686019160606124c7602083016111f1565b91015190612b9c565b906115d1565b61161f565b5f806123f6565b906124ed9291612099565b565b80519060205b82811061250157505050565b8082015160f81c6001820183015160601c308115021760158301840151916035840185015192836055860187015f9392835f146125615750505090915060011461255d575b5f1461255557605501016124f5565b3d5f803e3d5ffd5b5f80fd5b5f958695508594505af19050612546565b6125963361259061258a61258530610fee565b610ffa565b91610ffa565b1461105f565b61259e612643565b565b6125ac6125b191610ae1565b611877565b90565b6125be90546125a0565b90565b5f7f414553206b657920616c726561647920696e697469616c697a65640000000000910152565b6125f5601b602092610b2d565b6125fe816125c1565b0190565b6126179060208101905f8183039101526125e8565b90565b1561262157565b6126296100e4565b62461bcd60e51b81528061263f60048201612602565b0390fd5b61266761266261265c600161265661282b565b016125b4565b156101d8565b61261a565b61266f6126e9565b565b90565b61268861268361268d92612671565b610a3b565b612671565b90565b90565b906126a86126a36126af92612674565b612690565b82b0610e4a565b90b1565b906126bf60ff91610e45565b9181191691161790565b906126de6126d96126e59261127d565b611289565b82546126b3565b9055565b6127116126f461282b565b6127076126ff613784565b5f8301612693565b60018091016126c9565b565b61271b612572565b565b600461275461275b9261272e611305565b5061274e600261273c61282b565b01916127486001610a3e565b90610a6e565b90610ab6565b5001610d8c565b90565b5f90565b61276a61275e565b507f000000000000000000000000000000000000000000000000000000000000000090565b612797611305565b506127ab60026127a561282b565b01610aa9565b90565b68ffffffffffffffffff60b81b1690565b6127c8906127ae565b90565b60b81c90565b68ffffffffffffffffff1690565b6127f36127ee6127f8926127d1565b610a3b565b6127d1565b90565b61280761280c916127cb565b6127df565b90565b61282361281e612828926127d1565b610a3b565b610282565b90565b61286461285f61285a7f2a2cc7db52019c9ff565d289628faa407289ea9f1a3741cac1acd5fa3e843b636127bf565b6127fb565b61280f565b90565b604090612890612897949695939661288660608401985f8501906109a4565b602083019061094a565b01906109a4565b565b905090565b5f61190160f01b910152565b6128b660028092612899565b6128bf8161289e565b0190565b90565b6128d26128d7916109a1565b6128c3565b9052565b60208093926128f66128ef6128fe946128aa565b80926128c6565b0180926128c6565b0190565b9061296f6129a99261291261275e565b506129607f9bb939585d47b76d88b01231eb395b17e90aab08b4c65e93bb1425c9708dbab7919361294b612945826103e5565b91611b17565b206129546100e4565b94859360208501612867565b6020820181038252038261061c565b61298161297b826103e5565b91611b17565b209161299a61298e6100e4565b938492602084016128db565b6020820181038252038261061c565b6129bb6129b5826103e5565b91611b17565b2090565b6129c890610fbb565b90565b6129d4816129bf565b036129db57565b5f80fd5b905051906129ec826129cb565b565b90602082820312612a0757612a04915f016129df565b90565b6100ee565b612a1590610fe2565b90565b949391929094612a26610a34565b9080612a3a612a345f6103b3565b916103b3565b145f14612a7157505093612a56612a5f9392612a6d9596613c1b565b9390939161395d565b919091929390919293613c40565b905b565b80969296612a88612a8260016103b3565b916103b3565b145f14612aef575050612ae89394612ae0612adb612ac59594612aad612ad49561395d565b95909596612ab96100e4565b988991602083016109b1565b6020820181038252038861061c565b5f93610d99565b6139fc565b919293613abc565b905b612a6f565b95919095612b06612b0060026103b3565b916103b3565b14612b15575b50505050612aea565b612b46949550612b38612b41916020612b2d826103e5565b8183010191016129ee565b93919293612a0c565b61386d565b905f808080612b0c565b60ff1690565b60f81b90565b612b6590612b56565b90565b612b74612b7991612b50565b612b5c565b9052565b600181612b90612b989360209695612b68565b0180926128c6565b0190565b612bb1612bec91612bab61275e565b506103bf565b91612bc4612bbe826103e5565b91611b17565b2091612bdd612bd16100e4565b93849260208401612b7d565b6020820181038252038261061c565b612bfe612bf8826103e5565b91611b17565b2090565b90565b612c19612c14612c1e92612c02565b610a3b565b610fbb565b90565b612c2a90612c05565b90565b612c376064612c21565b90565b90565b612c51612c4c612c5692612c3a565b610a3b565b6100f6565b90565b60e01b90565b612c6890612c59565b90565b612c77612c7c916100f6565b612c5f565b9052565b612c8c81600493612c6b565b0190565b90612ca2612c9d8361065a565b610645565b918252565b3d5f14612cc257612cb73d612c90565b903d5f602084013e5b565b612cca61199b565b90612cc0565b5f7f524e4720507265636f6d70696c652063616c6c206661696c6564000000000000910152565b612d04601a602092610b2d565b612d0d81612cd0565b0190565b612d269060208101905f818303910152612cf7565b90565b15612d3057565b612d386100e4565b62461bcd60e51b815280612d4e60048201612d11565b0390fd5b612d5e612d6391610ae1565b610e60565b90565b612d7a612d75612d7f92610282565b610a3b565b61054f565b90565b612d8a611997565b50612dfb612df660205f80612d9d612c2d565b612dbf612dcd612dac86612c3d565b612db46100e4565b928391888301612c80565b87820181038252038261061c565b8481019051915afa612de6612de0612ca7565b91612d29565b612dee61275e565b500151612d52565b612d66565b90565b90565b612e0d612e1291612671565b612dfe565b9052565b60a01b90565b612e2590612e16565b90565b612e34612e399161054f565b612e1c565b9052565b905090565b612e67612e5e92602092612e55816103e5565b94858093612e3d565b938491016103f2565b0190565b91612e8a602084612e82612e919796600c96612e01565b018092612e28565b0190612e42565b90565b90565b612eab612ea6612eb092612e94565b610a3b565b610fbb565b90565b612ebc90612e97565b90565b612ec96066612eb3565b90565b60207f6564000000000000000000000000000000000000000000000000000000000000917f41455320656e637279707420707265636f6d70696c652063616c6c206661696c5f8201520152565b612f266022604092610b2d565b612f2f81612ecc565b0190565b612f489060208101905f818303910152612f19565b90565b15612f5257565b612f5a6100e4565b62461bcd60e51b815280612f7060048201612f33565b0390fd5b60207f7574000000000000000000000000000000000000000000000000000000000000917f456e6372797074696f6e2063616c6c2072657475726e6564206e6f206f7574705f8201520152565b612fce6022604092610b2d565b612fd781612f74565b0190565b612ff09060208101905f818303910152612fc1565b90565b15612ffa57565b6130026100e4565b62461bcd60e51b81528061301860048201612fdb565b0390fd5b916130565f9392613047859461303061199b565b50919361303b6100e4565b94859360208501612e6b565b6020820181038252038261061c565b61305e612ebf565b90602081019051915afa613079613073612ca7565b91612f4b565b61309d613085826103e5565b6130976130915f611108565b91610282565b11612ff3565b90565b5090565b5f7f436970686572746578742063616e6e6f7420626520656d707479000000000000910152565b6130d8601a602092610b2d565b6130e1816130a4565b0190565b6130fa9060208101905f8183039101526130cb565b90565b1561310457565b61310c6100e4565b62461bcd60e51b815280613122600482016130e5565b0390fd5b9091826131368161313d93612e3d565b809361067d565b0190565b916131606020846131586131679896600c96612e01565b018092612e28565b0191613126565b90565b90565b61318161317c6131869261316a565b610a3b565b610fbb565b90565b6131929061316d565b90565b61319f6067613189565b90565b60207f6564000000000000000000000000000000000000000000000000000000000000917f414553206465637279707420707265636f6d70696c652063616c6c206661696c5f8201520152565b6131fc6022604092610b2d565b613205816131a2565b0190565b61321e9060208101905f8183039101526131ef565b90565b1561322857565b6132306100e4565b62461bcd60e51b81528061324660048201613209565b0390fd5b5f939161329c8594936132ab9361325f61199b565b5061328661326e8784906130a0565b61328061327a8a611108565b91610282565b116130fd565b92946132906100e4565b95869460208601613141565b6020820181038252038261061c565b6132b3613195565b90602081019051915afa6132ce6132c8612ca7565b91613221565b90565b90565b6132e86132e36132ed926132d1565b610a3b565b610282565b90565b906132fa826103e5565b81101561330c57600160209102010190565b610a95565b60ff60f81b1690565b6133249051613311565b90565b60f81c90565b61334161333c61334692612b50565b610a3b565b612b50565b90565b61335561335a91613327565b61332d565b90565b61337161336c61337692611105565b610a3b565b612b50565b90565b90565b61339061338b61339592613379565b610a3b565b610282565b90565b6133ac6133a76133b192612c3a565b610a3b565b610282565b90565b60207f6c656e6774680000000000000000000000000000000000000000000000000000917f496e76616c6964204d756c746953656e6420646174613a2065786365656473205f8201520152565b61340e6026604092610b2d565b613417816133b4565b0190565b6134309060208101905f818303910152613401565b90565b1561343a57565b6134426100e4565b62461bcd60e51b8152806134586004820161341b565b0390fd5b60207f656420747261696c696e67206279746573000000000000000000000000000000917f496e76616c6964204d756c746953656e6420646174613a20756e6578706563745f8201520152565b6134b66031604092610b2d565b6134bf8161345c565b0190565b6134d89060208101905f8183039101526134a9565b90565b156134e257565b6134ea6100e4565b62461bcd60e51b815280613500600482016134c3565b0390fd5b9061350d611305565b906135175f611108565b91613521846103e5565b925b6135378161353160556132d4565b90611d34565b61354961354386610282565b91610282565b1161361c5761356961356461355f8784906132f0565b61331a565b613349565b61357b6135755f61335d565b91612b50565b146135ef575b6135986135ea91613592603561337c565b90611d34565b6135a0611305565b506135bc81602088010151916135b66020613398565b90611d34565b906135e46135cb838390611d34565b6135dd6135d789610282565b91610282565b1115613433565b90611d34565b613523565b906135986136136135ea92613602611305565b506015850160208901015190611d34565b92915050613581565b61363e9294506136326136389194929492610282565b91610282565b146134db565b90565b5f90565b5f7f6165732d6b657900000000000000000000000000000000000000000000000000910152565b61367860078092612899565b61368181613645565b0190565b90565b61369461369991610282565b613685565b9052565b906136b36136ac60209361366c565b8092613688565b0190565b806136c86004926136cf9594612c6b565b0190612e42565b90565b5f7f496e76616c696420524e47206f7574707574206c656e67746800000000000000910152565b6137066019602092610b2d565b61370f816136d2565b0190565b6137289060208101905f8183039101526136f9565b90565b1561373257565b61373a6100e4565b62461bcd60e51b81528061375060048201613713565b0390fd5b61376861376361376d92610282565b610a3b565b612671565b90565b61377c61378191610ae1565b613754565b90565b61378c613641565b5061384260205f806137ae6137bc426137a36100e4565b92839187830161369d565b86820181038252038261061c565b6137ec6137c885612c3d565b6137de6137d36100e4565b9384928884016136b7565b86820181038252038261061c565b6137f4612c2d565b908481019051915afa61380e613808612ca7565b91612d29565b61383261381a826103e5565b61382c61382685613398565b91610282565b1461372b565b61383a61275e565b500151613770565b90565b61385961385461385e92611105565b610a3b565b610fbb565b90565b61386a90613845565b90565b939291613878610a34565b948061389461388e6138895f613861565b610ffa565b91610ffa565b1461395757604051813b156138df5760209394959650631626ba7e60e01b94858252600482015260648660248301978895604087528160448601528385013701915afa91511416905b565b93929190928060401461392f576041146138fc57505050506138dd565b60408092939496508101355f1a60205281375b5f526020600160805f825afa511860601b3d11915f6060526040526138dd565b509091929450602081013590601b8260ff1c016020523560405260011b60011c60605261390f565b50505050565b9061396661275e565b5061396f61275e565b50603f8251116040816020850151029301510290565b61398f60c0610645565b90565b606090565b5f90565b6139a3613985565b9060208080808080876139b46117fb565b8152016139bf613992565b8152016139ca611800565b8152016139d5611800565b8152016139e0613997565b8152016139eb613997565b81525050565b6139f961399b565b90565b90613a056139f1565b9180519060c0821015613a17575b5050565b60200190810190808051019081108260c083011117613aaa5780805101918160208101510190828210818311178385108286111717613aa35780825160208401011190845160208601011117613a9d5760a09285526020850152604081015160408501526060810151606085015260808101516080850152015160a08301525f80613a13565b50613a13565b5050613a13565b613a13565b613ab990516109a1565b90565b949391929094613aca610a34565b50613ae0613ad661275e565b9160018091613cf0565b95602085015190602082519201976040870151606088015190825191600d83017f226368616c6c656e6765223a220000000000000000000000000000000000000060981c85528c878483011060228386840101515f1a1416918481601389012092012014169186826014011090821760801c10907f2274797065223a22776562617574686e2e67657422000000000000000000000060581c908d015160581c141616915286515191151560021b600117806021895101511614906020831116169788613be7575b50505085613bb6575b50505050565b613bdd94955092613bd560a0613bce60808401613aaf565b9201613aaf565b919293613c40565b905f808080613bb0565b6020919293506001908288510183858201809782825198019460025afa831b5afa5191523d15613c19575f8080613ba7565bfe5b9190603f90613c2861275e565b50613c3161275e565b50116020818435029301350290565b9290939193613c4d610a34565b506040519384526020840152836040840152606083015260808201525f805260205f60a0836101005afa503d15613cac575b507f7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a85f5160011491111090565b6d1ab2e8006fd8b71907bf06a5bdee3b15613cc7575b613c7f565b5f60a06020926dd01ea45f9efd5c54f037fa57ea1a5afa15613ce9575f613cc2565bfe5b606090565b929192613cfb613ceb565b93815180613d0a575b50505050565b90919294506003600282010460021b91610670604051967f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f5215027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f18603f5260208601938385019280826020010195600460038851945f8a525b0191603f8351818160121c16515f538181600c1c1651600153818160061c165160025316516003535f518152019085821015613dd05790603f6003600493909150929192613d87565b50955f9460039360209252016040520660020490613d3d60f01b82860352151502809303520382525f808080613d0456fea264697066735822122003025b9d185e84afdbe943189eb9229c0384b99f2a333fba3c99e7c0e6a9851a64736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x0000000000000000000000000000506172616d73": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b6104ac565b61001d5f3561008c565b80630ae9a1cb146100875780633705765414610082578063715018a61461007d5780638da5cb5b14610078578063b6c15add14610073578063ea01545d1461006e5763f2fde38b0361000e57610479565b610404565b61033e565b6102aa565b6101fb565b6101b2565b610112565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b60ff1690565b6100b3816100a4565b036100ba57565b5f80fd5b905035906100cb826100aa565b565b906020828203126100e6576100e3915f016100be565b90565b61009c565b151590565b6100f9906100eb565b9052565b9190610110905f602085019401906100f0565b565b346101425761013e61012d6101283660046100cd565b610550565b610135610092565b918291826100fd565b0390f35b610098565b5190565b60209181520190565b90825f9392825e0152565b601f801991011690565b6101886101916020936101969361017f81610147565b9384809361014b565b95869101610154565b61015f565b0190565b6101af9160208201915f818403910152610169565b90565b346101e2576101de6101cd6101c83660046100cd565b61069d565b6101d5610092565b9182918261019a565b0390f35b610098565b5f9103126101f157565b61009c565b5f0190565b346102295761020b3660046101e7565b610213610836565b61021b610092565b80610225816101f6565b0390f35b610098565b1c90565b60018060a01b031690565b61024d906008610252930261022e565b610232565b90565b90610260915461023d565b90565b61026e5f5f90610255565b90565b60018060a01b031690565b61028590610271565b90565b6102919061027c565b9052565b91906102a8905f60208501940190610288565b565b346102da576102ba3660046101e7565b6102d66102c5610263565b6102cd610092565b91829182610295565b0390f35b610098565b90565b90565b90565b6102fc6102f7610301926102df565b6102e5565b6102e2565b90565b61030e60646102e8565b90565b610319610304565b90565b610325906102e2565b9052565b919061033c905f6020850194019061031c565b565b3461036e5761034e3660046101e7565b61036a610359610311565b610361610092565b91829182610329565b0390f35b610098565b5f80fd5b5f80fd5b5f80fd5b909182601f830112156103b95781359167ffffffffffffffff83116103b45760200192600183028401116103af57565b61037b565b610377565b610373565b9190916040818403126103ff576103d7835f83016100be565b92602082013567ffffffffffffffff81116103fa576103f6920161037f565b9091565b6100a0565b61009c565b346104335761041d6104173660046103be565b91610bca565b610425610092565b8061042f816101f6565b0390f35b610098565b6104418161027c565b0361044857565b5f80fd5b9050359061045982610438565b565b9060208282031261047457610471915f0161044c565b90565b61009c565b346104a75761049161048c36600461045b565b610cb9565b610499610092565b806104a3816101f6565b0390f35b610098565b5f80fd5b5f90565b6104c86104c36104cd926100a4565b6102e5565b6100a4565b90565b906104da906104b4565b5f5260205260405f2090565b634e487b7160e01b5f52602260045260245ffd5b906001600283049216801561051a575b602083101461051557565b6104e6565b91607f169161050a565b61052e90546104fa565b90565b90565b61054861054361054d92610531565b6102e5565b6102e2565b90565b61056761056c9161055f6104b0565b5060016104d0565b610524565b61057e6105785f610534565b916102e2565b1190565b606090565b60209181520190565b5f5260205f2090565b905f92918054906105b36105ac836104fa565b8094610587565b916001811690815f1461060a57506001146105ce575b505050565b6105db9192939450610590565b915f925b8184106105f257505001905f80806105c9565b600181602092959395548486015201910192906105df565b92949550505060ff19168252151560200201905f80806105c9565b9061062f91610599565b90565b634e487b7160e01b5f52604160045260245ffd5b906106509061015f565b810190811067ffffffffffffffff82111761066a57604052565b610632565b9061068f6106889261067f610092565b93848092610625565b0383610646565b565b61069a9061066f565b90565b6106b46106b9916106ac610582565b5060016104d0565b610691565b90565b5f1c90565b6106cd6106d2916106bc565b610232565b90565b6106df90546106c1565b90565b336106fd6106f76106f25f6106d5565b61027c565b9161027c565b0361070c5761070a6107c7565b565b5f635fc483c560e01b815280610724600482016101f6565b0390fd5b61073c61073761074192610531565b6102e5565b610271565b90565b61074d90610728565b90565b5f1b90565b9061076660018060a01b0391610750565b9181191691161790565b61078461077f61078992610271565b6102e5565b610271565b90565b61079590610770565b90565b6107a19061078c565b90565b90565b906107bc6107b76107c392610798565b6107a4565b8254610755565b9055565b6107d05f6106d5565b6107e26107dc5f610744565b5f6107a7565b6107eb5f610744565b61081e6108187f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610798565b91610798565b91610827610092565b80610831816101f6565b0390a3565b61083e6106e2565b565b91903361085d6108576108525f6106d5565b61027c565b9161027c565b0361086d5761086b92610b18565b565b5f635fc483c560e01b815280610885600482016101f6565b0390fd5b5090565b9160206108ae9294936108a760408201965f83019061031c565b019061031c565b565b601f602091010490565b1b90565b919060086108d99102916108d35f19846108ba565b926108ba565b9181191691161790565b6108f76108f26108fc926102e2565b6102e5565b6102e2565b90565b90565b9190610918610913610920936108e3565b6108ff565b9083546108be565b9055565b5f90565b61093a91610934610924565b91610902565b565b5b818110610948575050565b806109555f600193610928565b0161093d565b9190601f811161096b575b505050565b61097761099c93610590565b906020610983846108b0565b830193106109a4575b610995906108b0565b019061093c565b5f8080610966565b91506109958192905061098c565b906109c2905f199060080261022e565b191690565b816109d1916109b2565b906002021790565b916109e49082610889565b9067ffffffffffffffff8211610aa357610a0882610a0285546104fa565b8561095b565b5f90601f8311600114610a3b57918091610a2a935f92610a2f575b50506109c7565b90555b565b90915001355f80610a23565b601f19831691610a4a85610590565b925f5b818110610a8b57509160029391856001969410610a71575b50505002019055610a2d565b610a81910135601f8416906109b2565b90555f8080610a65565b91936020600181928787013581550195019201610a4d565b610632565b90610ab392916109d9565b565b610abe906100a4565b9052565b90825f939282370152565b9190610ae781610ae081610aec9561014b565b8095610ac2565b61015f565b0190565b91610b15939192610b0860408201945f830190610ab5565b6020818503910152610acd565b90565b919091610b26838390610889565b610b3f610b39610b34610304565b6102e2565b916102e2565b11610b9957610b5b838390610b56600185906104d0565b610aa8565b919091610b947f660f700ec25321f4838828ca2284f96109a35e7b652e4511e8235bb7c2b9cc5193610b8b610092565b93849384610af0565b0390a1565b50610ba391610889565b610bab610304565b90610bc65f92839263a7075ceb60e01b84526004840161088d565b0390fd5b90610bd59291610840565b565b33610bf2610bec610be75f6106d5565b61027c565b9161027c565b03610c0257610c0090610c1e565b565b5f635fc483c560e01b815280610c1a600482016101f6565b0390fd5b80610c39610c33610c2e5f610744565b61027c565b9161027c565b14610c9d57610c475f6106d5565b610c51825f6107a7565b90610c85610c7f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610798565b91610798565b91610c8e610092565b80610c98816101f6565b0390a3565b5f63d92e233d60e01b815280610cb5600482016101f6565b0390fd5b610cc290610bd7565b56fea2646970667358221220441b2fc6b5144033f76820b0c8fa2708edeb583159e9e9b5ee6a07135997017f64736f6c637828302e382e33312d646576656c6f702e323032362e312e32332b636f6d6d69742e36373662646563630059", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0xd412c5ecd343e264381ff15afc0ad78a67b79f35" + } + }, + "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff4b064b81555f359062001fff015500", + "balance": "0x0" + }, + "0x00000000219ab540356cbb839cbe05303d7705fa": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b6103b4565b61001d5f3561005c565b806301ffc9a714610057578063621fd1301461005257806379f6caf51461004d5763c5f2892f0361000e5761037f565b610327565b610197565b6100e8565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b63ffffffff60e01b1690565b61008981610074565b0361009057565b5f80fd5b905035906100a182610080565b565b906020828203126100bc576100b9915f01610094565b90565b61006c565b151590565b6100cf906100c1565b9052565b91906100e6905f602085019401906100c6565b565b34610118576101146101036100fe3660046100a3565b6103bc565b61010b610062565b918291826100d3565b0390f35b610068565b5f91031261012757565b61006c565b5190565b60209181520190565b90825f9392825e0152565b601f801991011690565b61016d61017660209361017b936101648161012c565b93848093610130565b95869101610139565b610144565b0190565b6101949160208201915f81840391015261014e565b90565b346101c7576101a736600461011d565b6101c36101b261046b565b6101ba610062565b9182918261017f565b0390f35b610068565b5f80fd5b5f80fd5b5f80fd5b909182601f830112156102125781359167ffffffffffffffff831161020d57602001926001830284011161020857565b6101d4565b6101d0565b6101cc565b90565b61022381610217565b0361022a57565b5f80fd5b9050359061023b8261021a565b565b9160c08383031261031d575f83013567ffffffffffffffff811161031857826102679185016101d8565b929093602081013567ffffffffffffffff8111610313578261028a9183016101d8565b929093604083013567ffffffffffffffff811161030e57826102ad9185016101d8565b929093606081013567ffffffffffffffff811161030957826102d09183016101d8565b929093608083013567ffffffffffffffff8111610304576102f6836103019286016101d8565b93909460a00161022e565b90565b610070565b610070565b610070565b610070565b610070565b61006c565b5f0190565b61034761033536600461023d565b99989098979197969296959395611440565b61034f610062565b8061035981610322565b0390f35b61036690610217565b9052565b919061037d905f6020850194019061035d565b565b346103af5761038f36600461011d565b6103ab61039a611c35565b6103a2610062565b9182918261036a565b0390f35b610068565b5f80fd5b5f90565b6103c46103b8565b50806103df6103d96301ffc9a760e01b610074565b91610074565b149081156103ec575b5090565b9050610407610401636f0dc97560e11b610074565b91610074565b145f6103e8565b606090565b5f1c90565b90565b61042761042c91610413565b610418565b90565b610439905461041b565b90565b90565b67ffffffffffffffff1690565b90565b61046361045e6104689261043c565b61044c565b61043f565b90565b61047361040e565b5061048e610489610484602061042f565b61044f565b611fb9565b90565b5090565b90565b6104ac6104a76104b192610495565b61044c565b61043c565b90565b60209181520190565b60207f626b6579206c656e677468000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c6964206e6f64655f70755f8201520152565b610517602b6040926104b4565b610520816104bd565b0190565b6105399060208101905f81830391015261050a565b90565b1561054357565b61054b610062565b62461bcd60e51b81528061056160048201610524565b0390fd5b90565b61057c61057761058192610565565b61044c565b61043c565b90565b60207f75735f7075626b6579206c656e67746800000000000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420636f6e73656e735f8201520152565b6105de60306040926104b4565b6105e781610584565b0190565b6106009060208101905f8183039101526105d1565b90565b1561060a57565b610612610062565b62461bcd60e51b815280610628600482016105eb565b0390fd5b60207f77616c5f63726564656e7469616c73206c656e67746800000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420776974686472615f8201520152565b61068660366040926104b4565b61068f8161062c565b0190565b6106a89060208101905f818303910152610679565b90565b156106b257565b6106ba610062565b62461bcd60e51b8152806106d060048201610693565b0390fd5b90565b6106eb6106e66106f0926106d4565b61044c565b61043c565b90565b60207f676e6174757265206c656e677468000000000000000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c6964206e6f64655f73695f8201520152565b61074d602e6040926104b4565b610756816106f3565b0190565b61076f9060208101905f818303910152610740565b90565b1561077957565b610781610062565b62461bcd60e51b8152806107976004820161075a565b0390fd5b90565b6107b26107ad6107b79261079b565b61044c565b61043c565b90565b60207f75735f7369676e6174757265206c656e67746800000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420636f6e73656e735f8201520152565b61081460336040926104b4565b61081d816107ba565b0190565b6108369060208101905f818303910152610807565b90565b1561084057565b610848610062565b62461bcd60e51b81528061085e60048201610821565b0390fd5b634e487b7160e01b5f52603260045260245ffd5b9190811015610886576001020190565b610862565b90565b6108a261089d6108a79261088b565b61044c565b61043c565b90565b60ff60f81b1690565b90565b60f81b90565b6108d06108cb6108d5926108b3565b6108b6565b6108aa565b90565b60207f77616c5f63726564656e7469616c732070726566697800000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420776974686472615f8201520152565b61093260366040926104b4565b61093b816108d8565b0190565b6109549060208101905f818303910152610925565b90565b1561095e57565b610966610062565b62461bcd60e51b81528061097c6004820161093f565b0390fd5b61099461098f610999926108b3565b61044c565b61043c565b90565b90565b6109b36109ae6109b89261099c565b61044c565b61043c565b90565b5f80fd5b5f80fd5b909392938483116109e35784116109de576001820201920390565b6109bf565b6109bb565b6affffffffffffffffffffff60a81b1690565b1b90565b90610a0d610a149183610491565b91356109e8565b90600b8110610a22575b5090565b610a41906affffffffffffffffffffff60a81b90600b036008026109fb565b165f610a1e565b60a81b90565b610a62610a5d610a679261088b565b610a48565b6109e8565b90565b60207f77616c5f63726564656e7469616c732070616464696e67000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420776974686472615f8201520152565b610ac460376040926104b4565b610acd81610a6a565b0190565b610ae69060208101905f818303910152610ab7565b90565b15610af057565b610af8610062565b62461bcd60e51b815280610b0e60048201610ad1565b0390fd5b90565b610b29610b24610b2e92610b12565b61044c565b61043c565b90565b60207f6f6f206c6f770000000000000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a206465706f7369742076616c756520745f8201520152565b610b8b60266040926104b4565b610b9481610b31565b0190565b610bad9060208101905f818303910152610b7e565b90565b15610bb757565b610bbf610062565b62461bcd60e51b815280610bd560048201610b98565b0390fd5b90565b610bf0610beb610bf592610bd9565b61044c565b61043c565b90565b634e487b7160e01b5f52601260045260245ffd5b610c18610c1e9161043c565b9161043c565b908115610c29570690565b610bf8565b60207f6f74206d756c7469706c65206f66206777656900000000000000000000000000917f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e5f8201520152565b610c8860336040926104b4565b610c9181610c2e565b0190565b610caa9060208101905f818303910152610c7b565b90565b15610cb457565b610cbc610062565b62461bcd60e51b815280610cd260048201610c95565b0390fd5b634e487b7160e01b5f52601160045260245ffd5b610cf6610cfc9161043c565b9161043c565b908115610d07570490565b610bf8565b610d20610d1b610d259261043f565b61044c565b61043c565b90565b60207f6f6f206869676800000000000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a206465706f7369742076616c756520745f8201520152565b610d8260276040926104b4565b610d8b81610d28565b0190565b610da49060208101905f818303910152610d75565b90565b15610dae57565b610db6610062565b62461bcd60e51b815280610dcc60048201610d8f565b0390fd5b90825f939282370152565b9190610df581610dee81610dfa95610130565b8095610dd0565b610144565b0190565b9a969194610e6d96610e428d610e899f9d9b9897610e5f97610e34610e7b9f9a97610e519860e08601918683035f880152610ddb565b926020818503910152610ddb565b918d6040818503910152610ddb565b908a820360608c015261014e565b9188830360808a0152610ddb565b9185830360a0870152610ddb565b9160c081840391015261014e565b90565b6fffffffffffffffffffffffffffffffff191690565b60801b90565b610ebc610eb7610ec19261088b565b610ea2565b610e8c565b90565b905090565b909182610ed981610ee093610ec4565b8093610dd0565b0190565b90565b610ef3610ef891610e8c565b610ee4565b9052565b610f0d9060109493610f1493610ec9565b8092610ee7565b0190565b634e487b7160e01b5f52604160045260245ffd5b90610f3690610144565b810190811067ffffffffffffffff821117610f5057604052565b610f18565b5f1b90565b610f7f610f7692602092610f6d8161012c565b94858093610ec4565b93849101610139565b0190565b610f8c91610f5a565b90565b610f97610062565b3d5f823e3d90fd5b90565b610fae610fb391610217565b610f9f565b9052565b610fc89060209493610fcf93610ec9565b8092610fa2565b0190565b9091610fde92610ec9565b90565b9091610fec92610ec9565b90565b611003610ffe6110089261088b565b610f55565b610217565b90565b61101c906020949361102393610ec9565b8092610fa2565b0190565b60208161103961104193839695610fa2565b018092610fa2565b0190565b8061105660209261105d9694610fa2565b0191610ec9565b90565b67ffffffffffffffff191690565b60401b90565b61108861108361108d9261088b565b61106e565b611060565b90565b90565b61109f6110a491611060565b611090565b9052565b602093926110c56110be6018936110cd95610f5a565b8092611093565b018092610fa2565b0190565b60407f6564206465706f7369745f646174615f726f6f74000000000000000000000000917f4465706f736974436f6e74726163743a207265636f6e737472756374656420445f8201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960208201520152565b61115160546060926104b4565b61115a816110d1565b0190565b6111739060208101905f818303910152611144565b90565b1561117d57565b611185610062565b62461bcd60e51b81528061119b6004820161115e565b0390fd5b6111a96020610498565b90565b90565b6111c36111be6111c8926111ac565b61044c565b61043c565b90565b6111d49061043c565b60ff81116111e25760020a90565b610cd6565b6111f66111fc9193929361043c565b9261043c565b820391821161120757565b610cd6565b61122f61121f61121a61119f565b6111cb565b6112296001610980565b906111e7565b90565b60207f6c00000000000000000000000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c5f8201520152565b61128c60216040926104b4565b61129581611232565b0190565b6112ae9060208101905f81830391015261127f565b90565b156112b857565b6112c0610062565b62461bcd60e51b8152806112d660048201611299565b0390fd5b6112e96112ef9193929361043c565b9261043c565b82018092116112fa57565b610cd6565b9061130b5f1991610f55565b9181191691161790565b61132961132461132e9261043c565b61044c565b61043c565b90565b90565b9061134961134461135092611315565b611331565b82546112ff565b9055565b6001611360910161043c565b90565b50602090565b90565b61137581611363565b82101561138f57611387600191611369565b910201905f90565b610862565b919060086113af9102916113a95f19846109fb565b926109fb565b9181191691161790565b6113c290610217565b90565b6113ce90610413565b90565b91906113e76113e26113ef936113b9565b6113c5565b908354611394565b9055565b1c90565b90565b61140a90600861140f93026113f3565b6113f7565b90565b9061141d91546113fa565b90565b634e487b7160e01b5f52600160045260245ffd5b1561143b57565b611420565b9091989495979396929a999a818361145791610491565b602061146290610498565b9061146c9061043c565b146114769061053c565b898161148191610491565b603061148c90610568565b906114969061043c565b146114a090610603565b87876114ab91610491565b60206114b690610498565b906114c09061043c565b146114ca906106ab565b88846114d591610491565b60406114e0906106d7565b906114ea9061043c565b146114f490610772565b84866114ff91610491565b606061150a9061079e565b906115149061043c565b1461151e90610839565b87875f61152a9061088e565b9061153492610876565b3561153e906108aa565b6001611549906108bc565b90611553906108aa565b1461155d90610957565b87876001600c9061156d90610980565b906115779061099f565b91611581936109c3565b61158a916109ff565b5f61159490610a4e565b61159d906109e8565b906115a7906109e8565b146115b190610ae9565b34670de0b6b3a76400006115c490610b15565b906115ce9061043c565b10156115d990610bb0565b34633b9aca006115e890610bdc565b6115f191610c0c565b5f6115fb9061088e565b906116059061043c565b1461160f90610cad565b34633b9aca0061161e90610bdc565b61162791610cea565b8067ffffffffffffffff61163a90610d0c565b906116449061043c565b111561164f90610da7565b6116589061044f565b61166190611fb9565b99888a8c858b88928c8c8c89978b9995949091929394611681602061042f565b61168a9061044f565b61169390611fb9565b967f0cff1634a9a72df9d813ea7e3a3874a76086e081904ad3cf81e12e43f4d4c87a9b6116be610062565b9b8c9b6116cb9b8d610dfe565b0390a1905f6116d990610ea8565b916116e2610062565b92839260208401926116f393610efc565b6020820181038252036117069082610f2c565b61170e610062565b611719819282610f83565b03905a915f916002602094fa15611c03576117775f916117666020946117586117428651610f55565b93919361174d610062565b948593898501610fb7565b868201810382520382610f2c565b61176e610062565b91829182610f83565b039060025afa15611bfe575f6020916117908251610f55565b976117a561179c610062565b92839283610fd3565b039060025afa15611bf9576117ba5f51610f55565b9160205f6118136118026117dc86866040906117d687926106d7565b926109c3565b91906117f46117e9610062565b938492888401610fe1565b868201810382520382610f2c565b61180a610062565b91829182610f83565b039060025afa15611bf4575f6118896118786118496020946118358551610f55565b969061184160406106d7565b9080926109c3565b919061186a61185786610fef565b61185f610062565b94859389850161100b565b868201810382520382610f2c565b611880610062565b91829182610f83565b039060025afa15611bef575f6118de6020926118cd6118a88451610f55565b916118bf6118b4610062565b938492888401611027565b868201810382520382610f2c565b6118d5610062565b91829182610f83565b039060025afa15611bea575f6119336020926119226118fd8451610f55565b91611914611909610062565b938492888401611027565b868201810382520382610f2c565b61192a610062565b91829182610f83565b039060025afa15611be55761198b5f9161197a60209461196c6119568651610f55565b979193611961610062565b948593898501611045565b868201810382520382610f2c565b611982610062565b91829182610f83565b039060025afa15611be0575f6119ea6020926119d96119aa8451610f55565b956119cb6119b786611074565b936119c0610062565b9485938985016110a8565b868201810382520382610f2c565b6119e1610062565b91829182610f83565b039060025afa15611bdb575f611a3f602092611a2e611a098451610f55565b91611a20611a15610062565b938492888401611027565b868201810382520382610f2c565b611a36610062565b91829182610f83565b039060025afa15611bd657611a71611a575f51610f55565b92611a6b611a658592610217565b91610217565b14611176565b611a9d611a7e602061042f565b611a97611a91611a8c61120c565b61043c565b9161043c565b106112b1565b611ac3611abc611aad6001610980565b611ab7602061042f565b6112da565b6020611334565b611acd602061042f565b611ad65f61088e565b925b83611af2611aec611ae761119f565b61043c565b9161043c565b1015611bc75781611b036001610980565b16611b17611b116001610980565b9161043c565b14611bad575f611b6f602092611b5e611b3a611b34858a9061136c565b90611412565b611b50611b45610062565b938492888401611027565b868201810382520382610f2c565b611b66610062565b91829182610f83565b039060025afa15611ba857611ba1611b9b611b8a5f51610f55565b92611b9560026111af565b90610cea565b93611354565b9290611ad8565b610f8f565b611bc592939150611bbf90915f61136c565b906113d1565b565b50509050611bd45f611434565b565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b5f90565b60189392602082611c23611c2a94611c3196610fa2565b0190610f5a565b8092611093565b0190565b611c3d611c08565b50611c46611c08565b90611c51602061042f565b611c5a5f61088e565b925b83611c76611c70611c6b61119f565b61043c565b9161043c565b1015611dad575f60209183611c8b6001610980565b16611c9f611c996001610980565b9161043c565b148214611d3557611cf690611ce5611cc1611cbb858a9061136c565b90611412565b611cd7611ccc610062565b938492888401611027565b868201810382520382610f2c565b611ced610062565b91829182610f83565b039060025afa15611d3057611d29611d23611d115f51610f55565b925b611d1d60026111af565b90610cea565b93611354565b9290611c5c565b610f8f565b611d8790611d76611d51611d4b60218a9061136c565b90611412565b91611d68611d5d610062565b938492888401611027565b868201810382520382610f2c565b611d7e610062565b91829182610f83565b039060025afa15611da857611d29611d23611da25f51610f55565b92611d13565b610f8f565b60209293505f9150611e1490611e03611dd5611dd0611dcb8761042f565b61044f565b611fb9565b91611df5611de286611074565b611dea610062565b948593898501611c0c565b868201810382520382610f2c565b611e0b610062565b91829182610f83565b039060025afa15611e2c57611e295f51610f55565b90565b610f8f565b90565b611e48611e43611e4d92611e31565b61044c565b61043c565b90565b90611e63611e5c610062565b9283610f2c565b565b67ffffffffffffffff8111611e8357611e7f602091610144565b0190565b610f18565b90611e9a611e9583611e65565b611e50565b918252565b369037565b90611ec9611eb183611e88565b92602080611ebf8693611e65565b9201910390611e9f565b565b67ffffffffffffffff60c01b1690565b60c01b90565b611ef5611ef0611efa9261043f565b611edb565b611ecb565b90565b90565b611f14611f0f611f1992611efd565b61044c565b61043c565b90565b90611f268261012c565b811015611f3857600160209102010190565b610862565b90565b611f54611f4f611f5992611f3d565b61044c565b61043c565b90565b90565b611f73611f6e611f7892611f5c565b61044c565b61043c565b90565b90565b611f92611f8d611f9792611f7b565b61044c565b61043c565b90565b90565b611fb1611fac611fb692611f9a565b61044c565b61043c565b90565b90611fc261040e565b50611fde611fd8611fd36008611e34565b611ea4565b92611ee1565b80611fe96007611f00565b9060088210156121c057611ffd911a6108b6565b6120148461200e5f935f1a9361088e565b90611f1c565b53806120206006611f40565b9060088210156121bb57612034911a6108b6565b61204c846120466001935f1a93610980565b90611f1c565b53806120586005611f5f565b9060088210156121b65761206c911a6108b6565b6120848461207e6002935f1a936111af565b90611f1c565b53806120906004611f7e565b9060088210156121b1576120a4911a6108b6565b6120bc846120b66003935f1a93611f9d565b90611f1c565b53806120c86003611f9d565b9060088210156121ac576120dc911a6108b6565b6120f4846120ee6004935f1a93611f7e565b90611f1c565b538061210060026111af565b9060088210156121a757612114911a6108b6565b61212c846121266005935f1a93611f5f565b90611f1c565b53806121386001610980565b9060088210156121a25761214c911a6108b6565b6121648461215e6006935f1a93611f40565b90611f1c565b5361216e5f61088e565b90600882101561219d57612182911a6108b6565b61219a836121946007935f1a93611f00565b90611f1c565b53565b610862565b610862565b610862565b610862565b610862565b610862565b610862565b61086256fea264697066735822122088155372033ad8432d1e232fd8b99b2efa9bf3139204e1cfb792a24e11e419ed64736f6c637828302e382e33312d646576656c6f702e323032362e312e32332b636f6d6d69742e36373662646563630059" + }, + "0x00000961ef480eb55e80d19ad83579a64c007002": { + "balance": "0x0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd" + }, + "0x1000000000000000000000000000000000000001": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b61071b565b61001d5f3561007c565b806344c0b2bf146100775780637a737c37146100725780638da5cb5b1461006d57806391fef11614610068578063a409c6f0146100635763b115ce0d0361000e576106e6565b610605565b61052d565b61042a565b610397565b61023b565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906100c49061009c565b810190811067ffffffffffffffff8211176100de57604052565b6100a6565b906100f66100ef610082565b92836100ba565b565b67ffffffffffffffff81116101165761011260209161009c565b0190565b6100a6565b90825f939282370152565b9092919261013b610136826100f8565b6100e3565b93818552602085019082840111610157576101559261011b565b565b610098565b9080601f8301121561017a5781602061017793359101610126565b90565b610094565b151590565b61018d8161017f565b0361019457565b5f80fd5b905035906101a582610184565b565b608081830312610231575f81013567ffffffffffffffff811161022c57826101d091830161015c565b92602082013567ffffffffffffffff811161022757836101f191840161015c565b9260408301359067ffffffffffffffff8211610222576102168161021f93860161015c565b93606001610198565b90565b610090565b610090565b610090565b61008c565b5f0190565b3461026d5761025761024e3660046101a7565b92919091610a62565b61025f610082565b8061026981610236565b0390f35b610088565b5f80fd5b5f80fd5b9190916080818403126103385761029160806100e3565b925f82013567ffffffffffffffff811161033357816102b191840161015c565b5f850152602082013567ffffffffffffffff811161032e57816102d591840161015c565b6020850152604082013567ffffffffffffffff811161032957816102fa91840161015c565b6040850152606082013567ffffffffffffffff81116103245761031d920161015c565b6060830152565b610276565b610276565b610276565b610276565b610272565b9060208282031261036d575f82013567ffffffffffffffff811161036857610365920161027a565b90565b610090565b61008c565b90565b61037e90610372565b9052565b9190610395905f60208501940190610375565b565b346103c7576103c36103b26103ad36600461033d565b610c35565b6103ba610082565b91829182610382565b0390f35b610088565b5f9103126103d657565b61008c565b60026001609c1b0190565b6103ee6103db565b90565b60018060a01b031690565b610405906103f1565b90565b610411906103fc565b9052565b9190610428905f60208501940190610408565b565b3461045a5761043a3660046103cc565b6104566104456103e6565b61044d610082565b91829182610415565b0390f35b610088565b9190916060818403126104f35761047660606100e3565b925f82013567ffffffffffffffff81116104ee578161049691840161015c565b5f850152602082013567ffffffffffffffff81116104e957816104ba91840161015c565b6020850152604082013567ffffffffffffffff81116104e4576104dd920161015c565b6040830152565b610276565b610276565b610276565b610272565b90602082820312610528575f82013567ffffffffffffffff811161052357610520920161045f565b90565b610090565b61008c565b3461055d576105596105486105433660046104f8565b610cdc565b610550610082565b91829182610382565b0390f35b610088565b916060838303126105de575f83013567ffffffffffffffff81116105d9578261058c91850161015c565b92602081013567ffffffffffffffff81116105d457836105ad91830161015c565b92604082013567ffffffffffffffff81116105cf576105cc920161015c565b90565b610090565b610090565b610090565b61008c565b6105ec9061017f565b9052565b9190610603905f602085019401906105e3565b565b346106365761063261062161061b366004610562565b91610d4f565b610629610082565b918291826105f0565b0390f35b610088565b61064481610372565b0361064b57565b5f80fd5b9050359061065c8261063b565b565b9060208282031261067757610674915f0161064f565b90565b61008c565b61068590610372565b90565b906106929061067c565b5f5260205260405f2090565b1c90565b60ff1690565b6106b89060086106bd930261069e565b6106a2565b90565b906106cb91546106a8565b90565b6106e3906106de5f915f92610688565b6106c0565b90565b34610716576107126107016106fc36600461065e565b6106ce565b610709610082565b918291826105f0565b0390f35b610088565b5f80fd5b60209181520190565b5f7f4f6e6c79206f776e65722063616e207365742073746174757300000000000000910152565b61075c601960209261071f565b61076581610728565b0190565b61077e9060208101905f81830391015261074f565b90565b1561078857565b610790610082565b62461bcd60e51b8152806107a660048201610769565b0390fd5b5190565b90565b90565b90565b6107cb6107c66107d0926107b1565b6107b4565b6107ae565b90565b5f7f496e76616c6964206d727464206c656e67746800000000000000000000000000910152565b610807601360209261071f565b610810816107d3565b0190565b6108299060208101905f8183039101526107fa565b90565b1561083357565b61083b610082565b62461bcd60e51b81528061085160048201610814565b0390fd5b5f7f496e76616c6964206d727365616d206c656e6774680000000000000000000000910152565b610889601560209261071f565b61089281610855565b0190565b6108ab9060208101905f81830391015261087c565b90565b156108b557565b6108bd610082565b62461bcd60e51b8152806108d360048201610896565b0390fd5b90565b6108ee6108e96108f3926108d7565b6107b4565b6107ae565b90565b5f7f496e76616c69642070637234206c656e67746800000000000000000000000000910152565b61092a601360209261071f565b610933816108f6565b0190565b61094c9060208101905f81830391015261091d565b90565b1561095657565b61095e610082565b62461bcd60e51b81528061097460048201610937565b0390fd5b61098260606100e3565b90565b52565b5f1b90565b9061099960ff91610988565b9181191691161790565b6109ac9061017f565b90565b90565b906109c76109c26109ce926109a3565b6109af565b825461098d565b9055565b60209181520190565b90825f9392825e0152565b610a05610a0e602093610a13936109fc816107aa565b938480936109d2565b958691016109db565b61009c565b0190565b949391610a6093610a4a610a5892610a3c60609560808b01908b82035f8d01526109e6565b9089820360208b01526109e6565b9087820360408901526109e6565b9401906105e3565b565b610b7990610a8933610a83610a7d610a786103db565b6103fc565b916103fc565b14610781565b610aae610a95826107aa565b610aa8610aa260306107b7565b916107ae565b1461082c565b610ad3610aba846107aa565b610acd610ac760306107b7565b916107ae565b146108ae565b610af8610adf856107aa565b610af2610aec60206108da565b916107ae565b1461094f565b610b43610b3382610b2e86610b258991610b1c610b13610978565b955f8701610985565b60208501610985565b60408301610985565b610cdc565b610b3e87915f610688565b6109b2565b9192937ffbd013ecb3bb070127bc1b1186c451c2a5778c62b56de1db228acce4c28038ea94610b70610082565b94859485610a17565b0390a1565b5f90565b60209181520190565b610baa610bb3602093610bb893610ba1816107aa565b93848093610b82565b958691016109db565b61009c565b0190565b610c14916060610c03610bf1610bdf608085015f8701518682035f880152610b8b565b60208601518582036020870152610b8b565b60408501518482036040860152610b8b565b920151906060818403910152610b8b565b90565b610c2c9160208201915f818403910152610bbc565b90565b60200190565b610c68610c5991610c44610b7e565b50610c4d610082565b92839160208301610c17565b602082018103825203826100ba565b610c7a610c74826107aa565b91610c2f565b2090565b610cc1916040610cb0610c9e606084015f8601518582035f870152610b8b565b60208501518482036020860152610b8b565b920151906040818403910152610b8b565b90565b610cd99160208201915f818403910152610c7e565b90565b610d0f610d0091610ceb610b7e565b50610cf4610082565b92839160208301610cc4565b602082018103825203826100ba565b610d21610d1b826107aa565b91610c2f565b2090565b5f90565b5f1c90565b610d3a610d3f91610d29565b6106a2565b90565b610d4c9054610d2e565b90565b610e0b91610e00610e1094610df7610e0594610d69610d25565b50610d8f610d76826107aa565b610d89610d8360306107b7565b916107ae565b1461082c565b610db4610d9b866107aa565b610dae610da860306107b7565b916107ae565b146108ae565b610dd9610dc0846107aa565b610dd3610dcd60206108da565b916107ae565b1461094f565b93610dee610de5610978565b955f8701610985565b60208501610985565b60408301610985565b610cdc565b5f610688565b610d42565b9056fea26469706673582212209c9e77189674da6a0061a74e49989970b3eebaadb84294b33acb051b808ab37164736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000002": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b6109af565b61001d5f356100ec565b806325c99ae4146100e757806334107282146100e257806338c0ac5f146100dd5780633eeb92f6146100d85780634456251b146100d357806346a67577146100ce578063894f449c146100c95780639386775a146100c45780639f2ce678146100bf578063a1695993146100ba578063a9fcfb33146100b5578063cc3c74a1146100b05763e28ba0340361000e57610978565b610943565b6108c2565b61085d565b6107f9565b610791565b610673565b6105ab565b610382565b6102de565b610286565b61022e565b6101a8565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f91031261010a57565b6100fc565b60018060a01b031690565b90565b61013161012c6101369261010f565b61011a565b61010f565b90565b6101429061011d565b90565b61014e90610139565b90565b610160600180609c1b01610145565b90565b61016b610151565b90565b6101779061011d565b90565b6101839061016e565b90565b61018f9061017a565b9052565b91906101a6905f60208501940190610186565b565b346101d8576101b8366004610100565b6101d46101c3610163565b6101cb6100f2565b91829182610193565b0390f35b6100f8565b73f39fd6e51aad88f6f4ce6ab8827279cfffb9226690565b6101fd6101dd565b90565b6102099061010f565b90565b61021590610200565b9052565b919061022c905f6020850194019061020c565b565b3461025e5761023e366004610100565b61025a6102496101f5565b6102516100f2565b91829182610219565b0390f35b6100f8565b7370997970c51812dc3a010c7d01b50e0d17dc79c890565b610283610263565b90565b346102b657610296366004610100565b6102b26102a161027b565b6102a96100f2565b91829182610219565b0390f35b6100f8565b733c44cdddb6a900fa2b585dd299e03d12fa4293bc90565b6102db6102bb565b90565b3461030e576102ee366004610100565b61030a6102f96102d3565b6103016100f2565b91829182610219565b0390f35b6100f8565b5f80fd5b90565b61032381610317565b0361032a57565b5f80fd5b9050359061033b8261031a565b565b9060208282031261035657610353915f0161032e565b90565b6100fc565b151590565b6103699061035b565b9052565b9190610380905f60208501940190610360565b565b346103b2576103ae61039d61039836600461033d565b610a4b565b6103a56100f2565b9182918261036d565b0390f35b6100f8565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103e7906103bf565b810190811067ffffffffffffffff82111761040157604052565b6103c9565b906104196104126100f2565b92836103dd565b565b67ffffffffffffffff8111610439576104356020916103bf565b0190565b6103c9565b90825f939282370152565b9092919261045e6104598261041b565b610406565b9381855260208501908284011161047a576104789261043e565b565b6103bb565b9080601f8301121561049d5781602061049a93359101610449565b90565b6103b7565b6104ab8161035b565b036104b257565b5f80fd5b905035906104c3826104a2565b565b90565b6104d1816104c5565b036104d857565b5f80fd5b905035906104e9826104c8565b565b919060a083820312610584575f83013567ffffffffffffffff811161057f578161051691850161047f565b92602081013567ffffffffffffffff811161057a578261053791830161047f565b92604082013567ffffffffffffffff81116105755761055b8461057292850161047f565b9361056981606086016104b6565b936080016104dc565b90565b610313565b610313565b610313565b6100fc565b61059290610317565b9052565b91906105a9905f60208501940190610589565b565b346105df576105db6105ca6105c13660046104eb565b93929092610d6a565b6105d26100f2565b91829182610596565b0390f35b6100f8565b60808183031261066e575f81013567ffffffffffffffff8111610669578261060d91830161047f565b92602082013567ffffffffffffffff8111610664578361062e91840161047f565b9260408301359067ffffffffffffffff821161065f576106538161065c93860161047f565b936060016104b6565b90565b610313565b610313565b610313565b6100fc565b346106a7576106a36106926106893660046105e4565b929190916111fc565b61069a6100f2565b91829182610596565b0390f35b6100f8565b6106b581610200565b036106bc57565b5f80fd5b905035906106cd826106ac565b565b91906040838203126106f757806106eb6106f4925f860161032e565b936020016106c0565b90565b6100fc565b61070590610317565b90565b90610712906106fc565b5f5260205260405f2090565b6107279061016e565b90565b906107349061071e565b5f5260205260405f2090565b1c90565b60ff1690565b61075a90600861075f9302610740565b610744565b90565b9061076d915461074a565b90565b61078961078e926107846001935f94610708565b61072a565b610762565b90565b346107c2576107be6107ad6107a73660046106cf565b90610770565b6107b56100f2565b9182918261036d565b0390f35b6100f8565b91906040838203126107ef57806107e36107ec925f860161032e565b936020016104b6565b90565b6100fc565b5f0190565b346108285761081261080c3660046107c7565b90611469565b61081a6100f2565b80610824816107f4565b0390f35b6100f8565b610836906104c5565b9052565b91602061085b92949361085460408201965f83019061082d565b019061082d565b565b3461088e5761087561087036600461033d565b6115aa565b9061088a6108816100f2565b9283928361083a565b0390f35b6100f8565b9061089d906106fc565b5f5260205260405f2090565b6108bf906108ba6002915f92610893565b610762565b90565b346108f2576108ee6108dd6108d836600461033d565b6108a9565b6108e56100f2565b9182918261036d565b0390f35b6100f8565b90565b61090a90600861090f9302610740565b6108f7565b90565b9061091d91546108fa565b90565b61092b5f5f90610912565b90565b9190610941905f6020850194019061082d565b565b3461097357610953366004610100565b61096f61095e610920565b6109666100f2565b9182918261092e565b0390f35b6100f8565b346109aa5761099461098b3660046104eb565b93929092611772565b61099c6100f2565b806109a6816107f4565b0390f35b6100f8565b5f80fd5b5f90565b5f1c90565b6109c86109cd916109b7565b610744565b90565b6109da90546109bc565b90565b90565b6109f46109ef6109f9926109dd565b61011a565b6104c5565b90565b634e487b7160e01b5f52601160045260245ffd5b610a19906104c5565b5f198114610a275760010190565b6109fc565b90565b610a43610a3e610a4892610a2c565b61011a565b6104c5565b90565b610a536109b3565b50610a68610a6360028390610893565b6109d0565b610b4657610a755f6109e0565b90610a9b610a96610a8860018490610708565b610a906101dd565b9061072a565b6109d0565b610b36575b610ac5610ac0610ab260018490610708565b610aba610263565b9061072a565b6109d0565b610b19575b610ae9610adb610aee926001610708565b610ae36102bb565b9061072a565b6109d0565b610b0b575b610b06610b006002610a2f565b916104c5565b101590565b610b1490610a10565b610af3565b90610ae9610adb610b2c610aee93610a10565b9392505050610aca565b90610b4090610a10565b90610aa0565b505f90565b5f90565b610b596060610406565b90565b52565b5f80fd5b60e01b90565b90505190610b768261031a565b565b90602082820312610b9157610b8e915f01610b69565b90565b6100fc565b5190565b60209181520190565b90825f9392825e0152565b610bcd610bd6602093610bdb93610bc481610b96565b93848093610b9a565b95869101610ba3565b6103bf565b0190565b610c22916040610c11610bff606084015f8601518582035f870152610bae565b60208501518482036020860152610bae565b920151906040818403910152610bae565b90565b610c3a9160208201915f818403910152610bdf565b90565b610c456100f2565b3d5f823e3d90fd5b60209181520190565b60207f6564000000000000000000000000000000000000000000000000000000000000917f757067726164654f70657261746f722e636f6d7075746549645631206661696c5f8201520152565b610cb06022604092610c4d565b610cb981610c56565b0190565b610cd29060208101905f818303910152610ca3565b90565b90565b610ce4610ce991610317565b610cd5565b9052565b60f81b90565b610cfc90610ced565b90565b610d0890610cf3565b90565b610d17610d1c9161035b565b610cff565b9052565b90565b610d2f610d34916104c5565b610d20565b9052565b60209392610d588583610d50600195610d6097610cd8565b018092610d0b565b018092610d23565b0190565b60200190565b91610d9a610da39293610d7b610b4b565b5093610d91610d88610b4f565b955f8701610b5c565b60208501610b5c565b60408301610b5c565b90610de96020610db1610b4b565b93610dc2610dbd610151565b61017a565b610dde6391fef116610dd26100f2565b95869485938493610b63565b835260048301610c25565b03915afa80915f92610e78575b50155f14610e6a57506001610e4857610e23610e32925b9193610e176100f2565b94859360208501610d38565b602082018103825203826103dd565b610e44610e3e82610b96565b91610d64565b2090565b610e506100f2565b62461bcd60e51b815280610e6660048201610cbd565b0390fd5b610e329250610e2390610e0d565b610e9a91925060203d8111610ea1575b610e9281836103dd565b810190610b78565b905f610df6565b503d610e88565b90565b610ebf610eba610ec492610ea8565b61011a565b6104c5565b90565b5f7f496e76616c6964206d727464206c656e67746800000000000000000000000000910152565b610efb6013602092610c4d565b610f0481610ec7565b0190565b610f1d9060208101905f818303910152610eee565b90565b15610f2757565b610f2f6100f2565b62461bcd60e51b815280610f4560048201610f08565b0390fd5b5f7f496e76616c6964206d727365616d206c656e6774680000000000000000000000910152565b610f7d6015602092610c4d565b610f8681610f49565b0190565b610f9f9060208101905f818303910152610f70565b90565b15610fa957565b610fb16100f2565b62461bcd60e51b815280610fc760048201610f8a565b0390fd5b90565b610fe2610fdd610fe792610fcb565b61011a565b6104c5565b90565b5f7f496e76616c69642070637234206c656e67746800000000000000000000000000910152565b61101e6013602092610c4d565b61102781610fea565b0190565b6110409060208101905f818303910152611011565b90565b1561104a57565b6110526100f2565b62461bcd60e51b8152806110686004820161102b565b0390fd5b61107861107d916109b7565b6108f7565b90565b61108a905461106c565b90565b5f1b90565b9061109e5f199161108d565b9181191691161790565b6110bc6110b76110c1926104c5565b61011a565b6104c5565b90565b90565b906110dc6110d76110e3926110a8565b6110c4565b8254611092565b9055565b5f7f50726f706f73616c20616c726561647920657865637574656400000000000000910152565b61111b6019602092610c4d565b611124816110e7565b0190565b61113d9060208101905f81830391015261110e565b90565b1561114757565b61114f6100f2565b62461bcd60e51b81528061116560048201611128565b0390fd5b60209181520190565b61119161119a60209361119f9361118881610b96565b93848093611169565b95869101610ba3565b6103bf565b0190565b959492936111e46111fa956111d6896080966111c96111f2975f60a0850194019061082d565b8b820360208d0152611172565b9089820360408b0152611172565b908782036060890152611172565b940190610360565b565b9290611206610b4b565b5061122c61121385610b96565b6112266112206030610eab565b916104c5565b14610f20565b61125161123882610b96565b61124b6112456030610eab565b916104c5565b14610fa2565b61127661125d84610b96565b61127061126a6020610fce565b916104c5565b14611043565b61129061128a6112855f611080565b610a10565b5f6110c7565b6112a784828585916112a15f611080565b93610d6a565b936112cd6112c86112c26112bd60028990610893565b6109d0565b1561035b565b611140565b61131a85936112db5f611080565b9293956113087fc608a3fb719bb3f084c89497286b28154f3baeaf8b21efd34fafa4bab23daf0c966106fc565b966113116100f2565b958695866111a3565b0390a290565b5f7f4e6f7420617574686f72697a656420746f20766f746500000000000000000000910152565b6113546016602092610c4d565b61135d81611320565b0190565b6113769060208101905f818303910152611347565b90565b1561138057565b6113886100f2565b62461bcd60e51b81528061139e60048201611361565b0390fd5b5f7f416c726561647920766f74656400000000000000000000000000000000000000910152565b6113d6600d602092610c4d565b6113df816113a2565b0190565b6113f89060208101905f8183039101526113c9565b90565b1561140257565b61140a6100f2565b62461bcd60e51b815280611420600482016113e3565b0390fd5b9061143060ff9161108d565b9181191691161790565b6114439061035b565b90565b90565b9061145e6114596114659261143a565b611446565b8254611424565b9055565b3361148361147d6114786101dd565b610200565b91610200565b148015611585575b801561155f575b61149b90611379565b6114c06114bb6114b56114b060028590610893565b6109d0565b1561035b565b611140565b6114ef6114ea6114e46114df6114d860018690610708565b339061072a565b6109d0565b1561035b565b6113fb565b61150e8261150961150260018590610708565b339061072a565b611449565b9033909161155a6115486115427f8b40665146691327ee30f5bf56e9b2d6f445d2830d3b09b56385cd30f630ecfb936106fc565b9361071e565b936115516100f2565b9182918261036d565b0390a3565b5061149b3361157d6115776115726102bb565b610200565b91610200565b149050611492565b50336115a061159a611595610263565b610200565b91610200565b1461148b565b5f90565b906115b36115a6565b6115bb6115a6565b926115e16115dc6115ce60018490610708565b6115d66101dd565b9061072a565b6109d0565b61167c575b61160b6116066115f860018490610708565b611600610263565b9061072a565b6109d0565b611655575b61162f611621611634926001610708565b6116296102bb565b9061072a565b6109d0565b61163d575b9190565b61164961164f91610a10565b92610a10565b91611639565b929061162f61162161167261166c61163494610a10565b94610a10565b9592505050611610565b929061168a61169091610a10565b91610a10565b926115e6565b5f7f496e73756666696369656e7420766f7465730000000000000000000000000000910152565b6116ca6012602092610c4d565b6116d381611696565b0190565b6116ec9060208101905f8183039101526116bd565b90565b156116f657565b6116fe6100f2565b62461bcd60e51b815280611714600482016116d7565b0390fd5b5f91031261172257565b6100fc565b9493916117709361175a6117689261174c60609560808b01908b82035f8d0152611172565b9089820360208b0152611172565b908782036040890152611172565b940190610360565b565b919293611786908390838690889293610d6a565b936117ac6117a76117a161179c60028990610893565b6109d0565b1561035b565b611140565b6118506117b85f6109e0565b6117dd6117d86117ca60018a90610708565b6117d26101dd565b9061072a565b6109d0565b611955575b6118076118026117f460018a90610708565b6117fc610263565b9061072a565b6109d0565b611947575b61183161182c61181e60018a90610708565b6118266102bb565b9061072a565b6109d0565b611939575b6118496118436002610a2f565b916104c5565b10156116ef565b611866600161186160028890610893565b611449565b611876611871610151565b61017a565b906344c0b2bf93929490823b15611934575f946118b186926118a69461189a6100f2565b998a9889978896610b63565b865260048601611727565b03925af1801561192f57611903575b506118eb7f7b1bcf1ccf901a11589afff5504d59fd0a53780eed2a952adade0348985139e0916106fc565b906118f46100f2565b806118fe816107f4565b0390a2565b611922905f3d8111611928575b61191a81836103dd565b810190611718565b5f6118c0565b503d611910565b610c3d565b610b5f565b61194290610a10565b611836565b61195090610a10565b61180c565b61195e90610a10565b6117e256fea26469706673582212202d96e5873e9f4e8c9465739f2343b8fa8881d1850ca80037522a66301dbd4bff64736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000003": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b61049a565b61001d5f3561006c565b8063415028a914610067578063727c346d14610062578063ad28a8161461005d578063baefa307146100585763e8d6c79a0361000e5761046e565b6103db565b61036d565b6102ff565b610245565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906100b090610088565b810190811067ffffffffffffffff8211176100ca57604052565b610092565b906100e26100db610072565b92836100a6565b565b67ffffffffffffffff8111610102576100fe602091610088565b0190565b610092565b90825f939282370152565b90929192610127610122826100e4565b6100cf565b938185526020850190828401116101435761014192610107565b565b610084565b9080601f830112156101665781602061016393359101610112565b90565b610080565b6bffffffffffffffffffffffff1690565b6101858161016b565b0361018c57565b5f80fd5b9050359061019d8261017c565b565b91906040838203126101df575f8301359067ffffffffffffffff82116101da576101ce816101d7938601610148565b93602001610190565b90565b61007c565b610078565b5190565b60209181520190565b90825f9392825e0152565b61021b61022460209361022993610212816101e4565b938480936101e8565b958691016101f1565b610088565b0190565b6102429160208201915f8184039101526101fc565b90565b61026d61025c61025636600461019f565b90610513565b610264610072565b9182918261022d565b0390f35b5f91031261027b57565b610078565b90565b60018060a01b031690565b90565b6102a56102a06102aa92610280565b61028e565b610283565b90565b6102b690610291565b90565b6102c360686102ad565b90565b6102ce6102b9565b90565b6102da90610283565b90565b6102e6906102d1565b9052565b91906102fd905f602085019401906102dd565b565b61030a366004610271565b6103266103156102c6565b61031d610072565b918291826102ea565b0390f35b90565b61034161033c6103469261032a565b61028e565b610283565b90565b6103529061032d565b90565b61035f6067610349565b90565b61036a610355565b90565b610378366004610271565b610394610383610362565b61038b610072565b918291826102ea565b0390f35b90565b6103af6103aa6103b492610398565b61028e565b610283565b90565b6103c09061039b565b90565b6103cd60666103b7565b90565b6103d86103c3565b90565b6103e6366004610271565b6104026103f16103d0565b6103f9610072565b918291826102ea565b0390f35b90602082820312610436575f82013567ffffffffffffffff81116104315761042e9201610148565b90565b61007c565b610078565b6104449061016b565b9052565b9291602061046461046c9360408701908782035f8901526101fc565b94019061043b565b565b61048161047c366004610406565b610739565b9061049661048d610072565b92839283610448565b0390f35b5f80fd5b606090565b905090565b6104cd6104c4926020926104bb816101e4565b948580936104a3565b938491016101f1565b0190565b60a01b90565b6104e0906104d1565b90565b6104ef6104f49161016b565b6104d7565b9052565b61050861050f91600c94936104a8565b80926104e3565b0190565b6105469061051f61049e565b5061053761052b610072565b938492602084016104f8565b602082018103825203826100a6565b90565b5f90565b90565b90565b61056761056261056c9261054d565b61028e565b610550565b90565b634e487b7160e01b5f52601160045260245ffd5b61059261059891939293610550565b92610550565b82039182116105a357565b61056f565b906105ba6105b5836100e4565b6100cf565b918252565b369037565b906105e96105d1836105a8565b926020806105df86936100e4565b92019103906105bf565b565b90565b6106026105fd610607926105eb565b61028e565b610550565b90565b60016106169101610550565b90565b634e487b7160e01b5f52603260045260245ffd5b90610637826101e4565b81101561064957600160209102010190565b610619565b60ff60f81b1690565b610661905161064e565b90565b61067361067991939293610550565b92610550565b820180921161068457565b61056f565b60200190565b6bffffffffffffffffffffffff60a01b1690565b6106ad905161068f565b90565b1b90565b6106ce6106c96106c3836101e4565b92610689565b6106a3565b90600c81106106dc575b5090565b6106fc906bffffffffffffffffffffffff60a01b90600c036008026106b0565b165f6106d8565b60a01c90565b61071d6107186107229261016b565b61028e565b61016b565b90565b61073161073691610703565b610709565b90565b9061074261049e565b5061074b610549565b50610768610758836101e4565b610762600c610553565b90610583565b610771816105c4565b9061077b5f6105ee565b5b8061078f61078984610550565b91610550565b10156107c6576107c1906107ac6107a787839061062d565b610657565b6107bb859183905f1a9261062d565b5361060a565b61077c565b50926107da6107d5600c610553565b6105c4565b916107e45f6105ee565b5b806107f96107f3600c610553565b91610550565b101561083a576108359061082061081b856108158a8590610664565b9061062d565b610657565b61082f869183905f1a9261062d565b5361060a565b6107e5565b5093505061084a61084f916106b4565b610725565b9056fea2646970667358221220f9203a71c0b6a6da16bf7b2698301c72ec306733882bb85b4d6d1038767c731464736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000004": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b610694565b61001d5f356100ac565b8063210ca7be146100a7578063415028a9146100a257806370df09331461009d57806382678dd6146100985780638b2f9fd114610093578063affed0e01461008e578063b7f5f9b714610089578063e8d6c79a146100845763eefbaf180361000e5761065f565b610604565b6105a8565b61052e565b61048d565b6103d9565b610372565b6102f3565b610245565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906100f4906100cc565b810190811067ffffffffffffffff82111761010e57604052565b6100d6565b9061012661011f6100b2565b92836100ea565b565b67ffffffffffffffff8111610146576101426020916100cc565b0190565b6100d6565b90825f939282370152565b9092919261016b61016682610128565b610113565b93818552602085019082840111610187576101859261014b565b565b6100c8565b9080601f830112156101aa578160206101a793359101610156565b90565b6100c4565b906020828203126101df575f82013567ffffffffffffffff81116101da576101d7920161018c565b90565b6100c0565b6100bc565b5190565b60209181520190565b90825f9392825e0152565b61021b61022460209361022993610212816101e4565b938480936101e8565b958691016101f1565b6100cc565b0190565b6102429160208201915f8184039101526101fc565b90565b346102755761027161026061025b3660046101af565b610713565b6102686100b2565b9182918261022d565b0390f35b6100b8565b6bffffffffffffffffffffffff1690565b6102948161027a565b0361029b57565b5f80fd5b905035906102ac8261028b565b565b91906040838203126102ee575f8301359067ffffffffffffffff82116102e9576102dd816102e693860161018c565b9360200161029f565b90565b6100c0565b6100bc565b346103245761032061030f6103093660046102ae565b906107b7565b6103176100b2565b9182918261022d565b0390f35b6100b8565b90565b61033581610329565b0361033c57565b5f80fd5b9050359061034d8261032c565b565b9060208282031261036857610365915f01610340565b90565b6100bc565b5f0190565b346103a05761038a61038536600461034f565b610847565b6103926100b2565b8061039c8161036d565b0390f35b6100b8565b5f9103126103af57565b6100bc565b90565b6103c0906103b4565b9052565b91906103d7905f602085019401906103b7565b565b34610409576103e93660046103a5565b6104056103f46108be565b6103fc6100b2565b918291826103c4565b0390f35b6100b8565b60018060a01b031690565b6104229061040e565b90565b61042e81610419565b0361043557565b5f80fd5b9050359061044682610425565b565b906020828203126104615761045e915f01610439565b90565b6100bc565b151590565b61047490610466565b9052565b919061048b905f6020850194019061046b565b565b346104bd576104b96104a86104a3366004610448565b610908565b6104b06100b2565b91829182610478565b0390f35b6100b8565b1c90565b6bffffffffffffffffffffffff1690565b6104e79060086104ec93026104c2565b6104c6565b90565b906104fa91546104d7565b90565b61050960015f906104ef565b90565b6105159061027a565b9052565b919061052c905f6020850194019061050c565b565b3461055e5761053e3660046103a5565b61055a6105496104fd565b6105516100b2565b91829182610519565b0390f35b6100b8565b9190916040818403126105a35761057c835f8301610439565b92602082013567ffffffffffffffff811161059e5761059b920161018c565b90565b6100c0565b6100bc565b346105d9576105d56105c46105be366004610563565b906109fe565b6105cc6100b2565b9182918261022d565b0390f35b6100b8565b929160206105fa6106029360408701908782035f8901526101fc565b94019061050c565b565b346106355761061c6106173660046101af565b610c1b565b906106316106286100b2565b928392836105de565b0390f35b6100b8565b90565b6106469061063a565b9052565b919061065d905f6020850194019061063d565b565b3461068f5761068b61067a610675366004610448565b610d60565b6106826100b2565b9182918261064a565b0390f35b6100b8565b5f80fd5b606090565b90565b6106b46106af6106b99261040e565b61069d565b61040e565b90565b6106c5906106a0565b90565b6106d1906106bc565b90565b906106de906106c8565b5f5260205260405f2090565b5f1c90565b90565b6106fe610703916106ea565b6106ef565b90565b61071090b06106f2565b90565b61072861074491610722610698565b50610c1b565b9061073c6107375f33906106d4565b610706565b919091610e44565b90565b905090565b6107716107689260209261075f816101e4565b94858093610747565b938491016101f1565b0190565b60a01b90565b61078490610775565b90565b6107936107989161027a565b61077b565b9052565b6107ac6107b391600c949361074c565b8092610787565b0190565b6107ea906107c3610698565b506107db6107cf6100b2565b9384926020840161079c565b602082018103825203826100ea565b90565b5f1b90565b906107fe5f19916107ed565b9181191691161790565b61081c61081761082192610329565b61069d565b610329565b90565b90565b9061083c61083761084392610808565b610824565b82b06107f2565b90b1565b61085b906108565f33906106d4565b610827565b336108867fe09b54ab39b458cc6e350a9444815a294301d94eaa79ba68d8a2f9f9c7c0b4cc916106c8565b9061088f6100b2565b806108998161036d565b0390a2565b5f90565b6108b66108b16108bb92610329565b61069d565b6103b4565b90565b6108c661089e565b506108e26108dd6108d85f33906106d4565b610706565b6108a2565b90565b5f90565b90565b6109006108fb610905926108e9565b61069d565b610329565b90565b61091e610923916109176108e5565b505f6106d4565b610706565b61093d6109376109325f6108ec565b610329565b91610329565b141590565b61094e610953916106ea565b6104c6565b90565b6109609054610942565b90565b634e487b7160e01b5f52601160045260245ffd5b6109809061027a565b6bffffffffffffffffffffffff81146109995760010190565b610963565b906109b56bffffffffffffffffffffffff916107ed565b9181191691161790565b6109d36109ce6109d89261027a565b61069d565b61027a565b90565b90565b906109f36109ee6109fa926109bf565b6109db565b825461099e565b9055565b610a4291610a20610a1b610a3293610a14610698565b505f6106d4565b610706565b90610a2b6001610956565b9091610efd565b610a3c6001610956565b906107b7565b610a5e610a57610a526001610956565b610977565b60016109de565b90565b5f90565b90565b610a7c610a77610a8192610a65565b61069d565b6103b4565b90565b610a93610a99919392936103b4565b926103b4565b8203918211610aa457565b610963565b90610abb610ab683610128565b610113565b918252565b369037565b90610aea610ad283610aa9565b92602080610ae08693610128565b9201910390610ac0565b565b610b00610afb610b05926108e9565b61069d565b6103b4565b90565b6001610b1491016103b4565b90565b634e487b7160e01b5f52603260045260245ffd5b90610b35826101e4565b811015610b4757600160209102010190565b610b17565b60ff60f81b1690565b610b5f9051610b4c565b90565b610b71610b77919392936103b4565b926103b4565b8201809211610b8257565b610963565b60200190565b6bffffffffffffffffffffffff60a01b1690565b610bab9051610b8d565b90565b1b90565b610bcc610bc7610bc1836101e4565b92610b87565b610ba1565b90600c8110610bda575b5090565b610bfa906bffffffffffffffffffffffff60a01b90600c03600802610bae565b165f610bd6565b60a01c90565b610c13610c1891610c01565b6109bf565b90565b90610c24610698565b50610c2d610a61565b50610c4a610c3a836101e4565b610c44600c610a68565b90610a84565b610c5381610ac5565b90610c5d5f610aec565b5b80610c71610c6b846103b4565b916103b4565b1015610ca857610ca390610c8e610c89878390610b2b565b610b55565b610c9d859183905f1a92610b2b565b53610b08565b610c5e565b5092610cbc610cb7600c610a68565b610ac5565b91610cc65f610aec565b5b80610cdb610cd5600c610a68565b916103b4565b1015610d1c57610d1790610d02610cfd85610cf78a8590610b62565b90610b2b565b610b55565b610d11869183905f1a92610b2b565b53610b08565b610cc7565b50935050610d2c610d3191610bb2565b610c07565b90565b5f90565b90565b610d47610d4c91610329565b610d38565b9052565b610d5c81602093610d3b565b0190565b610da4610d81610d7c610d9593610d75610d34565b505f6106d4565b610706565b610d896100b2565b92839160208301610d50565b602082018103825203826100ea565b610db6610db0826101e4565b91610b87565b2090565b91610dd9602084610dd1610de09796600c96610d3b565b018092610787565b019061074c565b90565b90565b610dfa610df5610dff92610de3565b61069d565b61040e565b90565b610e0b90610de6565b90565b610e186067610e02565b90565b3d5f14610e3657610e2b3d610aa9565b903d5f602084013e5b565b610e3e610698565b90610e34565b91610e7e5f9392610e6f8594610e58610698565b509193610e636100b2565b94859360208501610dba565b602082018103825203826100ea565b610e86610e0e565b90602081019051915afa610ea2610e9b610e1b565b9115610466565b610ea95790565b5f63a99eec4b60e01b815280610ec16004820161036d565b0390fd5b90565b610edc610ed7610ee192610ec5565b61069d565b61040e565b90565b610eed90610ec8565b90565b610efa6066610ee4565b90565b91610f375f9392610f288594610f11610698565b509193610f1c6100b2565b94859360208501610dba565b602082018103825203826100ea565b610f3f610ef0565b90602081019051915afa610f5b610f54610e1b565b9115610466565b610f625790565b5f63a99eec4b60e01b815280610f7a6004820161036d565b0390fdfea2646970667358221220d49235db1fc2813aca0c2c613fb2406a25c06fae48bbc6f76adb97907c3ca3e164736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000005": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b610800565b61001d5f356100bc565b806346e2577a146100b75780634a8fcf9a146100b257806350f3fc81146100ad5780638a355a57146100a85780638da5cb5b146100a3578063a36250d81461009e578063ba1ab29114610099578063c41c2f2414610094578063ed03b3001461008f5763f2fde38b0361000e576107cd565b610798565b610741565b61067d565b610632565b6105da565b61058a565b610555565b61040f565b610131565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b60018060a01b031690565b6100e8906100d4565b90565b6100f4816100df565b036100fb57565b5f80fd5b9050359061010c826100eb565b565b9060208282031261012757610124915f016100ff565b90565b6100cc565b5f0190565b3461015f5761014961014436600461010e565b610b62565b6101516100c2565b8061015b8161012c565b0390f35b6100c8565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101949061016c565b810190811067ffffffffffffffff8211176101ae57604052565b610176565b906101c66101bf6100c2565b928361018a565b565b67ffffffffffffffff81116101e6576101e260209161016c565b0190565b610176565b90825f939282370152565b9092919261020b610206826101c8565b6101b3565b9381855260208501908284011161022757610225926101eb565b565b610168565b9080601f8301121561024a57816020610247933591016101f6565b90565b610164565b9060208282031261027f575f82013567ffffffffffffffff811161027a57610277920161022c565b90565b6100d0565b6100cc565b5190565b60209181520190565b60200190565b90565b6102a390610297565b9052565b906102b48160209361029a565b0190565b60200190565b906102db6102d56102ce84610284565b8093610288565b92610291565b905f5b8181106102eb5750505090565b9091926103046102fe60019286516102a7565b946102b8565b91019190916102de565b5190565b60209181520190565b60200190565b5190565b60209181520190565b90825f9392825e0152565b6103586103616020936103669361034f81610321565b93848093610325565b9586910161032e565b61016c565b0190565b9061037491610339565b90565b60200190565b9061039161038a8361030e565b8092610312565b90816103a26020830284019461031b565b925f915b8383106103b557505050505090565b909192939460206103d76103d18385600195038752895161036a565b97610377565b93019301919392906103a6565b90916103fe61040c9360408401908482035f8601526102be565b91602081840391015261037d565b90565b346104405761042761042236600461024f565b610e18565b9061043c6104336100c2565b928392836103e4565b0390f35b6100c8565b90565b61045181610445565b0361045857565b5f80fd5b9050359061046982610448565b565b9060208282031261048457610481915f0161045c565b90565b6100cc565b634e487b7160e01b5f52603260045260245ffd5b5490565b5f5260205f2090565b6104b38161049d565b8210156104cd576104c56001916104a1565b910201905f90565b610489565b1c90565b60018060a01b031690565b6104f19060086104f693026104d2565b6104d6565b90565b9061050491546104e1565b90565b60016105128161049d565b82101561052f5761052c91610526916104aa565b906104f9565b90565b5f80fd5b61053c906100df565b9052565b9190610553905f60208501940190610533565b565b346105855761058161057061056b36600461046b565b610507565b6105786100c2565b91829182610540565b0390f35b6100c8565b346105b8576105a261059d36600461010e565b61123b565b6105aa6100c2565b806105b48161012c565b0390f35b6100c8565b5f9103126105c757565b6100cc565b6105d75f5f906104f9565b90565b3461060a576105ea3660046105bd565b6106066105f56105cc565b6105fd6100c2565b91829182610540565b0390f35b6100c8565b736346d64a3f31774283b72926b75ffda9662266ce90565b61062f61060f565b90565b34610662576106423660046105bd565b61065e61064d610627565b6106556100c2565b91829182610540565b0390f35b6100c8565b60046001609c1b0190565b61067a610667565b90565b346106ad5761068d3660046105bd565b6106a9610698610672565b6106a06100c2565b91829182610540565b0390f35b6100c8565b90565b6106c96106c46106ce926100d4565b6106b2565b6100d4565b90565b6106da906106b5565b90565b6106e6906106d1565b90565b6106f96106f4610667565b6106dd565b90565b6107046106e9565b90565b610710906106b5565b90565b61071c90610707565b90565b61072890610713565b9052565b919061073f905f6020850194019061071f565b565b34610771576107513660046105bd565b61076d61075c6106fc565b6107646100c2565b9182918261072c565b0390f35b6100c8565b61077f90610445565b9052565b9190610796905f60208501940190610776565b565b346107c8576107a83660046105bd565b6107c46107b361124a565b6107bb6100c2565b91829182610783565b0390f35b6100c8565b346107fb576107e56107e036600461010e565b61131a565b6107ed6100c2565b806107f78161012c565b0390f35b6100c8565b5f80fd5b60209181520190565b5f7f4455504c49434154455f50524f56494445520000000000000000000000000000910152565b6108416012602092610804565b61084a8161080d565b0190565b6108639060208101905f818303910152610834565b90565b1561086d57565b6108756100c2565b62461bcd60e51b81528061088b6004820161084e565b0390fd5b6108bd906108b861089f82611325565b6108b26108ac5f19610445565b91610445565b14610866565b6109e1565b565b5f1c90565b6108d06108d5916108bf565b6104d6565b90565b6108e290546108c4565b90565b90565b6108fc6108f7610901926108e5565b6106b2565b6100d4565b90565b61090d906108e8565b90565b5f1b90565b9061092660018060a01b0391610910565b9181191691161790565b61093990610707565b90565b90565b9061095461094f61095b92610930565b61093c565b8254610915565b9055565b5f7f554e415554484f52495a45440000000000000000000000000000000000000000910152565b610993600c602092610804565b61099c8161095f565b0190565b6109b59060208101905f818303910152610986565b90565b156109bf57565b6109c76100c2565b62461bcd60e51b8152806109dd600482016109a0565b0390fd5b610a37906109ee5f6108d8565b610a08610a026109fd5f610904565b6100df565b916100df565b14610a39575b610a3233610a2c610a26610a215f6108d8565b6100df565b916100df565b146109b8565b610b0c565b565b610a4a610a4461060f565b5f61093f565b610a0e565b90565b5f5260205f2090565b5490565b610a6881610a5b565b821015610a8257610a7a600191610a52565b910201905f90565b610489565b1b90565b91906008610aab910291610aa560018060a01b0384610a87565b92610a87565b9181191691161790565b9190610acb610ac6610ad393610930565b61093c565b908354610a8b565b9055565b9081549168010000000000000000831015610b075782610aff916001610b0595018155610a5f565b90610ab5565b565b610176565b610b20610b196001610a4f565b8290610ad7565b610b4a7fae9c2c6481964847714ce58f65a7f6dcc41d0d8394449bacdf161b5920c4744a91610930565b90610b536100c2565b80610b5d8161012c565b0390a2565b610b6b9061088f565b565b606090565b606090565b67ffffffffffffffff8111610b8f5760208091020190565b610176565b90610ba6610ba183610b77565b6101b3565b918252565b369037565b90610bd5610bbd83610b94565b92602080610bcb8693610b77565b9201910390610bab565b565b67ffffffffffffffff8111610bef5760208091020190565b610176565b90610c06610c0183610bd7565b6101b3565b918252565b606090565b5f5b828110610c1e57505050565b602090610c29610c0b565b8184015201610c12565b90610c58610c4083610bf4565b92602080610c4e8693610bd7565b9201910390610c10565b565b610c6e610c69610c73926108e5565b6106b2565b610445565b90565b6001610c829101610445565b90565b60e01b90565b610c9481610297565b03610c9b57565b5f80fd5b90505190610cac82610c8b565b565b90602082820312610cc757610cc4915f01610c9f565b90565b6100cc565b610cd46100c2565b3d5f823e3d90fd5b90610ce682610284565b811015610cf7576020809102010190565b610489565b90610d0690610297565b9052565b90929192610d1f610d1a826101c8565b6101b3565b93818552602085019082840111610d3b57610d399261032e565b565b610168565b9080601f83011215610d5e57816020610d5b93519101610d0a565b90565b610164565b90602082820312610d93575f82015167ffffffffffffffff8111610d8e57610d8b9201610d40565b90565b6100d0565b6100cc565b60209181520190565b610dc0610dc9602093610dce93610db781610321565b93848093610d98565b9586910161032e565b61016c565b0190565b91610df592610de860408201935f830190610533565b6020818403910152610da1565b90565b90610e028261030e565b811015610e13576020809102010190565b610489565b90610e21610b6d565b50610e2a610b72565b50610e3b610e3661124a565b610bb0565b91610e4c610e4761124a565b610c33565b92610e565f610c5a565b5b80610e71610e6b610e6661124a565b610445565b91610445565b1015610fdc57610eca6020610e8c610e876106e9565b610713565b63eefbaf1890610ebf610eaa610ea4600188906104aa565b906104f9565b92610eb36100c2565b95869485938493610c85565b835260048301610540565b03915afa8015610fd757610ef2915f91610fa9575b50610eed8491849092610cdc565b610cfc565b610f02610efd6106e9565b610713565b905f63b7f5f9b792610f1f610f19600185906104aa565b906104f9565b90610f3d838896610f48610f316100c2565b98899687958694610c85565b845260048401610dd2565b03925af1918215610fa457610f7d92610f76915f91610f82575b50878391610f708383610df8565b52610df8565b5150610c76565b610e57565b610f9e91503d805f833e610f96818361018a565b810190610d63565b5f610f62565b610ccc565b610fca915060203d8111610fd0575b610fc2818361018a565b810190610cae565b5f610edf565b503d610fb8565b610ccc565b5090509190565b61103990610ff05f6108d8565b61100a611004610fff5f610904565b6100df565b916100df565b1461103b575b6110343361102e6110286110235f6108d8565b6100df565b916100df565b146109b8565b61115d565b565b61104c61104661060f565b5f61093f565b611010565b5f7f50524f56494445525f4e4f545f464f554e440000000000000000000000000000910152565b6110856012602092610804565b61108e81611051565b0190565b6110a79060208101905f818303910152611078565b90565b90565b6110c16110bc6110c6926110aa565b6106b2565b610445565b90565b634e487b7160e01b5f52601160045260245ffd5b6110ec6110f291939293610445565b92610445565b82039182116110fd57565b6110c9565b634e487b7160e01b5f52603160045260245ffd5b5f90565b61112c91611126611116565b91610ab5565b565b61113781610a5b565b801561115857600190039061115561114f8383610a5f565b9061111a565b55565b611102565b61116681611325565b8061117a6111745f19610445565b91610445565b14611219576111c5906111bf6111b76111b160016111ab61119b600161049d565b6111a560016110ad565b906110dd565b906104aa565b906104f9565b9160016104aa565b90610ab5565b6111d76111d26001610a4f565b61112e565b6112017f1589f8555933761a3cff8aa925061be3b46e2dd43f621322ab611d300f62b1d991610930565b9061120a6100c2565b806112148161012c565b0390a2565b6112216100c2565b62461bcd60e51b81528061123760048201611092565b0390fd5b61124490610fe3565b565b5f90565b611252611246565b5061125d600161049d565b90565b6112b69061126d5f6108d8565b61128761128161127c5f610904565b6100df565b916100df565b146112b8575b6112b1336112ab6112a56112a05f6108d8565b6100df565b916100df565b146109b8565b6112ce565b565b6112c96112c361060f565b5f61093f565b61128d565b6112d8815f61093f565b6113027f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616391610930565b9061130b6100c2565b806113158161012c565b0390a2565b61132390611260565b565b61132d611246565b506113375f610c5a565b5b8061135261134c61134761124a565b610445565b91610445565b10156113975761136d611367600183906104aa565b906104f9565b61137f611379846100df565b916100df565b146113925761138d90610c76565b611338565b905090565b50505f199056fea264697066735822122075752650c1eb298fcdd8aac8ecf892932d7cab4774bade6597e821b82ac2e90764736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x70997970c51812dc3a010c7d01b50e0d17dc79c8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x90f79bf6eb2c4f870365e785982e1f101e93b906": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xd412c5ecd343e264381ff15afc0ad78a67b79f35": { + "balance": "0x2000000000000000000000000000000000000000000000000000000000000000" + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0xD3C21BCECCEDA1000000" + } + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x0", + "extraData": "0x", + "gasLimit": "0x1c9c380", + "gasUsed": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0", + "number": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494", + "timestamp": "0x6490fdd2" +}
diff --git reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/headfcu.json seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/headfcu.json new file mode 100644 index 0000000000000000000000000000000000000000..d783f99363a9ea1520ee213761dda2a4e6178a07 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testdata/rpc-compat/headfcu.json @@ -0,0 +1,13 @@ +{ + "jsonrpc": "2.0", + "id": "fcu45", + "method": "engine_forkchoiceUpdatedV3", + "params": [ + { + "headBlockHash": "0xd5e69e4c67084751403c08f1bf816a42668470f292df03109769164b09cf756f", + "safeBlockHash": "0xd5e69e4c67084751403c08f1bf816a42668470f292df03109769164b09cf756f", + "finalizedBlockHash": "0xd5e69e4c67084751403c08f1bf816a42668470f292df03109769164b09cf756f" + }, + null + ] +}
diff --git reth/crates/seismic/node/tests/e2e/testsuite.rs seismic-reth/crates/seismic/node/tests/e2e/testsuite.rs new file mode 100644 index 0000000000000000000000000000000000000000..22d956f258d97f9e2cfe8e257797a60d6a73c664 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/testsuite.rs @@ -0,0 +1,36 @@ +use alloy_eips::eip2718::Encodable2718; +use alloy_primitives::{Address, U256}; +use alloy_rpc_types_eth::TransactionRequest; +use eyre::Result; +use reth_e2e_test_utils::transaction::TransactionTestContext; +use reth_seismic_node::utils::e2e::ensure_mock_purpose_keys; + +// Produces a single block on a Seismic node using the internal engine channel +// (not the JSON-RPC engine API, which loses Prague-era fields in V3 payloads). +#[tokio::test(flavor = "multi_thread")] +async fn test_seismic_produce_blocks() -> Result<()> { + reth_tracing::init_test_tracing(); + ensure_mock_purpose_keys(); + + let (mut nodes, _tasks, wallet) = reth_seismic_node::utils::e2e::setup(1).await?; + let mut node = nodes.pop().unwrap(); + + let tx = TransactionRequest { + nonce: Some(0), + value: Some(U256::from(100)), + to: Some(alloy_primitives::TxKind::Call(Address::random())), + gas: Some(21000), + max_fee_per_gas: Some(20e9 as u128), + max_priority_fee_per_gas: Some(20e9 as u128), + chain_id: Some(wallet.chain_id), + ..Default::default() + }; + let signed = TransactionTestContext::sign_tx(wallet.inner.clone(), tx).await; + let raw_tx: alloy_primitives::Bytes = signed.encoded_2718().into(); + + let tx_hash = node.rpc.inject_tx(raw_tx).await?; + let payload = node.advance_block().await?; + node.assert_new_block(tx_hash, payload.block().hash(), payload.block().number).await?; + + Ok(()) +}
diff --git reth/crates/seismic/node/tests/e2e/utils.rs seismic-reth/crates/seismic/node/tests/e2e/utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..d889067b4ca8295676fef85f50bf4109dc4f1fcf --- /dev/null +++ seismic-reth/crates/seismic/node/tests/e2e/utils.rs @@ -0,0 +1,396 @@ +use alloy_eips::{eip2930::AccessListItem, eip7702::Authorization, BlockId, BlockNumberOrTag}; +use alloy_primitives::{bytes, Address, B256, U256}; +use alloy_provider::{ + network::{ + Ethereum, EthereumWallet, NetworkWallet, TransactionBuilder, TransactionBuilder7702, + }, + Provider, ProviderBuilder, SendableTx, +}; +use alloy_rpc_types_engine::PayloadAttributes; +use alloy_rpc_types_eth::TransactionRequest; +use alloy_signer::SignerSync; +use rand::{seq::SliceRandom, Rng}; +use reth_e2e_test_utils::{wallet::Wallet, NodeHelperType, TmpDB}; +use reth_ethereum_engine_primitives::PayloadBuilderAttributes; +use reth_ethereum_primitives::TxType; +use reth_node_api::NodeTypesWithDBAdapter; +use reth_node_ethereum::EthereumNode; +use reth_provider::FullProvider; + +/// Helper function to create a new eth payload attributes +pub(crate) fn eth_payload_attributes(timestamp: u64) -> PayloadBuilderAttributes { + let attributes = PayloadAttributes { + timestamp, + prev_randao: B256::ZERO, + suggested_fee_recipient: Address::ZERO, + withdrawals: Some(vec![]), + parent_beacon_block_root: Some(B256::ZERO), + }; + PayloadBuilderAttributes::new(B256::ZERO, attributes) +} + +/// Advances node by producing blocks with random transactions. +pub(crate) async fn advance_with_random_transactions<Provider>( + node: &mut NodeHelperType<EthereumNode, Provider>, + num_blocks: usize, + rng: &mut impl Rng, + finalize: bool, +) -> eyre::Result<()> +where + Provider: FullProvider<NodeTypesWithDBAdapter<EthereumNode, TmpDB>>, +{ + let provider = ProviderBuilder::new().on_http(node.rpc_url()); + let signers = Wallet::new(1).with_chain_id(provider.get_chain_id().await?).gen(); + + // simple contract which writes to storage on any call + let dummy_bytecode = bytes!("6080604052348015600f57600080fd5b50602880601d6000396000f3fe4360a09081523360c0526040608081905260e08152902080805500fea164736f6c6343000810000a"); + let mut call_destinations = signers.iter().map(|s| s.address()).collect::<Vec<_>>(); + + for _ in 0..num_blocks { + let tx_count = rng.gen_range(1..20); + + let mut pending = vec![]; + for _ in 0..tx_count { + let signer = signers.choose(rng).unwrap(); + let tx_type = TxType::try_from(rng.gen_range(0..=4) as u64).unwrap(); + + let nonce = provider + .get_transaction_count(signer.address()) + .block_id(BlockId::Number(BlockNumberOrTag::Pending)) + .await?; + + let mut tx = + TransactionRequest::default().with_from(signer.address()).with_nonce(nonce); + + let should_create = + rng.gen::<bool>() && tx_type != TxType::Eip4844 && tx_type != TxType::Eip7702; + if should_create { + tx = tx.into_create().with_input(dummy_bytecode.clone()); + } else { + tx = tx.with_to(*call_destinations.choose(rng).unwrap()).with_input( + (0..rng.gen_range(0..10000)).map(|_| rng.gen()).collect::<Vec<u8>>(), + ); + } + + if matches!(tx_type, TxType::Legacy | TxType::Eip2930) { + tx = tx.with_gas_price(provider.get_gas_price().await?); + } + + if rng.gen::<bool>() || tx_type == TxType::Eip2930 { + tx = tx.with_access_list( + vec![AccessListItem { + address: *call_destinations.choose(rng).unwrap(), + storage_keys: (0..rng.gen_range(0..100)).map(|_| rng.gen()).collect(), + }] + .into(), + ); + } + + if tx_type == TxType::Eip7702 { + let signer = signers.choose(rng).unwrap(); + let auth = Authorization { + chain_id: U256::from(provider.get_chain_id().await?), + address: *call_destinations.choose(rng).unwrap(), + nonce: provider + .get_transaction_count(signer.address()) + .block_id(BlockId::Number(BlockNumberOrTag::Pending)) + .await?, + }; + let sig = signer.sign_hash_sync(&auth.signature_hash())?; + tx = tx.with_authorization_list(vec![auth.into_signed(sig)]) + } + + let gas = provider + .estimate_gas(tx.clone()) + .block(BlockId::Number(BlockNumberOrTag::Pending)) + .await + .unwrap_or(1_000_000); + + tx.set_gas_limit(gas); + + let SendableTx::Builder(tx) = provider.fill(tx).await? else { unreachable!() }; + let tx = + NetworkWallet::<Ethereum>::sign_request(&EthereumWallet::new(signer.clone()), tx) + .await?; + + pending.push(provider.send_tx_envelope(tx).await?); + } + + let payload = node.build_and_submit_payload().await?; + if finalize { + node.update_forkchoice(payload.block().hash(), payload.block().hash()).await?; + } else { + let last_safe = + provider.get_block_by_number(BlockNumberOrTag::Safe).await?.unwrap().header.hash; + node.update_forkchoice(last_safe, payload.block().hash()).await?; + } + + for pending in pending { + let receipt = pending.get_receipt().await?; + if let Some(address) = receipt.contract_address { + call_destinations.push(address); + } + } + } + + Ok(()) +} + +/// Test utils for the seismic rpc api +#[cfg(test)] +pub mod test_utils { + use super::*; + use crate::ext::test_address; + use alloy_consensus::{SignableTransaction, TxEnvelope, TypedTransaction}; + use alloy_dyn_abi::TypedData; + use alloy_eips::eip2718::Encodable2718; + use alloy_primitives::{ + aliases::U96, hex_literal, Address, Bytes, PrimitiveSignature, TxKind, B256, U256, + }; + use alloy_rpc_types::{ + engine::PayloadAttributes, Block, Header, Transaction, TransactionInput, TransactionReceipt, + }; + use alloy_rpc_types_eth::TransactionRequest; + use alloy_signer_local::PrivateKeySigner; + use core::str::FromStr; + use enr::EnrKey; + use jsonrpsee::http_client::HttpClient; + use jsonrpsee_core::server::Methods; + use k256::ecdsa::SigningKey; + use reth_chainspec::MAINNET; + use reth_e2e_test_utils::transaction::TransactionTestContext; + use reth_enclave::MockEnclaveServer; + use reth_network_api::noop::NoopNetwork; + use reth_payload_builder::EthPayloadBuilderAttributes; + use reth_primitives::TransactionSigned; + use reth_provider::StateProviderFactory; + use reth_rpc::EthApi; + use reth_rpc_builder::{ + RpcModuleSelection, RpcServerConfig, RpcServerHandle, TransportRpcModuleConfig, + }; + use reth_rpc_eth_api::EthApiClient; + use reth_seismic_chainspec::SEISMIC_DEV; + use reth_seismic_primitives::{SeismicPrimitives, SeismicTransactionSigned}; + use reth_transaction_pool::test_utils::TestPool; + use secp256k1::{PublicKey, SecretKey}; + use seismic_alloy_consensus::{ + SeismicTxEnvelope::Seismic, SeismicTypedTransaction, TxSeismic, TxSeismicElements, + TypedDataRequest, + }; + use seismic_alloy_rpc_types::SeismicTransactionRequest; + use serde_json::Value; + use std::{path::PathBuf, process::Stdio, sync::Arc}; + use tokio::{ + io::{AsyncBufReadExt, AsyncWriteExt, BufReader}, + process::Command, + sync::mpsc, + }; + // use reth_seismic_evm::engine::SeismicEngineValidator; + + /// Get the nonce from the client + pub async fn get_nonce(client: &HttpClient, address: Address) -> u64 { + let nonce = + EthApiClient::<Transaction, Block, TransactionReceipt, Header>::transaction_count( + client, address, None, + ) + .await + .unwrap(); + nonce.wrapping_to::<u64>() + } + + /// Get an unsigned seismic transaction request + pub async fn get_unsigned_seismic_tx_request( + sk_wallet: &PrivateKeySigner, + nonce: u64, + to: TxKind, + chain_id: u64, + plaintext: Bytes, + ) -> SeismicTransactionRequest { + SeismicTransactionRequest { + inner: TransactionRequest { + from: Some(sk_wallet.address()), + nonce: Some(nonce), + value: Some(U256::from(0)), + to: Some(to), + gas: Some(6000000), + gas_price: Some(20e9 as u128), + chain_id: Some(chain_id), + input: TransactionInput { input: Some(client_encrypt(&plaintext)), data: None }, + transaction_type: Some(TxSeismic::TX_TYPE), + ..Default::default() + }, + seismic_elements: Some(get_seismic_elements()), + } + } + + // /// Create a seismic transaction + // pub async fn get_signed_seismic_tx_bytes( + // sk_wallet: &PrivateKeySigner, + // nonce: u64, + // to: TxKind, + // chain_id: u64, + // plaintext: Bytes, + // ) -> Bytes { + // let mut tx = get_unsigned_seismic_tx_request(sk_wallet, nonce, to, chain_id, + // plaintext).await; let signed_inner = + // TransactionTestContext::sign_tx(sk_wallet.clone(), tx.inner).await; tx.inner = + // signed_inner.into(); <TxEnvelope as Encodable2718>::encoded_2718(&tx).into() + // } + + // /// Get an unsigned seismic transaction typed data + // pub async fn get_unsigned_seismic_tx_typed_data( + // sk_wallet: &PrivateKeySigner, + // nonce: u64, + // to: TxKind, + // chain_id: u64, + // decrypted_input: Bytes, + // ) -> TypedData { + // let tx_request = + // get_unsigned_seismic_tx_request(sk_wallet, nonce, to, chain_id, + // decrypted_input).await; let typed_tx = + // tx_request.inner.build_consensus_tx().unwrap(); match typed_tx { + // SeismicTypedTransaction::Seismic(seismic) => seismic.eip712_to_type_data(), + // _ => panic!("Typed transaction is not a seismic transaction"), + // } + // } + + // /// Create a seismic transaction with typed data + // pub async fn get_signed_seismic_tx_typed_data( + // sk_wallet: &PrivateKeySigner, + // nonce: u64, + // to: TxKind, + // chain_id: u64, + // plaintext: Bytes, + // ) -> TypedDataRequest { + // let mut tx: SeismicTransactionRequest = get_unsigned_seismic_tx_request(sk_wallet, nonce, + // to, chain_id, plaintext).await; tx.seismic_elements.unwrap().message_version = 2; + // let signed_inner = TransactionTestContext::sign_tx(sk_wallet.clone(), tx.inner).await; + + // tx.inner = signed_inner.into(); + // tx + + // // let tx = get_unsigned_seismic_tx_request(sk_wallet, nonce, to, chain_id, + // plaintext).await; // tx.seismic_elements.unwrap().message_version = 2; + // // let signed = TransactionTestContext::sign_tx(sk_wallet.clone(), tx).await; + + // // match signed { + // // Seismic(tx) => tx.into(), + // // _ => panic!("Signed transaction is not a seismic transaction"), + // // } + // } + + /// Get the network public key + pub fn get_network_public_key() -> PublicKey { + MockEnclaveServer::get_public_key() + } + + /// Encrypt plaintext using network public key and client private key + pub fn get_ciphertext() -> Bytes { + let encrypted_data = client_encrypt(&get_plaintext()); + encrypted_data + } + + /// Encrypt plaintext using network public key and client private key + pub fn client_encrypt(plaintext: &Bytes) -> Bytes { + get_seismic_elements() + .client_encrypt(plaintext, &get_network_public_key(), &get_encryption_private_key()) + .unwrap() + } + + /// Decrypt ciphertext using network public key and client private key + pub fn client_decrypt(ciphertext: &Bytes) -> Bytes { + get_seismic_elements() + .client_decrypt(ciphertext, &get_network_public_key(), &get_encryption_private_key()) + .unwrap() + } + + /// Get the encryption private key + pub fn get_encryption_private_key() -> SecretKey { + let private_key_bytes = + hex_literal::hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + SecretKey::from_slice(&private_key_bytes).expect("Invalid private key") + } + + /// Get the encryption nonce + pub fn get_encryption_nonce() -> U96 { + U96::MAX + } + + /// Get the seismic elements + pub fn get_seismic_elements() -> TxSeismicElements { + TxSeismicElements { + encryption_pubkey: get_encryption_private_key().public(), + encryption_nonce: get_encryption_nonce(), + message_version: 0, + } + } + + /// Get a wrong private key + pub fn get_wrong_private_key() -> SecretKey { + let private_key_bytes = + hex_literal::hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1e"); + SecretKey::from_slice(&private_key_bytes).expect("Invalid private key") + } + + /// Get the signing private key + pub fn get_signing_private_key() -> SigningKey { + let private_key_bytes = + hex_literal::hex!("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"); + let signing_key = + SigningKey::from_bytes(&private_key_bytes.into()).expect("Invalid private key"); + signing_key + } + + /// Get the plaintext for a seismic transaction + pub fn get_plaintext() -> Bytes { + Bytes::from_str("24a7f0b7000000000000000000000000000000000000000000000000000000000000000b") + .unwrap() + } + + /// Get a seismic transaction + pub fn get_seismic_tx() -> TxSeismic { + let ciphertext = get_ciphertext(); + TxSeismic { + chain_id: 1337, + nonce: 1, + gas_price: 20000000000, + gas_limit: 210000, + to: alloy_primitives::TxKind::Call( + Address::from_str("0x5fbdb2315678afecb367f032d93f642f64180aa3").unwrap(), + ), + value: U256::ZERO, + input: Bytes::copy_from_slice(&ciphertext), + seismic_elements: get_seismic_elements(), + authorization_list: vec![], + } + } + + /// Get the encoding of a signed seismic transaction + pub fn get_signed_seismic_tx_encoding() -> Vec<u8> { + let signed_tx = get_signed_seismic_tx(B256::ZERO); + let mut encoding = Vec::new(); + + signed_tx.encode_2718(&mut encoding); + encoding + } + + /// Sign a seismic transaction + pub fn sign_seismic_tx(tx: &TxSeismic) -> PrimitiveSignature { + let _signature = get_signing_private_key() + .clone() + .sign_prehash_recoverable(tx.signature_hash().as_slice()) + .expect("Failed to sign"); + + let recoverid = _signature.1; + let _signature = _signature.0; + + let signature = PrimitiveSignature::new( + U256::from_be_slice(_signature.r().to_bytes().as_slice()), + U256::from_be_slice(_signature.s().to_bytes().as_slice()), + recoverid.is_y_odd(), + ); + + signature + } + +}
diff --git reth/crates/seismic/node/tests/it/builder.rs seismic-reth/crates/seismic/node/tests/it/builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..69d048636fc9ed4ccde03817ca1862bdebea7f05 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/it/builder.rs @@ -0,0 +1,37 @@ +//! Node builder setup tests. + +use reth_db::test_utils::create_test_rw_db; +use reth_node_api::{FullNodeComponents, NodeTypesWithDBAdapter}; +use reth_node_builder::{Node, NodeBuilder, NodeConfig}; +use reth_provider::providers::BlockchainProvider; +use reth_seismic_chainspec::SEISMIC_MAINNET; +use reth_seismic_node::node::SeismicNode; + +#[test] +fn test_basic_setup() { + // parse CLI -> config + let config = NodeConfig::new(SEISMIC_MAINNET.clone()); + let db = create_test_rw_db(); + let seismic_node = SeismicNode::default(); + let _builder = NodeBuilder::new(config) + .with_database(db) + .with_types_and_provider::<SeismicNode, BlockchainProvider<NodeTypesWithDBAdapter<SeismicNode, _>>>() + .with_components(seismic_node.components()) + .with_add_ons(seismic_node.add_ons()) + .on_component_initialized(move |ctx| { + let _provider = ctx.provider(); + Ok(()) + }) + .on_node_started(|_full_node| Ok(())) + .on_rpc_started(|_ctx, handles| { + let _client = handles.rpc.http_client(); + Ok(()) + }) + .extend_rpc_modules(|ctx| { + let _ = ctx.config(); + let _ = ctx.node().provider(); + + Ok(()) + }) + .check_launch(); +}
diff --git reth/crates/seismic/node/tests/it/exex.rs seismic-reth/crates/seismic/node/tests/it/exex.rs new file mode 100644 index 0000000000000000000000000000000000000000..856220300c2bb0a79a8a717e77a389e4ef85f595 --- /dev/null +++ seismic-reth/crates/seismic/node/tests/it/exex.rs @@ -0,0 +1,39 @@ +use futures::future; +use reth_db::test_utils::create_test_rw_db; +use reth_exex::ExExContext; +use reth_node_api::FullNodeComponents; +use reth_node_builder::{NodeBuilder, NodeConfig}; +use reth_node_ethereum::{node::EthereumAddOns, EthereumNode}; +use std::{ + future::Future, + pin::Pin, + task::{Context, Poll}, +}; + +struct DummyExEx<Node: FullNodeComponents> { + _ctx: ExExContext<Node>, +} + +impl<Node> Future for DummyExEx<Node> +where + Node: FullNodeComponents, +{ + type Output = eyre::Result<()>; + + fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> { + Poll::Pending + } +} + +#[test] +fn basic_exex() { + let config = NodeConfig::test(); + let db = create_test_rw_db(); + let _builder = NodeBuilder::new(config) + .with_database(db) + .with_types::<EthereumNode>() + .with_components(EthereumNode::components()) + .with_add_ons(EthereumAddOns::default()) + .install_exex("dummy", move |ctx| future::ok(DummyExEx { _ctx: ctx })) + .check_launch(); +}
diff --git reth/crates/seismic/node/tests/it/main.rs seismic-reth/crates/seismic/node/tests/it/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..0f85adda31d0847f57e5047648129f97e62cfbbc --- /dev/null +++ seismic-reth/crates/seismic/node/tests/it/main.rs @@ -0,0 +1,6 @@ +#![allow(missing_docs)] + +mod builder; +mod exex; + +const fn main() {}
diff --git reth/crates/seismic/rpc/Cargo.toml seismic-reth/crates/seismic/rpc/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..32e58d4500f5b7e20016aae7bf0ece31db3150a2 --- /dev/null +++ seismic-reth/crates/seismic/rpc/Cargo.toml @@ -0,0 +1,106 @@ +[package] +name = "reth-seismic-rpc" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "Ethereum RPC implementation for seismic." + +[lints] +workspace = true + +[dependencies] + +# alloy +alloy-eips.workspace = true +alloy-primitives.workspace = true +alloy-rpc-types.workspace = true +alloy-rpc-types-eth.workspace = true +alloy-consensus.workspace = true +alloy-json-rpc.workspace = true +alloy-dyn-abi.workspace = true +alloy-sol-types.workspace = true + +# reth +reth-evm.workspace = true +reth-node-api.workspace = true +reth-node-builder.workspace = true +reth-primitives.workspace = true +reth-primitives-traits.workspace = true +reth-provider.workspace = true +reth-rpc.workspace = true +reth-rpc-convert.workspace = true +reth-rpc-eth-api.workspace = true +reth-rpc-eth-types.workspace = true +reth-rpc-layer.workspace = true +reth-rpc-server-types.workspace = true +reth-storage-api.workspace = true +reth-tasks = { workspace = true, features = ["rayon"] } +reth-tracing.workspace = true +reth-transaction-pool.workspace = true + +# revm +revm.workspace = true +revm-context.workspace = true + +# seismic-reth +reth-seismic-primitives = { workspace = true, features = [ + "reth-codec", + "serde-bincode-compat", +] } +seismic-enclave.workspace = true + +seismic-alloy-consensus.workspace = true +seismic-alloy-network.workspace = true +seismic-alloy-rpc-types = { workspace = true, features = ["serde", "k256"] } +reth-seismic-txpool.workspace = true +seismic-revm.workspace = true + +# async +tokio.workspace = true + +# rpc +jsonrpsee-types.workspace = true +jsonrpsee.workspace = true +futures.workspace = true + +# misc +eyre.workspace = true +serde.workspace = true +thiserror.workspace = true +tracing.workspace = true + +[dev-dependencies] +reth-seismic-chainspec.workspace = true +reth-consensus.workspace = true +reth-evm-ethereum.workspace = true +reth-ethereum-engine-primitives.workspace = true +reth-rpc-builder.workspace = true +reth-rpc-layer.workspace = true +reth-payload-builder.workspace = true +secp256k1.workspace = true +enr.workspace = true +k256.workspace = true +alloy-signer-local.workspace = true +reth-e2e-test-utils.workspace = true +reth-engine-primitives.workspace = true +reth-node-ethereum.workspace = true +reth-seismic-evm.workspace = true +reth-rpc-engine-api.workspace = true +alloy-rpc-types-engine.workspace = true + +[features] +default = ["client"] +timestamp-in-seconds = [ + "revm/timestamp-in-seconds", + "seismic-revm/timestamp-in-seconds", + "reth-seismic-primitives/timestamp-in-seconds", + "reth-seismic-chainspec/timestamp-in-seconds", +] +client = [ + "jsonrpsee/client", + "jsonrpsee/async-client", + "reth-rpc-eth-api/client", +]
diff --git reth/crates/seismic/rpc/src/error.rs seismic-reth/crates/seismic/rpc/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..063974a4ab97e9ea522f331fbf25c87c1ddcd4d3 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/error.rs @@ -0,0 +1,106 @@ +//! Error types for the seismic rpc api. + +use std::convert::Infallible; + +use alloy_rpc_types_eth::BlockError; +use reth_provider::ProviderError; +use reth_rpc_eth_api::{AsEthApiError, EthTxEnvError, TransactionConversionError}; +use reth_rpc_eth_types::{error::api::FromEvmHalt, EthApiError}; +use reth_rpc_server_types::result::internal_rpc_err; +use revm::context_interface::result::EVMError; +use revm_context::result::HaltReason; + +#[derive(Debug, thiserror::Error)] +/// Seismic API error +pub enum SeismicEthApiError { + /// Eth error + #[error(transparent)] + Eth(#[from] EthApiError), + /// Enclave error + #[error("enclave error: {0}")] + EnclaveError(String), +} + +impl AsEthApiError for SeismicEthApiError { + fn as_err(&self) -> Option<&EthApiError> { + match self { + Self::Eth(err) => Some(err), + _ => None, + } + } +} + +impl From<SeismicEthApiError> for jsonrpsee::types::error::ErrorObject<'static> { + fn from(error: SeismicEthApiError) -> Self { + match error { + SeismicEthApiError::Eth(e) => e.into(), + SeismicEthApiError::EnclaveError(e) => internal_rpc_err(format!("enclave error: {e}")), + } + } +} + +impl From<TransactionConversionError> for SeismicEthApiError { + fn from(value: TransactionConversionError) -> Self { + Self::Eth(EthApiError::from(value)) + } +} + +impl From<EthTxEnvError> for SeismicEthApiError { + fn from(value: EthTxEnvError) -> Self { + Self::Eth(EthApiError::from(value)) + } +} + +impl From<ProviderError> for SeismicEthApiError { + fn from(value: ProviderError) -> Self { + Self::Eth(EthApiError::from(value)) + } +} + +impl From<BlockError> for SeismicEthApiError { + fn from(value: BlockError) -> Self { + Self::Eth(EthApiError::from(value)) + } +} + +impl From<Infallible> for SeismicEthApiError { + fn from(value: Infallible) -> Self { + match value {} + } +} + +impl From<EVMError<ProviderError>> for SeismicEthApiError { + fn from(error: EVMError<ProviderError>) -> Self { + Self::Eth(EthApiError::from(error)) + } +} + +// Implementation for revm halt reason (base case) +impl From<HaltReason> for SeismicEthApiError { + fn from(halt: HaltReason) -> Self { + Self::Eth(EthApiError::other(internal_rpc_err(format!("EVM halted: {halt:?}")))) + } +} + +// FromEvmHalt implementation for base revm halt reason +impl FromEvmHalt<HaltReason> for SeismicEthApiError { + fn from_evm_halt(halt: HaltReason, gas_limit: u64) -> Self { + // Delegate to the existing From implementation for the halt reason + // and use the gas limit info if needed + Self::Eth(EthApiError::other(internal_rpc_err(format!( + "EVM halted: {halt:?} (gas limit: {gas_limit})" + )))) + } +} + +#[cfg(test)] +mod tests { + use crate::error::SeismicEthApiError; + + #[test] + fn enclave_error_message() { + let err: jsonrpsee::types::error::ErrorObject<'static> = + SeismicEthApiError::EnclaveError("test".to_string()).into(); + assert_eq!(err.message(), "enclave error: test"); + } +}
diff --git reth/crates/seismic/rpc/src/eth/api.rs seismic-reth/crates/seismic/rpc/src/eth/api.rs new file mode 100644 index 0000000000000000000000000000000000000000..8034a505b946c53261bb40d7ae1ccfea3aa27ec5 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/api.rs @@ -0,0 +1,37 @@ +//! Seismic extension of API traits + +use reth_rpc_eth_api::{ + helpers::{EthApiSpec, EthBlocks, EthCall, EthFees, EthState, LoadReceipt, Trace}, + FullEthApiTypes, +}; + +use super::ext::SeismicTransaction; + +/// Helper trait to unify all `eth` rpc server building block traits, for simplicity. +/// +/// This trait is automatically implemented for any type that implements all the `Eth` traits. +pub trait FullSeismicApi: + FullEthApiTypes + + EthApiSpec + + SeismicTransaction + + EthBlocks + + EthState + + EthCall + + EthFees + + Trace + + LoadReceipt +{ +} + +impl<T> FullSeismicApi for T where + T: FullEthApiTypes + + EthApiSpec + + SeismicTransaction + + EthBlocks + + EthState + + EthCall + + EthFees + + Trace + + LoadReceipt +{ +}
diff --git reth/crates/seismic/rpc/src/eth/block.rs seismic-reth/crates/seismic/rpc/src/eth/block.rs new file mode 100644 index 0000000000000000000000000000000000000000..d926a9113b29fa235db4ea7fd1b5ab70b6d3a092 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/block.rs @@ -0,0 +1,23 @@ +//! Loads and formats Seismic block RPC response. + +use crate::{SeismicEthApi, SeismicEthApiError}; +use reth_rpc_eth_api::{ + helpers::{EthBlocks, LoadBlock}, + FromEvmError, RpcConvert, RpcNodeCore, +}; + +impl<N, Rpc> EthBlocks for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ +} + +impl<N, Rpc> LoadBlock for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ +}
diff --git reth/crates/seismic/rpc/src/eth/call.rs seismic-reth/crates/seismic/rpc/src/eth/call.rs new file mode 100644 index 0000000000000000000000000000000000000000..05f54370539f9a0ae54225923e7bb97971c007f3 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/call.rs @@ -0,0 +1,180 @@ +use crate::{SeismicEthApi, SeismicEthApiError}; +use alloy_consensus::transaction::Either; +use alloy_eips::eip7702::{RecoveredAuthorization, SignedAuthorization}; +use alloy_primitives::{TxKind, U256}; +use alloy_rpc_types_eth::transaction::TransactionRequest; +use reth_evm::{EvmEnv, SpecFor, TxEnvFor}; +use reth_rpc_eth_api::{ + helpers::{estimate::EstimateCall, Call, EthCall}, + CallFees, EthTxEnvError, FromEthApiError, FromEvmError, IntoEthApiError, RpcConvert, + RpcNodeCore, RpcTxReq, +}; +use reth_rpc_eth_types::{EthApiError, RpcInvalidTransactionError}; +use revm::{context::TxEnv, context_interface::Block, Database}; +use seismic_alloy_consensus::SeismicTxType; +use seismic_revm::{self, SeismicTransaction}; + +impl<N, Rpc> EthCall for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + TxEnvFor<N::Evm>: From<SeismicTransaction<TxEnv>>, + SeismicTransaction<TxEnv>: Into<TxEnvFor<N::Evm>>, + Rpc: RpcConvert< + Primitives = N::Primitives, + Error = SeismicEthApiError, + TxEnv = TxEnvFor<N::Evm>, + Spec = SpecFor<N::Evm>, + >, +{ +} + +impl<N, Rpc> EstimateCall for SeismicEthApi<N, Rpc> +where + Self: Call, + Self::Error: From<EthApiError>, + N: RpcNodeCore, + Rpc: RpcConvert< + Primitives = N::Primitives, + Error = SeismicEthApiError, + TxEnv = TxEnvFor<N::Evm>, + Spec = SpecFor<N::Evm>, + >, +{ +} + +impl<N, Rpc> Call for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + TxEnvFor<N::Evm>: From<SeismicTransaction<TxEnv>>, + SeismicTransaction<TxEnv>: Into<TxEnvFor<N::Evm>>, + Rpc: RpcConvert< + Primitives = N::Primitives, + Error = SeismicEthApiError, + TxEnv = TxEnvFor<N::Evm>, + Spec = SpecFor<N::Evm>, + >, +{ + #[inline] + fn call_gas_limit(&self) -> u64 { + self.inner.gas_cap() + } + + #[inline] + fn max_simulate_blocks(&self) -> u64 { + self.inner.max_simulate_blocks() + } + + fn create_txn_env( + &self, + evm_env: &EvmEnv<SpecFor<Self::Evm>>, + request: RpcTxReq<Rpc::Network>, + mut db: impl Database<Error: Into<EthApiError>>, + ) -> Result<TxEnvFor<N::Evm>, Self::Error> { + // Convert network request to concrete TransactionRequest + let request: &TransactionRequest = request.as_ref(); + + // Ensure that if versioned hashes are set, they're not empty + if request.blob_versioned_hashes.as_ref().is_some_and(|hashes| hashes.is_empty()) { + return Err(RpcInvalidTransactionError::BlobTransactionMissingBlobHashes.into_eth_err()); + } + + let tx_type = if request.authorization_list.is_some() { + SeismicTxType::Eip7702 + } else if request.max_fee_per_gas.is_some() || request.max_priority_fee_per_gas.is_some() { + SeismicTxType::Eip1559 + } else if request.access_list.is_some() { + SeismicTxType::Eip2930 + } else { + SeismicTxType::Seismic + } as u8; + + let TransactionRequest { + from, + to, + gas_price, + max_fee_per_gas, + max_priority_fee_per_gas, + gas, + value, + input, + nonce, + access_list, + chain_id, + blob_versioned_hashes, + max_fee_per_blob_gas, + authorization_list, + transaction_type: _, + sidecar: _, + } = request; + + let CallFees { max_priority_fee_per_gas, gas_price, max_fee_per_blob_gas } = + CallFees::ensure_fees( + gas_price.map(U256::from), + max_fee_per_gas.map(U256::from), + max_priority_fee_per_gas.map(U256::from), + U256::from(evm_env.block_env.basefee), + blob_versioned_hashes.as_deref(), + max_fee_per_blob_gas.map(U256::from), + evm_env.block_env.blob_gasprice().map(U256::from), + ) + .map_err(EthTxEnvError::CallFees)?; + + let gas_limit = gas.unwrap_or( + // Use maximum allowed gas limit. The reason for this + // is that both Erigon and Geth use pre-configured gas cap even if + // it's possible to derive the gas limit from the block: + // <https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/cmd/rpcdaemon/commands/trace_adhoc.go#L956 + // https://github.com/ledgerwatch/erigon/blob/eae2d9a79cb70dbe30b3a6b79c436872e4605458/eth/ethconfig/config.go#L94> + evm_env.block_env.gas_limit, + ); + + let chain_id = chain_id.unwrap_or(evm_env.cfg_env.chain_id); + + let caller = from.unwrap_or_default(); + + let nonce = if let Some(nonce) = nonce { + *nonce + } else { + db.basic(caller).map_err(Into::into)?.map(|acc| acc.nonce).unwrap_or_default() + }; + + let authorization_list: Vec<Either<SignedAuthorization, RecoveredAuthorization>> = + authorization_list + .clone() + .unwrap_or_default() + .iter() + .map(|auth| Either::Left(auth.clone())) + .collect(); + let env = TxEnv { + tx_type, + gas_limit, + nonce, + caller, + gas_price: gas_price.saturating_to(), + gas_priority_fee: max_priority_fee_per_gas.map(|v| v.saturating_to()), + kind: to.unwrap_or(TxKind::Create), + value: value.unwrap_or_default(), + data: input + .clone() + .try_into_unique_input() + .map_err(Self::Error::from_eth_err)? + .unwrap_or_default(), + chain_id: Some(chain_id), + access_list: access_list.clone().unwrap_or_default(), + // EIP-4844 fields + blob_hashes: blob_versioned_hashes.clone().unwrap_or_default(), + max_fee_per_blob_gas: max_fee_per_blob_gas + .map(|v| v.saturating_to()) + .unwrap_or_default(), + // EIP-7702 fields + authorization_list, + }; + + tracing::debug!("reth-seismic-rpc::eth create_txn_env {:?}", env); + + Ok(SeismicTransaction { base: env, tx_hash: Default::default(), decryption_failed: false } + .into()) + } +}
diff --git reth/crates/seismic/rpc/src/eth/ext.rs seismic-reth/crates/seismic/rpc/src/eth/ext.rs new file mode 100644 index 0000000000000000000000000000000000000000..959f5d543d873bb87afed453da85632a3a2138ec --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/ext.rs @@ -0,0 +1,353 @@ +//! seismic implementation of eth api and its extensions +//! +//! Overrides the eth_ namespace to be compatible with seismic specific types +//! Most endpoints handle transaction decrytpion before passing to the inner eth api +//! For `eth_sendRawTransaction`, we directly call the inner eth api without decryption +//! See that function's docs for more details + +use super::api::FullSeismicApi; +use crate::utils::{ + convert_seismic_call_to_tx_request, parse_request_sender, signed_read_to_plaintext_tx, +}; +use alloy_dyn_abi::TypedData; +use alloy_json_rpc::RpcObject; +use alloy_primitives::{Address, Bytes, B256, U256}; +use alloy_rpc_types::{ + state::{EvmOverrides, StateOverride}, + BlockId, BlockOverrides, TransactionRequest, +}; +use alloy_rpc_types_eth::simulate::{ + SimBlock as EthSimBlock, SimulatePayload as EthSimulatePayload, SimulatedBlock, +}; +use futures::Future; +use jsonrpsee::{ + core::{async_trait, RpcResult}, + proc_macros::rpc, +}; +use reth_rpc_eth_api::{ + helpers::{EthCall, EthTransactions}, + RpcBlock, RpcTypes, +}; +use reth_rpc_eth_types::EthApiError; +use reth_tracing::tracing::*; +use seismic_alloy_consensus::{InputDecryptionElements, TxSeismicMetadata, TypedDataRequest}; +use seismic_alloy_rpc_types::{ + SeismicCallRequest, SeismicRawTxRequest, SeismicTransactionRequest, + SimBlock as SeismicSimBlock, SimulatePayload as SeismicSimulatePayload, +}; +use seismic_enclave::{secp256k1::PublicKey, GetPurposeKeysResponse}; +use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; + +/// trait interface for a custom rpc namespace: `seismic` +/// +/// This defines an additional namespace where all methods are configured as trait functions. +#[cfg_attr(not(feature = "client"), rpc(server, namespace = "seismic"))] +#[cfg_attr(feature = "client", rpc(server, client, namespace = "seismic"))] +pub trait SeismicApi { + /// Returns the network public key + #[method(name = "getTeePublicKey")] + async fn get_tee_public_key(&self) -> RpcResult<PublicKey>; +} + +/// Implementation of the seismic rpc api +#[derive(Debug, Clone)] +pub struct SeismicApi { + purpose_keys: GetPurposeKeysResponse, +} + +impl SeismicApi { + /// Creates a new seismic api instance + pub const fn new(purpose_keys: GetPurposeKeysResponse) -> Self { + Self { purpose_keys } + } +} + +#[async_trait] +impl SeismicApiServer for SeismicApi { + async fn get_tee_public_key(&self) -> RpcResult<PublicKey> { + trace!(target: "rpc::seismic", "Serving seismic_getTeePublicKey"); + Ok(self.purpose_keys.tx_io_pk) + } +} + +/// Localhost with port 0 so a free port is used. +pub const fn test_address() -> SocketAddr { + SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSPECIFIED, 0)) +} + +/// Extension trait for `EthTransactions` to add custom transaction sending functionalities. +pub trait SeismicTransaction: EthTransactions { + /// Decodes, signs (if necessary via an internal signer or enclave), + /// and submits a typed data transaction to the pool. + /// Returns the hash of the transaction. + fn send_typed_data_transaction( + &self, + tx_request: TypedDataRequest, + ) -> impl Future<Output = Result<B256, Self::Error>> + Send; +} + +/// Seismic `eth_` RPC namespace overrides. +#[cfg_attr(not(feature = "client"), rpc(server, namespace = "eth"))] +#[cfg_attr(feature = "client", rpc(server, client, namespace = "eth"))] +pub trait EthApiOverride<B: RpcObject> { + /// Returns the account and storage values of the specified account including the Merkle-proof. + /// This call can be used to verify that the data you are pulling from is not tampered with. + #[method(name = "signTypedData_v4")] + async fn sign_typed_data_v4(&self, address: Address, data: TypedData) -> RpcResult<String>; + + /// `eth_simulateV1` executes an arbitrary number of transactions on top of the requested state. + /// The transactions are packed into individual blocks. Overrides can be provided. + #[method(name = "simulateV1")] + async fn simulate_v1( + &self, + opts: SeismicSimulatePayload<SeismicCallRequest>, + block_number: Option<BlockId>, + ) -> RpcResult<Vec<SimulatedBlock<B>>>; + + /// Executes a new message call immediately without creating a transaction on the block chain. + #[method(name = "call")] + async fn call( + &self, + request: SeismicCallRequest, + block_number: Option<BlockId>, + state_overrides: Option<StateOverride>, + block_overrides: Option<Box<BlockOverrides>>, + ) -> RpcResult<Bytes>; + + /// Sends signed transaction, returning its hash. + #[method(name = "sendRawTransaction")] + async fn send_raw_transaction(&self, bytes: SeismicRawTxRequest) -> RpcResult<B256>; + + /// Generates and returns an estimate of how much gas is necessary to allow the transaction to + /// complete. + #[method(name = "estimateGas")] + async fn estimate_gas( + &self, + request: SeismicCallRequest, + block_number: Option<BlockId>, + state_override: Option<StateOverride>, + ) -> RpcResult<U256>; +} + +/// Implementation of the `eth_` namespace override +#[derive(Debug, Clone)] +pub struct EthApiExt<Eth> { + eth_api: Eth, + purpose_keys: GetPurposeKeysResponse, +} + +impl<Eth> EthApiExt<Eth> { + /// Create a new `EthApiExt` module. + pub const fn new(eth_api: Eth, purpose_keys: GetPurposeKeysResponse) -> Self { + Self { eth_api, purpose_keys } + } + + /// Build transaction metadata for encryption/decryption. + /// Returns an error if required fields are missing. + fn build_metadata( + request: &SeismicTransactionRequest, + sender: Address, + ) -> Result<TxSeismicMetadata, EthApiError> { + request.metadata(sender).map_err(|e| { + EthApiError::Other(Box::new(jsonrpsee_types::ErrorObject::owned( + -32602, + format!("Failed to build seismic metadata: {}", e), + None::<String>, + ))) + }) + } +} + +#[async_trait] +impl<Eth> EthApiOverrideServer<RpcBlock<Eth::NetworkTypes>> for EthApiExt<Eth> +where + Eth: FullSeismicApi + Send + Sync + 'static, + Eth::Error: Send + Sync + 'static, + jsonrpsee_types::error::ErrorObject<'static>: From<Eth::Error>, + <Eth::NetworkTypes as RpcTypes>::TransactionRequest: + From<TransactionRequest> + AsRef<TransactionRequest> + Send + Sync + 'static, +{ + /// Handler for: `eth_signTypedData_v4` + /// + /// TODO: determine if this should be removed, seems the same as eth functionality + async fn sign_typed_data_v4(&self, from: Address, data: TypedData) -> RpcResult<String> { + debug!(target: "reth-seismic-rpc::eth", "Serving seismic eth_signTypedData_v4 extension"); + let signature = EthTransactions::sign_typed_data(&self.eth_api, &data, from) + .map_err(|err| err.into())?; + let signature = alloy_primitives::hex::encode(signature); + Ok(format!("0x{signature}")) + } + + /// Handler for: `eth_simulateV1` + async fn simulate_v1( + &self, + payload: SeismicSimulatePayload<SeismicCallRequest>, + block_number: Option<BlockId>, + ) -> RpcResult<Vec<SimulatedBlock<RpcBlock<Eth::NetworkTypes>>>> { + debug!(target: "reth-seismic-rpc::eth", "Serving seismic eth_simulateV1 extension"); + + let seismic_sim_blocks: Vec<SeismicSimBlock<SeismicCallRequest>> = + payload.block_state_calls.clone(); + + // Recover EthSimBlocks from the SeismicSimulatePayload<SeismicCallRequest> + let mut eth_simulated_blocks: Vec< + EthSimBlock<<Eth::NetworkTypes as RpcTypes>::TransactionRequest>, + > = Vec::with_capacity(payload.block_state_calls.len()); + for block in payload.block_state_calls { + let SeismicSimBlock { block_overrides, state_overrides, calls } = block; + let mut prepared_calls = Vec::with_capacity(calls.len()); + + for call in calls { + let tx_req = convert_seismic_call_to_tx_request(call)?; + let plaintext_tx_req = + signed_read_to_plaintext_tx(tx_req, &self.purpose_keys.tx_io_sk)?; + let tx_request: TransactionRequest = plaintext_tx_req.inner; + prepared_calls.push(tx_request.into()); + } + + let prepared_block = + EthSimBlock { block_overrides, state_overrides, calls: prepared_calls }; + + eth_simulated_blocks.push(prepared_block); + } + + // Call Eth simulate_v1, which only takes EthSimPayload/EthSimBlock + let mut result = EthCall::simulate_v1( + &self.eth_api, + EthSimulatePayload { + block_state_calls: eth_simulated_blocks.clone(), + trace_transfers: payload.trace_transfers, + validation: payload.validation, + return_full_transactions: payload.return_full_transactions, + }, + block_number, + ) + .await?; + + // Convert Eth Blocks back to Seismic blocks + for (block, result) in seismic_sim_blocks.iter().zip(result.iter_mut()) { + let SeismicSimBlock::<SeismicCallRequest> { calls, .. } = block; + let SimulatedBlock { calls: call_results, .. } = result; + + for (call_result, call) in call_results.iter_mut().zip(calls.iter()) { + let (seismic_tx_request, signed_read) = + convert_seismic_call_to_tx_request(call.clone())?; + if signed_read { + // if there are seismic elements, encrypt the output + let sender = parse_request_sender(&seismic_tx_request)?; + let metadata = Self::build_metadata(&seismic_tx_request, sender)?; + let encrypted_output = metadata + .encrypt(&self.purpose_keys.tx_io_sk, &call_result.return_data) + .map_err(|e| ext_encryption_error(e.to_string()))?; + call_result.return_data = encrypted_output; + } + } + } + + Ok(result) + } + + /// Handler for: `eth_call` + async fn call( + &self, + request: SeismicCallRequest, + block_number: Option<BlockId>, + state_overrides: Option<StateOverride>, + block_overrides: Option<Box<BlockOverrides>>, + ) -> RpcResult<Bytes> { + debug!(target: "reth-seismic-rpc::eth", ?request, ?block_number, ?state_overrides, ?block_overrides, "Serving seismic eth_call extension"); + + // process different CallRequest types + let (seismic_tx_request, signed_read) = convert_seismic_call_to_tx_request(request)?; + let plaintext_tx_req = signed_read_to_plaintext_tx( + (seismic_tx_request.clone(), signed_read), + &self.purpose_keys.tx_io_sk, + )?; + + // call inner + let result = EthCall::call( + &self.eth_api, + plaintext_tx_req.inner.into(), + block_number, + EvmOverrides::new(state_overrides, block_overrides), + ) + .await?; + + // encrypt result - only for signed reads with seismic elements + if signed_read { + if let Some(seismic_elements) = seismic_tx_request.seismic_elements { + let sender = parse_request_sender(&seismic_tx_request)?; + let metadata = Self::build_metadata(&seismic_tx_request, sender)?; + return Ok(seismic_elements + .encrypt(&self.purpose_keys.tx_io_sk, &result, &metadata) + .map_err(|e| ext_encryption_error(e.to_string()))?); + } + } + + Ok(result) + } + + /// Handler for: `eth_sendRawTransaction` + /// + /// Directly calls the inner eth api without decryption + /// We do this so that it is encrypted in the tx pool, so it is encrypted in blocks + /// decryption during execution is handled by the [`SeismicBlockExecutor`] + async fn send_raw_transaction(&self, tx: SeismicRawTxRequest) -> RpcResult<B256> { + debug!(target: "reth-seismic-rpc::eth", ?tx, "Serving overridden eth_sendRawTransaction extension"); + match tx { + SeismicRawTxRequest::Bytes(bytes) => { + Ok(EthTransactions::send_raw_transaction(&self.eth_api, bytes).await?) + } + SeismicRawTxRequest::TypedData(typed_data) => { + Ok(SeismicTransaction::send_typed_data_transaction(&self.eth_api, typed_data) + .await?) + } + } + } + + async fn estimate_gas( + &self, + request: SeismicCallRequest, + block_number: Option<BlockId>, + state_override: Option<StateOverride>, + ) -> RpcResult<U256> { + debug!(target: "reth-seismic-rpc::eth", ?request, ?block_number, ?state_override, "serving seismic eth_estimateGas extension"); + + // Same sanitization as eth_call: unsigned requests have `from`, + // gas/value fields, and seismic_elements cleared to prevent caller + // spoofing that could leak private state. Signed requests (TypedData/Bytes) + // authenticate the sender cryptographically and are processed normally. + let (seismic_tx_request, signed_read) = convert_seismic_call_to_tx_request(request)?; + let decrypted_req = signed_read_to_plaintext_tx( + (seismic_tx_request, signed_read), + &self.purpose_keys.tx_io_sk, + )?; + + // call inner + Ok(EthCall::estimate_gas_at( + &self.eth_api, + decrypted_req.inner.into(), + block_number.unwrap_or_default(), + state_override, + ) + .await?) + } +} + +/// Creates an [`EthApiError`] that says that seismic decryption failed +pub fn ext_decryption_error(e_str: String) -> EthApiError { + EthApiError::Other(Box::new(jsonrpsee_types::ErrorObject::owned( + -32000, // TODO: pick a better error code? + "Error Decrypting in Seismic EthApiExt", + Some(e_str), + ))) +} + +/// Creates an [`EthApiError`] that says that seismic encryption failed +pub fn ext_encryption_error(e_str: String) -> EthApiError { + EthApiError::Other(Box::new(jsonrpsee_types::ErrorObject::owned( + -32000, // TODO: pick a better error code? + "Error Encrypting in Seismic EthApiExt", + Some(e_str), + ))) +}
diff --git reth/crates/seismic/rpc/src/eth/mod.rs seismic-reth/crates/seismic/rpc/src/eth/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..c878ff6a85865a0f23bbe5794bfa824a512c0680 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/mod.rs @@ -0,0 +1,455 @@ +//! Seismic-Reth `eth_` endpoint implementation. + +pub mod api; +pub mod ext; +pub mod receipt; +pub mod transaction; +pub mod utils; + +pub use api::FullSeismicApi; +pub use receipt::SeismicReceiptConverter; + +mod block; +mod call; +mod pending_block; + +use crate::{ + eth::transaction::{SeismicRpcTxConverter, SeismicSimTxConverter}, + SeismicEthApiError, +}; +use alloy_consensus::TxEip4844; +use alloy_eips::BlockId; +use alloy_primitives::{Address, U256}; +use futures::Future; +use reth_evm::{ConfigureEvm, SpecFor, TxEnvFor}; +use reth_node_api::{FullNodeComponents, HeaderTy}; +use reth_node_builder::rpc::{EthApiBuilder, EthApiCtx}; +use reth_rpc::{ + eth::{core::EthApiInner, DevSigner}, + RpcTypes, +}; +use reth_rpc_eth_api::{ + helpers::{ + pending_block::BuildPendingEnv, spec::SignersForApi, AddDevSigners, EthApiSpec, EthCall, + EthFees, EthState, LoadFee, LoadPendingBlock, LoadState, SpawnBlocking, Trace, + }, + EthApiTypes, FromEthApiError, FromEvmError, FullEthApiServer, RpcConvert, RpcConverter, + RpcNodeCore, RpcNodeCoreExt, SignableTxRequest, +}; +use reth_rpc_eth_types::{EthStateCache, FeeHistoryCache, GasPriceOracle}; +use reth_rpc_layer::Whitelist; +use reth_seismic_txpool::usdc::{usdc_balance_storage_key, USDC_CONTRACT, USDC_DECIMAL_SCALE}; +use reth_storage_api::{BlockReader, ProviderHeader, ProviderTx}; +use reth_tasks::{ + pool::{BlockingTaskGuard, BlockingTaskPool}, + TaskSpawner, +}; +use seismic_alloy_network::SeismicReth; +use seismic_revm::SeismicTransaction; +use std::{fmt, marker::PhantomData, sync::Arc}; + +use reth_rpc_convert::transaction::{EthTxEnvError, TryIntoTxEnv}; +use revm_context::{BlockEnv, CfgEnv, TxEnv}; +use seismic_alloy_rpc_types::SeismicTransactionRequest; + +// Additional imports for SignableTxRequest wrapper +use alloy_primitives::Signature; +use reth_rpc_convert::SignTxRequestError; +use seismic_alloy_network::TxSigner; + +/// Newtype wrapper around `SeismicTransactionRequest` to implement `SignableTxRequest` +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +pub struct SignableSeismicTransactionRequest(pub SeismicTransactionRequest); + +impl From<SeismicTransactionRequest> for SignableSeismicTransactionRequest { + fn from(req: SeismicTransactionRequest) -> Self { + Self(req) + } +} + +impl From<alloy_rpc_types_eth::TransactionRequest> for SignableSeismicTransactionRequest { + fn from(req: alloy_rpc_types_eth::TransactionRequest) -> Self { + Self(SeismicTransactionRequest { inner: req, seismic_elements: None }) + } +} + +impl AsRef<alloy_rpc_types_eth::TransactionRequest> for SignableSeismicTransactionRequest { + fn as_ref(&self) -> &alloy_rpc_types_eth::TransactionRequest { + &self.0.inner + } +} + +impl AsMut<alloy_rpc_types_eth::TransactionRequest> for SignableSeismicTransactionRequest { + fn as_mut(&mut self) -> &mut alloy_rpc_types_eth::TransactionRequest { + &mut self.0.inner + } +} + +impl TryIntoTxEnv<seismic_revm::SeismicTransaction<TxEnv>> for SignableSeismicTransactionRequest { + type Err = EthTxEnvError; + + fn try_into_tx_env<Spec>( + self, + cfg_env: &CfgEnv<Spec>, + block_env: &BlockEnv, + ) -> Result<seismic_revm::SeismicTransaction<TxEnv>, Self::Err> { + // First convert the inner transaction to TxEnv + let base_tx_env = self.0.inner.try_into_tx_env(cfg_env, block_env)?; + // Then wrap it in SeismicTransaction + Ok(seismic_revm::SeismicTransaction::new(base_tx_env)) + } +} + +impl SignableTxRequest<reth_seismic_primitives::SeismicTransactionSigned> + for SignableSeismicTransactionRequest +{ + async fn try_build_and_sign( + self, + _signer: impl TxSigner<Signature> + Send, + ) -> Result<reth_seismic_primitives::SeismicTransactionSigned, SignTxRequestError> { + // TODO: Implement proper signing logic + // For now, create a placeholder transaction to make it compile + use alloy_consensus::{Signed, TxLegacy}; + use alloy_primitives::{B256, U256}; + use reth_seismic_primitives::SeismicTransactionSigned; + use seismic_alloy_consensus::SeismicTxEnvelope; + + // Create a minimal transaction for compilation - this should be replaced with proper + // signing + let tx = TxLegacy { + chain_id: Some(1), + nonce: 0, + gas_price: 20_000_000_000u128, + gas_limit: 21_000, + to: alloy_primitives::TxKind::Create, + value: U256::ZERO, + input: Default::default(), + }; + + let signature = Signature::new(U256::ZERO, U256::ZERO, false); + let signed_tx = Signed::new_unchecked(tx, signature, B256::ZERO); + let envelope = SeismicTxEnvelope::<TxEip4844>::Legacy(signed_tx); + let seismic_signed = SeismicTransactionSigned::from(envelope); + + Ok(seismic_signed) + } +} + +/// Wrapper network type that uses `SignableSeismicTransactionRequest` +#[derive(Debug, Clone)] +pub struct SeismicRethWithSignable; + +impl reth_rpc_eth_api::RpcTypes for SeismicRethWithSignable { + type TransactionRequest = SignableSeismicTransactionRequest; + type Receipt = <SeismicReth as reth_rpc_eth_api::RpcTypes>::Receipt; + type TransactionResponse = <SeismicReth as reth_rpc_eth_api::RpcTypes>::TransactionResponse; + type Header = <SeismicReth as reth_rpc_eth_api::RpcTypes>::Header; +} + +/// Adapter for [`EthApiInner`], which holds all the data required to serve core `eth_` API. +pub type EthApiNodeBackend<N, Rpc> = EthApiInner<N, Rpc>; + +/// A helper trait with requirements for [`RpcNodeCore`] to be used in [`SeismicEthApi`]. +pub trait SeismicNodeCore: RpcNodeCore<Provider: BlockReader> {} +impl<T> SeismicNodeCore for T where T: RpcNodeCore<Provider: BlockReader> {} + +/// seismic-reth `Eth` API implementation. +#[derive(Clone)] +pub struct SeismicEthApi<N: SeismicNodeCore, Rpc: RpcConvert> { + /// Inner `Eth` API implementation. + pub inner: Arc<EthApiInner<N, Rpc>>, + /// Shared ops whitelist used to intercept sentinel transactions. + pub ops_whitelist: Option<Whitelist>, +} + +impl<N: RpcNodeCore, Rpc: RpcConvert> SeismicEthApi<N, Rpc> { + /// Returns a reference to the [`EthApiNodeBackend`]. + pub fn eth_api(&self) -> &EthApiNodeBackend<N, Rpc> { + &self.inner + } + + /// Build a [`SeismicEthApi`] using [`SeismicEthApiBuilder`]. + pub const fn builder() -> SeismicEthApiBuilder<Rpc> { + SeismicEthApiBuilder::new() + } +} + +impl<N, Rpc> EthApiTypes for SeismicEthApi<N, Rpc> +where + // Self: Send + Sync, + // N: SeismicNodeCore, + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives>, +{ + type Error = SeismicEthApiError; + type NetworkTypes = Rpc::Network; + type RpcConvert = Rpc; + + fn tx_resp_builder(&self) -> &Self::RpcConvert { + self.inner.tx_resp_builder() + } +} + +impl<N, Rpc> RpcNodeCore for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives>, +{ + type Primitives = N::Primitives; + type Provider = N::Provider; + type Pool = N::Pool; + type Evm = N::Evm; + type Network = N::Network; + + #[inline] + fn pool(&self) -> &Self::Pool { + self.inner.pool() + } + + #[inline] + fn evm_config(&self) -> &Self::Evm { + self.inner.evm_config() + } + + #[inline] + fn network(&self) -> &Self::Network { + self.inner.network() + } + + #[inline] + fn provider(&self) -> &Self::Provider { + self.inner.provider() + } +} + +impl<N, Rpc> RpcNodeCoreExt for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives>, +{ + #[inline] + fn cache(&self) -> &EthStateCache<N::Primitives> { + self.inner.cache() + } +} + +impl<N, Rpc> EthApiSpec for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives>, +{ + type Transaction = ProviderTx<Self::Provider>; + type Rpc = Rpc::Network; + + #[inline] + fn starting_block(&self) -> U256 { + self.inner.starting_block() + } + + #[inline] + fn signers(&self) -> &SignersForApi<Self> { + self.inner.signers() + } +} + +impl<N, Rpc> SpawnBlocking for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives>, +{ + #[inline] + fn io_task_spawner(&self) -> impl TaskSpawner { + self.inner.task_spawner() + } + + #[inline] + fn tracing_task_pool(&self) -> &BlockingTaskPool { + self.inner.blocking_task_pool() + } + + #[inline] + fn tracing_task_guard(&self) -> &BlockingTaskGuard { + self.inner.blocking_task_guard() + } +} + +impl<N, Rpc> LoadFee for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ + #[inline] + fn gas_oracle(&self) -> &GasPriceOracle<Self::Provider> { + self.inner.gas_oracle() + } + + #[inline] + fn fee_history_cache(&self) -> &FeeHistoryCache<ProviderHeader<N::Provider>> { + self.inner.fee_history_cache() + } +} + +impl<N, Rpc> LoadState for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives>, + Self: LoadPendingBlock, +{ +} + +impl<N, Rpc> EthState for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + TxEnvFor<N::Evm>: From<SeismicTransaction<TxEnv>>, + SeismicTransaction<TxEnv>: Into<TxEnvFor<N::Evm>>, + Rpc: RpcConvert< + Primitives = N::Primitives, + Error = SeismicEthApiError, + TxEnv = TxEnvFor<N::Evm>, + Spec = SpecFor<N::Evm>, + >, + <<Self as EthApiTypes>::NetworkTypes as reth_rpc_eth_api::RpcTypes>::TransactionRequest: + From<alloy_rpc_types_eth::TransactionRequest>, + Self: LoadPendingBlock + EthCall, +{ + #[inline] + fn max_proof_window(&self) -> u64 { + self.inner.eth_proof_window() + } + + #[inline] + fn storage_apis_enabled(&self) -> bool { + self.inner.storage_apis_enabled() + } + + /// Returns the higher of the native balance or the USDC predeploy balance (scaled to 18 + /// decimals) for `address`. USDC uses 6 decimals; we multiply by 10^12 so both balances + /// are comparable in 18-decimal wei units. + /// + /// The USDC predeploy on Seismic is a bytecode-less account whose `_balances` mapping + /// (slot 3) is read/written directly by the seismic-revm handler. We therefore read + /// the balance from raw storage instead of executing a `balanceOf` call (which would + /// return empty bytes since there is no contract code). + fn balance( + &self, + address: Address, + block_id: Option<BlockId>, + ) -> impl Future<Output = Result<U256, Self::Error>> + Send { + let storage_key = usdc_balance_storage_key(&address); + + self.spawn_blocking_io_fut(move |this| async move { + let state = this.state_at_block_id_or_latest(block_id).await?; + + // Read native balance. + let native_balance = state + .account_balance(&address) + .map_err(Self::Error::from_eth_err)? + .unwrap_or_default(); + + // Read USDC balance from contract storage and scale 6→18 decimals. + let usdc_balance = state + .storage(USDC_CONTRACT, storage_key) + .map_err(Self::Error::from_eth_err)? + .map(|s| s.value.saturating_mul(USDC_DECIMAL_SCALE)) + .unwrap_or_default(); + + Ok(std::cmp::max(native_balance, usdc_balance)) + }) + } +} + +impl<N, Rpc> EthFees for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ +} + +impl<N, Rpc> Trace for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + Rpc: RpcConvert<Primitives = N::Primitives>, +{ +} + +impl<N, Rpc> AddDevSigners for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert< + Network: RpcTypes<TransactionRequest: SignableTxRequest<ProviderTx<N::Provider>>>, + >, +{ + fn with_dev_accounts(&self) { + *self.inner.signers().write() = DevSigner::random_signers(20) + } +} + +impl<N: SeismicNodeCore, Rpc: RpcConvert> fmt::Debug for SeismicEthApi<N, Rpc> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SeismicEthApi").finish_non_exhaustive() + } +} + +/// Converter for Seismic RPC types. +pub type SeismicRpcConvert<N, NetworkT> = RpcConverter< + NetworkT, + <N as FullNodeComponents>::Evm, + SeismicReceiptConverter, + (), + (), + crate::eth::transaction::SeismicSimTxConverter, + crate::eth::transaction::SeismicRpcTxConverter, +>; + +/// Builds [`SeismicEthApi`] for Optimism. +#[derive(Debug)] +pub struct SeismicEthApiBuilder<NetworkT> { + _nt: PhantomData<NetworkT>, +} + +impl<NetworkT> Default for SeismicEthApiBuilder<NetworkT> { + fn default() -> Self { + Self { _nt: PhantomData } + } +} + +impl<NetworkT> SeismicEthApiBuilder<NetworkT> { + /// Creates a [`SeismicEthApiBuilder`] instance from core components. + pub const fn new() -> Self { + Self { _nt: PhantomData } + } +} + +impl<N, NetworkT> EthApiBuilder<N> for SeismicEthApiBuilder<NetworkT> +where + N: FullNodeComponents< + Evm: ConfigureEvm< + NextBlockEnvCtx: BuildPendingEnv<HeaderTy<N::Types>> + // + From<ExecutionPayloadBaseV1> + + Unpin, + >, + >, + NetworkT: RpcTypes, + SeismicRpcConvert<N, NetworkT>: RpcConvert<Network = NetworkT>, + SeismicEthApi<N, SeismicRpcConvert<N, NetworkT>>: + FullEthApiServer<Provider = N::Provider, Pool = N::Pool> + AddDevSigners, +{ + type EthApi = SeismicEthApi<N, SeismicRpcConvert<N, NetworkT>>; + + async fn build_eth_api(self, ctx: EthApiCtx<'_, N>) -> eyre::Result<Self::EthApi> { + let ops_whitelist = ctx.ops_whitelist.clone(); + let receipt_converter = SeismicReceiptConverter::new(); + + let rpc_converter: SeismicRpcConvert<N, NetworkT> = RpcConverter::new(receipt_converter) + .with_sim_tx_converter(SeismicSimTxConverter::new()) + .with_rpc_tx_converter(SeismicRpcTxConverter::new()); + + let eth_api = ctx.eth_api_builder().with_rpc_converter(rpc_converter).build_inner(); + + Ok(SeismicEthApi { inner: Arc::new(eth_api), ops_whitelist }) + } +}
diff --git reth/crates/seismic/rpc/src/eth/pending_block.rs seismic-reth/crates/seismic/rpc/src/eth/pending_block.rs new file mode 100644 index 0000000000000000000000000000000000000000..6390260ff2fbf2017710769f7ab23246c6019f9e --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/pending_block.rs @@ -0,0 +1,29 @@ +//! Loads Seismic pending block for a RPC response. + +use crate::{SeismicEthApi, SeismicEthApiError}; +use reth_rpc_eth_api::{helpers::LoadPendingBlock, FromEvmError, RpcConvert, RpcNodeCore}; +use reth_rpc_eth_types::PendingBlock; + +impl<N, Rpc> LoadPendingBlock for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + SeismicEthApiError: FromEvmError<N::Evm>, + Rpc: RpcConvert<Primitives = N::Primitives>, +{ + #[inline] + fn pending_block(&self) -> &tokio::sync::Mutex<Option<PendingBlock<Self::Primitives>>> { + self.inner.pending_block() + } + + #[inline] + fn pending_env_builder( + &self, + ) -> &dyn reth_rpc_eth_api::helpers::pending_block::PendingEnvBuilder<Self::Evm> { + self.inner.pending_env_builder() + } + + #[inline] + fn pending_block_kind(&self) -> reth_rpc_eth_types::builder::config::PendingBlockKind { + self.inner.pending_block_kind() + } +}
diff --git reth/crates/seismic/rpc/src/eth/receipt.rs seismic-reth/crates/seismic/rpc/src/eth/receipt.rs new file mode 100644 index 0000000000000000000000000000000000000000..d3964bc2a408de2d43b848c06bbdc0cda83cc971 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/receipt.rs @@ -0,0 +1,85 @@ +//! Loads and formats Seismic receipt RPC response. + +use reth_rpc_convert::transaction::{ConvertReceiptInput, ReceiptConverter}; +use reth_rpc_eth_api::{helpers::LoadReceipt, RpcConvert, RpcNodeCore}; +use reth_rpc_eth_types::{receipt::build_receipt, EthApiError}; +use reth_seismic_primitives::{SeismicPrimitives, SeismicReceipt}; +use seismic_alloy_consensus::SeismicReceiptEnvelope; +use seismic_alloy_rpc_types::SeismicTransactionReceipt; +use std::fmt::Debug; + +use crate::{SeismicEthApi, SeismicEthApiError}; + +impl<N, Rpc> LoadReceipt for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ +} + +/// Builds an [`SeismicTransactionReceipt`]. +/// +/// Like [`EthReceiptBuilder`], but with Seismic types +#[derive(Debug)] +pub struct SeismicReceiptBuilder { + /// The base response body, contains L1 fields. + pub base: SeismicTransactionReceipt, +} + +impl SeismicReceiptBuilder { + /// Returns a new builder. + pub fn new(input: ConvertReceiptInput<'_, SeismicPrimitives>) -> Result<Self, EthApiError> { + let base = build_receipt(&input, None, |receipt_with_bloom| match input.receipt.as_ref() { + SeismicReceipt::Legacy(_) => SeismicReceiptEnvelope::Legacy(receipt_with_bloom), + SeismicReceipt::Eip2930(_) => SeismicReceiptEnvelope::Eip2930(receipt_with_bloom), + SeismicReceipt::Eip1559(_) => SeismicReceiptEnvelope::Eip1559(receipt_with_bloom), + SeismicReceipt::Eip7702(_) => SeismicReceiptEnvelope::Eip7702(receipt_with_bloom), + SeismicReceipt::Seismic(_) => SeismicReceiptEnvelope::Seismic(receipt_with_bloom), + SeismicReceipt::Eip4844(_) => SeismicReceiptEnvelope::Eip4844(receipt_with_bloom), + }); + + Ok(Self { base }) + } + + /// Builds [`SeismicTransactionReceipt`] by combing core (l1) receipt fields and additional + /// Seismic receipt fields. + pub fn build(self) -> SeismicTransactionReceipt { + self.base + } +} + +/// Seismic receipt converter. +#[derive(Debug, Clone)] +pub struct SeismicReceiptConverter; + +impl Default for SeismicReceiptConverter { + fn default() -> Self { + Self::new() + } +} + +impl SeismicReceiptConverter { + /// Creates a new seismic receipt converter. + pub const fn new() -> Self { + Self + } +} + +impl ReceiptConverter<SeismicPrimitives> for SeismicReceiptConverter { + type Error = SeismicEthApiError; + type RpcReceipt = SeismicTransactionReceipt; + + fn convert_receipts( + &self, + inputs: Vec<ConvertReceiptInput<'_, SeismicPrimitives>>, + ) -> Result<Vec<Self::RpcReceipt>, Self::Error> { + inputs + .into_iter() + .map(|input| { + SeismicReceiptBuilder::new(input) + .map_err(SeismicEthApiError::Eth) + .map(|builder| builder.build()) + }) + .collect() + } +}
diff --git reth/crates/seismic/rpc/src/eth/transaction.rs seismic-reth/crates/seismic/rpc/src/eth/transaction.rs new file mode 100644 index 0000000000000000000000000000000000000000..9f7421dc136f3674f0e10e7f0656699eb5a180d2 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/transaction.rs @@ -0,0 +1,425 @@ +//! Loads and formats Seismic transaction RPC response. + +use super::ext::SeismicTransaction; +use crate::{ + eth::{SeismicNodeCore, SignableSeismicTransactionRequest}, + utils::recover_typed_data_request, + SeismicEthApi, SeismicEthApiError, +}; +use alloy_consensus::{transaction::Recovered, Transaction as _}; +use alloy_primitives::{Address, Bytes, Signature, B256}; +use alloy_rpc_types_eth::{Transaction, TransactionInfo}; +use alloy_sol_types::SolCall; +use reth_primitives_traits::SignedTransaction; +use reth_rpc_convert::transaction::{RpcTxConverter, SimTxConverter}; +use reth_rpc_eth_api::{ + helpers::{spec::SignersForRpc, EthTransactions, LoadTransaction}, + FromEthApiError, RpcConvert, RpcNodeCore, +}; +use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError}; +use reth_rpc_layer::{ + OpsWhitelistTxAuth, Whitelist, OPS_AUTH_CONTRACT, OPS_AUTH_SLOT, WHITELIST_TX_SENTINEL, +}; +use reth_seismic_primitives::SeismicTransactionSigned; +use reth_storage_api::{BlockReader, BlockReaderIdExt, ProviderTx, StateProviderFactory}; +use reth_transaction_pool::{ + AddedTransactionOutcome, PoolTransaction, TransactionOrigin, TransactionPool, +}; +use seismic_alloy_consensus::{Decodable712, SeismicTxEnvelope, TypedDataRequest}; +use seismic_alloy_rpc_types::SeismicTransactionRequest; +use std::time::{SystemTime, UNIX_EPOCH}; + +enum SentinelAction { + Whitelist { target: Address, expires_at: u64 }, + Revoke { target: Address }, +} + +impl<N, Rpc> SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ + fn try_handle_sentinel_transaction<T>( + &self, + recovered: &Recovered<T>, + whitelist: &Whitelist, + ) -> Result<bool, SeismicEthApiError> + where + T: alloy_consensus::Transaction, + { + let Some(action) = parse_sentinel_action(recovered)? else { return Ok(false) }; + + let governance_address = self.ops_governance_address()?; + if recovered.signer() != governance_address { + return Err(rpc_error("unauthorized ops whitelist sentinel signer")); + } + + match action { + SentinelAction::Whitelist { target, expires_at } => { + if expires_at <= current_unix_timestamp()? { + return Err(rpc_error("ops whitelist expiry must be in the future")); + } + whitelist.add(target, expires_at); + } + SentinelAction::Revoke { target } => { + whitelist.remove(&target); + } + } + + Ok(true) + } + + fn ops_governance_address(&self) -> Result<Address, SeismicEthApiError> { + let state = self.provider().latest().map_err(SeismicEthApiError::from)?; + let value = state + .storage(OPS_AUTH_CONTRACT, OPS_AUTH_SLOT) + .map_err(SeismicEthApiError::from)? + .ok_or_else(|| rpc_error("ops governance slot is unset"))?; + let bytes = value.value.to_be_bytes::<32>(); + let address = Address::from_slice(&bytes[12..]); + if address.is_zero() { + return Err(rpc_error("ops governance address resolved to zero address")); + } + Ok(address) + } +} + +impl<N, Rpc> EthTransactions for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ + fn signers(&self) -> &SignersForRpc<Self::Provider, Self::NetworkTypes> { + self.inner.signers() + } + + async fn send_raw_transaction(&self, tx: Bytes) -> Result<B256, Self::Error> { + let recovered: Recovered< + <<Self::Pool as TransactionPool>::Transaction as PoolTransaction>::Pooled, + > = recover_raw_transaction(&tx)?; + tracing::debug!(target: "reth-seismic-rpc::eth", tx_hash = %recovered.tx_hash(), "serving seismic_eth_api::send_raw_transaction"); + + if let Some(whitelist) = self.ops_whitelist.as_ref() { + if self.try_handle_sentinel_transaction(&recovered, whitelist)? { + return Ok(B256::from(*recovered.tx_hash())) + } + } + + let pool_transaction = <Self::Pool as TransactionPool>::Transaction::from_pooled(recovered); + + // submit the transaction to the pool with a `Local` origin + let AddedTransactionOutcome { hash, .. } = self + .pool() + .add_transaction(TransactionOrigin::Local, pool_transaction) + .await + .map_err(Self::Error::from_eth_err)?; + + Ok(hash) + } +} + +impl<N, Rpc> SeismicTransaction for SeismicEthApi<N, Rpc> +where + Self: LoadTransaction<Provider: BlockReaderIdExt>, + // N: RpcNodeCore, + N: SeismicNodeCore<Provider: BlockReader<Transaction = ProviderTx<Self::Provider>>>, + <<<Self as RpcNodeCore>::Pool as TransactionPool>::Transaction as PoolTransaction>::Pooled: + Decodable712, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ + async fn send_typed_data_transaction(&self, tx: TypedDataRequest) -> Result<B256, Self::Error> { + let recovered = recover_typed_data_request(&tx)?; + + // broadcast raw transaction to subscribers if there is any. + // TODO: maybe we need to broadcast the encoded tx instead of the recovered tx + // when other nodes receive the raw bytes the hash they recover needs to be + // type + // self.broadcast_raw_transaction(recovered.to); + + let pool_transaction = <Self::Pool as TransactionPool>::Transaction::from_pooled(recovered); + + // submit the transaction to the pool with a `Local` origin + let AddedTransactionOutcome { hash, .. } = self + .pool() + .add_transaction(TransactionOrigin::Local, pool_transaction) + .await + .map_err(Self::Error::from_eth_err)?; + + Ok(hash) + } +} + +impl<N, Rpc> LoadTransaction for SeismicEthApi<N, Rpc> +where + N: RpcNodeCore, + Rpc: RpcConvert<Primitives = N::Primitives, Error = SeismicEthApiError>, +{ +} + +fn parse_sentinel_action<T>( + recovered: &Recovered<T>, +) -> Result<Option<SentinelAction>, SeismicEthApiError> +where + T: alloy_consensus::Transaction, +{ + if recovered.to() != Some(WHITELIST_TX_SENTINEL) { + return Ok(None) + } + + let input = recovered.input(); + let selector = input + .get(..4) + .ok_or_else(|| rpc_error("ops whitelist sentinel calldata is missing selector"))?; + + if selector == OpsWhitelistTxAuth::whitelistKeyCall::SELECTOR { + let call = OpsWhitelistTxAuth::whitelistKeyCall::abi_decode(input) + .map_err(|_| rpc_error("failed to decode ops whitelist calldata"))?; + return Ok(Some(SentinelAction::Whitelist { + target: call.target, + expires_at: call.expiresAt, + })) + } + + if selector == OpsWhitelistTxAuth::revokeKeyCall::SELECTOR { + let call = OpsWhitelistTxAuth::revokeKeyCall::abi_decode(input) + .map_err(|_| rpc_error("failed to decode ops revoke calldata"))?; + return Ok(Some(SentinelAction::Revoke { target: call.target })) + } + + Err(rpc_error("unknown ops whitelist sentinel selector")) +} + +fn current_unix_timestamp() -> Result<u64, SeismicEthApiError> { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .map(|d| d.as_secs()) + .map_err(|_| rpc_error("system clock before unix epoch")) +} + +fn rpc_error(message: &'static str) -> SeismicEthApiError { + SeismicEthApiError::Eth(EthApiError::Other(Box::new(jsonrpsee_types::ErrorObject::owned( + -32000, message, None::<()>, + )))) +} + +/// Seismic RPC transaction converter that implements Debug +#[derive(Clone, Debug)] +pub struct SeismicRpcTxConverter; + +impl Default for SeismicRpcTxConverter { + fn default() -> Self { + Self::new() + } +} + +impl SeismicRpcTxConverter { + /// Creates a new converter + pub const fn new() -> Self { + Self + } +} + +/// Seismic simulation transaction converter that implements Debug +#[derive(Clone, Debug)] +pub struct SeismicSimTxConverter; + +impl Default for SeismicSimTxConverter { + fn default() -> Self { + Self::new() + } +} + +impl SeismicSimTxConverter { + /// Creates a new converter + pub const fn new() -> Self { + Self + } +} + +impl RpcTxConverter<SeismicTransactionSigned, Transaction<SeismicTxEnvelope>, TransactionInfo> + for SeismicRpcTxConverter +{ + type Err = SeismicEthApiError; + + fn convert_rpc_tx( + &self, + tx: SeismicTransactionSigned, + signer: alloy_primitives::Address, + tx_info: TransactionInfo, + ) -> Result<Transaction<SeismicTxEnvelope>, Self::Err> { + let tx_envelope: SeismicTxEnvelope = tx.into(); + let recovered_tx = Recovered::new_unchecked(tx_envelope, signer); + + let TransactionInfo { + block_hash, block_number, index: transaction_index, base_fee, .. + } = tx_info; + + let effective_gas_price = base_fee + .map(|base_fee| { + recovered_tx.effective_tip_per_gas(base_fee).unwrap_or_default() + base_fee as u128 + }) + .unwrap_or_else(|| recovered_tx.max_fee_per_gas()); + + Ok(Transaction::<SeismicTxEnvelope> { + inner: recovered_tx, + block_hash, + block_number, + transaction_index, + effective_gas_price: Some(effective_gas_price), + }) + } +} + +impl SimTxConverter<alloy_rpc_types_eth::TransactionRequest, SeismicTransactionSigned> + for SeismicSimTxConverter +{ + type Err = SeismicEthApiError; + + fn convert_sim_tx( + &self, + tx_req: alloy_rpc_types_eth::TransactionRequest, + ) -> Result<SeismicTransactionSigned, Self::Err> { + let request = SeismicTransactionRequest { + inner: tx_req, + seismic_elements: None, + /* Assumed that the transaction has already been decrypted in + * the EthApiExt */ + }; + let Ok(tx) = request.build_typed_tx() else { + return Err(SeismicEthApiError::Eth(EthApiError::TransactionConversionError)); + }; + + // Create an empty signature for the transaction. + let signature = Signature::new(Default::default(), Default::default(), false); + Ok(SeismicTransactionSigned::new_unhashed(tx, signature)) + } +} + +// Additional implementation for SeismicTransactionRequest directly +impl SimTxConverter<SeismicTransactionRequest, SeismicTransactionSigned> for SeismicSimTxConverter { + type Err = SeismicEthApiError; + + fn convert_sim_tx( + &self, + request: SeismicTransactionRequest, + ) -> Result<SeismicTransactionSigned, Self::Err> { + let Ok(tx) = request.build_typed_tx() else { + return Err(SeismicEthApiError::Eth(EthApiError::TransactionConversionError)); + }; + + // Create an empty signature for the transaction. + let signature = Signature::new(Default::default(), Default::default(), false); + Ok(SeismicTransactionSigned::new_unhashed(tx, signature)) + } +} + +// Implementation for SignableSeismicTransactionRequest wrapper +impl SimTxConverter<SignableSeismicTransactionRequest, SeismicTransactionSigned> + for SeismicSimTxConverter +{ + type Err = SeismicEthApiError; + + fn convert_sim_tx( + &self, + request: SignableSeismicTransactionRequest, + ) -> Result<SeismicTransactionSigned, Self::Err> { + // Delegate to the inner SeismicTransactionRequest implementation + self.convert_sim_tx(request.0) + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod test { + use alloy_primitives::{Bytes, FixedBytes}; + use reth_primitives_traits::SignedTransaction; + use reth_rpc_eth_types::utils::recover_raw_transaction; + use reth_seismic_primitives::SeismicTransactionSigned; + use std::str::FromStr; + + /// Helper function to generate a new raw seismic transaction for testing. + /// Kept here for future use if the protocol changes and test data needs regeneration. + /// + /// Uses: + /// - First Anvil private key: + /// 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 + /// - Sender address: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 + /// - Network public key from seismic-enclave (insecure sample key) + #[allow(dead_code)] + fn generate_test_raw_tx() -> (Bytes, FixedBytes<32>) { + use alloy_consensus::SignableTransaction; + use alloy_eips::eip2718::Encodable2718; + use alloy_primitives::{aliases::U96, hex, Address, TxKind, U256}; + use k256::ecdsa::SigningKey; + use secp256k1::PublicKey; + use seismic_alloy_consensus::{TxSeismic, TxSeismicElements}; + use seismic_enclave::get_unsecure_sample_secp256k1_pk; + + // First anvil key + let private_key_bytes: [u8; 32] = + hex::decode("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80") + .unwrap() + .try_into() + .unwrap(); + let signing_key = SigningKey::from_bytes(&private_key_bytes.into()).unwrap(); + + // Network public key + let network_pubkey: PublicKey = get_unsecure_sample_secp256k1_pk(); + + // Create a seismic transaction + let tx = TxSeismic { + chain_id: 5123, // seismic dev chain id + nonce: 1, + gas_price: 20000000000, + gas_limit: 210000, + to: TxKind::Call( + Address::from_str("0x3aB946eEC2553114040dE82D2e18798a51cf1e14").unwrap(), + ), + value: U256::from(1000000000000000u64), + input: Bytes::from_str( + "0x4e69e56c3bb999b8c98772ebb32aebcbd43b33e9e65a46333dfe6636f37f3009e93bad33", + ) + .unwrap(), + seismic_elements: TxSeismicElements { + encryption_pubkey: network_pubkey, + encryption_nonce: U96::from_str("0x7da3a99bf0f90d56551d99ea").unwrap(), + message_version: 2, + recent_block_hash: reth_seismic_chainspec::SEISMIC_DEV_GENESIS_HASH, + expires_at_block: 1000000, + signed_read: false, + }, + authorization_list: vec![], + }; + + // Sign the transaction + let sig_hash = tx.signature_hash(); + let sig = signing_key.sign_prehash_recoverable(sig_hash.as_slice()).unwrap(); + let recoverid = sig.1; + + let signature = alloy_primitives::Signature::new( + U256::from_be_slice(sig.0.r().to_bytes().as_ref()), + U256::from_be_slice(sig.0.s().to_bytes().as_ref()), + recoverid.is_y_odd(), + ); + + // Create signed transaction + let signed: SeismicTransactionSigned = + SignableTransaction::into_signed(tx, signature).into(); + + // Encode to raw bytes + let mut encoded = Vec::new(); + signed.encode_2718(&mut encoded); + + // Get hash + let hash = *signed.tx_hash(); + + (Bytes::from(encoded), hash) + } + + #[test] + fn test_generate_and_recover_raw_tx() { + let (raw_bytes, hash) = generate_test_raw_tx(); + let recovered = recover_raw_transaction::<SeismicTransactionSigned>(&raw_bytes).unwrap(); + assert_eq!(recovered.tx_hash(), &hash); + } +}
diff --git reth/crates/seismic/rpc/src/eth/utils.rs seismic-reth/crates/seismic/rpc/src/eth/utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..dade20f8bf31f42d6d6a79dfc4b79a92ac2b2503 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/eth/utils.rs @@ -0,0 +1,192 @@ +//! Utils for testing the seismic rpc api + +use alloy_primitives::Address; +use reth_primitives::Recovered; +use reth_primitives_traits::SignedTransaction; +use reth_rpc_eth_types::{utils::recover_raw_transaction, EthApiError, EthResult}; +use seismic_alloy_consensus::{Decodable712, SeismicTxEnvelope, TypedDataRequest}; +use seismic_alloy_network::{SeismicReth, TransactionBuilder}; +use seismic_alloy_rpc_types::{SeismicCallRequest, SeismicTransactionRequest}; + +use crate::ext::ext_decryption_error; +use seismic_alloy_consensus::InputDecryptionElements; +use seismic_enclave::secp256k1::SecretKey; + +/// Override the request for seismic calls +pub const fn seismic_override_call_request(request: &mut SeismicTransactionRequest) { + // If user calls with the standard (unsigned) eth_call, + // then disregard whatever they put in the from field + // They will still be able to read public contract functions, + // but they will not be able to spoof msg.sender in these calls + request.inner.from = None; + request.inner.gas_price = None; // preventing InsufficientFunds error + request.inner.max_fee_per_gas = None; // preventing InsufficientFunds error + request.inner.max_priority_fee_per_gas = None; // preventing InsufficientFunds error + request.inner.max_fee_per_blob_gas = None; // preventing InsufficientFunds error + request.inner.value = None; // preventing InsufficientFunds error + request.seismic_elements = None; // zero out seismic elements +} + +/// Recovers a [`SignedTransaction`] from a typed data request. +/// +/// This is a helper function that returns the appropriate RPC-specific error if the input data is +/// malformed. +/// +/// See [`alloy_eips::eip2718::Decodable2718::decode_2718`] +pub fn recover_typed_data_request<T: SignedTransaction + Decodable712>( + data: &TypedDataRequest, +) -> EthResult<Recovered<T>> { + let transaction = + T::decode_712(data).map_err(|_| EthApiError::FailedToDecodeSignedTransaction)?; + + SignedTransaction::try_into_recovered(transaction) + .or(Err(EthApiError::InvalidTransactionSignature)) +} + +/// Convert a [`SeismicCallRequest`] to a [`SeismicTransactionRequest`]. +/// +/// If the call requests simulates a transaction without a signature from msg.sender, +/// we null out the fields that may reveal sensitive information. +pub fn convert_seismic_call_to_tx_request( + request: SeismicCallRequest, +) -> Result<(SeismicTransactionRequest, bool), EthApiError> { + match request { + SeismicCallRequest::TransactionRequest(mut tx_request) => { + seismic_override_call_request(&mut tx_request); // null fields that may reveal sensitive information + Ok((tx_request, false)) + } + + SeismicCallRequest::TypedData(typed_request) => { + let req = SeismicTransactionRequest::decode_712(&typed_request) + .map_err(|_e| EthApiError::FailedToDecodeSignedTransaction)?; + Ok((req, true)) + } + + SeismicCallRequest::Bytes(bytes) => { + let tx = recover_raw_transaction::<SeismicTxEnvelope>(&bytes)?; + let mut req: SeismicTransactionRequest = tx.inner().clone().into(); + TransactionBuilder::<SeismicReth>::set_from(&mut req, tx.signer()); + Ok((req, true)) + } + } +} + +/// Get the sender address from a seismic transaction request. +/// Returns an error if the sender is missing. +pub fn parse_request_sender(request: &SeismicTransactionRequest) -> Result<Address, EthApiError> { + request.inner.from.ok_or_else(|| { + EthApiError::Other(Box::new(jsonrpsee_types::ErrorObject::owned( + -32602, + "Missing 'from' field for seismic transaction", + None::<String>, + ))) + }) +} + +/// Conditionally decrypt a seismic transaction request based on whether it's a signed read. +/// +/// For non-seismic transactions (`signed_read = false`), returns the request unchanged. +/// For seismic transactions (`signed_read = true`), decrypts the request using the provided secret +/// key. +pub fn signed_read_to_plaintext_tx( + (seismic_tx_request, signed_read): (SeismicTransactionRequest, bool), + secret_key: &SecretKey, +) -> Result<SeismicTransactionRequest, EthApiError> { + match signed_read { + false => Ok(seismic_tx_request), + true => { + let sender = parse_request_sender(&seismic_tx_request)?; + let seismic_tx_request = seismic_tx_request + .plaintext_copy(secret_key, sender) + .map_err(|e| ext_decryption_error(e.to_string()))?; + Ok(seismic_tx_request) + } + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used, clippy::expect_used, clippy::indexing_slicing)] +mod test { + use crate::utils::recover_typed_data_request; + use alloy_primitives::{ + aliases::U96, + hex::{self, FromHex}, + Address, Bytes, FixedBytes, Signature, U256, + }; + use reth_primitives_traits::SignedTransaction; + use reth_seismic_primitives::SeismicTransactionSigned; + use secp256k1::PublicKey; + use seismic_alloy_consensus::{ + SeismicTxEnvelope, TxSeismic, TxSeismicElements, TypedDataRequest, + }; + use std::str::FromStr; + + #[test] + fn test_typed_data_tx_hash() { + let r_bytes = + hex::decode("e93185920818650416b4b0cc953c48f59fd9a29af4b7e1c4b1ac4824392f9220") + .unwrap(); + let s_bytes = + hex::decode("79b76b064a83d423997b7234c575588f60da5d3e1e0561eff9804eb04c23789a") + .unwrap(); + let mut r_padded = [0u8; 32]; + let mut s_padded = [0u8; 32]; + let r_start = 32 - r_bytes.len(); + let s_start = 32 - s_bytes.len(); + + r_padded[r_start..].copy_from_slice(&r_bytes); + s_padded[s_start..].copy_from_slice(&s_bytes); + + let r = U256::from_be_bytes(r_padded); + let s = U256::from_be_bytes(s_padded); + + let signature = Signature::new(r, s, false); + + let tx = TxSeismic { + chain_id: 5124, + nonce: 48, + gas_price: 360000, + gas_limit: 169477, + to: alloy_primitives::TxKind::Call(Address::from_str("0x3aB946eEC2553114040dE82D2e18798a51cf1e14").unwrap()), + value: U256::from_str("1000000000000000").unwrap(), + input: Bytes::from_str("0x4e69e56c3bb999b8c98772ebb32aebcbd43b33e9e65a46333dfe6636f37f3009e93bad334235aec73bd54d11410e64eb2cab4da8").unwrap(), + seismic_elements: TxSeismicElements { + encryption_pubkey: PublicKey::from_str("028e76821eb4d77fd30223ca971c49738eb5b5b71eabe93f96b348fdce788ae5a0").unwrap(), + encryption_nonce: U96::from_str("0x7da3a99bf0f90d56551d99ea").unwrap(), + message_version: 2, + recent_block_hash: alloy_primitives::B256::from_slice(&hex::decode("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").unwrap()), + expires_at_block: 1000000, + signed_read: false, + }, + authorization_list: vec![], + }; + + let signed = SeismicTransactionSigned::new_unhashed( + seismic_alloy_consensus::SeismicTypedTransaction::Seismic(tx.clone()), + signature, + ); + let signed_hash = signed.recalculate_hash(); + let signed_sighash = signed.signature_hash(); + + let td = tx.eip712_to_type_data(); + let req = TypedDataRequest { signature, data: td }; + + let recovered = recover_typed_data_request::<SeismicTxEnvelope>(&req).unwrap(); + let recovered_hash = recovered.tx_hash(); + let recovered_sighash = recovered.signature_hash(); + + let expected_tx_hash = FixedBytes::<32>::from_hex( + "0xe82f9ce621da07a8ae10d330383275402ff9430dbe4b8b10cd0038ede3ef3718", + ) + .unwrap(); + assert_eq!(signed_hash, expected_tx_hash); + assert_eq!(recovered_hash, expected_tx_hash); + + let expected_sighash = FixedBytes::<32>::from_hex( + "a6bc27ff66ea25d3665afa7f617291cc523a1a04fa651213bccd4393d049a180", + ) + .unwrap(); + assert_eq!(signed_sighash, expected_sighash); + assert_eq!(recovered_sighash, expected_sighash); + } +}
diff --git reth/crates/seismic/rpc/src/lib.rs seismic-reth/crates/seismic/rpc/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..662bcc0df94fece6fa0f552cb30a6285ec5de503 --- /dev/null +++ seismic-reth/crates/seismic/rpc/src/lib.rs @@ -0,0 +1,15 @@ +//! Seismic-Reth RPC support. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod eth; +pub use eth::*; + +mod error; +pub use error::*;
diff --git reth/crates/seismic/primitives/Cargo.toml seismic-reth/crates/seismic/primitives/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..32408aabe95556c4f74788d5d7fefaba632b2ec7 --- /dev/null +++ seismic-reth/crates/seismic/primitives/Cargo.toml @@ -0,0 +1,141 @@ +[package] +name = "reth-seismic-primitives" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "Seismic primitive types" + +[lints] +workspace = true + +[dependencies] +seismic-enclave.workspace = true + +# reth +reth-primitives-traits = { workspace = true, features = ["serde"] } +reth-codecs = { workspace = true, optional = true } +reth-zstd-compressors = { workspace = true, optional = true } +revm-context.workspace = true + +# ethereum +alloy-evm.workspace = true +alloy-primitives = { workspace = true, features = ["serde"] } +alloy-consensus.workspace = true +alloy-rlp.workspace = true +alloy-eips = { workspace = true, features = ["k256"] } +alloy-network = { workspace = true } + +# seismic +seismic-alloy-consensus.workspace = true +seismic-alloy-network = { workspace = true } +seismic-revm.workspace = true + +# codec +bytes = { workspace = true, optional = true } +modular-bitfield = { workspace = true, optional = true } +serde = { workspace = true, optional = true } +serde_with = { workspace = true, optional = true } + +# misc +derive_more = { workspace = true, features = [ + "deref", + "from", + "into", + "constructor", +] } +secp256k1 = { workspace = true, features = ["rand", "std", "global-context", "recovery"]} +anyhow.workspace = true +tracing.workspace = true + +# test +arbitrary = { workspace = true, features = ["derive"], optional = true } +rand_08 = { workspace = true, optional = true } +proptest = { workspace = true, optional = true } + +# test utils +alloy-signer-local.workspace = true +alloy-rpc-types.workspace = true +k256.workspace = true +enr = {workspace = true, features = ["rust-secp256k1"]} +alloy-dyn-abi.workspace = true +seismic-alloy-rpc-types.workspace = true + +[dev-dependencies] +arbitrary.workspace = true +proptest-arbitrary-interop.workspace = true +proptest.workspace = true +rand.workspace = true +rand_08.workspace = true +reth-codecs = { workspace = true, features = ["test-utils"] } +rstest.workspace = true +serde_json.workspace = true +bincode.workspace = true + +[features] +default = ["std", "serde", "serde-bincode-compat", "reth-codec"] +timestamp-in-seconds = ["seismic-revm/timestamp-in-seconds"] +std = [ + "reth-primitives-traits/std", + "reth-codecs?/std", + "alloy-consensus/std", + "alloy-eips/std", + "alloy-primitives/std", + "serde?/std", + "bytes?/std", + "derive_more/std", + "secp256k1/std", + "alloy-rlp/std", + "reth-zstd-compressors?/std", + "seismic-alloy-consensus/std", + "revm-context/std", + "serde_json/std", + "alloy-evm/std", + "serde_with?/std", +] +reth-codec = [ + "dep:reth-codecs", + "std", + "dep:proptest", + "reth-primitives-traits/reth-codec", + "reth-codecs?/op", + "dep:bytes", + "dep:modular-bitfield", + "dep:reth-zstd-compressors", +] +serde = [ + "dep:serde", + "reth-primitives-traits/serde", + "alloy-primitives/serde", + "alloy-consensus/serde", + "alloy-eips/serde", + "bytes?/serde", + "reth-codecs?/serde", + "seismic-alloy-consensus/serde", + "rand/serde", + "secp256k1/serde", + "revm-context/serde", +] +serde-bincode-compat = [ + "serde", + "serde_with", + "alloy-consensus/serde-bincode-compat", + "alloy-eips/serde-bincode-compat", + "seismic-alloy-consensus/serde-bincode-compat", + "reth-primitives-traits/serde-bincode-compat", +] +arbitrary = [ + "std", + "dep:arbitrary", + # "dep:secp256k1", + "secp256k1/rand", + "reth-primitives-traits/arbitrary", + "reth-codecs?/arbitrary", + "seismic-alloy-consensus/arbitrary", + "alloy-consensus/arbitrary", + "alloy-eips/arbitrary", + "alloy-primitives/arbitrary", + "rand_08", +]
diff --git reth/crates/seismic/primitives/src/lib.rs seismic-reth/crates/seismic/primitives/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..2f0e6ea9c4fef50fcc316784372ac9474a3c30bc --- /dev/null +++ seismic-reth/crates/seismic/primitives/src/lib.rs @@ -0,0 +1,46 @@ +//! Standalone crate for Seismic-specific Reth primitive types. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" +)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; + +pub mod transaction; +pub use transaction::{signed::SeismicTransactionSigned, tx_type::SeismicTxType}; + +mod receipt; +pub use receipt::SeismicReceipt; +pub mod test_utils; + +/// Seismic-specific block type. +pub type SeismicBlock = alloy_consensus::Block<SeismicTransactionSigned>; + +/// Seismic-specific block body type. +pub type SeismicBlockBody = <SeismicBlock as reth_primitives_traits::Block>::Body; + +/// Primitive types for Seismic Node. +#[derive(Debug, Default, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct SeismicPrimitives; + +impl reth_primitives_traits::NodePrimitives for SeismicPrimitives { + type Block = SeismicBlock; + type BlockHeader = alloy_consensus::Header; + type BlockBody = SeismicBlockBody; + type SignedTx = SeismicTransactionSigned; + type Receipt = SeismicReceipt; +} + +/// Bincode-compatible serde implementations. +#[cfg(feature = "serde-bincode-compat")] +pub mod serde_bincode_compat { + pub use super::{ + receipt::serde_bincode_compat::*, transaction::signed::serde_bincode_compat::*, + }; +}
diff --git reth/crates/seismic/primitives/src/receipt.rs seismic-reth/crates/seismic/primitives/src/receipt.rs new file mode 100644 index 0000000000000000000000000000000000000000..5b1c1ae3be9bca01cf4bbd8c6898d134dc6dd262 --- /dev/null +++ seismic-reth/crates/seismic/primitives/src/receipt.rs @@ -0,0 +1,709 @@ +use alloy_consensus::{ + proofs::ordered_trie_root_with_encoder, Eip2718EncodableReceipt, Eip658Value, Receipt, + ReceiptWithBloom, RlpDecodableReceipt, RlpEncodableReceipt, TxReceipt, Typed2718, +}; +use alloy_eips::{eip2718::Eip2718Result, Decodable2718, Encodable2718}; +use alloy_primitives::{Bloom, Log, B256}; +use alloy_rlp::{BufMut, Decodable, Encodable, Header}; +use reth_primitives_traits::InMemorySize; +use seismic_alloy_consensus::SeismicTxType; + +/// Typed ethereum transaction receipt. +/// Receipt containing result of transaction execution. +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] +pub enum SeismicReceipt { + /// Legacy receipt + Legacy(Receipt), + /// EIP-2930 receipt + Eip2930(Receipt), + /// EIP-1559 receipt + Eip1559(Receipt), + /// EIP-4844 receipt + Eip4844(Receipt), + /// EIP-7702 receipt + Eip7702(Receipt), + /// Seismic receipt + Seismic(Receipt), +} + +impl Default for SeismicReceipt { + fn default() -> Self { + Self::Legacy(Default::default()) + } +} + +impl SeismicReceipt { + /// Returns [`SeismicTxType`] of the receipt. + pub const fn tx_type(&self) -> SeismicTxType { + match self { + Self::Legacy(_) => SeismicTxType::Legacy, + Self::Eip2930(_) => SeismicTxType::Eip2930, + Self::Eip1559(_) => SeismicTxType::Eip1559, + Self::Eip4844(_) => SeismicTxType::Eip4844, + Self::Eip7702(_) => SeismicTxType::Eip7702, + Self::Seismic(_) => SeismicTxType::Seismic, + } + } + + /// Returns inner [`Receipt`], + pub const fn as_receipt(&self) -> &Receipt { + match self { + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip4844(receipt) | + Self::Eip7702(receipt) | + Self::Seismic(receipt) => receipt, + } + } + + /// Returns a mutable reference to the inner [`Receipt`], + pub const fn as_receipt_mut(&mut self) -> &mut Receipt { + match self { + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip4844(receipt) | + Self::Eip7702(receipt) | + Self::Seismic(receipt) => receipt, + } + } + + /// Consumes this and returns the inner [`Receipt`]. + pub fn into_receipt(self) -> Receipt { + match self { + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip4844(receipt) | + Self::Eip7702(receipt) | + Self::Seismic(receipt) => receipt, + } + } + + /// Returns length of RLP-encoded receipt fields with the given [`Bloom`] without an RLP header. + pub fn rlp_encoded_fields_length(&self, bloom: &Bloom) -> usize { + match self { + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip4844(receipt) | + Self::Eip7702(receipt) | + Self::Seismic(receipt) => receipt.rlp_encoded_fields_length_with_bloom(bloom), + } + } + + /// RLP-encodes receipt fields with the given [`Bloom`] without an RLP header. + pub fn rlp_encode_fields(&self, bloom: &Bloom, out: &mut dyn BufMut) { + match self { + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip4844(receipt) | + Self::Eip7702(receipt) | + Self::Seismic(receipt) => receipt.rlp_encode_fields_with_bloom(bloom, out), + } + } + + /// Returns RLP header for inner encoding. + pub fn rlp_header_inner(&self, bloom: &Bloom) -> Header { + Header { list: true, payload_length: self.rlp_encoded_fields_length(bloom) } + } + + /// Returns RLP header for inner encoding without bloom. + pub fn rlp_header_inner_without_bloom(&self) -> Header { + Header { list: true, payload_length: self.rlp_encoded_fields_length_without_bloom() } + } + + /// RLP-decodes the receipt from the provided buffer. This does not expect a type byte or + /// network header. + pub fn rlp_decode_inner( + buf: &mut &[u8], + tx_type: SeismicTxType, + ) -> alloy_rlp::Result<ReceiptWithBloom<Self>> { + match tx_type { + SeismicTxType::Legacy => { + let ReceiptWithBloom { receipt, logs_bloom } = + RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; + Ok(ReceiptWithBloom { receipt: Self::Legacy(receipt), logs_bloom }) + } + SeismicTxType::Eip2930 => { + let ReceiptWithBloom { receipt, logs_bloom } = + RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; + Ok(ReceiptWithBloom { receipt: Self::Eip2930(receipt), logs_bloom }) + } + SeismicTxType::Eip1559 => { + let ReceiptWithBloom { receipt, logs_bloom } = + RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; + Ok(ReceiptWithBloom { receipt: Self::Eip1559(receipt), logs_bloom }) + } + SeismicTxType::Eip4844 => { + let ReceiptWithBloom { receipt, logs_bloom } = + RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; + Ok(ReceiptWithBloom { receipt: Self::Eip4844(receipt), logs_bloom }) + } + SeismicTxType::Eip7702 => { + let ReceiptWithBloom { receipt, logs_bloom } = + RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; + Ok(ReceiptWithBloom { receipt: Self::Eip7702(receipt), logs_bloom }) + } + SeismicTxType::Seismic => { + let ReceiptWithBloom { receipt, logs_bloom } = + RlpDecodableReceipt::rlp_decode_with_bloom(buf)?; + Ok(ReceiptWithBloom { receipt: Self::Seismic(receipt), logs_bloom }) + } + } + } + + /// RLP-encodes receipt fields without an RLP header. + pub fn rlp_encode_fields_without_bloom(&self, out: &mut dyn BufMut) { + match self { + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip4844(receipt) | + Self::Eip7702(receipt) | + Self::Seismic(receipt) => { + receipt.status.encode(out); + receipt.cumulative_gas_used.encode(out); + receipt.logs.encode(out); + } + } + } + + /// Returns length of RLP-encoded receipt fields without an RLP header. + pub fn rlp_encoded_fields_length_without_bloom(&self) -> usize { + match self { + Self::Legacy(receipt) | + Self::Eip2930(receipt) | + Self::Eip1559(receipt) | + Self::Eip4844(receipt) | + Self::Eip7702(receipt) | + Self::Seismic(receipt) => { + receipt.status.length() + + receipt.cumulative_gas_used.length() + + receipt.logs.length() + } + } + } + + /// RLP-decodes the receipt from the provided buffer without bloom. + pub fn rlp_decode_inner_without_bloom( + buf: &mut &[u8], + tx_type: SeismicTxType, + ) -> alloy_rlp::Result<Self> { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + + let remaining = buf.len(); + let status = Decodable::decode(buf)?; + let cumulative_gas_used = Decodable::decode(buf)?; + let logs = Decodable::decode(buf)?; + + if buf.len() + header.payload_length != remaining { + return Err(alloy_rlp::Error::UnexpectedLength); + } + + match tx_type { + SeismicTxType::Legacy => { + Ok(Self::Legacy(Receipt { status, cumulative_gas_used, logs })) + } + SeismicTxType::Eip2930 => { + Ok(Self::Eip2930(Receipt { status, cumulative_gas_used, logs })) + } + SeismicTxType::Eip1559 => { + Ok(Self::Eip1559(Receipt { status, cumulative_gas_used, logs })) + } + SeismicTxType::Eip4844 => { + Ok(Self::Eip4844(Receipt { status, cumulative_gas_used, logs })) + } + SeismicTxType::Eip7702 => { + Ok(Self::Eip7702(Receipt { status, cumulative_gas_used, logs })) + } + SeismicTxType::Seismic => { + Ok(Self::Seismic(Receipt { status, cumulative_gas_used, logs })) + } + } + } + + /// Calculates the receipt root for a header for the reference type of [Receipt]. + /// + /// NOTE: Prefer `proofs::calculate_receipt_root` if you have log blooms memoized. + pub fn calculate_receipt_root_no_memo(receipts: &[Self]) -> B256 { + ordered_trie_root_with_encoder(receipts, |r, buf| r.with_bloom_ref().encode_2718(buf)) + } +} + +impl Eip2718EncodableReceipt for SeismicReceipt { + fn eip2718_encoded_length_with_bloom(&self, bloom: &Bloom) -> usize { + !self.tx_type().is_legacy() as usize + self.rlp_header_inner(bloom).length_with_payload() + } + + fn eip2718_encode_with_bloom(&self, bloom: &Bloom, out: &mut dyn BufMut) { + if !self.tx_type().is_legacy() { + out.put_u8(self.tx_type() as u8); + } + self.rlp_header_inner(bloom).encode(out); + self.rlp_encode_fields(bloom, out); + } +} + +impl RlpEncodableReceipt for SeismicReceipt { + fn rlp_encoded_length_with_bloom(&self, bloom: &Bloom) -> usize { + let mut len = self.eip2718_encoded_length_with_bloom(bloom); + if !self.tx_type().is_legacy() { + len += Header { + list: false, + payload_length: self.eip2718_encoded_length_with_bloom(bloom), + } + .length(); + } + + len + } + + fn rlp_encode_with_bloom(&self, bloom: &Bloom, out: &mut dyn BufMut) { + if !self.tx_type().is_legacy() { + Header { list: false, payload_length: self.eip2718_encoded_length_with_bloom(bloom) } + .encode(out); + } + self.eip2718_encode_with_bloom(bloom, out); + } +} + +impl RlpDecodableReceipt for SeismicReceipt { + fn rlp_decode_with_bloom(buf: &mut &[u8]) -> alloy_rlp::Result<ReceiptWithBloom<Self>> { + let header_buf = &mut &**buf; + let header = Header::decode(header_buf)?; + + // Legacy receipt, reuse initial buffer without advancing + if header.list { + return Self::rlp_decode_inner(buf, SeismicTxType::Legacy) + } + + // Otherwise, advance the buffer and try decoding type flag followed by receipt + *buf = *header_buf; + + let remaining = buf.len(); + let tx_type = SeismicTxType::decode(buf)?; + let this = Self::rlp_decode_inner(buf, tx_type)?; + + if buf.len() + header.payload_length != remaining { + return Err(alloy_rlp::Error::UnexpectedLength); + } + + Ok(this) + } +} + +impl Encodable2718 for SeismicReceipt { + fn encode_2718_len(&self) -> usize { + !self.tx_type().is_legacy() as usize + + self.rlp_header_inner_without_bloom().length_with_payload() + } + + fn encode_2718(&self, out: &mut dyn BufMut) { + if !self.tx_type().is_legacy() { + out.put_u8(self.tx_type() as u8); + } + self.rlp_header_inner_without_bloom().encode(out); + self.rlp_encode_fields_without_bloom(out); + } +} + +impl Decodable2718 for SeismicReceipt { + fn typed_decode(ty: u8, buf: &mut &[u8]) -> Eip2718Result<Self> { + Ok(Self::rlp_decode_inner_without_bloom(buf, SeismicTxType::try_from(ty)?)?) + } + + fn fallback_decode(buf: &mut &[u8]) -> Eip2718Result<Self> { + Ok(Self::rlp_decode_inner_without_bloom(buf, SeismicTxType::Legacy)?) + } +} + +impl Encodable for SeismicReceipt { + fn encode(&self, out: &mut dyn BufMut) { + self.network_encode(out); + } + + fn length(&self) -> usize { + self.network_len() + } +} + +impl Decodable for SeismicReceipt { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> { + Ok(Self::network_decode(buf)?) + } +} + +impl TxReceipt for SeismicReceipt { + type Log = Log; + + fn status_or_post_state(&self) -> Eip658Value { + self.as_receipt().status_or_post_state() + } + + fn status(&self) -> bool { + self.as_receipt().status() + } + + fn bloom(&self) -> Bloom { + self.as_receipt().bloom() + } + + fn cumulative_gas_used(&self) -> u64 { + self.as_receipt().cumulative_gas_used() + } + + fn logs(&self) -> &[Log] { + self.as_receipt().logs() + } +} + +impl Typed2718 for SeismicReceipt { + fn ty(&self) -> u8 { + self.tx_type().into() + } +} + +impl InMemorySize for SeismicReceipt { + fn size(&self) -> usize { + self.as_receipt().size() + } +} + +#[cfg(feature = "reth-codec")] +mod compact { + use super::*; + use alloc::borrow::Cow; + use reth_codecs::Compact; + + #[derive(reth_codecs::CompactZstd)] + #[reth_zstd( + compressor = reth_zstd_compressors::RECEIPT_COMPRESSOR, + decompressor = reth_zstd_compressors::RECEIPT_DECOMPRESSOR + )] + struct CompactSeismicReceipt<'a> { + tx_type: SeismicTxType, + success: bool, + cumulative_gas_used: u64, + #[expect(clippy::owned_cow)] + logs: Cow<'a, Vec<Log>>, + } + + impl<'a> From<&'a SeismicReceipt> for CompactSeismicReceipt<'a> { + fn from(receipt: &'a SeismicReceipt) -> Self { + Self { + tx_type: receipt.tx_type(), + success: receipt.status(), + cumulative_gas_used: receipt.cumulative_gas_used(), + logs: Cow::Borrowed(&receipt.as_receipt().logs), + } + } + } + + impl From<CompactSeismicReceipt<'_>> for SeismicReceipt { + fn from(receipt: CompactSeismicReceipt<'_>) -> Self { + let CompactSeismicReceipt { tx_type, success, cumulative_gas_used, logs } = receipt; + + let inner = + Receipt { status: success.into(), cumulative_gas_used, logs: logs.into_owned() }; + + match tx_type { + SeismicTxType::Legacy => Self::Legacy(inner), + SeismicTxType::Eip2930 => Self::Eip2930(inner), + SeismicTxType::Eip1559 => Self::Eip1559(inner), + SeismicTxType::Eip4844 => Self::Eip4844(inner), + SeismicTxType::Eip7702 => Self::Eip7702(inner), + SeismicTxType::Seismic => Self::Seismic(inner), + } + } + } + + impl Compact for SeismicReceipt { + fn to_compact<B>(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + CompactSeismicReceipt::from(self).to_compact(buf) + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { + let (receipt, buf) = CompactSeismicReceipt::from_compact(buf, len); + (receipt.into(), buf) + } + } +} + +#[cfg(all(feature = "serde", feature = "serde-bincode-compat"))] +pub(super) mod serde_bincode_compat { + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use serde_with::{DeserializeAs, SerializeAs}; + + /// Bincode-compatible [`super::SeismicReceipt`] serde implementation. + /// + /// Intended to use with the [`serde_with::serde_as`] macro in the following way: + /// ```rust + /// use reth_seismic_primitives::{serde_bincode_compat, SeismicReceipt}; + /// use serde::{de::DeserializeOwned, Deserialize, Serialize}; + /// use serde_with::serde_as; + /// + /// #[serde_as] + /// #[derive(Serialize, Deserialize)] + /// struct Data { + /// #[serde_as(as = "serde_bincode_compat::SeismicReceipt<'_>")] + /// receipt: SeismicReceipt, + /// } + /// ``` + #[derive(Debug, Serialize, Deserialize)] + pub enum SeismicReceipt<'a> { + /// Legacy receipt + Legacy(alloy_consensus::serde_bincode_compat::Receipt<'a, alloy_primitives::Log>), + /// EIP-2930 receipt + Eip2930(alloy_consensus::serde_bincode_compat::Receipt<'a, alloy_primitives::Log>), + /// EIP-1559 receipt + Eip1559(alloy_consensus::serde_bincode_compat::Receipt<'a, alloy_primitives::Log>), + /// EIP-4844 receipt + Eip4844(alloy_consensus::serde_bincode_compat::Receipt<'a, alloy_primitives::Log>), + /// EIP-7702 receipt + Eip7702(alloy_consensus::serde_bincode_compat::Receipt<'a, alloy_primitives::Log>), + /// Seismic receipt + Seismic(alloy_consensus::serde_bincode_compat::Receipt<'a, alloy_primitives::Log>), + } + + impl<'a> From<&'a super::SeismicReceipt> for SeismicReceipt<'a> { + fn from(value: &'a super::SeismicReceipt) -> Self { + match value { + super::SeismicReceipt::Legacy(receipt) => Self::Legacy(receipt.into()), + super::SeismicReceipt::Eip2930(receipt) => Self::Eip2930(receipt.into()), + super::SeismicReceipt::Eip1559(receipt) => Self::Eip1559(receipt.into()), + super::SeismicReceipt::Eip4844(receipt) => Self::Eip4844(receipt.into()), + super::SeismicReceipt::Eip7702(receipt) => Self::Eip7702(receipt.into()), + super::SeismicReceipt::Seismic(receipt) => Self::Seismic(receipt.into()), + } + } + } + + impl<'a> From<SeismicReceipt<'a>> for super::SeismicReceipt { + fn from(value: SeismicReceipt<'a>) -> Self { + match value { + SeismicReceipt::Legacy(receipt) => Self::Legacy(receipt.into()), + SeismicReceipt::Eip2930(receipt) => Self::Eip2930(receipt.into()), + SeismicReceipt::Eip1559(receipt) => Self::Eip1559(receipt.into()), + SeismicReceipt::Eip4844(receipt) => Self::Eip4844(receipt.into()), + SeismicReceipt::Eip7702(receipt) => Self::Eip7702(receipt.into()), + SeismicReceipt::Seismic(receipt) => Self::Seismic(receipt.into()), + } + } + } + + impl SerializeAs<super::SeismicReceipt> for SeismicReceipt<'_> { + fn serialize_as<S>(source: &super::SeismicReceipt, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + SeismicReceipt::<'_>::from(source).serialize(serializer) + } + } + + impl<'de> DeserializeAs<'de, super::SeismicReceipt> for SeismicReceipt<'de> { + fn deserialize_as<D>(deserializer: D) -> Result<super::SeismicReceipt, D::Error> + where + D: Deserializer<'de>, + { + SeismicReceipt::<'_>::deserialize(deserializer).map(Into::into) + } + } + + impl reth_primitives_traits::serde_bincode_compat::SerdeBincodeCompat for super::SeismicReceipt { + type BincodeRepr<'a> = SeismicReceipt<'a>; + + fn as_repr(&self) -> Self::BincodeRepr<'_> { + self.into() + } + + fn from_repr(repr: Self::BincodeRepr<'_>) -> Self { + repr.into() + } + } + + #[cfg(test)] + #[allow(clippy::expect_used)] // Test code - expect on failure is acceptable + #[allow(clippy::unwrap_used)] // Test code - unwrap on failure is acceptable + #[allow(clippy::panic)] // Test code - panic on failure is acceptable + mod tests { + use crate::{receipt::serde_bincode_compat, SeismicReceipt}; + use arbitrary::Arbitrary; + use rand::Rng; + use serde::{Deserialize, Serialize}; + use serde_with::serde_as; + + #[test] + fn test_tx_bincode_roundtrip() { + #[serde_as] + #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] + struct Data { + #[serde_as(as = "serde_bincode_compat::SeismicReceipt<'_>")] + receipt: SeismicReceipt, + } + + let mut bytes = [0u8; 1024]; + rand::rng().fill(bytes.as_mut_slice()); + let mut data = Data { + receipt: SeismicReceipt::arbitrary(&mut arbitrary::Unstructured::new(&bytes)) + .unwrap(), + }; + let success = data.receipt.as_receipt_mut().status.coerce_status(); + // // ensure we don't have an invalid poststate variant + data.receipt.as_receipt_mut().status = success.into(); + + let encoded = bincode::serialize(&data).unwrap(); + let decoded: Data = bincode::deserialize(&encoded).unwrap(); + assert_eq!(decoded, data); + } + } +} + +#[cfg(test)] +#[allow(clippy::expect_used)] // Test code - expect on failure is acceptable +#[allow(clippy::unwrap_used)] // Test code - unwrap on failure is acceptable +#[allow(clippy::panic)] // Test code - panic on failure is acceptable +mod tests { + use super::*; + use alloy_eips::eip2718::Encodable2718; + use alloy_primitives::{address, b256, bytes, hex_literal::hex}; + use alloy_rlp::Encodable; + + #[test] + #[cfg(feature = "reth-codec")] + // checks compact encoding, test decode performs a roundtrip check + fn test_decode_receipt() { + reth_codecs::test_utils::test_decode::<SeismicReceipt>(&hex!( + "c428b52ffd23fc42696156b10200f034792b6a94c3850215c2fef7aea361a0c31b79d9a32652eefc0d4e2e730036061cff7344b6fc6132b50cda0ed810a991ae58ef013150c12b2522533cb3b3a8b19b7786a8b5ff1d3cdc84225e22b02def168c8858df" + )); + } + + // Test vector from: https://eips.ethereum.org/EIPS/eip-2481 + // checks rlp encoding + #[test] + fn encode_legacy_receipt() { + let expected = hex!("f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"); + + let mut data = Vec::with_capacity(expected.length()); + let receipt = ReceiptWithBloom { + receipt: SeismicReceipt::Legacy(Receipt { + status: Eip658Value::Eip658(false), + cumulative_gas_used: 0x1, + logs: vec![Log::new_unchecked( + address!("0x0000000000000000000000000000000000000011"), + vec![ + b256!("0x000000000000000000000000000000000000000000000000000000000000dead"), + b256!("0x000000000000000000000000000000000000000000000000000000000000beef"), + ], + bytes!("0100ff"), + )], + }), + logs_bloom: [0; 256].into(), + }; + + receipt.encode(&mut data); + + // check that the rlp length equals the length of the expected rlp + assert_eq!(receipt.length(), expected.len()); + assert_eq!(data, expected); + } + + // Test vector from: https://eips.ethereum.org/EIPS/eip-2481 + // checks rlp decoding + #[test] + fn decode_legacy_receipt() { + let data = hex!("f901668001b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f85ff85d940000000000000000000000000000000000000011f842a0000000000000000000000000000000000000000000000000000000000000deada0000000000000000000000000000000000000000000000000000000000000beef830100ff"); + + // EIP658Receipt + let expected = ReceiptWithBloom { + receipt: SeismicReceipt::Legacy(Receipt { + status: Eip658Value::Eip658(false), + cumulative_gas_used: 0x1, + logs: vec![Log::new_unchecked( + address!("0x0000000000000000000000000000000000000011"), + vec![ + b256!("0x000000000000000000000000000000000000000000000000000000000000dead"), + b256!("0x000000000000000000000000000000000000000000000000000000000000beef"), + ], + bytes!("0100ff"), + )], + }), + logs_bloom: [0; 256].into(), + }; + + let receipt = ReceiptWithBloom::decode(&mut &data[..]).unwrap(); + assert_eq!(receipt, expected); + } + + #[test] + fn test_encode_2718_length() { + let receipt = ReceiptWithBloom { + receipt: SeismicReceipt::Eip1559(Receipt { + status: Eip658Value::Eip658(true), + cumulative_gas_used: 21000, + logs: vec![], + }), + logs_bloom: Bloom::default(), + }; + + let encoded = receipt.encoded_2718(); + assert_eq!( + encoded.len(), + receipt.encode_2718_len(), + "Encoded length should match the actual encoded data length" + ); + + // Test for legacy receipt as well + let legacy_receipt = ReceiptWithBloom { + receipt: SeismicReceipt::Legacy(Receipt { + status: Eip658Value::Eip658(true), + cumulative_gas_used: 21000, + logs: vec![], + }), + logs_bloom: Bloom::default(), + }; + + let legacy_encoded = legacy_receipt.encoded_2718(); + assert_eq!( + legacy_encoded.len(), + legacy_receipt.encode_2718_len(), + "Encoded length for legacy receipt should match the actual encoded data length" + ); + } + + #[test] + // checks rlp encoding for SeismicReceipt::Seismic + fn seismic_seismic_receipt_roundtrip() { + let receipt: ReceiptWithBloom<SeismicReceipt> = ReceiptWithBloom { + receipt: SeismicReceipt::Legacy(Receipt { + status: Eip658Value::Eip658(false), + cumulative_gas_used: 0x1, + logs: vec![Log::new_unchecked( + address!("0x0000000000000000000000000000000000000011"), + vec![ + b256!("0x000000000000000000000000000000000000000000000000000000000000dead"), + b256!("0x000000000000000000000000000000000000000000000000000000000000beef"), + ], + bytes!("0100ff"), + )], + }), + logs_bloom: [0; 256].into(), + }; + + let mut data = Vec::with_capacity(receipt.encode_2718_len()); + receipt.encode(&mut data); + let decoded: ReceiptWithBloom<SeismicReceipt> = + ReceiptWithBloom::decode(&mut &data[..]).unwrap(); + assert_eq!(receipt, decoded); + } +}
diff --git reth/crates/seismic/primitives/src/test_utils.rs seismic-reth/crates/seismic/primitives/src/test_utils.rs new file mode 100644 index 0000000000000000000000000000000000000000..7dd531d2c0df33472ed1a4db04132c6477316d0a --- /dev/null +++ seismic-reth/crates/seismic/primitives/src/test_utils.rs @@ -0,0 +1,342 @@ +//! Test utils for seismic primitives, e.g. `SeismicTransactionSigned` + +#![allow(clippy::unwrap_used, clippy::expect_used)] // Test utilities - panics are acceptable + +use crate::SeismicTransactionSigned; +use alloy_consensus::SignableTransaction; +use alloy_dyn_abi::TypedData; +use alloy_eips::eip2718::Encodable2718; +use alloy_network::{EthereumWallet, TransactionBuilder}; +use alloy_primitives::{aliases::U96, hex_literal, Address, Bytes, Signature, TxKind, B256, U256}; +use alloy_rpc_types::{TransactionInput, TransactionRequest}; +use alloy_signer_local::PrivateKeySigner; +use core::str::FromStr; +use enr::EnrKey; +use k256::ecdsa::SigningKey; +use seismic_enclave::get_unsecure_sample_secp256k1_pk; + +use secp256k1::{PublicKey, SecretKey}; +use seismic_alloy_consensus::{ + InputDecryptionElements, SeismicTxEnvelope, SeismicTypedTransaction, TxLegacyFields, TxSeismic, + TxSeismicElements, TxSeismicMetadata, TypedDataRequest, +}; +use seismic_alloy_rpc_types::SeismicTransactionRequest; + +/// Get the network public key +pub fn get_network_public_key() -> PublicKey { + get_unsecure_sample_secp256k1_pk() +} + +/// Get the client's sk for tx io +pub fn get_client_io_sk() -> SecretKey { + let private_key_bytes = + hex_literal::hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + SecretKey::from_slice(&private_key_bytes).expect("Invalid private key") +} + +/// Get the client's signing private key +pub fn get_signing_private_key() -> SigningKey { + let private_key_bytes = + hex_literal::hex!("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"); + + SigningKey::from_bytes(&private_key_bytes.into()).expect("Invalid private key") +} + +/// Get a wrong private secp256k1 key +pub fn get_wrong_private_key() -> SecretKey { + let private_key_bytes = + hex_literal::hex!("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1e"); + SecretKey::from_slice(&private_key_bytes).expect("Invalid private key") +} + +/// Get the encryption nonce +pub const fn get_encryption_nonce() -> U96 { + U96::MAX +} + +/// Get the seismic elements +pub fn get_seismic_elements(recent_block_hash: B256) -> TxSeismicElements { + TxSeismicElements { + encryption_pubkey: get_client_io_sk().public(), + encryption_nonce: get_encryption_nonce(), + message_version: 0, + recent_block_hash, + expires_at_block: 1000000, + signed_read: false, + } +} + +/// Encrypt plaintext using network public key and client private key +pub fn client_encrypt( + metadata: &TxSeismicMetadata, + plaintext: &Bytes, +) -> Result<Bytes, anyhow::Error> { + metadata.client_encrypt(plaintext, &get_network_public_key(), &get_client_io_sk()) +} + +/// Decrypt ciphertext using network public key and client private key +pub fn client_decrypt( + metadata: TxSeismicMetadata, + ciphertext: &Bytes, +) -> Result<Bytes, anyhow::Error> { + let plaintext = + metadata.client_decrypt(ciphertext, &get_network_public_key(), &get_client_io_sk())?; + Ok(plaintext) +} + +/// Get the plaintext for a seismic transaction +pub fn get_plaintext() -> Bytes { + Bytes::from_str("24a7f0b7000000000000000000000000000000000000000000000000000000000000000b") + .unwrap() +} + +/// Encrypt plaintext using network public key and client private key +pub fn get_ciphertext(metadata: &TxSeismicMetadata) -> Bytes { + metadata + .client_encrypt(&get_plaintext(), &get_network_public_key(), &get_client_io_sk()) + .unwrap() +} + +/// Get a seismic transaction +pub fn get_seismic_tx(sender: Address, recent_block_hash: B256) -> TxSeismic { + let mut tx = TxSeismic { + chain_id: 5123, // seismic chain id + nonce: 1, + gas_price: 20000000000, + gas_limit: 210000, + to: alloy_primitives::TxKind::Call( + Address::from_str("0x5fbdb2315678afecb367f032d93f642f64180aa3").unwrap(), + ), + value: U256::ZERO, + input: Bytes::new(), + seismic_elements: get_seismic_elements(recent_block_hash), + authorization_list: vec![], + }; + let ciphertext = get_ciphertext(&tx.metadata(sender).unwrap()); + tx.input = ciphertext; + tx +} + +/// Sign a seismic transaction +pub fn sign_seismic_tx(tx: &TxSeismic, signing_sk: &SigningKey) -> Signature { + let _signature = signing_sk + .clone() + .sign_prehash_recoverable(tx.signature_hash().as_slice()) + .expect("Failed to sign"); + + let recoverid = _signature.1; + let _signature = _signature.0; + + let signature = Signature::new( + U256::from_be_slice(_signature.r().to_bytes().as_ref()), + U256::from_be_slice(_signature.s().to_bytes().as_ref()), + recoverid.is_y_odd(), + ); + + signature +} + +/// signes a [`SeismicTypedTransaction`] using the provided [`SigningKey`] +pub fn sign_seismic_typed_tx( + typed_data: &SeismicTypedTransaction, + signing_sk: &SigningKey, +) -> Signature { + let sig_hash = typed_data.signature_hash(); + let sig = signing_sk.sign_prehash_recoverable(sig_hash.as_slice()).unwrap(); + let recoverid = sig.1; + + let signature = Signature::new( + U256::from_be_slice(sig.0.r().to_bytes().as_ref()), + U256::from_be_slice(sig.0.s().to_bytes().as_ref()), + recoverid.is_y_odd(), + ); + signature +} + +/// Get a signed seismic transaction +pub fn get_signed_seismic_tx(recent_block_hash: B256) -> SeismicTransactionSigned { + let signing_sk = get_signing_private_key(); + let sender = Address::from_public_key(signing_sk.verifying_key()); + let tx = get_seismic_tx(sender, recent_block_hash); + let signature = sign_seismic_tx(&tx, &signing_sk); + SignableTransaction::into_signed(tx, signature).into() +} + +/// Get the encoding of a signed seismic transaction +pub fn get_signed_seismic_tx_encoding(recent_block_hash: B256) -> Vec<u8> { + let signed_tx = get_signed_seismic_tx(recent_block_hash); + let mut encoding = Vec::new(); + + signed_tx.encode_2718(&mut encoding); + encoding +} + +fn get_plaintext_tx_request( + sk_wallet: &PrivateKeySigner, + nonce: u64, + to: TxKind, + chain_id: u64, + plaintext: &Bytes, +) -> TransactionRequest { + TransactionRequest { + from: Some(sk_wallet.address()), + nonce: Some(nonce), + value: Some(U256::from(0)), + to: Some(to), + gas: Some(6000000), + gas_price: Some(20e9 as u128), + chain_id: Some(chain_id), + input: TransactionInput { input: Some(plaintext.clone()), data: None }, + transaction_type: Some(TxSeismic::TX_TYPE), + ..Default::default() + } +} + +fn get_metadata(plaintext_req: &TransactionRequest, recent_block_hash: B256) -> TxSeismicMetadata { + TxSeismicMetadata { + sender: plaintext_req.from.unwrap(), + legacy_fields: TxLegacyFields { + chain_id: plaintext_req.chain_id.unwrap(), + nonce: plaintext_req.nonce.unwrap(), + to: plaintext_req.to.unwrap(), + value: plaintext_req.value.unwrap(), + }, + seismic_elements: get_seismic_elements(recent_block_hash), + } +} + +/// Get seismic transaction metadata for testing +pub fn get_seismic_metadata( + sender: Address, + chain_id: u64, + nonce: u64, + to: TxKind, + value: U256, + recent_block_hash: B256, +) -> TxSeismicMetadata { + TxSeismicMetadata { + sender, + legacy_fields: TxLegacyFields { chain_id, nonce, to, value }, + seismic_elements: get_seismic_elements(recent_block_hash), + } +} + +/// Get an unsigned seismic transaction request +pub async fn get_unsigned_seismic_tx_request( + sk_wallet: &PrivateKeySigner, + nonce: u64, + to: TxKind, + chain_id: u64, + plaintext: Bytes, + recent_block_hash: B256, +) -> SeismicTransactionRequest { + let mut plaintext_req = get_plaintext_tx_request(sk_wallet, nonce, to, chain_id, &plaintext); + let metadata = get_metadata(&plaintext_req, recent_block_hash); + let ciphertext = metadata + .client_encrypt(&plaintext, &get_network_public_key(), &get_client_io_sk()) + .unwrap(); + plaintext_req.input = TransactionInput { input: Some(ciphertext), data: None }; + SeismicTransactionRequest { + inner: plaintext_req, + seismic_elements: Some(metadata.seismic_elements), + } +} + +/// Get an unsigned seismic transaction request +pub async fn get_unsigned_legacy_tx_request( + sk_wallet: &PrivateKeySigner, + nonce: u64, + to: TxKind, + chain_id: u64, + plaintext: Bytes, +) -> SeismicTransactionRequest { + let mut plaintext_req = get_plaintext_tx_request(sk_wallet, nonce, to, chain_id, &plaintext); + plaintext_req.transaction_type = None; + SeismicTransactionRequest { inner: plaintext_req, seismic_elements: None } +} + +/// Signs an arbitrary [`TransactionRequest`] using the provided wallet +pub async fn sign_tx(wallet: PrivateKeySigner, tx: SeismicTransactionRequest) -> SeismicTxEnvelope { + let signer = EthereumWallet::from(wallet); + <SeismicTransactionRequest as TransactionBuilder<seismic_alloy_network::Seismic>>::build( + tx, &signer, + ) + .await + .unwrap() +} + +/// Create a seismic transaction +pub async fn get_signed_seismic_tx_bytes( + sk_wallet: &PrivateKeySigner, + nonce: u64, + to: TxKind, + chain_id: u64, + plaintext: Bytes, + recent_block_hash: B256, +) -> Bytes { + let tx = get_unsigned_seismic_tx_request( + sk_wallet, + nonce, + to, + chain_id, + plaintext, + recent_block_hash, + ) + .await; + let signed_inner = sign_tx(sk_wallet.clone(), tx).await; + <SeismicTxEnvelope as Encodable2718>::encoded_2718(&signed_inner).into() +} + +/// Get an unsigned seismic transaction typed data +#[allow(clippy::panic)] // Test util function - panic on failure is acceptable +pub async fn get_unsigned_seismic_tx_typed_data( + sk_wallet: &PrivateKeySigner, + nonce: u64, + to: TxKind, + chain_id: u64, + decrypted_input: Bytes, + recent_block_hash: B256, +) -> TypedData { + let tx_request = get_unsigned_seismic_tx_request( + sk_wallet, + nonce, + to, + chain_id, + decrypted_input, + recent_block_hash, + ) + .await; + let typed_tx = tx_request.build_typed_tx().unwrap(); + match typed_tx { + SeismicTypedTransaction::Seismic(seismic) => seismic.eip712_to_type_data(), + _ => panic!("Typed transaction is not a seismic transaction"), + } +} + +/// Create a seismic transaction with typed data +#[allow(clippy::panic)] // Test util function - panic on failure is acceptable +pub async fn get_signed_seismic_tx_typed_data( + sk_wallet: &PrivateKeySigner, + nonce: u64, + to: TxKind, + chain_id: u64, + plaintext: Bytes, + recent_block_hash: B256, +) -> TypedDataRequest { + let tx = get_unsigned_seismic_tx_request( + sk_wallet, + nonce, + to, + chain_id, + plaintext, + recent_block_hash, + ) + .await; + tx.seismic_elements.unwrap().message_version = 2; + let signed = sign_tx(sk_wallet.clone(), tx).await; + + match signed { + SeismicTxEnvelope::Seismic(tx) => tx.into(), + _ => panic!("Signed transaction is not a seismic transaction"), + } +}
diff --git reth/crates/seismic/primitives/src/transaction/error.rs seismic-reth/crates/seismic/primitives/src/transaction/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..fbdc4402b711c1b31f75c3ee71dd253f177c26ed --- /dev/null +++ seismic-reth/crates/seismic/primitives/src/transaction/error.rs @@ -0,0 +1,32 @@ +//! Seismic transaction error types + +use alloy_primitives::B256; + +/// Errors specific to seismic transactions +#[derive(Debug, Clone, Eq, PartialEq, derive_more::Display)] +pub enum SeismicTxError { + /// The `recent_block_hash` was not found in the last `lookback` blocks + #[display("recent_block_hash {hash} not found in the last {lookback} blocks")] + RecentBlockHashNotFound { + /// The `recent_block_hash` that was provided + hash: B256, + /// Number of blocks searched + lookback: u64, + }, + /// The transaction has expired based on `expires_at_block` + #[display( + "transaction expired: current block {current_block} > expires_at_block {expires_at_block}" + )] + TransactionExpired { + /// Current block number + current_block: u64, + /// The block number at which the transaction expires + expires_at_block: u64, + }, + /// A write transaction (non-contract creation) cannot have `signed_read` = true + #[display("write transactions cannot have signed_read set to true")] + InvalidSignedReadForWrite, + /// Failed to decrypt calldata of seismic tx + #[display("failed to decrypt seismic transaction")] + FailedToDecrypt, +}
diff --git reth/crates/seismic/primitives/src/transaction/mod.rs seismic-reth/crates/seismic/primitives/src/transaction/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..030131761d4ccd55633ae3b87ff79f42ce0ae637 --- /dev/null +++ seismic-reth/crates/seismic/primitives/src/transaction/mod.rs @@ -0,0 +1,5 @@ +//! Optimism transaction types + +pub mod error; +pub mod signed; +pub mod tx_type;
diff --git reth/crates/seismic/primitives/src/transaction/signed.rs seismic-reth/crates/seismic/primitives/src/transaction/signed.rs new file mode 100644 index 0000000000000000000000000000000000000000..0969f135acc1bf0b7c0ef31ebf3c9689c1e39c08 --- /dev/null +++ seismic-reth/crates/seismic/primitives/src/transaction/signed.rs @@ -0,0 +1,798 @@ +//! A signed Seismic transaction. + +use alloc::vec::Vec; +use alloy_consensus::{ + transaction::{RlpEcdsaDecodableTx, RlpEcdsaEncodableTx}, + SignableTransaction, Signed, Transaction, TxEip1559, TxEip2930, TxEip4844, TxEip7702, TxLegacy, + Typed2718, +}; +use alloy_eips::{ + eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, + eip2930::AccessList, + eip7702::SignedAuthorization, +}; +use alloy_evm::FromRecoveredTx; +use alloy_primitives::{keccak256, Address, Bytes, Signature, TxHash, TxKind, Uint, B256}; +use alloy_rlp::Header; +use core::{ + hash::{Hash, Hasher}, + mem, + ops::Deref, +}; +use derive_more::{AsRef, Deref}; +#[cfg(any(test, feature = "reth-codec"))] +use proptest as _; +use reth_primitives_traits::{ + crypto::secp256k1::{recover_signer, recover_signer_unchecked}, + sync::OnceLock, + transaction::signed::RecoveryError, + InMemorySize, SignedTransaction, SignerRecoverable, +}; +use revm_context::TxEnv; +use seismic_alloy_consensus::{ + InputDecryptionElements, InputDecryptionElementsError, SeismicTxEnvelope, + SeismicTypedTransaction, TxSeismic, TxSeismicElements, TxSeismicMetadata, +}; +use seismic_revm::SeismicTransaction; + +// Seismic imports, not used by upstream +use alloy_evm::FromTxWithEncoded; + +/// Signed transaction. +/// +/// [`SeismicTransactionSigned`] is a wrapper around a [`SeismicTypedTransaction`] enum, +/// which can be Seismic(TxSeismic) with additional fields, or Ethereum compatible transactions. +#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(rlp))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[derive(Debug, Clone, Eq, AsRef, Deref)] +pub struct SeismicTransactionSigned { + /// Transaction hash + #[cfg_attr(feature = "serde", serde(skip))] + hash: OnceLock<TxHash>, + /// The transaction signature values + signature: Signature, + /// Raw transaction info + #[deref] + #[as_ref] + transaction: SeismicTypedTransaction, +} + +impl SeismicTransactionSigned { + /// Creates a new signed transaction from the given transaction, signature and hash. + pub fn new(transaction: SeismicTypedTransaction, signature: Signature, hash: B256) -> Self { + Self { hash: hash.into(), signature, transaction } + } + + /// Consumes the type and returns the transaction. + #[inline] + pub fn into_transaction(self) -> SeismicTypedTransaction { + self.transaction + } + + /// Returns the transaction. + #[inline] + pub const fn transaction(&self) -> &SeismicTypedTransaction { + &self.transaction + } + + /// Splits the `SeismicTransactionSigned` into its transaction and signature. + pub fn split(self) -> (SeismicTypedTransaction, Signature) { + (self.transaction, self.signature) + } + + /// Creates a new signed transaction from the given transaction and signature without the hash. + /// + /// Note: this only calculates the hash on the first [`SeismicTransactionSigned::hash`] call. + pub fn new_unhashed(transaction: SeismicTypedTransaction, signature: Signature) -> Self { + Self { hash: Default::default(), signature, transaction } + } + + /// Splits the transaction into parts. + pub fn into_parts(self) -> (SeismicTypedTransaction, Signature, B256) { + let hash = *self.hash.get_or_init(|| self.recalculate_hash()); + (self.transaction, self.signature, hash) + } +} + +impl SignerRecoverable for SeismicTransactionSigned { + fn recover_signer(&self) -> Result<Address, RecoveryError> { + let Self { transaction, signature, .. } = self; + let signature_hash = signature_hash(transaction); + recover_signer(signature, signature_hash) + } + + fn recover_signer_unchecked(&self) -> Result<Address, RecoveryError> { + let Self { transaction, signature, .. } = self; + let signature_hash = signature_hash(transaction); + recover_signer_unchecked(signature, signature_hash) + } +} + +impl SignedTransaction for SeismicTransactionSigned { + fn tx_hash(&self) -> &TxHash { + self.hash.get_or_init(|| self.recalculate_hash()) + } + + fn recalculate_hash(&self) -> B256 { + keccak256(self.encoded_2718()) + } +} + +macro_rules! impl_from_signed { + ($($tx:ident),*) => { + $( + impl From<Signed<$tx>> for SeismicTransactionSigned { + fn from(value: Signed<$tx>) -> Self { + let(tx,sig,hash) = value.into_parts(); + Self::new(tx.into(), sig, hash) + } + } + )* + }; +} + +impl_from_signed!( + TxLegacy, + TxEip2930, + TxEip1559, + TxEip4844, + TxEip7702, + TxSeismic, + SeismicTypedTransaction +); + +impl From<SeismicTxEnvelope> for SeismicTransactionSigned { + fn from(value: SeismicTxEnvelope) -> Self { + match value { + SeismicTxEnvelope::Legacy(tx) => tx.into(), + SeismicTxEnvelope::Eip2930(tx) => tx.into(), + SeismicTxEnvelope::Eip1559(tx) => tx.into(), + SeismicTxEnvelope::Eip4844(tx) => tx.into(), + SeismicTxEnvelope::Eip7702(tx) => tx.into(), + SeismicTxEnvelope::Seismic(tx) => tx.into(), + } + } +} + +impl From<SeismicTransactionSigned> for SeismicTxEnvelope { + fn from(value: SeismicTransactionSigned) -> Self { + let (tx, signature, hash) = value.into_parts(); + match tx { + SeismicTypedTransaction::Legacy(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + SeismicTypedTransaction::Eip2930(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + SeismicTypedTransaction::Eip1559(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + SeismicTypedTransaction::Eip4844(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + SeismicTypedTransaction::Seismic(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + SeismicTypedTransaction::Eip7702(tx) => { + Signed::new_unchecked(tx, signature, hash).into() + } + } + } +} + +impl From<SeismicTransactionSigned> for Signed<SeismicTypedTransaction> { + fn from(value: SeismicTransactionSigned) -> Self { + let (tx, sig, hash) = value.into_parts(); + Self::new_unchecked(tx, sig, hash) + } +} + +// This function converts reth types (SeismicTransactionSigned) to revm types +// (SeismicTransaction<TxEnv>) +impl FromRecoveredTx<SeismicTransactionSigned> for SeismicTransaction<TxEnv> { + fn from_recovered_tx(tx: &SeismicTransactionSigned, sender: Address) -> Self { + let tx_hash = *tx.tx_hash(); + let base = match &tx.transaction { + SeismicTypedTransaction::Legacy(tx) => TxEnv::from_recovered_tx(tx, sender), + SeismicTypedTransaction::Eip2930(tx) => TxEnv::from_recovered_tx(tx, sender), + SeismicTypedTransaction::Eip1559(tx) => TxEnv::from_recovered_tx(tx, sender), + SeismicTypedTransaction::Eip4844(tx) => TxEnv::from_recovered_tx(tx, sender), + SeismicTypedTransaction::Eip7702(tx) => TxEnv::from_recovered_tx(tx, sender), + SeismicTypedTransaction::Seismic(tx) => TxEnv::from_recovered_tx(tx, sender), + }; + let tx = Self { base, tx_hash, decryption_failed: false }; + tracing::debug!("from_recovered_tx: tx: {:?}", tx); + tx + } +} + +impl FromTxWithEncoded<SeismicTransactionSigned> for SeismicTransaction<TxEnv> { + fn from_encoded_tx(tx: &SeismicTransactionSigned, sender: Address, _encoded: Bytes) -> Self { + let tx_env = Self::from_recovered_tx(tx, sender); + Self { base: tx_env.base, tx_hash: tx_env.tx_hash, decryption_failed: false } + } +} + +impl InMemorySize for SeismicTransactionSigned { + #[inline] + fn size(&self) -> usize { + mem::size_of::<TxHash>() + self.transaction.size() + mem::size_of::<Signature>() + } +} + +impl alloy_rlp::Encodable for SeismicTransactionSigned { + fn encode(&self, out: &mut dyn alloy_rlp::bytes::BufMut) { + self.network_encode(out); + } + + fn length(&self) -> usize { + let mut payload_length = self.encode_2718_len(); + if !self.is_legacy() { + payload_length += Header { list: false, payload_length }.length(); + } + + payload_length + } +} + +impl alloy_rlp::Decodable for SeismicTransactionSigned { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> { + Self::network_decode(buf).map_err(Into::into) + } +} + +impl Encodable2718 for SeismicTransactionSigned { + fn type_flag(&self) -> Option<u8> { + if Typed2718::is_legacy(self) { + None + } else { + Some(self.ty()) + } + } + + fn encode_2718_len(&self) -> usize { + match &self.transaction { + SeismicTypedTransaction::Legacy(legacy_tx) => { + legacy_tx.eip2718_encoded_length(&self.signature) + } + SeismicTypedTransaction::Eip2930(access_list_tx) => { + access_list_tx.eip2718_encoded_length(&self.signature) + } + SeismicTypedTransaction::Eip1559(dynamic_fee_tx) => { + dynamic_fee_tx.eip2718_encoded_length(&self.signature) + } + SeismicTypedTransaction::Eip4844(blob_tx) => { + blob_tx.eip2718_encoded_length(&self.signature) + } + SeismicTypedTransaction::Eip7702(set_code_tx) => { + set_code_tx.eip2718_encoded_length(&self.signature) + } + SeismicTypedTransaction::Seismic(seismic_tx) => { + seismic_tx.eip2718_encoded_length(&self.signature) + } + } + } + + fn encode_2718(&self, out: &mut dyn alloy_rlp::BufMut) { + let Self { transaction, signature, .. } = self; + + match &transaction { + SeismicTypedTransaction::Legacy(legacy_tx) => { + // do nothing w/ with_header + legacy_tx.eip2718_encode(signature, out) + } + SeismicTypedTransaction::Eip2930(access_list_tx) => { + access_list_tx.eip2718_encode(signature, out) + } + SeismicTypedTransaction::Eip1559(dynamic_fee_tx) => { + dynamic_fee_tx.eip2718_encode(signature, out) + } + SeismicTypedTransaction::Eip4844(blob_tx) => blob_tx.eip2718_encode(signature, out), + SeismicTypedTransaction::Eip7702(set_code_tx) => { + set_code_tx.eip2718_encode(signature, out) + } + SeismicTypedTransaction::Seismic(seismic_tx) => { + seismic_tx.eip2718_encode(signature, out) + } + } + } +} + +impl Decodable2718 for SeismicTransactionSigned { + fn typed_decode(ty: u8, buf: &mut &[u8]) -> Eip2718Result<Self> { + match ty.try_into().map_err(|_| Eip2718Error::UnexpectedType(ty))? { + seismic_alloy_consensus::SeismicTxType::Legacy => Err(Eip2718Error::UnexpectedType(0)), + seismic_alloy_consensus::SeismicTxType::Eip2930 => { + let (tx, signature, hash) = TxEip2930::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(SeismicTypedTransaction::Eip2930(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + seismic_alloy_consensus::SeismicTxType::Eip1559 => { + let (tx, signature, hash) = TxEip1559::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(SeismicTypedTransaction::Eip1559(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + seismic_alloy_consensus::SeismicTxType::Eip4844 => { + let (tx, signature, hash) = TxEip4844::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(SeismicTypedTransaction::Eip4844(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + seismic_alloy_consensus::SeismicTxType::Eip7702 => { + let (tx, signature, hash) = TxEip7702::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(SeismicTypedTransaction::Eip7702(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + seismic_alloy_consensus::SeismicTxType::Seismic => { + let (tx, signature, hash) = TxSeismic::rlp_decode_signed(buf)?.into_parts(); + let signed_tx = Self::new_unhashed(SeismicTypedTransaction::Seismic(tx), signature); + signed_tx.hash.get_or_init(|| hash); + Ok(signed_tx) + } + } + } + + fn fallback_decode(buf: &mut &[u8]) -> Eip2718Result<Self> { + let (transaction, signature) = TxLegacy::rlp_decode_with_signature(buf)?; + let signed_tx = Self::new_unhashed(SeismicTypedTransaction::Legacy(transaction), signature); + + Ok(signed_tx) + } +} + +impl Transaction for SeismicTransactionSigned { + fn chain_id(&self) -> Option<u64> { + self.deref().chain_id() + } + + fn nonce(&self) -> u64 { + self.deref().nonce() + } + + fn gas_limit(&self) -> u64 { + self.deref().gas_limit() + } + + fn gas_price(&self) -> Option<u128> { + self.deref().gas_price() + } + + fn max_fee_per_gas(&self) -> u128 { + self.deref().max_fee_per_gas() + } + + fn max_priority_fee_per_gas(&self) -> Option<u128> { + self.deref().max_priority_fee_per_gas() + } + + fn max_fee_per_blob_gas(&self) -> Option<u128> { + self.deref().max_fee_per_blob_gas() + } + + fn priority_fee_or_price(&self) -> u128 { + self.deref().priority_fee_or_price() + } + + fn effective_gas_price(&self, base_fee: Option<u64>) -> u128 { + self.deref().effective_gas_price(base_fee) + } + + fn effective_tip_per_gas(&self, base_fee: u64) -> Option<u128> { + self.deref().effective_tip_per_gas(base_fee) + } + + fn is_dynamic_fee(&self) -> bool { + self.deref().is_dynamic_fee() + } + + fn kind(&self) -> TxKind { + self.deref().kind() + } + + fn is_create(&self) -> bool { + self.deref().is_create() + } + + fn value(&self) -> Uint<256, 4> { + self.deref().value() + } + + fn input(&self) -> &Bytes { + self.deref().input() + } + + fn access_list(&self) -> Option<&AccessList> { + self.deref().access_list() + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + self.deref().blob_versioned_hashes() + } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + self.deref().authorization_list() + } +} + +impl InputDecryptionElements for SeismicTransactionSigned { + fn get_decryption_elements(&self) -> Result<TxSeismicElements, InputDecryptionElementsError> { + self.transaction.get_decryption_elements() + } + + fn get_input(&self) -> Result<Bytes, InputDecryptionElementsError> { + self.transaction.get_input() + } + + fn set_input(&mut self, input: Bytes) -> Result<(), InputDecryptionElementsError> { + self.transaction.set_input(input) + } + + fn metadata(&self, sender: Address) -> Result<TxSeismicMetadata, InputDecryptionElementsError> { + match &self.transaction { + SeismicTypedTransaction::Seismic(tx) => tx.metadata(sender), + _ => { + Err(InputDecryptionElementsError::UnsupportedTxType(format!("{}", self.tx_type()))) + } + } + } +} + +impl Typed2718 for SeismicTransactionSigned { + fn ty(&self) -> u8 { + self.deref().ty() + } +} + +impl PartialEq for SeismicTransactionSigned { + fn eq(&self, other: &Self) -> bool { + self.signature == other.signature && + self.transaction == other.transaction && + self.tx_hash() == other.tx_hash() + } +} + +impl Hash for SeismicTransactionSigned { + fn hash<H: Hasher>(&self, state: &mut H) { + self.signature.hash(state); + self.transaction.hash(state); + } +} + +#[cfg(feature = "reth-codec")] +impl reth_codecs::Compact for SeismicTransactionSigned { + fn to_compact<B>(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let start = buf.as_mut().len(); + + // Placeholder for bitflags. + // The first byte uses 4 bits as flags: IsCompressed[1bit], TxType[2bits], Signature[1bit] + buf.put_u8(0); + + let sig_bit = self.signature.to_compact(buf) as u8; + let zstd_bit = self.transaction.input().len() >= 32; + + // The `Compact` trait does not support fallible encoding. + // Compression failure indicates a catastrophic system error like OOM/corruption. + // Panicking here is intentional since silently corrupting data would be worse. + #[allow(clippy::expect_used)] + let tx_bits = if zstd_bit { + let mut tmp = Vec::with_capacity(256); + if cfg!(feature = "std") { + reth_zstd_compressors::TRANSACTION_COMPRESSOR.with(|compressor| { + let mut compressor = compressor.borrow_mut(); + let tx_bits = self.transaction.to_compact(&mut tmp); + buf.put_slice(&compressor.compress(&tmp).expect("Failed to compress")); + tx_bits as u8 + }) + } else { + let mut compressor = reth_zstd_compressors::create_tx_compressor(); + let tx_bits = self.transaction.to_compact(&mut tmp); + buf.put_slice( + &compressor + .compress(&tmp) + .expect("zstd compression with static dictionary should never fail"), + ); + tx_bits as u8 + } + } else { + self.transaction.to_compact(buf) as u8 + }; + + debug_assert!( + start < buf.as_mut().len(), + "buffer invariant violated: start index {start} >= buffer length {}", + buf.as_mut().len() + ); + + // Replace bitflags with the actual values + // SAFETY: debug_assert above verifies start < len, and we reserved space at line 583 + #[allow(clippy::indexing_slicing)] + { + buf.as_mut()[start] = sig_bit | (tx_bits << 1) | ((zstd_bit as u8) << 3); + } + + buf.as_mut().len() - start + } + + fn from_compact(mut buf: &[u8], _len: usize) -> (Self, &[u8]) { + use bytes::Buf; + + // The first byte uses 4 bits as flags: IsCompressed[1], TxType[2], Signature[1] + let bitflags = buf.get_u8() as usize; + + let sig_bit = bitflags & 1; + let (signature, buf) = Signature::from_compact(buf, sig_bit); + + let zstd_bit = bitflags >> 3; + let (transaction, buf) = if zstd_bit != 0 { + if cfg!(feature = "std") { + reth_zstd_compressors::TRANSACTION_DECOMPRESSOR.with(|decompressor| { + let mut decompressor = decompressor.borrow_mut(); + + // TODO: enforce that zstd is only present at a "top" level type + let transaction_type = (bitflags & 0b110) >> 1; + let (transaction, _) = SeismicTypedTransaction::from_compact( + decompressor.decompress(buf), + transaction_type, + ); + + (transaction, buf) + }) + } else { + let mut decompressor = reth_zstd_compressors::create_tx_decompressor(); + let transaction_type = (bitflags & 0b110) >> 1; + let (transaction, _) = SeismicTypedTransaction::from_compact( + decompressor.decompress(buf), + transaction_type, + ); + + (transaction, buf) + } + } else { + let transaction_type = bitflags >> 1; + SeismicTypedTransaction::from_compact(buf, transaction_type) + }; + + (Self { signature, transaction, hash: Default::default() }, buf) + } +} + +#[cfg(any(test, feature = "arbitrary"))] +impl<'a> arbitrary::Arbitrary<'a> for SeismicTransactionSigned { + #[allow(clippy::unwrap_used)] // Test/arbitrary code - panic on failure is acceptable + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> { + #[allow(unused_mut)] + let mut transaction = SeismicTypedTransaction::arbitrary(u)?; + + let secp = secp256k1::Secp256k1::new(); + let key_pair = secp256k1::Keypair::new(&secp, &mut rand_08::thread_rng()); + let signature = reth_primitives_traits::crypto::secp256k1::sign_message( + B256::from_slice(&key_pair.secret_bytes()[..]), + signature_hash(&transaction), + ) + .unwrap(); + + Ok(Self::new_unhashed(transaction, signature)) + } +} + +/// Calculates the signing hash for the transaction. +fn signature_hash(tx: &SeismicTypedTransaction) -> B256 { + match tx { + SeismicTypedTransaction::Legacy(tx) => tx.signature_hash(), + SeismicTypedTransaction::Eip2930(tx) => tx.signature_hash(), + SeismicTypedTransaction::Eip1559(tx) => tx.signature_hash(), + SeismicTypedTransaction::Eip4844(tx) => tx.signature_hash(), + SeismicTypedTransaction::Eip7702(tx) => tx.signature_hash(), + SeismicTypedTransaction::Seismic(tx) => tx.signature_hash(), + } +} + +/// Bincode-compatible transaction type serde implementations. +#[cfg(feature = "serde-bincode-compat")] +pub mod serde_bincode_compat { + use alloy_consensus::{ + transaction::serde_bincode_compat::{TxEip1559, TxEip2930, TxEip7702, TxLegacy}, + TxEip4844, + }; + use alloy_primitives::{Signature, TxHash}; + use reth_primitives_traits::{serde_bincode_compat::SerdeBincodeCompat, SignedTransaction}; + use seismic_alloy_consensus::serde_bincode_compat::TxSeismic; + use serde::{Deserialize, Serialize}; + + /// Bincode-compatible [`super::SeismicTypedTransaction`] serde implementation. + #[derive(Debug, Serialize, Deserialize)] + #[allow(missing_docs)] + enum SeismicTypedTransaction<'a> { + Legacy(TxLegacy<'a>), + Eip2930(TxEip2930<'a>), + Eip1559(TxEip1559<'a>), + Eip7702(TxEip7702<'a>), + Seismic(seismic_alloy_consensus::serde_bincode_compat::TxSeismic<'a>), + Eip4844(TxEip4844), + } + + impl<'a> From<&'a super::SeismicTypedTransaction> for SeismicTypedTransaction<'a> { + fn from(value: &'a super::SeismicTypedTransaction) -> Self { + match value { + super::SeismicTypedTransaction::Legacy(tx) => Self::Legacy(TxLegacy::from(tx)), + super::SeismicTypedTransaction::Eip2930(tx) => Self::Eip2930(TxEip2930::from(tx)), + super::SeismicTypedTransaction::Eip1559(tx) => Self::Eip1559(TxEip1559::from(tx)), + super::SeismicTypedTransaction::Eip4844(tx) => Self::Eip4844(tx.clone()), + super::SeismicTypedTransaction::Eip7702(tx) => Self::Eip7702(TxEip7702::from(tx)), + super::SeismicTypedTransaction::Seismic(tx) => Self::Seismic(TxSeismic::from(tx)), + } + } + } + + impl<'a> From<SeismicTypedTransaction<'a>> for super::SeismicTypedTransaction { + fn from(value: SeismicTypedTransaction<'a>) -> Self { + match value { + SeismicTypedTransaction::Legacy(tx) => Self::Legacy(tx.into()), + SeismicTypedTransaction::Eip2930(tx) => Self::Eip2930(tx.into()), + SeismicTypedTransaction::Eip1559(tx) => Self::Eip1559(tx.into()), + SeismicTypedTransaction::Eip7702(tx) => Self::Eip7702(tx.into()), + SeismicTypedTransaction::Seismic(tx) => Self::Seismic(tx.into()), + SeismicTypedTransaction::Eip4844(tx) => Self::Eip4844(tx), + } + } + } + + /// Bincode-compatible [`super::SeismicTransactionSigned`] serde implementation. + #[derive(Debug, Serialize, Deserialize)] + pub struct SeismicTransactionSigned<'a> { + hash: TxHash, + signature: Signature, + transaction: SeismicTypedTransaction<'a>, + } + + impl<'a> From<&'a super::SeismicTransactionSigned> for SeismicTransactionSigned<'a> { + fn from(value: &'a super::SeismicTransactionSigned) -> Self { + Self { + hash: *value.tx_hash(), + signature: value.signature, + transaction: SeismicTypedTransaction::from(&value.transaction), + } + } + } + + impl<'a> From<SeismicTransactionSigned<'a>> for super::SeismicTransactionSigned { + fn from(value: SeismicTransactionSigned<'a>) -> Self { + Self { + hash: value.hash.into(), + signature: value.signature, + transaction: value.transaction.into(), + } + } + } + + impl SerdeBincodeCompat for super::SeismicTransactionSigned { + type BincodeRepr<'a> = SeismicTransactionSigned<'a>; + + fn as_repr(&self) -> Self::BincodeRepr<'_> { + self.into() + } + + fn from_repr(repr: Self::BincodeRepr<'_>) -> Self { + repr.into() + } + } +} + +#[cfg(test)] +#[allow(clippy::expect_used)] // Test code - expect on failure is acceptable +#[allow(clippy::unwrap_used)] // Test code - unwrap on failure is acceptable +#[allow(clippy::panic)] // Test code - panic on failure is acceptable +mod tests { + use core::str::FromStr; + + use crate::test_utils::{get_signed_seismic_tx, get_signing_private_key}; + + use super::*; + use alloy_primitives::{aliases::U96, hex, U256}; + use proptest::proptest; + use proptest_arbitrary_interop::arb; + use reth_codecs::Compact; + use secp256k1::PublicKey; + use seismic_alloy_consensus::SeismicTxType; + use seismic_revm::transaction::abstraction::SeismicTxTr; + + #[test] + fn recover_signer_test() { + let signed_tx = get_signed_seismic_tx(B256::ZERO); + let recovered_signer = signed_tx.recover_signer().expect("Failed to recover signer"); + + let expected_signer = Address::from_private_key(&get_signing_private_key()); + + assert_eq!(recovered_signer, expected_signer); + } + + proptest! { + #[test] + fn test_roundtrip_2718(reth_tx in arb::<SeismicTransactionSigned>()) { + println!("{}", reth_tx.transaction().tx_type()); + if reth_tx.transaction().tx_type() == SeismicTxType::Eip4844 { + // TODO: make this work for eip4844 in seismic-alloy + return Ok(()) + } + + let mut signed_tx_bytes = Vec::<u8>::new(); + reth_tx.encode_2718(&mut signed_tx_bytes); + let recovered_tx = SeismicTransactionSigned::decode_2718(&mut &signed_tx_bytes[..]) + .expect("Failed to decode transaction"); + assert_eq!(recovered_tx, reth_tx); + + } + + #[test] + fn test_roundtrip_compact_encode_envelope(reth_tx in arb::<SeismicTransactionSigned>()) { + let mut expected_buf = Vec::<u8>::new(); + let expected_len = reth_tx.to_compact(&mut expected_buf); + + let mut actual_but = Vec::<u8>::new(); + let alloy_tx = SeismicTxEnvelope::<TxEip4844>::from(reth_tx); + let actual_len = alloy_tx.to_compact(&mut actual_but); + + assert_eq!(actual_but, expected_buf); + assert_eq!(actual_len, expected_len); + } + + #[test] + fn test_roundtrip_compact_decode_envelope(reth_tx in arb::<SeismicTransactionSigned>()) { + let mut buf = Vec::<u8>::new(); + let len = reth_tx.to_compact(&mut buf); + + let (actual_tx, _) = SeismicTxEnvelope::<TxEip4844>::from_compact(&buf, len); + let expected_tx = SeismicTxEnvelope::<TxEip4844>::from(reth_tx); + + assert_eq!(actual_tx, expected_tx); + } + } + + #[test] + fn test_typed_data_signature() { + let r = U256::from_str( + "71428958633055842950552481968900399270748852734491747368417687851448988125054", + ) + .unwrap(); + let s = U256::from_str( + "33262000809980766041358100082526545952432844285780958277847084121198676124377", + ) + .unwrap(); + let signature = Signature::new(r, s, false); + + let tx = TxSeismic { + chain_id: 5124, + nonce: 47, + gas_price: 360000, + gas_limit: 169477, + to: TxKind::Call( + Address::from_str("0x3ab946eec2553114040de82d2e18798a51cf1e14").unwrap(), + ), + value: U256::from_str("1000000000000000").unwrap(), + input: Bytes::from_str("0xf05bb3655142e855b09496062e5bd8e54852857b4e1f6c771ca9a44fcb4ecbd5cba03a534367563204044bb9466b04ae770ab4f1").unwrap(), + seismic_elements: TxSeismicElements { + encryption_pubkey: PublicKey::from_str("028e76821eb4d77fd30223ca971c49738eb5b5b71eabe93f96b348fdce788ae5a0").unwrap(), + encryption_nonce: U96::from_str("38883482092810179043846363626").unwrap(), + message_version: 2, + recent_block_hash: alloy_primitives::B256::from_slice(&hex::decode("1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef").unwrap()), + expires_at_block: 1000000, + signed_read: false, + }, + authorization_list: vec![], + }; + + let signed = + SeismicTransactionSigned::new_unhashed(SeismicTypedTransaction::Seismic(tx), signature); + + let sender = Address::from_str("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266").unwrap(); + let recovered = SeismicTransaction::<TxEnv>::from_recovered_tx(&signed, sender); + + assert_eq!(recovered.tx_hash(), signed.recalculate_hash()); + } +}
diff --git reth/crates/seismic/primitives/src/transaction/tx_type.rs seismic-reth/crates/seismic/primitives/src/transaction/tx_type.rs new file mode 100644 index 0000000000000000000000000000000000000000..44b72f7e2dcf00ed6c9ec248ed62d2b4e36960d5 --- /dev/null +++ seismic-reth/crates/seismic/primitives/src/transaction/tx_type.rs @@ -0,0 +1,49 @@ +//! Seismic transaction type. + +pub use seismic_alloy_consensus::SeismicTxType; + +#[cfg(test)] +mod tests { + use super::*; + use alloy_consensus::constants::EIP7702_TX_TYPE_ID; + use reth_codecs::{txtype::*, Compact}; + use rstest::rstest; + + #[rstest] + #[case(SeismicTxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(SeismicTxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(SeismicTxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(SeismicTxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[case(SeismicTxType::Seismic, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![74_u8])] + fn test_txtype_to_compact( + #[case] tx_type: SeismicTxType, + #[case] expected_identifier: usize, + #[case] expected_buf: Vec<u8>, + ) { + let mut buf = vec![]; + let identifier = tx_type.to_compact(&mut buf); + + assert_eq!( + identifier, expected_identifier, + "Unexpected identifier for SeismicTxType {tx_type:?}", + ); + assert_eq!(buf, expected_buf, "Unexpected buffer for SeismicTxType {tx_type:?}",); + } + + #[rstest] + #[case(SeismicTxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])] + #[case(SeismicTxType::Eip2930, COMPACT_IDENTIFIER_EIP2930, vec![])] + #[case(SeismicTxType::Eip1559, COMPACT_IDENTIFIER_EIP1559, vec![])] + #[case(SeismicTxType::Eip7702, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![EIP7702_TX_TYPE_ID])] + #[case(SeismicTxType::Seismic, COMPACT_EXTENDED_IDENTIFIER_FLAG, vec![74_u8])] + fn test_txtype_from_compact( + #[case] expected_type: SeismicTxType, + #[case] identifier: usize, + #[case] buf: Vec<u8>, + ) { + let (actual_type, remaining_buf) = SeismicTxType::from_compact(&buf, identifier); + + assert_eq!(actual_type, expected_type, "Unexpected TxType for identifier {identifier}"); + assert!(remaining_buf.is_empty(), "Buffer not fully consumed for identifier {identifier}"); + } +}
diff --git reth/crates/seismic/txpool/Cargo.toml seismic-reth/crates/seismic/txpool/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..d5fa99fbb9794b40197f0a515b2659d5700e4e36 --- /dev/null +++ seismic-reth/crates/seismic/txpool/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "reth-seismic-txpool" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "Seismic-Reth Transaction Pool" + +[lints] +workspace = true + +[dependencies] +# ethereum +alloy-consensus.workspace = true +alloy-eips.workspace = true +alloy-primitives.workspace = true +seismic-alloy-consensus.workspace = true + +# reth +reth-chainspec.workspace = true +reth-execution-types.workspace = true +reth-primitives-traits.workspace = true +reth-provider.workspace = true +reth-transaction-pool = {workspace = true, features = ["serde", "reth-codec", "serde-bincode-compat"]} + +# seismic +reth-seismic-primitives = {workspace = true, features = ["serde", "reth-codec", "serde-bincode-compat"]} + +# misc +c-kzg.workspace = true +derive_more.workspace = true +tracing.workspace = true + +[dev-dependencies] +reth-seismic-chainspec.workspace = true +reth-provider = { workspace = true, features = ["test-utils"] } +tokio.workspace = true
diff --git reth/crates/seismic/txpool/src/lib.rs seismic-reth/crates/seismic/txpool/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..fbe3209e795fd434b2db2414c73090bf61e463ac --- /dev/null +++ seismic-reth/crates/seismic/txpool/src/lib.rs @@ -0,0 +1,29 @@ +//! Seismic-Reth Transaction pool. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +use reth_transaction_pool::{CoinbaseTipOrdering, Pool, TransactionValidationTaskExecutor}; + +mod maintain; +mod recent_block_cache; +mod transaction; +pub mod usdc; +mod validator; + +pub use maintain::SeismicBalanceHook; +pub use recent_block_cache::{RecentBlockCache, SEISMIC_TX_RECENT_BLOCK_LOOKBACK}; +pub use transaction::SeismicPooledTransaction; +pub use validator::SeismicTransactionValidator; + +/// Type alias for default seismic transaction pool +pub type SeismicTransactionPool<Client, S, T = SeismicPooledTransaction> = Pool< + TransactionValidationTaskExecutor<SeismicTransactionValidator<Client, T>>, + CoinbaseTipOrdering<T>, + S, +>;
diff --git reth/crates/seismic/txpool/src/maintain.rs seismic-reth/crates/seismic/txpool/src/maintain.rs new file mode 100644 index 0000000000000000000000000000000000000000..e657aa9879ae35307dfb8a55c21c538c276558c0 --- /dev/null +++ seismic-reth/crates/seismic/txpool/src/maintain.rs @@ -0,0 +1,37 @@ +//! Seismic-specific pool maintenance hook that augments native balances with +//! USDC predeploy balances. + +use reth_execution_types::ChangedAccount; +use reth_provider::StateProvider; +use reth_transaction_pool::maintain::ChangedAccountsHook; +use tracing::debug; + +/// A [`ChangedAccountsHook`] that reads each sender's USDC predeploy balance +/// and sets `balance = max(native, usdc_scaled)` so the pool can make accurate +/// demotion decisions for accounts paying gas in USDC. +/// +/// The hook uses the [`StateProvider`] passed by the maintenance loop rather +/// than opening its own snapshot, so the USDC balance is always read from the +/// same block as the native balance and nonce. +#[derive(Debug, Default)] +pub struct SeismicBalanceHook; + +impl ChangedAccountsHook for SeismicBalanceHook { + fn transform(&self, state: &dyn StateProvider, accounts: &mut Vec<ChangedAccount>) { + for acc in accounts.iter_mut() { + let usdc = crate::usdc::read_usdc_balance(state, &acc.address); + let new_balance = std::cmp::max(acc.balance, usdc); + if new_balance != acc.balance { + debug!( + target: "seismic::txpool", + address = %acc.address, + native_balance = %acc.balance, + usdc_scaled_balance = %usdc, + effective_balance = %new_balance, + "augmenting changed account balance with USDC" + ); + acc.balance = new_balance; + } + } + } +}
diff --git reth/crates/seismic/txpool/src/recent_block_cache.rs seismic-reth/crates/seismic/txpool/src/recent_block_cache.rs new file mode 100644 index 0000000000000000000000000000000000000000..ac8b23fdd24b87fc7d6cb932cd6f6ea02af9d36e --- /dev/null +++ seismic-reth/crates/seismic/txpool/src/recent_block_cache.rs @@ -0,0 +1,324 @@ +//! Bounded cache of recent block hashes for O(1) lookup during transaction validation. + +use alloy_primitives::B256; +use std::collections::{HashSet, VecDeque}; + +/// Maximum number of blocks to look back for `recent_block_hash` validation. +pub const SEISMIC_TX_RECENT_BLOCK_LOOKBACK: u64 = 100; + +/// A bounded cache that stores recent block hashes with FIFO eviction. +/// +/// Used by [`SeismicTransactionValidator`](crate::SeismicTransactionValidator) to validate +/// `recent_block_hash` in seismic transactions without iterating over blocks via the client. +/// Updated on each new head block via `on_new_head_block`. +#[derive(Debug)] +pub struct RecentBlockCache { + /// Set of block hashes for O(1) lookup. + hashes: HashSet<B256>, + /// Ordered queue of block hashes (front = oldest, back = newest) for FIFO eviction. + ordered: VecDeque<B256>, + /// The block number of the most recently inserted block. + current_block_number: u64, + /// Maximum number of block hashes to retain. + max_size: u64, +} + +impl Default for RecentBlockCache { + fn default() -> Self { + Self::new(SEISMIC_TX_RECENT_BLOCK_LOOKBACK) + } +} + +impl RecentBlockCache { + /// Creates a new empty cache with the given maximum size. + pub fn new(max_size: u64) -> Self { + Self { + hashes: HashSet::with_capacity(max_size as usize), + ordered: VecDeque::with_capacity(max_size as usize), + current_block_number: 0, + max_size, + } + } + + /// Inserts a block hash into the cache, evicting the oldest entry if at capacity. + pub fn insert(&mut self, hash: B256, block_number: u64) { + self.current_block_number = block_number; + self.ordered.push_back(hash); + self.hashes.insert(hash); + while self.ordered.len() as u64 > self.max_size { + if let Some(old) = self.ordered.pop_front() { + self.hashes.remove(&old); + } + } + } + + /// Returns `true` if the cache contains the given block hash. + pub fn contains(&self, hash: &B256) -> bool { + self.hashes.contains(hash) + } + + /// Returns the block number of the most recently inserted block. + pub const fn current_block_number(&self) -> u64 { + self.current_block_number + } + + /// Returns `true` if the cache is empty (no blocks have been inserted yet). + pub fn is_empty(&self) -> bool { + self.ordered.is_empty() + } + + /// Returns the hash of the most recently inserted block, if any. + pub fn latest_hash(&self) -> Option<&B256> { + self.ordered.back() + } + + /// Clears the cache and repopulates it from the given entries. + /// + /// Called on reorgs or any non-sequential block update, since stale hashes from + /// the old fork must be purged and replaced with the current canonical chain. + pub fn rebuild(&mut self, entries: impl Iterator<Item = (B256, u64)>) { + self.hashes.clear(); + self.ordered.clear(); + self.current_block_number = 0; + for (hash, number) in entries { + self.insert(hash, number); + } + } + + /// Rebuilds the cache from the canonical chain up to the given tip block number. + /// + /// `canonical_hash_at` is a closure that returns the canonical block hash for a + /// given block number, or `None` if unavailable. This is used both at startup + /// (to populate the cache) and during reorg recovery. + pub fn rebuild_to_tip(&mut self, tip: u64, canonical_hash_at: impl Fn(u64) -> Option<B256>) { + let earliest = tip.saturating_sub(self.max_size); + self.rebuild((earliest..=tip).filter_map(|n| canonical_hash_at(n).map(|h| (h, n)))); + } + + /// Updates the cache with a new head block, handling gaps and reorgs. + /// + /// The cache must always reflect the canonical chain so that validation + /// accepts exactly the hashes that the RPC layer would return for + /// `eth_getBlockByNumber("latest")`. Three cases: + /// + /// 1. **Sequential block** (`new == cached + 1`): The common case during normal operation. We + /// just append the new hash — O(1). + /// + /// 2. **Gap but still canonical** (`new > cached` and our latest hash is still on the canonical + /// chain): Multiple blocks were produced between callbacks (e.g. between `new()` and the + /// first callback, or a slow consumer). We backfill only the missing blocks. + /// + /// 3. **Stale cache** (reorg, empty, or same/lower height): The cache contains hashes from a + /// fork that is no longer canonical. We clear and rebuild the full lookback window to purge + /// stale fork hashes. + pub fn update( + &mut self, + new_hash: B256, + new_number: u64, + canonical_hash_at: impl Fn(u64) -> Option<B256>, + ) { + // Happy path: sequential block, just append + if new_number == self.current_block_number + 1 { + self.insert(new_hash, new_number); + return; + } + + // Non-sequential: check if the cache is still on the canonical chain + if new_number > self.current_block_number && self.is_on_canonical_chain(&canonical_hash_at) + { + // Cache is canonical but behind — backfill the gap + let backfill_start = self.current_block_number + 1; + for n in backfill_start..=new_number { + if let Some(hash) = canonical_hash_at(n) { + self.insert(hash, n); + } + } + return; + } + + // Cache is stale (reorg, empty, or same/lower height) — full rebuild + self.rebuild_to_tip(new_number, canonical_hash_at); + } + + /// Checks whether the cache's latest block is still on the canonical chain. + /// + /// Compares the cache's latest hash against what the canonical chain reports for + /// that block number. Returns `false` if the cache is empty, the block has been + /// reorged out, or the lookup fails. + fn is_on_canonical_chain(&self, canonical_hash_at: &impl Fn(u64) -> Option<B256>) -> bool { + let Some(&cached_hash) = self.latest_hash() else { + return false; + }; + canonical_hash_at(self.current_block_number).is_some_and(|h| h == cached_hash) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_insert_and_contains() { + let mut cache = RecentBlockCache::new(3); + let h1 = B256::from([1u8; 32]); + let h2 = B256::from([2u8; 32]); + + cache.insert(h1, 1); + cache.insert(h2, 2); + + assert!(cache.contains(&h1)); + assert!(cache.contains(&h2)); + assert!(!cache.contains(&B256::from([3u8; 32]))); + assert_eq!(cache.current_block_number(), 2); + } + + #[test] + fn test_eviction() { + let mut cache = RecentBlockCache::new(2); + let h1 = B256::from([1u8; 32]); + let h2 = B256::from([2u8; 32]); + let h3 = B256::from([3u8; 32]); + + cache.insert(h1, 1); + cache.insert(h2, 2); + cache.insert(h3, 3); + + // h1 should be evicted + assert!(!cache.contains(&h1)); + assert!(cache.contains(&h2)); + assert!(cache.contains(&h3)); + assert_eq!(cache.current_block_number(), 3); + } + + #[test] + fn test_is_empty() { + let mut cache = RecentBlockCache::new(5); + assert!(cache.is_empty()); + + cache.insert(B256::from([1u8; 32]), 1); + assert!(!cache.is_empty()); + } + + #[test] + fn test_rebuild_replaces_all_entries() { + let mut cache = RecentBlockCache::new(5); + let h1 = B256::from([1u8; 32]); + let h2 = B256::from([2u8; 32]); + let h3 = B256::from([3u8; 32]); + let h4 = B256::from([4u8; 32]); + + cache.insert(h1, 10); + cache.insert(h2, 11); + + // Rebuild with completely different entries (simulates a reorg) + cache.rebuild(vec![(h3, 10), (h4, 11)].into_iter()); + + assert!(!cache.contains(&h1)); + assert!(!cache.contains(&h2)); + assert!(cache.contains(&h3)); + assert!(cache.contains(&h4)); + assert_eq!(cache.current_block_number(), 11); + } + + /// Helper: creates a closure that maps block number -> hash for a slice of (hash, number). + fn mock_canonical(blocks: &[(B256, u64)]) -> impl Fn(u64) -> Option<B256> + '_ { + move |n| blocks.iter().find(|(_, num)| *num == n).map(|(h, _)| *h) + } + + #[test] + fn test_rebuild_to_tip() { + let mut cache = RecentBlockCache::new(3); + let h8 = B256::from([8u8; 32]); + let h9 = B256::from([9u8; 32]); + let h10 = B256::from([10u8; 32]); + + let blocks = [(h8, 8), (h9, 9), (h10, 10)]; + cache.rebuild_to_tip(10, mock_canonical(&blocks)); + + assert!(cache.contains(&h8)); + assert!(cache.contains(&h9)); + assert!(cache.contains(&h10)); + assert_eq!(cache.current_block_number(), 10); + } + + #[test] + fn test_update_sequential() { + let mut cache = RecentBlockCache::new(5); + let h1 = B256::from([1u8; 32]); + let h2 = B256::from([2u8; 32]); + + cache.insert(h1, 1); + // Sequential: block 2 follows block 1 + #[allow(clippy::panic)] + cache.update(h2, 2, |_| panic!("should not be called for sequential")); + + assert!(cache.contains(&h1)); + assert!(cache.contains(&h2)); + assert_eq!(cache.current_block_number(), 2); + } + + #[test] + fn test_update_gap_still_canonical() { + let mut cache = RecentBlockCache::new(10); + let h5 = B256::from([5u8; 32]); + let h6 = B256::from([6u8; 32]); + let h7 = B256::from([7u8; 32]); + let h8 = B256::from([8u8; 32]); + + cache.insert(h5, 5); + + // Gap: jump from 5 to 8, but cache is still canonical + let blocks = [(h5, 5), (h6, 6), (h7, 7), (h8, 8)]; + cache.update(h8, 8, mock_canonical(&blocks)); + + assert!(cache.contains(&h5)); + assert!(cache.contains(&h6)); + assert!(cache.contains(&h7)); + assert!(cache.contains(&h8)); + assert_eq!(cache.current_block_number(), 8); + } + + #[test] + fn test_update_reorg_triggers_rebuild() { + let mut cache = RecentBlockCache::new(5); + let h5_old = B256::from([50u8; 32]); + let h6_old = B256::from([60u8; 32]); + let h7_old = B256::from([70u8; 32]); + let h5_new = B256::from([55u8; 32]); + let h6_new = B256::from([66u8; 32]); + + cache.insert(h5_old, 5); + cache.insert(h6_old, 6); + cache.insert(h7_old, 7); + + // Reorg: new canonical chain is shorter (tip at 6), old fork hashes are stale. + // new_number (6) <= current_block_number (7), so this triggers a full rebuild. + let blocks = [(h5_new, 5), (h6_new, 6)]; + cache.update(h6_new, 6, mock_canonical(&blocks)); + + // Old fork hashes should be gone, new canonical hashes present + assert!(!cache.contains(&h5_old)); + assert!(!cache.contains(&h6_old)); + assert!(!cache.contains(&h7_old)); + assert!(cache.contains(&h5_new)); + assert!(cache.contains(&h6_new)); + assert_eq!(cache.current_block_number(), 6); + } + + #[test] + fn test_update_same_height_triggers_rebuild() { + let mut cache = RecentBlockCache::new(5); + let h5_old = B256::from([50u8; 32]); + let h5_new = B256::from([55u8; 32]); + + cache.insert(h5_old, 5); + + // Same height but different hash (reorg at same level) + let blocks = [(h5_new, 5)]; + cache.update(h5_new, 5, mock_canonical(&blocks)); + + assert!(!cache.contains(&h5_old)); + assert!(cache.contains(&h5_new)); + assert_eq!(cache.current_block_number(), 5); + } +}
diff --git reth/crates/seismic/txpool/src/transaction.rs seismic-reth/crates/seismic/txpool/src/transaction.rs new file mode 100644 index 0000000000000000000000000000000000000000..f178b0951547504fc4568bec1e91265774e14906 --- /dev/null +++ seismic-reth/crates/seismic/txpool/src/transaction.rs @@ -0,0 +1,235 @@ +use alloy_consensus::{transaction::Recovered, BlobTransactionValidationError, Typed2718}; +use alloy_eips::{ + eip2930::AccessList, eip7594::BlobTransactionSidecarVariant, eip7702::SignedAuthorization, + Encodable2718, +}; +use alloy_primitives::{Address, Bytes, TxHash, TxKind, B256, U256}; +use c_kzg::KzgSettings; +use core::fmt::Debug; +use reth_primitives_traits::{InMemorySize, SignedTransaction}; +use reth_seismic_primitives::SeismicTransactionSigned; +use reth_transaction_pool::{ + EthBlobTransactionSidecar, EthPoolTransaction, EthPooledTransaction, PoolTransaction, +}; +use seismic_alloy_consensus::SeismicTxEnvelope; +use std::sync::Arc; + +/// Pool Transaction for Seismic. +#[derive(Debug, Clone, derive_more::Deref)] +pub struct SeismicPooledTransaction<Cons = SeismicTransactionSigned, Pooled = SeismicTxEnvelope> { + #[deref] + inner: EthPooledTransaction<Cons>, + /// The pooled transaction type. + _pd: core::marker::PhantomData<Pooled>, +} + +impl<Cons: SignedTransaction, Pooled> SeismicPooledTransaction<Cons, Pooled> { + /// Create a new [`SeismicPooledTransaction`]. + pub fn new(transaction: Recovered<Cons>, encoded_length: usize) -> Self { + Self { + inner: EthPooledTransaction::new(transaction, encoded_length), + _pd: core::marker::PhantomData, + } + } +} + +impl<Cons, Pooled> PoolTransaction for SeismicPooledTransaction<Cons, Pooled> +where + Cons: SignedTransaction + From<Pooled>, + Pooled: SignedTransaction + TryFrom<Cons, Error: core::error::Error>, +{ + type TryFromConsensusError = <Pooled as TryFrom<Cons>>::Error; + type Consensus = Cons; + type Pooled = Pooled; + + fn hash(&self) -> &TxHash { + self.inner.transaction.tx_hash() + } + + fn sender(&self) -> Address { + self.inner.transaction.signer() + } + + fn sender_ref(&self) -> &Address { + self.inner.transaction.signer_ref() + } + + fn cost(&self) -> &U256 { + &self.inner.cost + } + + fn encoded_length(&self) -> usize { + self.inner.encoded_length + } + + fn clone_into_consensus(&self) -> Recovered<Self::Consensus> { + self.inner.transaction().clone() + } + + fn into_consensus(self) -> Recovered<Self::Consensus> { + self.inner.transaction + } + + fn from_pooled(tx: Recovered<Self::Pooled>) -> Self { + let encoded_len = tx.encode_2718_len(); + Self::new(tx.convert(), encoded_len) + } +} + +impl<Cons: Typed2718, Pooled> Typed2718 for SeismicPooledTransaction<Cons, Pooled> { + fn ty(&self) -> u8 { + self.inner.ty() + } +} + +impl<Cons: InMemorySize, Pooled> InMemorySize for SeismicPooledTransaction<Cons, Pooled> { + fn size(&self) -> usize { + self.inner.size() + } +} + +impl<Cons, Pooled> alloy_consensus::Transaction for SeismicPooledTransaction<Cons, Pooled> +where + Cons: alloy_consensus::Transaction + SignedTransaction, // Ensure Cons has the methods + Pooled: Debug + Send + Sync + 'static, /* From Optimism example, for + * completeness */ +{ + fn chain_id(&self) -> Option<u64> { + self.inner.chain_id() + } + fn nonce(&self) -> u64 { + self.inner.nonce() + } + fn gas_limit(&self) -> u64 { + self.inner.gas_limit() + } + fn gas_price(&self) -> Option<u128> { + self.inner.gas_price() + } + fn max_fee_per_gas(&self) -> u128 { + self.inner.max_fee_per_gas() + } + fn max_priority_fee_per_gas(&self) -> Option<u128> { + self.inner.max_priority_fee_per_gas() + } + fn max_fee_per_blob_gas(&self) -> Option<u128> { + self.inner.max_fee_per_blob_gas() + } + fn value(&self) -> U256 { + self.inner.value() + } + fn input(&self) -> &Bytes { + self.inner.input() + } + fn access_list(&self) -> Option<&AccessList> { + self.inner.access_list() + } + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + self.inner.blob_versioned_hashes() + } + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + self.inner.authorization_list() + } + fn priority_fee_or_price(&self) -> u128 { + self.inner.priority_fee_or_price() + } + fn effective_gas_price(&self, base_fee: Option<u64>) -> u128 { + self.inner.effective_gas_price(base_fee) + } + fn is_dynamic_fee(&self) -> bool { + self.inner.is_dynamic_fee() + } + fn kind(&self) -> TxKind { + self.inner.kind() + } + fn is_create(&self) -> bool { + self.inner.is_create() + } +} + +impl<Cons, Pooled> EthPoolTransaction for SeismicPooledTransaction<Cons, Pooled> +where + Cons: SignedTransaction + From<Pooled>, + Pooled: SignedTransaction + TryFrom<Cons>, + <Pooled as TryFrom<Cons>>::Error: core::error::Error, +{ + fn take_blob(&mut self) -> EthBlobTransactionSidecar { + EthBlobTransactionSidecar::None + } + + fn try_into_pooled_eip4844( + self, + _sidecar: Arc<BlobTransactionSidecarVariant>, + ) -> Option<Recovered<Self::Pooled>> { + None + } + + fn try_from_eip4844( + _tx: Recovered<Self::Consensus>, + _sidecar: BlobTransactionSidecarVariant, + ) -> Option<Self> { + None + } + + fn validate_blob( + &self, + _sidecar: &BlobTransactionSidecarVariant, + _settings: &KzgSettings, + ) -> Result<(), BlobTransactionValidationError> { + Err(BlobTransactionValidationError::NotBlobTransaction(self.ty())) + } +} + +#[cfg(test)] +#[allow(clippy::expect_used)] // Test code - expect on failure is acceptable +#[allow(clippy::unwrap_used)] // Test code - unwrap on failure is acceptable +#[allow(clippy::panic)] // Test code - panic on failure is acceptable +mod tests { + use crate::SeismicPooledTransaction; + use alloy_consensus::transaction::Recovered; + use alloy_eips::eip2718::Encodable2718; + use alloy_primitives::B256; + use reth_primitives_traits::transaction::error::InvalidTransactionError; + use reth_provider::test_utils::MockEthProvider; + use reth_seismic_chainspec::SEISMIC_MAINNET; + use reth_seismic_primitives::test_utils::get_signed_seismic_tx; + use reth_transaction_pool::{ + blobstore::InMemoryBlobStore, error::InvalidPoolTransactionError, + validate::EthTransactionValidatorBuilder, TransactionOrigin, TransactionValidationOutcome, + }; + + #[tokio::test] + async fn validate_seismic_transaction() { + // setup validator + let client = MockEthProvider::default().with_chain_spec(SEISMIC_MAINNET.clone()); + let validator = EthTransactionValidatorBuilder::new(client) + .no_shanghai() + .no_cancun() + .build(InMemoryBlobStore::default()); + + // check that a SeismicTypedTransaction::Seismic is valid + let origin = TransactionOrigin::External; + let signer = Default::default(); + let signed_seismic_tx = get_signed_seismic_tx(B256::ZERO); + let signed_recovered = Recovered::new_unchecked(signed_seismic_tx, signer); + let len = signed_recovered.encode_2718_len(); + let pooled_tx: SeismicPooledTransaction = + SeismicPooledTransaction::new(signed_recovered, len); + + let outcome = validator.validate_one(origin, pooled_tx); + + match outcome { + TransactionValidationOutcome::Invalid( + _, + InvalidPoolTransactionError::Consensus(InvalidTransactionError::InsufficientFunds( + _, + )), + ) => { + // expected since the client (MockEthProvider) state does not have funds for any + // accounts account balance is one of the last things checked in + // validate_one, so getting that far good news + } + _ => panic!("Did not get expected outcome, got: {:?}", outcome), + } + } +}
diff --git reth/crates/seismic/txpool/src/usdc.rs seismic-reth/crates/seismic/txpool/src/usdc.rs new file mode 100644 index 0000000000000000000000000000000000000000..b799e82c8dae415a039593a522fce83f7ccc678e --- /dev/null +++ seismic-reth/crates/seismic/txpool/src/usdc.rs @@ -0,0 +1,98 @@ +//! Utilities for reading USDC balances from contract storage. +//! +//! The Seismic USDC predeploy stores its `_balances` mapping at storage slot 3. +//! We read balances directly from storage +//! (cheap) rather than executing an EVM `balanceOf` call (expensive). + +use alloy_primitives::{keccak256, Address, B256, U256}; +use reth_provider::StateProvider; + +/// USDC predeploy address on Seismic. +pub const USDC_CONTRACT: Address = + alloy_primitives::address!("0x790701048922E265105fd6a4467a2901c2201C43"); + +/// Scale factor to convert USDC (6 decimals) to 18 decimals: 10^12. +pub const USDC_DECIMAL_SCALE: U256 = U256::from_limbs([1_000_000_000_000u64, 0, 0, 0]); + +/// Storage slot of the `_balances` mapping in the USDC predeploy contract. +const BALANCES_MAPPING_SLOT: U256 = U256::from_limbs([3, 0, 0, 0]); + +/// Computes the storage key for `_balances[address]`. +/// +/// For a Solidity `mapping(address => uint256)` at slot `s`, the value for key +/// `k` is stored at `keccak256(abi.encode(k, s))` — i.e. `k` left-padded to 32 +/// bytes concatenated with `s` as a 32-byte big-endian integer. +pub fn usdc_balance_storage_key(address: &Address) -> B256 { + let mut buf = [0u8; 64]; + // address is 20 bytes, right-aligned in the first 32-byte word + buf[12..32].copy_from_slice(address.as_slice()); + // second 32-byte word: slot number (0) — already zeroed + #[allow(clippy::indexing_slicing)] + BALANCES_MAPPING_SLOT.to_be_bytes::<32>().iter().enumerate().for_each(|(i, &b)| { + buf[32 + i] = b; + }); + keccak256(buf) +} + +/// Reads the USDC balance for `address` from contract storage and scales it to +/// 18 decimals. Returns `U256::ZERO` on any error (missing account, missing +/// slot, provider failure). +pub fn read_usdc_balance(state: &dyn StateProvider, address: &Address) -> U256 { + let key = usdc_balance_storage_key(address); + match state.storage(USDC_CONTRACT, key) { + Ok(Some(flagged)) => flagged.value.saturating_mul(USDC_DECIMAL_SCALE), + _ => U256::ZERO, + } +} + +/// Returns the *effective* balance: `max(native_balance, usdc_balance_scaled)`. +/// +/// This is used as the balance for transaction pool ordering and demotion +/// decisions so that accounts paying gas in USDC are treated equivalently to +/// accounts paying in native token. +pub fn effective_balance( + state: &dyn StateProvider, + address: &Address, + native_balance: U256, +) -> U256 { + let usdc = read_usdc_balance(state, address); + std::cmp::max(native_balance, usdc) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn storage_key_is_deterministic() { + let addr = alloy_primitives::address!("0000000000000000000000000000000000000001"); + let k1 = usdc_balance_storage_key(&addr); + let k2 = usdc_balance_storage_key(&addr); + assert_eq!(k1, k2); + } + + #[test] + fn storage_key_differs_per_address() { + let a = alloy_primitives::address!("0000000000000000000000000000000000000001"); + let b = alloy_primitives::address!("0000000000000000000000000000000000000002"); + assert_ne!(usdc_balance_storage_key(&a), usdc_balance_storage_key(&b)); + } + + /// Replicates the seismic-revm `erc_address_storage` computation byte-for-byte + /// to confirm we read the same slot the EVM writes to. + #[test] + fn storage_key_matches_seismic_revm() { + let addr = alloy_primitives::address!("0123456789abcdef0123456789abcdef01234567"); + + // seismic-revm erc_address_storage(addr): + // buf[12..32] = addr + // buf[63] = 3 + // keccak256(buf) + let mut expected_buf = [0u8; 64]; + expected_buf[12..32].copy_from_slice(addr.as_slice()); + expected_buf[63] = 3; + let expected = keccak256(expected_buf); + + assert_eq!(usdc_balance_storage_key(&addr), expected); + } +}
diff --git reth/crates/seismic/txpool/src/validator.rs seismic-reth/crates/seismic/txpool/src/validator.rs new file mode 100644 index 0000000000000000000000000000000000000000..00774e28f49a07c2b771c80777635c7470f97caa --- /dev/null +++ seismic-reth/crates/seismic/txpool/src/validator.rs @@ -0,0 +1,279 @@ +//! Seismic transaction validator + +use crate::recent_block_cache::RecentBlockCache; +use alloy_consensus::BlockHeader; +use alloy_primitives::{Sealable, TxKind, B256, U256}; +use reth_chainspec::ChainSpecProvider; +use reth_primitives_traits::{transaction::error::InvalidTransactionError, Block, GotExpected}; +use reth_provider::{BlockReaderIdExt, StateProviderFactory}; +use reth_seismic_primitives::{transaction::error::SeismicTxError, SeismicTransactionSigned}; +use reth_transaction_pool::{ + error::InvalidPoolTransactionError, + validate::{TransactionValidationOutcome, TransactionValidator}, + EthPoolTransaction, EthTransactionValidator, TransactionOrigin, +}; +use seismic_alloy_consensus::SeismicTxType; +use std::{ + fmt, + marker::PhantomData, + sync::{Arc, RwLock}, +}; + +/// Seismic transaction validator that adds seismic-specific validation on top of Ethereum +/// validation. +pub struct SeismicTransactionValidator<Client, T> { + /// Inner Ethereum transaction validator + inner: Arc<EthTransactionValidator<Client, T>>, + /// Cache of recent block hashes for O(1) validation + recent_blocks: RwLock<RecentBlockCache>, + /// Phantom data for transaction type + _pd: PhantomData<T>, +} + +impl<Client, T> fmt::Debug for SeismicTransactionValidator<Client, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SeismicTransactionValidator") + .field("inner", &"EthTransactionValidator") + .field("recent_blocks", &"RwLock<RecentBlockCache>") + .finish() + } +} + +impl<Client, T> SeismicTransactionValidator<Client, T> +where + Client: BlockReaderIdExt, +{ + /// Creates a new seismic transaction validator wrapping an Ethereum validator. + /// + /// Pre-populates the recent block hash cache from the client so that validation + /// works immediately without a cold-start fallback. + pub fn new(inner: EthTransactionValidator<Client, T>) -> Self { + let mut cache = RecentBlockCache::default(); + + // Populate cache from the current canonical chain + if let Ok(tip) = inner.client().best_block_number() { + cache.rebuild_to_tip(tip, |n| { + inner.client().header_by_number(n).ok()?.map(|h| h.hash_slow()) + }); + } + + Self { inner: Arc::new(inner), recent_blocks: RwLock::new(cache), _pd: PhantomData } + } + + /// Get a reference to the inner validator + pub fn inner(&self) -> &EthTransactionValidator<Client, T> { + &self.inner + } +} + +impl<Client, Tx> TransactionValidator for SeismicTransactionValidator<Client, Tx> +where + Client: StateProviderFactory + + BlockReaderIdExt + + ChainSpecProvider<ChainSpec: reth_chainspec::EthereumHardforks> + + Clone + + 'static, + Tx: EthPoolTransaction<Consensus = SeismicTransactionSigned> + fmt::Debug, +{ + type Transaction = Tx; + + async fn validate_transaction( + &self, + origin: TransactionOrigin, + transaction: Self::Transaction, + ) -> TransactionValidationOutcome<Self::Transaction> { + // First run the standard Ethereum validation + let outcome = self.inner.validate_transaction(origin, transaction).await; + + // If the standard validation failed, return early + match outcome { + TransactionValidationOutcome::Valid { + balance, + state_nonce, + transaction: valid_tx, + propagate, + bytecode_hash, + authorities, + } => { + // Validation passed, continue with seismic-specific checks + let consensus_tx = valid_tx.transaction().clone_into_consensus(); + + // Only validate seismic transactions + if consensus_tx.tx_type() == SeismicTxType::Seismic { + // Get seismic elements from the transaction + if let seismic_alloy_consensus::SeismicTypedTransaction::Seismic(seismic_tx) = + consensus_tx.transaction() + { + let seismic_elements = &seismic_tx.seismic_elements; + + // Validate recent_block_hash is in the last 100 blocks + if let Err(err) = + self.validate_recent_block_hash(seismic_elements.recent_block_hash) + { + return TransactionValidationOutcome::Invalid( + valid_tx.into_transaction(), + err, + ); + } + + // Validate expires_at_block is not in the past + if let Err(err) = + self.validate_expiration(seismic_elements.expires_at_block) + { + return TransactionValidationOutcome::Invalid( + valid_tx.into_transaction(), + err, + ); + } + + // Validate signed_read for write transactions + if let Err(err) = Self::validate_signed_read_for_write( + seismic_tx.to, + seismic_elements.signed_read, + ) { + return TransactionValidationOutcome::Invalid( + valid_tx.into_transaction(), + err, + ); + } + } + } + + // Compute the effective balance: max(native, usdc_scaled). + // Gas on Seismic can be paid in either native token or USDC, so + // we consider both when deciding pool admission. + let sender = *valid_tx.transaction().sender_ref(); + let cost = *valid_tx.transaction().cost(); + let (eff_balance, usdc_raw) = match self.inner.client().latest() { + Ok(state) => { + let usdc = crate::usdc::read_usdc_balance(&*state, &sender); + (std::cmp::max(balance, usdc), usdc) + } + // If we can't read state, fall back to native balance only. + Err(err) => { + tracing::warn!( + target: "seismic::txpool", + %err, + %sender, + "failed to read state for USDC balance check" + ); + (balance, U256::ZERO) + } + }; + + tracing::debug!( + target: "seismic::txpool", + %sender, + tx_hash = %valid_tx.hash(), + native_balance = %balance, + usdc_scaled_balance = %usdc_raw, + effective_balance = %eff_balance, + cost = %cost, + "seismic validator effective balance check" + ); + + // Reject if the sender cannot afford the transaction with either token. + if cost > eff_balance { + tracing::debug!( + target: "seismic::txpool", + %sender, + tx_hash = %valid_tx.hash(), + effective_balance = %eff_balance, + cost = %cost, + "rejecting tx: effective balance insufficient for cost" + ); + return TransactionValidationOutcome::Invalid( + valid_tx.into_transaction(), + InvalidTransactionError::InsufficientFunds( + GotExpected { got: eff_balance, expected: cost }.into(), + ) + .into(), + ); + } + + TransactionValidationOutcome::Valid { + balance: eff_balance, + state_nonce, + transaction: valid_tx, + propagate, + bytecode_hash, + authorities, + } + } + // For invalid or error outcomes, pass through + other => other, + } + } + + fn on_new_head_block<B>(&self, new_tip_block: &reth_primitives_traits::SealedBlock<B>) + where + B: Block, + { + self.inner.on_new_head_block(new_tip_block); + + let mut cache = self.recent_blocks.write().unwrap_or_else(|e| e.into_inner()); + cache.update(new_tip_block.hash(), new_tip_block.header().number(), |n| { + self.inner.client().header_by_number(n).ok()?.map(|h| h.hash_slow()) + }); + } +} + +impl<Client, Tx> SeismicTransactionValidator<Client, Tx> { + /// Validates that the `recent_block_hash` field provided in a Seismic tx + /// is in the last `SEISMIC_TX_RECENT_BLOCK_LOOKBACK` blocks. + /// + /// Uses an in-memory cache populated at startup and updated via `on_new_head_block` + /// for O(1) lookup. + fn validate_recent_block_hash( + &self, + recent_block_hash: B256, + ) -> Result<(), InvalidPoolTransactionError> { + let cache = self.recent_blocks.read().unwrap_or_else(|e| e.into_inner()); + if cache.contains(&recent_block_hash) { + return Ok(()); + } + + let err = SeismicTxError::RecentBlockHashNotFound { + hash: recent_block_hash, + lookback: crate::SEISMIC_TX_RECENT_BLOCK_LOOKBACK, + }; + Err(InvalidTransactionError::SeismicTx(err.to_string()).into()) + } + + /// Validates that the transaction has not expired. + /// + /// Uses the cache's `current_block_number` (updated via `on_new_head_block`) so that + /// both hash validation and expiration check use the same consensus-driven source. + fn validate_expiration( + &self, + expires_at_block: u64, + ) -> Result<(), InvalidPoolTransactionError> { + let current_block_num = + self.recent_blocks.read().unwrap_or_else(|e| e.into_inner()).current_block_number(); + + if current_block_num > expires_at_block { + let err = SeismicTxError::TransactionExpired { + current_block: current_block_num, + expires_at_block, + }; + return Err(InvalidTransactionError::SeismicTx(err.to_string()).into()); + } + + Ok(()) + } + + /// Validates that `signed_read` is false for write transactions (transactions with a `to` + /// address) + fn validate_signed_read_for_write( + to: TxKind, + signed_read: bool, + ) -> Result<(), InvalidPoolTransactionError> { + // If this is a write transaction (has a destination), signed_read must be false + if !to.is_create() && signed_read { + let err = SeismicTxError::InvalidSignedReadForWrite; + return Err(InvalidTransactionError::SeismicTx(err.to_string()).into()); + } + + Ok(()) + } +}
diff --git reth/crates/seismic/chainspec/Cargo.toml seismic-reth/crates/seismic/chainspec/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..b8710e3f328ae9587debdf0b368777d5acc57f7f --- /dev/null +++ seismic-reth/crates/seismic/chainspec/Cargo.toml @@ -0,0 +1,69 @@ +[package] +name = "reth-seismic-chainspec" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "EVM chain spec implementation for seismic" + +[lints] +workspace = true + +[dependencies] +# reth +reth-chainspec.workspace = true +reth-ethereum-forks.workspace = true +reth-primitives-traits.workspace = true +reth-network-peers.workspace = true + +# seismic-reth +reth-seismic-primitives.workspace = true +reth-seismic-forks.workspace = true + +# ethereum +alloy-chains.workspace = true +alloy-genesis.workspace = true +alloy-primitives.workspace = true +alloy-consensus.workspace = true +alloy-eips.workspace = true +alloy-hardforks.workspace = true + +# op +seismic-alloy-rpc-types.workspace = true +seismic-alloy-consensus.workspace = true +# io +serde_json.workspace = true + +# misc +thiserror.workspace = true +derive_more.workspace = true +once_cell.workspace = true + +[dev-dependencies] +reth-chainspec = { workspace = true, features = ["test-utils"] } +alloy-genesis.workspace = true +seismic-alloy-rpc-types.workspace = true + +[features] +default = ["std"] +timestamp-in-seconds = [] +std = [ + "alloy-chains/std", + "alloy-genesis/std", + "alloy-primitives/std", + "alloy-eips/std", + "seismic-alloy-rpc-types/std", + "reth-chainspec/std", + "reth-ethereum-forks/std", + "reth-primitives-traits/std", + "reth-seismic-primitives/std", + "alloy-consensus/std", + "once_cell/std", + "derive_more/std", + "reth-network-peers/std", + "thiserror/std", + "serde_json/std", + "seismic-alloy-consensus/std", +]
diff --git reth/crates/seismic/chainspec/res/genesis/dev.json seismic-reth/crates/seismic/chainspec/res/genesis/dev.json new file mode 100644 index 0000000000000000000000000000000000000000..f703b154d161df8bb3f8deb923ea12ea41109b91 --- /dev/null +++ seismic-reth/crates/seismic/chainspec/res/genesis/dev.json @@ -0,0 +1,100 @@ +{ + "config": { + "berlinBlock": 0, + "byzantiumBlock": 0, + "cancunTime": 0, + "chainId": 5124, + "constantinopleBlock": 0, + "daoForkSupport": true, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "ethash": {}, + "homesteadBlock": 0, + "istanbulBlock": 0, + "londonBlock": 0, + "osakaTime": 0, + "petersburgBlock": 0, + "pragueTime": 0, + "shanghaiTime": 0, + "terminalTotalDifficulty": 0 + }, + "alloc": { + "0x0000000000000000000000000000000000002001": { + "balance": "0x0", + "code": "0x60806040526004361015610015575b36610a3057005b61001f5f356100de565b80630e292a29146100d95780632cc06b1e146100d45780632f1d7903146100cf57806331b00e46146100ca5780635e677dd0146100c557806368eddae7146100c05780638730d33b146100bb5780638d80ff0a146100b6578063a85f5c37146100b1578063c9e6db8e146100ac578063ed24911d146100a75763fac750e00361000e576109fb565b6109c6565b61096c565b610917565b6108df565b610876565b610800565b610726565b6105cd565b6104e4565b61032c565b6101ff565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b63ffffffff1690565b610108816100f6565b0361010f57565b5f80fd5b90503590610120826100ff565b565b5f80fd5b5f80fd5b5f80fd5b909182601f830112156101685781359167ffffffffffffffff831161016357602001926001830284011161015e57565b61012a565b610126565b610122565b6060818303126101d357610183825f8301610113565b92602082013567ffffffffffffffff81116101ce57836101a491840161012e565b929093604082013567ffffffffffffffff81116101c9576101c5920161012e565b9091565b6100f2565b6100f2565b6100ee565b151590565b6101e6906101d8565b9052565b91906101fd905f602085019401906101dd565b565b346102335761022f61021e61021536600461016d565b93929092610e9f565b6102266100e4565b918291826101ea565b0390f35b6100ea565b6003111561024257565b5f80fd5b9050359061025382610238565b565b64ffffffffff1690565b61026881610255565b0361026f57565b5f80fd5b905035906102808261025f565b565b90565b61028e81610282565b0361029557565b5f80fd5b905035906102a682610285565b565b91608083830312610305576102bf825f8501610246565b9260208101359167ffffffffffffffff8311610300576102e4846102fd94840161012e565b9390946102f48160408601610273565b93606001610299565b90565b6100f2565b6100ee565b610313906100f6565b9052565b919061032a905f6020850194019061030a565b565b346103605761035c61034b6103423660046102a8565b939290926117ca565b6103536100e4565b91829182610317565b0390f35b6100ea565b9060208282031261037e5761037b915f01610113565b90565b6100ee565b61038c90610255565b9052565b634e487b7160e01b5f52602160045260245ffd5b600311156103ae57565b610390565b906103bd826103a4565b565b6103c8906103b3565b90565b6103d4906103bf565b9052565b6103e1906101d8565b9052565b5190565b60209181520190565b90825f9392825e0152565b601f801991011690565b61042661042f6020936104349361041d816103e5565b938480936103e9565b958691016103f2565b6103fd565b0190565b61044190610282565b9052565b906104c99060c08061049a60e084016104645f8801515f870190610383565b610476602088015160208701906103cb565b610488604088015160408701906103d8565b60608701518582036060870152610407565b946104ad60808201516080860190610438565b6104bf60a082015160a0860190610438565b0151910190610438565b90565b6104e19160208201915f818403910152610445565b90565b34610514576105106104ff6104fa366004610365565b611959565b6105076100e4565b918291826104cc565b0390f35b6100ea565b9060208282031261054a575f82013567ffffffffffffffff811161054557610541920161012e565b9091565b6100f2565b6100ee565b6bffffffffffffffffffffffff1690565b6105699061054f565b9052565b60209181520190565b61059561059e6020936105a39361058c816103e5565b9384809361056d565b958691016103f2565b6103fd565b0190565b916105ca926105bd60408201935f830190610560565b6020818403910152610576565b90565b346105ff576105e66105e0366004610519565b906119e0565b906105fb6105f26100e4565b928392836105a7565b0390f35b6100ea565b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b90610626906103fd565b810190811067ffffffffffffffff82111761064057604052565b610608565b906106586106516100e4565b928361061c565b565b67ffffffffffffffff8111610678576106746020916103fd565b0190565b610608565b90825f939282370152565b9092919261069d6106988261065a565b610645565b938185526020850190828401116106b9576106b79261067d565b565b610604565b9080601f830112156106dc578160206106d993359101610688565b90565b610122565b919091604081840312610721576106fa835f8301610246565b92602082013567ffffffffffffffff811161071c5761071992016106be565b90565b6100f2565b6100ee565b346107575761075361074261073c3660046106e1565b90611b9f565b61074a6100e4565b91829182610317565b0390f35b6100ea565b6107658161054f565b0361076c57565b5f80fd5b9050359061077d8261075c565b565b91906080838203126107f657610797815f8501610770565b92602081013567ffffffffffffffff81116107f157826107b891830161012e565b929093604083013567ffffffffffffffff81116107ec576107de836107e992860161012e565b939094606001610113565b90565b6100f2565b6100f2565b6100ee565b5f0190565b61081a61080e36600461077f565b94939093929192611ddb565b6108226100e4565b8061082c816107fb565b0390f35b91909160408184031261087157610849835f8301610246565b92602082013567ffffffffffffffff811161086c57610868920161012e565b9091565b6100f2565b6100ee565b346108a55761088f610889366004610830565b916124e2565b6108976100e4565b806108a1816107fb565b0390f35b6100ea565b906020828203126108da575f82013567ffffffffffffffff81116108d5576108d292016106be565b90565b6100f2565b6100ee565b6108f26108ed3660046108aa565b6124ef565b6108fa6100e4565b80610904816107fb565b0390f35b5f91031261091257565b6100ee565b3461094557610927366004610908565b61092f612713565b6109376100e4565b80610941816107fb565b0390f35b6100ea565b61095390610282565b9052565b919061096a905f6020850194019061094a565b565b3461099c57610998610987610982366004610365565b61271d565b61098f6100e4565b91829182610957565b0390f35b6100ea565b90565b6109ad906109a1565b9052565b91906109c4905f602085019401906109a4565b565b346109f6576109d6366004610908565b6109f26109e1612762565b6109e96100e4565b918291826109b1565b0390f35b6100ea565b34610a2b57610a0b366004610908565b610a27610a1661278f565b610a1e6100e4565b91829182610957565b0390f35b6100ea565b5f80fd5b5f90565b90565b90565b610a52610a4d610a5792610a38565b610a3b565b6100f6565b90565b634e487b7160e01b5f52601160045260245ffd5b610a7a610a80916100f6565b916100f6565b90039063ffffffff8211610a9057565b610a5a565b634e487b7160e01b5f52603260045260245ffd5b5490565b5f5260205f2090565b610abf81610aa9565b821015610ad957610ad1600591610aad565b910201905f90565b610a95565b90565b5f1c90565b64ffffffffff1690565b610afc610b0191610ae1565b610ae6565b90565b610b0e9054610af0565b90565b610b25610b20610b2a92610255565b610a3b565b610282565b90565b60209181520190565b5f7f6b65792065787069726564000000000000000000000000000000000000000000910152565b610b6a600b602092610b2d565b610b7381610b36565b0190565b610b8c9060208101905f818303910152610b5d565b90565b15610b9657565b610b9e6100e4565b62461bcd60e51b815280610bb460048201610b77565b0390fd5b60281c90565b60ff1690565b610bd0610bd591610bb8565b610bbe565b90565b610be29054610bc4565b90565b634e487b7160e01b5f52602260045260245ffd5b9060016002830492168015610c19575b6020831014610c1457565b610be5565b91607f1691610c09565b5f5260205f2090565b905f9291805490610c46610c3f83610bf9565b80946103e9565b916001811690815f14610c9d5750600114610c61575b505050565b610c6e9192939450610c23565b915f925b818410610c8557505001905f8080610c5c565b60018160209295939554848601520191019290610c72565b92949550505060ff19168252151560200201905f8080610c5c565b90610cc291610c2c565b90565b90610ce5610cde92610cd56100e4565b93848092610cb8565b038361061c565b565b610cf090610cc5565b90565b5f7f6b6579207265766f6b6564000000000000000000000000000000000000000000910152565b610d27600b602092610b2d565b610d3081610cf3565b0190565b610d499060208101905f818303910152610d1a565b90565b15610d5357565b610d5b6100e4565b62461bcd60e51b815280610d7160048201610d34565b0390fd5b90565b610d84610d8991610ae1565b610d75565b90565b610d969054610d78565b90565b610da4913691610688565b90565b5f7f696e76616c696420736967000000000000000000000000000000000000000000910152565b610ddb600b602092610b2d565b610de481610da7565b0190565b610dfd9060208101905f818303910152610dce565b90565b15610e0757565b610e0f6100e4565b62461bcd60e51b815280610e2560048201610de8565b0390fd5b610e3290610282565b5f198114610e405760010190565b610a5a565b5f1b90565b90610e565f1991610e45565b9181191691161790565b610e74610e6f610e7992610282565b610a3b565b610282565b90565b90565b90610e94610e8f610e9b92610e60565b610e7c565b8254610e4a565b9055565b91600493610fb295610f73610f9593610f9a95610eba610a34565b50610f4e610eef610ee96002610ece61282b565b01610ee38c610edd6001610a3e565b90610a6e565b90610ab6565b50610ade565b98610f16610efe5f8c01610b04565b610f10610f0a42610282565b91610b11565b11610b8f565b610f48610f42610f3d8c610f376001610f305f8401610bd8565b9201610ce7565b90611b9f565b6100f6565b916100f6565b14610d4c565b610f6d610f59612762565b610f648b8b01610d8c565b92939093610d99565b90612902565b91610f7f5f8701610bd8565b610f8f6001880194929394610ce7565b90612a18565b610e00565b01610fac610fa782610d8c565b610e29565b90610e7f565b600190565b5f90565b60018060a01b031690565b610fda610fd5610fdf92610fbb565b610a3b565b610fbb565b90565b610feb90610fc6565b90565b610ff790610fe2565b90565b61100390610fbb565b90565b5f7f6f6e6c792073656c660000000000000000000000000000000000000000000000910152565b61103a6009602092610b2d565b61104381611006565b0190565b61105c9060208101905f81830391015261102d565b90565b1561106657565b61106e6100e4565b62461bcd60e51b81528061108460048201611047565b0390fd5b906110ba95949392916110b5336110af6110a96110a430610fee565b610ffa565b91610ffa565b1461105f565b611665565b90565b6110c760e0610645565b90565b906110d490610255565b9052565b906110e2906103b3565b9052565b906110f0906101d8565b9052565b52565b9061110190610282565b9052565b90565b61111c61111761112192611105565b610a3b565b610282565b90565b61113861113361113d92610282565b610a3b565b6100f6565b90565b90565b5f5260205f2090565b5490565b6111598161114c565b8210156111735761116b600591611143565b910201905f90565b610a95565b634e487b7160e01b5f525f60045260245ffd5b6111959051610255565b90565b906111a864ffffffffff91610e45565b9181191691161790565b6111c66111c16111cb92610255565b610a3b565b610255565b90565b90565b906111e66111e16111ed926111b2565b6111ce565b8254611198565b9055565b6111fb90516103b3565b90565b60281b90565b9061121565ff0000000000916111fe565b9181191691161790565b611228906103b3565b90565b90565b9061124361123e61124a9261121f565b61122b565b8254611204565b9055565b61125890516101d8565b90565b60301b90565b9061127366ff0000000000009161125b565b9181191691161790565b611286906101d8565b90565b90565b906112a161129c6112a89261127d565b611289565b8254611261565b9055565b5190565b601f602091010490565b1b90565b919060086112d99102916112d35f19846112ba565b926112ba565b9181191691161790565b91906112f96112f461130193610e60565b610e7c565b9083546112be565b9055565b5f90565b61131b91611315611305565b916112e3565b565b5b818110611329575050565b806113365f600193611309565b0161131e565b9190601f811161134c575b505050565b61135861137d93610c23565b906020611364846112b0565b83019310611385575b611376906112b0565b019061131d565b5f8080611347565b91506113768192905061136d565b1c90565b906113a7905f1990600802611393565b191690565b816113b691611397565b906002021790565b906113c8816103e5565b9067ffffffffffffffff8211611488576113ec826113e68554610bf9565b8561133c565b602090601f83116001146114205791809161140f935f92611414575b50506113ac565b90555b565b90915001515f80611408565b601f1983169161142f85610c23565b925f5b81811061147057509160029391856001969410611456575b50505002019055611412565b611466910151601f841690611397565b90555f808061144a565b91936020600181928787015181550195019201611432565b610608565b90611497916113be565b565b6114a39051610282565b90565b9061154c60c06004611552946114c95f82016114c35f880161118b565b906111d1565b6114e15f82016114db602088016111f1565b9061122e565b6114f95f82016114f36040880161124e565b9061128c565b6115126001820161150c606088016112ac565b9061148d565b61152b6002820161152560808801611499565b90610e7f565b6115446003820161153e60a08801611499565b90610e7f565b019201611499565b90610e7f565b565b919061156557611563916114a6565b565b611178565b908154916801000000000000000083101561159a578261159291600161159895018155611150565b90611554565b565b610608565b6115ab6115b1916100f6565b916100f6565b019063ffffffff82116115c057565b610a5a565b6115ce906109a1565b90565b906115db906115c5565b5f5260205260405f2090565b906115f663ffffffff91610e45565b9181191691161790565b61161461160f611619926100f6565b610a3b565b6100f6565b90565b90565b9061163461162f61163b92611600565b61161c565b82546115e7565b9055565b916116629261165560408201935f8301906109a4565b6020818403910152610445565b90565b9490949392935061167461282b565b92859083869193905f925f9460019061168b6110bd565b975f890190611699916110ca565b60208801906116a7916110d8565b60408701906116b5916110e6565b6116be91610d99565b60608501906116cc916110f4565b60808401906116da916110f7565b6116e390611108565b60a08301906116f1916110f7565b6116fa90611108565b60c0820190611708916110f7565b928260020161171690610aa9565b61171f90611124565b948360020161172d90611140565b856117379161156a565b919061174291610d99565b61174b91612b9c565b9083600161175890610a3e565b6117619161159f565b906003018261176f916115d1565b906117799161161f565b7f4ea58b0cfbd7dbef4ca1db95d39abfddd4b9a1614dbd63cfb36d3b132e4589d7916117a36100e4565b9182916117b0918361163f565b0390a160016117be90610a3e565b6117c79161159f565b90565b906117df949392916117da610fb7565b611088565b90565b6117ec60e0610645565b90565b5f90565b5f90565b5f90565b606090565b5f90565b61180c6117e2565b9060208080808080808861181e6117ef565b8152016118296117f3565b8152016118346117f7565b81520161183f6117fb565b81520161184a611800565b815201611855611800565b815201611860611800565b81525050565b61186e611804565b90565b60301c90565b60ff1690565b61188961188e91611871565b611877565b90565b61189b905461187d565b90565b9061194b61194260046118af6117e2565b946118c66118be5f8301610b04565b5f88016110ca565b6118dd6118d45f8301610bd8565b602088016110d8565b6118f46118eb5f8301611891565b604088016110e6565b61190c61190360018301610cc5565b606088016110f4565b61192461191b60028301610d8c565b608088016110f7565b61193c61193360038301610d8c565b60a088016110f7565b01610d8c565b60c084016110f7565b565b6119569061189e565b90565b61198e61199491611968611866565b50611988600261197661282b565b01916119826001610a3e565b90610a6e565b90610ab6565b5061194d565b90565b5f90565b606090565b6119b46119af6119b992611105565b610a3b565b61054f565b90565b90565b6119cb6119d091610ae1565b6119bc565b90565b6119dd90b06119bf565b90565b9190916119eb611997565b506119f461199b565b506119fd612d82565b5b80611a11611a0b5f6119a0565b9161054f565b03611a245750611a1f612d82565b6119fe565b92611a4c91611a46611a3e5f611a3861282b565b016119d3565b928692610d99565b9161301c565b90565b63ffffffff1690565b611a64611a6991610ae1565b611a4f565b90565b611a769054611a58565b90565b611a8d611a88611a9292611105565b610a3b565b6100f6565b90565b5f7f6b6579206e6f7420666f756e6400000000000000000000000000000000000000910152565b611ac9600d602092610b2d565b611ad281611a95565b0190565b611aeb9060208101905f818303910152611abc565b90565b15611af557565b611afd6100e4565b62461bcd60e51b815280611b1360048201611ad6565b0390fd5b60200190565b5f7f696e76616c6964206b6579206d617070696e6700000000000000000000000000910152565b611b516013602092610b2d565b611b5a81611b1d565b0190565b611b739060208101905f818303910152611b44565b90565b15611b7d57565b611b856100e4565b62461bcd60e51b815280611b9b60048201611b5e565b0390fd5b90611c4090611bac610fb7565b50611bb561282b565b90611bd5611bd0611bc7868490612b9c565b600385016115d1565b611a6c565b93611bf385611bec611be65f611a79565b916100f6565b1415611aee565b611c31611c2b611c255f611c1e60028801611c188b611c126001610a3e565b90610a6e565b90610ab6565b5001610bd8565b926103b3565b916103b3565b149182611c43575b5050611b76565b90565b611caa919250611c786001611c716002611ca49401611c6b89611c6585610a3e565b90610a6e565b90610ab6565b5001610ce7565b611c8a611c84826103e5565b91611b17565b2092611c9e611c98826103e5565b91611b17565b206109a1565b916109a1565b145f80611c39565b5f7f696e76616c6964207369676e6174757265000000000000000000000000000000910152565b611ce66011602092610b2d565b611cef81611cb2565b0190565b611d089060208101905f818303910152611cd9565b90565b15611d1257565b611d1a6100e4565b62461bcd60e51b815280611d3060048201611cf3565b0390fd5b611d43611d4991939293610282565b92610282565b8201809211611d5457565b610a5a565b5f7f7370656e64206c696d6974206578636565646564000000000000000000000000910152565b611d8d6014602092610b2d565b611d9681611d59565b0190565b611daf9060208101905f818303910152611d80565b90565b15611db957565b611dc16100e4565b62461bcd60e51b815280611dd760048201611d9a565b0390fd5b91949092611de761282b565b94611df061199b565b5033611e0c611e06611e0130610fee565b610ffa565b91610ffa565b145f14611e68575050509081611e479492611e2f611e295f6119a0565b9161054f565b145f14611e4a5750611e419250610d99565b5b6124ef565b5b565b9190611e5a5f611e6395016119d3565b9290919261324a565b611e42565b859295600201866001611e7a90610a3e565b611e8391610a6e565b611e8c91610ab6565b50611e9690610ade565b95865f01611ea390610b04565b42611ead90610282565b90611eb790610b11565b11611ec190610b8f565b83600301875f01611ed190610bd8565b88600101611ede90610ce7565b611ee791612b9c565b611ef0916115d1565b611ef990611a6c565b611f02906100f6565b90611f0c906100f6565b14611f1690610d4c565b85600401611f2390610d8c565b8588907f000000000000000000000000000000000000000000000000000000000000000091611f5191610d99565b611f5a92612902565b90865f01611f6790610bd8565b928760010192909192611f7990610ce7565b611f8294612a18565b611f8b90611d0b565b815f611f96906119a0565b90611fa09061054f565b145f14946120069360049361200b9761207a5750611fbe9250610d99565b925b611fc95f611108565b50611fd660028201610d8c565b611fe8611fe25f611108565b91610282565b03612010575b01612000611ffb82610d8c565b610e29565b90610e7f565b6124ef565b611e48565b61207561201c85613504565b61205961203561202e60038601610d8c565b8390611d34565b61205261204c61204760028801610d8c565b610282565b91610282565b1115611db2565b61206f600384019161206a83610d8c565b611d34565b90610e7f565b611fee565b919061208a5f61209395016119d3565b9290919261324a565b92611fc0565b906120c892916120c3336120bd6120b76120b230610fee565b610ffa565b91610ffa565b1461105f565b61236e565b565b634e487b7160e01b5f52603160045260245ffd5b906120f1905f1990602003600802611393565b8154169055565b905f9161210f61210782610c23565b9283546113ac565b905555565b919290602082105f1461216d57601f841160011461213d576121379293506113ac565b90555b5b565b509061216361216893600161215a61215485610c23565b926112b0565b8201910161131d565b6120f8565b61213a565b506121a4829361217e600194610c23565b61219d61218a856112b0565b820192601f8616806121af575b506112b0565b019061131d565b60020217905561213b565b6121bb908886036120de565b5f612197565b929091680100000000000000008211612221576020115f1461221257602081105f146121f6576121f0916113ac565b90555b5b565b60019160ff191661220684610c23565b556002020190556121f3565b600191506002020190556121f4565b610608565b90815461223281610bf9565b9081831161225b575b818310612249575b50505050565b61225293612114565b5f808080612243565b612267838383876121c1565b61223b565b5f61227691612226565b565b905f0361228a576122889061226c565b565b611178565b5f60046122c89282808201556122a88360018301612278565b6122b58360028301611309565b6122c28360038301611309565b01611309565b565b905f036122dc576122da9061228f565b565b611178565b6122ea8161114c565b801561230b5760019003906123086123028383611150565b906122ca565b55565b6120ca565b9190600861232e91029161232863ffffffff846112ba565b926112ba565b9181191691161790565b919061234e61234961235693611600565b61161c565b908354612310565b9055565b61236c91612366610fb7565b91612338565b565b9161241460036123956124199461238f5f9561238861282b565b9892610d99565b90612b9c565b946123ab6123a683830188906115d1565b611a6c565b6123c8816123c16123bb88611a79565b916100f6565b1415611aee565b6123dc6123d760028401610aa9565b611124565b90806123f06123ea846100f6565b916100f6565b03612454575b505061240c61240760028301611140565b6122e1565b0184906115d1565b61235a565b61244f7fd76dbee353f8817df12bf008d3fec1c2f26c9afc1e832f74757756b060b25f82916124466100e4565b918291826109b1565b0390a1565b6124d661248561247f6124db9461247960028801916124736001610a3e565b90610a6e565b90610ab6565b5061194d565b916124b1836124ab600288016124a58561249f6001610a3e565b90610a6e565b90610ab6565b90611554565b916124d08686019160606124c7602083016111f1565b91015190612b9c565b906115d1565b61161f565b5f806123f6565b906124ed9291612099565b565b80519060205b82811061250157505050565b8082015160f81c6001820183015160601c308115021760158301840151916035840185015192836055860187015f9392835f146125615750505090915060011461255d575b5f1461255557605501016124f5565b3d5f803e3d5ffd5b5f80fd5b5f958695508594505af19050612546565b6125963361259061258a61258530610fee565b610ffa565b91610ffa565b1461105f565b61259e612643565b565b6125ac6125b191610ae1565b611877565b90565b6125be90546125a0565b90565b5f7f414553206b657920616c726561647920696e697469616c697a65640000000000910152565b6125f5601b602092610b2d565b6125fe816125c1565b0190565b6126179060208101905f8183039101526125e8565b90565b1561262157565b6126296100e4565b62461bcd60e51b81528061263f60048201612602565b0390fd5b61266761266261265c600161265661282b565b016125b4565b156101d8565b61261a565b61266f6126e9565b565b90565b61268861268361268d92612671565b610a3b565b612671565b90565b90565b906126a86126a36126af92612674565b612690565b82b0610e4a565b90b1565b906126bf60ff91610e45565b9181191691161790565b906126de6126d96126e59261127d565b611289565b82546126b3565b9055565b6127116126f461282b565b6127076126ff613784565b5f8301612693565b60018091016126c9565b565b61271b612572565b565b600461275461275b9261272e611305565b5061274e600261273c61282b565b01916127486001610a3e565b90610a6e565b90610ab6565b5001610d8c565b90565b5f90565b61276a61275e565b507f000000000000000000000000000000000000000000000000000000000000000090565b612797611305565b506127ab60026127a561282b565b01610aa9565b90565b68ffffffffffffffffff60b81b1690565b6127c8906127ae565b90565b60b81c90565b68ffffffffffffffffff1690565b6127f36127ee6127f8926127d1565b610a3b565b6127d1565b90565b61280761280c916127cb565b6127df565b90565b61282361281e612828926127d1565b610a3b565b610282565b90565b61286461285f61285a7f2a2cc7db52019c9ff565d289628faa407289ea9f1a3741cac1acd5fa3e843b636127bf565b6127fb565b61280f565b90565b604090612890612897949695939661288660608401985f8501906109a4565b602083019061094a565b01906109a4565b565b905090565b5f61190160f01b910152565b6128b660028092612899565b6128bf8161289e565b0190565b90565b6128d26128d7916109a1565b6128c3565b9052565b60208093926128f66128ef6128fe946128aa565b80926128c6565b0180926128c6565b0190565b9061296f6129a99261291261275e565b506129607f9bb939585d47b76d88b01231eb395b17e90aab08b4c65e93bb1425c9708dbab7919361294b612945826103e5565b91611b17565b206129546100e4565b94859360208501612867565b6020820181038252038261061c565b61298161297b826103e5565b91611b17565b209161299a61298e6100e4565b938492602084016128db565b6020820181038252038261061c565b6129bb6129b5826103e5565b91611b17565b2090565b6129c890610fbb565b90565b6129d4816129bf565b036129db57565b5f80fd5b905051906129ec826129cb565b565b90602082820312612a0757612a04915f016129df565b90565b6100ee565b612a1590610fe2565b90565b949391929094612a26610a34565b9080612a3a612a345f6103b3565b916103b3565b145f14612a7157505093612a56612a5f9392612a6d9596613c1b565b9390939161395d565b919091929390919293613c40565b905b565b80969296612a88612a8260016103b3565b916103b3565b145f14612aef575050612ae89394612ae0612adb612ac59594612aad612ad49561395d565b95909596612ab96100e4565b988991602083016109b1565b6020820181038252038861061c565b5f93610d99565b6139fc565b919293613abc565b905b612a6f565b95919095612b06612b0060026103b3565b916103b3565b14612b15575b50505050612aea565b612b46949550612b38612b41916020612b2d826103e5565b8183010191016129ee565b93919293612a0c565b61386d565b905f808080612b0c565b60ff1690565b60f81b90565b612b6590612b56565b90565b612b74612b7991612b50565b612b5c565b9052565b600181612b90612b989360209695612b68565b0180926128c6565b0190565b612bb1612bec91612bab61275e565b506103bf565b91612bc4612bbe826103e5565b91611b17565b2091612bdd612bd16100e4565b93849260208401612b7d565b6020820181038252038261061c565b612bfe612bf8826103e5565b91611b17565b2090565b90565b612c19612c14612c1e92612c02565b610a3b565b610fbb565b90565b612c2a90612c05565b90565b612c376064612c21565b90565b90565b612c51612c4c612c5692612c3a565b610a3b565b6100f6565b90565b60e01b90565b612c6890612c59565b90565b612c77612c7c916100f6565b612c5f565b9052565b612c8c81600493612c6b565b0190565b90612ca2612c9d8361065a565b610645565b918252565b3d5f14612cc257612cb73d612c90565b903d5f602084013e5b565b612cca61199b565b90612cc0565b5f7f524e4720507265636f6d70696c652063616c6c206661696c6564000000000000910152565b612d04601a602092610b2d565b612d0d81612cd0565b0190565b612d269060208101905f818303910152612cf7565b90565b15612d3057565b612d386100e4565b62461bcd60e51b815280612d4e60048201612d11565b0390fd5b612d5e612d6391610ae1565b610e60565b90565b612d7a612d75612d7f92610282565b610a3b565b61054f565b90565b612d8a611997565b50612dfb612df660205f80612d9d612c2d565b612dbf612dcd612dac86612c3d565b612db46100e4565b928391888301612c80565b87820181038252038261061c565b8481019051915afa612de6612de0612ca7565b91612d29565b612dee61275e565b500151612d52565b612d66565b90565b90565b612e0d612e1291612671565b612dfe565b9052565b60a01b90565b612e2590612e16565b90565b612e34612e399161054f565b612e1c565b9052565b905090565b612e67612e5e92602092612e55816103e5565b94858093612e3d565b938491016103f2565b0190565b91612e8a602084612e82612e919796600c96612e01565b018092612e28565b0190612e42565b90565b90565b612eab612ea6612eb092612e94565b610a3b565b610fbb565b90565b612ebc90612e97565b90565b612ec96066612eb3565b90565b60207f6564000000000000000000000000000000000000000000000000000000000000917f41455320656e637279707420707265636f6d70696c652063616c6c206661696c5f8201520152565b612f266022604092610b2d565b612f2f81612ecc565b0190565b612f489060208101905f818303910152612f19565b90565b15612f5257565b612f5a6100e4565b62461bcd60e51b815280612f7060048201612f33565b0390fd5b60207f7574000000000000000000000000000000000000000000000000000000000000917f456e6372797074696f6e2063616c6c2072657475726e6564206e6f206f7574705f8201520152565b612fce6022604092610b2d565b612fd781612f74565b0190565b612ff09060208101905f818303910152612fc1565b90565b15612ffa57565b6130026100e4565b62461bcd60e51b81528061301860048201612fdb565b0390fd5b916130565f9392613047859461303061199b565b50919361303b6100e4565b94859360208501612e6b565b6020820181038252038261061c565b61305e612ebf565b90602081019051915afa613079613073612ca7565b91612f4b565b61309d613085826103e5565b6130976130915f611108565b91610282565b11612ff3565b90565b5090565b5f7f436970686572746578742063616e6e6f7420626520656d707479000000000000910152565b6130d8601a602092610b2d565b6130e1816130a4565b0190565b6130fa9060208101905f8183039101526130cb565b90565b1561310457565b61310c6100e4565b62461bcd60e51b815280613122600482016130e5565b0390fd5b9091826131368161313d93612e3d565b809361067d565b0190565b916131606020846131586131679896600c96612e01565b018092612e28565b0191613126565b90565b90565b61318161317c6131869261316a565b610a3b565b610fbb565b90565b6131929061316d565b90565b61319f6067613189565b90565b60207f6564000000000000000000000000000000000000000000000000000000000000917f414553206465637279707420707265636f6d70696c652063616c6c206661696c5f8201520152565b6131fc6022604092610b2d565b613205816131a2565b0190565b61321e9060208101905f8183039101526131ef565b90565b1561322857565b6132306100e4565b62461bcd60e51b81528061324660048201613209565b0390fd5b5f939161329c8594936132ab9361325f61199b565b5061328661326e8784906130a0565b61328061327a8a611108565b91610282565b116130fd565b92946132906100e4565b95869460208601613141565b6020820181038252038261061c565b6132b3613195565b90602081019051915afa6132ce6132c8612ca7565b91613221565b90565b90565b6132e86132e36132ed926132d1565b610a3b565b610282565b90565b906132fa826103e5565b81101561330c57600160209102010190565b610a95565b60ff60f81b1690565b6133249051613311565b90565b60f81c90565b61334161333c61334692612b50565b610a3b565b612b50565b90565b61335561335a91613327565b61332d565b90565b61337161336c61337692611105565b610a3b565b612b50565b90565b90565b61339061338b61339592613379565b610a3b565b610282565b90565b6133ac6133a76133b192612c3a565b610a3b565b610282565b90565b60207f6c656e6774680000000000000000000000000000000000000000000000000000917f496e76616c6964204d756c746953656e6420646174613a2065786365656473205f8201520152565b61340e6026604092610b2d565b613417816133b4565b0190565b6134309060208101905f818303910152613401565b90565b1561343a57565b6134426100e4565b62461bcd60e51b8152806134586004820161341b565b0390fd5b60207f656420747261696c696e67206279746573000000000000000000000000000000917f496e76616c6964204d756c746953656e6420646174613a20756e6578706563745f8201520152565b6134b66031604092610b2d565b6134bf8161345c565b0190565b6134d89060208101905f8183039101526134a9565b90565b156134e257565b6134ea6100e4565b62461bcd60e51b815280613500600482016134c3565b0390fd5b9061350d611305565b906135175f611108565b91613521846103e5565b925b6135378161353160556132d4565b90611d34565b61354961354386610282565b91610282565b1161361c5761356961356461355f8784906132f0565b61331a565b613349565b61357b6135755f61335d565b91612b50565b146135ef575b6135986135ea91613592603561337c565b90611d34565b6135a0611305565b506135bc81602088010151916135b66020613398565b90611d34565b906135e46135cb838390611d34565b6135dd6135d789610282565b91610282565b1115613433565b90611d34565b613523565b906135986136136135ea92613602611305565b506015850160208901015190611d34565b92915050613581565b61363e9294506136326136389194929492610282565b91610282565b146134db565b90565b5f90565b5f7f6165732d6b657900000000000000000000000000000000000000000000000000910152565b61367860078092612899565b61368181613645565b0190565b90565b61369461369991610282565b613685565b9052565b906136b36136ac60209361366c565b8092613688565b0190565b806136c86004926136cf9594612c6b565b0190612e42565b90565b5f7f496e76616c696420524e47206f7574707574206c656e67746800000000000000910152565b6137066019602092610b2d565b61370f816136d2565b0190565b6137289060208101905f8183039101526136f9565b90565b1561373257565b61373a6100e4565b62461bcd60e51b81528061375060048201613713565b0390fd5b61376861376361376d92610282565b610a3b565b612671565b90565b61377c61378191610ae1565b613754565b90565b61378c613641565b5061384260205f806137ae6137bc426137a36100e4565b92839187830161369d565b86820181038252038261061c565b6137ec6137c885612c3d565b6137de6137d36100e4565b9384928884016136b7565b86820181038252038261061c565b6137f4612c2d565b908481019051915afa61380e613808612ca7565b91612d29565b61383261381a826103e5565b61382c61382685613398565b91610282565b1461372b565b61383a61275e565b500151613770565b90565b61385961385461385e92611105565b610a3b565b610fbb565b90565b61386a90613845565b90565b939291613878610a34565b948061389461388e6138895f613861565b610ffa565b91610ffa565b1461395757604051813b156138df5760209394959650631626ba7e60e01b94858252600482015260648660248301978895604087528160448601528385013701915afa91511416905b565b93929190928060401461392f576041146138fc57505050506138dd565b60408092939496508101355f1a60205281375b5f526020600160805f825afa511860601b3d11915f6060526040526138dd565b509091929450602081013590601b8260ff1c016020523560405260011b60011c60605261390f565b50505050565b9061396661275e565b5061396f61275e565b50603f8251116040816020850151029301510290565b61398f60c0610645565b90565b606090565b5f90565b6139a3613985565b9060208080808080876139b46117fb565b8152016139bf613992565b8152016139ca611800565b8152016139d5611800565b8152016139e0613997565b8152016139eb613997565b81525050565b6139f961399b565b90565b90613a056139f1565b9180519060c0821015613a17575b5050565b60200190810190808051019081108260c083011117613aaa5780805101918160208101510190828210818311178385108286111717613aa35780825160208401011190845160208601011117613a9d5760a09285526020850152604081015160408501526060810151606085015260808101516080850152015160a08301525f80613a13565b50613a13565b5050613a13565b613a13565b613ab990516109a1565b90565b949391929094613aca610a34565b50613ae0613ad661275e565b9160018091613cf0565b95602085015190602082519201976040870151606088015190825191600d83017f226368616c6c656e6765223a220000000000000000000000000000000000000060981c85528c878483011060228386840101515f1a1416918481601389012092012014169186826014011090821760801c10907f2274797065223a22776562617574686e2e67657422000000000000000000000060581c908d015160581c141616915286515191151560021b600117806021895101511614906020831116169788613be7575b50505085613bb6575b50505050565b613bdd94955092613bd560a0613bce60808401613aaf565b9201613aaf565b919293613c40565b905f808080613bb0565b6020919293506001908288510183858201809782825198019460025afa831b5afa5191523d15613c19575f8080613ba7565bfe5b9190603f90613c2861275e565b50613c3161275e565b50116020818435029301350290565b9290939193613c4d610a34565b506040519384526020840152836040840152606083015260808201525f805260205f60a0836101005afa503d15613cac575b507f7fffffff800000007fffffffffffffffde737d56d38bcf4279dce5617e3192a85f5160011491111090565b6d1ab2e8006fd8b71907bf06a5bdee3b15613cc7575b613c7f565b5f60a06020926dd01ea45f9efd5c54f037fa57ea1a5afa15613ce9575f613cc2565bfe5b606090565b929192613cfb613ceb565b93815180613d0a575b50505050565b90919294506003600282010460021b91610670604051967f4142434445464748494a4b4c4d4e4f505152535455565758595a616263646566601f5215027f6768696a6b6c6d6e6f707172737475767778797a303132333435363738392d5f18603f5260208601938385019280826020010195600460038851945f8a525b0191603f8351818160121c16515f538181600c1c1651600153818160061c165160025316516003535f518152019085821015613dd05790603f6003600493909150929192613d87565b50955f9460039360209252016040520660020490613d3d60f01b82860352151502809303520382525f808080613d0456fea264697066735822122003025b9d185e84afdbe943189eb9229c0384b99f2a333fba3c99e7c0e6a9851a64736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x0000000000000000000000000000506172616d73": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b6104ac565b61001d5f3561008c565b80630ae9a1cb146100875780633705765414610082578063715018a61461007d5780638da5cb5b14610078578063b6c15add14610073578063ea01545d1461006e5763f2fde38b0361000e57610479565b610404565b61033e565b6102aa565b6101fb565b6101b2565b610112565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b60ff1690565b6100b3816100a4565b036100ba57565b5f80fd5b905035906100cb826100aa565b565b906020828203126100e6576100e3915f016100be565b90565b61009c565b151590565b6100f9906100eb565b9052565b9190610110905f602085019401906100f0565b565b346101425761013e61012d6101283660046100cd565b610550565b610135610092565b918291826100fd565b0390f35b610098565b5190565b60209181520190565b90825f9392825e0152565b601f801991011690565b6101886101916020936101969361017f81610147565b9384809361014b565b95869101610154565b61015f565b0190565b6101af9160208201915f818403910152610169565b90565b346101e2576101de6101cd6101c83660046100cd565b61069d565b6101d5610092565b9182918261019a565b0390f35b610098565b5f9103126101f157565b61009c565b5f0190565b346102295761020b3660046101e7565b610213610836565b61021b610092565b80610225816101f6565b0390f35b610098565b1c90565b60018060a01b031690565b61024d906008610252930261022e565b610232565b90565b90610260915461023d565b90565b61026e5f5f90610255565b90565b60018060a01b031690565b61028590610271565b90565b6102919061027c565b9052565b91906102a8905f60208501940190610288565b565b346102da576102ba3660046101e7565b6102d66102c5610263565b6102cd610092565b91829182610295565b0390f35b610098565b90565b90565b90565b6102fc6102f7610301926102df565b6102e5565b6102e2565b90565b61030e60646102e8565b90565b610319610304565b90565b610325906102e2565b9052565b919061033c905f6020850194019061031c565b565b3461036e5761034e3660046101e7565b61036a610359610311565b610361610092565b91829182610329565b0390f35b610098565b5f80fd5b5f80fd5b5f80fd5b909182601f830112156103b95781359167ffffffffffffffff83116103b45760200192600183028401116103af57565b61037b565b610377565b610373565b9190916040818403126103ff576103d7835f83016100be565b92602082013567ffffffffffffffff81116103fa576103f6920161037f565b9091565b6100a0565b61009c565b346104335761041d6104173660046103be565b91610bca565b610425610092565b8061042f816101f6565b0390f35b610098565b6104418161027c565b0361044857565b5f80fd5b9050359061045982610438565b565b9060208282031261047457610471915f0161044c565b90565b61009c565b346104a75761049161048c36600461045b565b610cb9565b610499610092565b806104a3816101f6565b0390f35b610098565b5f80fd5b5f90565b6104c86104c36104cd926100a4565b6102e5565b6100a4565b90565b906104da906104b4565b5f5260205260405f2090565b634e487b7160e01b5f52602260045260245ffd5b906001600283049216801561051a575b602083101461051557565b6104e6565b91607f169161050a565b61052e90546104fa565b90565b90565b61054861054361054d92610531565b6102e5565b6102e2565b90565b61056761056c9161055f6104b0565b5060016104d0565b610524565b61057e6105785f610534565b916102e2565b1190565b606090565b60209181520190565b5f5260205f2090565b905f92918054906105b36105ac836104fa565b8094610587565b916001811690815f1461060a57506001146105ce575b505050565b6105db9192939450610590565b915f925b8184106105f257505001905f80806105c9565b600181602092959395548486015201910192906105df565b92949550505060ff19168252151560200201905f80806105c9565b9061062f91610599565b90565b634e487b7160e01b5f52604160045260245ffd5b906106509061015f565b810190811067ffffffffffffffff82111761066a57604052565b610632565b9061068f6106889261067f610092565b93848092610625565b0383610646565b565b61069a9061066f565b90565b6106b46106b9916106ac610582565b5060016104d0565b610691565b90565b5f1c90565b6106cd6106d2916106bc565b610232565b90565b6106df90546106c1565b90565b336106fd6106f76106f25f6106d5565b61027c565b9161027c565b0361070c5761070a6107c7565b565b5f635fc483c560e01b815280610724600482016101f6565b0390fd5b61073c61073761074192610531565b6102e5565b610271565b90565b61074d90610728565b90565b5f1b90565b9061076660018060a01b0391610750565b9181191691161790565b61078461077f61078992610271565b6102e5565b610271565b90565b61079590610770565b90565b6107a19061078c565b90565b90565b906107bc6107b76107c392610798565b6107a4565b8254610755565b9055565b6107d05f6106d5565b6107e26107dc5f610744565b5f6107a7565b6107eb5f610744565b61081e6108187f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610798565b91610798565b91610827610092565b80610831816101f6565b0390a3565b61083e6106e2565b565b91903361085d6108576108525f6106d5565b61027c565b9161027c565b0361086d5761086b92610b18565b565b5f635fc483c560e01b815280610885600482016101f6565b0390fd5b5090565b9160206108ae9294936108a760408201965f83019061031c565b019061031c565b565b601f602091010490565b1b90565b919060086108d99102916108d35f19846108ba565b926108ba565b9181191691161790565b6108f76108f26108fc926102e2565b6102e5565b6102e2565b90565b90565b9190610918610913610920936108e3565b6108ff565b9083546108be565b9055565b5f90565b61093a91610934610924565b91610902565b565b5b818110610948575050565b806109555f600193610928565b0161093d565b9190601f811161096b575b505050565b61097761099c93610590565b906020610983846108b0565b830193106109a4575b610995906108b0565b019061093c565b5f8080610966565b91506109958192905061098c565b906109c2905f199060080261022e565b191690565b816109d1916109b2565b906002021790565b916109e49082610889565b9067ffffffffffffffff8211610aa357610a0882610a0285546104fa565b8561095b565b5f90601f8311600114610a3b57918091610a2a935f92610a2f575b50506109c7565b90555b565b90915001355f80610a23565b601f19831691610a4a85610590565b925f5b818110610a8b57509160029391856001969410610a71575b50505002019055610a2d565b610a81910135601f8416906109b2565b90555f8080610a65565b91936020600181928787013581550195019201610a4d565b610632565b90610ab392916109d9565b565b610abe906100a4565b9052565b90825f939282370152565b9190610ae781610ae081610aec9561014b565b8095610ac2565b61015f565b0190565b91610b15939192610b0860408201945f830190610ab5565b6020818503910152610acd565b90565b919091610b26838390610889565b610b3f610b39610b34610304565b6102e2565b916102e2565b11610b9957610b5b838390610b56600185906104d0565b610aa8565b919091610b947f660f700ec25321f4838828ca2284f96109a35e7b652e4511e8235bb7c2b9cc5193610b8b610092565b93849384610af0565b0390a1565b50610ba391610889565b610bab610304565b90610bc65f92839263a7075ceb60e01b84526004840161088d565b0390fd5b90610bd59291610840565b565b33610bf2610bec610be75f6106d5565b61027c565b9161027c565b03610c0257610c0090610c1e565b565b5f635fc483c560e01b815280610c1a600482016101f6565b0390fd5b80610c39610c33610c2e5f610744565b61027c565b9161027c565b14610c9d57610c475f6106d5565b610c51825f6107a7565b90610c85610c7f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e093610798565b91610798565b91610c8e610092565b80610c98816101f6565b0390a3565b5f63d92e233d60e01b815280610cb5600482016101f6565b0390fd5b610cc290610bd7565b56fea2646970667358221220441b2fc6b5144033f76820b0c8fa2708edeb583159e9e9b5ee6a07135997017f64736f6c637828302e382e33312d646576656c6f702e323032362e312e32332b636f6d6d69742e36373662646563630059", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0xd412c5ecd343e264381ff15afc0ad78a67b79f35" + } + }, + "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff4b064b81555f359062001fff015500", + "balance": "0x0" + }, + "0x00000000219ab540356cbb839cbe05303d7705fa": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b6103b4565b61001d5f3561005c565b806301ffc9a714610057578063621fd1301461005257806379f6caf51461004d5763c5f2892f0361000e5761037f565b610327565b610197565b6100e8565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b63ffffffff60e01b1690565b61008981610074565b0361009057565b5f80fd5b905035906100a182610080565b565b906020828203126100bc576100b9915f01610094565b90565b61006c565b151590565b6100cf906100c1565b9052565b91906100e6905f602085019401906100c6565b565b34610118576101146101036100fe3660046100a3565b6103bc565b61010b610062565b918291826100d3565b0390f35b610068565b5f91031261012757565b61006c565b5190565b60209181520190565b90825f9392825e0152565b601f801991011690565b61016d61017660209361017b936101648161012c565b93848093610130565b95869101610139565b610144565b0190565b6101949160208201915f81840391015261014e565b90565b346101c7576101a736600461011d565b6101c36101b261046b565b6101ba610062565b9182918261017f565b0390f35b610068565b5f80fd5b5f80fd5b5f80fd5b909182601f830112156102125781359167ffffffffffffffff831161020d57602001926001830284011161020857565b6101d4565b6101d0565b6101cc565b90565b61022381610217565b0361022a57565b5f80fd5b9050359061023b8261021a565b565b9160c08383031261031d575f83013567ffffffffffffffff811161031857826102679185016101d8565b929093602081013567ffffffffffffffff8111610313578261028a9183016101d8565b929093604083013567ffffffffffffffff811161030e57826102ad9185016101d8565b929093606081013567ffffffffffffffff811161030957826102d09183016101d8565b929093608083013567ffffffffffffffff8111610304576102f6836103019286016101d8565b93909460a00161022e565b90565b610070565b610070565b610070565b610070565b610070565b61006c565b5f0190565b61034761033536600461023d565b99989098979197969296959395611440565b61034f610062565b8061035981610322565b0390f35b61036690610217565b9052565b919061037d905f6020850194019061035d565b565b346103af5761038f36600461011d565b6103ab61039a611c35565b6103a2610062565b9182918261036a565b0390f35b610068565b5f80fd5b5f90565b6103c46103b8565b50806103df6103d96301ffc9a760e01b610074565b91610074565b149081156103ec575b5090565b9050610407610401636f0dc97560e11b610074565b91610074565b145f6103e8565b606090565b5f1c90565b90565b61042761042c91610413565b610418565b90565b610439905461041b565b90565b90565b67ffffffffffffffff1690565b90565b61046361045e6104689261043c565b61044c565b61043f565b90565b61047361040e565b5061048e610489610484602061042f565b61044f565b611fb9565b90565b5090565b90565b6104ac6104a76104b192610495565b61044c565b61043c565b90565b60209181520190565b60207f626b6579206c656e677468000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c6964206e6f64655f70755f8201520152565b610517602b6040926104b4565b610520816104bd565b0190565b6105399060208101905f81830391015261050a565b90565b1561054357565b61054b610062565b62461bcd60e51b81528061056160048201610524565b0390fd5b90565b61057c61057761058192610565565b61044c565b61043c565b90565b60207f75735f7075626b6579206c656e67746800000000000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420636f6e73656e735f8201520152565b6105de60306040926104b4565b6105e781610584565b0190565b6106009060208101905f8183039101526105d1565b90565b1561060a57565b610612610062565b62461bcd60e51b815280610628600482016105eb565b0390fd5b60207f77616c5f63726564656e7469616c73206c656e67746800000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420776974686472615f8201520152565b61068660366040926104b4565b61068f8161062c565b0190565b6106a89060208101905f818303910152610679565b90565b156106b257565b6106ba610062565b62461bcd60e51b8152806106d060048201610693565b0390fd5b90565b6106eb6106e66106f0926106d4565b61044c565b61043c565b90565b60207f676e6174757265206c656e677468000000000000000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c6964206e6f64655f73695f8201520152565b61074d602e6040926104b4565b610756816106f3565b0190565b61076f9060208101905f818303910152610740565b90565b1561077957565b610781610062565b62461bcd60e51b8152806107976004820161075a565b0390fd5b90565b6107b26107ad6107b79261079b565b61044c565b61043c565b90565b60207f75735f7369676e6174757265206c656e67746800000000000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420636f6e73656e735f8201520152565b61081460336040926104b4565b61081d816107ba565b0190565b6108369060208101905f818303910152610807565b90565b1561084057565b610848610062565b62461bcd60e51b81528061085e60048201610821565b0390fd5b634e487b7160e01b5f52603260045260245ffd5b9190811015610886576001020190565b610862565b90565b6108a261089d6108a79261088b565b61044c565b61043c565b90565b60ff60f81b1690565b90565b60f81b90565b6108d06108cb6108d5926108b3565b6108b6565b6108aa565b90565b60207f77616c5f63726564656e7469616c732070726566697800000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420776974686472615f8201520152565b61093260366040926104b4565b61093b816108d8565b0190565b6109549060208101905f818303910152610925565b90565b1561095e57565b610966610062565b62461bcd60e51b81528061097c6004820161093f565b0390fd5b61099461098f610999926108b3565b61044c565b61043c565b90565b90565b6109b36109ae6109b89261099c565b61044c565b61043c565b90565b5f80fd5b5f80fd5b909392938483116109e35784116109de576001820201920390565b6109bf565b6109bb565b6affffffffffffffffffffff60a81b1690565b1b90565b90610a0d610a149183610491565b91356109e8565b90600b8110610a22575b5090565b610a41906affffffffffffffffffffff60a81b90600b036008026109fb565b165f610a1e565b60a81b90565b610a62610a5d610a679261088b565b610a48565b6109e8565b90565b60207f77616c5f63726564656e7469616c732070616464696e67000000000000000000917f4465706f736974436f6e74726163743a20696e76616c696420776974686472615f8201520152565b610ac460376040926104b4565b610acd81610a6a565b0190565b610ae69060208101905f818303910152610ab7565b90565b15610af057565b610af8610062565b62461bcd60e51b815280610b0e60048201610ad1565b0390fd5b90565b610b29610b24610b2e92610b12565b61044c565b61043c565b90565b60207f6f6f206c6f770000000000000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a206465706f7369742076616c756520745f8201520152565b610b8b60266040926104b4565b610b9481610b31565b0190565b610bad9060208101905f818303910152610b7e565b90565b15610bb757565b610bbf610062565b62461bcd60e51b815280610bd560048201610b98565b0390fd5b90565b610bf0610beb610bf592610bd9565b61044c565b61043c565b90565b634e487b7160e01b5f52601260045260245ffd5b610c18610c1e9161043c565b9161043c565b908115610c29570690565b610bf8565b60207f6f74206d756c7469706c65206f66206777656900000000000000000000000000917f4465706f736974436f6e74726163743a206465706f7369742076616c7565206e5f8201520152565b610c8860336040926104b4565b610c9181610c2e565b0190565b610caa9060208101905f818303910152610c7b565b90565b15610cb457565b610cbc610062565b62461bcd60e51b815280610cd260048201610c95565b0390fd5b634e487b7160e01b5f52601160045260245ffd5b610cf6610cfc9161043c565b9161043c565b908115610d07570490565b610bf8565b610d20610d1b610d259261043f565b61044c565b61043c565b90565b60207f6f6f206869676800000000000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a206465706f7369742076616c756520745f8201520152565b610d8260276040926104b4565b610d8b81610d28565b0190565b610da49060208101905f818303910152610d75565b90565b15610dae57565b610db6610062565b62461bcd60e51b815280610dcc60048201610d8f565b0390fd5b90825f939282370152565b9190610df581610dee81610dfa95610130565b8095610dd0565b610144565b0190565b9a969194610e6d96610e428d610e899f9d9b9897610e5f97610e34610e7b9f9a97610e519860e08601918683035f880152610ddb565b926020818503910152610ddb565b918d6040818503910152610ddb565b908a820360608c015261014e565b9188830360808a0152610ddb565b9185830360a0870152610ddb565b9160c081840391015261014e565b90565b6fffffffffffffffffffffffffffffffff191690565b60801b90565b610ebc610eb7610ec19261088b565b610ea2565b610e8c565b90565b905090565b909182610ed981610ee093610ec4565b8093610dd0565b0190565b90565b610ef3610ef891610e8c565b610ee4565b9052565b610f0d9060109493610f1493610ec9565b8092610ee7565b0190565b634e487b7160e01b5f52604160045260245ffd5b90610f3690610144565b810190811067ffffffffffffffff821117610f5057604052565b610f18565b5f1b90565b610f7f610f7692602092610f6d8161012c565b94858093610ec4565b93849101610139565b0190565b610f8c91610f5a565b90565b610f97610062565b3d5f823e3d90fd5b90565b610fae610fb391610217565b610f9f565b9052565b610fc89060209493610fcf93610ec9565b8092610fa2565b0190565b9091610fde92610ec9565b90565b9091610fec92610ec9565b90565b611003610ffe6110089261088b565b610f55565b610217565b90565b61101c906020949361102393610ec9565b8092610fa2565b0190565b60208161103961104193839695610fa2565b018092610fa2565b0190565b8061105660209261105d9694610fa2565b0191610ec9565b90565b67ffffffffffffffff191690565b60401b90565b61108861108361108d9261088b565b61106e565b611060565b90565b90565b61109f6110a491611060565b611090565b9052565b602093926110c56110be6018936110cd95610f5a565b8092611093565b018092610fa2565b0190565b60407f6564206465706f7369745f646174615f726f6f74000000000000000000000000917f4465706f736974436f6e74726163743a207265636f6e737472756374656420445f8201527f65706f7369744461746120646f6573206e6f74206d6174636820737570706c6960208201520152565b61115160546060926104b4565b61115a816110d1565b0190565b6111739060208101905f818303910152611144565b90565b1561117d57565b611185610062565b62461bcd60e51b81528061119b6004820161115e565b0390fd5b6111a96020610498565b90565b90565b6111c36111be6111c8926111ac565b61044c565b61043c565b90565b6111d49061043c565b60ff81116111e25760020a90565b610cd6565b6111f66111fc9193929361043c565b9261043c565b820391821161120757565b610cd6565b61122f61121f61121a61119f565b6111cb565b6112296001610980565b906111e7565b90565b60207f6c00000000000000000000000000000000000000000000000000000000000000917f4465706f736974436f6e74726163743a206d65726b6c6520747265652066756c5f8201520152565b61128c60216040926104b4565b61129581611232565b0190565b6112ae9060208101905f81830391015261127f565b90565b156112b857565b6112c0610062565b62461bcd60e51b8152806112d660048201611299565b0390fd5b6112e96112ef9193929361043c565b9261043c565b82018092116112fa57565b610cd6565b9061130b5f1991610f55565b9181191691161790565b61132961132461132e9261043c565b61044c565b61043c565b90565b90565b9061134961134461135092611315565b611331565b82546112ff565b9055565b6001611360910161043c565b90565b50602090565b90565b61137581611363565b82101561138f57611387600191611369565b910201905f90565b610862565b919060086113af9102916113a95f19846109fb565b926109fb565b9181191691161790565b6113c290610217565b90565b6113ce90610413565b90565b91906113e76113e26113ef936113b9565b6113c5565b908354611394565b9055565b1c90565b90565b61140a90600861140f93026113f3565b6113f7565b90565b9061141d91546113fa565b90565b634e487b7160e01b5f52600160045260245ffd5b1561143b57565b611420565b9091989495979396929a999a818361145791610491565b602061146290610498565b9061146c9061043c565b146114769061053c565b898161148191610491565b603061148c90610568565b906114969061043c565b146114a090610603565b87876114ab91610491565b60206114b690610498565b906114c09061043c565b146114ca906106ab565b88846114d591610491565b60406114e0906106d7565b906114ea9061043c565b146114f490610772565b84866114ff91610491565b606061150a9061079e565b906115149061043c565b1461151e90610839565b87875f61152a9061088e565b9061153492610876565b3561153e906108aa565b6001611549906108bc565b90611553906108aa565b1461155d90610957565b87876001600c9061156d90610980565b906115779061099f565b91611581936109c3565b61158a916109ff565b5f61159490610a4e565b61159d906109e8565b906115a7906109e8565b146115b190610ae9565b34670de0b6b3a76400006115c490610b15565b906115ce9061043c565b10156115d990610bb0565b34633b9aca006115e890610bdc565b6115f191610c0c565b5f6115fb9061088e565b906116059061043c565b1461160f90610cad565b34633b9aca0061161e90610bdc565b61162791610cea565b8067ffffffffffffffff61163a90610d0c565b906116449061043c565b111561164f90610da7565b6116589061044f565b61166190611fb9565b99888a8c858b88928c8c8c89978b9995949091929394611681602061042f565b61168a9061044f565b61169390611fb9565b967f0cff1634a9a72df9d813ea7e3a3874a76086e081904ad3cf81e12e43f4d4c87a9b6116be610062565b9b8c9b6116cb9b8d610dfe565b0390a1905f6116d990610ea8565b916116e2610062565b92839260208401926116f393610efc565b6020820181038252036117069082610f2c565b61170e610062565b611719819282610f83565b03905a915f916002602094fa15611c03576117775f916117666020946117586117428651610f55565b93919361174d610062565b948593898501610fb7565b868201810382520382610f2c565b61176e610062565b91829182610f83565b039060025afa15611bfe575f6020916117908251610f55565b976117a561179c610062565b92839283610fd3565b039060025afa15611bf9576117ba5f51610f55565b9160205f6118136118026117dc86866040906117d687926106d7565b926109c3565b91906117f46117e9610062565b938492888401610fe1565b868201810382520382610f2c565b61180a610062565b91829182610f83565b039060025afa15611bf4575f6118896118786118496020946118358551610f55565b969061184160406106d7565b9080926109c3565b919061186a61185786610fef565b61185f610062565b94859389850161100b565b868201810382520382610f2c565b611880610062565b91829182610f83565b039060025afa15611bef575f6118de6020926118cd6118a88451610f55565b916118bf6118b4610062565b938492888401611027565b868201810382520382610f2c565b6118d5610062565b91829182610f83565b039060025afa15611bea575f6119336020926119226118fd8451610f55565b91611914611909610062565b938492888401611027565b868201810382520382610f2c565b61192a610062565b91829182610f83565b039060025afa15611be55761198b5f9161197a60209461196c6119568651610f55565b979193611961610062565b948593898501611045565b868201810382520382610f2c565b611982610062565b91829182610f83565b039060025afa15611be0575f6119ea6020926119d96119aa8451610f55565b956119cb6119b786611074565b936119c0610062565b9485938985016110a8565b868201810382520382610f2c565b6119e1610062565b91829182610f83565b039060025afa15611bdb575f611a3f602092611a2e611a098451610f55565b91611a20611a15610062565b938492888401611027565b868201810382520382610f2c565b611a36610062565b91829182610f83565b039060025afa15611bd657611a71611a575f51610f55565b92611a6b611a658592610217565b91610217565b14611176565b611a9d611a7e602061042f565b611a97611a91611a8c61120c565b61043c565b9161043c565b106112b1565b611ac3611abc611aad6001610980565b611ab7602061042f565b6112da565b6020611334565b611acd602061042f565b611ad65f61088e565b925b83611af2611aec611ae761119f565b61043c565b9161043c565b1015611bc75781611b036001610980565b16611b17611b116001610980565b9161043c565b14611bad575f611b6f602092611b5e611b3a611b34858a9061136c565b90611412565b611b50611b45610062565b938492888401611027565b868201810382520382610f2c565b611b66610062565b91829182610f83565b039060025afa15611ba857611ba1611b9b611b8a5f51610f55565b92611b9560026111af565b90610cea565b93611354565b9290611ad8565b610f8f565b611bc592939150611bbf90915f61136c565b906113d1565b565b50509050611bd45f611434565b565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b610f8f565b5f90565b60189392602082611c23611c2a94611c3196610fa2565b0190610f5a565b8092611093565b0190565b611c3d611c08565b50611c46611c08565b90611c51602061042f565b611c5a5f61088e565b925b83611c76611c70611c6b61119f565b61043c565b9161043c565b1015611dad575f60209183611c8b6001610980565b16611c9f611c996001610980565b9161043c565b148214611d3557611cf690611ce5611cc1611cbb858a9061136c565b90611412565b611cd7611ccc610062565b938492888401611027565b868201810382520382610f2c565b611ced610062565b91829182610f83565b039060025afa15611d3057611d29611d23611d115f51610f55565b925b611d1d60026111af565b90610cea565b93611354565b9290611c5c565b610f8f565b611d8790611d76611d51611d4b60218a9061136c565b90611412565b91611d68611d5d610062565b938492888401611027565b868201810382520382610f2c565b611d7e610062565b91829182610f83565b039060025afa15611da857611d29611d23611da25f51610f55565b92611d13565b610f8f565b60209293505f9150611e1490611e03611dd5611dd0611dcb8761042f565b61044f565b611fb9565b91611df5611de286611074565b611dea610062565b948593898501611c0c565b868201810382520382610f2c565b611e0b610062565b91829182610f83565b039060025afa15611e2c57611e295f51610f55565b90565b610f8f565b90565b611e48611e43611e4d92611e31565b61044c565b61043c565b90565b90611e63611e5c610062565b9283610f2c565b565b67ffffffffffffffff8111611e8357611e7f602091610144565b0190565b610f18565b90611e9a611e9583611e65565b611e50565b918252565b369037565b90611ec9611eb183611e88565b92602080611ebf8693611e65565b9201910390611e9f565b565b67ffffffffffffffff60c01b1690565b60c01b90565b611ef5611ef0611efa9261043f565b611edb565b611ecb565b90565b90565b611f14611f0f611f1992611efd565b61044c565b61043c565b90565b90611f268261012c565b811015611f3857600160209102010190565b610862565b90565b611f54611f4f611f5992611f3d565b61044c565b61043c565b90565b90565b611f73611f6e611f7892611f5c565b61044c565b61043c565b90565b90565b611f92611f8d611f9792611f7b565b61044c565b61043c565b90565b90565b611fb1611fac611fb692611f9a565b61044c565b61043c565b90565b90611fc261040e565b50611fde611fd8611fd36008611e34565b611ea4565b92611ee1565b80611fe96007611f00565b9060088210156121c057611ffd911a6108b6565b6120148461200e5f935f1a9361088e565b90611f1c565b53806120206006611f40565b9060088210156121bb57612034911a6108b6565b61204c846120466001935f1a93610980565b90611f1c565b53806120586005611f5f565b9060088210156121b65761206c911a6108b6565b6120848461207e6002935f1a936111af565b90611f1c565b53806120906004611f7e565b9060088210156121b1576120a4911a6108b6565b6120bc846120b66003935f1a93611f9d565b90611f1c565b53806120c86003611f9d565b9060088210156121ac576120dc911a6108b6565b6120f4846120ee6004935f1a93611f7e565b90611f1c565b538061210060026111af565b9060088210156121a757612114911a6108b6565b61212c846121266005935f1a93611f5f565b90611f1c565b53806121386001610980565b9060088210156121a25761214c911a6108b6565b6121648461215e6006935f1a93611f40565b90611f1c565b5361216e5f61088e565b90600882101561219d57612182911a6108b6565b61219a836121946007935f1a93611f00565b90611f1c565b53565b610862565b610862565b610862565b610862565b610862565b610862565b610862565b61086256fea264697066735822122088155372033ad8432d1e232fd8b99b2efa9bf3139204e1cfb792a24e11e419ed64736f6c637828302e382e33312d646576656c6f702e323032362e312e32332b636f6d6d69742e36373662646563630059" + }, + "0x00000961ef480eb55e80d19ad83579a64c007002": { + "balance": "0x0", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd" + }, + "0x1000000000000000000000000000000000000001": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b61071b565b61001d5f3561007c565b806344c0b2bf146100775780637a737c37146100725780638da5cb5b1461006d57806391fef11614610068578063a409c6f0146100635763b115ce0d0361000e576106e6565b610605565b61052d565b61042a565b610397565b61023b565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906100c49061009c565b810190811067ffffffffffffffff8211176100de57604052565b6100a6565b906100f66100ef610082565b92836100ba565b565b67ffffffffffffffff81116101165761011260209161009c565b0190565b6100a6565b90825f939282370152565b9092919261013b610136826100f8565b6100e3565b93818552602085019082840111610157576101559261011b565b565b610098565b9080601f8301121561017a5781602061017793359101610126565b90565b610094565b151590565b61018d8161017f565b0361019457565b5f80fd5b905035906101a582610184565b565b608081830312610231575f81013567ffffffffffffffff811161022c57826101d091830161015c565b92602082013567ffffffffffffffff811161022757836101f191840161015c565b9260408301359067ffffffffffffffff8211610222576102168161021f93860161015c565b93606001610198565b90565b610090565b610090565b610090565b61008c565b5f0190565b3461026d5761025761024e3660046101a7565b92919091610a62565b61025f610082565b8061026981610236565b0390f35b610088565b5f80fd5b5f80fd5b9190916080818403126103385761029160806100e3565b925f82013567ffffffffffffffff811161033357816102b191840161015c565b5f850152602082013567ffffffffffffffff811161032e57816102d591840161015c565b6020850152604082013567ffffffffffffffff811161032957816102fa91840161015c565b6040850152606082013567ffffffffffffffff81116103245761031d920161015c565b6060830152565b610276565b610276565b610276565b610276565b610272565b9060208282031261036d575f82013567ffffffffffffffff811161036857610365920161027a565b90565b610090565b61008c565b90565b61037e90610372565b9052565b9190610395905f60208501940190610375565b565b346103c7576103c36103b26103ad36600461033d565b610c35565b6103ba610082565b91829182610382565b0390f35b610088565b5f9103126103d657565b61008c565b60026001609c1b0190565b6103ee6103db565b90565b60018060a01b031690565b610405906103f1565b90565b610411906103fc565b9052565b9190610428905f60208501940190610408565b565b3461045a5761043a3660046103cc565b6104566104456103e6565b61044d610082565b91829182610415565b0390f35b610088565b9190916060818403126104f35761047660606100e3565b925f82013567ffffffffffffffff81116104ee578161049691840161015c565b5f850152602082013567ffffffffffffffff81116104e957816104ba91840161015c565b6020850152604082013567ffffffffffffffff81116104e4576104dd920161015c565b6040830152565b610276565b610276565b610276565b610272565b90602082820312610528575f82013567ffffffffffffffff811161052357610520920161045f565b90565b610090565b61008c565b3461055d576105596105486105433660046104f8565b610cdc565b610550610082565b91829182610382565b0390f35b610088565b916060838303126105de575f83013567ffffffffffffffff81116105d9578261058c91850161015c565b92602081013567ffffffffffffffff81116105d457836105ad91830161015c565b92604082013567ffffffffffffffff81116105cf576105cc920161015c565b90565b610090565b610090565b610090565b61008c565b6105ec9061017f565b9052565b9190610603905f602085019401906105e3565b565b346106365761063261062161061b366004610562565b91610d4f565b610629610082565b918291826105f0565b0390f35b610088565b61064481610372565b0361064b57565b5f80fd5b9050359061065c8261063b565b565b9060208282031261067757610674915f0161064f565b90565b61008c565b61068590610372565b90565b906106929061067c565b5f5260205260405f2090565b1c90565b60ff1690565b6106b89060086106bd930261069e565b6106a2565b90565b906106cb91546106a8565b90565b6106e3906106de5f915f92610688565b6106c0565b90565b34610716576107126107016106fc36600461065e565b6106ce565b610709610082565b918291826105f0565b0390f35b610088565b5f80fd5b60209181520190565b5f7f4f6e6c79206f776e65722063616e207365742073746174757300000000000000910152565b61075c601960209261071f565b61076581610728565b0190565b61077e9060208101905f81830391015261074f565b90565b1561078857565b610790610082565b62461bcd60e51b8152806107a660048201610769565b0390fd5b5190565b90565b90565b90565b6107cb6107c66107d0926107b1565b6107b4565b6107ae565b90565b5f7f496e76616c6964206d727464206c656e67746800000000000000000000000000910152565b610807601360209261071f565b610810816107d3565b0190565b6108299060208101905f8183039101526107fa565b90565b1561083357565b61083b610082565b62461bcd60e51b81528061085160048201610814565b0390fd5b5f7f496e76616c6964206d727365616d206c656e6774680000000000000000000000910152565b610889601560209261071f565b61089281610855565b0190565b6108ab9060208101905f81830391015261087c565b90565b156108b557565b6108bd610082565b62461bcd60e51b8152806108d360048201610896565b0390fd5b90565b6108ee6108e96108f3926108d7565b6107b4565b6107ae565b90565b5f7f496e76616c69642070637234206c656e67746800000000000000000000000000910152565b61092a601360209261071f565b610933816108f6565b0190565b61094c9060208101905f81830391015261091d565b90565b1561095657565b61095e610082565b62461bcd60e51b81528061097460048201610937565b0390fd5b61098260606100e3565b90565b52565b5f1b90565b9061099960ff91610988565b9181191691161790565b6109ac9061017f565b90565b90565b906109c76109c26109ce926109a3565b6109af565b825461098d565b9055565b60209181520190565b90825f9392825e0152565b610a05610a0e602093610a13936109fc816107aa565b938480936109d2565b958691016109db565b61009c565b0190565b949391610a6093610a4a610a5892610a3c60609560808b01908b82035f8d01526109e6565b9089820360208b01526109e6565b9087820360408901526109e6565b9401906105e3565b565b610b7990610a8933610a83610a7d610a786103db565b6103fc565b916103fc565b14610781565b610aae610a95826107aa565b610aa8610aa260306107b7565b916107ae565b1461082c565b610ad3610aba846107aa565b610acd610ac760306107b7565b916107ae565b146108ae565b610af8610adf856107aa565b610af2610aec60206108da565b916107ae565b1461094f565b610b43610b3382610b2e86610b258991610b1c610b13610978565b955f8701610985565b60208501610985565b60408301610985565b610cdc565b610b3e87915f610688565b6109b2565b9192937ffbd013ecb3bb070127bc1b1186c451c2a5778c62b56de1db228acce4c28038ea94610b70610082565b94859485610a17565b0390a1565b5f90565b60209181520190565b610baa610bb3602093610bb893610ba1816107aa565b93848093610b82565b958691016109db565b61009c565b0190565b610c14916060610c03610bf1610bdf608085015f8701518682035f880152610b8b565b60208601518582036020870152610b8b565b60408501518482036040860152610b8b565b920151906060818403910152610b8b565b90565b610c2c9160208201915f818403910152610bbc565b90565b60200190565b610c68610c5991610c44610b7e565b50610c4d610082565b92839160208301610c17565b602082018103825203826100ba565b610c7a610c74826107aa565b91610c2f565b2090565b610cc1916040610cb0610c9e606084015f8601518582035f870152610b8b565b60208501518482036020860152610b8b565b920151906040818403910152610b8b565b90565b610cd99160208201915f818403910152610c7e565b90565b610d0f610d0091610ceb610b7e565b50610cf4610082565b92839160208301610cc4565b602082018103825203826100ba565b610d21610d1b826107aa565b91610c2f565b2090565b5f90565b5f1c90565b610d3a610d3f91610d29565b6106a2565b90565b610d4c9054610d2e565b90565b610e0b91610e00610e1094610df7610e0594610d69610d25565b50610d8f610d76826107aa565b610d89610d8360306107b7565b916107ae565b1461082c565b610db4610d9b866107aa565b610dae610da860306107b7565b916107ae565b146108ae565b610dd9610dc0846107aa565b610dd3610dcd60206108da565b916107ae565b1461094f565b93610dee610de5610978565b955f8701610985565b60208501610985565b60408301610985565b610cdc565b5f610688565b610d42565b9056fea26469706673582212209c9e77189674da6a0061a74e49989970b3eebaadb84294b33acb051b808ab37164736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000002": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b6109af565b61001d5f356100ec565b806325c99ae4146100e757806334107282146100e257806338c0ac5f146100dd5780633eeb92f6146100d85780634456251b146100d357806346a67577146100ce578063894f449c146100c95780639386775a146100c45780639f2ce678146100bf578063a1695993146100ba578063a9fcfb33146100b5578063cc3c74a1146100b05763e28ba0340361000e57610978565b610943565b6108c2565b61085d565b6107f9565b610791565b610673565b6105ab565b610382565b6102de565b610286565b61022e565b6101a8565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f91031261010a57565b6100fc565b60018060a01b031690565b90565b61013161012c6101369261010f565b61011a565b61010f565b90565b6101429061011d565b90565b61014e90610139565b90565b610160600180609c1b01610145565b90565b61016b610151565b90565b6101779061011d565b90565b6101839061016e565b90565b61018f9061017a565b9052565b91906101a6905f60208501940190610186565b565b346101d8576101b8366004610100565b6101d46101c3610163565b6101cb6100f2565b91829182610193565b0390f35b6100f8565b73f39fd6e51aad88f6f4ce6ab8827279cfffb9226690565b6101fd6101dd565b90565b6102099061010f565b90565b61021590610200565b9052565b919061022c905f6020850194019061020c565b565b3461025e5761023e366004610100565b61025a6102496101f5565b6102516100f2565b91829182610219565b0390f35b6100f8565b7370997970c51812dc3a010c7d01b50e0d17dc79c890565b610283610263565b90565b346102b657610296366004610100565b6102b26102a161027b565b6102a96100f2565b91829182610219565b0390f35b6100f8565b733c44cdddb6a900fa2b585dd299e03d12fa4293bc90565b6102db6102bb565b90565b3461030e576102ee366004610100565b61030a6102f96102d3565b6103016100f2565b91829182610219565b0390f35b6100f8565b5f80fd5b90565b61032381610317565b0361032a57565b5f80fd5b9050359061033b8261031a565b565b9060208282031261035657610353915f0161032e565b90565b6100fc565b151590565b6103699061035b565b9052565b9190610380905f60208501940190610360565b565b346103b2576103ae61039d61039836600461033d565b610a4b565b6103a56100f2565b9182918261036d565b0390f35b6100f8565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906103e7906103bf565b810190811067ffffffffffffffff82111761040157604052565b6103c9565b906104196104126100f2565b92836103dd565b565b67ffffffffffffffff8111610439576104356020916103bf565b0190565b6103c9565b90825f939282370152565b9092919261045e6104598261041b565b610406565b9381855260208501908284011161047a576104789261043e565b565b6103bb565b9080601f8301121561049d5781602061049a93359101610449565b90565b6103b7565b6104ab8161035b565b036104b257565b5f80fd5b905035906104c3826104a2565b565b90565b6104d1816104c5565b036104d857565b5f80fd5b905035906104e9826104c8565b565b919060a083820312610584575f83013567ffffffffffffffff811161057f578161051691850161047f565b92602081013567ffffffffffffffff811161057a578261053791830161047f565b92604082013567ffffffffffffffff81116105755761055b8461057292850161047f565b9361056981606086016104b6565b936080016104dc565b90565b610313565b610313565b610313565b6100fc565b61059290610317565b9052565b91906105a9905f60208501940190610589565b565b346105df576105db6105ca6105c13660046104eb565b93929092610d6a565b6105d26100f2565b91829182610596565b0390f35b6100f8565b60808183031261066e575f81013567ffffffffffffffff8111610669578261060d91830161047f565b92602082013567ffffffffffffffff8111610664578361062e91840161047f565b9260408301359067ffffffffffffffff821161065f576106538161065c93860161047f565b936060016104b6565b90565b610313565b610313565b610313565b6100fc565b346106a7576106a36106926106893660046105e4565b929190916111fc565b61069a6100f2565b91829182610596565b0390f35b6100f8565b6106b581610200565b036106bc57565b5f80fd5b905035906106cd826106ac565b565b91906040838203126106f757806106eb6106f4925f860161032e565b936020016106c0565b90565b6100fc565b61070590610317565b90565b90610712906106fc565b5f5260205260405f2090565b6107279061016e565b90565b906107349061071e565b5f5260205260405f2090565b1c90565b60ff1690565b61075a90600861075f9302610740565b610744565b90565b9061076d915461074a565b90565b61078961078e926107846001935f94610708565b61072a565b610762565b90565b346107c2576107be6107ad6107a73660046106cf565b90610770565b6107b56100f2565b9182918261036d565b0390f35b6100f8565b91906040838203126107ef57806107e36107ec925f860161032e565b936020016104b6565b90565b6100fc565b5f0190565b346108285761081261080c3660046107c7565b90611469565b61081a6100f2565b80610824816107f4565b0390f35b6100f8565b610836906104c5565b9052565b91602061085b92949361085460408201965f83019061082d565b019061082d565b565b3461088e5761087561087036600461033d565b6115aa565b9061088a6108816100f2565b9283928361083a565b0390f35b6100f8565b9061089d906106fc565b5f5260205260405f2090565b6108bf906108ba6002915f92610893565b610762565b90565b346108f2576108ee6108dd6108d836600461033d565b6108a9565b6108e56100f2565b9182918261036d565b0390f35b6100f8565b90565b61090a90600861090f9302610740565b6108f7565b90565b9061091d91546108fa565b90565b61092b5f5f90610912565b90565b9190610941905f6020850194019061082d565b565b3461097357610953366004610100565b61096f61095e610920565b6109666100f2565b9182918261092e565b0390f35b6100f8565b346109aa5761099461098b3660046104eb565b93929092611772565b61099c6100f2565b806109a6816107f4565b0390f35b6100f8565b5f80fd5b5f90565b5f1c90565b6109c86109cd916109b7565b610744565b90565b6109da90546109bc565b90565b90565b6109f46109ef6109f9926109dd565b61011a565b6104c5565b90565b634e487b7160e01b5f52601160045260245ffd5b610a19906104c5565b5f198114610a275760010190565b6109fc565b90565b610a43610a3e610a4892610a2c565b61011a565b6104c5565b90565b610a536109b3565b50610a68610a6360028390610893565b6109d0565b610b4657610a755f6109e0565b90610a9b610a96610a8860018490610708565b610a906101dd565b9061072a565b6109d0565b610b36575b610ac5610ac0610ab260018490610708565b610aba610263565b9061072a565b6109d0565b610b19575b610ae9610adb610aee926001610708565b610ae36102bb565b9061072a565b6109d0565b610b0b575b610b06610b006002610a2f565b916104c5565b101590565b610b1490610a10565b610af3565b90610ae9610adb610b2c610aee93610a10565b9392505050610aca565b90610b4090610a10565b90610aa0565b505f90565b5f90565b610b596060610406565b90565b52565b5f80fd5b60e01b90565b90505190610b768261031a565b565b90602082820312610b9157610b8e915f01610b69565b90565b6100fc565b5190565b60209181520190565b90825f9392825e0152565b610bcd610bd6602093610bdb93610bc481610b96565b93848093610b9a565b95869101610ba3565b6103bf565b0190565b610c22916040610c11610bff606084015f8601518582035f870152610bae565b60208501518482036020860152610bae565b920151906040818403910152610bae565b90565b610c3a9160208201915f818403910152610bdf565b90565b610c456100f2565b3d5f823e3d90fd5b60209181520190565b60207f6564000000000000000000000000000000000000000000000000000000000000917f757067726164654f70657261746f722e636f6d7075746549645631206661696c5f8201520152565b610cb06022604092610c4d565b610cb981610c56565b0190565b610cd29060208101905f818303910152610ca3565b90565b90565b610ce4610ce991610317565b610cd5565b9052565b60f81b90565b610cfc90610ced565b90565b610d0890610cf3565b90565b610d17610d1c9161035b565b610cff565b9052565b90565b610d2f610d34916104c5565b610d20565b9052565b60209392610d588583610d50600195610d6097610cd8565b018092610d0b565b018092610d23565b0190565b60200190565b91610d9a610da39293610d7b610b4b565b5093610d91610d88610b4f565b955f8701610b5c565b60208501610b5c565b60408301610b5c565b90610de96020610db1610b4b565b93610dc2610dbd610151565b61017a565b610dde6391fef116610dd26100f2565b95869485938493610b63565b835260048301610c25565b03915afa80915f92610e78575b50155f14610e6a57506001610e4857610e23610e32925b9193610e176100f2565b94859360208501610d38565b602082018103825203826103dd565b610e44610e3e82610b96565b91610d64565b2090565b610e506100f2565b62461bcd60e51b815280610e6660048201610cbd565b0390fd5b610e329250610e2390610e0d565b610e9a91925060203d8111610ea1575b610e9281836103dd565b810190610b78565b905f610df6565b503d610e88565b90565b610ebf610eba610ec492610ea8565b61011a565b6104c5565b90565b5f7f496e76616c6964206d727464206c656e67746800000000000000000000000000910152565b610efb6013602092610c4d565b610f0481610ec7565b0190565b610f1d9060208101905f818303910152610eee565b90565b15610f2757565b610f2f6100f2565b62461bcd60e51b815280610f4560048201610f08565b0390fd5b5f7f496e76616c6964206d727365616d206c656e6774680000000000000000000000910152565b610f7d6015602092610c4d565b610f8681610f49565b0190565b610f9f9060208101905f818303910152610f70565b90565b15610fa957565b610fb16100f2565b62461bcd60e51b815280610fc760048201610f8a565b0390fd5b90565b610fe2610fdd610fe792610fcb565b61011a565b6104c5565b90565b5f7f496e76616c69642070637234206c656e67746800000000000000000000000000910152565b61101e6013602092610c4d565b61102781610fea565b0190565b6110409060208101905f818303910152611011565b90565b1561104a57565b6110526100f2565b62461bcd60e51b8152806110686004820161102b565b0390fd5b61107861107d916109b7565b6108f7565b90565b61108a905461106c565b90565b5f1b90565b9061109e5f199161108d565b9181191691161790565b6110bc6110b76110c1926104c5565b61011a565b6104c5565b90565b90565b906110dc6110d76110e3926110a8565b6110c4565b8254611092565b9055565b5f7f50726f706f73616c20616c726561647920657865637574656400000000000000910152565b61111b6019602092610c4d565b611124816110e7565b0190565b61113d9060208101905f81830391015261110e565b90565b1561114757565b61114f6100f2565b62461bcd60e51b81528061116560048201611128565b0390fd5b60209181520190565b61119161119a60209361119f9361118881610b96565b93848093611169565b95869101610ba3565b6103bf565b0190565b959492936111e46111fa956111d6896080966111c96111f2975f60a0850194019061082d565b8b820360208d0152611172565b9089820360408b0152611172565b908782036060890152611172565b940190610360565b565b9290611206610b4b565b5061122c61121385610b96565b6112266112206030610eab565b916104c5565b14610f20565b61125161123882610b96565b61124b6112456030610eab565b916104c5565b14610fa2565b61127661125d84610b96565b61127061126a6020610fce565b916104c5565b14611043565b61129061128a6112855f611080565b610a10565b5f6110c7565b6112a784828585916112a15f611080565b93610d6a565b936112cd6112c86112c26112bd60028990610893565b6109d0565b1561035b565b611140565b61131a85936112db5f611080565b9293956113087fc608a3fb719bb3f084c89497286b28154f3baeaf8b21efd34fafa4bab23daf0c966106fc565b966113116100f2565b958695866111a3565b0390a290565b5f7f4e6f7420617574686f72697a656420746f20766f746500000000000000000000910152565b6113546016602092610c4d565b61135d81611320565b0190565b6113769060208101905f818303910152611347565b90565b1561138057565b6113886100f2565b62461bcd60e51b81528061139e60048201611361565b0390fd5b5f7f416c726561647920766f74656400000000000000000000000000000000000000910152565b6113d6600d602092610c4d565b6113df816113a2565b0190565b6113f89060208101905f8183039101526113c9565b90565b1561140257565b61140a6100f2565b62461bcd60e51b815280611420600482016113e3565b0390fd5b9061143060ff9161108d565b9181191691161790565b6114439061035b565b90565b90565b9061145e6114596114659261143a565b611446565b8254611424565b9055565b3361148361147d6114786101dd565b610200565b91610200565b148015611585575b801561155f575b61149b90611379565b6114c06114bb6114b56114b060028590610893565b6109d0565b1561035b565b611140565b6114ef6114ea6114e46114df6114d860018690610708565b339061072a565b6109d0565b1561035b565b6113fb565b61150e8261150961150260018590610708565b339061072a565b611449565b9033909161155a6115486115427f8b40665146691327ee30f5bf56e9b2d6f445d2830d3b09b56385cd30f630ecfb936106fc565b9361071e565b936115516100f2565b9182918261036d565b0390a3565b5061149b3361157d6115776115726102bb565b610200565b91610200565b149050611492565b50336115a061159a611595610263565b610200565b91610200565b1461148b565b5f90565b906115b36115a6565b6115bb6115a6565b926115e16115dc6115ce60018490610708565b6115d66101dd565b9061072a565b6109d0565b61167c575b61160b6116066115f860018490610708565b611600610263565b9061072a565b6109d0565b611655575b61162f611621611634926001610708565b6116296102bb565b9061072a565b6109d0565b61163d575b9190565b61164961164f91610a10565b92610a10565b91611639565b929061162f61162161167261166c61163494610a10565b94610a10565b9592505050611610565b929061168a61169091610a10565b91610a10565b926115e6565b5f7f496e73756666696369656e7420766f7465730000000000000000000000000000910152565b6116ca6012602092610c4d565b6116d381611696565b0190565b6116ec9060208101905f8183039101526116bd565b90565b156116f657565b6116fe6100f2565b62461bcd60e51b815280611714600482016116d7565b0390fd5b5f91031261172257565b6100fc565b9493916117709361175a6117689261174c60609560808b01908b82035f8d0152611172565b9089820360208b0152611172565b908782036040890152611172565b940190610360565b565b919293611786908390838690889293610d6a565b936117ac6117a76117a161179c60028990610893565b6109d0565b1561035b565b611140565b6118506117b85f6109e0565b6117dd6117d86117ca60018a90610708565b6117d26101dd565b9061072a565b6109d0565b611955575b6118076118026117f460018a90610708565b6117fc610263565b9061072a565b6109d0565b611947575b61183161182c61181e60018a90610708565b6118266102bb565b9061072a565b6109d0565b611939575b6118496118436002610a2f565b916104c5565b10156116ef565b611866600161186160028890610893565b611449565b611876611871610151565b61017a565b906344c0b2bf93929490823b15611934575f946118b186926118a69461189a6100f2565b998a9889978896610b63565b865260048601611727565b03925af1801561192f57611903575b506118eb7f7b1bcf1ccf901a11589afff5504d59fd0a53780eed2a952adade0348985139e0916106fc565b906118f46100f2565b806118fe816107f4565b0390a2565b611922905f3d8111611928575b61191a81836103dd565b810190611718565b5f6118c0565b503d611910565b610c3d565b610b5f565b61194290610a10565b611836565b61195090610a10565b61180c565b61195e90610a10565b6117e256fea26469706673582212202d96e5873e9f4e8c9465739f2343b8fa8881d1850ca80037522a66301dbd4bff64736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000003": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b61049a565b61001d5f3561006c565b8063415028a914610067578063727c346d14610062578063ad28a8161461005d578063baefa307146100585763e8d6c79a0361000e5761046e565b6103db565b61036d565b6102ff565b610245565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906100b090610088565b810190811067ffffffffffffffff8211176100ca57604052565b610092565b906100e26100db610072565b92836100a6565b565b67ffffffffffffffff8111610102576100fe602091610088565b0190565b610092565b90825f939282370152565b90929192610127610122826100e4565b6100cf565b938185526020850190828401116101435761014192610107565b565b610084565b9080601f830112156101665781602061016393359101610112565b90565b610080565b6bffffffffffffffffffffffff1690565b6101858161016b565b0361018c57565b5f80fd5b9050359061019d8261017c565b565b91906040838203126101df575f8301359067ffffffffffffffff82116101da576101ce816101d7938601610148565b93602001610190565b90565b61007c565b610078565b5190565b60209181520190565b90825f9392825e0152565b61021b61022460209361022993610212816101e4565b938480936101e8565b958691016101f1565b610088565b0190565b6102429160208201915f8184039101526101fc565b90565b61026d61025c61025636600461019f565b90610513565b610264610072565b9182918261022d565b0390f35b5f91031261027b57565b610078565b90565b60018060a01b031690565b90565b6102a56102a06102aa92610280565b61028e565b610283565b90565b6102b690610291565b90565b6102c360686102ad565b90565b6102ce6102b9565b90565b6102da90610283565b90565b6102e6906102d1565b9052565b91906102fd905f602085019401906102dd565b565b61030a366004610271565b6103266103156102c6565b61031d610072565b918291826102ea565b0390f35b90565b61034161033c6103469261032a565b61028e565b610283565b90565b6103529061032d565b90565b61035f6067610349565b90565b61036a610355565b90565b610378366004610271565b610394610383610362565b61038b610072565b918291826102ea565b0390f35b90565b6103af6103aa6103b492610398565b61028e565b610283565b90565b6103c09061039b565b90565b6103cd60666103b7565b90565b6103d86103c3565b90565b6103e6366004610271565b6104026103f16103d0565b6103f9610072565b918291826102ea565b0390f35b90602082820312610436575f82013567ffffffffffffffff81116104315761042e9201610148565b90565b61007c565b610078565b6104449061016b565b9052565b9291602061046461046c9360408701908782035f8901526101fc565b94019061043b565b565b61048161047c366004610406565b610739565b9061049661048d610072565b92839283610448565b0390f35b5f80fd5b606090565b905090565b6104cd6104c4926020926104bb816101e4565b948580936104a3565b938491016101f1565b0190565b60a01b90565b6104e0906104d1565b90565b6104ef6104f49161016b565b6104d7565b9052565b61050861050f91600c94936104a8565b80926104e3565b0190565b6105469061051f61049e565b5061053761052b610072565b938492602084016104f8565b602082018103825203826100a6565b90565b5f90565b90565b90565b61056761056261056c9261054d565b61028e565b610550565b90565b634e487b7160e01b5f52601160045260245ffd5b61059261059891939293610550565b92610550565b82039182116105a357565b61056f565b906105ba6105b5836100e4565b6100cf565b918252565b369037565b906105e96105d1836105a8565b926020806105df86936100e4565b92019103906105bf565b565b90565b6106026105fd610607926105eb565b61028e565b610550565b90565b60016106169101610550565b90565b634e487b7160e01b5f52603260045260245ffd5b90610637826101e4565b81101561064957600160209102010190565b610619565b60ff60f81b1690565b610661905161064e565b90565b61067361067991939293610550565b92610550565b820180921161068457565b61056f565b60200190565b6bffffffffffffffffffffffff60a01b1690565b6106ad905161068f565b90565b1b90565b6106ce6106c96106c3836101e4565b92610689565b6106a3565b90600c81106106dc575b5090565b6106fc906bffffffffffffffffffffffff60a01b90600c036008026106b0565b165f6106d8565b60a01c90565b61071d6107186107229261016b565b61028e565b61016b565b90565b61073161073691610703565b610709565b90565b9061074261049e565b5061074b610549565b50610768610758836101e4565b610762600c610553565b90610583565b610771816105c4565b9061077b5f6105ee565b5b8061078f61078984610550565b91610550565b10156107c6576107c1906107ac6107a787839061062d565b610657565b6107bb859183905f1a9261062d565b5361060a565b61077c565b50926107da6107d5600c610553565b6105c4565b916107e45f6105ee565b5b806107f96107f3600c610553565b91610550565b101561083a576108359061082061081b856108158a8590610664565b9061062d565b610657565b61082f869183905f1a9261062d565b5361060a565b6107e5565b5093505061084a61084f916106b4565b610725565b9056fea2646970667358221220f9203a71c0b6a6da16bf7b2698301c72ec306733882bb85b4d6d1038767c731464736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000004": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b610694565b61001d5f356100ac565b8063210ca7be146100a7578063415028a9146100a257806370df09331461009d57806382678dd6146100985780638b2f9fd114610093578063affed0e01461008e578063b7f5f9b714610089578063e8d6c79a146100845763eefbaf180361000e5761065f565b610604565b6105a8565b61052e565b61048d565b6103d9565b610372565b6102f3565b610245565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906100f4906100cc565b810190811067ffffffffffffffff82111761010e57604052565b6100d6565b9061012661011f6100b2565b92836100ea565b565b67ffffffffffffffff8111610146576101426020916100cc565b0190565b6100d6565b90825f939282370152565b9092919261016b61016682610128565b610113565b93818552602085019082840111610187576101859261014b565b565b6100c8565b9080601f830112156101aa578160206101a793359101610156565b90565b6100c4565b906020828203126101df575f82013567ffffffffffffffff81116101da576101d7920161018c565b90565b6100c0565b6100bc565b5190565b60209181520190565b90825f9392825e0152565b61021b61022460209361022993610212816101e4565b938480936101e8565b958691016101f1565b6100cc565b0190565b6102429160208201915f8184039101526101fc565b90565b346102755761027161026061025b3660046101af565b610713565b6102686100b2565b9182918261022d565b0390f35b6100b8565b6bffffffffffffffffffffffff1690565b6102948161027a565b0361029b57565b5f80fd5b905035906102ac8261028b565b565b91906040838203126102ee575f8301359067ffffffffffffffff82116102e9576102dd816102e693860161018c565b9360200161029f565b90565b6100c0565b6100bc565b346103245761032061030f6103093660046102ae565b906107b7565b6103176100b2565b9182918261022d565b0390f35b6100b8565b90565b61033581610329565b0361033c57565b5f80fd5b9050359061034d8261032c565b565b9060208282031261036857610365915f01610340565b90565b6100bc565b5f0190565b346103a05761038a61038536600461034f565b610847565b6103926100b2565b8061039c8161036d565b0390f35b6100b8565b5f9103126103af57565b6100bc565b90565b6103c0906103b4565b9052565b91906103d7905f602085019401906103b7565b565b34610409576103e93660046103a5565b6104056103f46108be565b6103fc6100b2565b918291826103c4565b0390f35b6100b8565b60018060a01b031690565b6104229061040e565b90565b61042e81610419565b0361043557565b5f80fd5b9050359061044682610425565b565b906020828203126104615761045e915f01610439565b90565b6100bc565b151590565b61047490610466565b9052565b919061048b905f6020850194019061046b565b565b346104bd576104b96104a86104a3366004610448565b610908565b6104b06100b2565b91829182610478565b0390f35b6100b8565b1c90565b6bffffffffffffffffffffffff1690565b6104e79060086104ec93026104c2565b6104c6565b90565b906104fa91546104d7565b90565b61050960015f906104ef565b90565b6105159061027a565b9052565b919061052c905f6020850194019061050c565b565b3461055e5761053e3660046103a5565b61055a6105496104fd565b6105516100b2565b91829182610519565b0390f35b6100b8565b9190916040818403126105a35761057c835f8301610439565b92602082013567ffffffffffffffff811161059e5761059b920161018c565b90565b6100c0565b6100bc565b346105d9576105d56105c46105be366004610563565b906109fe565b6105cc6100b2565b9182918261022d565b0390f35b6100b8565b929160206105fa6106029360408701908782035f8901526101fc565b94019061050c565b565b346106355761061c6106173660046101af565b610c1b565b906106316106286100b2565b928392836105de565b0390f35b6100b8565b90565b6106469061063a565b9052565b919061065d905f6020850194019061063d565b565b3461068f5761068b61067a610675366004610448565b610d60565b6106826100b2565b9182918261064a565b0390f35b6100b8565b5f80fd5b606090565b90565b6106b46106af6106b99261040e565b61069d565b61040e565b90565b6106c5906106a0565b90565b6106d1906106bc565b90565b906106de906106c8565b5f5260205260405f2090565b5f1c90565b90565b6106fe610703916106ea565b6106ef565b90565b61071090b06106f2565b90565b61072861074491610722610698565b50610c1b565b9061073c6107375f33906106d4565b610706565b919091610e44565b90565b905090565b6107716107689260209261075f816101e4565b94858093610747565b938491016101f1565b0190565b60a01b90565b61078490610775565b90565b6107936107989161027a565b61077b565b9052565b6107ac6107b391600c949361074c565b8092610787565b0190565b6107ea906107c3610698565b506107db6107cf6100b2565b9384926020840161079c565b602082018103825203826100ea565b90565b5f1b90565b906107fe5f19916107ed565b9181191691161790565b61081c61081761082192610329565b61069d565b610329565b90565b90565b9061083c61083761084392610808565b610824565b82b06107f2565b90b1565b61085b906108565f33906106d4565b610827565b336108867fe09b54ab39b458cc6e350a9444815a294301d94eaa79ba68d8a2f9f9c7c0b4cc916106c8565b9061088f6100b2565b806108998161036d565b0390a2565b5f90565b6108b66108b16108bb92610329565b61069d565b6103b4565b90565b6108c661089e565b506108e26108dd6108d85f33906106d4565b610706565b6108a2565b90565b5f90565b90565b6109006108fb610905926108e9565b61069d565b610329565b90565b61091e610923916109176108e5565b505f6106d4565b610706565b61093d6109376109325f6108ec565b610329565b91610329565b141590565b61094e610953916106ea565b6104c6565b90565b6109609054610942565b90565b634e487b7160e01b5f52601160045260245ffd5b6109809061027a565b6bffffffffffffffffffffffff81146109995760010190565b610963565b906109b56bffffffffffffffffffffffff916107ed565b9181191691161790565b6109d36109ce6109d89261027a565b61069d565b61027a565b90565b90565b906109f36109ee6109fa926109bf565b6109db565b825461099e565b9055565b610a4291610a20610a1b610a3293610a14610698565b505f6106d4565b610706565b90610a2b6001610956565b9091610efd565b610a3c6001610956565b906107b7565b610a5e610a57610a526001610956565b610977565b60016109de565b90565b5f90565b90565b610a7c610a77610a8192610a65565b61069d565b6103b4565b90565b610a93610a99919392936103b4565b926103b4565b8203918211610aa457565b610963565b90610abb610ab683610128565b610113565b918252565b369037565b90610aea610ad283610aa9565b92602080610ae08693610128565b9201910390610ac0565b565b610b00610afb610b05926108e9565b61069d565b6103b4565b90565b6001610b1491016103b4565b90565b634e487b7160e01b5f52603260045260245ffd5b90610b35826101e4565b811015610b4757600160209102010190565b610b17565b60ff60f81b1690565b610b5f9051610b4c565b90565b610b71610b77919392936103b4565b926103b4565b8201809211610b8257565b610963565b60200190565b6bffffffffffffffffffffffff60a01b1690565b610bab9051610b8d565b90565b1b90565b610bcc610bc7610bc1836101e4565b92610b87565b610ba1565b90600c8110610bda575b5090565b610bfa906bffffffffffffffffffffffff60a01b90600c03600802610bae565b165f610bd6565b60a01c90565b610c13610c1891610c01565b6109bf565b90565b90610c24610698565b50610c2d610a61565b50610c4a610c3a836101e4565b610c44600c610a68565b90610a84565b610c5381610ac5565b90610c5d5f610aec565b5b80610c71610c6b846103b4565b916103b4565b1015610ca857610ca390610c8e610c89878390610b2b565b610b55565b610c9d859183905f1a92610b2b565b53610b08565b610c5e565b5092610cbc610cb7600c610a68565b610ac5565b91610cc65f610aec565b5b80610cdb610cd5600c610a68565b916103b4565b1015610d1c57610d1790610d02610cfd85610cf78a8590610b62565b90610b2b565b610b55565b610d11869183905f1a92610b2b565b53610b08565b610cc7565b50935050610d2c610d3191610bb2565b610c07565b90565b5f90565b90565b610d47610d4c91610329565b610d38565b9052565b610d5c81602093610d3b565b0190565b610da4610d81610d7c610d9593610d75610d34565b505f6106d4565b610706565b610d896100b2565b92839160208301610d50565b602082018103825203826100ea565b610db6610db0826101e4565b91610b87565b2090565b91610dd9602084610dd1610de09796600c96610d3b565b018092610787565b019061074c565b90565b90565b610dfa610df5610dff92610de3565b61069d565b61040e565b90565b610e0b90610de6565b90565b610e186067610e02565b90565b3d5f14610e3657610e2b3d610aa9565b903d5f602084013e5b565b610e3e610698565b90610e34565b91610e7e5f9392610e6f8594610e58610698565b509193610e636100b2565b94859360208501610dba565b602082018103825203826100ea565b610e86610e0e565b90602081019051915afa610ea2610e9b610e1b565b9115610466565b610ea95790565b5f63a99eec4b60e01b815280610ec16004820161036d565b0390fd5b90565b610edc610ed7610ee192610ec5565b61069d565b61040e565b90565b610eed90610ec8565b90565b610efa6066610ee4565b90565b91610f375f9392610f288594610f11610698565b509193610f1c6100b2565b94859360208501610dba565b602082018103825203826100ea565b610f3f610ef0565b90602081019051915afa610f5b610f54610e1b565b9115610466565b610f625790565b5f63a99eec4b60e01b815280610f7a6004820161036d565b0390fdfea2646970667358221220d49235db1fc2813aca0c2c613fb2406a25c06fae48bbc6f76adb97907c3ca3e164736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000005": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b610800565b61001d5f356100bc565b806346e2577a146100b75780634a8fcf9a146100b257806350f3fc81146100ad5780638a355a57146100a85780638da5cb5b146100a3578063a36250d81461009e578063ba1ab29114610099578063c41c2f2414610094578063ed03b3001461008f5763f2fde38b0361000e576107cd565b610798565b610741565b61067d565b610632565b6105da565b61058a565b610555565b61040f565b610131565b60e01c90565b60405190565b5f80fd5b5f80fd5b5f80fd5b60018060a01b031690565b6100e8906100d4565b90565b6100f4816100df565b036100fb57565b5f80fd5b9050359061010c826100eb565b565b9060208282031261012757610124915f016100ff565b90565b6100cc565b5f0190565b3461015f5761014961014436600461010e565b610b62565b6101516100c2565b8061015b8161012c565b0390f35b6100c8565b5f80fd5b5f80fd5b601f801991011690565b634e487b7160e01b5f52604160045260245ffd5b906101949061016c565b810190811067ffffffffffffffff8211176101ae57604052565b610176565b906101c66101bf6100c2565b928361018a565b565b67ffffffffffffffff81116101e6576101e260209161016c565b0190565b610176565b90825f939282370152565b9092919261020b610206826101c8565b6101b3565b9381855260208501908284011161022757610225926101eb565b565b610168565b9080601f8301121561024a57816020610247933591016101f6565b90565b610164565b9060208282031261027f575f82013567ffffffffffffffff811161027a57610277920161022c565b90565b6100d0565b6100cc565b5190565b60209181520190565b60200190565b90565b6102a390610297565b9052565b906102b48160209361029a565b0190565b60200190565b906102db6102d56102ce84610284565b8093610288565b92610291565b905f5b8181106102eb5750505090565b9091926103046102fe60019286516102a7565b946102b8565b91019190916102de565b5190565b60209181520190565b60200190565b5190565b60209181520190565b90825f9392825e0152565b6103586103616020936103669361034f81610321565b93848093610325565b9586910161032e565b61016c565b0190565b9061037491610339565b90565b60200190565b9061039161038a8361030e565b8092610312565b90816103a26020830284019461031b565b925f915b8383106103b557505050505090565b909192939460206103d76103d18385600195038752895161036a565b97610377565b93019301919392906103a6565b90916103fe61040c9360408401908482035f8601526102be565b91602081840391015261037d565b90565b346104405761042761042236600461024f565b610e18565b9061043c6104336100c2565b928392836103e4565b0390f35b6100c8565b90565b61045181610445565b0361045857565b5f80fd5b9050359061046982610448565b565b9060208282031261048457610481915f0161045c565b90565b6100cc565b634e487b7160e01b5f52603260045260245ffd5b5490565b5f5260205f2090565b6104b38161049d565b8210156104cd576104c56001916104a1565b910201905f90565b610489565b1c90565b60018060a01b031690565b6104f19060086104f693026104d2565b6104d6565b90565b9061050491546104e1565b90565b60016105128161049d565b82101561052f5761052c91610526916104aa565b906104f9565b90565b5f80fd5b61053c906100df565b9052565b9190610553905f60208501940190610533565b565b346105855761058161057061056b36600461046b565b610507565b6105786100c2565b91829182610540565b0390f35b6100c8565b346105b8576105a261059d36600461010e565b61123b565b6105aa6100c2565b806105b48161012c565b0390f35b6100c8565b5f9103126105c757565b6100cc565b6105d75f5f906104f9565b90565b3461060a576105ea3660046105bd565b6106066105f56105cc565b6105fd6100c2565b91829182610540565b0390f35b6100c8565b736346d64a3f31774283b72926b75ffda9662266ce90565b61062f61060f565b90565b34610662576106423660046105bd565b61065e61064d610627565b6106556100c2565b91829182610540565b0390f35b6100c8565b60046001609c1b0190565b61067a610667565b90565b346106ad5761068d3660046105bd565b6106a9610698610672565b6106a06100c2565b91829182610540565b0390f35b6100c8565b90565b6106c96106c46106ce926100d4565b6106b2565b6100d4565b90565b6106da906106b5565b90565b6106e6906106d1565b90565b6106f96106f4610667565b6106dd565b90565b6107046106e9565b90565b610710906106b5565b90565b61071c90610707565b90565b61072890610713565b9052565b919061073f905f6020850194019061071f565b565b34610771576107513660046105bd565b61076d61075c6106fc565b6107646100c2565b9182918261072c565b0390f35b6100c8565b61077f90610445565b9052565b9190610796905f60208501940190610776565b565b346107c8576107a83660046105bd565b6107c46107b361124a565b6107bb6100c2565b91829182610783565b0390f35b6100c8565b346107fb576107e56107e036600461010e565b61131a565b6107ed6100c2565b806107f78161012c565b0390f35b6100c8565b5f80fd5b60209181520190565b5f7f4455504c49434154455f50524f56494445520000000000000000000000000000910152565b6108416012602092610804565b61084a8161080d565b0190565b6108639060208101905f818303910152610834565b90565b1561086d57565b6108756100c2565b62461bcd60e51b81528061088b6004820161084e565b0390fd5b6108bd906108b861089f82611325565b6108b26108ac5f19610445565b91610445565b14610866565b6109e1565b565b5f1c90565b6108d06108d5916108bf565b6104d6565b90565b6108e290546108c4565b90565b90565b6108fc6108f7610901926108e5565b6106b2565b6100d4565b90565b61090d906108e8565b90565b5f1b90565b9061092660018060a01b0391610910565b9181191691161790565b61093990610707565b90565b90565b9061095461094f61095b92610930565b61093c565b8254610915565b9055565b5f7f554e415554484f52495a45440000000000000000000000000000000000000000910152565b610993600c602092610804565b61099c8161095f565b0190565b6109b59060208101905f818303910152610986565b90565b156109bf57565b6109c76100c2565b62461bcd60e51b8152806109dd600482016109a0565b0390fd5b610a37906109ee5f6108d8565b610a08610a026109fd5f610904565b6100df565b916100df565b14610a39575b610a3233610a2c610a26610a215f6108d8565b6100df565b916100df565b146109b8565b610b0c565b565b610a4a610a4461060f565b5f61093f565b610a0e565b90565b5f5260205f2090565b5490565b610a6881610a5b565b821015610a8257610a7a600191610a52565b910201905f90565b610489565b1b90565b91906008610aab910291610aa560018060a01b0384610a87565b92610a87565b9181191691161790565b9190610acb610ac6610ad393610930565b61093c565b908354610a8b565b9055565b9081549168010000000000000000831015610b075782610aff916001610b0595018155610a5f565b90610ab5565b565b610176565b610b20610b196001610a4f565b8290610ad7565b610b4a7fae9c2c6481964847714ce58f65a7f6dcc41d0d8394449bacdf161b5920c4744a91610930565b90610b536100c2565b80610b5d8161012c565b0390a2565b610b6b9061088f565b565b606090565b606090565b67ffffffffffffffff8111610b8f5760208091020190565b610176565b90610ba6610ba183610b77565b6101b3565b918252565b369037565b90610bd5610bbd83610b94565b92602080610bcb8693610b77565b9201910390610bab565b565b67ffffffffffffffff8111610bef5760208091020190565b610176565b90610c06610c0183610bd7565b6101b3565b918252565b606090565b5f5b828110610c1e57505050565b602090610c29610c0b565b8184015201610c12565b90610c58610c4083610bf4565b92602080610c4e8693610bd7565b9201910390610c10565b565b610c6e610c69610c73926108e5565b6106b2565b610445565b90565b6001610c829101610445565b90565b60e01b90565b610c9481610297565b03610c9b57565b5f80fd5b90505190610cac82610c8b565b565b90602082820312610cc757610cc4915f01610c9f565b90565b6100cc565b610cd46100c2565b3d5f823e3d90fd5b90610ce682610284565b811015610cf7576020809102010190565b610489565b90610d0690610297565b9052565b90929192610d1f610d1a826101c8565b6101b3565b93818552602085019082840111610d3b57610d399261032e565b565b610168565b9080601f83011215610d5e57816020610d5b93519101610d0a565b90565b610164565b90602082820312610d93575f82015167ffffffffffffffff8111610d8e57610d8b9201610d40565b90565b6100d0565b6100cc565b60209181520190565b610dc0610dc9602093610dce93610db781610321565b93848093610d98565b9586910161032e565b61016c565b0190565b91610df592610de860408201935f830190610533565b6020818403910152610da1565b90565b90610e028261030e565b811015610e13576020809102010190565b610489565b90610e21610b6d565b50610e2a610b72565b50610e3b610e3661124a565b610bb0565b91610e4c610e4761124a565b610c33565b92610e565f610c5a565b5b80610e71610e6b610e6661124a565b610445565b91610445565b1015610fdc57610eca6020610e8c610e876106e9565b610713565b63eefbaf1890610ebf610eaa610ea4600188906104aa565b906104f9565b92610eb36100c2565b95869485938493610c85565b835260048301610540565b03915afa8015610fd757610ef2915f91610fa9575b50610eed8491849092610cdc565b610cfc565b610f02610efd6106e9565b610713565b905f63b7f5f9b792610f1f610f19600185906104aa565b906104f9565b90610f3d838896610f48610f316100c2565b98899687958694610c85565b845260048401610dd2565b03925af1918215610fa457610f7d92610f76915f91610f82575b50878391610f708383610df8565b52610df8565b5150610c76565b610e57565b610f9e91503d805f833e610f96818361018a565b810190610d63565b5f610f62565b610ccc565b610fca915060203d8111610fd0575b610fc2818361018a565b810190610cae565b5f610edf565b503d610fb8565b610ccc565b5090509190565b61103990610ff05f6108d8565b61100a611004610fff5f610904565b6100df565b916100df565b1461103b575b6110343361102e6110286110235f6108d8565b6100df565b916100df565b146109b8565b61115d565b565b61104c61104661060f565b5f61093f565b611010565b5f7f50524f56494445525f4e4f545f464f554e440000000000000000000000000000910152565b6110856012602092610804565b61108e81611051565b0190565b6110a79060208101905f818303910152611078565b90565b90565b6110c16110bc6110c6926110aa565b6106b2565b610445565b90565b634e487b7160e01b5f52601160045260245ffd5b6110ec6110f291939293610445565b92610445565b82039182116110fd57565b6110c9565b634e487b7160e01b5f52603160045260245ffd5b5f90565b61112c91611126611116565b91610ab5565b565b61113781610a5b565b801561115857600190039061115561114f8383610a5f565b9061111a565b55565b611102565b61116681611325565b8061117a6111745f19610445565b91610445565b14611219576111c5906111bf6111b76111b160016111ab61119b600161049d565b6111a560016110ad565b906110dd565b906104aa565b906104f9565b9160016104aa565b90610ab5565b6111d76111d26001610a4f565b61112e565b6112017f1589f8555933761a3cff8aa925061be3b46e2dd43f621322ab611d300f62b1d991610930565b9061120a6100c2565b806112148161012c565b0390a2565b6112216100c2565b62461bcd60e51b81528061123760048201611092565b0390fd5b61124490610fe3565b565b5f90565b611252611246565b5061125d600161049d565b90565b6112b69061126d5f6108d8565b61128761128161127c5f610904565b6100df565b916100df565b146112b8575b6112b1336112ab6112a56112a05f6108d8565b6100df565b916100df565b146109b8565b6112ce565b565b6112c96112c361060f565b5f61093f565b61128d565b6112d8815f61093f565b6113027f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc68616391610930565b9061130b6100c2565b806113158161012c565b0390a2565b61132390611260565b565b61132d611246565b506113375f610c5a565b5b8061135261134c61134761124a565b610445565b91610445565b10156113975761136d611367600183906104aa565b906104f9565b61137f611379846100df565b916100df565b146113925761138d90610c76565b611338565b905090565b50505f199056fea264697066735822122075752650c1eb298fcdd8aac8ecf892932d7cab4774bade6597e821b82ac2e90764736f6c637829302e382e33312d646576656c6f702e323032352e31312e31322b636f6d6d69742e3637366264656363005a" + }, + "0x1000000000000000000000000000000000000006": { + "balance": "0x0", + "code": "0x60806040526004361015610013575b610163565b61001d5f3561003c565b806303c601e31461003757635ae7ab320361000e57610137565b6100ec565b60e01c90565b60405190565b5f80fd5b5f80fd5b60018060a01b031690565b61006490610050565b90565b6100708161005b565b0361007757565b5f80fd5b9050359061008882610067565b565b67ffffffffffffffff1690565b6100a08161008a565b036100a757565b5f80fd5b905035906100b882610097565b565b91906040838203126100e257806100d66100df925f860161007b565b936020016100ab565b90565b61004c565b5f0190565b34610114576100fc3660046100ba565b5050610106610042565b80610110816100e7565b0390f35b610048565b906020828203126101325761012f915f0161007b565b90565b61004c565b3461015e57610147366004610119565b50610150610042565b8061015a816100e7565b0390f35b610048565b5f80fdfea264697066735822122056c8e2b943386ac70b4ad2e17941c118cd4dbfeb7aa843d2d6b0551c94cfe23564736f6c634300081e0033" + }, + "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x70997970c51812dc3a010c7d01b50e0d17dc79c8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x90f79bf6eb2c4f870365e785982e1f101e93b906": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xD9b09DCAe1B5D2fFd36200E12f2617414D5fcC30": { + "balance": "0x2000000000000000000000000000000000000000000000000000000000000000" + }, + "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x2aA4C90C2F9D8A699A0C87B573411Db0d34BE61B":{ + "balance": "0xD3C21BCECCEDA1000000" + } + }, + "coinbase": "0x0000000000000000000000000000000000000000", + "difficulty": "0x0", + "extraData": "0x", + "gasLimit": "0x1c9c380", + "gasUsed": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0", + "number": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494", + "timestamp": "0x6490fdd2" +}
diff --git reth/crates/seismic/chainspec/res/genesis/dev_no_contracts.json seismic-reth/crates/seismic/chainspec/res/genesis/dev_no_contracts.json new file mode 100644 index 0000000000000000000000000000000000000000..f6e9b2c695fbef30d294b22794df80d2d72eb3ab --- /dev/null +++ seismic-reth/crates/seismic/chainspec/res/genesis/dev_no_contracts.json @@ -0,0 +1,75 @@ +{ + "nonce": "0x0", + "timestamp": "0x6490fdd2", + "extraData": "0x", + "gasLimit": "0x1c9c380", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494", + "alloc": { + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x90F79bf6EB2c4f870365E785982E1f101E93b906": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x976EA74026E726554dB657fA54763abd0C3a0aa9": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xBcd4042DE499D14e55001CcbB24a551F3b954096": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x71bE63f3384f5fb98995898A86B02Fb2426c5788": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xFABB0ac9d68B0B445fB7357272Ff202C5651694a": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xcd3B766CCDd6AE721141F452C550Ca635964ce71": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x2546BcD3c84621e976D8185a91A922aE77ECEc30": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xbDA5747bFD65F08deb54cb465eB87D40e51B197E": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xdD2FD4581271e230360230F9337D5c0430Bf44C0": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199": { + "balance": "0xD3C21BCECCEDA1000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file
diff --git reth/crates/seismic/chainspec/res/genesis/mainnet.json seismic-reth/crates/seismic/chainspec/res/genesis/mainnet.json new file mode 100644 index 0000000000000000000000000000000000000000..fded21a2fb903bdf7a00f9597e07601dc1fc3598 --- /dev/null +++ seismic-reth/crates/seismic/chainspec/res/genesis/mainnet.json @@ -0,0 +1,26719 @@ +{ + "config": { + "ethash": {}, + "chainId": 5123, + "homesteadBlock": 0, + "daoForkSupport": true, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "terminalTotalDifficulty": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "pragueTime": 0, + "osakaTime": 0 + }, + "nonce": "0x42", + "timestamp": "0x0", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388", + "difficulty": "0x400000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544", + "alloc": { + "000d836201318ec6899a67540690382780743280": { + "balance": "0xad78ebc5ac6200000" + }, + "001762430ea9c3a26e5749afdb70da5f78ddbb8c": { + "balance": "0xad78ebc5ac6200000" + }, + "001d14804b399c6ef80e64576f657660804fec0b": { + "balance": "0xe3aeb5737240a00000" + }, + "0032403587947b9f15622a68d104d54d33dbd1cd": { + "balance": "0x433874f632cc60000" + }, + "00497e92cdc0e0b963d752b2296acb87da828b24": { + "balance": "0xa8f649fe7c6180000" + }, + "004bfbe1546bc6c65b5c7eaa55304b38bbfec6d3": { + "balance": "0x6c6b935b8bbd400000" + }, + "005a9c03f69d17d66cbb8ad721008a9ebbb836fb": { + "balance": "0x6c6b935b8bbd400000" + }, + "005d0ee8155ec0a6ff6808552ca5f16bb5be323a": { + "balance": "0xaadec983fcff40000" + }, + "007622d84a234bb8b078230fcf84b67ae9a8acae": { + "balance": "0x25e1cc519952f80000" + }, + "007b9fc31905b4994b04c9e2cfdc5e2770503f42": { + "balance": "0x6c5db2a4d815dc0000" + }, + "007f4a23ca00cd043d25c2888c1aa5688f81a344": { + "balance": "0x29f0a95bfbf7290000" + }, + "008639dabbe3aeac887b5dc0e43e13bcd287d76c": { + "balance": "0x10d0e3c87d6e2c0000" + }, + "0089508679abf8c71bf6781687120e3e6a84584d": { + "balance": "0x6194049f30f7200000" + }, + "008fc7cbadffbd0d7fe44f8dfd60a79d721a1c9c": { + "balance": "0x3635c9adc5dea00000" + }, + "009560a3de627868f91fa8bfe1c1b7afaf08186b": { + "balance": "0x1c67f5f7baa0b00000" + }, + "00969747f7a5b30645fe00e44901435ace24cc37": { + "balance": "0x5c283d410394100000" + }, + "009a6d7db326679b77c90391a7476d238f3ba33e": { + "balance": "0xada55474b81340000" + }, + "009eef0a0886056e3f69211853b9b7457f3782e4": { + "balance": "0xa2a878069b28e00000" + }, + "009fdbf44e1f4a6362b769c39a475f95a96c2bc7": { + "balance": "0x1e931283ccc8500000" + }, + "00a5797f52c9d58f189f36b1d45d1bf6041f2f6b": { + "balance": "0x127d1b3461acd1a0000" + }, + "00aa5381b2138ebeffc191d5d8c391753b7098d2": { + "balance": "0x35abb09ffedeb68000" + }, + "00aada25ea2286709abb422d41923fd380cd04c7": { + "balance": "0x233df3299f61720000" + }, + "00acbfb2f25a5485c739ef70a44eeeeb7c65a66f": { + "balance": "0x56bc75e2d63100000" + }, + "00acc6f082a442828764d11f58d6894ae408f073": { + "balance": "0xcb49b44ba602d800000" + }, + "00b277b099a8e866ca0ec65bcb87284fd142a582": { + "balance": "0x6acb3df27e1f880000" + }, + "00bdd4013aa31c04616c2bc9785f2788f915679b": { + "balance": "0xb9f65d00f63c0000" + }, + "00c27d63fde24b92ee8a1e7ed5d26d8dc5c83b03": { + "balance": "0x6c6b935b8bbd400000" + }, + "00c40fe2095423509b9fd9b754323158af2310f3": { "balance": "0x0" }, + "00d75ed60c774f8b3a5a5173fb1833ad7105a2d9": { + "balance": "0x6cb7e74867d5e60000" + }, + "00d78d89b35f472716eceafebf600527d3a1f969": { + "balance": "0x5e0549c9632e1d80000" + }, + "00dae27b350bae20c5652124af5d8b5cba001ec1": { + "balance": "0x22b1c8c1227a00000" + }, + "00dc01cbf44978a42e8de8e436edf94205cfb6ec": { + "balance": "0x4f0febbcda8cb40000" + }, + "00e681bc2d10db62de85848324492250348e90bf": { + "balance": "0x43c33c1937564800000" + }, + "00f463e137dcf625fbf3bca39eca98d2b968cf7f": { + "balance": "0x14061b9d77a5e980000" + }, + "010007394b8b7565a1658af88ce463499135d6b7": { + "balance": "0x56bc75e2d63100000" + }, + "010df1df4bed23760d2d1c03781586ddf7918e54": { + "balance": "0x340aad21b3b700000" + }, + "010f4a98dfa1d9799bf5c796fb550efbe7ecd877": { + "balance": "0x1b2f292236292c70000" + }, + "01155057002f6b0d18acb9388d3bc8129f8f7a20": { + "balance": "0x48a43c54602f700000" + }, + "01226e0ad8d62277b162621c62c928e96e0b9a8c": { + "balance": "0x6c6b935b8bbd400000" + }, + "0126e12ebc17035f35c0e9d11dd148393c405d7a": { + "balance": "0x6c660645aa47180000" + }, + "012f396a2b5eb83559bac515e5210df2c8c362ba": { + "balance": "0xad78ebc5ac6200000" + }, + "0134ff38155fabae94fd35c4ffe1d79de7ef9c59": { + "balance": "0x35659ef93f0fc40000" + }, + "0136a5af6c3299c6b5f005fdaddb148c070b299b": { + "balance": "0x11aa9ac15f1280000" + }, + "01488ad3da603c4cdd6cb0b7a1e30d2a30c8fc38": { + "balance": "0xad78ebc5ac6200000" + }, + "014974a1f46bf204944a853111e52f1602617def": { + "balance": "0x6c6b935b8bbd400000" + }, + "014b7f67b14f5d983d87014f570c8b993b9872b5": { + "balance": "0xad78ebc5ac6200000" + }, + "0151fa5d17a2dce2d7f1eb39ef7fe2ad213d5d89": { + "balance": "0xd8d726b7177a800000" + }, + "01577afd4e50890247c9b10d44af73229aec884f": { + "balance": "0x24dce54d34a1a00000" + }, + "015f097d9acddcddafaf2a107eb93a40fc94b04c": { + "balance": "0x43c33c1937564800000" + }, + "0169c1c210eae845e56840412e1f65993ea90fb4": { + "balance": "0x6c6b935b8bbd400000" + }, + "016b60bb6d67928c29fd0313c666da8f1698d9c5": { + "balance": "0x6c6b935b8bbd400000" + }, + "016c85e1613b900fa357b8283b120e65aefcdd08": { + "balance": "0x2b5d9784a97cd50000" + }, + "018492488ba1a292342247b31855a55905fef269": { + "balance": "0x796e3ea3f8ab00000" + }, + "018f20a27b27ec441af723fd9099f2cbb79d6263": { + "balance": "0x75792a8abdef7c0000" + }, + "0191eb547e7bf6976b9b1b577546761de65622e2": { + "balance": "0x6c6b4c4da6ddbe0000" + }, + "019d709579ff4bc09fdcdde431dc1447d2c260bc": { + "balance": "0x1158e460913d00000" + }, + "01a25a5f5af0169b30864c3be4d7563ccd44f09e": { + "balance": "0x4d853c8f8908980000" + }, + "01a7d9fa7d0eb1185c67e54da83c2e75db69e39f": { + "balance": "0x19d4addd0d8bc960000" + }, + "01a818135a414210c37c62b625aca1a54611ac36": { + "balance": "0xe18398e7601900000" + }, + "01b1cae91a3b9559afb33cdc6d689442fdbfe037": { + "balance": "0xad78ebc5ac6200000" + }, + "01b5b5bc5a117fa08b34ed1db9440608597ac548": { + "balance": "0xad78ebc5ac6200000" + }, + "01bbc14f67af0639aab1441e6a08d4ce7162090f": { + "balance": "0x46fcf68ff8be060000" + }, + "01d03815c61f416b71a2610a2daba59ff6a6de5b": { + "balance": "0x205dfe50b81c82e0000" + }, + "01d599ee0d5f8c38ab2d392e2c65b74c3ce31820": { + "balance": "0x1ba5abf9e779380000" + }, + "01e40521122530d9ac91113c06a0190b6d63850b": { + "balance": "0x487a9a304539440000" + }, + "01e6415d587b065490f1ed7f21d6e0f386ee6747": { + "balance": "0x6c6b935b8bbd400000" + }, + "01e864d354741b423e6f42851724468c74f5aa9c": { + "balance": "0x43c33c1937564800000" + }, + "01ed5fba8d2eab673aec042d30e4e8a611d8c55a": { + "balance": "0x6c6b935b8bbd400000" + }, + "01fb8ec12425a04f813e46c54c05748ca6b29aa9": { + "balance": "0xe15730385467c0000" + }, + "01ff1eb1dead50a7f2f9638fdee6eccf3a7b2ac8": { + "balance": "0x2086ac351052600000" + }, + "020362c3ade878ca90d6b2d889a4cc5510eed5f3": { + "balance": "0x3888e8b311adb38000" + }, + "0203ae01d4c41cae1865e04b1f5b53cdfaecae31": { + "balance": "0x3689cdceb28cd70000" + }, + "02089361a3fe7451fb1f87f01a2d866653dc0b07": { + "balance": "0x22ac74832b5040000" + }, + "021f69043de88c4917ca10f1842897eec0589c7c": { + "balance": "0x6b44cfb81487f40000" + }, + "02290fb5f9a517f82845acdeca0fc846039be233": { + "balance": "0x6c6b935b8bbd400000" + }, + "0239b4f21f8e05cd01512b2be7a0e18a6d974607": { + "balance": "0x3635c9adc5dea00000" + }, + "02477212ffdd75e5155651b76506b1646671a1eb": { + "balance": "0x5f68e8131ecf800000" + }, + "024a098ae702bef5406c9c22b78bd4eb2cc7a293": { + "balance": "0xd8d726b7177a800000" + }, + "024bdd2c7bfd500ee7404f7fb3e9fb31dd20fbd1": { + "balance": "0x9c2007651b2500000" + }, + "025367960304beee34591118e9ac2d1358d8021a": { + "balance": "0x6c6b935b8bbd400000" + }, + "0256149f5b5063bea14e15661ffb58f9b459a957": { + "balance": "0x2629f66e0c53000000" + }, + "02603d7a3bb297c67c877e5d34fbd5b913d4c63a": { + "balance": "0x1158e460913d00000" + }, + "0261ad3a172abf1315f0ffec3270986a8409cb25": { + "balance": "0xb08213bcf8ffe0000" + }, + "026432af37dc5113f1f46d480a4de0b28052237e": { + "balance": "0x1349b786e40bfc0000" + }, + "0266ab1c6b0216230b9395443d5fa75e684568c6": { + "balance": "0x3635c9adc5dea00000" + }, + "02751dc68cb5bd737027abf7ddb77390cd77c16b": { + "balance": "0x1158e460913d00000" + }, + "02778e390fa17510a3428af2870c4273547d386c": { + "balance": "0x36c3c66170c0d720000" + }, + "02ade5db22f8b758ee1443626c64ec2f32aa0a15": { + "balance": "0x43c33c1937564800000" + }, + "02af2459a93d0b3f4d062636236cd4b29e3bcecf": { + "balance": "0x678a932062e4180000" + }, + "02b1af72339b2a2256389fd64607de24f0de600a": { + "balance": "0x6c6b935b8bbd400000" + }, + "02b643d6fabd437a851accbe79abb7fde126dccf": { + "balance": "0x18650127cc3dc800000" + }, + "02b6d65cb00b7b36e1fb5ed3632c4cb20a894130": { + "balance": "0x43c33c1937564800000" + }, + "02b7b1d6b34ce053a40eb65cd4a4f7dddd0e9f30": { + "balance": "0x252248deb6e6940000" + }, + "02c9f7940a7b8b7a410bf83dc9c22333d4275dd3": { + "balance": "0x10f0cf064dd59200000" + }, + "02d4a30968a39e2b3498c3a6a4ed45c1c6646822": { + "balance": "0x6c6b935b8bbd400000" + }, + "02dfcb17a1b87441036374b762a5d3418b1cb4d4": { + "balance": "0x48b02ba9d1ba460000" + }, + "02e4cb22be46258a40e16d4338d802fffd00c151": { + "balance": "0x149696eaceba810000" + }, + "02e816afc1b5c0f39852131959d946eb3b07b5ad": { + "balance": "0x3635c9adc5dea00000" + }, + "02f7f67209b16a17550c694c72583819c80b54ad": { + "balance": "0x5559306a78a700000" + }, + "030973807b2f426914ad00181270acd27b8ff61f": { + "balance": "0x121ea68c114e5100000" + }, + "03097923ba155e16d82f3ad3f6b815540884b92c": { + "balance": "0x62a992e53a0af00000" + }, + "030fb3401f72bd3418b7d1da75bf8c519dd707dc": { + "balance": "0xa2a15d09519be00000" + }, + "031e25db516b0f099faebfd94f890cf96660836b": { + "balance": "0x6c6b935b8bbd400000" + }, + "0328510c09dbcd85194a98d67c33ac49f2f94d60": { + "balance": "0x2544faa778090e00000" + }, + "0329188f080657ab3a2afa522467178279832085": { + "balance": "0xbbf510ddfcb260000" + }, + "03317826d1f70aa4bddfa09be0c4105552d2358b": { + "balance": "0x21a754a6dc5280000" + }, + "03337012ae1d7ff3ee7f697c403e7780188bf0ef": { + "balance": "0xad78ebc5ac6200000" + }, + "03377c0e556b640103289a6189e1aeae63493467": { + "balance": "0x43c33c1937564800000" + }, + "0349634dc2a9e80c3f7721ee2b5046aeaaedfbb5": { + "balance": "0xd8d726b7177a800000" + }, + "0355bcacbd21441e95adeedc30c17218c8a408ce": { + "balance": "0x15af1d78b58c400000" + }, + "036eeff5ba90a6879a14dff4c5043b18ca0460c9": { + "balance": "0x56bc75e2d63100000" + }, + "03714b41d2a6f751008ef8dd4d2b29aecab8f36e": { + "balance": "0x14542ba12a337c00000" + }, + "0372e852582e0934344a0fed2178304df25d4628": { + "balance": "0x43c33c1937564800000" + }, + "0372ee5508bf8163ed284e5eef94ce4d7367e522": { + "balance": "0x56bc75e2d63100000" + }, + "037dd056e7fdbd641db5b6bea2a8780a83fae180": { + "balance": "0x796e3ea3f8ab00000" + }, + "038323b184cff7a82ae2e1bda7793fe4319ca0bf": { + "balance": "0x43c33c1937564800000" + }, + "038779ca2dbe663e63db3fe75683ea0ec62e2383": { + "balance": "0x5a87e7d7f5f6580000" + }, + "038e45eadd3d88b87fe4dab066680522f0dfc8f9": { + "balance": "0x21e19e0c9bab2400000" + }, + "0392549a727f81655429cb928b529f25df4d1385": { + "balance": "0x16c43a0eea0740000" + }, + "0394b90fadb8604f86f43fc1e35d3124b32a5989": { + "balance": "0x296aa140278e700000" + }, + "039e7a4ebc284e2ccd42b1bdd60bd6511c0f7706": { + "balance": "0xf015f25736420000" + }, + "039ef1ce52fe7963f166d5a275c4b1069fe3a832": { + "balance": "0x15af39e4aab2740000" + }, + "03a26cfc4c18316f70d59e9e1a79ee3e8b962f4c": { + "balance": "0x6c6b935b8bbd400000" + }, + "03aa622881236dd0f4940c24c324ff8b7b7e2186": { + "balance": "0xad78ebc5ac62000000" + }, + "03af7ad9d5223cf7c8c13f20df67ebe5ffc5bb41": { + "balance": "0xad78ebc5ac6200000" + }, + "03b0f17cd4469ddccfb7da697e82a91a5f9e7774": { + "balance": "0x1158e460913d00000" + }, + "03b41b51f41df20dd279bae18c12775f77ad771c": { + "balance": "0x3635c9adc5dea00000" + }, + "03be5b4629aefbbcab9de26d39576cb7f691d764": { + "balance": "0xadf30ba70c8970000" + }, + "03c647a9f929b0781fe9ae01caa3e183e876777e": { + "balance": "0x182ab7c20ce5240000" + }, + "03c91d92943603e752203e05340e566013b90045": { + "balance": "0x2b7cc2e9c3225c0000" + }, + "03cb4c4f4516c4ff79a1b6244fbf572e1c7fea79": { + "balance": "0x9489237adb9a500000" + }, + "03cb98d7acd817de9d886d22fab3f1b57d92a608": { + "balance": "0x56bc75e2d631000000" + }, + "03cc9d2d21f86b84ac8ceaf971dba78a90e62570": { + "balance": "0x57473d05dabae80000" + }, + "03d1724fd00e54aabcd2de2a91e8462b1049dd3a": { + "balance": "0x8f1d5c1cae37400000" + }, + "03dedfcd0b3c2e17c705da248790ef98a6bd5751": { + "balance": "0x487a9a304539440000" + }, + "03e8b084537557e709eae2e1e1a5a6bce1ef8314": { + "balance": "0x1158e460913d00000" + }, + "03ea6d26d080e57aee3926b18e8ed73a4e5b2826": { + "balance": "0xad78ebc5ac6200000" + }, + "03eb3cb860f6028da554d344a2bb5a500ae8b86f": { + "balance": "0x6c6b935b8bbd400000" + }, + "03ebc63fda6660a465045e235fbe6e5cf195735f": { + "balance": "0x7b06ce87fdd680000" + }, + "03ef6ad20ff7bd4f002bac58d47544cf879ae728": { + "balance": "0x175c758d0b96e5c0000" + }, + "03f7b92008813ae0a676eb212814afab35221069": { + "balance": "0x6c6b935b8bbd400000" + }, + "041170f581de80e58b2a045c8f7c1493b001b7cb": { + "balance": "0x303c74a1a336940000" + }, + "0413d0cf78c001898a378b918cd6e498ea773c4d": { + "balance": "0xf2dc7d47f15600000" + }, + "04241b41ecbd0bfdf1295e9d4fa59ea09e6c6186": { + "balance": "0x655f769450bc780000" + }, + "043707071e2ae21eed977891dc79cd5d8ee1c2da": { + "balance": "0x6c6b935b8bbd400000" + }, + "044e853144e3364495e7a69fa1d46abea3ac0964": { + "balance": "0x2ab2254b1dc9a8000" + }, + "0455dcec8a7fc4461bfd7f37456fce3f4c3caac7": { + "balance": "0x15af1d78b58c400000" + }, + "045ed7f6d9ee9f252e073268db022c6326adfc5b": { + "balance": "0x56bc75e2d63100000" + }, + "046377f864b0143f282174a892a73d3ec8ec6132": { + "balance": "0xa5aa85009e39c0000" + }, + "0469e8c440450b0e512626fe817e6754a8152830": { + "balance": "0x6c6b935b8bbd400000" + }, + "046d274b1af615fb505a764ad8dda770b1db2f3d": { + "balance": "0x6c6b935b8bbd400000" + }, + "047d5a26d7ad8f8e70600f70a398ddaa1c2db26f": { + "balance": "0x14542ba12a337c00000" + }, + "047e87c8f7d1fce3b01353a85862a948ac049f3e": { + "balance": "0x50c5e761a444080000" + }, + "047f9bf1529daf87d407175e6f171b5e59e9ff3e": { + "balance": "0x233c8fe42703e80000" + }, + "04852732b4c652f6c2e58eb36587e60a62da14db": { + "balance": "0x43c33c1937564800000" + }, + "048a8970ea4145c64d5517b8de5b46d0595aad06": { + "balance": "0x43c33c1937564800000" + }, + "049c5d4bc6f25d4e456c697b52a07811ccd19fb1": { + "balance": "0x104400a2470e680000" + }, + "04a1cada1cc751082ff8da928e3cfa000820a9e9": { + "balance": "0x22b1c8c1227a00000" + }, + "04a80afad53ef1f84165cfd852b0fdf1b1c24ba8": { + "balance": "0x324e964b3eca80000" + }, + "04aafc8ae5ce6f4903c89d7fac9cb19512224777": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "04ba4bb87140022c214a6fac42db5a16dd954045": { + "balance": "0x3635c9adc5dea00000" + }, + "04ba8a3f03f08b895095994dda619edaacee3e7a": { + "balance": "0x6c6b935b8bbd400000" + }, + "04c2c64bb54c3eccd05585e10ec6f99a0cdb01a3": { + "balance": "0x56bc75e2d63100000" + }, + "04ce45f600db18a9d0851b29d9393ebdaafe3dc5": { + "balance": "0x1158e460913d00000" + }, + "04d6b8d4da867407bb997749debbcdc0b358538a": { + "balance": "0x3635c9adc5dea00000" + }, + "04d73896cf6593a691972a13a6e4871ff2c42b13": { + "balance": "0x6c6b935b8bbd400000" + }, + "04d82af9e01a936d97f8f85940b970f9d4db9936": { + "balance": "0xad78ebc5ac6200000" + }, + "04e5f5bc7c923fd1e31735e72ef968fd67110c6e": { + "balance": "0x57551dbc8e624c0000" + }, + "04eca501630abce35218b174956b891ba25efb23": { + "balance": "0x36369ed7747d260000" + }, + "0505a08e22a109015a22f685305354662a5531d5": { + "balance": "0x8cf23f909c0fa00000" + }, + "0514954c3c2fb657f9a06f510ea22748f027cdd3": { + "balance": "0x15af1d78b58c400000" + }, + "051633080d07a557adde319261b074997f14692d": { + "balance": "0x13a6b2b564871a00000" + }, + "0517448dada761cc5ba4033ee881c83037036400": { + "balance": "0x6c4fd1ee246e780000" + }, + "051d424276b21239665186133d653bb8b1862f89": { + "balance": "0x3635c9adc5dea00000" + }, + "0521bc3a9f8711fecb10f50797d71083e341eb9d": { + "balance": "0x1158e460913d00000" + }, + "05236d4c90d065f9e3938358aaffd777b86aec49": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "052a58e035f1fe9cdd169bcf20970345d12b9c51": { + "balance": "0x50c5e761a444080000" + }, + "052eab1f61b6d45517283f41d1441824878749d0": { + "balance": "0xd8d726b7177a800000" + }, + "05336e9a722728d963e7a1cf2759fd0274530fca": { + "balance": "0x31a2443f888a798000" + }, + "053471cd9a41925b3904a5a8ffca3659e034be23": { + "balance": "0xad201a6794ff80000" + }, + "05361d8eb6941d4e90fb7e1418a95a32d5257732": { + "balance": "0x1158e460913d00000" + }, + "05423a54c8d0f9707e704173d923b946edc8e700": { + "balance": "0x6ea03c2bf8ba58000" + }, + "05440c5b073b529b4829209dff88090e07c4f6f5": { + "balance": "0x45d29737e22f200000" + }, + "055ab658c6f0ed4f875ed6742e4bc7292d1abbf0": { + "balance": "0x486cb9799191e0000" + }, + "055bd02caf19d6202bbcdc836d187bd1c01cf261": { + "balance": "0x56bc75e2d63100000" + }, + "055eac4f1ad3f58f0bd024d68ea60dbe01c6afb3": { + "balance": "0x56bc75e2d63100000" + }, + "05665155cc49cbf6aabdd5ae92cbfaad82b8c0c1": { + "balance": "0x15af1d78b58c400000" + }, + "056686078fb6bcf9ba0a8a8dc63a906f5feac0ea": { + "balance": "0x1b181e4bf2343c0000" + }, + "05696b73916bd3033e05521e3211dfec026e98e4": { + "balance": "0x6c6b935b8bbd400000" + }, + "056b1546894f9a85e203fb336db569b16c25e04f": { + "balance": "0x92edb09ff08d88000" + }, + "057949e1ca0570469e4ce3c690ae613a6b01c559": { + "balance": "0xad78ebc5ac6200000" + }, + "057dd29f2d19aa3da42327ea50bce86ff5c911d9": { + "balance": "0xd8d726b7177a800000" + }, + "057f7f81cd7a406fc45994408b5049912c566463": { + "balance": "0x5c283d410394100000" + }, + "05915d4e225a668162aee7d6c25fcfc6ed18db03": { + "balance": "0x398c37279259e0000" + }, + "0596a27dc3ee115fce2f94b481bc207a9e261525": { + "balance": "0x3635c9adc5dea00000" + }, + "05a830724302bc0f6ebdaa1ebeeeb46e6ce00b39": { + "balance": "0x556f64c1fe7fa0000" + }, + "05ae7fd4bbcc80ca11a90a1ec7a301f7cccc83db": { + "balance": "0x3154c9729d05780000" + }, + "05bb64a916be66f460f5e3b64332110d209e19ae": { + "balance": "0xe3aeb5737240a00000" + }, + "05bf4fcfe772e45b826443852e6c351350ce72a2": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "05c64004a9a826e94e5e4ee267fa2a7632dd4e6f": { + "balance": "0x36dc42ebff90b7f8000" + }, + "05c736d365aa37b5c0be9c12c8ad5cd903c32cf9": { + "balance": "0x1455e7b800a86880000" + }, + "05cb6c3b0072d3116761b532b218443b53e8f6c5": { + "balance": "0x1e02c3d7fca9b6280000" + }, + "05d0f4d728ebe82e84bf597515ad41b60bf28b39": { + "balance": "0xe3aeb5737240a00000" + }, + "05d68dad61d3bbdfb3f779265c49474aff3fcd30": { + "balance": "0x222c55dc1519d8000" + }, + "05e671de55afec964b074de574d5158d5d21b0a3": { + "balance": "0xd5967be4fc3f100000" + }, + "05e97b09492cd68f63b12b892ed1d11d152c0eca": { + "balance": "0x3708baed3d68900000" + }, + "05f3631f5664bdad5d0132c8388d36d7d8920918": { + "balance": "0x1158e460913d00000" + }, + "0609d83a6ce1ffc9b690f3e9a81e983e8bdc4d9d": { + "balance": "0xed2b525841adfc00000" + }, + "061ea4877cd08944eb64c2966e9db8dedcfec06b": { + "balance": "0x3635c9adc5dea00000" + }, + "0625d06056968b002206ff91980140242bfaa499": { + "balance": "0x3635c9adc5dea00000" + }, + "0628bfbe5535782fb588406bc96660a49b011af5": { + "balance": "0x52663ccab1e1c00000" + }, + "0631d18bbbbd30d9e1732bf36edae2ce8901ab80": { + "balance": "0xa3f98855ec39900000" + }, + "0631dc40d74e5095e3729eddf49544ecd4396f67": { + "balance": "0x8ac7230489e800000" + }, + "063759dd1c4e362eb19398951ff9f8fad1d31068": { + "balance": "0x21e19e0c9bab2400000" + }, + "065ff575fd9c16d3cb6fd68ffc8f483fc32ec835": { + "balance": "0xad78ebc5ac6200000" + }, + "06618e9d5762df62028601a81d4487d6a0ecb80e": { + "balance": "0x487a9a304539440000" + }, + "066647cfc85d23d37605573d208ca154b244d76c": { + "balance": "0x21e19e0c9bab2400000" + }, + "0678654ac6761db904a2f7e8595ec1eaac734308": { + "balance": "0x2f98b29c2818f80000" + }, + "06860a93525955ff624940fadcffb8e149fd599c": { + "balance": "0x6c68ccd09b022c0000" + }, + "068ce8bd6e902a45cb83b51541b40f39c4469712": { + "balance": "0x11c0f9bad4a46e00000" + }, + "068e29b3f191c812a6393918f71ab933ae6847f2": { + "balance": "0x6c6acc67d7b1d40000" + }, + "068e655766b944fb263619658740b850c94afa31": { + "balance": "0x1e87f85809dc00000" + }, + "06964e2d17e9189f88a8203936b40ac96e533c06": { + "balance": "0xfc936392801c0000" + }, + "06994cd83aa2640a97b2600b41339d1e0d3ede6c": { + "balance": "0xd8d726b7177a80000" + }, + "069ed0ab7aa77de571f16106051d92afe195f2d0": { + "balance": "0xad78ebc5ac6200000" + }, + "06ac26ad92cb859bd5905ddce4266aa0ec50a9c5": { + "balance": "0x2a034919dfbfbc0000" + }, + "06b0c1e37f5a5ec4bbf50840548f9d3ac0288897": { + "balance": "0xd8d882e1928e7d0000" + }, + "06b0ff834073cce1cbc9ea557ea87b605963e8b4": { + "balance": "0x1043561a8829300000" + }, + "06b106649aa8c421ddcd1b8c32cd0418cf30da1f": { + "balance": "0x878678326eac9000000" + }, + "06b5ede6fdf1d6e9a34721379aeaa17c713dd82a": { + "balance": "0x6c6b935b8bbd400000" + }, + "06cbfa08cdd4fba737bac407be8224f4eef35828": { + "balance": "0x202be5e8382e8b8000" + }, + "06d6cb308481c336a6e1a225a912f6e6355940a1": { + "balance": "0x5f68e8131ecf800000" + }, + "06dc7f18cee7edab5b795337b1df6a9e8bd8ae59": { + "balance": "0x15af1d78b58c400000" + }, + "06f68de3d739db41121eacf779aada3de8762107": { + "balance": "0x18493fba64ef00000" + }, + "06f7dc8d1b9462cef6feb13368a7e3974b097f9f": { + "balance": "0x6c6b935b8bbd400000" + }, + "0701f9f147ec486856f5e1b71de9f117e99e2105": { + "balance": "0x965da717fd5b80000" + }, + "070d5d364cb7bbf822fc2ca91a35bdd441b215d5": { + "balance": "0x6c6b935b8bbd400000" + }, + "071dd90d14d41f4ff7c413c24238d3359cd61a07": { + "balance": "0x7b53f79e888dac00000" + }, + "0726c42e00f45404836eb1e280d073e7059687f5": { + "balance": "0x58003e3fb947a38000" + }, + "0727be0a2a00212048b5520fbefb953ebc9d54a0": { + "balance": "0x21e19e0c9bab2400000" + }, + "0729a8a4a5ba23f579d0025b1ad0f8a0d35cdfd2": { + "balance": "0x20dd68aaf3289100000" + }, + "0729b4b47c09eb16158464c8aa7fd9690b438839": { + "balance": "0x6c68ccd09b022c0000" + }, + "0734a0a81c9562f4d9e9e10a8503da15db46d76e": { + "balance": "0xfc936392801c0000" + }, + "073c67e09b5c713c5221c8a0c7f3f74466c347b0": { + "balance": "0x41bad155e6512200000" + }, + "073f1ed1c9c3e9c52a9b0249a5c1caa0571fdf05": { + "balance": "0x3d0ff0b013b800000" + }, + "0748713145ef83c3f0ef4d31d823786f7e9cc689": { + "balance": "0xf3f20b8dfa69d00000" + }, + "075d15e2d33d8b4fa7dba8b9e607f04a261e340b": { + "balance": "0x678a932062e4180000" + }, + "076561a856455d7ef86e63f87c73dbb628a55f45": { + "balance": "0x30ca024f987b900000" + }, + "076ee99d3548623a03b5f99859d2d785a1778d48": { + "balance": "0xad78ebc5ac6200000" + }, + "0770b43dbae4b1f35a927b4fa8124d3866caf97b": { + "balance": "0x37193ea7ef5b470000" + }, + "0770c61be78772230cb5a3bb2429a72614a0b336": { + "balance": "0x16ee0a299b713418000" + }, + "07723e3c30e8b731ee456a291ee0e798b0204a77": { + "balance": "0x6c6b935b8bbd400000" + }, + "0773eeacc050f74720b4a1bd57895b1cceeb495d": { + "balance": "0x21e19e0c9bab2400000" + }, + "07800d2f8068e448c79a4f69b1f15ef682aae5f6": { + "balance": "0x41bad155e6512200000" + }, + "07a8dadec142571a7d53a4297051786d072cba55": { + "balance": "0x13b6da1139bda8000" + }, + "07af938c1237a27c9030094dcf240750246e3d2c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "07b1a306cb4312df66482c2cae72d1e061400fcd": { + "balance": "0x43c33c1937564800000" + }, + "07b7a57033f8f11330e4665e185d234e83ec140b": { + "balance": "0xea7ee92a0c9a0b8000" + }, + "07bc2cc8eedc01970700efc9c4fb36735e98cd71": { + "balance": "0xd8d726b7177a800000" + }, + "07d41217badca5e0e60327d845a3464f0f27f84a": { + "balance": "0xd8d726b7177a800000" + }, + "07d4334ec385e8aa54eedaeadb30022f0cdfa4ab": { + "balance": "0x8e91d520f2eb790000" + }, + "07dae622630d1136381933d2ad6b22b839d82102": { + "balance": "0xad78ebc5ac6200000" + }, + "07dc2bf83bc6af19a842ffea661af5b41b67fda1": { + "balance": "0x5150ae84a8cdf00000" + }, + "07dc8c8b927adbedfa8f5d639b4352351f2f36d2": { + "balance": "0x110aed3b5530db0000" + }, + "07ddd0422c86ef65bf0c7fc3452862b1228b08b8": { + "balance": "0x6ff5d2aa8f9fcf0000" + }, + "07e1162ceae3cf21a3f62d105990302e307f4e3b": { + "balance": "0x52f103edb66ba80000" + }, + "07e2b4cdeed9d087b12e556d9e770c13c099615f": { + "balance": "0x243d4d18229ca20000" + }, + "07feef54c136850829badc4b49c3f2a73c89fb9e": { + "balance": "0x6685ac1bfe32c0000" + }, + "080546508a3d2682c8b9884f13637b8847b44db3": { + "balance": "0x6c6b935b8bbd400000" + }, + "08090876baadfee65c3d363ba55312748cfa873d": { + "balance": "0x5c2a99371cffe10000" + }, + "08166f02313feae18bb044e7877c808b55b5bf58": { + "balance": "0x6acb3df27e1f880000" + }, + "0829d0f7bb7c446cfbb0deadb2394d9db7249a87": { + "balance": "0x22ca3587cf4eb0000" + }, + "08306de51981e7aca1856859b7c778696a6b69f9": { + "balance": "0xad78ebc5ac62000000" + }, + "0837539b5f6a522a482cdcd3a9bb7043af39bdd2": { + "balance": "0x14542ba12a337c00000" + }, + "0838a7768d9c2aca8ba279adfee4b1f491e326f1": { + "balance": "0xad78ebc5ac6200000" + }, + "08411652c871713609af0062a8a1281bf1bbcfd9": { + "balance": "0x4be4e7267b6ae00000" + }, + "084d103254759b343cb2b9c2d8ff9e1ac5f14596": { + "balance": "0x19bff2ff57968c00000" + }, + "08504f05643fab5919f5eea55925d7a3ed7d807a": { + "balance": "0x1158e460913d00000" + }, + "085b4ab75d8362d914435cedee1daa2b1ee1a23b": { + "balance": "0xd255d112e103a00000" + }, + "085ba65febe23eefc2c802666ab1262382cfc494": { + "balance": "0x15af1d78b58c400000" + }, + "087498c0464668f31150f4d3c4bcdda5221ba102": { + "balance": "0x1158e460913d00000" + }, + "0877eeaeab78d5c00e83c32b2d98fa79ad51482f": { + "balance": "0x17d22d71da62260000" + }, + "08936a37df85b3a158cafd9de021f58137681347": { + "balance": "0xfc936392801c0000" + }, + "08a9a44e1f41de3dbba7a363a3ab412c124cd15e": { + "balance": "0xad78ebc5ac6200000" + }, + "08b7bdcf944d5570838be70460243a8694485858": { + "balance": "0x6c6b935b8bbd400000" + }, + "08b84536b74c8c01543da88b84d78bb95747d822": { + "balance": "0xad78ebc5ac6200000" + }, + "08c2f236ac4adcd3fda9fbc6e4532253f9da3bec": { + "balance": "0x1158e460913d00000" + }, + "08c802f87758349fa03e6bc2e2fd0791197eea9a": { + "balance": "0x6c6b935b8bbd400000" + }, + "08c9f1bfb689fdf804d769f82123360215aff93b": { + "balance": "0x6acb3df27e1f880000" + }, + "08cac8952641d8fc526ec1ab4f2df826a5e7710f": { + "balance": "0x1043561a8829300000" + }, + "08ccda50e4b26a0ffc0ef92e9205310706bec2c7": { + "balance": "0x149756c3857c6000000" + }, + "08d0864dc32f9acb36bf4ea447e8dd6726906a15": { + "balance": "0x6c6e59e67c78540000" + }, + "08d4267feb15da9700f7ccc3c84a8918bf17cfde": { + "balance": "0x61093d7c2c6d380000" + }, + "08d4311c9c1bbaf87fabe1a1d01463828d5d98ce": { + "balance": "0x130ee8e7179044400000" + }, + "08d54e83ad486a934cfaeae283a33efd227c0e99": { + "balance": "0x38530583245edc0000" + }, + "08d97eadfcb7b064e1ccd9c8979fbee5e77a9719": { + "balance": "0xe6c5da8d67ac18000" + }, + "08da3a7a0f452161cfbcec311bb68ebfdee17e88": { + "balance": "0x6c6b935b8bbd400000" + }, + "08e38ee0ce48c9ca645c1019f73b5355581c56e6": { + "balance": "0x56bc75e2d631000000" + }, + "08ef3fa4c43ccdc57b22a4b9b2331a82e53818f2": { + "balance": "0xd8d726b7177a800000" + }, + "0909648c18a3ce5bae7a047ec2f868d24cdda81d": { + "balance": "0xcf152640c5c8300000" + }, + "090cd67b60e81d54e7b5f6078f3e021ba65b9a1e": { + "balance": "0x3635c9adc5dea00000" + }, + "090cebef292c3eb081a05fd8aaf7d39bf07b89d4": { + "balance": "0xd8d726b7177a800000" + }, + "090fa9367bda57d0d3253a0a8ff76ce0b8e19a73": { + "balance": "0x3635c9adc5dea00000" + }, + "09146ea3885176f07782e1fe30dce3ce24c49e1f": { + "balance": "0x1158e460913d00000" + }, + "0921605f99164e3bcc28f31caece78973182561d": { + "balance": "0x2b07692a9065a80000" + }, + "09261f9acb451c3788844f0c1451a35bad5098e3": { + "balance": "0x1d5ad27502920600000" + }, + "0927220492194b2eda9fc4bbe38f25d681dfd36c": { + "balance": "0x14542ba12a337c00000" + }, + "092acb624b08c05510189bbbe21e6524d644ccad": { + "balance": "0xfc936392801c0000" + }, + "092e815558402d67f90d6bfe6da0b2fffa91455a": { + "balance": "0x340aad21b3b700000" + }, + "095030e4b82692dcf8b8d0912494b9b378ec9328": { + "balance": "0x48a43c54602f700000" + }, + "095270cc42141dd998ad2862dbd1fe9b44e7e650": { + "balance": "0x410d586a20a4c00000" + }, + "095457f8ef8e2bdc362196b9a9125da09c67e3ab": { + "balance": "0xad78ebc5ac6200000" + }, + "0954a8cb5d321fc3351a7523a617d0f58da676a7": { + "balance": "0x87d9bc7aa498e80000" + }, + "095b0ea2b218d82e0aea7c2889238a39c9bf9077": { + "balance": "0x43c33c1937564800000" + }, + "095b949de3333a377d5019d893754a5e4656ff97": { + "balance": "0x126e72a69a50d00000" + }, + "095e0174829f34c3781be1a5e38d1541ea439b7f": { + "balance": "0x14542ba12a337c00000" + }, + "095f5a51d06f6340d80b6d29ea2e88118ad730fe": { + "balance": "0x6c6e59e67c78540000" + }, + "0968ee5a378f8cadb3bafdbed1d19aaacf936711": { + "balance": "0x3635c9adc5dea00000" + }, + "0977bfba038a44fb49b03970d8d8cf2cb61f8b25": { + "balance": "0x16c4abbebea0100000" + }, + "097da12cfc1f7c1a2464def08c29bed5e2f851e9": { + "balance": "0x1158e460913d00000" + }, + "097ecda22567c2d91cb03f8c5215c22e9dcda949": { + "balance": "0x11651ac3e7a758000" + }, + "0989c200440b878991b69d6095dfe69e33a22e70": { + "balance": "0x678a932062e4180000" + }, + "0990e81cd785599ea236bd1966cf526302c35b9c": { + "balance": "0x3635c9adc5dea00000" + }, + "0998d8273115b56af43c505e087aff0676ed3659": { + "balance": "0xd8d6eddf2d2e180000" + }, + "09a025316f967fa8b9a1d60700063f5a68001caa": { + "balance": "0x21221a99b93ec0000" + }, + "09a928d528ec1b3e25ffc83e218c1e0afe8928c7": { + "balance": "0xfc936392801c0000" + }, + "09ae49e37f121df5dc158cfde806f173a06b0c7f": { + "balance": "0xd8309e26aba1d00000" + }, + "09afa73bc047ef46b977fd9763f87286a6be68c6": { + "balance": "0x1b2fb5e8f06a660000" + }, + "09b4668696f86a080f8bebb91db8e6f87015915a": { + "balance": "0x238ff7b34f60010000" + }, + "09b59b8698a7fbd3d2f8c73a008988de3e406b2b": { + "balance": "0x878678326eac9000000" + }, + "09b7a988d13ff89186736f03fdf46175b53d16e0": { + "balance": "0x14542ba12a337c00000" + }, + "09c177f1ae442411ddacf187d46db956148360e7": { + "balance": "0x1e52e336cde22180000" + }, + "09c88f917e4d6ad473fa12e98ea3c4472a5ed6da": { + "balance": "0x21e19e0c9bab2400000" + }, + "09d0b8cd077c69d9f32d9cca43b3c208a21ed48b": { + "balance": "0x821d221b5291f8000" + }, + "09d6cefd75b0c4b3f8f1d687a522c96123f1f539": { + "balance": "0x14542ba12a337c00000" + }, + "09e437d448861228a232b62ee8d37965a904ed9c": { + "balance": "0x498cf401df8842e8000" + }, + "09ee12b1b42b05af9cf207d5fcac255b2ec411f2": { + "balance": "0x331cddd47e0fe8000" + }, + "09f3f601f605441140586ce0656fa24aa5b1d9ae": { + "balance": "0x5373776fe8c4540000" + }, + "09f9575be57d004793c7a4eb84b71587f97cbb6a": { + "balance": "0xad78ebc5ac6200000" + }, + "0a0650861f785ed8e4bf1005c450bbd06eb48fb6": { + "balance": "0xa6413b79144e7e0000" + }, + "0a06fad7dcd7a492cbc053eeabde6934b39d8637": { + "balance": "0x1158e460913d00000" + }, + "0a077db13ffeb09484c217709d5886b8bf9c5a8b": { + "balance": "0xd8d726b7177a800000" + }, + "0a0ecda6636f7716ef1973614687fd89a820a706": { + "balance": "0x155bd9307f9fe80000" + }, + "0a29a8a4d5fd950075ffb34d77afeb2d823bd689": { + "balance": "0xad78ebc5ac6200000" + }, + "0a2ade95b2e8c66d8ae6f0ba64ca57d783be6d44": { + "balance": "0xd8d726b7177a800000" + }, + "0a2b4fc5d81ace67dc4bba03f7b455413d46fe3d": { + "balance": "0xaadec983fcff40000" + }, + "0a2dcb7a671701dbb8f495728088265873356c8e": { + "balance": "0x83f16ce08a06c0000" + }, + "0a3de155d5ecd8e81c1ff9bbf0378301f8d4c623": { + "balance": "0xd8d726b7177a800000" + }, + "0a47ad9059a249fc936b2662353da6905f75c2b9": { + "balance": "0x6c6b935b8bbd400000" + }, + "0a48296f7631708c95d2b74975bc4ab88ac1392a": { + "balance": "0x10f0cf064dd59200000" + }, + "0a4a011995c681bc999fdd79754e9a324ae3b379": { + "balance": "0x8c19ab06eb89af60000" + }, + "0a58fddd71898de773a74fdae45e7bd84ef43646": { + "balance": "0x1158e460913d00000" + }, + "0a5b79d8f23b6483dbe2bdaa62b1064cc76366ae": { + "balance": "0x6ac882100952c78000" + }, + "0a652e2a8b77bd97a790d0e91361c98890dbb04e": { + "balance": "0x3635c9adc5dea00000" + }, + "0a6ebe723b6ed1f9a86a69ddda68dc47465c2b1b": { + "balance": "0x403d2db599d5e40000" + }, + "0a77e7f72b437b574f00128b21f2ac265133528c": { + "balance": "0x6c6b935b8bbd400000" + }, + "0a917f3b5cb0b883047fd9b6593dbcd557f453b9": { + "balance": "0x3635c9adc5dea00000" + }, + "0a931b449ea8f12cdbd5e2c8cc76bad2c27c0639": { + "balance": "0x13f9e8c79fe058000" + }, + "0a9804137803ba6868d93a55f9985fcd540451e4": { + "balance": "0xb98bc829a6f90000" + }, + "0a9ab2638b1cfd654d25dab018a0aebddf85fd55": { + "balance": "0x12e8cb5fe4c4a8000" + }, + "0ab366e6e7d5abbce6b44a438d69a1cabb90d133": { + "balance": "0x1158e460913d000000" + }, + "0ab4281ebb318590abb89a81df07fa3af904258a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "0ab59d390702c9c059db148eb4f3fcfa7d04c7e7": { + "balance": "0xfc936392801c0000" + }, + "0abfb39b11486d79572866195ba26c630b6784db": { + "balance": "0x19ba8737f96928f00000" + }, + "0aca9a5626913b08cfc9a66d40508dce52b60f87": { + "balance": "0x678a932062e4180000" + }, + "0ad3e44d3c001fa290b393617030544108ac6eb9": { + "balance": "0x6abda0bc30b2df8000" + }, + "0aec2e426ed6cc0cf3c249c1897eac47a7faa9bd": { + "balance": "0xad78ebc5ac6200000" + }, + "0af65f14784e55a6f95667fd73252a1c94072d2a": { + "balance": "0xa763b8e02d44f8000" + }, + "0af6c8d539c96d50259e1ba6719e9c8060f388c2": { + "balance": "0x3635c9adc5dea00000" + }, + "0b06390f2437b20ec4a3d3431b3279c6583e5ed7": { + "balance": "0xa844a7424d9c80000" + }, + "0b0b3862112aeec3a03492b1b05f440eca54256e": { + "balance": "0xd8d726b7177a800000" + }, + "0b0e055b28cbd03dc5ff44aa64f3dce04f5e63fb": { + "balance": "0x6c6b935b8bbd400000" + }, + "0b119df99c6b8de58a1e2c3f297a6744bf552277": { + "balance": "0x6c6b935b8bbd400000" + }, + "0b14891999a65c9ef73308efe3100ca1b20e8192": { + "balance": "0x2b5e3af16b18800000" + }, + "0b2113504534642a1daf102eee10b9ebde76e261": { + "balance": "0x942cdd7c95f2bd8000" + }, + "0b288a5a8b75f3dc4191eb0457e1c83dbd204d25": { + "balance": "0x10714e77bb43ab40000" + }, + "0b369e002e1b4c7913fcf00f2d5e19c58165478f": { + "balance": "0x37f6516288c340000" + }, + "0b43bd2391025581d8956ce42a072579cbbfcb14": { + "balance": "0x104e70464b1580000" + }, + "0b507cf553568daaf65504ae4eaa17a8ea3cdbf5": { + "balance": "0x6c6b935b8bbd400000" + }, + "0b5d66b13c87b392e94d91d5f76c0d450a552843": { + "balance": "0x6c6b935b8bbd400000" + }, + "0b5e2011ebc25a007f21362960498afb8af280fb": { + "balance": "0x6c6b935b8bbd400000" + }, + "0b649da3b96a102cdc6db652a0c07d65b1e443e6": { + "balance": "0x6c6b935b8bbd400000" + }, + "0b6920a64b363b8d5d90802494cf564b547c430d": { + "balance": "0x410d586a20a4c00000" + }, + "0b701101a4109f9cb360dc57b77442673d5e5983": { + "balance": "0x6c6b935b8bbd400000" + }, + "0b71f554122469ef978e2f1fefd7cbb410982772": { + "balance": "0xd255d112e103a00000" + }, + "0b7bb342f01bc9888e6a9af4a887cbf4c2dd2caf": { + "balance": "0x3635c9adc5dea000000" + }, + "0b7d339371e5be6727e6e331b5821fa24bdb9d5a": { + "balance": "0x2e7f81868262010000" + }, + "0b7fc9ddf70576f6330669eaaa71b6a831e99528": { + "balance": "0x796e3ea3f8ab00000" + }, + "0b80fc70282cbdd5fde35bf78984db3bdb120188": { + "balance": "0x3638021cecdab00000" + }, + "0b924df007e9c0878417cfe63b976ea1a382a897": { + "balance": "0x22b1c8c1227a00000" + }, + "0b93fca4a4f09cac20db60e065edcccc11e0a5b6": { + "balance": "0xad78ebc5ac6200000" + }, + "0b9df80fbe232009dacf0aa8cac59376e2476203": { + "balance": "0x6c6b935b8bbd400000" + }, + "0ba6e46af25a13f57169255a34a4dac7ce12be04": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "0ba8705bf55cf219c0956b5e3fc01c4474a6cdc1": { + "balance": "0x525e0595d4d6b8000" + }, + "0baf6ecdb91acb3606a8357c0bc4f45cfd2d7e6f": { + "balance": "0x3635c9adc5dea00000" + }, + "0bb05f7224bb5804856556c07eeadbed87ba8f7c": { + "balance": "0x15be6174e1912e0000" + }, + "0bb0c12682a2f15c9b5741b2385cbe41f034068e": { + "balance": "0x5150ae84a8cdf00000" + }, + "0bb25ca7d188e71e4d693d7b170717d6f8f0a70a": { + "balance": "0x124302a82fadd70000" + }, + "0bb2650ea01aca755bc0c017b64b1ab5a66d82e3": { + "balance": "0x487a9a304539440000" + }, + "0bb54c72fd6610bfa4363397e020384b022b0c49": { + "balance": "0x487a9a304539440000" + }, + "0bb7160aba293762f8734f3e0326ffc9a4cac190": { + "balance": "0x3635c9adc5dea00000" + }, + "0bc95cb32dbb574c832fa8174a81356d38bc92ac": { + "balance": "0x6c6b935b8bbd400000" + }, + "0bd67dbde07a856ebd893b5edc4f3a5be4202616": { + "balance": "0x6c6b935b8bbd400000" + }, + "0bdbc54cc8bdbbb402a08911e2232a5460ce866b": { + "balance": "0xa2a15d09519be00000" + }, + "0bdd58b96e7c916dd2fb30356f2aebfaaf1d8630": { + "balance": "0x6c6b935b8bbd400000" + }, + "0be1bcb90343fae5303173f461bd914a4839056c": { + "balance": "0x14542ba12a337c00000" + }, + "0be1fdf626ee6189102d70d13b31012c95cd1cd6": { + "balance": "0x6c6b935b8bbd400000" + }, + "0be2b94ad950a2a62640c35bfccd6c67dae450f6": { + "balance": "0x692ae8897081d00000" + }, + "0be6a09e4307fe48d412b8d1a1a8284dce486261": { + "balance": "0x40fbff85c0138300000" + }, + "0befb54707f61b2c9fb04715ab026e1bb72042bd": { + "balance": "0xd8d726b7177a800000" + }, + "0bf064428f83626722a7b5b26a9ab20421a7723e": { + "balance": "0x73f75d1a085ba0000" + }, + "0bfbb6925dc75e52cf2684224bbe0550fea685d3": { + "balance": "0x6acb3df27e1f880000" + }, + "0c088006c64b30c4ddafbc36cb5f05469eb62834": { + "balance": "0x6c6b935b8bbd400000" + }, + "0c2073ba44d3ddbdb639c04e191039a71716237f": { + "balance": "0x4d853c8f8908980000" + }, + "0c222c7c41c9b048efcce0a232434362e12d673b": { + "balance": "0x21e8359697677380000" + }, + "0c2808b951ed9e872d7b32790fcc5994ae41ffdc": { + "balance": "0x15996e5b3cd6b3c00000" + }, + "0c28847e4f09dfce5f9b25af7c4e530f59c880fe": { + "balance": "0x3635c9adc5dea00000" + }, + "0c2d5c920538e953caaf24f0737f554cc6927742": { + "balance": "0x3635c9adc5dea00000" + }, + "0c30cacc3f72269f8b4f04cf073d2b05a83d9ad1": { + "balance": "0x6c7974123f64a40000" + }, + "0c3239e2e841242db989a61518c22247e8c55208": { + "balance": "0xe4af6471734640000" + }, + "0c480de9f7461002908b49f60fc61e2b62d3140b": { + "balance": "0x21e19e0c9bab2400000" + }, + "0c48ae62d1539788eba013d75ea60b64eeba4e80": { + "balance": "0x77fbdc43e030998000" + }, + "0c5589a7a89b9ad15b02751930415948a875fbef": { + "balance": "0x6d499ec6c63380000" + }, + "0c67033dd8ee7f0c8ae534d42a51f7d9d4f7978f": { + "balance": "0xad78ebc5ac6200000" + }, + "0c6845bf41d5ee273c3ee6b5b0d69f6fd5eabbf7": { + "balance": "0xa2a1b9682e58090000" + }, + "0c7f869f8e90d53fdc03e8b2819b016b9d18eb26": { + "balance": "0x43c33c1937564800000" + }, + "0c8692eeff2a53d6d1688ed56a9ddbbd68dabba1": { + "balance": "0x6c6b935b8bbd400000" + }, + "0c8f66c6017bce5b20347204b602b743bad78d60": { + "balance": "0x6c6b935b8bbd400000" + }, + "0c8fd7775e54a6d9c9a3bf890e761f6577693ff0": { + "balance": "0x215f835bc769da80000" + }, + "0c925ad5eb352c8ef76d0c222d115b0791b962a1": { + "balance": "0xac635d7fa34e300000" + }, + "0c967e3061b87a753e84507eb60986782c8f3013": { + "balance": "0x56bc75e2d63100000" + }, + "0ca12ab0b9666cf0cec6671a15292f2653476ab2": { + "balance": "0x2c7827c42d22d07c0000" + }, + "0ca670eb2c8b96cba379217f5929c2b892f39ef6": { + "balance": "0x6c6b935b8bbd400000" + }, + "0cae108e6db99b9e637876b064c6303eda8a65c8": { + "balance": "0xa2a15d09519be00000" + }, + "0cbd921dbe121563b98a6871fecb14f1cc7e88d7": { + "balance": "0xad78ebc5ac6200000" + }, + "0cbf8770f0d1082e5c20c5aead34e5fca9ae7ae2": { + "balance": "0x3635c9adc5dea00000" + }, + "0cc67f8273e1bae0867fd42e8b8193d72679dbf8": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "0cd6a141918d126b106d9f2ebf69e102de4d3277": { + "balance": "0x1158e460913d00000" + }, + "0cda12bf72d461bbc479eb92e6491d057e6b5ad1": { + "balance": "0x21e19e0c9bab2400000" + }, + "0cdc960b998c141998160dc179b36c15d28470ed": { + "balance": "0x1b1b6bd7af64c70000" + }, + "0cfb172335b16c87d519cd1475530d20577f5e0e": { + "balance": "0x152d02c7e14af6800000" + }, + "0d1f2a57713ebc6e94de29846e8844d376665763": { + "balance": "0x10f0cf064dd59200000" + }, + "0d3265d3e7bdb93d5e8e8b1ca47f210a793ecc8e": { + "balance": "0xad78ebc5ac6200000" + }, + "0d35408f226566116fb8acdaa9e2c9d59b76683f": { + "balance": "0x32f51edbaaa3300000" + }, + "0d551ec1a2133c981d5fc6a8c8173f9e7c4f47af": { + "balance": "0x6c6b935b8bbd400000" + }, + "0d5d98565c647ca5f177a2adb9d3022fac287f21": { + "balance": "0xad78ebc5ac6200000" + }, + "0d658014a199061cf6b39433140303c20ffd4e5a": { + "balance": "0x1bc85dc2a89bb200000" + }, + "0d678706d037187f3e22e6f69b99a592d11ebc59": { + "balance": "0x55a6e79ccd1d300000" + }, + "0d69100c395ce6c5eaadf95d05d872837ededd21": { + "balance": "0x15af1d78b58c400000" + }, + "0d747ee5969bf79d57381d6fe3a2406cd0d8ce27": { + "balance": "0x152d02c7e14af6800000" + }, + "0d8023929d917234ae40512b1aabb5e8a4512771": { + "balance": "0x805e99fdcc5d00000" + }, + "0d8aab8f74ea862cdf766805009d3f3e42d8d00b": { + "balance": "0x13b80b99c5185700000" + }, + "0d8c40a79e18994ff99ec251ee10d088c3912e80": { + "balance": "0x63664fcd2bbc40000" + }, + "0d8ed7d0d15638330ed7e4eaccab8a458d75737e": { + "balance": "0x6c6b935b8bbd400000" + }, + "0d92582fdba05eabc3e51538c56db8813785b328": { + "balance": "0xa5aa85009e39c0000" + }, + "0d9443a79468a5bbf7c13c6e225d1de91aee07df": { + "balance": "0x3cb71f51fc5580000" + }, + "0d9a825ff2bcd397cbad5b711d9dcc95f1cc112d": { + "balance": "0x2b5e3af16b188000000" + }, + "0d9d3f9bc4a4c6efbd59679b69826bc1f63d9916": { + "balance": "0x2086ac351052600000" + }, + "0da532c910e3ac0dfb14db61cd739a93353fd05f": { + "balance": "0x4878be1ffaf95d0000" + }, + "0da7401262384e2e8b4b26dd154799b55145efa0": { + "balance": "0x1043561a8829300000" + }, + "0dae3ee5b915b36487f9161f19846d101433318a": { + "balance": "0x678a932062e4180000" + }, + "0dbd417c372b8b0d01bcd944706bd32e60ae28d1": { + "balance": "0x126e72a69a50d00000" + }, + "0dc100b107011c7fc0a1339612a16ccec3285208": { + "balance": "0x6c6b935b8bbd400000" + }, + "0dcf9d8c9804459f647c14138ed50fad563b4154": { + "balance": "0x960db77681e940000" + }, + "0dcfe837ea1cf28c65fccec3bef1f84e59d150c0": { + "balance": "0xad78ebc5ac6200000" + }, + "0dd4e674bbadb1b0dc824498713dce3b5156da29": { + "balance": "0x93739534d28680000" + }, + "0dfbd4817050d91d9d625c02053cf61a3ee28572": { + "balance": "0x126e72a69a50d00000" + }, + "0e024e7f029c6aaf3a8b910f5e080873b85795aa": { + "balance": "0x3635c9adc5dea00000" + }, + "0e09646c99af438e99fa274cb2f9c856cb65f736": { + "balance": "0x678a932062e4180000" + }, + "0e0c9d005ea016c295cd795cc9213e87febc33eb": { + "balance": "0xabbcd4ef377580000" + }, + "0e0d6633db1e0c7f234a6df163a10e0ab39c200f": { + "balance": "0xad78ebc5ac6200000" + }, + "0e11d77a8977fac30d268445e531149b31541a24": { + "balance": "0x6c6b935b8bbd400000" + }, + "0e123d7da6d1e6fac2dcadd27029240bb39052fe": { + "balance": "0x3635c9adc5dea00000" + }, + "0e1801e70b6262861b1134ccbc391f568afc92f7": { + "balance": "0xd8d726b7177a800000" + }, + "0e2094ac1654a46ba1c4d3a40bb8c17da7f39688": { + "balance": "0x13683f7f3c15d80000" + }, + "0e21af1b8dbf27fcf63f37e047b87a825cbe7c27": { + "balance": "0xa2a15d09519be00000" + }, + "0e2e504a2d1122b5a9feee5cb1451bf4c2ace87b": { + "balance": "0xd5967be4fc3f100000" + }, + "0e2f8e28a681f77c583bd0ecde16634bdd7e00cd": { + "balance": "0x52738f659bca20000" + }, + "0e320219838e859b2f9f18b72e3d4073ca50b37d": { + "balance": "0x6c6b935b8bbd400000" + }, + "0e33fcbbc003510be35785b52a9c5d216bc005f4": { + "balance": "0x65ea3db75546600000" + }, + "0e3696cf1f4217b163d1bc12a5ea730f1c32a14a": { + "balance": "0xd8d726b7177a800000" + }, + "0e390f44053ddfcef0d608b35e4d9c2cbe9871bb": { + "balance": "0x6acb3df27e1f880000" + }, + "0e3a28c1dfafb0505bdce19fe025f506a6d01ceb": { + "balance": "0x6c6b935b8bbd400000" + }, + "0e3dd7d4e429fe3930a6414035f52bdc599d784d": { + "balance": "0x22ca3587cf4eb0000" + }, + "0e4765790352656bc656682c24fc5ef3e76a23c7": { + "balance": "0x286d7fc0cb4f50000" + }, + "0e498800447177b8c8afc3fdfa7f69f4051bb629": { + "balance": "0x7405b69b8de5610000" + }, + "0e6baaa3deb989f289620076668618e9ac332865": { + "balance": "0xad78ebc5ac6200000" + }, + "0e6cd664ad9c1ed64bf98749f40644b626e3792c": { + "balance": "0xcb49b44ba602d800000" + }, + "0e6dfd553b2e873d2aec15bd5fbb3f8472d8d394": { + "balance": "0x28a857425466f800000" + }, + "0e6ec313376271dff55423ab5422cc3a8b06b22b": { + "balance": "0xd8d726b7177a800000" + }, + "0e6ece99111cad1961c748ed3df51edd69d2a3b1": { + "balance": "0x152d02c7e14af6800000" + }, + "0e83b850481ab44d49e0a229a2e464902c69539b": { + "balance": "0x56bc75e2d63100000" + }, + "0e89eddd3fa0d71d8ab0ff8da5580686e3d4f74f": { + "balance": "0x6c6b935b8bbd400000" + }, + "0e9096d343c060db581a120112b278607ec6e52b": { + "balance": "0x1158e460913d00000" + }, + "0e9c511864a177f49be78202773f60489fe04e52": { + "balance": "0x14542ba12a337c00000" + }, + "0ea2a210312b3e867ee0d1cc682ce1d666f18ed5": { + "balance": "0x21e19e0c9bab2400000" + }, + "0eb189ef2c2d5762a963d6b7bdf9698ea8e7b48a": { + "balance": "0x487a9a304539440000" + }, + "0eb5b662a1c718608fd52f0c25f9378830178519": { + "balance": "0x14a37281a612e740000" + }, + "0ec46696ffac1f58005fa8439824f08eed1df89b": { + "balance": "0x21e19e0c9bab2400000" + }, + "0ec50aa823f465b9464b0bc0c4a57724a555f5d6": { + "balance": "0xc83d1426ac7b1f00000" + }, + "0ec5308b31282e218fc9e759d4fec5db3708cec4": { + "balance": "0x3643aa647986040000" + }, + "0eccf617844fd61fba62cb0e445b7ac68bcc1fbe": { + "balance": "0x14fe4fe63565c60000" + }, + "0ed3bb3a4eb554cfca97947d575507cdfd6d21d8": { + "balance": "0x1db3205fcc23d58000" + }, + "0ed76c2c3b5d50ff8fb50b3eeacd681590be1c2d": { + "balance": "0x56bc75e2d63100000" + }, + "0eda80f4ed074aea697aeddf283b63dbca3dc4da": { + "balance": "0x6c6b935b8bbd400000" + }, + "0edd4b580ff10fe06c4a03116239ef96622bae35": { + "balance": "0xaadec983fcff40000" + }, + "0ee391f03c765b11d69026fd1ab35395dc3802a0": { + "balance": "0xad78ebc5ac6200000" + }, + "0ee414940487fd24e390378285c5d7b9334d8b65": { + "balance": "0x914878a8c05ee00000" + }, + "0ef54ac7264d2254abbb5f8b41adde875157db7c": { + "balance": "0x22b1c8c1227a00000" + }, + "0ef85b49d08a75198692914eddb4b22cf5fa4450": { + "balance": "0x6cae30621d47200000" + }, + "0efd1789eb1244a3dede0f5de582d8963cb1f39f": { + "balance": "0x5150ae84a8cdf00000" + }, + "0f042c9c2fb18766f836bb59f735f27dc329fe3c": { + "balance": "0x21e19e0c9bab2400000" + }, + "0f049a8bdfd761de8ec02cee2829c4005b23c06b": { + "balance": "0xda933d8d8c6700000" + }, + "0f05f120c89e9fbc93d4ab0c5e2b4a0df092b424": { + "balance": "0x65a4da25d3016c00000" + }, + "0f127bbf8e311caea2ba502a33feced3f730ba42": { + "balance": "0xa31062beeed700000" + }, + "0f1c249cd962b00fd114a9349f6a6cc778d76c4d": { + "balance": "0x6c6b935b8bbd400000" + }, + "0f206e1a1da7207ea518b112418baa8b06260328": { + "balance": "0x2086ac351052600000" + }, + "0f24105abbdaa03fa6309ef6c188e51f714a6e59": { + "balance": "0xad78ebc5ac6200000" + }, + "0f26480a150961b8e30750713a94ee6f2e47fc00": { + "balance": "0x3635c9adc5dea00000" + }, + "0f2d8daf04b5414a0261f549ff6477b80f2f1d07": { + "balance": "0x2a5a058fc295ed000000" + }, + "0f2fb884c8aaff6f543ac6228bd08e4f60b0a5fd": { + "balance": "0xaa7da485136b840000" + }, + "0f32d9cb4d0fdaa0150656bb608dcc43ed7d9301": { + "balance": "0x28df8bf440db790000" + }, + "0f3665d48e9f1419cd984fc7fa92788710c8f2e4": { + "balance": "0x6c6b935b8bbd400000" + }, + "0f3a1023cac04dbf44f5a5fa6a9cf8508cd4fddf": { + "balance": "0x62a992e53a0af00000" + }, + "0f4073c1b99df60a1549d69789c7318d9403a814": { + "balance": "0x43c33c1937564800000" + }, + "0f46c81db780c1674ac73d314f06539ee56ebc83": { + "balance": "0x215f835bc769da80000" + }, + "0f4f94b9191bb7bb556aaad7c74ddb288417a50b": { + "balance": "0x4be4e7267b6ae00000" + }, + "0f6000de1578619320aba5e392706b131fb1de6f": { + "balance": "0x1b1ab319f5ec750000" + }, + "0f6e840a3f2a24647d8e43e09d45c7c335df4248": { + "balance": "0x878678326eac900000" + }, + "0f7515ff0e808f695e0c20485ff96ed2f7b79310": { + "balance": "0x3638221660a5aa8000" + }, + "0f789e30397c53bf256fc364e6ef39f853504114": { + "balance": "0xc55325ca7415e00000" + }, + "0f7b61c59b016322e8226cafaee9d9e76d50a1b3": { + "balance": "0xd8d726b7177a800000" + }, + "0f7bea4ef3f73ae0233df1e100718cbe29310bb0": { + "balance": "0x6c6b935b8bbd400000" + }, + "0f7bf6373f771a4601762c4dae5fbbf4fedd9cc9": { + "balance": "0x6c6b935b8bbd400000" + }, + "0f832a93df9d7f74cd0fb8546b7198bf5377d925": { + "balance": "0x7c0860e5a80dc0000" + }, + "0f83461ba224bb1e8fdd9dae535172b735acb4e0": { + "balance": "0xad78ebc5ac6200000" + }, + "0f85e42b1df321a4b3e835b50c00b06173968436": { + "balance": "0x35659ef93f0fc40000" + }, + "0f88aac9346cb0e7347fba70905475ba8b3e5ece": { + "balance": "0x21e19e0c9bab2400000" + }, + "0f929cf895db017af79f3ead2216b1bd69c37dc7": { + "balance": "0x6c6b935b8bbd400000" + }, + "0fa010ce0c731d3b628e36b91f571300e49dbeab": { + "balance": "0x36330322d5238c0000" + }, + "0fa5d8c5b3f294efd495ab69d768f81872508548": { + "balance": "0x6c6b935b8bbd400000" + }, + "0fa6c7b0973d0bae2940540e247d3627e37ca347": { + "balance": "0x3635c9adc5dea00000" + }, + "0fad05507cdc8f24b2be4cb7fa5d927ddb911b88": { + "balance": "0xa2df13f441f0098000" + }, + "0fb5d2c673bfb1ddca141b9894fd6d3f05da6720": { + "balance": "0x56bc75e2d63100000" + }, + "0fc9a0e34145fbfdd2c9d2a499b617d7a02969b9": { + "balance": "0x9c2007651b2500000" + }, + "0fcfc4065008cfd323305f6286b57a4dd7eee23b": { + "balance": "0x43c33c1937564800000" + }, + "0fdd65402395df9bd19fee4507ef5345f745104c": { + "balance": "0x10f0cf064dd59200000" + }, + "0fec4ee0d7ca180290b6bd20f9992342f60ff68d": { + "balance": "0x12207f0edce9718000" + }, + "0fee81ac331efd8f81161c57382bb4507bb9ebec": { + "balance": "0x15af880d8cdb830000" + }, + "0ffea06d7113fb6aec2869f4a9dfb09007facef4": { + "balance": "0xc384681b1e1740000" + }, + "10097198b4e7ee91ff82cc2f3bd95fed73c540c0": { + "balance": "0x6c6b935b8bbd400000" + }, + "100b4d0977fcbad4debd5e64a0497aeae5168fab": { + "balance": "0x110c9073b5245a0000" + }, + "101a0a64f9afcc448a8a130d4dfcbee89537d854": { + "balance": "0x337fe5feaf2d1800000" + }, + "102c477d69aadba9a0b0f62b7459e17fbb1c1561": { + "balance": "0x6c6b935b8bbd400000" + }, + "1031e0ecb54985ae21af1793950dc811888fde7c": { + "balance": "0x1158e460913d00000" + }, + "10346414bec6d3dcc44e50e54d54c2b8c3734e3e": { + "balance": "0xd8d726b7177a800000" + }, + "10389858b800e8c0ec32f51ed61a355946cc409b": { + "balance": "0xad78ebc5ac6200000" + }, + "1059cbc63e36c43e88f30008aca7ce058eeaa096": { + "balance": "0x152d02c7e14af6800000" + }, + "106ed5c719b5261477890425ae7551dc59bd255c": { + "balance": "0x2896a58c95be5880000" + }, + "10711c3dda32317885f0a2fd8ae92e82069b0d0b": { + "balance": "0xd8d726b7177a800000" + }, + "107379d4c467464f235bc18e55938aad3e688ad7": { + "balance": "0x2b5e3af16b1880000" + }, + "1076212d4f758c8ec7121c1c7d74254926459284": { + "balance": "0x7695b59b5c17b4c0000" + }, + "1078d7f61b0e56c74ee6635b2e1819ef1e3d8785": { + "balance": "0x3635c9adc5dea00000" + }, + "107a03cf0842dbdeb0618fb587ca69189ec92ff5": { + "balance": "0x6acb3df27e1f880000" + }, + "1080c1d8358a15bc84dac8253c6883319020df2c": { + "balance": "0x90f534608a72880000" + }, + "108a2b7c336f784779d8b54d02a8d31d9a139c0a": { + "balance": "0x21e19e0c9bab2400000" + }, + "108ba7c2895c50e072dc6f964932d50c282d3034": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "108fe8ee2a13da487b22c6ab6d582ea71064d98c": { + "balance": "0x15ac56edc4d12c0000" + }, + "1091176be19b9964a8f72e0ece6bf8e3cfad6e9c": { + "balance": "0x21f2f6f0fc3c6100000" + }, + "1098c774c20ca1daac5ddb620365316d353f109c": { + "balance": "0x56bc75e2d63100000" + }, + "1098cc20ef84bad5146639c4cd1ca6c3996cb99b": { + "balance": "0xfc936392801c0000" + }, + "10a1c42dc1ba746986b985a522a73c93eae64c63": { + "balance": "0x3635c9adc5dea00000" + }, + "10a93457496f1108cd98e140a1ecdbae5e6de171": { + "balance": "0x15a99062d416180000" + }, + "10b5b34d1248fcf017f8c8ffc408ce899ceef92f": { + "balance": "0xe7eeba3410b740000" + }, + "10cf560964ff83c1c9674c783c0f73fcd89943fc": { + "balance": "0x878678326eac9000000" + }, + "10d32416722ca4e648630548ead91edd79c06aff": { + "balance": "0x56bc75e2d63100000" + }, + "10d945334ecde47beb9ca3816c173dfbbd0b5333": { + "balance": "0x4be4e7267b6ae00000" + }, + "10df681506e34930ac7a5c67a54c3e89ce92b981": { + "balance": "0x74c1fab8adb4540000" + }, + "10e1e3377885c42d7df218522ee7766887c05e6a": { + "balance": "0x1043c43cde1d398000" + }, + "10e390ad2ba33d82b37388d09c4544c6b0225de5": { + "balance": "0xad78ebc5ac6200000" + }, + "10f4bff0caa5027c0a6a2dcfc952824de2940909": { + "balance": "0x6c6b935b8bbd400000" + }, + "11001b89ed873e3aaec1155634b4681643986323": { + "balance": "0x3635c9adc5dea00000" + }, + "110237cf9117e767922fc4a1b78d7964da82df20": { + "balance": "0xd5967be4fc3f100000" + }, + "1111e5dbf45e6f906d62866f1708101788ddd571": { + "balance": "0x467be6533ec2e40000" + }, + "11172b278ddd44eea2fdf4cb1d16962391c453d9": { + "balance": "0xc62f3d9bfd4895f00000" + }, + "112634b4ec30ff786e024159f796a57939ea144e": { + "balance": "0x6c6acc67d7b1d40000" + }, + "11306c7d57588637780fc9fde8e98ecb008f0164": { + "balance": "0x6c6acc67d7b1d40000" + }, + "113612bc3ba0ee4898b49dd20233905f2f458f62": { + "balance": "0x2f6f10780d22cc00000" + }, + "11415fab61e0dfd4b90676141a557a869ba0bde9": { + "balance": "0x6f05b59d3b20000000" + }, + "114cbbbf6fb52ac414be7ec61f7bb71495ce1dfa": { + "balance": "0xa2a15d09519be00000" + }, + "114cfefe50170dd97ae08f0a44544978c599548d": { + "balance": "0x2ec887e7a14a1c0000" + }, + "116108c12084612eeda7a93ddcf8d2602e279e5c": { + "balance": "0x6c6b935b8bbd400000" + }, + "1164caaa8cc5977afe1fad8a7d6028ce2d57299b": { + "balance": "0x15af1d78b58c400000" + }, + "11675a25554607a3b6c92a9ee8f36f75edd3e336": { + "balance": "0x8a9aba557e36c0000" + }, + "116a09df66cb150e97578e297fb06e13040c893c": { + "balance": "0x6c6b935b8bbd400000" + }, + "116fef5e601642c918cb89160fc2293ba71da936": { + "balance": "0x2b7cc2e9c3225c0000" + }, + "1178501ff94add1c5881fe886136f6dfdbe61a94": { + "balance": "0x890b0c2e14fb80000" + }, + "1179c60dbd068b150b074da4be23033b20c68558": { + "balance": "0x24dce54d34a1a00000" + }, + "117d9aa3c4d13bee12c7500f09f5dd1c66c46504": { + "balance": "0xb2ad30490b2780000" + }, + "117db836377fe15455e02c2ebda40b1ceb551b19": { + "balance": "0x14542ba12a337c00000" + }, + "118c18b2dce170e8f445753ba5d7513cb7636d2d": { + "balance": "0x1dd0c885f9a0d800000" + }, + "118fbd753b9792395aef7a4d78d263cdcaabd4f7": { + "balance": "0x36330322d5238c0000" + }, + "11928378d27d55c520ceedf24ceb1e822d890df0": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "119aa64d5b7d181dae9d3cb449955c89c1f963fa": { + "balance": "0x25f273933db5700000" + }, + "11c0358aa6479de21866fe21071924b65e70f8b9": { + "balance": "0x7b53f79e888dac00000" + }, + "11d2247a221e70c2d66d17ee138d38c55ffb8640": { + "balance": "0x21e19e0c9bab2400000" + }, + "11d7844a471ef89a8d877555583ceebd1439ea26": { + "balance": "0x22369e6ba80c6880000" + }, + "11dd6185d9a8d73ddfdaa71e9b7774431c4dfec2": { + "balance": "0x3635c9adc5dea00000" + }, + "11e7997edd904503d77da6038ab0a4c834bbd563": { + "balance": "0x150894e849b3900000" + }, + "11ec00f849b6319cf51aa8dd8f66b35529c0be77": { + "balance": "0x6c6b935b8bbd400000" + }, + "11efb8a20451161b644a8ccebbc1d343a3bbcb52": { + "balance": "0xad78ebc5ac62000000" + }, + "11fefb5dc1a4598aa712640c517775dfa1d91f8c": { + "balance": "0x21e19e0c9bab2400000" + }, + "120f9de6e0af7ec02a07c609ca8447f157e6344c": { + "balance": "0xe7eeba3410b740000" + }, + "1210f80bdb826c175462ab0716e69e46c24ad076": { + "balance": "0x56bc75e2d63100000" + }, + "12134e7f6b017bf48e855a399ca58e2e892fa5c8": { + "balance": "0x3635c9adc5dea00000" + }, + "12173074980153aeaa4b0dcbc7132eadcec21b64": { + "balance": "0xd02ab486cedc00000" + }, + "121f855b70149ac83473b9706fb44d47828b983b": { + "balance": "0x4be4e7267b6ae00000" + }, + "1227e10a4dbf9caca31b1780239f557615fc35c1": { + "balance": "0xad78ebc5ac6200000" + }, + "122dcfd81addb97d1a0e4925c4b549806e9f3beb": { + "balance": "0x522035cc6e01210000" + }, + "122f56122549d168a5c5e267f52662e5c5cce5c8": { + "balance": "0xa076407d3f7440000" + }, + "12316fc7f178eac22eb2b25aedeadf3d75d00177": { + "balance": "0x43c33be05f6bfb98000" + }, + "123759f333e13e3069e2034b4f05398918119d36": { + "balance": "0x43c33c1937564800000" + }, + "125cc5e4d56b2bcc2ee1c709fb9e68fb177440bd": { + "balance": "0x6c6b935b8bbd400000" + }, + "12632388b2765ee4452b50161d1fffd91ab81f4a": { + "balance": "0x281d901f4fdd100000" + }, + "126897a311a14ad43b78e0920100c4426bfd6bdd": { + "balance": "0x34c726893f2d948000" + }, + "126d91f7ad86debb0557c612ca276eb7f96d00a1": { + "balance": "0x56bc75e2d63100000" + }, + "127d3fc5003bf63c0d83e93957836515fd279045": { + "balance": "0x610c9222e6e750000" + }, + "127db1cadf1b771cbd7475e1b272690f558c8565": { + "balance": "0x2f6f10780d22cc00000" + }, + "1284f0cee9d2ff2989b65574d06ffd9ab0f7b805": { + "balance": "0x15af1d78b58c400000" + }, + "128b908fe743a434203de294c441c7e20a86ea67": { + "balance": "0x26ab14e0c0e13c0000" + }, + "1293c78c7d6a443b9d74b0ba5ee7bb47fd418588": { + "balance": "0x16a6502f15a1e540000" + }, + "1296acded1e063af39fe8ba0b4b63df789f70517": { + "balance": "0x56bf91b1a65eb0000" + }, + "12aa7d86ddfbad301692feac8a08f841cb215c37": { + "balance": "0x76d41c62494840000" + }, + "12afbcba1427a6a39e7ba4849f7ab1c4358ac31b": { + "balance": "0x43c33c1937564800000" + }, + "12b5e28945bb2969f9c64c63cc05b6f1f8d6f4d5": { + "balance": "0x1a29e86913b74050000" + }, + "12cf8b0e465213211a5b53dfb0dd271a282c12c9": { + "balance": "0xd2f13f7789f00000" + }, + "12d20790b7d3dbd88c81a279b812039e8a603bd0": { + "balance": "0x56f985d38644b80000" + }, + "12d60d65b7d9fc48840be5f891c745ce76ee501e": { + "balance": "0x485e5388d0c76840000" + }, + "12d91a92d74fc861a729646db192a125b79f5374": { + "balance": "0xfc936392801c0000" + }, + "12e9a4ad2ad57484dd700565bddb46423bd9bd31": { + "balance": "0x43c30fb0884a96c0000" + }, + "12f32c0a1f2daab676fe69abd9e018352d4ccd45": { + "balance": "0x2b5e3af16b1880000" + }, + "12f460ae646cd2780fd35c50a6af4b9accfa85c6": { + "balance": "0x3635c9adc5dea00000" + }, + "12ffc1128605cb0c13709a7290506f2690977193": { + "balance": "0xb50fcfafebecb00000" + }, + "13032446e7d610aa00ec8c56c9b574d36ca1c016": { + "balance": "0x6c6b935b8bbd400000" + }, + "131c792c197d18bd045d7024937c1f84b60f4438": { + "balance": "0xd8d726b7177a800000" + }, + "131df8d330eb7cc7147d0a55576f05de8d26a8b7": { + "balance": "0xa31062beeed700000" + }, + "131faed12561bb7aee04e5185af802b1c3438d9b": { + "balance": "0xbdf3c4bb0328c0000" + }, + "1321b605026f4ffb296a3e0edcb390c9c85608b7": { + "balance": "0x6c6b935b8bbd400000" + }, + "1321ccf29739b974e5a516f18f3a843671e39642": { + "balance": "0xd8d726b7177a800000" + }, + "1327d759d56e0ab87af37ecf63fe01f310be100a": { + "balance": "0x23bc3cdb68a1800000" + }, + "1329dd19cd4baa9fc64310efeceab22117251f12": { + "balance": "0xad78ebc5ac6200000" + }, + "13371f92a56ea8381e43059a95128bdc4d43c5a6": { + "balance": "0x3635c9adc5dea00000" + }, + "133c490fa5bf7f372888e607d958fab7f955bae1": { + "balance": "0x55a6e79ccd1d300000" + }, + "133e4f15e1e39c53435930aaedf3e0fe56fde843": { + "balance": "0x1158e460913d00000" + }, + "134163be9fbbe1c5696ee255e90b13254395c318": { + "balance": "0xad78ebc5ac6200000" + }, + "135cecd955e5798370769230159303d9b1839f66": { + "balance": "0x10f0cf064dd59200000" + }, + "135d1719bf03e3f866312479fe338118cd387e70": { + "balance": "0x6c6b935b8bbd400000" + }, + "135eb8c0e9e101deedec11f2ecdb66ae1aae8867": { + "balance": "0x43c33c1937564800000" + }, + "1360e87df24c69ee6d51c76e73767ffe19a2131c": { + "balance": "0x4fcc1a89027f00000" + }, + "136c834bf111326d207395295b2e583ea7f33572": { + "balance": "0x56bc75e2d63100000" + }, + "136d4b662bbd1080cfe4445b0fa213864435b7f1": { + "balance": "0xd8d726b7177a800000" + }, + "136f4907cab41e27084b9845069ff2fd0c9ade79": { + "balance": "0xd8d726b7177a800000" + }, + "1374facd7b3f8d68649d60d4550ee69ff0484133": { + "balance": "0xe9ed6e11172da0000" + }, + "137cf341e8516c815814ebcd73e6569af14cf7bc": { + "balance": "0x3635c9adc5dea00000" + }, + "13848b46ea75beb7eaa85f59d866d77fd24cf21a": { + "balance": "0xa968163f0a57b400000" + }, + "139d3531c9922ad56269f6309aa789fb2485f98c": { + "balance": "0xd8d726b7177a800000" + }, + "139e479764b499d666208c4a8a047a97043163dd": { + "balance": "0x2077212aff6df00000" + }, + "13a5eecb38305df94971ef2d9e179ae6cebab337": { + "balance": "0x11e3ab8395c6e80000" + }, + "13acada8980affc7504921be84eb4944c8fbb2bd": { + "balance": "0x56d2aa3a5c09a00000" + }, + "13b9b10715714c09cfd610cf9c9846051cb1d513": { + "balance": "0x6acb3df27e1f880000" + }, + "13ce332dff65a6ab933897588aa23e000980fa82": { + "balance": "0xe020536f028f00000" + }, + "13d67a7e25f2b12cdb85585009f8acc49b967301": { + "balance": "0x6c6acc67d7b1d40000" + }, + "13dee03e3799952d0738843d4be8fc0a803fb20e": { + "balance": "0x6c6b935b8bbd400000" + }, + "13e02fb448d6c84ae17db310ad286d056160da95": { + "balance": "0x6c6b935b8bbd400000" + }, + "13e321728c9c57628058e93fc866a032dd0bda90": { + "balance": "0x26bcca23fe2ea20000" + }, + "13ec812284026e409bc066dfebf9d5a4a2bf801e": { + "balance": "0x57473d05dabae80000" + }, + "140129eaa766b5a29f5b3af2574e4409f8f6d3f1": { + "balance": "0x15af1d78b58c4000000" + }, + "140518a3194bad1350b8949e650565debe6db315": { + "balance": "0x6c6b935b8bbd400000" + }, + "1406854d149e081ac09cb4ca560da463f3123059": { + "balance": "0x487a9a304539440000" + }, + "140ca28ff33b9f66d7f1fc0078f8c1eef69a1bc0": { + "balance": "0x56bc75e2d631000000" + }, + "140fba58dbc04803d84c2130f01978f9e0c73129": { + "balance": "0x15af1d78b58c400000" + }, + "141a5e39ee2f680a600fbf6fa297de90f3225cdd": { + "balance": "0x21e19e0c9bab2400000" + }, + "14254ea126b52d0142da0a7e188ce255d8c47178": { + "balance": "0x2a034919dfbfbc0000" + }, + "142b87c5043ffb5a91df18c2e109ced6fe4a71db": { + "balance": "0xad78ebc5ac6200000" + }, + "143c639752caeecf6a997d39709fc8f19878c7e8": { + "balance": "0x6acb3df27e1f880000" + }, + "143d536b8b1cb84f56a39e0bc81fd5442bcacce1": { + "balance": "0x56bc75e2d63100000" + }, + "143f5f1658d9e578f4f3d95f80c0b1bd3933cbda": { + "balance": "0x50c5e761a444080000" + }, + "14410fb310711be074a80883c635d0ef6afb2539": { + "balance": "0x6c6b935b8bbd400000" + }, + "144b19f1f66cbe318347e48d84b14039466c5909": { + "balance": "0x6c6b935b8bbd400000" + }, + "145250b06e4fa7cb2749422eb817bdda8b54de5f": { + "balance": "0xbdf3c4bb0328c0000" + }, + "145e0600e2a927b2dd8d379356b45a2e7d51d3ae": { + "balance": "0x8a02ab400bb2cb8000" + }, + "145e1de0147911ccd880875fbbea61f6a142d11d": { + "balance": "0xd8d726b7177a800000" + }, + "1463a873555bc0397e575c2471cf77fa9db146e0": { + "balance": "0x21e19e0c9bab2400000" + }, + "1479a9ec7480b74b5db8fc499be352da7f84ee9c": { + "balance": "0x3635c9adc5dea00000" + }, + "147af46ae9ccd18bb35ca01b353b51990e49dce1": { + "balance": "0xd8d726b7177a800000" + }, + "147f4210ab5804940a0b7db8c14c28396b62a6bf": { + "balance": "0x6c6b935b8bbd400000" + }, + "14830704e99aaad5c55e1f502b27b22c12c91933": { + "balance": "0x219c3a7b1966300000" + }, + "149b6dbde632c19f5af47cb493114bebd9b03c1f": { + "balance": "0x28a857425466f800000" + }, + "149ba10f0da2725dc704733e87f5a524ca88515e": { + "balance": "0x1ab2cf7c9f87e200000" + }, + "14a7352066364404db50f0d0d78d754a22198ef4": { + "balance": "0x65ea3db75546600000" + }, + "14ab164b3b524c82d6abfbc0de831126ae8d1375": { + "balance": "0x6c6b935b8bbd400000" + }, + "14b1603ec62b20022033eec4d6d6655ac24a015a": { + "balance": "0x2b5e3af16b1880000" + }, + "14c63ba2dcb1dd4df33ddab11c4f0007fa96a62d": { + "balance": "0x34841b6057afab00000" + }, + "14cdddbc8b09e6675a9e9e05091cb92238c39e1e": { + "balance": "0x11478b7c30abc300000" + }, + "14d00aad39a0a7d19ca05350f7b03727f08dd82e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "14eec09bf03e352bd6ff1b1e876be664ceffd0cf": { + "balance": "0x116dc3a8994b30000" + }, + "14f221159518783bc4a706676fc4f3c5ee405829": { + "balance": "0xad78ebc5ac6200000" + }, + "14fcd1391e7d732f41766cdacd84fa1deb9ffdd2": { + "balance": "0x6c6b935b8bbd400000" + }, + "150e3dbcbcfc84ccf89b73427763a565c23e60d0": { + "balance": "0x22b1c8c1227a00000" + }, + "1518627b88351fede796d3f3083364fbd4887b0c": { + "balance": "0x3635c9adc5dea000000" + }, + "15224ad1c0face46f9f556e4774a3025ad06bd52": { + "balance": "0xb98bc829a6f90000" + }, + "152f2bd229ddf3cb0fdaf455c183209c0e1e39a2": { + "balance": "0x6c6b935b8bbd400000" + }, + "152f4e860ef3ee806a502777a1b8dbc91a907668": { + "balance": "0x2086ac351052600000" + }, + "153c08aa8b96a611ef63c0253e2a4334829e579d": { + "balance": "0x155bd9307f9fe80000" + }, + "153cf2842cb9de876c276fa64767d1a8ecf573bb": { + "balance": "0x6c6b935b8bbd400000" + }, + "153ef58a1e2e7a3eb6b459a80ab2a547c94182a2": { + "balance": "0x14542ba12a337c000000" + }, + "154459fa2f21318e3434449789d826cdc1570ce5": { + "balance": "0x6c6b935b8bbd400000" + }, + "1547b9bf7ad66274f3413827231ba405ee8c88c1": { + "balance": "0x3a9d5baa4abf1d00000" + }, + "1548b770a5118ede87dba2f690337f616de683ab": { + "balance": "0x1c995685e0bf870000" + }, + "15528350e0d9670a2ea27f7b4a33b9c0f9621d21": { + "balance": "0xd8d8583fa2d52f0000" + }, + "155b3779bb6d56342e2fda817b5b2d81c7f41327": { + "balance": "0x2b8aa3a076c9c0000" + }, + "1565af837ef3b0bd4e2b23568d5023cd34b16498": { + "balance": "0x1551e9724ac4ba0000" + }, + "15669180dee29598869b08a721c7d24c4c0ee63f": { + "balance": "0x3635c9adc5dea00000" + }, + "1572cdfab72a01ce968e78f5b5448da29853fbdd": { + "balance": "0x112626c49060fa60000" + }, + "157559adc55764cc6df79323092534e3d6645a66": { + "balance": "0x14542ba12a337c00000" + }, + "1578bdbc371b4d243845330556fff2d5ef4dff67": { + "balance": "0x56bc75e2d63100000" + }, + "157eb3d3113bd3b597714d3a954edd018982a5cb": { + "balance": "0x6c6b935b8bbd400000" + }, + "1584a2c066b7a455dbd6ae2807a7334e83c35fa5": { + "balance": "0x70c1cc73b00c80000" + }, + "15874686b6733d10d703c9f9bec6c52eb8628d67": { + "balance": "0x6c6b935b8bbd400000" + }, + "158a0d619253bf4432b5cd02c7b862f7c2b75636": { + "balance": "0x75bac7c5b12188000" + }, + "1598127982f2f8ad3b6b8fc3cf27bf617801ba2b": { + "balance": "0x960db77681e940000" + }, + "159adce27aa10b47236429a34a5ac42cad5b6416": { + "balance": "0x6bf90a96edbfa718000" + }, + "15a0aec37ff9ff3d5409f2a4f0c1212aaccb0296": { + "balance": "0x3635c9adc5dea00000" + }, + "15aa530dc36958b4edb38eee6dd9e3c77d4c9145": { + "balance": "0x6c6b935b8bbd400000" + }, + "15acb61568ec4af7ea2819386181b116a6c5ee70": { + "balance": "0x690836c0af5f5600000" + }, + "15b96f30c23b8664e7490651066b00c4391fbf84": { + "balance": "0x1642e9df4876290000" + }, + "15c7edb8118ee27b342285eb5926b47a855bc7a5": { + "balance": "0x1158e460913d00000" + }, + "15d99468507aa0413fb60dca2adc7f569cb36b54": { + "balance": "0x6c6b935b8bbd400000" + }, + "15dbb48c98309764f99ced3692dcca35ee306bac": { + "balance": "0x1fc3842bd1f071c00000" + }, + "15dcafcc2bace7b55b54c01a1c514626bf61ebd8": { + "balance": "0x1fd933494aa5fe00000" + }, + "15e3b584056b62c973cf5eb096f1733e54c15c91": { + "balance": "0x32c75a0223ddf30000" + }, + "15ebd1c7cad2aff19275c657c4d808d010efa0f5": { + "balance": "0xadf30ba70c8970000" + }, + "15ee0fc63ebf1b1fc49d7bb38f8863823a2e17d2": { + "balance": "0x678a932062e4180000" + }, + "15f1b352110d68901d8f67aac46a6cfafe031477": { + "balance": "0xad78ebc5ac6200000" + }, + "15f2b7b16432ee50a5f55b41232f6334ed58bdc0": { + "balance": "0x15af1d78b58c400000" + }, + "16019a4dafab43f4d9bf4163fae0847d848afca2": { + "balance": "0x15bc70139f74a0000" + }, + "160226efe7b53a8af462d117a0108089bdecc2d1": { + "balance": "0xadf30ba70c8970000" + }, + "160ceb6f980e04315f53c4fc988b2bf69e284d7d": { + "balance": "0x10910d4cdc9f60000" + }, + "161caf5a972ace8379a6d0a04ae6e163fe21df2b": { + "balance": "0x152d02c7e14af6800000" + }, + "161d26ef6759ba5b9f20fdcd66f16132c352415e": { + "balance": "0x6c6b935b8bbd400000" + }, + "162110f29eac5f7d02b543d8dcd5bb59a5e33b73": { + "balance": "0x6c6b935b8bbd400000" + }, + "162ba503276214b509f97586bd842110d103d517": { + "balance": "0x1e7ffd8895c22680000" + }, + "162d76c2e6514a3afb6fe3d3cb93a35c5ae783f1": { + "balance": "0x6c6b935b8bbd400000" + }, + "163bad4a122b457d64e8150a413eae4d07023e6b": { + "balance": "0x104e70464b1580000" + }, + "163cc8be227646cb09719159f28ed09c5dc0dce0": { + "balance": "0x487a9a304539440000" + }, + "163dca73d7d6ea3f3e6062322a8734180c0b78ef": { + "balance": "0x9f742003cb7dfc0000" + }, + "164d7aac3eecbaeca1ad5191b753f173fe12ec33": { + "balance": "0x285652b8a468690000" + }, + "16526c9edf943efa4f6d0f0bae81e18b31c54079": { + "balance": "0x35659ef93f0fc40000" + }, + "165305b787322e25dc6ad0cefe6c6f334678d569": { + "balance": "0x6c6b935b8bbd400000" + }, + "1665ab1739d71119ee6132abbd926a279fe67948": { + "balance": "0x56bc75e2d63100000" + }, + "166bf6dab22d841b486c38e7ba6ab33a1487ed8c": { + "balance": "0x43c33c1937564800000" + }, + "167699f48a78c615512515739958993312574f07": { + "balance": "0x21d3bd55e803c0000" + }, + "1678c5f2a522393225196361894f53cc752fe2f3": { + "balance": "0x68f365aea1e4400000" + }, + "167ce7de65e84708595a525497a3eb5e5a665073": { + "balance": "0x1f314773666fc40000" + }, + "167e3e3ae2003348459392f7dfce44af7c21ad59": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "1680cec5021ee93050f8ae127251839e74c1f1fd": { + "balance": "0x2c61461e5d743d68000" + }, + "16816aac0ede0d2d3cd442da79e063880f0f1d67": { + "balance": "0x6c6b935b8bbd400000" + }, + "168b5019b818691644835fe69bf229e17112d52c": { + "balance": "0x5ede20f01a459800000" + }, + "168bdec818eafc6d2992e5ef54aa0e1601e3c561": { + "balance": "0x3637507a30abeb0000" + }, + "168d30e53fa681092b52e9bae15a0dcb41a8c9bb": { + "balance": "0x56bc75e2d63100000" + }, + "169bbefc41cfd7d7cbb8dfc63020e9fb06d49546": { + "balance": "0x6c6b935b8bbd400000" + }, + "16a58e985dccd707a594d193e7cca78b5d027849": { + "balance": "0x49b9ca9a6943400000" + }, + "16a9e9b73ae98b864d1728798b8766dbc6ea8d12": { + "balance": "0x33e7b44b0db5040000" + }, + "16aa52cb0b554723e7060f21f327b0a68315fea3": { + "balance": "0xd8d726b7177a80000" + }, + "16abb8b021a710bdc78ea53494b20614ff4eafe8": { + "balance": "0x890b0c2e14fb80000" + }, + "16afa787fc9f94bdff6976b1a42f430a8bf6fb0f": { + "balance": "0x6c6b935b8bbd400000" + }, + "16bae5d24eff91778cd98b4d3a1cc3162f44aa77": { + "balance": "0x15be6174e1912e0000" + }, + "16bc40215abbd9ae5d280b95b8010b4514ff1292": { + "balance": "0xad78ebc5ac6200000" + }, + "16be75e98a995a395222d00bd79ff4b6e638e191": { + "balance": "0x79f905c6fd34e800000" + }, + "16c1bf5b7dc9c83c179efacbcf2eb174e3561cb3": { + "balance": "0x3635c9adc5dea00000" + }, + "16c7b31e8c376282ac2271728c31c95e35d952c3": { + "balance": "0x6c6b935b8bbd400000" + }, + "16f313cf8ad000914a0a176dc6a4342b79ec2538": { + "balance": "0x6c6b935b8bbd400000" + }, + "16ffac84032940f0121a09668b858a7e79ffa3bb": { + "balance": "0xd24ada6e1087110000" + }, + "1703b4b292b8a9deddede81bb25d89179f6446b6": { + "balance": "0x42b65a455e8b1680000" + }, + "17049311101d817efb1d65910f663662a699c98c": { + "balance": "0x6c68ccd09b022c0000" + }, + "1704cefcfb1331ec7a78388b29393e85c1af7916": { + "balance": "0x15af1d78b58c400000" + }, + "170a88a8997f92d238370f1affdee6347050b013": { + "balance": "0xa2ac77351488300000" + }, + "17108dab2c50f99de110e1b3b3b4cd82f5df28e7": { + "balance": "0x35203b67bccad00000" + }, + "17125b59ac51cee029e4bd78d7f5947d1ea49bb2": { + "balance": "0x4a89f54ef0121c00000" + }, + "171ad9a04bedc8b861e8ed4bddf5717813b1bb48": { + "balance": "0x15af1d78b58c400000" + }, + "171ca02a8b6d62bf4ca47e906914079861972cb2": { + "balance": "0xad78ebc5ac6200000" + }, + "1722c4cbe70a94b6559d425084caeed4d6e66e21": { + "balance": "0xd8d726b7177a800000" + }, + "17580b766f7453525ca4c6a88b01b50570ea088c": { + "balance": "0x56bc75e2d63100000" + }, + "17589a6c006a54cad70103123aae0a82135fdeb4": { + "balance": "0xd8d726b7177a800000" + }, + "175a183a3a235ffbb03ba835675267229417a091": { + "balance": "0x3635c9adc5dea000000" + }, + "175feeea2aa4e0efda12e1588d2f483290ede81a": { + "balance": "0xad78ebc5ac6200000" + }, + "1765361c2ec2f83616ce8363aae21025f2566f40": { + "balance": "0x10f0cf064dd59200000" + }, + "1767525c5f5a22ed80e9d4d7710f0362d29efa33": { + "balance": "0x15af1d78b58c400000" + }, + "17762560e82a93b3f522e0e524adb8612c3a7470": { + "balance": "0x3635c9adc5dea00000" + }, + "177dae78bc0113d8d39c4402f2a641ae2a105ab8": { + "balance": "0x6292425620b4480000" + }, + "1784948bf99848c89e445638504dd698271b5924": { + "balance": "0x1474c410d87baee0000" + }, + "1788da9b57fd05edc4ff99e7fef301519c8a0a1e": { + "balance": "0x6c6b935b8bbd400000" + }, + "178eaf6b8554c45dfde16b78ce0c157f2ee31351": { + "balance": "0x1158e460913d000000" + }, + "17961d633bcf20a7b029a7d94b7df4da2ec5427f": { + "balance": "0xc6ff070f1938b8000" + }, + "1796bcc97b8abc717f4b4a7c6b1036ea2182639f": { + "balance": "0x1341f91cd8e3510000" + }, + "17993d312aa1106957868f6a55a5e8f12f77c843": { + "balance": "0x1865e814f4142e8000" + }, + "179a825e0f1f6e985309668465cffed436f6aea9": { + "balance": "0x1158e460913d00000" + }, + "17b2d6cf65c6f4a347ddc6572655354d8a412b29": { + "balance": "0x6c6b935b8bbd400000" + }, + "17b807afa3ddd647e723542e7b52fee39527f306": { + "balance": "0x15af40ffa7fc010000" + }, + "17c0478657e1d3d17aaa331dd429cecf91f8ae5d": { + "balance": "0x3634fb9f1489a70000" + }, + "17c0fef6986cfb2e4041f9979d9940b69dff3de2": { + "balance": "0xd8d726b7177a800000" + }, + "17d4918dfac15d77c47f9ed400a850190d64f151": { + "balance": "0x6c6b935b8bbd400000" + }, + "17d521a8d9779023f7164d233c3b6420ffd223ed": { + "balance": "0x1158e460913d00000" + }, + "17d931d4c56294dcbe77c8655be4695f006d4a3c": { + "balance": "0x6c6b935b8bbd400000" + }, + "17df49518d73b129f0da36b1c9b40cb66420fdc7": { + "balance": "0x21e19e0c9bab2400000" + }, + "17e4a0e52bac3ee44efe0954e753d4b85d644e05": { + "balance": "0x6c6b935b8bbd400000" + }, + "17e584e810e567702c61d55d434b34cdb5ee30f6": { + "balance": "0x10f0cf064dd59200000" + }, + "17e82e7078dc4fd9e879fb8a50667f53a5c54591": { + "balance": "0xad78ebc5ac6200000" + }, + "17e86f3b5b30c0ba59f2b2e858425ba89f0a10b0": { + "balance": "0x6c6b935b8bbd400000" + }, + "17ee9f54d4ddc84d670eff11e54a659fd72f4455": { + "balance": "0x3635c9adc5dea000000" + }, + "17ef4acc1bf147e326749d10e677dcffd76f9e06": { + "balance": "0x87751f4e0e1b5300000" + }, + "17f14632a7e2820be6e8f6df823558283dadab2d": { + "balance": "0x6c6b935b8bbd400000" + }, + "17f523f117bc9fe978aa481eb4f5561711371bc8": { + "balance": "0x6c69f73e29134e0000" + }, + "17fd9b551a98cb61c2e07fbf41d3e8c9a530cba5": { + "balance": "0x1768c308193048000" + }, + "180478a655d78d0f3b0c4f202b61485bc4002fd5": { + "balance": "0x6c6b935b8bbd400000" + }, + "18136c9df167aa17b6f18e22a702c88f4bc28245": { + "balance": "0xd8d726b7177a800000" + }, + "1815279dff9952da3be8f77249dbe22243377be7": { + "balance": "0x1017cb76e7b26640000" + }, + "181fbba852a7f50178b1c7f03ed9e58d54162929": { + "balance": "0x241a9b4f617a280000" + }, + "1827039f09570294088fddf047165c33e696a492": { + "balance": "0x205b4dfa1ee74780000" + }, + "182db85293f606e88988c3704cb3f0c0bbbfca5a": { + "balance": "0x73f75d1a085ba0000" + }, + "1848003c25bfd4aa90e7fcb5d7b16bcd0cffc0d8": { + "balance": "0x3635c9adc5dea00000" + }, + "184a4f0beb71ffd558a6b6e8f228b78796c4cf3e": { + "balance": "0x28a857425466f800000" + }, + "184d86f3466ae6683b19729982e7a7e1a48347b2": { + "balance": "0x21e19e0c9bab2400000" + }, + "1851a063ccdb30549077f1d139e72de7971197d5": { + "balance": "0x6c6b935b8bbd400000" + }, + "185546e8768d506873818ac9751c1f12116a3bef": { + "balance": "0xad78ebc5ac6200000" + }, + "1858cf11aea79f5398ad2bb22267b5a3c952ea74": { + "balance": "0x215f835bc769da80000" + }, + "185a7fc4ace368d233e620b2a45935661292bdf2": { + "balance": "0x43c33c1937564800000" + }, + "1864a3c7b48155448c54c88c708f166709736d31": { + "balance": "0x73f75d1a085ba0000" + }, + "186afdc085f2a3dce4615edffbadf71a11780f50": { + "balance": "0xad78ebc5ac6200000" + }, + "186b95f8e5effddcc94f1a315bf0295d3b1ea588": { + "balance": "0x6c6acc67d7b1d40000" + }, + "187d9f0c07f8eb74faaad15ebc7b80447417f782": { + "balance": "0x1158e460913d00000" + }, + "1895a0eb4a4372722fcbc5afe6936f289c88a419": { + "balance": "0x3154c9729d05780000" + }, + "1899f69f653b05a5a6e81f480711d09bbf97588c": { + "balance": "0x69fb133df750ac0000" + }, + "18a6d2fc52be73084023c91802f05bc24a4be09f": { + "balance": "0x6c6b935b8bbd400000" + }, + "18b0407cdad4ce52600623bd5e1f6a81ab61f026": { + "balance": "0x1151ccf0c654c68000" + }, + "18b8bcf98321da61fb4e3eacc1ec5417272dc27e": { + "balance": "0x2fb474098f67c00000" + }, + "18c6723a6753299cb914477d04a3bd218df8c775": { + "balance": "0x3635c9adc5dea00000" + }, + "18e113d8177c691a61be785852fa5bb47aeebdaf": { + "balance": "0x487a9a304539440000" + }, + "18e4ce47483b53040adbab35172c01ef64506e0c": { + "balance": "0x1e7e4171bf4d3a00000" + }, + "18e53243981aabc8767da10c73449f1391560eaa": { + "balance": "0x14542ba12a337c00000" + }, + "18fa8625c9dc843c78c7ab259ff87c9599e07f10": { + "balance": "0x3635c9adc5dea00000" + }, + "18fb09188f27f1038e654031924f628a2106703d": { + "balance": "0x6c6b935b8bbd400000" + }, + "18fccf62d2c3395453b7587b9e26f5cff9eb7482": { + "balance": "0x3635c9adc5dea00000" + }, + "191313525238a21c767457a91374f02200c55448": { + "balance": "0x64f5fdf494f780000" + }, + "1914f1eb95d1277e93b6e61b668b7d77f13a11a1": { + "balance": "0x34957444b840e80000" + }, + "1923cfc68b13ea7e2055803645c1e320156bd88d": { + "balance": "0x487a9a304539440000" + }, + "19336a236ded755872411f2e0491d83e3e00159e": { + "balance": "0x32f51edbaaa3300000" + }, + "1933e334c40f3acbad0c0b851158206924beca3a": { + "balance": "0x1995eaf01b896188000" + }, + "1937c5c515057553ccbd46d5866455ce66290284": { + "balance": "0xd3c21bcecceda1000000" + }, + "193ac65183651800e23580f8f0ead3bb597eb8a4": { + "balance": "0x2b62abcfb910a0000" + }, + "193d37ed347d1c2f4e35350d9a444bc57ca4db43": { + "balance": "0x340aad21b3b700000" + }, + "1940dc9364a852165f47414e27f5002445a4f143": { + "balance": "0x24c2dff6a3c7c480000" + }, + "1945fe377fe6d4b71e3e791f6f17db243c9b8b0f": { + "balance": "0x7679e7beb988360000" + }, + "194a6bb302b8aba7a5b579df93e0df1574967625": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "194cebb4929882bf3b4bf9864c2b1b0f62c283f9": { + "balance": "0x1ef861531f74aa0000" + }, + "194ff44aefc17bd20efd7a204c47d1620c86db5d": { + "balance": "0xa29909687f6aa40000" + }, + "194ffe78bbf5d20dd18a1f01da552e00b7b11db1": { + "balance": "0x17b7883c06916600000" + }, + "1953313e2ad746239cb2270f48af34d8bb9c4465": { + "balance": "0x6c6b935b8bbd400000" + }, + "19571a2b8f81c6bcf66ab3a10083295617150003": { + "balance": "0x1ab2cf7c9f87e20000" + }, + "19687daa39c368139b6e7be60dc1753a9f0cbea3": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "196c02210a450ab0b36370655f717aa87bd1c004": { + "balance": "0xe10ace157dbc00000" + }, + "196e85df7e732b4a8f0ed03623f4db9db0b8fa31": { + "balance": "0x125b92f5cef248000" + }, + "19732bf973055dbd91a4533adaa2149a91d38380": { + "balance": "0x6c6b935b8bbd400000" + }, + "197672fd39d6f246ce66a790d13aa922d70ea109": { + "balance": "0x3635c9adc5dea00000" + }, + "19798cbda715ea9a9b9d6aab942c55121e98bf91": { + "balance": "0x410d586a20a4c00000" + }, + "198bfcf1b07ae308fa2c02069ac9dafe7135fb47": { + "balance": "0x1158e460913d00000" + }, + "198ef1ec325a96cc354c7266a038be8b5c558f67": { + "balance": "0x80d1e4373e7f21da0000" + }, + "19918aa09e7d494e98ffa5db50350892f7156ac6": { + "balance": "0x21e19e0c9bab2400000" + }, + "19b36b0c87ea664ed80318dc77b688dde87d95a5": { + "balance": "0x699f499802303d0000" + }, + "19df9445a81c1b3d804aeaeb6f6e204e4236663f": { + "balance": "0x206d94e6a49878000" + }, + "19e5dea3370a2c746aae34a37c531f41da264e83": { + "balance": "0xad78ebc5ac6200000" + }, + "19e7f3eb7bf67f3599209ebe08b62ad3327f8cde": { + "balance": "0x6c6b935b8bbd400000" + }, + "19e94e620050aad766b9e1bad931238312d4bf49": { + "balance": "0x81e32df972abf00000" + }, + "19ecf2abf40c9e857b252fe1dbfd3d4c5d8f816e": { + "balance": "0x6c6b935b8bbd400000" + }, + "19f5caf4c40e6908813c0745b0aea9586d9dd931": { + "balance": "0x23fed9e1fa2b600000" + }, + "19f643e1a8fa04ae16006028138333a59a96de87": { + "balance": "0x1158e460913d00000" + }, + "19f99f2c0b46ce8906875dc9f90ae104dae35594": { + "balance": "0xf4575a5d4d162a0000" + }, + "19ff244fcfe3d4fa2f4fd99f87e55bb315b81eb6": { + "balance": "0xad78ebc5ac6200000" + }, + "1a04cec420ad432215246d77fe178d339ed0b595": { + "balance": "0x11216185c29f700000" + }, + "1a04d5389eb006f9ce880c30d15353f8d11c4b31": { + "balance": "0x39d84b2186dc9100000" + }, + "1a0841b92a7f7075569dc4627e6b76cab05ade91": { + "balance": "0x52663ccab1e1c00000" + }, + "1a085d43ec92414ea27b914fe767b6d46b1eef44": { + "balance": "0x641e8a13563d8f80000" + }, + "1a09fdc2c7a20e23574b97c69e93deba67d37220": { + "balance": "0x6c4fd1ee246e780000" + }, + "1a0a1ddfb031e5c8cc1d46cf05842d50fddc7130": { + "balance": "0x3635c9adc5dea00000" + }, + "1a1c9a26e0e02418a5cf687da75a275c622c9440": { + "balance": "0x10f0cf064dd59200000" + }, + "1a201b4327cea7f399046246a3c87e6e03a3cda8": { + "balance": "0x3635c9adc5dea00000" + }, + "1a2434cc774422d48d53d59c5d562cce8407c94b": { + "balance": "0x1a055690d9db80000" + }, + "1a25e1c5bc7e5f50ec16f8885f210ea1b938800e": { + "balance": "0xd8d726b7177a800000" + }, + "1a2694ec07cf5e4d68ba40f3e7a14c53f3038c6e": { + "balance": "0x3636cd06e2db3a8000" + }, + "1a3520453582c718a21c42375bc50773255253e1": { + "balance": "0x2ad373ce668e980000" + }, + "1a376e1b2d2f590769bb858d4575320d4e149970": { + "balance": "0x106712576391d180000" + }, + "1a3a330e4fcb69dbef5e6901783bf50fd1c15342": { + "balance": "0xe3aeb5737240a00000" + }, + "1a4ec6a0ae7f5a9427d23db9724c0d0cffb2ab2f": { + "balance": "0x9b41fbf9e0aec0000" + }, + "1a505e62a74e87e577473e4f3afa16bedd3cfa52": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "1a5ee533acbfb3a2d76d5b685277b796c56a052b": { + "balance": "0x6c6b935b8bbd400000" + }, + "1a644a50cbc2aee823bd2bf243e825be4d47df02": { + "balance": "0x56be03ca3e47d8000" + }, + "1a7044e2383f8708305b495bd1176b92e7ef043a": { + "balance": "0xad78ebc5ac6200000" + }, + "1a79c7f4039c67a39d7513884cdc0e2c34222490": { + "balance": "0x1158e460913d00000" + }, + "1a89899cbebdbb64bb26a195a63c08491fcd9eee": { + "balance": "0x6c6b935b8bbd400000" + }, + "1a8a5ce414de9cd172937e37f2d59cff71ce57a0": { + "balance": "0x21e19e0c9bab2400000" + }, + "1a95a8a8082e4652e4170df9271cb4bb4305f0b2": { + "balance": "0x2b5e3af16b1880000" + }, + "1a95c9b7546b5d1786c3858fb1236446bc0ca4ce": { + "balance": "0x6acb3df27e1f880000" + }, + "1a987e3f83de75a42f1bde7c997c19217b4a5f24": { + "balance": "0x6c6b935b8bbd400000" + }, + "1a9e702f385dcd105e8b9fa428eea21c57ff528a": { + "balance": "0x4be4e7267b6ae00000" + }, + "1aa1021f550af158c747668dd13b463160f95a40": { + "balance": "0x4fb0591b9b30380000" + }, + "1aa27699cada8dc3a76f7933aa66c71919040e88": { + "balance": "0x15af1d78b58c400000" + }, + "1aa40270d21e5cde86b6316d1ac3c533494b79ed": { + "balance": "0x1158e460913d00000" + }, + "1ab53a11bcc63ddfaa40a02b9e186496cdbb8aff": { + "balance": "0x6c3f2aac800c000000" + }, + "1abc4e253b080aeb437984ab05bca0979aa43e1c": { + "balance": "0x3635c9adc5dea00000" + }, + "1ac089c3bc4d82f06a20051a9d732dc0e734cb61": { + "balance": "0x25f69d63a6ce0e0000" + }, + "1ad4563ea5786be1159935abb0f1d5879c3e7372": { + "balance": "0x14542ba12a337c00000" + }, + "1ad72d20a76e7fcc6b764058f48d417d496fa6cd": { + "balance": "0x6c6b935b8bbd400000" + }, + "1adaf4abfa867db17f99af6abebf707a3cf55df6": { + "balance": "0x14542ba12a337c00000" + }, + "1af60343360e0b2d75255210375720df21db5c7d": { + "balance": "0x3635c9adc5dea00000" + }, + "1afcc585896cd0ede129ee2de5c19ea811540b64": { + "balance": "0xaf2aba0c8e5bef8000" + }, + "1b05ea6a6ac8af7cb6a8b911a8cce8fe1a2acfc8": { + "balance": "0x6c6b935b8bbd400000" + }, + "1b0b31afff4b6df3653a94d7c87978ae35f34aae": { + "balance": "0x133910453fa9840000" + }, + "1b0d076817e8d68ee2df4e1da1c1142d198c4435": { + "balance": "0x54069233bf7f780000" + }, + "1b130d6fa51d5c48ec8d1d52dc8a227be8735c8a": { + "balance": "0x6c6b935b8bbd400000" + }, + "1b23cb8663554871fbbe0d9e60397efb6faedc3e": { + "balance": "0xad78ebc5ac6200000" + }, + "1b2639588b55c344b023e8de5fd4087b1f040361": { + "balance": "0x5150ae84a8cdf00000" + }, + "1b3920d001c43e72b24e7ca46f0fd6e0c20a5ff2": { + "balance": "0x6c6b935b8bbd400000" + }, + "1b3cb81e51011b549d78bf720b0d924ac763a7c2": { + "balance": "0x7695a92c20d6fe000000" + }, + "1b43232ccd4880d6f46fa751a96cd82473315841": { + "balance": "0x4563918244f400000" + }, + "1b4bbcb18165211b265b280716cb3f1f212176e8": { + "balance": "0x199ad37d03d0608000" + }, + "1b4d07acd38183a61bb2783d2b7b178dd502ac8d": { + "balance": "0xad78ebc5ac6200000" + }, + "1b636b7a496f044d7359596e353a104616436f6b": { + "balance": "0x1388ea95c33f1d0000" + }, + "1b6495891240e64e594493c2662171db5e30ce13": { + "balance": "0x95887d695ed580000" + }, + "1b6610fb68bad6ed1cfaa0bbe33a24eb2e96fafb": { + "balance": "0x83d6c7aab63600000" + }, + "1b799033ef6dc7127822f74542bb22dbfc09a308": { + "balance": "0x56bc75e2d63100000" + }, + "1b7ed974b6e234ce81247498429a5bd4a0a2d139": { + "balance": "0x6c6b935b8bbd400000" + }, + "1b826fb3c012b0d159e294ba5b8a499ff3c0e03c": { + "balance": "0x6c6b935b8bbd400000" + }, + "1b8aa0160cd79f005f88510a714913d70ad3be33": { + "balance": "0xaeffb83079ad00000" + }, + "1b8bd6d2eca20185a78e7d98e8e185678dac4830": { + "balance": "0x3894f0e6f9b9f700000" + }, + "1b9b2dc2960e4cb9408f7405827c9b59071612fd": { + "balance": "0x3635c9adc5dea00000" + }, + "1ba9228d388727f389150ea03b73c82de8eb2e09": { + "balance": "0x18974fbe177c9280000" + }, + "1ba9f7997e5387b6b2aa0135ac2452fe36b4c20d": { + "balance": "0x2e141ea081ca080000" + }, + "1bba03ff6b4ad5bf18184acb21b188a399e9eb4a": { + "balance": "0x61093d7c2c6d380000" + }, + "1bbc199e586790be87afedc849c04726745c5d7b": { + "balance": "0xd8d726b7177a800000" + }, + "1bbc60bcc80e5cdc35c5416a1f0a40a83dae867b": { + "balance": "0x6c6b935b8bbd400000" + }, + "1bc44c8761231ba1f11f5faa40fa669a013e12ce": { + "balance": "0xb0952c45aeaad0000" + }, + "1bcf3441a866bdbe963009ce33c81cbb0261b02c": { + "balance": "0x9ddc1e3b901180000" + }, + "1bd28cd5c78aee51357c95c1ef9235e7c18bc854": { + "balance": "0x6c6b935b8bbd400000" + }, + "1bd8ebaa7674bb18e19198db244f570313075f43": { + "balance": "0x821ab0d4414980000" + }, + "1bd909ac0d4a1102ec98dcf2cca96a0adcd7a951": { + "balance": "0x11651ac3e7a758000" + }, + "1be3542c3613687465f15a70aeeb81662b65cca8": { + "balance": "0x6c6b935b8bbd400000" + }, + "1bea4df5122fafdeb3607eddda1ea4ffdb9abf2a": { + "balance": "0x12c1b6eed03d280000" + }, + "1bec4d02ce85fc48feb62489841d85b170586a9b": { + "balance": "0x821ab0d44149800000" + }, + "1bf974d9904f45ce81a845e11ef4cbcf27af719e": { + "balance": "0x56bc75e2d63100000" + }, + "1c045649cd53dc23541f8ed4d341812808d5dd9c": { + "balance": "0x17b7883c06916600000" + }, + "1c128bd6cda5fca27575e4b43b3253c8c4172afe": { + "balance": "0x6c6b935b8bbd400000" + }, + "1c13d38637b9a47ce79d37a86f50fb409c060728": { + "balance": "0x487a9a304539440000" + }, + "1c2010bd662df417f2a271879afb13ef4c88a3ae": { + "balance": "0xd8d726b7177a800000" + }, + "1c257ad4a55105ea3b58ed374b198da266c85f63": { + "balance": "0x21e19e0c9bab2400000" + }, + "1c2e3607e127caca0fbd5c5948adad7dd830b285": { + "balance": "0x42bf06b78ed3b500000" + }, + "1c356cfdb95febb714633b28d5c132dd84a9b436": { + "balance": "0x15af1d78b58c40000" + }, + "1c35aab688a0cd8ef82e76541ba7ac39527f743b": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "1c3ef05dae9dcbd489f3024408669de244c52a02": { + "balance": "0x43c33c1937564800000" + }, + "1c4af0e863d2656c8635bc6ffec8dd9928908cb5": { + "balance": "0x6c6b935b8bbd400000" + }, + "1c601993789207f965bb865cbb4cd657cce76fc0": { + "balance": "0x5541a7037503f0000" + }, + "1c63fa9e2cbbf23c49fcdef1cbabfe6e0d1e14c1": { + "balance": "0x3635c9adc5dea00000" + }, + "1c6702b3b05a5114bdbcaeca25531aeeb34835f4": { + "balance": "0x58556bead45dcae0000" + }, + "1c68a66138783a63c98cc675a9ec77af4598d35e": { + "balance": "0x2b746f48f0f120000" + }, + "1c73d00b6e25d8eb9c1ff4ad827b6b9e9cf6d20c": { + "balance": "0xad78ebc5ac6200000" + }, + "1c751e7f24df9d94a637a5dedeffc58277b5db19": { + "balance": "0xae8e7a0bb575d00000" + }, + "1c7cb2fe6bf3e09cbcdc187af38fa8f5053a70b6": { + "balance": "0x21c84f742d0cead8000" + }, + "1c89060f987c518fa079ec2c0a5ebfa30f5d20f7": { + "balance": "0x80bfbefcb5f0bc00000" + }, + "1c94d636e684eb155895ce6db4a2588fba1d001b": { + "balance": "0x6c6b935b8bbd400000" + }, + "1c99fe9bb6c6d1066d912099547fd1f4809eacd9": { + "balance": "0x6c6b935b8bbd400000" + }, + "1cb450920078aab2317c7db3b38af7dd298b2d41": { + "balance": "0x126e72a69a50d00000" + }, + "1cb5f33b4d488936d13e3161da33a1da7df70d1b": { + "balance": "0xad78ebc5ac6200000" + }, + "1cb6b2d7cfc559b7f41e6f56ab95c7c958cd0e4c": { + "balance": "0x487a9a304539440000" + }, + "1cc1d3c14f0fb8640e36724dc43229d2ea7a1e48": { + "balance": "0x5c283d410394100000" + }, + "1cc90876004109cd79a3dea866cb840ac364ba1b": { + "balance": "0x6c6b935b8bbd400000" + }, + "1cd1f0a314cbb200de0a0cb1ef97e920709d97c2": { + "balance": "0x6c6b935b8bbd400000" + }, + "1cda411bd5163baeca1e558563601ce720e24ee1": { + "balance": "0xfc936392801c0000" + }, + "1ce81d31a7923022e125bf48a3e03693b98dc9dd": { + "balance": "0x6c6b935b8bbd400000" + }, + "1cebf0985d7f680aaa915c44cc62edb49eab269e": { + "balance": "0x3635c9adc5dea00000" + }, + "1ced6715f862b1ff86058201fcce5082b36e62b2": { + "balance": "0x16a5e60bee273b10000" + }, + "1cf04cb14380059efd3f238b65d5beb86afa14d8": { + "balance": "0x1158e460913d00000" + }, + "1cf105ab23023b554c583e86d7921179ee83169f": { + "balance": "0x6acb3df27e1f880000" + }, + "1cf2eb7a8ccac2adeaef0ee87347d535d3b94058": { + "balance": "0x6c6b935b8bbd400000" + }, + "1cfcf7517f0c08459720942b647ad192aa9c8828": { + "balance": "0x2b5e3af16b18800000" + }, + "1d09ad2412691cc581c1ab36b6f9434cd4f08b54": { + "balance": "0x17b7883c06916600000" + }, + "1d157c5876c5cad553c912caf6ce2d5277e05c73": { + "balance": "0x6c6b935b8bbd400000" + }, + "1d2615f8b6ca5012b663bdd094b0c5137c778ddf": { + "balance": "0x21e19e0c9bab2400000" + }, + "1d29c7aab42b2048d2b25225d498dba67a03fbb2": { + "balance": "0xad78ebc5ac6200000" + }, + "1d341fa5a3a1bd051f7db807b6db2fc7ba4f9b45": { + "balance": "0xfc936392801c0000" + }, + "1d344e962567cb27e44db9f2fac7b68df1c1e6f7": { + "balance": "0x692ae8897081d00000" + }, + "1d36683063b7e9eb99462dabd569bddce71686f2": { + "balance": "0x3635c9adc5dea00000" + }, + "1d37616b793f94911838ac8e19ee9449df921ec4": { + "balance": "0x5150ae84a8cdf00000" + }, + "1d395b30adda1cf21f091a4f4a7b753371189441": { + "balance": "0x152d02c7e14af6800000" + }, + "1d45586eb803ca2190650bf748a2b174312bb507": { + "balance": "0x4be4e7267b6ae00000" + }, + "1d572edd2d87ca271a6714c15a3b37761dcca005": { + "balance": "0x6ebd52a8ddd390000" + }, + "1d633097a85225a1ff4321b12988fdd55c2b3844": { + "balance": "0xd8d726b7177a800000" + }, + "1d69c83d28ff0474ceebeacb3ad227a144ece7a3": { + "balance": "0x128cc03920a62d28000" + }, + "1d96bcd58457bbf1d3c2a46ffaf16dbf7d836859": { + "balance": "0x9497209d8467e8000" + }, + "1d9e6aaf8019a05f230e5def05af5d889bd4d0f2": { + "balance": "0x73f75d1a085ba0000" + }, + "1dab172effa6fbee534c94b17e794edac54f55f8": { + "balance": "0x6acb3df27e1f880000" + }, + "1db9ac9a9eaeec0a523757050c71f47278c72d50": { + "balance": "0x487a9a304539440000" + }, + "1dbe8e1c2b8a009f85f1ad3ce80d2e05350ee39c": { + "balance": "0x7570d6e9ebbe40000" + }, + "1dc7f7dad85df53f1271152403f4e1e4fdb3afa0": { + "balance": "0xad78ebc5ac6200000" + }, + "1dcebcb7656df5dcaa3368a055d22f9ed6cdd940": { + "balance": "0x1b181e4bf2343c0000" + }, + "1dd77441844afe9cc18f15d8c77bccfb655ee034": { + "balance": "0x106eb45579944880000" + }, + "1ddefefd35ab8f658b2471e54790bc17af98dea4": { + "balance": "0x3635c9adc5dea00000" + }, + "1deec01abe5c0d952de9106c3dc30639d85005d6": { + "balance": "0x6c6b935b8bbd400000" + }, + "1df6911672679bb0ef3509038c0c27e394fdfe30": { + "balance": "0x1d460162f516f00000" + }, + "1dfaee077212f1beaf0e6f2f1840537ae154ad86": { + "balance": "0x3635c9adc5dea00000" + }, + "1e060dc6c5f1cb8cc7e1452e02ee167508b56542": { + "balance": "0x2b14f02c864c77e0000" + }, + "1e13ec51142cebb7a26083412c3ce35144ba56a1": { + "balance": "0x10f0cf064dd59200000" + }, + "1e1a4828119be309bd88236e4d482b504dc55711": { + "balance": "0xa030dcebbd2f4c0000" + }, + "1e1aed85b86c6562cb8fa1eb6f8f3bc9dcae6e79": { + "balance": "0xf4d2dd84259b240000" + }, + "1e1c6351776ac31091397ecf16002d979a1b2d51": { + "balance": "0x4be4e7267b6ae00000" + }, + "1e1d7a5f2468b94ea826982dbf2125793c6e4a5a": { + "balance": "0x3634f48417401a0000" + }, + "1e210e7047886daa52aaf70f4b991dac68e3025e": { + "balance": "0xad78ebc5ac6200000" + }, + "1e2bf4ba8e5ef18d37de6d6ad636c4cae489d0cc": { + "balance": "0x6c6b935b8bbd400000" + }, + "1e2fe4e4a77d141ff49a0c7fbc95b0a2b283eeeb": { + "balance": "0x6c6b935b8bbd400000" + }, + "1e33d1c2fb5e084f2f1d54bc5267727fec3f985d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "1e381adcf801a3bf9fd7bfac9ccc2b8482ad5e66": { + "balance": "0x208972c0010d740000" + }, + "1e3badb1b6e1380e27039c576ae6222e963a5b53": { + "balance": "0x43c33c1937564800000" + }, + "1e484d0621f0f5331b35d5408d9aae4eb1acf21e": { + "balance": "0x1158e460913d00000" + }, + "1e5800227d4dcf75e30f5595c5bed3f72e341e3b": { + "balance": "0xd75dace73417e0000" + }, + "1e596a81b357c6f24970cc313df6dbdaabd0d09e": { + "balance": "0x6c6b935b8bbd400000" + }, + "1e6915ebd9a19c81b692ad99b1218a592c1ac7b1": { + "balance": "0xd8d726b7177a800000" + }, + "1e6e0153fc161bc05e656bbb144c7187bf4fe84d": { + "balance": "0x6c6b935b8bbd400000" + }, + "1e706655e284dcf0bb37fe075d613a18dc12ff4a": { + "balance": "0xed43bf1eee82ac0000" + }, + "1e783e522ab7df0acaac9eeed3593039e5ac7579": { + "balance": "0x2b1446dd6aefe41c0000" + }, + "1e7b5e4d1f572becf2c00fc90cb4767b4a6e33d4": { + "balance": "0x61fc6107593e10000" + }, + "1e8e689b02917cdc29245d0c9c68b094b41a9ed6": { + "balance": "0x6c6b935b8bbd400000" + }, + "1ea334b5750807ea74aac5ab8694ec5f28aa77cf": { + "balance": "0x1ab2cf7c9f87e20000" + }, + "1ea4715504c6af107b0194f4f7b1cb6fcccd6f4b": { + "balance": "0x20043197e0b0270000" + }, + "1ea492bce1ad107e337f4bd4a7ac9a7babcccdab": { + "balance": "0x56bc75e2d63100000" + }, + "1ea6bf2f15ae9c1dbc64daa7f8ea4d0d81aad3eb": { + "balance": "0xe3aeb5737240a00000" + }, + "1eb4bf73156a82a0a6822080c6edf49c469af8b9": { + "balance": "0x678a932062e4180000" + }, + "1ebacb7844fdc322f805904fbf1962802db1537c": { + "balance": "0x21e19e0c9bab2400000" + }, + "1ec4ec4b77bf19d091a868e6f49154180541f90e": { + "balance": "0x6c6b935b8bbd400000" + }, + "1ed06ee51662a86c634588fb62dc43c8f27e7c17": { + "balance": "0xad78ebc5ac6200000" + }, + "1ed8bb3f06778b039e9961d81cb71a73e6787c8e": { + "balance": "0x6c6b935b8bbd400000" + }, + "1eda084e796500ba14c5121c0d90846f66e4be62": { + "balance": "0x1cfdd7468216e80000" + }, + "1eee6cbee4fe96ad615a9cf5857a647940df8c78": { + "balance": "0x10d3aa536e2940000" + }, + "1ef2dcbfe0a500411d956eb8c8939c3d6cfe669d": { + "balance": "0x2a1129d09367200000" + }, + "1ef5c9c73650cfbbde5c885531d427c7c3fe5544": { + "balance": "0x14542ba12a337c00000" + }, + "1f0412bfedcd964e837d092c71a5fcbaf30126e2": { + "balance": "0x1158e460913d00000" + }, + "1f174f40a0447234e66653914d75bc003e5690dc": { + "balance": "0x8ac7230489e800000" + }, + "1f2186ded23e0cf9521694e4e164593e690a9685": { + "balance": "0x1043561a8829300000" + }, + "1f2afc0aed11bfc71e77a907657b36ea76e3fb99": { + "balance": "0xd8d726b7177a800000" + }, + "1f3959fc291110e88232c36b7667fc78a379613f": { + "balance": "0xfc936392801c0000" + }, + "1f3da68fe87eaf43a829ab6d7ec5a6e009b204fb": { + "balance": "0x1e1601758c2c7e0000" + }, + "1f49b86d0d3945590698a6aaf1673c37755ca80d": { + "balance": "0x25f273933db5700000" + }, + "1f5f3b34bd134b2781afe5a0424ac5846cdefd11": { + "balance": "0x55de6a779bbac0000" + }, + "1f6f0030349752061c96072bc3d6eb3549208d6b": { + "balance": "0x14b8de1eb88db8000" + }, + "1f7d8e86d6eeb02545aad90e91327bd369d7d2f3": { + "balance": "0x1158e460913d00000" + }, + "1f8116bd0af5570eaf0c56c49c7ab5e37a580458": { + "balance": "0x6c6b935b8bbd400000" + }, + "1f88f8a1338fc7c10976abcd3fb8d38554b5ec9c": { + "balance": "0xb9f65d00f63c0000" + }, + "1f9c3268458da301a2be5ab08257f77bb5a98aa4": { + "balance": "0xad78ebc5ac6200000" + }, + "1fa2319fed8c2d462adf2e17feec6a6f30516e95": { + "balance": "0x6cae30621d4720000" + }, + "1fb463a0389983df7d593f7bdd6d78497fed8879": { + "balance": "0x1158e460913d00000" + }, + "1fb7bd310d95f2a6d9baaf8a8a430a9a04453a8b": { + "balance": "0xa2a15d09519be00000" + }, + "1fcc7ce6a8485895a3199e16481f72e1f762defe": { + "balance": "0x3635c9adc5dea00000" + }, + "1fcfd1d57f872290560cb62d600e1defbefccc1c": { + "balance": "0x50c5e761a444080000" + }, + "1fd296be03ad737c92f9c6869e8d80a71c5714aa": { + "balance": "0xb98bc829a6f90000" + }, + "1fddd85fc98be9c4045961f40f93805ecc4549e5": { + "balance": "0x8e3f50b173c100000" + }, + "2001bef77b66f51e1599b02fb110194a0099b78d": { + "balance": "0x6c6b935b8bbd400000" + }, + "200264a09f8c68e3e6629795280f56254f8640d0": { + "balance": "0x1158e460913d00000" + }, + "2003717907a72560f4307f1beecc5436f43d21e7": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "200dfc0b71e359b2b465440a36a6cdc352773007": { + "balance": "0x5150ae84a8cdf00000" + }, + "20134cbff88bfadc466b52eceaa79857891d831e": { + "balance": "0x3635c9adc5dea00000" + }, + "2014261f01089f53795630ba9dd24f9a34c2d942": { + "balance": "0x487a9a304539440000" + }, + "2016895df32c8ed5478269468423aea7b7fbce50": { + "balance": "0x1158e460913d00000" + }, + "20181c4b41f6f972b66958215f19f570c15ddff1": { + "balance": "0x56bc75e2d631000000" + }, + "201864a8f784c2277b0b7c9ee734f7b377eab648": { + "balance": "0xf2281400d1d5ec0000" + }, + "2020b81ae53926ace9f7d7415a050c031d585f20": { + "balance": "0x127f19e83eb3480000" + }, + "203c6283f20df7bc86542fdfb4e763ecdbbbeef5": { + "balance": "0x54b40b1f852bda00000" + }, + "204ac98867a7c9c7ed711cb82f28a878caf69b48": { + "balance": "0x14542ba12a337c00000" + }, + "205237c4be146fba99478f3a7dad17b09138da95": { + "balance": "0x6c6b935b8bbd400000" + }, + "2053ac97548a0c4e8b80bc72590cd6a098fe7516": { + "balance": "0xa2325753b460c0000" + }, + "205f5166f12440d85762c967d3ae86184f8f4d98": { + "balance": "0x177224aa844c720000" + }, + "205fc843e19a4913d1881eb69b69c0fa3be5c50b": { + "balance": "0x20dd68aaf3289100000" + }, + "206482ee6f138a778fe1ad62b180ce856fbb23e6": { + "balance": "0x6c6b935b8bbd400000" + }, + "2066774d822793ff25f1760909479cf62491bf88": { + "balance": "0xbae3ac685cb72e00000" + }, + "206d55d5792a514ec108e090599f2a065e501185": { + "balance": "0xadf30ba70c8970000" + }, + "20707e425d2a11d2c89f391b2b809f556c592421": { + "balance": "0x6c6b935b8bbd400000" + }, + "207ef80b5d60b6fbffc51f3a64b8c72036a5abbd": { + "balance": "0x16a6502f15a1e540000" + }, + "20824ba1dbebbef9846ef3d0f6c1b017e6912ec4": { + "balance": "0x184b26e4daf1d350000" + }, + "2084fce505d97bebf1ad8c5ff6826fc645371fb2": { + "balance": "0x1a055690d9db80000" + }, + "208c45732c0a378f17ac8324926d459ba8b658b4": { + "balance": "0xa030dcebbd2f4c0000" + }, + "209377b6ad3fe101c9685b3576545c6b1684e73c": { + "balance": "0x62a992e53a0af00000" + }, + "209e8e29d33beae8fb6baa783d133e1d9ec1bc0b": { + "balance": "0x2d43f3ebfafb2c0000" + }, + "20a15256d50ce058bf0eac43aa533aa16ec9b380": { + "balance": "0x1158e460913d00000" + }, + "20a29c5079e26b3f18318bb2e50e8e8b346e5be8": { + "balance": "0x1b1ab319f5ec750000" + }, + "20a81680e465f88790f0074f60b4f35f5d1e6aa5": { + "balance": "0x456180278f0c778000" + }, + "20b9a9e6bd8880d9994ae00dd0b9282a0beab816": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "20c284ba10a20830fc3d699ec97d2dfa27e1b95e": { + "balance": "0x6c6b935b8bbd400000" + }, + "20d1417f99c569e3beb095856530fe12d0fceaaa": { + "balance": "0x4015f94b1183698000" + }, + "20dd8fcbb46ea46fe381a68b8ca0ea5be21fe9a5": { + "balance": "0x6c6b935b8bbd400000" + }, + "20ff3ede8cadb5c37b48cb14580fb65e23090a7b": { + "balance": "0x8e4d316827686400000" + }, + "2100381d60a5b54adc09d19683a8f6d5bb4bfbcb": { + "balance": "0x21e19e0c9bab2400000" + }, + "2118c116ab0cdf6fd11d54a4309307b477c3fc0f": { + "balance": "0x21e19e0c9bab2400000" + }, + "211b29cefc79ae976744fdebcebd3cbb32c51303": { + "balance": "0x2f6f10780d22cc00000" + }, + "21206ce22ea480e85940d31314e0d64f4e4d3a04": { + "balance": "0x3635c9adc5dea00000" + }, + "2132c0516a2e17174ac547c43b7b0020d1eb4c59": { + "balance": "0x35659ef93f0fc40000" + }, + "21408b4d7a2c0e6eca4143f2cacdbbccba121bd8": { + "balance": "0x43c33c1937564800000" + }, + "214b743955a512de6e0d886a8cbd0282bee6d2a2": { + "balance": "0x6c6b935b8bbd400000" + }, + "214c89c5bd8e7d22bc574bb35e48950211c6f776": { + "balance": "0x10654f258fd358000" + }, + "21546914dfd3af2add41b0ff3e83ffda7414e1e0": { + "balance": "0x14395e7385a502e0000" + }, + "21582e99e502cbf3d3c23bdffb76e901ac6d56b2": { + "balance": "0x56bc75e2d63100000" + }, + "2159240813a73095a7ebf7c3b3743e8028ae5f09": { + "balance": "0x6c6b935b8bbd400000" + }, + "2160b4c02cac0a81de9108de434590a8bfe68735": { + "balance": "0x6acb3df27e1f880000" + }, + "216e41864ef98f060da08ecae19ad1166a17d036": { + "balance": "0x1369fb96128ac480000" + }, + "21846f2fdf5a41ed8df36e5ed8544df75988ece3": { + "balance": "0x6c6acc67d7b1d40000" + }, + "21a6db6527467bc6dad54bc16e9fe2953b6794ed": { + "balance": "0x2f6f10780d22cc00000" + }, + "21a6feb6ab11c766fdd977f8df4121155f47a1c0": { + "balance": "0x319cf38f100580000" + }, + "21b182f2da2b384493cf5f35f83d9d1ee14f2a21": { + "balance": "0x6c6b935b8bbd400000" + }, + "21bfe1b45cacde6274fd8608d9a178bf3eeb6edc": { + "balance": "0x6cee06ddbe15ec0000" + }, + "21c07380484f6cbc8724ad32bc864c3b5ad500b7": { + "balance": "0x3635c9adc5dea00000" + }, + "21c3a8bba267c8cca27b1a9afabad86f607af708": { + "balance": "0x1e4a36c49d998300000" + }, + "21ce6d5b9018cec04ad6967944bea39e8030b6b8": { + "balance": "0x1158e460913d00000" + }, + "21d02705f3f64905d80ed9147913ea8c7307d695": { + "balance": "0x49edb1c09887360000" + }, + "21d13f0c4024e967d9470791b50f22de3afecf1b": { + "balance": "0xf15ad35e2e31e50000" + }, + "21dbdb817a0d8404c6bdd61504374e9c43c9210e": { + "balance": "0x21e18b9e9ab45e48000" + }, + "21df1ec24b4e4bfe79b0c095cebae198f291fbd1": { + "balance": "0x43c33c1937564800000" + }, + "21df2dcdaf74b2bf803404dd4de6a35eabec1bbd": { + "balance": "0x177224aa844c7200000" + }, + "21e219c89ca8ac14ae4cba6130eeb77d9e6d3962": { + "balance": "0x2acd9faaa038ee0000" + }, + "21e5d2bae995ccfd08a5c16bb524e1f630448f82": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "21e5d77320304c201c1e53b261a123d0a1063e81": { + "balance": "0x4b6fa9d33dd460000" + }, + "21eae6feffa9fbf4cd874f4739ace530ccbe5937": { + "balance": "0x10f0cf064dd59200000" + }, + "21ecb2dfa65779c7592d041cd2105a81f4fd4e46": { + "balance": "0x3635c9adc5dea00000" + }, + "21efbca09b3580b98e73f5b2f7f4dc0bf02c529c": { + "balance": "0x6c6b935b8bbd400000" + }, + "21fd0bade5f4ef7474d058b7f3d854cb1300524e": { + "balance": "0x1158e460913d00000" + }, + "21fd47c5256012198fa5abf131c06d6aa1965f75": { + "balance": "0x1ab2cf7c9f87e200000" + }, + "21fd6c5d97f9c600b76821ddd4e776350fce2be0": { + "balance": "0x6c6ad382d4fb610000" + }, + "220dc68df019b6b0ccbffb784b5a5ab4b15d4060": { + "balance": "0xd5967be4fc3f100000" + }, + "220e2b92c0f6c902b513d9f1e6fab6a8b0def3d7": { + "balance": "0x2b5e3af16b18800000" + }, + "22561c5931143536309c17e832587b625c390b9a": { + "balance": "0xd8d726b7177a800000" + }, + "2257fca16a6e5c2a647c3c29f36ce229ab93b17e": { + "balance": "0xd8d726b7177a800000" + }, + "225d35faedb391c7bc2db7fa9071160405996d00": { + "balance": "0x91854fc1862630000" + }, + "225f9eb3fb6ff3e9e3c8447e14a66e8d4f3779f6": { + "balance": "0x6c6b935b8bbd400000" + }, + "2272186ef27dcbe2f5fc373050fdae7f2ace2316": { + "balance": "0x368c8623a8b4d100000" + }, + "2273bad7bc4e487622d175ef7a66988b6a93c4ee": { + "balance": "0x1158e460913d00000" + }, + "2276264bec8526c0c0f270677abaf4f0e441e167": { + "balance": "0x3635c9adc5dea00000" + }, + "228242f8336eecd8242e1f000f41937e71dffbbf": { + "balance": "0x10f0cf064dd59200000" + }, + "22842ab830da509913f81dd1f04f10af9edd1c55": { + "balance": "0x6c6b935b8bbd400000" + }, + "22944fbca9b57963084eb84df7c85fb9bcdfb856": { + "balance": "0xfc118fef90ba388000" + }, + "229cc4711b62755ea296445ac3b77fc633821cf2": { + "balance": "0x223e8b05219328000" + }, + "229e430de2b74f442651ddcdb70176bc054cad54": { + "balance": "0xbbf981bc4aaa8000" + }, + "229f4f1a2a4f540774505b4707a81de44410255b": { + "balance": "0x6c6b935b8bbd400000" + }, + "229ff80bf5708009a9f739e0f8b560914016d5a6": { + "balance": "0x1211ecb56d13488000" + }, + "22a25812ab56dcc423175ed1d8adacce33cd1810": { + "balance": "0x6449e84e47a8a80000" + }, + "22b96ab2cad55db100b53001f9e4db378104c807": { + "balance": "0x21e19e0c9bab2400000" + }, + "22bdffc240a88ff7431af3bff50e14da37d5183e": { + "balance": "0x3635c9adc5dea00000" + }, + "22ce349159eeb144ef06ff2636588aef79f62832": { + "balance": "0xa31062beeed700000" + }, + "22db559f2c3c1475a2e6ffe83a5979599196a7fa": { + "balance": "0x3635c9adc5dea00000" + }, + "22e15158b5ee3e86eb0332e3e6a9ac6cd9b55ecd": { + "balance": "0x8ac7230489e800000" + }, + "22e2488e2da26a49ae84c01bd54b21f2947891c6": { + "balance": "0x5dc892aa1131c80000" + }, + "22e512149a18d369b73c71efa43e86c9edabaf1d": { + "balance": "0x4ee02e6714615c0000" + }, + "22eb7db0ba56b0f8b816ccb206e615d929185b0d": { + "balance": "0x45d29737e22f20000" + }, + "22eed327f8eb1d1338a3cb7b0f8a4baa5907cd95": { + "balance": "0x1455d5f4877088000" + }, + "22f004df8de9e6ebf523ccace457accb26f97281": { + "balance": "0x21e19e0c9bab2400000" + }, + "22f2dcff5ad78c3eb6850b5cb951127b659522e6": { + "balance": "0xbe202d6a0eda0000" + }, + "22f3c779dd79023ea92a78b65c1a1780f62d5c4a": { + "balance": "0x6acb3df27e1f880000" + }, + "22fe884d9037291b4d52e6285ae68dea0be9ffb5": { + "balance": "0x6c6b935b8bbd400000" + }, + "2306df931a940d58c01665fa4d0800802c02edfe": { + "balance": "0x3635c9adc5dea00000" + }, + "2309d34091445b3232590bd70f4f10025b2c9509": { + "balance": "0x21e19e0c9bab2400000" + }, + "23120046f6832102a752a76656691c863e17e59c": { + "balance": "0x11e0e4f8a50bd40000" + }, + "231a15acc199c89fa9cb22441cc70330bdcce617": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "231d94155dbcfe2a93a319b6171f63b20bd2b6fa": { + "balance": "0xcf147bb906e2f80000" + }, + "232832cd5977e00a4c30d0163f2e24f088a6cb09": { + "balance": "0xa2a15d09519be00000" + }, + "232c6d03b5b6e6711efff190e49c28eef36c82b0": { + "balance": "0x487a9a304539440000" + }, + "232cb1cd49993c144a3f88b3611e233569a86bd6": { + "balance": "0x34c606c42d0ac600000" + }, + "232ce782506225fd9860a2edc14a7a3047736da2": { + "balance": "0x1158e460913d00000" + }, + "232f525d55859b7d4e608d20487faadb00293135": { + "balance": "0xd8d726b7177a800000" + }, + "2334c590c7a48769103045c5b6534c8a3469f44a": { + "balance": "0x3b199073df72dc00000" + }, + "23376ecabf746ce53321cf42c86649b92b67b2ff": { + "balance": "0x6c6b935b8bbd400000" + }, + "23378f42926d0184b793b0c827a6dd3e3d334fcd": { + "balance": "0x30927f74c9de00000" + }, + "233842b1d0692fd11140cf5acda4bf9630bae5f8": { + "balance": "0x6c6b935b8bbd400000" + }, + "2339e9492870afea2537f389ac2f838302a33c06": { + "balance": "0x6c6b935b8bbd400000" + }, + "233bdddd5da94852f4ade8d212885682d9076bc6": { + "balance": "0xd8d726b7177a800000" + }, + "234f46bab73fe45d31bf87f0a1e0466199f2ebac": { + "balance": "0x1a4aba225c20740000" + }, + "23551f56975fe92b31fa469c49ea66ee6662f41e": { + "balance": "0x678a932062e4180000" + }, + "23569542c97d566018c907acfcf391d14067e87e": { + "balance": "0x6c6b935b8bbd400000" + }, + "235fa66c025ef5540070ebcf0d372d8177c467ab": { + "balance": "0x7129e1cdf373ee00000" + }, + "2372c4c1c9939f7aaf6cfac04090f00474840a09": { + "balance": "0x21e19e0c9bab2400000" + }, + "23730c357a91026e44b1d0e2fc2a51d071d8d77b": { + "balance": "0xd8d726b7177a800000" + }, + "2376ada90333b1d181084c97e645e810aa5b76f1": { + "balance": "0x28a857425466f80000" + }, + "2378fd4382511e968ed192106737d324f454b535": { + "balance": "0x3635c9adc5dea00000" + }, + "2382a9d48ec83ea3652890fd0ee79c907b5b2dc1": { + "balance": "0x73f75d1a085ba0000" + }, + "2383c222e67e969190d3219ef14da37850e26c55": { + "balance": "0x6c6b935b8bbd400000" + }, + "238a6b7635252f5244486c0af0a73a207385e039": { + "balance": "0x4a4491bd6dcd280000" + }, + "239a733e6b855ac592d663156186a8a174d2449e": { + "balance": "0x58be3758b241f60000" + }, + "23ab09e73f87aa0f3be0139df0c8eb6be5634f95": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "23abd9e93e7957e5b636be6579051c15e5ce0b0e": { + "balance": "0x3a3c8f7cbf42c380000" + }, + "23b1c4917fbd93ee3d48389306957384a5496cbf": { + "balance": "0xd8d8583fa2d52f0000" + }, + "23ba3864da583dab56f420873c37679690e02f00": { + "balance": "0x21342520d5fec200000" + }, + "23c55aeb5739876f0ac8d7ebea13be729685f000": { + "balance": "0x487a9a304539440000" + }, + "23c99ba087448e19c9701df66e0cab52368331fa": { + "balance": "0x6c6b935b8bbd400000" + }, + "23ccc3c6acd85c2e460c4ffdd82bc75dc849ea14": { + "balance": "0xd8d726b7177a800000" + }, + "23cd2598a20e149ead2ad69379576ecedb60e38e": { + "balance": "0x6c6b935b8bbd400000" + }, + "23df8f48ee009256ea797e1fa369beebcf6bc663": { + "balance": "0x7cd3fac26d19818000" + }, + "23e2c6a8be8e0acfa5c4df5e36058bb7cbac5a81": { + "balance": "0x6c6b935b8bbd400000" + }, + "23ea669e3564819a83b0c26c00a16d9e826f6c46": { + "balance": "0x4d8d6ca968ca130000" + }, + "23eb6fd85671a9063ab7678ebe265a20f61a02b3": { + "balance": "0x6c6b935b8bbd400000" + }, + "23f9ecf3e5dddca38815d3e59ed34b5b90b4a353": { + "balance": "0xb1781a3f0bb200000" + }, + "23fa7eb51a48229598f97e762be0869652dffc66": { + "balance": "0x3635c9adc5dea00000" + }, + "240305727313d01e73542c775ff59d11cd35f819": { + "balance": "0x141885666807f5c8000" + }, + "24046b91da9b61b629cb8b8ec0c351a07e0703e4": { + "balance": "0x6c6b935b8bbd400000" + }, + "240e559e274aaef0c258998c979f671d1173b88b": { + "balance": "0xd8d726b7177a800000" + }, + "241361559feef80ef137302153bd9ed2f25db3ef": { + "balance": "0x43c33c1937564800000" + }, + "243b3bca6a299359e886ce33a30341fafe4d573d": { + "balance": "0x43c33c1937564800000" + }, + "243c84d12420570cc4ef3baba1c959c283249520": { + "balance": "0x7f1f6993a853040000" + }, + "24434a3e32e54ecf272fe3470b5f6f512f675520": { + "balance": "0x14061b9d77a5e980000" + }, + "2448596f91c09baa30bc96106a2d37b5705e5d28": { + "balance": "0x6c6b935b8bbd400000" + }, + "24586ec5451735eeaaeb470dc8736aae752f82e5": { + "balance": "0xf43fc2c04ee00000" + }, + "2458d6555ff98a129cce4037953d00206eff4287": { + "balance": "0xaadec983fcff40000" + }, + "246291165b59332df5f18ce5c98856fae95897d6": { + "balance": "0x5c283d410394100000" + }, + "2467c6a5c696ede9a1e542bf1ad06bcc4b06aca0": { + "balance": "0x100bd33fb98ba0000" + }, + "2476b2bb751ce748e1a4c4ff7b230be0c15d2245": { + "balance": "0xd8d726b7177a800000" + }, + "247a0a11c57f0383b949de540b66dee68604b0a1": { + "balance": "0x39fbae8d042dd00000" + }, + "2487c3c4be86a2723d917c06b458550170c3edba": { + "balance": "0x3635c9adc5dea00000" + }, + "2489ac126934d4d6a94df08743da7b7691e9798e": { + "balance": "0x3635c9adc5dea00000" + }, + "249db29dbc19d1235da7298a04081c315742e9ac": { + "balance": "0x61acff81a78ad40000" + }, + "24a4eb36a7e498c36f99975c1a8d729fd6b305d7": { + "balance": "0xdfc78210eb2c80000" + }, + "24a750eae5874711116dd7d47b7186ce990d3103": { + "balance": "0xad78ebc5ac6200000" + }, + "24aa1151bb765fa3a89ca50eb6e1b1c706417fd4": { + "balance": "0xa80d24677efef00000" + }, + "24aca08d5be85ebb9f3132dfc1b620824edfedf9": { + "balance": "0xfc936392801c0000" + }, + "24b2be118b16d8b2174769d17b4cf84f07ca946d": { + "balance": "0x6c6b935b8bbd400000" + }, + "24b8b446debd1947955dd084f2c544933346d3ad": { + "balance": "0xea696d904039bd8000" + }, + "24b95ebef79500baa0eda72e77f877415df75c33": { + "balance": "0x3154c9729d05780000" + }, + "24b9e6644f6ba4cde126270d81f6ab60f286dff4": { + "balance": "0x73f75d1a085ba0000" + }, + "24bd5904059091d2f9e12d6a26a010ca22ab14e8": { + "balance": "0x65ea3db75546600000" + }, + "24c0c88b54a3544709828ab4ab06840559f6c5e2": { + "balance": "0x90f534608a72880000" + }, + "24c117d1d2b3a97ab11a4679c99a774a9eade8d1": { + "balance": "0x3635c9adc5dea00000" + }, + "24cff0e9336a9f80f9b1cb968caf6b1d1c4932a4": { + "balance": "0xada55474b81340000" + }, + "24daaaddf7b06bbcea9b80590085a88567682b4e": { + "balance": "0x114b2015d2bbd00000" + }, + "24dcc24bd9c7210ceacfb30da98ae04a4d7b8ab9": { + "balance": "0x3635c9adc5dea00000" + }, + "24f7450ddbf18b020feb1a2032d9d54b633edf37": { + "balance": "0x2b5e3af16b1880000" + }, + "24fc73d20793098e09ddab5798506224fa1e1850": { + "balance": "0xad78ebc5ac6200000" + }, + "24fd9a6c874c2fab3ff36e9afbf8ce0d32c7de92": { + "balance": "0x487a9a304539440000" + }, + "250a40cef3202397f240469548beb5626af4f23c": { + "balance": "0x503b203e9fba20000" + }, + "250a69430776f6347703f9529783955a6197b682": { + "balance": "0x692ae8897081d00000" + }, + "250eb7c66f869ddf49da85f3393e980c029aa434": { + "balance": "0xd8d726b7177a800000" + }, + "25106ab6755df86d6b63a187703b0cfea0e594a0": { + "balance": "0x17c405ad41db40000" + }, + "25185f325acf2d64500698f65c769ddf68301602": { + "balance": "0x10f0cf064dd59200000" + }, + "251c12722c6879227992a304eb3576cd18434ea5": { + "balance": "0x6c6b935b8bbd400000" + }, + "251e6838f7cec5b383c1d90146341274daf8e502": { + "balance": "0x7ff1ccb7561df0000" + }, + "25259d975a21d83ae30e33f800f53f37dfa01938": { + "balance": "0x1158e460913d00000" + }, + "25287b815f5c82380a73b0b13fbaf982be24c4d3": { + "balance": "0x22b1c8c1227a00000" + }, + "252b6555afdc80f2d96d972d17db84ea5ad521ac": { + "balance": "0x1ab2cf7c9f87e200000" + }, + "2538532936813c91e653284f017c80c3b8f8a36f": { + "balance": "0x6c8754c8f30c080000" + }, + "253e32b74ea4490ab92606fda0aa257bf23dcb8b": { + "balance": "0x21e19e0c9bab2400000" + }, + "253f1e742a2cec86b0d7b306e5eacb6ccb2f8554": { + "balance": "0x43e5ede1f878c200000" + }, + "2541314a0b408e95a694444977712a50713591ab": { + "balance": "0x589e1a5df4d7b50000" + }, + "254c1ecc630c2877de8095f0a8dba1e8bf1f550c": { + "balance": "0x5c283d410394100000" + }, + "255abc8d08a096a88f3d6ab55fbc7352bddcb9ce": { + "balance": "0x4743682313ede8000" + }, + "255bdd6474cc8262f26a22c38f45940e1ceea69b": { + "balance": "0xd8d726b7177a800000" + }, + "2560b09b89a4ae6849ed5a3c9958426631714466": { + "balance": "0x5c283d410394100000" + }, + "2561a138dcf83bd813e0e7f108642be3de3d6f05": { + "balance": "0x3634f48417401a0000" + }, + "2561ec0f379218fe5ed4e028a3f744aa41754c72": { + "balance": "0xb98bc829a6f90000" + }, + "256292a191bdda34c4da6b6bd69147bf75e2a9ab": { + "balance": "0xc2ff2e0dfb038000" + }, + "25697ef20cccaa70d32d376f8272d9c1070c3d78": { + "balance": "0xad78ebc5ac6200000" + }, + "256fa150cc87b5056a07d004efc84524739e62b5": { + "balance": "0xad78ebc5ac6200000" + }, + "25721c87b0dc21377c7200e524b14a22f0af69fb": { + "balance": "0xd8d726b7177a800000" + }, + "258939bbf00c9de9af5338f5d714abf6d0c1c671": { + "balance": "0x54069233bf7f780000" + }, + "2590126870e0bde8a663ab040a72a5573d8d41c2": { + "balance": "0x10f0cf064dd59200000" + }, + "259ec4d265f3ab536b7c70fa97aca142692c13fc": { + "balance": "0x11b1b5bea89f80000" + }, + "25a500eeec7a662a841552b5168b707b0de21e9e": { + "balance": "0x21f2f6f0fc3c6100000" + }, + "25a5a44d38a2f44c6a9db9cdbc6b1e2e97abb509": { + "balance": "0x39992648a23c8a00000" + }, + "25a74c2ac75dc8baa8b31a9c7cb4b7829b2456da": { + "balance": "0x6c6b935b8bbd400000" + }, + "25adb8f96f39492c9bb47c5edc88624e46075697": { + "balance": "0x5a9940bc56879500000" + }, + "25aee68d09afb71d8817f3f184ec562f7897b734": { + "balance": "0x6c6b935b8bbd400000" + }, + "25b0533b81d02a617b9229c7ec5d6f2f672e5b5a": { + "balance": "0x3635c9adc5dea00000" + }, + "25b78c9fad85b43343f0bfcd0fac11c9949ca5eb": { + "balance": "0x6c6b935b8bbd400000" + }, + "25bc49ef288cd165e525c661a812cf84fbec8f33": { + "balance": "0x125921aebda9d00000" + }, + "25bdfa3ee26f3849617b230062588a97e3cae701": { + "balance": "0x3635e619bb04d40000" + }, + "25c1a37ee5f08265a1e10d3d90d5472955f97806": { + "balance": "0x62a992e53a0af00000" + }, + "25c6e74ff1d928df98137af4df8430df24f07cd7": { + "balance": "0x15245655b102580000" + }, + "25cfc4e25c35c13b69f7e77dbfb08baf58756b8d": { + "balance": "0x878678326eac9000000" + }, + "25dad495a11a86b9eeece1eeec805e57f157faff": { + "balance": "0x3635c9adc5dea000000" + }, + "25e037f00a18270ba5ec3420229ddb0a2ce38fa2": { + "balance": "0x21e19e0c9bab2400000" + }, + "25e661c939863acc044e6f17b5698cce379ec3cc": { + "balance": "0x4a4491bd6dcd280000" + }, + "26048fe84d9b010a62e731627e49bc2eb73f408f": { + "balance": "0xd8d726b7177a800000" + }, + "2606c3b3b4ca1b091498602cb1978bf3b95221c0": { + "balance": "0x15af1d78b58c400000" + }, + "260a230e4465077e0b14ee4442a482d5b0c914bf": { + "balance": "0x5af606a06b5b118000" + }, + "260df8943a8c9a5dba7945327fd7e0837c11ad07": { + "balance": "0xad78ebc5ac6200000" + }, + "2614f42d5da844377578e6b448dc24305bef2b03": { + "balance": "0x6c6b935b8bbd400000" + }, + "2615100ea7e25bba9bca746058afbbb4ffbe4244": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "261575e9cf59c8226fa7aaf91de86fb70f5ac3ae": { + "balance": "0x1043a4436a523f0000" + }, + "261e0fa64c51137465eecf5b90f197f7937fdb05": { + "balance": "0x3cfc82e37e9a7400000" + }, + "262a8bfd7d9dc5dd3ad78161b6bb560824373655": { + "balance": "0x3f6a8384072b760000" + }, + "262aed4bc0f4a4b2c6fb35793e835a49189cdfec": { + "balance": "0x21e19e0c9bab2400000" + }, + "262dc1364ccf6df85c43268ee182554dae692e29": { + "balance": "0x10b202fec74ced80000" + }, + "263814309de4e635cf585e0d365477fc40e66cf7": { + "balance": "0x7ea28327577080000" + }, + "2639eee9873ceec26fcc9454b548b9e7c54aa65c": { + "balance": "0x3635c9adc5dea00000" + }, + "263e57dacbe0149f82fe65a2664898866ff5b463": { + "balance": "0x80bfbefcb5f0bc00000" + }, + "26475419c06d5f147aa597248eb46cf7befa64a5": { + "balance": "0x58e7926ee858a00000" + }, + "264cc8086a8710f91b21720905912cd7964ae868": { + "balance": "0x1731790534df20000" + }, + "265383d68b52d034161bfab01ae1b047942fbc32": { + "balance": "0x47271dee20d745c0000" + }, + "2659facb1e83436553b5b42989adb8075f9953ed": { + "balance": "0x1976576771a5e0000" + }, + "266f2da7f0085ef3f3fa09baee232b93c744db2e": { + "balance": "0xcb49b44ba602d800000" + }, + "267148fd72c54f620a592fb92799319cc4532b5c": { + "balance": "0x1639e49bba16280000" + }, + "26784ade91c8a83a8e39658c8d8277413ccc9954": { + "balance": "0x14542ba12a337c00000" + }, + "267a7e6e82e1b91d51deddb644f0e96dbb1f7f7e": { + "balance": "0x1158e460913d00000" + }, + "2680713d40808e2a50ed013150a2a694b96a7f1d": { + "balance": "0x61093d7c2c6d380000" + }, + "2697b339813b0c2d964b2471eb1c606f4ecb9616": { + "balance": "0x3e8ef795d890c80000" + }, + "26a68eab905a8b3dce00e317308225dab1b9f6b8": { + "balance": "0x6b56051582a9700000" + }, + "26b11d066588ce74a572a85a6328739212aa8b40": { + "balance": "0x6c6b935b8bbd400000" + }, + "26babf42b267fdcf3861fdd4236a5e474848b358": { + "balance": "0x3635c9adc5dea00000" + }, + "26c0054b700d3a7c2dcbe275689d4f4cad16a335": { + "balance": "0x6c6b935b8bbd400000" + }, + "26c2ffc30efdc5273e76183a16c2698d6e531286": { + "balance": "0x2a1129d09367200000" + }, + "26c99f8849c9802b83c861217fd07a9e84cdb79d": { + "balance": "0x1043561a8829300000" + }, + "26cfffd052152bb3f957b478d5f98b233a7c2b92": { + "balance": "0xd8d726b7177a800000" + }, + "26d4a16891f52922789217fcd886f7fce296d400": { + "balance": "0x6c6b935b8bbd400000" + }, + "26d4ec17d5ceb2c894bdc59d0a6a695dad2b43cc": { + "balance": "0x9f1f78761d341a0000" + }, + "26e801b62c827191dd68d31a011990947fd0ebe0": { + "balance": "0x1158e460913d00000" + }, + "26e9e2ad729702626417ef25de0dc800f7a779b3": { + "balance": "0x3635c9adc5dea00000" + }, + "26f9f7cefd7e394b9d3924412bf2c2831faf1f85": { + "balance": "0xd8d726b7177a800000" + }, + "26fe174cbf526650e0cd009bd6126502ce8e684d": { + "balance": "0x277017338a30ae00000" + }, + "26ff0a51e7cece8400276978dbd6236ef162c0e6": { + "balance": "0x152e185627540a500000" + }, + "27101a0f56d39a88c5a84f9b324cdde33e5cb68c": { + "balance": "0x6c6b935b8bbd400000" + }, + "27144ca9a7771a836ad50f803f64d869b2ae2b20": { + "balance": "0xd8d726b7177a800000" + }, + "27146913563aa745e2588430d9348e86ea7c3510": { + "balance": "0x15af1d78b58c400000" + }, + "271d3d481cb88e7671ad216949b6365e06303de0": { + "balance": "0xd8d726b7177a800000" + }, + "2720f9ca426ef2f2cbd2fecd39920c4f1a89e16d": { + "balance": "0x6c6b935b8bbd400000" + }, + "272a131a5a656a7a3aca35c8bd202222a7592258": { + "balance": "0x90f534608a72880000" + }, + "2744ff67464121e35afc2922177164fa2fcb0267": { + "balance": "0x56bc75e2d63100000" + }, + "274a3d771a3d709796fbc4d5f48fce2fe38c79d6": { + "balance": "0x1158e460913d00000" + }, + "274d69170fe7141401882b886ac4618c6ae40edb": { + "balance": "0x33c5499031720c0000" + }, + "27521deb3b6ef1416ea4c781a2e5d7b36ee81c61": { + "balance": "0x6c6b935b8bbd400000" + }, + "275875ff4fbb0cf3a430213127487f7608d04cba": { + "balance": "0x1b1c010e766d580000" + }, + "276a006e3028ecd44cdb62ba0a77ce94ebd9f10f": { + "balance": "0x6194049f30f7200000" + }, + "276b0521b0e68b277df0bb32f3fd48326350bfb2": { + "balance": "0x2b5e3af16b1880000" + }, + "276fd7d24f8f883f5a7a28295bf17151c7a84b03": { + "balance": "0x6c6b935b8bbd400000" + }, + "2770f14efb165ddeba79c10bb0af31c31e59334c": { + "balance": "0xa2a15d09519be00000" + }, + "277677aba1e52c3b53bfa2071d4e859a0af7e8e1": { + "balance": "0x3635c9adc5dea00000" + }, + "27824666d278d70423f03dfe1dc7a3f02f43e2b5": { + "balance": "0x3636c25e66ece70000" + }, + "27830c5f6023afaaf79745676c204a0faccda0ba": { + "balance": "0xd02ab486cedc00000" + }, + "2784903f1d7c1b5cd901f8875d14a79b3cbe2a56": { + "balance": "0x4bda7e9d74ad5500000" + }, + "278c0bde630ec393b1e7267fc9d7d97019e4145b": { + "balance": "0x6c6b935b8bbd400000" + }, + "27987110221a880826adb2e7ab5eca78c6e31aec": { + "balance": "0xd8d726b7177a800000" + }, + "27ac073be79ce657a93aa693ee43bf0fa41fef04": { + "balance": "0xa968163f0a57b400000" + }, + "27b1694eafa165ebd7cc7bc99e74814a951419dc": { + "balance": "0x2b5e3af16b18800000" + }, + "27b62816e1e3b8d19b79d1513d5dfa855b0c3a2a": { + "balance": "0x56af5c1fd69508000" + }, + "27bf943c1633fe32f8bcccdb6302b407a5724e44": { + "balance": "0x32f84c6df408c08000" + }, + "27bf9f44ba7d05c33540c3a53bb02cbbffe7c3c6": { + "balance": "0x6c6b935b8bbd400000" + }, + "27c2d7ca504daa3d9066dc09137dc42f3aaab452": { + "balance": "0x2086ac351052600000" + }, + "27d158ac3d3e1109ab6e570e90e85d3892cd7680": { + "balance": "0x56bc75e2d63100000" + }, + "27e63989ca1e903bc620cf1b9c3f67b9e2ae6581": { + "balance": "0x487a9a304539440000" + }, + "27f03cf1abc5e1b51dbc444b289e542c9ddfb0e6": { + "balance": "0x10f0cf064dd59200000" + }, + "27fc85a49cff90dbcfdadc9ddd40d6b9a2210a6c": { + "balance": "0x56bc75e2d63100000" + }, + "2805415e1d7fdec6dedfb89e521d10592d743c10": { + "balance": "0x56bc75e2d63100000" + }, + "28073efc17d05cab3195c2db332b61984777a612": { + "balance": "0x3635c9adc5dea00000" + }, + "281250a29121270a4ee5d78d24feafe82c70ba3a": { + "balance": "0x3635c9adc5dea00000" + }, + "2813d263fc5ff2479e970595d6b6b560f8d6d6d1": { + "balance": "0x6c6b935b8bbd400000" + }, + "282e80a554875a56799fa0a97f5510e795974c4e": { + "balance": "0x3635c9adc5dea00000" + }, + "283396ce3cac398bcbe7227f323e78ff96d08767": { + "balance": "0x15af1d78b58c400000" + }, + "28349f7ef974ea55fe36a1583b34cec3c45065f0": { + "balance": "0xcb633d49e65590000" + }, + "2836123046b284e5ef102bfd22b1765e508116ad": { + "balance": "0x1653fbb5c427e40000" + }, + "283c2314283c92d4b064f0aef9bb5246a7007f39": { + "balance": "0xad78ebc5ac6200000" + }, + "283e11203749b1fa4f32febb71e49d135919382a": { + "balance": "0x3635c9adc5dea00000" + }, + "283e6252b4efcf4654391acb75f903c59b78c5fb": { + "balance": "0x28a857425466f800000" + }, + "28510e6eff1fc829b6576f4328bc3938ec7a6580": { + "balance": "0x21e19e0c9bab2400000" + }, + "2858acacaf21ea81cab7598fdbd86b452e9e8e15": { + "balance": "0x241a9b4f617a280000" + }, + "285ae51b9500c58d541365d97569f14bb2a3709b": { + "balance": "0x6c6b935b8bbd400000" + }, + "2866b81decb02ee70ae250cee5cdc77b59d7b679": { + "balance": "0x6c6b935b8bbd400000" + }, + "286906b6bd4972e3c71655e04baf36260c7cb153": { + "balance": "0x126e72a69a50d00000" + }, + "286b186d61ea1fd78d9930fe12b06537b05c3d51": { + "balance": "0x3635c9adc5dea00000" + }, + "2874f3e2985d5f7b406627e17baa772b01abcc9e": { + "balance": "0x146050410765f380000" + }, + "287cf9d0902ef819a7a5f149445bf1775ee8c47c": { + "balance": "0x3635c9adc5dea000000" + }, + "28818e18b610001321b31df6fe7d2815cdadc9f5": { + "balance": "0x3635c9adc5dea00000" + }, + "28868324337e11ba106cb481da962f3a8453808d": { + "balance": "0x6c6b935b8bbd400000" + }, + "28904bb7c4302943b709b14d7970e42b8324e1a1": { + "balance": "0x21f97846a072d7e0000" + }, + "2895e80999d406ad592e2b262737d35f7db4b699": { + "balance": "0x692ae8897081d00000" + }, + "28967280214e218a120c5dda37041b111ea36d74": { + "balance": "0xad78ebc5ac6200000" + }, + "28a3da09a8194819ae199f2e6d9d1304817e28a5": { + "balance": "0x6c6b935b8bbd400000" + }, + "28ab165ffb69eda0c549ae38e9826f5f7f92f853": { + "balance": "0x464df6d7c844590000" + }, + "28b77585cb3d55a199ab291d3a18c68fe89a848a": { + "balance": "0x6a4076cf7995a00000" + }, + "28d4ebf41e3d3c451e943bdd7e1f175fae932a3d": { + "balance": "0x14542ba12a337c00000" + }, + "28d7e5866f1d85fd1ceb32bfbe1dfc36db434566": { + "balance": "0x1864231c610351c0000" + }, + "28d8c35fb7eea622582135e3ad47a227c9a663bd": { + "balance": "0xfc936392801c0000" + }, + "28e4af30cd93f686a122ad7bb19f8a8785eee342": { + "balance": "0x71e53b706cc7b40000" + }, + "28eaea78cd4d95faecfb68836eafe83520f3bbb7": { + "balance": "0xad78ebc5ac6200000" + }, + "28efae6356509edface89fc61a7fdcdb39eea8e5": { + "balance": "0x121ea68c114e5100000" + }, + "28fa2580f9ebe420f3e5eefdd371638e3b7af499": { + "balance": "0x14542ba12a337c00000" + }, + "2901f8077f34190bb47a8e227fa29b30ce113b31": { + "balance": "0x56bc75e2d63100000" + }, + "2905b192e83ce659aa355b9d0c204e3e95f9bb9a": { + "balance": "0x75235c1d00393e8000" + }, + "290a56d41f6e9efbdcea0342e0b7929a8cdfcb05": { + "balance": "0x12a5f58168ee600000" + }, + "2915624bcb679137b8dae9ab57d11b4905eaee4b": { + "balance": "0x1158e460913d00000" + }, + "291efe0081dce8c14799f7b2a43619c0c3b3fc1f": { + "balance": "0x410d586a20a4c00000" + }, + "291f929ca59b54f8443e3d4d75d95dee243cef78": { + "balance": "0x1b1a089237073d0000" + }, + "29298ccbdff689f87fe41aa6e98fdfb53deaf37a": { + "balance": "0x4315c32d71a9e600000" + }, + "292f228b0a94748c8eec612d246f989363e08f08": { + "balance": "0xa076407d3f7440000" + }, + "293384c42b6f8f2905ce52b7205c2274376c612b": { + "balance": "0x4be4e7267b6ae00000" + }, + "2934c0df7bbc172b6c186b0b72547ace8bf75454": { + "balance": "0x340aad21b3b700000" + }, + "293c2306df3604ae4fda0d207aba736f67de0792": { + "balance": "0xad78ebc5ac6200000" + }, + "2949fd1def5c76a286b3872424809a07db3966f3": { + "balance": "0x11bd906daa0c9438000" + }, + "294f494b3f2e143c2ffc9738cbfd9501850b874e": { + "balance": "0x796e3ea3f8ab000000" + }, + "2955c357fd8f75d5159a3dfa69c5b87a359dea8c": { + "balance": "0x6c6b935b8bbd400000" + }, + "2961fb391c61957cb5c9e407dda29338d3b92c80": { + "balance": "0x3634fb9f1489a70000" + }, + "29681d9912ddd07eaabb88d05d90f766e862417d": { + "balance": "0x3635c9adc5dea00000" + }, + "296b71c0015819c242a7861e6ff7eded8a5f71e3": { + "balance": "0x6c68ccd09b022c0000" + }, + "296d66b521571a4e4103a7f562c511e6aa732d81": { + "balance": "0x243d4d18229ca20000" + }, + "296f00de1dc3bb01d47a8ccd1e5d1dd9a1eb7791": { + "balance": "0x3635c9adc5dea00000" + }, + "297385e88634465685c231a314a0d5dcd146af01": { + "balance": "0x54069233bf7f780000" + }, + "29763dd6da9a7c161173888321eba6b63c8fb845": { + "balance": "0x11c7ea162e78200000" + }, + "2979741174a8c1ea0b7f9edf658177859417f512": { + "balance": "0x1901966c8496838000" + }, + "297a88921b5fca10e5bb9ded60025437ae221694": { + "balance": "0xad78ebc5ac6200000" + }, + "297d5dbe222f2fb52531acbd0b013dc446ac7368": { + "balance": "0x43c33c1937564800000" + }, + "29824e94cc4348bc963279dcdf47391715324cd3": { + "balance": "0x692ae8897081d00000" + }, + "2982d76a15f847dd41f1922af368fe678d0e681e": { + "balance": "0x56bc75e2d63100000" + }, + "298887bab57c5ba4f0615229d7525fa113b7ea89": { + "balance": "0x22b1c8c1227a00000" + }, + "298ec76b440d8807b3f78b5f90979bee42ed43db": { + "balance": "0x65a4da25d3016c00000" + }, + "299368609042a858d1ecdf1fc0ada5eaceca29cf": { + "balance": "0x6c6b935b8bbd400000" + }, + "299e0bca55e069de8504e89aca6eca21d38a9a5d": { + "balance": "0x302379bf2ca2e0000" + }, + "29ac2b458454a36c7e96c73a8667222a12242c71": { + "balance": "0xd8d726b7177a800000" + }, + "29adcf83b6b20ac6a434abb1993cbd05c60ea2e4": { + "balance": "0x21e19e0c9bab2400000" + }, + "29aef48de8c9fbad4b9e4ca970797a5533eb722d": { + "balance": "0x21e19e0c9bab2400000" + }, + "29b3f561ee7a6e25941e98a5325b78adc79785f3": { + "balance": "0x56bc75e2d63100000" + }, + "29bdc4f28de0180f433c2694eb74f5504ce94337": { + "balance": "0x6c6b935b8bbd400000" + }, + "29cc804d922be91f5909f348b0aaa5d21b607830": { + "balance": "0xd8d726b7177a800000" + }, + "29da3e35b23bb1f72f8e2258cf7f553359d24bac": { + "balance": "0x43c33c1937564800000" + }, + "29e67990e1b6d52e1055ffe049c53195a81542cf": { + "balance": "0x43c33c1937564800000" + }, + "29eaae82761762f4d2db53a9c68b0f6b0b6d4e66": { + "balance": "0x6c6b935b8bbd400000" + }, + "29eb7eefdae9feb449c63ff5f279d67510eb1422": { + "balance": "0x10d3aa536e2940000" + }, + "29f0edc60338e7112085a1d114da8c42ce8f55d6": { + "balance": "0xa05a7f0fd825780000" + }, + "29f8fba4c30772b057edbbe62ae7420c390572e1": { + "balance": "0x3635c9adc5dea00000" + }, + "29f9286c0e738d1721a691c6b95ab3d9a797ede8": { + "balance": "0x2a5a058fc295ed000000" + }, + "2a085e25b64862f5e68d768e2b0f7a8529858eee": { + "balance": "0x6b883acd5766cd0000" + }, + "2a2ab6b74c7af1d9476bb5bcb4524797bedc3552": { + "balance": "0x3635c9adc5dea00000" + }, + "2a39190a4fde83dfb3ddcb4c5fbb83ac6c49755c": { + "balance": "0x3635c9adc5dea00000" + }, + "2a400dff8594de7228b4fd15c32322b75bb87da8": { + "balance": "0x531a17f607a2d0000" + }, + "2a44a7218fe44d65a1b4b7a7d9b1c2c52c8c3e34": { + "balance": "0xd2d06c305a1eb578000" + }, + "2a46d353777176ff8e83ffa8001f4f70f9733aa5": { + "balance": "0x5bf0ba6634f680000" + }, + "2a595f16eee4cb0c17d9a2d939b3c10f6c677243": { + "balance": "0x3ba1910bf341b00000" + }, + "2a59e47ea5d8f0e7c028a3e8e093a49c1b50b9a3": { + "balance": "0x6c6b935b8bbd400000" + }, + "2a5ba9e34cd58da54c9a2712663a3be274c8e47b": { + "balance": "0xaadec983fcff40000" + }, + "2a5e3a40d2cd0325766de73a3d671896b362c73b": { + "balance": "0x152d02c7e14af6800000" + }, + "2a63590efe9986c3fee09b0a0a338b15bed91f21": { + "balance": "0x15e1c4e05ee26d00000" + }, + "2a67660a1368efcd626ef36b2b1b601980941c05": { + "balance": "0x73f75d1a085ba0000" + }, + "2a742b8910941e0932830a1d9692cfd28494cf40": { + "balance": "0x1b1ab319f5ec750000" + }, + "2a746cd44027af3ebd37c378c85ef7f754ab5f28": { + "balance": "0x155bd9307f9fe80000" + }, + "2a81d27cb6d4770ff4f3c4a3ba18e5e57f07517c": { + "balance": "0x6c6b935b8bbd400000" + }, + "2a91a9fed41b7d0e5cd2d83158d3e8a41a9a2d71": { + "balance": "0x692ae8897081d00000" + }, + "2a9c57fe7b6b138a920d676f3c76b6c2a0eef699": { + "balance": "0x1fd933494aa5fe00000" + }, + "2a9c96c19151ffcbe29a4616d0c52b3933b4659f": { + "balance": "0x3c1379b8765e18000" + }, + "2aa192777ca5b978b6b2c2ff800ac1860f753f47": { + "balance": "0x12290f15180bdc0000" + }, + "2aaa35274d742546670b7426264521032af4f4c3": { + "balance": "0x21e19e0c9bab2400000" + }, + "2aaea1f1046f30f109faec1c63ef5c7594eb08da": { + "balance": "0xd8d726b7177a800000" + }, + "2ab97e8d59eee648ab6caf8696f89937143864d6": { + "balance": "0xcf152640c5c8300000" + }, + "2abce1808940cd4ef5b5e05285f82df7a9ab5e03": { + "balance": "0x21342520d5fec200000" + }, + "2abdf1a637ef6c42a7e2fe217773d677e804ebdd": { + "balance": "0x10f0cf064dd59200000" + }, + "2ac1f8d7bf721f3cfe74d20fea9b87a28aaa982c": { + "balance": "0x8ba52e6fc45e40000" + }, + "2acc9c1a32240b4d5b2f777a2ea052b42fc1271c": { + "balance": "0x8d807ee14d836100000" + }, + "2ad6c9d10c261819a1a0ca2c48d8c7b2a71728df": { + "balance": "0x3635c9adc5dea00000" + }, + "2ae53866fc2d14d572ab73b4a065a1188267f527": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "2ae73a79aea0278533accf21070922b1613f8f32": { + "balance": "0xa7e94bbeae701a8000" + }, + "2ae82dab92a66389eea1abb901d1d57f5a7cca0b": { + "balance": "0x6c6b935b8bbd400000" + }, + "2aec809df9325b9f483996e99f7331097f08aa0e": { + "balance": "0xd8d726b7177a800000" + }, + "2aed2ce531c056b0097efc3c6de10c4762004ed9": { + "balance": "0x2356953ab7ddc380000" + }, + "2afb058c3d31032b353bf24f09ae20d54de57dbe": { + "balance": "0x3ba1910bf341b00000" + }, + "2b0362633614bfcb583569438ecc4ea57b1d337e": { + "balance": "0x43c33c1937564800000" + }, + "2b101e822cd962962a06800a2c08d3b15d82b735": { + "balance": "0x83d6c7aab63600000" + }, + "2b129c26b75dde127f8320bd0f63410c92a9f876": { + "balance": "0x77432217e683600000" + }, + "2b241f037337eb4acc61849bd272ac133f7cdf4b": { + "balance": "0x500b6bca962ab8400000" + }, + "2b3a68db6b0cae8a7c7a476bdfcfbd6205e10687": { + "balance": "0x821ab0d44149800000" + }, + "2b3cf97311ff30f460945a9d8099f4a88e26d456": { + "balance": "0x6c6b935b8bbd400000" + }, + "2b49fba29830360fcdb6da23bbfea5c0bbac5281": { + "balance": "0x1158e460913d00000" + }, + "2b4f4507bb6b9817942ce433781b708fbcd166fd": { + "balance": "0xfc936392801c0000" + }, + "2b5016e2457387956562587115aa8759d8695fdf": { + "balance": "0x2a5a058fc295ed000000" + }, + "2b5c60e84535eeb4d580de127a12eb2677ccb392": { + "balance": "0x43c33c1937564800000" + }, + "2b5ced9987c0765f900e49cf9da2d9f9c1138855": { + "balance": "0x15af1d78b58c400000" + }, + "2b5f4b3f1e11707a227aa5e69fa49dded33fb321": { + "balance": "0x14542ba12a337c00000" + }, + "2b68306ba7f8daaf73f4c644ef7d2743c0f26856": { + "balance": "0x2ee182ca17ddd00000" + }, + "2b6ed29a95753c3ad948348e3e7b1a251080ffb9": { + "balance": "0x34f086f3b33b68400000" + }, + "2b701d16c0d3cc1e4cd85445e6ad02eea4ac012d": { + "balance": "0x2086ac351052600000" + }, + "2b717cd432a323a4659039848d3b87de26fc9546": { + "balance": "0x69e10de76676d0800000" + }, + "2b74c373d04bfb0fd60a18a01a88fbe84770e58c": { + "balance": "0x22b1c8c1227a00000" + }, + "2b77a4d88c0d56a3dbe3bae04a05f4fcd1b757e1": { + "balance": "0x1043561a8829300000" + }, + "2b8488bd2d3c197a3d26151815b5a798d27168dc": { + "balance": "0x16a1f9f5fd7d9600000" + }, + "2b8a0dee5cb0e1e97e15cfca6e19ad21f995efad": { + "balance": "0x1b55438d9a249b0000" + }, + "2b8fe4166e23d11963c0932b8ade8e0145ea0770": { + "balance": "0x92896529baddc880000" + }, + "2b99b42e4f42619ee36baa7e4af2d65eacfcba35": { + "balance": "0x878678326eac9000000" + }, + "2bab0fbe28d58420b52036770a12f9952aea6911": { + "balance": "0xcf152640c5c8300000" + }, + "2bade91d154517620fd4b439ac97157a4102a9f7": { + "balance": "0xd8d726b7177a800000" + }, + "2baf8d6e221174124820ee492b9459ec4fadafbb": { + "balance": "0x6c6b935b8bbd400000" + }, + "2bafbf9e9ed2c219f7f2791374e7d05cb06777e7": { + "balance": "0xbed1d0263d9f00000" + }, + "2bb366b9edcb0da680f0e10b3b6e28748190d6c3": { + "balance": "0x13a62d7b57640640000" + }, + "2bb6f578adfbe7b2a116b3554facf9969813c319": { + "balance": "0x19127a1391ea2a00000" + }, + "2bbe62eac80ca7f4d6fdee7e7d8e28b63acf770e": { + "balance": "0x81e32df972abf00000" + }, + "2bbe672a1857508f630f2a5edb563d9e9de92815": { + "balance": "0x6c6b935b8bbd400000" + }, + "2bc429d618a66a4cf82dbb2d824e9356effa126a": { + "balance": "0x6c6acc67d7b1d40000" + }, + "2bd252e0d732ff1d7c78f0a02e6cb25423cf1b1a": { + "balance": "0x90f534608a72880000" + }, + "2bdd03bebbee273b6ca1059b34999a5bbd61bb79": { + "balance": "0x1158e460913d00000" + }, + "2c04115c3e52961b0dc0b0bf31fba4546f5966fd": { + "balance": "0xad78ebc5ac6200000" + }, + "2c06dd922b61514aafedd84488c0c28e6dcf0e99": { + "balance": "0x152d02c7e14af6800000" + }, + "2c0cc3f951482cc8a2925815684eb9f94e060200": { + "balance": "0x14542ba12a337c00000" + }, + "2c0ee134d8b36145b47beee7af8d2738dbda08e8": { + "balance": "0xae56f730e6d840000" + }, + "2c0f5b9df43625798e7e03c1a5fd6a6d091af82b": { + "balance": "0x1b0fcaab200300000" + }, + "2c128c95d957215101f043dd8fc582456d41016d": { + "balance": "0x2d43f3ebfafb2c0000" + }, + "2c1800f35fa02d3eb6ff5b25285f5e4add13b38d": { + "balance": "0x3122d3adafde100000" + }, + "2c1c19114e3d6de27851484b8d2715e50f8a1065": { + "balance": "0x56bc75e2d63100000" + }, + "2c1cc6e18c152488ba11c2cc1bcefa2df306abd1": { + "balance": "0x5a87e7d7f5f6580000" + }, + "2c1df8a76f48f6b54bcf9caf56f0ee1cf57ab33d": { + "balance": "0x2247f750089da580000" + }, + "2c2147947ae33fb098b489a5c16bfff9abcd4e2a": { + "balance": "0xad78ebc5ac6200000" + }, + "2c234f505ca8dcc77d9b7e01d257c318cc19396d": { + "balance": "0x56bc75e2d63100000" + }, + "2c2428e4a66974edc822d5dbfb241b2728075158": { + "balance": "0x6c6b935b8bbd400000" + }, + "2c2d15ff39561c1b72eda1cc027ffef23743a144": { + "balance": "0xd480ed9ef32b400000" + }, + "2c2db28c3309375eea3c6d72cd6d0eec145afcc0": { + "balance": "0x6c6b935b8bbd400000" + }, + "2c424ee47f583cdce07ae318b6fad462381d4d2b": { + "balance": "0xd8d726b7177a800000" + }, + "2c4b470307a059854055d91ec3794d80b53d0f4a": { + "balance": "0x43c33c1937564800000" + }, + "2c52c984102ee0cd3e31821b84d408930efa1ac7": { + "balance": "0x6c6b935b8bbd400000" + }, + "2c5a2d0abda03bbe215781b4ff296c8c61bdbaf6": { + "balance": "0x1a8e56f48c0228000" + }, + "2c5b7d7b195a371bf9abddb42fe04f2f1d9a9910": { + "balance": "0xad78ebc5ac6200000" + }, + "2c5df866666a194b26cebb407e4a1fd73e208d5e": { + "balance": "0x3635c9adc5dea00000" + }, + "2c603ff0fe93616c43573ef279bfea40888d6ae7": { + "balance": "0x100f4b6d66757900000" + }, + "2c6846a1aa999a2246a287056000ba4dcba8e63d": { + "balance": "0x21f2f6f0fc3c6100000" + }, + "2c6afcd4037c1ed14fa74ff6758e0945a185a8e8": { + "balance": "0xf43fc2c04ee00000" + }, + "2c6b699d9ead349f067f45711a074a641db6a897": { + "balance": "0x1158e460913d00000" + }, + "2c6f5c124cc789f8bb398e3f889751bc4b602d9e": { + "balance": "0x159f20bed00f00000" + }, + "2c83aeb02fcf067d65a47082fd977833ab1cec91": { + "balance": "0x8273823258ac00000" + }, + "2c89f5fdca3d155409b638b98a742e55eb4652b7": { + "balance": "0x14dbb2195ca228900000" + }, + "2c964849b1f69cc7cea4442538ed87fdf16cfc8f": { + "balance": "0x6c6b935b8bbd400000" + }, + "2c9fa72c95f37d08e9a36009e7a4b07f29bad41a": { + "balance": "0xdf6eb0b2d3ca0000" + }, + "2caf6bf4ec7d5a19c5e0897a5eeb011dcece4210": { + "balance": "0x7934835a031160000" + }, + "2cb4c3c16bb1c55e7c6b7a19b127a1ac9390cc09": { + "balance": "0xb82794a9244f0c8000" + }, + "2cb5495a505336c2465410d1cae095b8e1ba5cdd": { + "balance": "0x43c33c1937564800000" + }, + "2cb615073a40dcdb99faa848572e987b3b056efb": { + "balance": "0x2b58addb89a2580000" + }, + "2cba6d5d0dc204ea8a25ada2e26f5675bd5f2fdc": { + "balance": "0x4823ef7ddb9af38000" + }, + "2cbb0c73df91b91740b6693b774a7d05177e8e58": { + "balance": "0x6449e84e47a8a80000" + }, + "2ccb66494d0af689abf9483d365d782444e7dead": { + "balance": "0x3635c9adc5dea00000" + }, + "2ccc1f1cb5f4a8002e186b20885d9dbc030c0894": { + "balance": "0x6c6b935b8bbd400000" + }, + "2ccf80e21898125eb4e807cd82e09b9d28592f6e": { + "balance": "0x6c6b935b8bbd400000" + }, + "2cd19694d1926a0fa9189edebafc671cf1b2caa5": { + "balance": "0x3635c9adc5dea00000" + }, + "2cd39334ac7eac797257abe3736195f5b4b5ce0f": { + "balance": "0x56b47785e37260000" + }, + "2cd79eb52027b12c18828e3eaab2969bfcd287e9": { + "balance": "0x1158e460913d00000" + }, + "2cd87866568dd81ad47d9d3ad0846e5a65507373": { + "balance": "0x15af1d78b58c400000" + }, + "2cdb3944650616e47cb182e060322fa1487978ce": { + "balance": "0x62a992e53a0af00000" + }, + "2ce11a92fad024ff2b3e87e3b542e6c60dcbd996": { + "balance": "0xd8d726b7177a800000" + }, + "2d0326b23f0409c0c0e9236863a133075a94ba18": { + "balance": "0xb679be75be6ae0000" + }, + "2d0dec51a6e87330a6a8fa2a0f65d88d4abcdf73": { + "balance": "0xa076407d3f7440000" + }, + "2d23766b6f6b05737dad80a419c40eda4d77103e": { + "balance": "0xcf152640c5c8300000" + }, + "2d2b032359b363964fc11a518263bfd05431e867": { + "balance": "0x81c1df7629e700000" + }, + "2d3480bf0865074a72c7759ee5137b4d70c51ce9": { + "balance": "0xad78ebc5ac6200000" + }, + "2d35a9df62757f7ffad1049afb06ca4afc464c51": { + "balance": "0x1158e460913d00000" + }, + "2d40558b06f90a3923145592123b6774e46e31f4": { + "balance": "0x3635c9adc5dea00000" + }, + "2d426912d059fad9740b2e390a2eeac0546ff01b": { + "balance": "0x4be4e7267b6ae00000" + }, + "2d532df4c63911d1ce91f6d1fcbff7960f78a885": { + "balance": "0x5a85968a5878da8000" + }, + "2d5391e938b34858cf965b840531d5efda410b09": { + "balance": "0x4be4e7267b6ae00000" + }, + "2d5b42fc59ebda0dfd66ae914bc28c1b0a6ef83a": { + "balance": "0x2bc8b59fdcd836638000" + }, + "2d5d7335acb0362b47dfa3a8a4d3f5949544d380": { + "balance": "0xad78ebc5ac6200000" + }, + "2d61bfc56873923c2b00095dc3eaa0f590d8ae0f": { + "balance": "0x46566dff8ce55600000" + }, + "2d6511fd7a3800b26854c7ec39c0dcb5f4c4e8e8": { + "balance": "0x15adddba2f9e770000" + }, + "2d7d5c40ddafc450b04a74a4dabc2bb5d665002e": { + "balance": "0x6c6b935b8bbd400000" + }, + "2d89a8006a4f137a20dc2bec46fe2eb312ea9654": { + "balance": "0xad78ebc5ac6200000" + }, + "2d8c52329f38d2a2fa9cbaf5c583daf1490bb11c": { + "balance": "0x1158e460913d00000" + }, + "2d8e061892a5dcce21966ae1bb0788fd3e8ba059": { + "balance": "0xd8e5ce617f2d50000" + }, + "2d8e5bb8d3521695c77e7c834e0291bfacee7408": { + "balance": "0x6acb3df27e1f880000" + }, + "2d90b415a38e2e19cdd02ff3ad81a97af7cbf672": { + "balance": "0x5f3c7f64131e40000" + }, + "2d9bad6f1ee02a70f1f13def5cccb27a9a274031": { + "balance": "0x61093d7c2c6d380000" + }, + "2d9c5fecd2b44fbb6a1ec732ea059f4f1f9d2b5c": { + "balance": "0x36ca32661d1aa70000" + }, + "2da617695009cc57d26ad490b32a5dfbeb934e5e": { + "balance": "0x43c33c1937564800000" + }, + "2da76b7c39b420e388ba2c1020b0856b0270648a": { + "balance": "0x6c6b935b8bbd400000" + }, + "2dc79d6e7f55bce2e2d0c02ad07ceca8bb529354": { + "balance": "0x55a6e79ccd1d300000" + }, + "2dca0e449ab646dbdfd393a96662960bcab5ae1e": { + "balance": "0x878678326eac9000000" + }, + "2dd325fdffb97b19995284afa5abdb574a1df16a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "2dd578f7407dfbd548d05e95ccc39c485429626a": { + "balance": "0xe3aeb5737240a00000" + }, + "2dd8eeef87194abc2ce7585da1e35b7cea780cb7": { + "balance": "0x3635c6204739d98000" + }, + "2ddf40905769bcc426cb2c2938ffe077e1e89d98": { + "balance": "0xa2a15d09519be00000" + }, + "2de0964400c282bdd78a919c6bf77c6b5f796179": { + "balance": "0xad78ebc5ac6200000" + }, + "2de31afd189a13a76ff6fe73ead9f74bb5c4a629": { + "balance": "0x14542ba12a337c00000" + }, + "2dec98329d1f96c3a59caa7981755452d4da49d5": { + "balance": "0xad78ebc5ac6200000" + }, + "2dee90a28f192d676a8773232b56f18f239e2fad": { + "balance": "0x3efa7e747b6d1ad0000" + }, + "2e0880a34596230720f05ac8f065af8681dcb6c2": { + "balance": "0x152d02c7e14af6800000" + }, + "2e0c57b47150f95aa6a7e16ab9b1cbf54328979a": { + "balance": "0x56bc75e2d63100000" + }, + "2e10910ba6e0bc17e055556614cb87090f4d7e5b": { + "balance": "0xad78ebc5ac6200000" + }, + "2e24b597873bb141bdb237ea8a5ab747799af02d": { + "balance": "0x43c33c1937564800000" + }, + "2e2810dee44ae4dff3d86342ab126657d653c336": { + "balance": "0xad78ebc5ac6200000" + }, + "2e2cbd7ad82547b4f5ff8b3ab56f942a6445a3b0": { + "balance": "0xad78ebc5ac6200000" + }, + "2e2d7ea66b9f47d8cc52c01c52b6e191bc7d4786": { + "balance": "0xd8d4602c26bf6c0000" + }, + "2e439348df8a4277b22a768457d1158e97c40904": { + "balance": "0x2a1e9ff26fbf410000" + }, + "2e46fcee6a3bb145b594a243a3913fce5dad6fba": { + "balance": "0x21e19e0c9bab2400000" + }, + "2e47f287f498233713850d3126823cc67dcee255": { + "balance": "0xca9d9ea558b40000" + }, + "2e4ee1ae996aa0a1d92428d06652a6bea6d2d15d": { + "balance": "0x6c6b935b8bbd400000" + }, + "2e52912bc10ea39d54e293f7aed6b99a0f4c73be": { + "balance": "0x15af1d78b58c400000" + }, + "2e619f57abc1e987aa936ae3a2264962e7eb2d9a": { + "balance": "0x28fb9b8a8a53500000" + }, + "2e64a8d71111a22f4c5de1e039b336f68d398a7c": { + "balance": "0x6c6b935b8bbd400000" + }, + "2e6933543d4f2cc00b5350bd8068ba9243d6beb0": { + "balance": "0x6c6b935b8bbd400000" + }, + "2e7e05e29edda7e4ae25c5173543efd71f6d3d80": { + "balance": "0x14542ba12a337c00000" + }, + "2e7f465520ec35cc23d68e75651bb6689544a196": { + "balance": "0x38ec5b721a1a268000" + }, + "2e8eb30a716e5fe15c74233e039bfb1106e81d12": { + "balance": "0x56bc75e2d63100000" + }, + "2e9824b5c132111bca24ddfba7e575a5cd7296c1": { + "balance": "0x3a484516e6d7ffe0000" + }, + "2ea5fee63f337a376e4b918ea82148f94d48a626": { + "balance": "0x650f8e0dd293c50000" + }, + "2eaf4e2a46b789ccc288c8d1d9294e3fb0853896": { + "balance": "0x6c6b935b8bbd400000" + }, + "2eaff9f8f8113064d3957ac6d6e11eee42c8195d": { + "balance": "0x6acb3df27e1f880000" + }, + "2eba0c6ee5a1145c1c573984963a605d880a7a20": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "2ec95822eb887bc113b4712a4dfd7f13b097b5e7": { + "balance": "0x3635c9adc5dea00000" + }, + "2eca6a3c5d9f449d0956bd43fa7b4d7be8435958": { + "balance": "0x6c6bda69709cc20000" + }, + "2ecac504b233866eb5a4a99e7bd2901359e43b3d": { + "balance": "0x43c33c1937564800000" + }, + "2eebf59432b52892f9380bd140aa99dcf8ad0c0f": { + "balance": "0x83d6c7aab63600000" + }, + "2eeed50471a1a2bf53ee30b1232e6e9d80ef866d": { + "balance": "0x1158e460913d00000" + }, + "2eef6b1417d7b10ecfc19b123a8a89e73e526c58": { + "balance": "0x2086ac351052600000" + }, + "2ef869f0350b57d53478d701e3fee529bc911c75": { + "balance": "0x2b5e3af16b1880000" + }, + "2ef9e465716acacfb8c8252fa8e7bc7969ebf6e4": { + "balance": "0x959eb1c0e4ae200000" + }, + "2efc4c647dac6acac35577ad221758fef6616faa": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "2f13657526b177cad547c3908c840eff647b45d9": { + "balance": "0x3f76849cf1ee2c8000" + }, + "2f187d5a704d5a338c5b2876a090dce964284e29": { + "balance": "0xd8d726b7177a800000" + }, + "2f2523cc834f0086052402626296675186a8e582": { + "balance": "0x3635c9adc5dea000000" + }, + "2f282abbb6d4a3c3cd3b5ca812f7643e80305f06": { + "balance": "0x6449e84e47a8a80000" + }, + "2f2bba1b1796821a766fce64b84f28ec68f15aea": { + "balance": "0x1158e460913d00000" + }, + "2f315d9016e8ee5f536681202f9084b032544d4d": { + "balance": "0x383cd12b9e863c0000" + }, + "2f4da753430fc09e73acbccdcde9da647f2b5d37": { + "balance": "0xad78ebc5ac6200000" + }, + "2f5080b83f7e2dc0a1dd11b092ad042bff788f4c": { + "balance": "0xb4f8fb79231d2b8000" + }, + "2f61efa5819d705f2b1e4ee754aeb8a819506a75": { + "balance": "0x4f2591f896a6500000" + }, + "2f66bfbf2262efcc8d2bd0444fc5b0696298ff1e": { + "balance": "0x21ad935f79f76d00000" + }, + "2f6dce1330c59ef921602154572d4d4bacbd048a": { + "balance": "0x3635c9adc5dea00000" + }, + "2f7d3290851be5c6b4b43f7d4574329f61a792c3": { + "balance": "0x56bc75e2d63100000" + }, + "2f853817afd3b8f3b86e9f60ee77b5d97773c0e3": { + "balance": "0x4eaeea44e368b90000" + }, + "2fa491fb5920a6574ebd289f39c1b2430d2d9a6a": { + "balance": "0x6c6b935b8bbd400000" + }, + "2fb566c94bbba4e3cb67cdda7d5fad7131539102": { + "balance": "0x6c6b935b8bbd400000" + }, + "2fbb504a5dc527d3e3eb0085e2fc3c7dd538cb7a": { + "balance": "0x43c2b18aec3c0a8000" + }, + "2fbc85798a583598b522166d6e9dda121d627dbc": { + "balance": "0xad78ebc5ac6200000" + }, + "2fbcef3384d420e4bf61a0669990bc7054f1a5af": { + "balance": "0x6c6b935b8bbd400000" + }, + "2fc82ef076932341264f617a0c80dd571e6ae939": { + "balance": "0x18424f5f0b1b4e00000" + }, + "2fdd9b79df8df530ad63c20e62af431ae99216b8": { + "balance": "0x1236efcbcbb340000" + }, + "2fe0023f5722650f3a8ac01009125e74e3f82e9b": { + "balance": "0xa2a15d09519be00000" + }, + "2fe0cc424b53a31f0916be08ec81c50bf8eab0c1": { + "balance": "0x2086ac351052600000" + }, + "2fe13a8d0785de8758a5e41876c36e916cf75074": { + "balance": "0xd8d726b7177a800000" + }, + "2fea1b2f834f02fc54333f8a809f0438e5870aa9": { + "balance": "0x11854d0f9cee40000" + }, + "2fee36a49ee50ecf716f1047915646779f8ba03f": { + "balance": "0x394222c4da86d70000" + }, + "2fef81478a4b2e8098db5ff387ba2153f4e22b79": { + "balance": "0x3627e8f712373c0000" + }, + "2ff160c44f72a299b5ec2d71e28ce5446d2fcbaf": { + "balance": "0x138400eca364a00000" + }, + "2ff1ca55fd9cec1b1fe9f0a9abb74c513c1e2aaa": { + "balance": "0xa2a15d09519be00000" + }, + "2ff5cab12c0d957fd333f382eeb75107a64cb8e8": { + "balance": "0x21e19e0c9bab2400000" + }, + "2ff830cf55fb00d5a0e03514fecd44314bd6d9f1": { + "balance": "0x21e19e0c9bab2400000" + }, + "2ffe93ec1a5636e9ee34af70dff52682e6ff7079": { + "balance": "0x6c6b935b8bbd400000" + }, + "30037988702671acbe892c03fe5788aa98af287a": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "30248d58e414b20fed3a6c482b59d9d8f5a4b7e2": { + "balance": "0x340aad21b3b700000" + }, + "303139bc596403d5d3931f774c66c4ba467454db": { + "balance": "0x5c25e14aea283f0000" + }, + "30380087786965149e81423b15e313ba32c5c783": { + "balance": "0xfc936392801c0000" + }, + "303a30ac4286ae17cf483dad7b870c6bd64d7b4a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "303fbaebbe46b35b6e5b74946a5f99bc1585cae7": { + "balance": "0x2f9ac0695f5bba0000" + }, + "3041445a33ba158741160d9c344eb88e5c306f94": { + "balance": "0x340aad21b3b700000" + }, + "30480164bcd84974ebc0d90c9b9afab626cd1c73": { + "balance": "0x2b5e3af16b18800000" + }, + "304ec69a74545721d7316aef4dcfb41ac59ee2f0": { + "balance": "0xad78ebc5ac6200000" + }, + "30511832918d8034a7bee72ef2bfee440ecbbcf6": { + "balance": "0x368c8623a8b4d100000" + }, + "30513fca9f36fd788cfea7a340e86df98294a244": { + "balance": "0x183b5f03b1479c0000" + }, + "3055efd26029e0d11b930df4f53b162c8c3fd2ce": { + "balance": "0x1b1a089237073d0000" + }, + "305d26c10bdc103f6b9c21272eb7cb2d9108c47e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "305f78d618b990b4295bac8a2dfa262884f804ea": { + "balance": "0xd8d726b7177a800000" + }, + "3064899a963c4779cbf613cd6980846af1e6ec65": { + "balance": "0x17b773ce6e5df0a0000" + }, + "30730466b8eb6dc90d5496aa76a3472d7dbe0bbe": { + "balance": "0x6c68ccd09b022c0000" + }, + "30742ccdf4abbcd005681f8159345c9e79054b1a": { + "balance": "0x243d4d18229ca20000" + }, + "3083ef0ed4c4401196774a95cf4edc83edc1484f": { + "balance": "0x23ffb7ed6565d6400000" + }, + "308dd21cebe755126704b48c0f0dc234c60ba9b1": { + "balance": "0xad78ebc5ac6200000" + }, + "3090f8130ec44466afadb36ed3c926133963677b": { + "balance": "0xd8d726b7177a800000" + }, + "309544b6232c3dd737f945a03193d19b5f3f65b9": { + "balance": "0x3af342f67ef6c80000" + }, + "3096dca34108085bcf04ae72b94574a13e1a3e1d": { + "balance": "0xad78ebc5ac6200000" + }, + "3098b65db93ecacaf7353c48808390a223d57684": { + "balance": "0x186484cf7bb6a48000" + }, + "30a9da72574c51e7ee0904ba1f73a6b7b83b9b9d": { + "balance": "0x11854d0f9cee40000" + }, + "30acd858875fa24eef0d572fc7d62aad0ebddc35": { + "balance": "0x15af1d78b58c400000" + }, + "30b66150f1a63457023fdd45d0cc6cb54e0c0f06": { + "balance": "0x3635c9adc5dea00000" + }, + "30bb4357cd6910c86d2238bf727cbe8156680e62": { + "balance": "0x56bf91b1a65eb0000" + }, + "30bf61b2d877fe10635126326fa189e4b0b1c3b0": { + "balance": "0x37b48985a5d7e60000" + }, + "30c01142907acb1565f70438b9980ae731818738": { + "balance": "0x6c6b935b8bbd400000" + }, + "30c26a8e971baa1855d633ba703f028cc7873140": { + "balance": "0x21e19e0c9bab2400000" + }, + "30db6b9b107e62102f434a9dd0960c2021f5ce4c": { + "balance": "0x2083179b6e42530000" + }, + "30e33358fc21c85006e40f32357dc8895940aaf0": { + "balance": "0x678a932062e4180000" + }, + "30e60900cacc7203f314dc604347255167fc2a0f": { + "balance": "0x6c6b935b8bbd400000" + }, + "30e789b3d2465e946e6210fa5b35de4e8c93085f": { + "balance": "0x6c6b935b8bbd400000" + }, + "30e9698cf1e08a9d048bd8d8048f28be7ed9409f": { + "balance": "0x16a6502f15a1e540000" + }, + "30e9d5a0088f1ddb2fd380e2a049192266c51cbf": { + "balance": "0xaacacd9b9e22b0000" + }, + "30eac740e4f02cb56eef0526e5d300322600d03e": { + "balance": "0x6acb3df27e1f880000" + }, + "30ec9392244a2108c987bc5cdde0ed9f837a817b": { + "balance": "0x549925f6c9c5250000" + }, + "30ed11b77bc17e5e6694c8bc5b6e4798f68d9ca7": { + "balance": "0x1e6fb3421fe0299e0000" + }, + "30f7d025d16f7bee105580486f9f561c7bae3fef": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "30fbe5885f9fcce9ea5edb82ed4a1196dd259aed": { + "balance": "0x119e47f21381f400000" + }, + "31047d703f63b93424fbbd6e2f1f9e74de13e709": { + "balance": "0x9a8166f7e6b2a78000" + }, + "31313ffd635bf2f3324841a88c07ed146144ceeb": { + "balance": "0x6acb3df27e1f880000" + }, + "3159e90c48a915904adfe292b22fa5fd5e72796b": { + "balance": "0x36afe98f2606100000" + }, + "315db7439fa1d5b423afa7dd7198c1cf74c918bc": { + "balance": "0x2086ac351052600000" + }, + "315ef2da620fd330d12ee55de5f329a696e0a968": { + "balance": "0x821ab0d4414980000" + }, + "316e92a91bbda68b9e2f98b3c048934e3cc0b416": { + "balance": "0x6c6b935b8bbd400000" + }, + "316eb4e47df71b42e16d6fe46825b7327baf3124": { + "balance": "0xd8d726b7177a800000" + }, + "3171877e9d820cc618fc0919b29efd333fda4934": { + "balance": "0x3635c9adc5dea00000" + }, + "317cf4a23cb191cdc56312c29d15e210b3b9b784": { + "balance": "0x7ce66c50e28400000" + }, + "318b2ea5f0aaa879c4d5e548ac9d92a0c67487b7": { + "balance": "0xad78ebc5ac6200000" + }, + "318c76ecfd8af68d70555352e1f601e35988042d": { + "balance": "0x1b31192e68c7f00000" + }, + "318f1f8bd220b0558b95fb33100ffdbb640d7ca6": { + "balance": "0xd8d726b7177a800000" + }, + "31aa3b1ebe8c4dbcb6a708b1d74831e60e497660": { + "balance": "0x15af1d78b58c400000" + }, + "31ab088966ecc7229258f6098fce68cf39b38485": { + "balance": "0x3635c9adc5dea00000" + }, + "31ad4d9946ef09d8e988d946b1227f9141901736": { + "balance": "0x4d853c8f89089800000" + }, + "31b43b015d0081643c6cda46a7073a6dfdbca825": { + "balance": "0xa97916520cd18e80000" + }, + "31ccc616b3118268e75d9ab8996c8858ebd7f3c3": { + "balance": "0x15ae0f771ca1520000" + }, + "31d81d526c195e3f10b5c6db52b5e59afbe0a995": { + "balance": "0xe4fbc69449f200000" + }, + "31e9c00f0c206a4e4e7e0522170dc81e88f3eb70": { + "balance": "0x918ddc3a42a3d40000" + }, + "31ea12d49a35a740780ddeeaece84c0835b26270": { + "balance": "0xad78ebc5ac6200000" + }, + "31ea6eab19d00764e9a95e183f2b1b22fc7dc40f": { + "balance": "0x1158e460913d00000" + }, + "31eb123c95c82bf685ace7a75a1881a289efca10": { + "balance": "0x31e009607371bd0000" + }, + "31ed858788bda4d5270992221cc04206ec62610d": { + "balance": "0x3fc0474948f3600000" + }, + "31f006f3494ed6c16eb92aaf9044fa8abb5fd5a3": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "3201259caf734ad7581c561051ba0bca7fd6946b": { + "balance": "0x261dd1ce2f2088800000" + }, + "32034e8581d9484e8af42a28df190132ec29c466": { + "balance": "0xbb9125542263900000" + }, + "322021022678a0166d204b3aaa7ad4ec4b88b7d0": { + "balance": "0x15af1d78b58c400000" + }, + "3225c1ca5f2a9c88156bb7d9cdc44a326653c214": { + "balance": "0x15af1d78b58c400000" + }, + "322788b5e29bf4f5f55ae1ddb32085fda91b8ebe": { + "balance": "0xad78ebc5ac6200000" + }, + "322d6f9a140d213f4c80cd051afe25c620bf4c7d": { + "balance": "0x1158e460913d00000" + }, + "322e5c43b0f524389655a9b3ff24f2d4db3da10f": { + "balance": "0xfc13b69b3e7e680000" + }, + "323486ca64b375474fb2b759a9e7a135859bd9f6": { + "balance": "0x15af1d78b58c400000" + }, + "323749a3b971959e46c8b4822dcafaf7aaf9bd6e": { + "balance": "0x11671a5b245700000" + }, + "323aad41df4b6fc8fece8c93958aa901fa680843": { + "balance": "0x34957444b840e80000" + }, + "323b3cfe3ee62bbde2a261e53cb3ecc05810f2c6": { + "balance": "0x2eb8eb1a172dcb80000" + }, + "323fca5ed77f699f9d9930f5ceeff8e56f59f03c": { + "balance": "0x487a9a304539440000" + }, + "32485c818728c197fea487fbb6e829159eba8370": { + "balance": "0x3921b413bc4ec08000" + }, + "3250e3e858c26adeccadf36a5663c22aa84c4170": { + "balance": "0x10f0cf064dd59200000" + }, + "3259bd2fddfbbc6fbad3b6e874f0bbc02cda18b5": { + "balance": "0x2846056495b0d188000" + }, + "3275496fd4dd8931fd69fb0a0b04c4d1ff879ef5": { + "balance": "0x182d7e4cfda0380000" + }, + "327bb49e754f6fb4f733c6e06f3989b4f65d4bee": { + "balance": "0x1158e460913d00000" + }, + "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { + "balance": "0x487a9a304539440000" + }, + "3283eb7f9137dd39bed55ffe6b8dc845f3e1a079": { + "balance": "0x3970ae92155780000" + }, + "32860997d730b2d83b73241a25d3667d51c908ef": { + "balance": "0x1b1a089237073d0000" + }, + "3286d1bc657a312c8847d93cb3cb7950f2b0c6e3": { + "balance": "0x43c33c1937564800000" + }, + "32a20d028e2c6218b9d95b445c771524636a22ef": { + "balance": "0x202fefbf2d7c2f00000" + }, + "32a70691255c9fc9791a4f75c8b81f388e0a2503": { + "balance": "0x35659ef93f0fc40000" + }, + "32b7feebc5c59bf65e861c4c0be42a7611a5541a": { + "balance": "0x77e9aaa8525c100000" + }, + "32ba9a7d0423e03a525fe2ebeb661d2085778bd8": { + "balance": "0x43c33c1937564800000" + }, + "32bb2e9693e4e085344d2f0dbd46a283e3a087fd": { + "balance": "0x15af1d78b58c400000" + }, + "32c2fde2b6aabb80e5aea2b949a217f3cb092283": { + "balance": "0x1306160afdf20378000" + }, + "32d950d5e93ea1d5b48db4714f867b0320b31c0f": { + "balance": "0x3708baed3d68900000" + }, + "32dbb6716c54e83165829a4abb36757849b6e47d": { + "balance": "0x3635c9adc5dea00000" + }, + "32eb64be1b5dede408c6bdefbe6e405c16b7ed02": { + "balance": "0x6acb3df27e1f880000" + }, + "32ef5cdc671df5562a901aee5db716b9be76dcf6": { + "balance": "0x6c6b935b8bbd400000" + }, + "32f29e8727a74c6b4301e3ffff0687c1b870dae9": { + "balance": "0x3635c9adc5dea00000" + }, + "32fa0e86cd087dd68d693190f32d93310909ed53": { + "balance": "0xd8d726b7177a800000" + }, + "32fbeed6f626fcdfd51acafb730b9eeff612f564": { + "balance": "0x6c6b935b8bbd400000" + }, + "3300fb149aded65bcba6c04e9cd6b7a03b893bb1": { + "balance": "0xfc936392801c0000" + }, + "3301d9ca2f3bfe026279cd6819f79a293d98156e": { + "balance": "0xa968163f0a57b400000" + }, + "3308b03466c27a17dfe1aafceb81e16d2934566f": { + "balance": "0x39992648a23c8a00000" + }, + "331a1c26cc6994cdd3c14bece276ffff4b9df77c": { + "balance": "0xfa7aeddf4f068000" + }, + "3326b88de806184454c40b27f309d9dd6dcfb978": { + "balance": "0x3ca5c66d9bc44300000" + }, + "3329eb3baf4345d600ced40e6e9975656f113742": { + "balance": "0x10f08eda8e555098000" + }, + "33320dd90f2baa110dd334872a998f148426453c": { + "balance": "0x36356633ebd8ea0000" + }, + "3336c3ef6e8b50ee90e037b164b7a8ea5faac65d": { + "balance": "0xec8a3a71c22540000" + }, + "33380c6fff5acd2651309629db9a71bf3f20c5ba": { + "balance": "0x368c8623a8b4d100000" + }, + "333ad1596401e05aea2d36ca47318ef4cd2cb3df": { + "balance": "0x9dc05cce28c2b80000" + }, + "334340ee4b9cdc81f850a75116d50ee9b69825bf": { + "balance": "0x6c6b935b8bbd400000" + }, + "33481e856ebed48ea708a27426ef28e867f57cd1": { + "balance": "0xad78ebc5ac6200000" + }, + "33565ba9da2c03e778ce12294f081dfe81064d24": { + "balance": "0x3635c9adc5dea000000" + }, + "33581cee233088c0860d944e0cf1ceabb8261c2e": { + "balance": "0xb98bc829a6f90000" + }, + "335858f749f169cabcfe52b796e3c11ec47ea3c2": { + "balance": "0xad78ebc5ac6200000" + }, + "335e22025b7a77c3a074c78b8e3dfe071341946e": { + "balance": "0x227ca730ab3f6ac0000" + }, + "33629bd52f0e107bc071176c64df108f64777d49": { + "balance": "0x1cfdd7468216e8000" + }, + "337b3bdf86d713dbd07b5dbfcc022b7a7b1946ae": { + "balance": "0xd7c198710e66b00000" + }, + "337cfe1157a5c6912010dd561533791769c2b6a6": { + "balance": "0x3635c9adc5dea00000" + }, + "33b336f5ba5edb7b1ccc7eb1a0d984c1231d0edc": { + "balance": "0x6c6b935b8bbd400000" + }, + "33c407133b84b3ca4c3ded1f4658900c38101624": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "33d172ab075c51db1cd40a8ca8dbff0d93b843bb": { + "balance": "0x136780510d12de38000" + }, + "33e9b71823952e1f66958c278fc28b1196a6c5a4": { + "balance": "0x56bc75e2d63100000" + }, + "33ea6b7855e05b07ab80dab1e14de9b649e99b6c": { + "balance": "0x1cd6fbad57dbd00000" + }, + "33f15223310d44de8b6636685f3a4c3d9c5655a5": { + "balance": "0xd9462c6cb4b5a0000" + }, + "33f4a6471eb1bca6a9f85b3b4872e10755c82be1": { + "balance": "0x6c6b935b8bbd400000" + }, + "33fb577a4d214fe010d32cca7c3eeda63f87ceef": { + "balance": "0x3635c9adc5dea00000" + }, + "33fd718f0b91b5cec88a5dc15eecf0ecefa4ef3d": { + "balance": "0x177224aa844c720000" + }, + "341480cc8cb476f8d01ff30812e7c70e05afaf5d": { + "balance": "0x6c6b935b8bbd400000" + }, + "34272d5e7574315dcae9abbd317bac90289d4765": { + "balance": "0x62a992e53a0af00000" + }, + "3430a16381f869f6ea5423915855e800883525a9": { + "balance": "0x3ca5c66d9bc44300000" + }, + "34318625818ec13f11835ae97353ce377d6f590a": { + "balance": "0x52663ccab1e1c00000" + }, + "34393c5d91b9de597203e75bac4309b5fa3d28c3": { + "balance": "0xa844a7424d9c80000" + }, + "3439998b247cb4bf8bc80a6d2b3527f1dfe9a6d2": { + "balance": "0x796e3ea3f8ab00000" + }, + "34437d1465640b136cb5841c3f934f9ba0b7097d": { + "balance": "0x960db77681e940000" + }, + "344a8db086faed4efc37131b3a22b0782dad7095": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "34664d220fa7f37958024a3332d684bcc6d4c8bd": { + "balance": "0x21e19e0c9bab2400000" + }, + "3466f67e39636c01f43b3a21a0e8529325c08624": { + "balance": "0x2db1167650acd80000" + }, + "3485361ee6bf06ef6508ccd23d94641f814d3e2f": { + "balance": "0x6c6b935b8bbd400000" + }, + "3485f621256433b98a4200dad857efe55937ec98": { + "balance": "0x6c6b935b8bbd400000" + }, + "34958a46d30e30b273ecc6e5d358a212e5307e8c": { + "balance": "0x6c6b935b8bbd400000" + }, + "3497dd66fd118071a78c2cb36e40b6651cc82598": { + "balance": "0x5f1016b5076d00000" + }, + "349a816b17ab3d27bbc0ae0051f6a070be1ff29d": { + "balance": "0x21e19e0c9bab2400000" + }, + "349d2c918fd09e2807318e66ce432909176bd50b": { + "balance": "0x3cb71f51fc55800000" + }, + "34a0431fff5ead927f3c69649616dc6e97945f6f": { + "balance": "0x15af1d78b58c400000" + }, + "34a85d6d243fb1dfb7d1d2d44f536e947a4cee9e": { + "balance": "0x43c33c1937564800000" + }, + "34a901a69f036bcf9f7843c0ba01b426e8c3dc2b": { + "balance": "0xd8d726b7177a800000" + }, + "34b454416e9fb4274e6addf853428a0198d62ee1": { + "balance": "0x161042779f1ffc0000" + }, + "34c8e5f1330fcb4b14ca75cb2580a4b93d204e36": { + "balance": "0x6c6b935b8bbd400000" + }, + "34e2849bea583ab0cc37975190f322b395055582": { + "balance": "0x1a5c5e857fdf2b20000" + }, + "34fa7792bad8bbd7ff64056214a33eb6600c1ea8": { + "balance": "0x2b5e3af16b1880000" + }, + "34ff26eb60a8d1a95a489fae136ee91d4e58084c": { + "balance": "0x2086ac351052600000" + }, + "34ff582952ff24458f7b13d51f0b4f987022c1fe": { + "balance": "0x9806de3da6e9780000" + }, + "35106ba94e8563d4b3cb3c5c692c10e604b7ced8": { + "balance": "0x6c6b935b8bbd400000" + }, + "35145f620397c69cb8e00962961f0f4886643989": { + "balance": "0x14542ba12a337c00000" + }, + "35147430c3106500e79fa2f502462e94703c23b1": { + "balance": "0x6c6acc67d7b1d40000" + }, + "351787843505f8e4eff46566cce6a59f4d1c5fe7": { + "balance": "0x1f5718987664b480000" + }, + "351f16e5e0735af56751b0e225b2421171394090": { + "balance": "0x2d4ca05e2b43ca80000" + }, + "3524a000234ebaaf0789a134a2a417383ce5282a": { + "balance": "0x1317955947d8e2c0000" + }, + "3526eece1a6bdc3ee7b400fe935b48463f31bed7": { + "balance": "0x477879b6d14300000" + }, + "352a785f4a921632504ce5d015f83c49aa838d6d": { + "balance": "0xe9e7e0fb35b7780000" + }, + "352d29a26e8a41818181746467f582e6e84012e0": { + "balance": "0x14542ba12a337c00000" + }, + "352e77c861696ef96ad54934f894aa8ea35151dd": { + "balance": "0x3635c9adc5dea00000" + }, + "352f25babf4a690673e35195efa8f79d05848aad": { + "balance": "0xe253c39be6e7dc00000" + }, + "3536453322c1466cb905af5c335ca8db74bff1e6": { + "balance": "0x183b5f03b1479c0000" + }, + "353dbec42f92b50f975129b93c4c997375f09073": { + "balance": "0x6c5db2a4d815dc0000" + }, + "3540c7bd7a8442d5bee21a2180a1c4edff1649e0": { + "balance": "0x432eac4c6f05b98000" + }, + "3549bd40bbbc2b30095cac8be2c07a0588e0aed6": { + "balance": "0x1158e460913d00000" + }, + "3552a496eba67f12be6eedab360cd13661dc7480": { + "balance": "0x1043561a8829300000" + }, + "3554947b7b947b0040da52ca180925c6d3b88ffe": { + "balance": "0x39fbae8d042dd0000" + }, + "355c0c39f5d5700b41d375b3f17851dcd52401f9": { + "balance": "0xd7b3b7ba5abf4c0000" + }, + "355ccfe0e77d557b971be1a558bc02df9eee0594": { + "balance": "0x5f5cb1afc865280000" + }, + "3571cf7ad304ecaee595792f4bbfa484418549d6": { + "balance": "0x13bcd0d892d9e160000" + }, + "3575c770668a9d179f1ef768c293f80166e2aa3d": { + "balance": "0x19b21248a3ef280000" + }, + "357a02c0a9dfe287de447fb67a70ec5b62366647": { + "balance": "0x1731790534df20000" + }, + "35855ec641ab9e081ed0c2a6dcd81354d0244a87": { + "balance": "0x4127abe993a7aa8000" + }, + "3588895ac9fbafec012092dc05c0c302d90740fa": { + "balance": "0xa2a15d09519be00000" + }, + "3599493ce65772cf93e98af1195ec0955dc98002": { + "balance": "0x5151590c67b3280000" + }, + "35a08081799173e001cc5bd46a02406dc95d1787": { + "balance": "0x21e19e0c9bab2400000" + }, + "35a549e8fd6c368d6dcca6d2e7d18e4db95f5284": { + "balance": "0x1b1a089237073d0000" + }, + "35a6885083c899dabbf530ed6c12f4dd3a204cf5": { + "balance": "0xad78ebc5ac6200000" + }, + "35aaa0465d1c260c420fa30e2629869fb6559207": { + "balance": "0x263781e0e087c80000" + }, + "35ac1d3ed7464fa3db14e7729213ceaa378c095e": { + "balance": "0x52663ccab1e1c00000" + }, + "35af040a0cc2337a76af288154c7561e1a233349": { + "balance": "0x3635c9adc5dea00000" + }, + "35b03ea4245736f57b85d2eb79628f036ddcd705": { + "balance": "0xd8d726b7177a800000" + }, + "35bd246865fab490ac087ac1f1d4f2c10d0cda03": { + "balance": "0x15af1d78b58c400000" + }, + "35bf6688522f35467a7f75302314c02ba176800e": { + "balance": "0x3af418202d954e00000" + }, + "35c8adc11125432b3b77acd64625fe58ebee9d66": { + "balance": "0x6c6b935b8bbd400000" + }, + "35d2970f49dcc81ea9ee707e9c8a0ab2a8bb7463": { + "balance": "0x4e1003b28d92800000" + }, + "35e096120deaa5c1ecb1645e2ccb8b4edbd9299a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "35ea2163a38cdf9a123f82a5ec00258dae0bc767": { + "balance": "0xd8d726b7177a800000" + }, + "35f1da127b83376f1b88c82a3359f67a5e67dd50": { + "balance": "0x678a932062e4180000" + }, + "35f2949cf78bc219bb4f01907cf3b4b3d3865482": { + "balance": "0xfb5c86c92e4340000" + }, + "35f5860149e4bbc04b8ac5b272be55ad1aca58e0": { + "balance": "0xad78ebc5ac6200000" + }, + "3602458da86f6d6a9d9eb03daf97fe5619d442fa": { + "balance": "0x6c6b935b8bbd400000" + }, + "3605372d93a9010988018f9f315d032ed1880fa1": { + "balance": "0x1b1bcf51896a7d0000" + }, + "3616d448985f5d32aefa8b93a993e094bd854986": { + "balance": "0xb227f63be813c0000" + }, + "3616fb46c81578c9c8eb4d3bf880451a88379d7d": { + "balance": "0xad78ebc5ac6200000" + }, + "361c75931696bc3d427d93e76c77fd13b241f6f4": { + "balance": "0x1dc5d8fc266dd60000" + }, + "361d9ed80b5bd27cf9f1226f26753258ee5f9b3f": { + "balance": "0xbf6914ba7d72c20000" + }, + "361f3ba9ed956b770f257d3672fe1ff9f7b0240c": { + "balance": "0x2086ac351052600000" + }, + "36227cdfa0fd3b9d7e6a744685f5be9aa366a7f0": { + "balance": "0xac2730ee9c6c18000" + }, + "362fbcb10662370a068fc2652602a2577937cce6": { + "balance": "0xad78ebc5ac6200000" + }, + "3630c5e565ceaa8a0f0ffe32875eae2a6ce63c19": { + "balance": "0x937722b3774d00000" + }, + "36339f84a5c2b44ce53dfdb6d4f97df78212a7df": { + "balance": "0x116f18b81715a00000" + }, + "36343aeca07b6ed58a0e62fa4ecb498a124fc971": { + "balance": "0x1043561a8829300000" + }, + "366175403481e0ab15bb514615cbb989ebc68f82": { + "balance": "0x6c6b935b8bbd400000" + }, + "36726f3b885a24f92996da81625ec8ad16d8cbe6": { + "balance": "0x53af75d18148578000" + }, + "3673954399f6dfbe671818259bb278e2e92ee315": { + "balance": "0x2a5a058fc295ed000000" + }, + "36758e049cd98bcea12277a676f9297362890023": { + "balance": "0xd8d726b7177a800000" + }, + "367f59cc82795329384e41e1283115e791f26a01": { + "balance": "0x6c6b935b8bbd400000" + }, + "36810ff9d213a271eda2b8aa798be654fa4bbe06": { + "balance": "0x6c6b935b8bbd400000" + }, + "368c5414b56b8455171fbf076220c1cba4b5ca31": { + "balance": "0x1e3ef911e83d720000" + }, + "3690246ba3c80679e22eac4412a1aefce6d7cd82": { + "balance": "0x43c33c1937564800000" + }, + "36928b55bc861509d51c8cf1d546bfec6e3e90af": { + "balance": "0x6acb3df27e1f880000" + }, + "369822f5578b40dd1f4471706b22cd971352da6b": { + "balance": "0x12c1b6eed03d280000" + }, + "369ef761195f3a373e24ece6cd22520fe0b9e86e": { + "balance": "0x1cffafc94db2088000" + }, + "36a08fd6fd1ac17ce15ed57eefb12a2be28188bf": { + "balance": "0x487a9a304539440000" + }, + "36a0e61e1be47fa87e30d32888ee0330901ca991": { + "balance": "0x1158e460913d00000" + }, + "36b2c85e3aeeebb70d63c4a4730ce2e8e88a3624": { + "balance": "0x21e19e0c9bab2400000" + }, + "36bf43ff35df90908824336c9b31ce33067e2f50": { + "balance": "0x49721510c1c1e9480000" + }, + "36bfe1fa3b7b70c172eb042f6819a8972595413e": { + "balance": "0x3635c9adc5dea00000" + }, + "36c510bf8d6e569bf2f37d47265dbcb502ff2bce": { + "balance": "0x65a4da25d3016c00000" + }, + "36d85dc3683156e63bf880a9fab7788cf8143a27": { + "balance": "0x43c33c1937564800000" + }, + "36df8f883c1273ec8a171f7a33cfd649b1fe6075": { + "balance": "0xc52484ac416890000" + }, + "36e156610cd8ff64e780d89d0054385ca76755aa": { + "balance": "0x2f6f10780d22cc00000" + }, + "36fec62c2c425e219b18448ad757009d8c54026f": { + "balance": "0x15af1d78b58c400000" + }, + "3700e3027424d939dbde5d42fb78f6c4dbec1a8f": { + "balance": "0x22b1c8c1227a00000" + }, + "3702e704cc21617439ad4ea27a5714f2fda1e932": { + "balance": "0x3635c9adc5dea00000" + }, + "3703350c4d6fe337342cddc65bf1e2386bf3f9b2": { + "balance": "0x6d8121a194d1100000" + }, + "3708e59de6b4055088782902e0579c7201a8bf50": { + "balance": "0x2a5a058fc295ed000000" + }, + "3712367e5e55a96d5a19168f6eb2bc7e9971f869": { + "balance": "0x3635c9adc5dea00000" + }, + "37195a635dcc62f56a718049d47e8f9f96832891": { + "balance": "0x6acb3df27e1f880000" + }, + "3727341f26c12001e378405ee38b2d8464ec7140": { + "balance": "0x6c6b935b8bbd400000" + }, + "372e453a6b629f27678cc8aeb5e57ce85ec0aef9": { + "balance": "0xad78ebc5ac6200000" + }, + "3734cb187491ede713ae5b3b2d12284af46b8101": { + "balance": "0xa2a15d09519be00000" + }, + "3737216ee91f177732fb58fa4097267207e2cf55": { + "balance": "0x52663ccab1e1c00000" + }, + "373c547e0cb5ce632e1c5ad66155720c01c40995": { + "balance": "0xfe54dcdce6c55a0000" + }, + "376cd7577383e902951b60a2017ba7ea29e33576": { + "balance": "0x6c6b935b8bbd400000" + }, + "378ea1dc8edc19bae82638029ea8752ce98bcfcd": { + "balance": "0x6c6b935b8bbd400000" + }, + "378f37243f3ff0bef5e1dc85eb4308d9340c29f9": { + "balance": "0x6c6e59e67c78540000" + }, + "37959c20b7e9931d72f5a8ae869dafddad3b6d5c": { + "balance": "0xad78ebc5ac6200000" + }, + "379a7f755a81a17edb7daaa28afc665dfa6be63a": { + "balance": "0x15af1d78b58c40000" + }, + "379c7166849bc24a02d6535e2def13daeef8aa8d": { + "balance": "0x56bc75e2d63100000" + }, + "37a05aceb9395c8635a39a7c5d266ae610d10bf2": { + "balance": "0x65a4da25d3016c00000" + }, + "37a10451f36166cf643dd2de6c1cbba8a011cfa3": { + "balance": "0x14998f32ac78700000" + }, + "37a7a6ff4ea3d60ec307ca516a48d3053bb79cbb": { + "balance": "0x6c6b935b8bbd400000" + }, + "37ab66083a4fa23848b886f9e66d79cdc150cc70": { + "balance": "0x12be22ffb5ec00380000" + }, + "37ac29bda93f497bc4aeaab935452c431510341e": { + "balance": "0x35659ef93f0fc40000" + }, + "37b8beac7b1ca38829d61ab552c766f48a10c32f": { + "balance": "0x15af1d78b58c400000" + }, + "37bbc47212d82fcb5ee08f5225ecc2041ad2da7d": { + "balance": "0xb1cf24ddd0b1400000" + }, + "37cb868d2c3f95b257611eb34a4188d58b749802": { + "balance": "0x6c6b935b8bbd400000" + }, + "37d980a12ee3bf23cc5cdb63b4ae45691f74c837": { + "balance": "0x6c6b935b8bbd400000" + }, + "37e169a93808d8035698f815c7235613c1e659f2": { + "balance": "0x3635c9adc5dea00000" + }, + "37eada93c475ded2f7e15e7787d400470fa52062": { + "balance": "0xad78ebc5ac6200000" + }, + "37fac1e6bc122e936dfb84de0c4bef6e0d60c2d7": { + "balance": "0x6c6b935b8bbd400000" + }, + "3807eff43aa97c76910a19752dd715ee0182d94e": { + "balance": "0xd90156f6fc2fb0000" + }, + "3815b0743f94fc8cc8654fd9d597ed7d8b77c57e": { + "balance": "0x2809d429d896750000" + }, + "381db4c8465df446a4ce15bf81d47e2f17c980bf": { + "balance": "0x6c6b935b8bbd4000000" + }, + "38202c5cd7078d4f887673ab07109ad8ada89720": { + "balance": "0x3635c9adc5dea00000" + }, + "3821862493242c0aeb84b90de05d250c1e50c074": { + "balance": "0x11776c58e946dc0000" + }, + "382591e7217b435e8e884cdbf415fe377a6fe29e": { + "balance": "0x1b2df9d219f57980000" + }, + "382ba76db41b75606dd48a48f0137e9174e031b6": { + "balance": "0x1158e460913d00000" + }, + "3831757eae7557cb8a37a4b10644b63e4d3b3c75": { + "balance": "0xad78ebc5ac6200000" + }, + "383304dd7a5720b29c1a10f60342219f48032f80": { + "balance": "0x12f939c99edab800000" + }, + "383a7c899ee18bc214969870bc7482f6d8f3570e": { + "balance": "0x21e19e0c9bab2400000" + }, + "38430e931d93be01b4c3ef0dc535f1e0a9610063": { + "balance": "0x21e19e0c9bab2400000" + }, + "38439aaa24e3636f3a18e020ea1da7e145160d86": { + "balance": "0x8cf23f909c0fa00000" + }, + "38458e0685573cb4d28f53098829904570179266": { + "balance": "0x22b1c8c1227a00000" + }, + "3847667038f33b01c1cc795d8daf5475eff5a0d4": { + "balance": "0x277b9bf4246c410000" + }, + "38643babea6011316cc797d9b093c897a17bdae7": { + "balance": "0x1220bb7445daa00000" + }, + "38695fc7e1367ceb163ebb053751f9f68ddb07a0": { + "balance": "0x6c6b935b8bbd400000" + }, + "3872f48dc5e3f817bc6b2ad2d030fc5e0471193d": { + "balance": "0xd8d726b7177a800000" + }, + "387eeafd6b4009deaf8bd5b85a72983a8dcc3487": { + "balance": "0xd8d726b7177a800000" + }, + "3881defae1c07b3ce04c78abe26b0cdc8d73f010": { + "balance": "0xad78ebc5ac6200000" + }, + "3883becc08b9be68ad3b0836aac3b620dc0017ef": { + "balance": "0x6c6b935b8bbd400000" + }, + "3885fee67107dc3a3c741ee290c98918c9b99397": { + "balance": "0x1158e460913d00000" + }, + "3887192c7f705006b630091276b39ac680448d6b": { + "balance": "0x340aad21b3b700000" + }, + "38898bbb4553e00bbfd0cf268b2fc464d154add5": { + "balance": "0x1158e460913d000000" + }, + "388bdcdae794fc44082e667501344118ea96cd96": { + "balance": "0x5a87e7d7f5f6580000" + }, + "388c85a9b9207d8146033fe38143f6d34b595c47": { + "balance": "0xad78ebc5ac6200000" + }, + "3896ad743579d38e2302454d1fb6e2ab69e01bfd": { + "balance": "0x65ea3db75546600000" + }, + "38a3dccf2fcfe0c91a2624bd0cbf88ee4a076c33": { + "balance": "0x6c6b935b8bbd400000" + }, + "38a744efa6d5c2137defef8ef9187b649eee1c78": { + "balance": "0xd8d726b7177a800000" + }, + "38ac664ee8e0795e4275cb852bcba6a479ad9c8d": { + "balance": "0x1158e460913d00000" + }, + "38b2197106123387a0d4de368431a8bacdda30e2": { + "balance": "0x1158e460913d00000" + }, + "38b3965c21fa893931079beacfffaf153678b6eb": { + "balance": "0x93c6a0a51e2670000" + }, + "38b403fb1fb7c14559a2d6f6564a5552bca39aff": { + "balance": "0x6c6b935b8bbd400000" + }, + "38b50146e71916a5448de12a4d742135dcf39833": { + "balance": "0x6d190c475169a200000" + }, + "38bf2a1f7a69de0e2546adb808b36335645da9ff": { + "balance": "0x6c700439d9b5600000" + }, + "38c10b90c859cbb7815692f99dae520ab5febf5e": { + "balance": "0x2c9e4966fa5cf240000" + }, + "38c7851f5ffd4cee98df30f3b25597af8a6ca263": { + "balance": "0x8ead3a2f7d7e180000" + }, + "38d2e9154964b41c8d50a7487d391e7ee2c3d3c2": { + "balance": "0xbdbc41e0348b300000" + }, + "38da1ba2de9e2c954b092dd9d81204fd016ba016": { + "balance": "0x2268ed01f34b3300000" + }, + "38df0c4abe7ded5fe068eadf154ac691774324a4": { + "balance": "0x61093d7c2c6d380000" + }, + "38e2af73393ea98a1d993a74df5cd754b98d529a": { + "balance": "0x61093d7c2c6d380000" + }, + "38e46de4453c38e941e7930f43304f94bb7b2be8": { + "balance": "0x6cb7e74867d5e60000" + }, + "38e7dba8fd4f1f850dbc2649d8e84f0952e3eb3c": { + "balance": "0x2b5e3af16b1880000" + }, + "38e8a31af2d265e31a9fff2d8f46286d1245a467": { + "balance": "0x1158e460913d00000" + }, + "38ea6f5b5a7b88417551b4123dc127dfe9342da6": { + "balance": "0x15af1d78b58c400000" + }, + "38eec6e217f4d41aa920e424b9525197041cd4c6": { + "balance": "0xf00d25eb922e670000" + }, + "38f387e1a4ed4a73106ef2b462e474e2e3143ad0": { + "balance": "0x14542ba12a337c00000" + }, + "391161b0e43c302066e8a68d2ce7e199ecdb1d57": { + "balance": "0xd8d726b7177a800000" + }, + "3915eab5ab2e5977d075dec47d96b68b4b5cf515": { + "balance": "0xd07018185120f400000" + }, + "391a77405c09a72b5e8436237aaaf95d68da1709": { + "balance": "0x2a9264af3d1b90000" + }, + "391f20176d12360d724d51470a90703675594a4d": { + "balance": "0x56bc75e2d631000000" + }, + "392433d2ce83d3fb4a7602cca3faca4ec140a4b0": { + "balance": "0x2c3c465ca58ec0000" + }, + "393f783b5cdb86221bf0294fb714959c7b45899c": { + "balance": "0x14061b9d77a5e980000" + }, + "393ff4255e5c658f2e7f10ecbd292572671bc2d2": { + "balance": "0x6c6b935b8bbd400000" + }, + "394132600f4155e07f4d45bc3eb8d9fb72dcd784": { + "balance": "0x9f6e92edea07d40000" + }, + "3951e48e3c869e6b72a143b6a45068cdb9d466d0": { + "balance": "0x1158e460913d00000" + }, + "3954bdfe0bf587c695a305d9244c3d5bdddac9bb": { + "balance": "0x410278327f985608000" + }, + "395d6d255520a8db29abc47d83a5db8a1a7df087": { + "balance": "0x56bc75e2d63100000" + }, + "39636b25811b176abfcfeeca64bc87452f1fdff4": { + "balance": "0x15af1d78b58c400000" + }, + "3969b4f71bb8751ede43c016363a7a614f76118e": { + "balance": "0x6c6b935b8bbd400000" + }, + "39782ffe06ac78822a3c3a8afe305e50a56188ce": { + "balance": "0x21e19e0c9bab2400000" + }, + "397a6ef8763a18f00fac217e055c0d3094101011": { + "balance": "0x6c6b935b8bbd400000" + }, + "397cdb8c80c67950b18d654229610e93bfa6ee1a": { + "balance": "0x3f95c8e08215210000" + }, + "39824f8bced176fd3ea22ec6a493d0ccc33fc147": { + "balance": "0xd8d726b7177a800000" + }, + "39936c2719450b9420cc2522cf91db01f227c1c1": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "3995e096b08a5a726800fcd17d9c64c64e088d2b": { + "balance": "0xad78ebc5ac6200000" + }, + "399aa6f5d078cb0970882bc9992006f8fbdf3471": { + "balance": "0x3635c9adc5dea00000" + }, + "39aa05e56d7d32385421cf9336e90d3d15a9f859": { + "balance": "0x168d28e3f00280000" + }, + "39aaf0854db6eb39bc7b2e43846a76171c0445de": { + "balance": "0x6449e84e47a8a80000" + }, + "39b1c471ae94e12164452e811fbbe2b3cd7275ac": { + "balance": "0x6c6b935b8bbd400000" + }, + "39b299327490d72f9a9edff11b83afd0e9d3c450": { + "balance": "0xad78ebc5ac6200000" + }, + "39bac68d947859f59e9226089c96d62e9fbe3cde": { + "balance": "0x22b1c8c1227a00000" + }, + "39bfd978689bec048fc776aa15247f5e1d7c39a2": { + "balance": "0x43c33c1937564800000" + }, + "39c773367c8825d3596c686f42bf0d14319e3f84": { + "balance": "0x73f75d1a085ba0000" + }, + "39d4a931402c0c79c457186f24df8729cf957031": { + "balance": "0xd8d726b7177a800000" + }, + "39d6caca22bccd6a72f87ee7d6b59e0bde21d719": { + "balance": "0x6c8754c8f30c080000" + }, + "39e0db4d60568c800b8c5500026c2594f5768960": { + "balance": "0x3635c9adc5dea00000" + }, + "39ee4fe00fbced647068d4f57c01cb22a80bccd1": { + "balance": "0x14542ba12a337c00000" + }, + "39f198331e4b21c1b760a3155f4ab2fe00a74619": { + "balance": "0x6c6b935b8bbd400000" + }, + "39f44663d92561091b82a70dcf593d754005973a": { + "balance": "0xad78b2edc21598000" + }, + "3a035594c747476d42d1ee966c36224cdd224993": { + "balance": "0x134af74569f9c50000" + }, + "3a04572847d31e81f7765ca5bfc9d557159f3683": { + "balance": "0x7362d0dabeafd8000" + }, + "3a06e3bb1edcfd0c44c3074de0bb606b049894a2": { + "balance": "0x21e19e0c9bab2400000" + }, + "3a10888b7e149cae272c01302c327d0af01a0b24": { + "balance": "0xebec21ee1da40000" + }, + "3a3108c1e680a33b336c21131334409d97e5adec": { + "balance": "0x1158e460913d00000" + }, + "3a368efe4ad786e26395ec9fc6ad698cae29fe01": { + "balance": "0x2245899675f9f40000" + }, + "3a3dd104cd7eb04f21932fd433ea7affd39369f5": { + "balance": "0x13614f23e242260000" + }, + "3a4297da3c555e46c073669d0478fce75f2f790e": { + "balance": "0x6ac5c62d9486070000" + }, + "3a476bd2c9e664c63ab266aa4c6e4a4825f516c3": { + "balance": "0xad78ebc5ac6200000" + }, + "3a48e0a7098b06a905802b87545731118e89f439": { + "balance": "0x6c6b935b8bbd400000" + }, + "3a4da78dce05aeb87de9aead9185726da1926798": { + "balance": "0xad78ebc5ac6200000" + }, + "3a59a08246a8206f8d58f70bb1f0d35c5bcc71bd": { + "balance": "0xa076407d3f7440000" + }, + "3a72d635aadeee4382349db98a1813a4cfeb3df1": { + "balance": "0x2a5a058fc295ed000000" + }, + "3a7db224acae17de7798797d82cdf8253017dfa8": { + "balance": "0x10f0cf064dd59200000" + }, + "3a805fa0f7387f73055b7858ca8519edd93d634f": { + "balance": "0x6449e84e47a8a80000" + }, + "3a84e950ed410e51b7e8801049ab2634b285fea1": { + "balance": "0x3f52fdaa822d2c80000" + }, + "3a86ee94862b743dd34f410969d94e2c5652d4ad": { + "balance": "0xaede69ad30e810000" + }, + "3a9132b7093d3ec42e1e4fb8cb31ecdd43ae773c": { + "balance": "0x6c6b935b8bbd400000" + }, + "3a9960266df6492063538a99f487c950a3a5ec9e": { + "balance": "0x5150ae84a8cdf000000" + }, + "3a9b111029ce1f20c9109c7a74eeeef34f4f2eb2": { + "balance": "0xd8d726b7177a800000" + }, + "3a9e5441d44b243be55b75027a1ceb9eacf50df2": { + "balance": "0x3635c9adc5dea00000" + }, + "3aa07a34a1afc8967d3d1383b96b62cf96d5fa90": { + "balance": "0x43c33c1937564800000" + }, + "3aa42c21b9b31c3e27ccd17e099af679cdf56907": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "3aa948ea02397755effb2f9dc9392df1058f7e33": { + "balance": "0x2e141ea081ca080000" + }, + "3aadf98b61e5c896e7d100a3391d3250225d61df": { + "balance": "0xcaf67003701680000" + }, + "3aae4872fd9093cbcad1406f1e8078bab50359e2": { + "balance": "0x222c8eb3ff6640000" + }, + "3abb8adfc604f48d5984811d7f1d52fef6758270": { + "balance": "0xf29719b66f110c0000" + }, + "3ac2f0ff1612e4a1c346d53382abf6d8a25baa53": { + "balance": "0x6c6b935b8bbd400000" + }, + "3ac9dc7a436ae98fd01c7a9621aa8e9d0b8b531d": { + "balance": "0x61093d7c2c6d380000" + }, + "3ad06149b21c55ff867cc3fb9740d2bcc7101231": { + "balance": "0x29b76432b94451200000" + }, + "3ad70243d88bf0400f57c8c1fd57811848af162a": { + "balance": "0x2e9ee5c38653f00000" + }, + "3ad915d550b723415620f5a9b5b88a85f382f035": { + "balance": "0x3635c9adc5dea00000" + }, + "3ae160e3cd60ae31b9d6742d68e14e76bd96c517": { + "balance": "0x1a055690d9db80000" + }, + "3ae62bd271a760637fad79c31c94ff62b4cd12f7": { + "balance": "0x6c6b935b8bbd400000" + }, + "3aea4e82d2400248f99871a41ca257060d3a221b": { + "balance": "0x3635c9adc5dea00000" + }, + "3af65b3e28895a4a001153391d1e69c31fb9db39": { + "balance": "0xd5967be4fc3f100000" + }, + "3b07db5a357f5af2484cbc9d77d73b1fd0519fc7": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "3b0accaf4b607cfe61d17334c214b75cdefdbd89": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b13631a1b89cb566548899a1d60915cdcc4205b": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b159099075207c6807663b1f0f7eda54ac8cce3": { + "balance": "0x6ac4e65b69f92d8000" + }, + "3b1937d5e793b89b63fb8eb5f1b1c9ca6ba0fa8e": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b22da2a0271c8efe102532773636a69b1c17e09": { + "balance": "0x1b36a6444a3e180000" + }, + "3b22dea3c25f1b59c7bd27bb91d3a3eaecef3984": { + "balance": "0x56bc75e2d63100000" + }, + "3b2367f8494b5fe18d683c055d89999c9f3d1b34": { + "balance": "0x21e19e0c9bab2400000" + }, + "3b2c45990e21474451cf4f59f01955b331c7d7c9": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b4100e30a73b0c734b18ffa8426d19b19312f1a": { + "balance": "0xbb5d1aa700afd900000" + }, + "3b42a66d979f582834747a8b60428e9b4eeccd23": { + "balance": "0x21a1c790fadc580000" + }, + "3b4768fd71e2db2cbe7fa050483c27b4eb931df3": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b566a8afad19682dc2ce8679a3ce444a5b0fd4f": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b5c251d7fd7893ba209fe541cecd0ce253a990d": { + "balance": "0x65a4da25d3016c00000" + }, + "3b5e8b3c77f792decb7a8985df916efb490aac23": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b6e814f770748a7c3997806347605480a3fd509": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b7b4f53c45655f3dc5f017edc23b16f9bc536fa": { + "balance": "0x56bc75e2d63100000" + }, + "3b7b8e27de33d3ce7961b98d19a52fe79f6c25be": { + "balance": "0x152d02c7e14af6800000" + }, + "3b7c77dbe95dc2602ce3269a9545d04965fefdbd": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b8098533f7d9bdcd307dbb23e1777ca18418936": { + "balance": "0x6c6b935b8bbd400000" + }, + "3b93b16136f11eaf10996c95990d3b2739ccea5f": { + "balance": "0x21e19e0c9bab2400000" + }, + "3bab4b01a7c84ba13feea9b0bb191b77a3aadca3": { + "balance": "0xad78ebc5ac6200000" + }, + "3bb53598cc20e2055dc553b049404ac9b7dd1e83": { + "balance": "0x21571df77c00be0000" + }, + "3bbc13d04accc0707aebdcaef087d0b87e0b5ee3": { + "balance": "0xbed1d0263d9f000000" + }, + "3bc6e3ee7a56ce8f14a37532590f63716b9966e8": { + "balance": "0x6c6b935b8bbd400000" + }, + "3bc85d6c735b9cda4bba5f48b24b13e70630307b": { + "balance": "0x6acb3df27e1f880000" + }, + "3bd624b548cb659736907ed8aa3c0c705e24b575": { + "balance": "0x6c6b935b8bbd400000" + }, + "3bd9a06d1bd36c4edd27fc0d1f5b088ddae3c72a": { + "balance": "0x1b1a7a420ba00d0000" + }, + "3bddbc8134f77d55597fc97c26d26698090604eb": { + "balance": "0xbe202d6a0eda0000" + }, + "3bf86ed8a3153ec933786a02ac090301855e576b": { + "balance": "0x5f4a8c8375d155400000" + }, + "3bfbd3847c17a61cf3f17b52f8eba1b960b3f39f": { + "balance": "0xa2a15d09519be00000" + }, + "3c03bbc023e1e93fa3a3a6e428cf0cd8f95e1ec6": { + "balance": "0x52663ccab1e1c00000" + }, + "3c0c3defac9cea7acc319a96c30b8e1fedab4574": { + "balance": "0x692ae8897081d00000" + }, + "3c15b3511df6f0342e7348cc89af39a168b7730f": { + "balance": "0x3635c9adc5dea00000" + }, + "3c1f91f301f4b565bca24751aa1f761322709ddd": { + "balance": "0x61093d7c2c6d380000" + }, + "3c286cfb30146e5fd790c2c8541552578de334d8": { + "balance": "0x2291b11aa306e8c0000" + }, + "3c322e611fdb820d47c6f8fc64b6fad74ca95f5e": { + "balance": "0xd258ece1b13150000" + }, + "3c5a241459c6abbf630239c98a30d20b8b3ac561": { + "balance": "0x88b23acffd9900000" + }, + "3c79c863c3d372b3ff0c6f452734a7f97042d706": { + "balance": "0x98a7d9b8314c00000" + }, + "3c83c1701db0388b68210d00f5717cd9bd322c6a": { + "balance": "0x65a4da25d3016c00000" + }, + "3c860e2e663f46db53427b29fe3ea5e5bf62bbcc": { + "balance": "0x556f64c1fe7fa0000" + }, + "3c869c09696523ced824a070414605bb76231ff2": { + "balance": "0x3635c9adc5dea00000" + }, + "3c925619c9b33144463f0537d896358706c520b0": { + "balance": "0x6c6b935b8bbd400000" + }, + "3c98594bf68b57351e8814ae9e6dfd2d254aa06f": { + "balance": "0x1043561a8829300000" + }, + "3cadeb3d3eed3f62311d52553e70df4afce56f23": { + "balance": "0xd8d726b7177a800000" + }, + "3caedb5319fe806543c56e5021d372f71be9062e": { + "balance": "0x878678326eac9000000" + }, + "3cafaf5e62505615068af8eb22a13ad8a9e55070": { + "balance": "0x6c660645aa47180000" + }, + "3cb179cb4801a99b95c3b0c324a2bdc101a65360": { + "balance": "0x168d28e3f00280000" + }, + "3cb561ce86424b359891e364ec925ffeff277df7": { + "balance": "0xad78ebc5ac6200000" + }, + "3ccb71aa6880cb0b84012d90e60740ec06acd78f": { + "balance": "0x6c6b935b8bbd400000" + }, + "3ccef88679573947e94997798a1e327e08603a65": { + "balance": "0x2bc916d69f3b020000" + }, + "3cd1d9731bd548c1dd6fcea61beb75d91754f7d3": { + "balance": "0x1161d01b215cae48000" + }, + "3cd3a6e93579c56d494171fc533e7a90e6f59464": { + "balance": "0x6c6b935b8bbd400000" + }, + "3cd6b7593cbee77830a8b19d0801958fcd4bc57a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "3cd7f7c7c2353780cde081eeec45822b25f2860c": { + "balance": "0xad78ebc5ac6200000" + }, + "3ce1dc97fcd7b7c4d3a18a49d6f2a5c1b1a906d7": { + "balance": "0xad78ebc5ac6200000" + }, + "3cea302a472a940379dd398a24eafdbadf88ad79": { + "balance": "0xa2a15d09519be00000" + }, + "3ceca96bb1cdc214029cbc5e181d398ab94d3d41": { + "balance": "0x10f0cf064dd592000000" + }, + "3cf484524fbdfadae26dc185e32b2b630fd2e726": { + "balance": "0x185452cb2a91c30000" + }, + "3cf9a1d465e78b7039e3694478e2627b36fcd141": { + "balance": "0x4a60532ad51bf00000" + }, + "3cfbf066565970639e130df2a7d16b0e14d6091c": { + "balance": "0x5c283d410394100000" + }, + "3d09688d93ad07f3abe68c722723cd680990435e": { + "balance": "0x65a4ce99f769e6e0000" + }, + "3d31587b5fd5869845788725a663290a49d3678c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "3d3fad49c9e5d2759c8e8e5a7a4d60a0dd135692": { + "balance": "0x1158e460913d00000" + }, + "3d574fcf00fae1d98cc8bf9ddfa1b3953b9741bc": { + "balance": "0x6acb3df27e1f880000" + }, + "3d5a8b2b80be8b35d8ecf789b5ed7a0775c5076c": { + "balance": "0x1158e460913d00000" + }, + "3d66cd4bd64d5c8c1b5eea281e106d1c5aad2373": { + "balance": "0x69c4f3a8a110a60000" + }, + "3d6ae053fcbc318d6fd0fbc353b8bf542e680d27": { + "balance": "0xc673ce3c40160000" + }, + "3d6ff82c9377059fb30d9215723f60c775c891fe": { + "balance": "0xd8e5ce617f2d50000" + }, + "3d79a853d71be0621b44e29759656ca075fdf409": { + "balance": "0x6c6b935b8bbd400000" + }, + "3d7ea5bf03528100ed8af8aed2653e921b6e6725": { + "balance": "0x3635c9adc5dea00000" + }, + "3d813ff2b6ed57b937dabf2b381d148a411fa085": { + "balance": "0x56bc75e2d63100000" + }, + "3d881433f04a7d0d27f84944e08a512da3555287": { + "balance": "0x410d586a20a4c00000" + }, + "3d89e505cb46e211a53f32f167a877bec87f4b0a": { + "balance": "0x15b3557f1937f8000" + }, + "3d8d0723721e73a6c0d860aa0557abd14c1ee362": { + "balance": "0x10f0cf064dd59200000" + }, + "3d8f39881b9edfe91227c33fa4cdd91e678544b0": { + "balance": "0x4ab07ba43ada98000" + }, + "3d9d6be57ff83e065985664f12564483f2e600b2": { + "balance": "0x6eace43f23bd800000" + }, + "3da39ce3ef4a7a3966b32ee7ea4ebc2335a8f11f": { + "balance": "0x6c6b935b8bbd400000" + }, + "3daa01ceb70eaf9591fa521ba4a27ea9fb8ede4a": { + "balance": "0x5a63d2c9bc76540000" + }, + "3db5fe6a68bd3612ac15a99a61e555928eeceaf3": { + "balance": "0x55a6e79ccd1d300000" + }, + "3db9ed7f024c7e26372feacf2b050803445e3810": { + "balance": "0x45b148b4996a300000" + }, + "3dbf0dbfd77890800533f09dea8301b9f025d2a6": { + "balance": "0x3635c9adc5dea00000" + }, + "3dcef19c868b15d34eda426ec7e04b18b6017002": { + "balance": "0x6c68ccd09b022c0000" + }, + "3dd12e556a603736feba4a6fa8bd4ac45d662a04": { + "balance": "0x23757b9183e078280000" + }, + "3dde8b15b3ccbaa5780112c3d674f313bba68026": { + "balance": "0x601d515a3e4f940000" + }, + "3ddedbe48923fbf9e536bf9ffb0747c9cdd39eef": { + "balance": "0x368c8623a8b4d100000" + }, + "3deae43327913f62808faa1b6276a2bd6368ead9": { + "balance": "0x6c6b935b8bbd400000" + }, + "3df762049eda8ac6927d904c7af42f94e5519601": { + "balance": "0x6c6b935b8bbd400000" + }, + "3e040d40cb80ba0125f3b15fdefcc83f3005da1b": { + "balance": "0x384524cc70b7780000" + }, + "3e0b8ed86ed669e12723af7572fbacfe829b1e16": { + "balance": "0x514de7f9b812dc0000" + }, + "3e0cbe6a6dcb61f110c45ba2aa361d7fcad3da73": { + "balance": "0x1b2df9d219f57980000" + }, + "3e194b4ecef8bb711ea2ff24fec4e87bd032f7d1": { + "balance": "0x8b9dc1bc1a036a8000" + }, + "3e1b2230afbbd310b4926a4c776d5ae7819c661d": { + "balance": "0x65a4da25d3016c00000" + }, + "3e1c53300e4c168912163c7e99b95da268ad280a": { + "balance": "0x3662325cd18fe00000" + }, + "3e1c962063e0d5295941f210dca3ab531eec8809": { + "balance": "0xa2a15d09519be00000" + }, + "3e2ca0d234baf607ad466a1b85f4a6488ef00ae7": { + "balance": "0x4da21a3483d568000" + }, + "3e2f26235e137a7324e4dc154b5df5af46ea1a49": { + "balance": "0x137aad8032db90000" + }, + "3e3161f1ea2fbf126e79da1801da9512b37988c9": { + "balance": "0xa6dd90cae5114480000" + }, + "3e36c17253c11cf38974ed0db1b759160da63783": { + "balance": "0x17b7883c06916600000" + }, + "3e3cd3bec06591d6346f254b621eb41c89008d31": { + "balance": "0x35dfbeda9f37340000" + }, + "3e45bd55db9060eced923bb9cb733cb3573fb531": { + "balance": "0x58e7926ee858a00000" + }, + "3e4d13c55a84e46ed7e9cb90fd355e8ad991e38f": { + "balance": "0x3635c9adc5dea00000" + }, + "3e4e9265223c9738324cf20bd06006d0073edb8c": { + "balance": "0x73f75d1a085ba0000" + }, + "3e4fbd661015f6461ed6735cefef01f31445de3a": { + "balance": "0x36e342998b8b0200000" + }, + "3e53ff2107a8debe3328493a92a586a7e1f49758": { + "balance": "0x4e69c2a71a405ab0000" + }, + "3e5a39fdda70df1126ab0dc49a7378311a537a1f": { + "balance": "0x821ab0d44149800000" + }, + "3e5abd09ce5af7ba8487c359e0f2a93a986b0b18": { + "balance": "0x21e19e0c9bab2400000" + }, + "3e5cb8928c417825c03a3bfcc52183e5c91e42d7": { + "balance": "0xe731d9c52c962f0000" + }, + "3e5e93fb4c9c9d1246f8f247358e22c3c5d17b6a": { + "balance": "0x821ab0d4414980000" + }, + "3e618350fa01657ab0ef3ebac8e37012f8fc2b6f": { + "balance": "0x9806de3da6e9780000" + }, + "3e63ce3b24ca2865b4c5a687b7aea3597ef6e548": { + "balance": "0x6c6b935b8bbd400000" + }, + "3e66b84769566ab67945d5fa81373556bcc3a1fa": { + "balance": "0x83d6c7aab63600000" + }, + "3e76a62db187aa74f63817533b306cead0e8cebe": { + "balance": "0x69b5afac750bb800000" + }, + "3e7a966b5dc357ffb07e9fe067c45791fd8e3049": { + "balance": "0x3342d60dff1960000" + }, + "3e81772175237eb4cbe0fe2dcafdadffeb6a1999": { + "balance": "0x1dd0c885f9a0d800000" + }, + "3e8349b67f5745449f659367d9ad4712db5b895a": { + "balance": "0x62a992e53a0af00000" + }, + "3e83544f0082552572c782bee5d218f1ef064a9d": { + "balance": "0x56cd55fc64dfe0000" + }, + "3e84b35c5b2265507061d30b6f12da033fe6f8b9": { + "balance": "0x61093d7c2c6d380000" + }, + "3e8641d43c42003f0a33c929f711079deb2b9e46": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "3e8745ba322f5fd6cb50124ec46688c7a69a7fae": { + "balance": "0x10afc1ade3b4ed40000" + }, + "3e914e3018ac00449341c49da71d04dfeeed6221": { + "balance": "0xd8d726b7177a800000" + }, + "3e9410d3b9a87ed5e451a6b91bb8923fe90fb2b5": { + "balance": "0xad78ebc5ac6200000" + }, + "3e94df5313fa520570ef232bc3311d5f622ff183": { + "balance": "0x6c6b935b8bbd400000" + }, + "3e9b34a57f3375ae59c0a75e19c4b641228d9700": { + "balance": "0xf8699329677e0000" + }, + "3eada8c92f56067e1bb73ce378da56dc2cdfd365": { + "balance": "0x77cde93aeb0d480000" + }, + "3eaf0879b5b6db159b589f84578b6a74f6c10357": { + "balance": "0x18938b671fa65a28000" + }, + "3eaf316b87615d88f7adc77c58e712ed4d77966b": { + "balance": "0x56dbc4cee24648000" + }, + "3eb8b33b21d23cda86d8288884ab470e164691b5": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "3eb9ef06d0c259040319947e8c7a6812aa0253d8": { + "balance": "0x90d972f32323c0000" + }, + "3ecc8e1668dde995dc570fe414f44211c534a615": { + "balance": "0x6c6b935b8bbd400000" + }, + "3ecdb532e397579662b2a46141e78f8235936a5f": { + "balance": "0x39fbae8d042dd0000" + }, + "3eee6f1e96360b7689b3069adaf9af8eb60ce481": { + "balance": "0x3635c9adc5dea00000" + }, + "3f08d9ad894f813e8e2148c160d24b353a8e74b0": { + "balance": "0xcb49b44ba602d800000" + }, + "3f0c83aac5717962734e5ceaeaecd39b28ad06be": { + "balance": "0x6c6b935b8bbd400000" + }, + "3f10800282d1b7ddc78fa92d8230074e1bf6aeae": { + "balance": "0x10afc1ade3b4ed40000" + }, + "3f1233714f204de9de4ee96d073b368d8197989f": { + "balance": "0x217c41074e6bb0000" + }, + "3f173aa6edf469d185e59bd26ae4236b92b4d8e1": { + "balance": "0x1158e460913d000000" + }, + "3f1bc420c53c002c9e90037c44fe6a8ef4ddc962": { + "balance": "0x960db77681e940000" + }, + "3f236108eec72289bac3a65cd283f95e041d144c": { + "balance": "0x3634bf39ab98788000" + }, + "3f2da093bb16eb064f8bfa9e30b929d15f8e1c4c": { + "balance": "0x6c6b935b8bbd400000" + }, + "3f2dd55db7eab0ebee65b33ed8202c1e992e958b": { + "balance": "0x2c73c937742c500000" + }, + "3f2f381491797cc5c0d48296c14fd0cd00cdfa2d": { + "balance": "0x2b95bdcc39b6100000" + }, + "3f30d3bc9f602232bc724288ca46cd0b0788f715": { + "balance": "0xd8d726b7177a800000" + }, + "3f3c8e61e5604cef0605d436dd22accd862217fc": { + "balance": "0x487a9a304539440000" + }, + "3f3f46b75cabe37bfacc8760281f4341ca7f463d": { + "balance": "0x20ac448235fae88000" + }, + "3f472963197883bbda5a9b7dfcb22db11440ad31": { + "balance": "0x1a19643cb1eff08000" + }, + "3f4cd1399f8a34eddb9a17a471fc922b5870aafc": { + "balance": "0xad78ebc5ac6200000" + }, + "3f551ba93cd54693c183fb9ad60d65e1609673c9": { + "balance": "0x6c6b935b8bbd400000" + }, + "3f627a769e6a950eb87017a7cd9ca20871136831": { + "balance": "0x2eb8eb1a172dcb80000" + }, + "3f6dd3650ee428dcb7759553b017a96a94286ac9": { + "balance": "0x487a9a304539440000" + }, + "3f747237806fed3f828a6852eb0867f79027af89": { + "balance": "0x5150ae84a8cdf00000" + }, + "3f75ae61cc1d8042653b5baec4443e051c5e7abd": { + "balance": "0x52d542804f1ce0000" + }, + "3fb7d197b3ba4fe045efc23d50a14585f558d9b2": { + "balance": "0x1158e460913d00000" + }, + "3fbc1e4518d73400c6d046359439fb68ea1a49f4": { + "balance": "0x3790bb8551376400000" + }, + "3fbed6e7e0ca9c84fbe9ebcf9d4ef9bb49428165": { + "balance": "0x6c6b935b8bbd400000" + }, + "3fd0bb47798cf44cdfbe4d333de637df4a00e45c": { + "balance": "0x56c5579f722140000" + }, + "3fe40fbd919aad2818df01ee4df46c46842ac539": { + "balance": "0x14542ba12a337c00000" + }, + "3fe801e61335c5140dc7eda2ef5204460a501230": { + "balance": "0x6c6b935b8bbd400000" + }, + "3ff836b6f57b901b440c30e4dbd065cf37d3d48c": { + "balance": "0xad78ebc5ac6200000" + }, + "3ffcb870d4023d255d5167d8a507cefc366b68ba": { + "balance": "0x23343c4354d2ac0000" + }, + "401354a297952fa972ad383ca07a0a2811d74a71": { + "balance": "0xc249fdd327780000" + }, + "4030a925706b2c101c8c5cb9bd05fbb4f6759b18": { + "balance": "0xd8d726b7177a800000" + }, + "403145cb4ae7489fcc90cd985c6dc782b3cc4e44": { + "balance": "0x1453ff387b27cac0000" + }, + "403220600a36f73f24e190d1edb2d61be3f41354": { + "balance": "0x107ad8f556c6c00000" + }, + "4039bd50a2bde15ffe37191f410390962a2b8886": { + "balance": "0xad78ebc5ac6200000" + }, + "403c64896a75cad816a9105e18d8aa5bf80f238e": { + "balance": "0x35659ef93f0fc40000" + }, + "403d53cf620f0922b417848dee96c190b5bc8271": { + "balance": "0x215f835bc769da80000" + }, + "404100db4c5d0eec557823b58343758bcc2c8083": { + "balance": "0x1158e460913d00000" + }, + "4041374b0feef4792e4b33691fb86897a4ff560c": { + "balance": "0x13c9647e25a9940000" + }, + "40467d80e74c35407b7db51789234615fea66818": { + "balance": "0x150894e849b3900000" + }, + "40585200683a403901372912a89834aadcb55fdb": { + "balance": "0x6c6b935b8bbd400000" + }, + "4058808816fdaa3a5fc98ed47cfae6c18315422e": { + "balance": "0xad4c8316a0b0c0000" + }, + "405f596b94b947344c033ce2dcbff12e25b79784": { + "balance": "0x6c6b935b8bbd400000" + }, + "40630024bd2c58d248edd8465617b2bf1647da0e": { + "balance": "0x3635c9adc5dea00000" + }, + "40652360d6716dc55cf9aab21f3482f816cc2cbd": { + "balance": "0x21e19e0c9bab2400000" + }, + "407295ebd94b48269c2d569c9b9af9aa05e83e5e": { + "balance": "0x21e19e0c9bab2400000" + }, + "4073fa49b87117cb908cf1ab512da754a932d477": { + "balance": "0x6acb3df27e1f880000" + }, + "408a69a40715e1b313e1354e600800a1e6dc02a5": { + "balance": "0x1e7b891cc92540000" + }, + "409bd75085821c1de70cdc3b11ffc3d923c74010": { + "balance": "0xd8d726b7177a800000" + }, + "409d5a962edeeebea178018c0f38b9cdb213f289": { + "balance": "0x1158e460913d00000" + }, + "40a331195b977325c2aa28fa2f42cb25ec3c253c": { + "balance": "0x6c6b935b8bbd400000" + }, + "40a7f72867a7dc86770b162b7557a434ed50cce9": { + "balance": "0x3635c9adc5dea00000" + }, + "40ab0a3e83d0c8ac9366910520eab1772bac3b1a": { + "balance": "0x34f10c2dc05e7c0000" + }, + "40ab66fe213ea56c3afb12c75be33f8e32fd085d": { + "balance": "0xd8d726b7177a800000" + }, + "40ad74bc0bce2a45e52f36c3debb1b3ada1b7619": { + "balance": "0x170162de109c6580000" + }, + "40cf890591eae4a18f812a2954cb295f633327e6": { + "balance": "0x29bf736fc591a0000" + }, + "40cf90ef5b768c5da585002ccbe6617650d8e837": { + "balance": "0x36330322d5238c0000" + }, + "40d45d9d7625d15156c932b771ca7b0527130958": { + "balance": "0x152d02c7e14af6800000" + }, + "40db1ba585ce34531edec5494849391381e6ccd3": { + "balance": "0x61093d7c2c6d380000" + }, + "40df495ecf3f8b4cef2a6c189957248fe884bc2b": { + "balance": "0x28a857425466f800000" + }, + "40e0dbf3efef9084ea1cd7e503f40b3b4a8443f6": { + "balance": "0xd8d726b7177a800000" + }, + "40e2440ae142c880366a12c6d4102f4b8434b62a": { + "balance": "0x3635c9adc5dea00000" + }, + "40e3c283f7e24de0410c121bee60a5607f3e29a6": { + "balance": "0x3635c9adc5dea00000" + }, + "40ea5044b204b23076b1a5803bf1d30c0f88871a": { + "balance": "0x2f6f10780d22cc00000" + }, + "40eddb448d690ed72e05c225d34fc8350fa1e4c5": { + "balance": "0x17b7883c06916600000" + }, + "40f4f4c06c732cd35b119b893b127e7d9d0771e4": { + "balance": "0x21e19e0c9bab2400000" + }, + "41010fc8baf8437d17a04369809a168a17ca56fb": { + "balance": "0x56bc75e2d63100000" + }, + "4103299671d46763978fa4aa19ee34b1fc952784": { + "balance": "0xad78ebc5ac6200000" + }, + "41033c1b6d05e1ca89b0948fc64453fbe87ab25e": { + "balance": "0x487a9a304539440000" + }, + "41098a81452317c19e3eef0bd123bbe178e9e9ca": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "411610b178d5617dfab934d293f512a93e5c10e1": { + "balance": "0x93739534d28680000" + }, + "411c831cc6f44f1965ec5757ab4e5b3ca4cffd1f": { + "balance": "0x170a0f5040e5040000" + }, + "412a68f6c645559cc977fc4964047a201d1bb0e2": { + "balance": "0xa968163f0a57b400000" + }, + "413f4b02669ccff6806bc826fcb7deca3b0ea9bc": { + "balance": "0x1158e460913d00000" + }, + "414599092e879ae25372a84d735af5c4e510cd6d": { + "balance": "0x15af1d78b58c400000" + }, + "41485612d03446ec4c05e5244e563f1cbae0f197": { + "balance": "0x34957444b840e80000" + }, + "415d096ab06293183f3c033d25f6cf7178ac3bc7": { + "balance": "0x22b1c8c1227a00000" + }, + "4166fc08ca85f766fde831460e9dc93c0e21aa6c": { + "balance": "0x3635c9adc5dea00000" + }, + "416784af609630b070d49a8bcd12235c6428a408": { + "balance": "0x43c33c1937564800000" + }, + "4167cd48e733418e8f99ffd134121c4a4ab278c4": { + "balance": "0xc55325ca7415e00000" + }, + "416c86b72083d1f8907d84efd2d2d783dffa3efb": { + "balance": "0x6c6acc67d7b1d40000" + }, + "4173419d5c9f6329551dc4d3d0ceac1b701b869e": { + "balance": "0x4c53ecdc18a600000" + }, + "4174fa1bc12a3b7183cbabb77a0b59557ba5f1db": { + "balance": "0x6c6b935b8bbd400000" + }, + "41786a10d447f484d33244ccb7facd8b427b5b8c": { + "balance": "0x3635c9adc5dea00000" + }, + "417a3cd19496530a6d4204c3b5a17ce0f207b1a5": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "417e4e2688b1fd66d821529e46ed4f42f8b3db3d": { + "balance": "0x6c6b935b8bbd400000" + }, + "419a71a36c11d105e0f2aef5a3e598078e85c80b": { + "balance": "0x10f0cf064dd59200000" + }, + "419bde7316cc1ed295c885ace342c79bf7ee33ea": { + "balance": "0x14542ba12a337c00000" + }, + "41a2f2e6ecb86394ec0e338c0fc97e9c5583ded2": { + "balance": "0x6cee06ddbe15ec0000" + }, + "41a8c2830081b102df6e0131657c07ab635b54ce": { + "balance": "0x6c6acc67d7b1d40000" + }, + "41a8e236a30e6d63c1ff644d132aa25c89537e01": { + "balance": "0x1158e460913d00000" + }, + "41a9a404fc9f5bfee48ec265b12523338e29a8bf": { + "balance": "0x150894e849b3900000" + }, + "41ad369f758fef38a19aa3149379832c818ef2a0": { + "balance": "0x36369ed7747d260000" + }, + "41b2d34fde0b1029262b4172c81c1590405b03ae": { + "balance": "0x3635c9adc5dea00000" + }, + "41b2dbd79dda9b864f6a7030275419c39d3efd3b": { + "balance": "0xad78ebc5ac62000000" + }, + "41c3c2367534d13ba2b33f185cdbe6ac43c2fa31": { + "balance": "0xd8d726b7177a800000" + }, + "41cb9896445f70a10a14215296daf614e32cf4d5": { + "balance": "0x678a932062e4180000" + }, + "41ce79950935cff55bf78e4ccec2fe631785db95": { + "balance": "0x6c6b935b8bbd400000" + }, + "41d3b731a326e76858baa5f4bd89b57b36932343": { + "balance": "0x155bd9307f9fe80000" + }, + "41e4a20275e39bdcefeb655c0322744b765140c2": { + "balance": "0x21e19e0c9bab2400000" + }, + "41ed2d8e7081482c919fc23d8f0091b3c82c4685": { + "balance": "0x463a1e765bd78a0000" + }, + "41f27e744bd29de2b0598f02a0bb9f98e681eaa4": { + "balance": "0x1a4aba225c207400000" + }, + "41f489a1ec747bc29c3e5f9d8db97877d4d1b4e9": { + "balance": "0x73f75d1a085ba0000" + }, + "420fb86e7d2b51401fc5e8c72015decb4ef8fc2e": { + "balance": "0x3635c9adc5dea00000" + }, + "421684baa9c0b4b5f55338e6f6e7c8e146d41cb7": { + "balance": "0x5150ae84a8cdf00000" + }, + "42399659aca6a5a863ea2245c933fe9a35b7880e": { + "balance": "0x6ece32c26c82700000" + }, + "423bca47abc00c7057e3ad34fca63e375fbd8b4a": { + "balance": "0x3cfc82e37e9a7400000" + }, + "423c3107f4bace414e499c64390a51f74615ca5e": { + "balance": "0x6c6b935b8bbd400000" + }, + "423cc4594cf4abb6368de59fd2b1230734612143": { + "balance": "0x6c6b935b8bbd400000" + }, + "4244f1331158b9ce26bbe0b9236b9203ca351434": { + "balance": "0x21e19e0c9bab2400000" + }, + "425177eb74ad0a9d9a5752228147ee6d6356a6e6": { + "balance": "0xb98bc829a6f90000" + }, + "425725c0f08f0811f5f006eec91c5c5c126b12ae": { + "balance": "0x821ab0d4414980000" + }, + "4258fd662fc4ce3295f0d4ed8f7bb1449600a0a9": { + "balance": "0x16c452ed6088ad80000" + }, + "425c1816868f7777cc2ba6c6d28c9e1e796c52b3": { + "balance": "0x21e19e0c9bab2400000" + }, + "425c338a1325e3a1578efa299e57d986eb474f81": { + "balance": "0x6c6b935b8bbd400000" + }, + "426259b0a756701a8b663528522156c0288f0f24": { + "balance": "0x218ae196b8d4f300000" + }, + "426d15f407a01135b13a6b72f8f2520b3531e302": { + "balance": "0x1158e460913d00000" + }, + "426f78f70db259ac8534145b2934f4ef1098b5d8": { + "balance": "0x138400eca364a00000" + }, + "42732d8ef49ffda04b19780fd3c18469fb374106": { + "balance": "0x170b00e5e4a9be0000" + }, + "427417bd16b1b3d22dbb902d8f9657016f24a61c": { + "balance": "0x6c6b935b8bbd400000" + }, + "42746aeea14f27beff0c0da64253f1e7971890a0": { + "balance": "0x54069233bf7f780000" + }, + "427b462ab84e5091f48a46eb0cdc92ddcb26e078": { + "balance": "0x6c6b935b8bbd400000" + }, + "427e4751c3babe78cff8830886febc10f9908d74": { + "balance": "0x6acb3df27e1f880000" + }, + "427ec668ac9404e895cc861511d1620a4912be98": { + "balance": "0x878678326eac9000000" + }, + "4280a58f8bb10b9440de94f42b4f592120820191": { + "balance": "0x6c6b935b8bbd400000" + }, + "428a1ee0ed331d7952ccbe1c7974b2852bd1938a": { + "balance": "0x77b74a4e8de5650000" + }, + "429c06b487e8546abdfc958a25a3f0fba53f6f00": { + "balance": "0xbb644af542198000" + }, + "42a98bf16027ce589c4ed2c95831e2724205064e": { + "balance": "0x21e19e0c9bab2400000" + }, + "42c6edc515d35557808d13cd44dcc4400b2504e4": { + "balance": "0xaba14c59ba7320000" + }, + "42cecfd2921079c2d7df3f08b07aa3beee5e219a": { + "balance": "0x3635c9adc5dea00000" + }, + "42d1a6399b3016a8597f8b640927b8afbce4b215": { + "balance": "0xa18bcec34888100000" + }, + "42d34940edd2e7005d46e2188e4cfece8311d74d": { + "balance": "0x890b0c2e14fb80000" + }, + "42d3a5a901f2f6bd9356f112a70180e5a1550b60": { + "balance": "0x3224f42723d4540000" + }, + "42d6b263d9e9f4116c411424fc9955783c763030": { + "balance": "0x6c6b935b8bbd400000" + }, + "42db0b902559e04087dd5c441bc7611934184b89": { + "balance": "0x6d33b17d253a620000" + }, + "42ddd014dc52bfbcc555325a40b516f4866a1dd3": { + "balance": "0x6c6b935b8bbd400000" + }, + "4319263f75402c0b5325f263be4a5080651087f0": { + "balance": "0x354b0f14631bab0000" + }, + "431f2c19e316b044a4b3e61a0c6ff8c104a1a12f": { + "balance": "0x3635c9adc5dea00000" + }, + "43227d65334e691cf231b4a4e1d339b95d598afb": { + "balance": "0x21e19e0c9bab2400000" + }, + "432809a2390f07c665921ff37d547d12f1c9966a": { + "balance": "0x65a4da25d3016c00000" + }, + "4329fc0931cbeb033880fe4c9398ca45b0e2d11a": { + "balance": "0x6c7120716d33680000" + }, + "432d884bd69db1acc0d89c64ade4cb4fc3a88b7a": { + "balance": "0x869a8c10808eec0000" + }, + "4331ab3747d35720a9d8ca25165cd285acd4bda8": { + "balance": "0x6c6b935b8bbd400000" + }, + "433a3b68e56b0df1862b90586bbd39c840ff1936": { + "balance": "0x6c6b935b8bbd400000" + }, + "433e3ba1c51b810fc467d5ba4dea42f7a9885e69": { + "balance": "0x878678326eac9000000" + }, + "433eb94a339086ed12d9bde9cd1d458603c97dd6": { + "balance": "0x152d02c7e14af6800000" + }, + "4349225a62f70aea480a029915a01e5379e64fa5": { + "balance": "0x8cd67e2334c0d80000" + }, + "4354221e62dc09e6406436163a185ef06d114a81": { + "balance": "0x6c6b935b8bbd400000" + }, + "435443b81dfdb9bd8c6787bc2518e2d47e57c15f": { + "balance": "0x1438d9397881ef20000" + }, + "4361d4846fafb377b6c0ee49a596a78ddf3516a3": { + "balance": "0xc2127af858da700000" + }, + "4364309a9fa07095600f79edc65120cdcd23dc64": { + "balance": "0x21e19e0c9bab2400000" + }, + "4367ae4b0ce964f4a54afd4b5c368496db169e9a": { + "balance": "0x6c6b935b8bbd400000" + }, + "43748928e8c3ec4436a1d092fbe43ac749be1251": { + "balance": "0x15af1d78b58c400000" + }, + "43767bf7fd2af95b72e9312da9443cb1688e4343": { + "balance": "0x1043561a8829300000" + }, + "437983388ab59a4ffc215f8e8269461029c3f1c1": { + "balance": "0x43c33c1937564800000" + }, + "43898c49a34d509bfed4f76041ee91caf3aa6aa5": { + "balance": "0x1043561a8829300000" + }, + "438c2f54ff8e629bab36b1442b760b12a88f02ae": { + "balance": "0x6c6b935b8bbd400000" + }, + "4398628ea6632d393e929cbd928464c568aa4a0c": { + "balance": "0x4be4e7267b6ae00000" + }, + "439d2f2f5110a4d58b1757935015408740fec7f8": { + "balance": "0xcfa5c5150f4c888000" + }, + "439dee3f7679ff1030733f9340c096686b49390b": { + "balance": "0x6c6b935b8bbd400000" + }, + "43b079baf0727999e66bf743d5bcbf776c3b0922": { + "balance": "0x6c6b935b8bbd400000" + }, + "43bc2d4ddcd6583be2c7bc094b28fb72e62ba83b": { + "balance": "0x6c6b935b8bbd400000" + }, + "43c7ebc5b3e7af16f47dc5617ab10e0f39b4afbb": { + "balance": "0x678a932062e4180000" + }, + "43cb9652818c6f4d6796b0e89409306c79db6349": { + "balance": "0x6c6b935b8bbd400000" + }, + "43cc08d0732aa58adef7619bed46558ad7774173": { + "balance": "0xf0e7dcb0122a8f0000" + }, + "43d5a71ce8b8f8ae02b2eaf8eaf2ca2840b93fb6": { + "balance": "0x14542ba12a337c00000" + }, + "43db7ff95a086d28ebbfb82fb8fb5f230a5ebccd": { + "balance": "0xdf6eb0b2d3ca0000" + }, + "43e7ec846358d7d0f937ad1c350ba069d7bf72bf": { + "balance": "0x670ae629214680000" + }, + "43f16f1e75c3c06a9478e8c597a40a3cb0bf04cc": { + "balance": "0x9df7dfa8f760480000" + }, + "43f470ed659e2991c375957e5ddec5bd1d382231": { + "balance": "0x56bc75e2d63100000" + }, + "43f7e86e381ec51ec4906d1476cba97a3db584e4": { + "balance": "0x3635c9adc5dea00000" + }, + "43ff38743ed0cd43308c066509cc8e7e72c862aa": { + "balance": "0x692ae8897081d00000" + }, + "43ff8853e98ed8406b95000ada848362d6a0392a": { + "balance": "0x4ae0b1c4d2e84d00000" + }, + "44098866a69b68c0b6bc168229b9603587058967": { + "balance": "0xa31062beeed700000" + }, + "4419ac618d5dea7cdc6077206fb07dbdd71c1702": { + "balance": "0xd8d726b7177a800000" + }, + "441a52001661fac718b2d7b351b7c6fb521a7afd": { + "balance": "0x15af1d78b58c400000" + }, + "441aca82631324acbfa2468bda325bbd78477bbf": { + "balance": "0x14542ba12a337c00000" + }, + "441f37e8a029fd02482f289c49b5d06d00e408a4": { + "balance": "0x1211ecb56d13488000" + }, + "4420aa35465be617ad2498f370de0a3cc4d230af": { + "balance": "0x6c6b935b8bbd400000" + }, + "44232ff66ddad1fd841266380036afd7cf7d7f42": { + "balance": "0xad78ebc5ac6200000" + }, + "44250d476e062484e9080a3967bf3a4a732ad73f": { + "balance": "0x1158e460913d00000" + }, + "4429a29fee198450672c0c1d073162250bec6474": { + "balance": "0x362aaf8202f2500000" + }, + "44355253b27748e3f34fe9cae1fb718c8f249529": { + "balance": "0xad78ebc5ac6200000" + }, + "4438e880cb2766b0c1ceaec9d2418fceb952a044": { + "balance": "0x73fa073903f080000" + }, + "444caf79b71338ee9aa7c733b02acaa7dc025948": { + "balance": "0x22b1c8c1227a00000" + }, + "445cb8de5e3df520b499efc980f52bff40f55c76": { + "balance": "0x6c6b935b8bbd400000" + }, + "446a8039cecf9dce4879cbcaf3493bf545a88610": { + "balance": "0x17b7883c06916600000" + }, + "4474299d0ee090dc90789a1486489c3d0d645e6d": { + "balance": "0x3635c9adc5dea00000" + }, + "448bf410ad9bbc2fecc4508d87a7fc2e4b8561ad": { + "balance": "0xad6eedd17cf3b8000" + }, + "44901e0d0e08ac3d5e95b8ec9d5e0ff5f12e0393": { + "balance": "0x16a1f9f5fd7d960000" + }, + "4493123c021ece3b33b1a452c9268de14007f9d3": { + "balance": "0x16a6502f15a1e540000" + }, + "449ac4fbe383e36738855e364a57f471b2bfa131": { + "balance": "0x29b76432b94451200000" + }, + "44a01fb04ac0db2cce5dbe281e1c46e28b39d878": { + "balance": "0x6c6acc67d7b1d40000" + }, + "44a63d18424587b9b307bfc3c364ae10cd04c713": { + "balance": "0x1158e460913d00000" + }, + "44a8989e32308121f72466978db395d1f76c3a4b": { + "balance": "0x18850299f42b06a0000" + }, + "44c1110b18870ec81178d93d215838c551d48e64": { + "balance": "0xad6f98593bd8f0000" + }, + "44c14765127cde11fab46c5d2cf4d4b2890023fd": { + "balance": "0x6c6b935b8bbd400000" + }, + "44c54eaa8ac940f9e80f1e74e82fc14f1676856a": { + "balance": "0x1ab2cf7c9f87e200000" + }, + "44cd77535a893fa7c4d5eb3a240e79d099a72d2d": { + "balance": "0x2c73c937742c500000" + }, + "44dfba50b829becc5f4f14d1b04aab3320a295e5": { + "balance": "0x3635c9adc5dea00000" + }, + "44e2fdc679e6bee01e93ef4a3ab1bcce012abc7c": { + "balance": "0x163d194900c5458000" + }, + "44f62f2aaabc29ad3a6b04e1ff6f9ce452d1c140": { + "balance": "0x39992648a23c8a00000" + }, + "44fff37be01a3888d3b8b8e18880a7ddefeeead3": { + "balance": "0xe0c5bfc7dae9a8000" + }, + "4506fe19fa4b006baa3984529d8516db2b2b50ab": { + "balance": "0x6c6b935b8bbd400000" + }, + "451b3699475bed5d7905f8905aa3456f1ed788fc": { + "balance": "0x8ac7230489e8000000" + }, + "451b7070259bdba27100e36e23428a53dfe304e9": { + "balance": "0xb98bc829a6f90000" + }, + "45272b8f62e9f9fa8ce04420e1aea3eba9686eac": { + "balance": "0xd8d726b7177a800000" + }, + "452b64db8ef7d6df87c788639c2290be8482d575": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "453e359a3397944c5a275ab1a2f70a5e5a3f6989": { + "balance": "0xd02ab486cedc00000" + }, + "4549b15979255f7e65e99b0d5604db98dfcac8bf": { + "balance": "0xd8d726b7177a800000" + }, + "454b61b344c0ef965179238155f277c3829d0b38": { + "balance": "0x6c6b935b8bbd400000" + }, + "454f0141d721d33cbdc41018bd01119aa4784818": { + "balance": "0x14542ba12a337c00000" + }, + "45533390e340fe0de3b3cf5fb9fc8ea552e29e62": { + "balance": "0x4f2591f896a6500000" + }, + "455396a4bbd9bae8af9fb7c4d64d471db9c24505": { + "balance": "0x8ba52e6fc45e40000" + }, + "455b9296921a74d1fc41617f43b8303e6f3ed76c": { + "balance": "0xe3aeb5737240a00000" + }, + "455cb8ee39ffbc752331e5aefc588ef0ee593454": { + "balance": "0x3635463a780def8000" + }, + "456ae0aca48ebcfae166060250525f63965e760f": { + "balance": "0x1043561a8829300000" + }, + "456f8d746682b224679349064d1b368c7c05b176": { + "balance": "0xc893d09c8f51500000" + }, + "457029c469c4548d168cec3e65872e4428d42b67": { + "balance": "0x6c6b935b8bbd400000" + }, + "4571de672b9904bad8743692c21c4fdcea4c2e01": { + "balance": "0xd8d726b7177a800000" + }, + "45781bbe7714a1c8f73b1c747921df4f84278b70": { + "balance": "0x6c6b935b8bbd400000" + }, + "457bcef37dd3d60b2dd019e3fe61d46b3f1e7252": { + "balance": "0x1158e460913d00000" + }, + "458e3cc99e947844a18e6a42918fef7e7f5f5eb3": { + "balance": "0x7b53f79e888dac00000" + }, + "459393d63a063ef3721e16bd9fde45ee9dbd77fb": { + "balance": "0x6abad6a3c153050000" + }, + "45a570dcc2090c86a6b3ea29a60863dde41f13b5": { + "balance": "0xc9a95ee2986520000" + }, + "45a820a0672f17dc74a08112bc643fd1167736c3": { + "balance": "0xad6c43b2815ed8000" + }, + "45b47105fe42c4712dce6e2a21c05bffd5ea47a9": { + "balance": "0x6c6b935b8bbd400000" + }, + "45bb829652d8bfb58b8527f0ecb621c29e212ec3": { + "balance": "0x6c6b935b8bbd400000" + }, + "45c0d19f0b8e054f9e893836d5ecae7901af2812": { + "balance": "0x10f0cf064dd59200000" + }, + "45c4ecb4ee891ea984a7c5cefd8dfb00310b2850": { + "balance": "0x6b56051582a9700000" + }, + "45ca8d956608f9e00a2f9974028640888465668f": { + "balance": "0x6c6b935b8bbd400000" + }, + "45ca9862003b4e40a3171fb5cafa9028cac8de19": { + "balance": "0x2eb8eb1a172dcb80000" + }, + "45d1c9eedf7cab41a779057b79395f5428d80528": { + "balance": "0x6c6b935b8bbd400000" + }, + "45d4b54d37a8cf599821235f062fa9d170ede8a4": { + "balance": "0x1190673b5fda900000" + }, + "45db03bccfd6a5f4d0266b82a22a368792c77d83": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "45e3a93e72144ada860cbc56ff85145ada38c6da": { + "balance": "0x57473d05dabae80000" + }, + "45e68db8dbbaba5fc2cb337c62bcd0d61b059189": { + "balance": "0x6c6b935b8bbd400000" + }, + "45e68db94c7d0ab7ac41857a71d67147870f4e71": { + "balance": "0x54b40b1f852bda000000" + }, + "45f4fc60f08eaca10598f0336329801e3c92cb46": { + "balance": "0xad78ebc5ac6200000" + }, + "460d5355b2ceeb6e62107d81e51270b26bf45620": { + "balance": "0x6cb7e74867d5e60000" + }, + "46224f32f4ece5c8867090d4409d55e50b18432d": { + "balance": "0x14542ba12a337c00000" + }, + "4627c606842671abde8295ee5dd94c7f549534f4": { + "balance": "0xf895fbd8732f40000" + }, + "462b678b51b584f3ed7ada070b5cd99c0bf7b87f": { + "balance": "0x56bc75e2d63100000" + }, + "464d9c89cce484df000277198ed8075fa63572d1": { + "balance": "0x1158e460913d00000" + }, + "46504e6a215ac83bccf956befc82ab5a679371c8": { + "balance": "0x1c212805c2b4a50000" + }, + "4651dc420e08c3293b27d2497890eb50223ae2f4": { + "balance": "0x43c33c1937564800000" + }, + "46531e8b1bde097fdf849d6d119885608a008df7": { + "balance": "0xad78ebc5ac6200000" + }, + "466292f0e80d43a78774277590a9eb45961214f4": { + "balance": "0x34957444b840e80000" + }, + "4662a1765ee921842ddc88898d1dc8627597bd7e": { + "balance": "0x21e19e0c9bab2400000" + }, + "4665e47396c7db97eb2a03d90863d5d4ba319a94": { + "balance": "0x2086ac351052600000" + }, + "466fda6b9b58c5532750306a10a2a8c768103b07": { + "balance": "0xad6eedd17cf3b8000" + }, + "467124ae7f452f26b3d574f6088894fa5d1cfb3b": { + "balance": "0x925e06eec972b00000" + }, + "46722a36a01e841d03f780935e917d85d5a67abd": { + "balance": "0xcec76f0e71520000" + }, + "46779a5656ff00d73eac3ad0c38b6c853094fb40": { + "balance": "0xc8253c96c6af00000" + }, + "4677b04e0343a32131fd6abb39b1b6156bba3d5b": { + "balance": "0xad78ebc5ac6200000" + }, + "467d5988249a68614716659840ed0ae6f6f457bc": { + "balance": "0x1501a48cefdfde0000" + }, + "467e0ed54f3b76ae0636176e07420815a021736e": { + "balance": "0x6c6b935b8bbd400000" + }, + "467ea10445827ef1e502daf76b928a209e0d4032": { + "balance": "0x6c6b935b8bbd400000" + }, + "467fbf41441600757fe15830c8cd5f4ffbbbd560": { + "balance": "0x21e19e0c9bab2400000" + }, + "469358709332c82b887e20bcddd0220f8edba7d0": { + "balance": "0x3a9d5baa4abf1d00000" + }, + "4697baaf9ccb603fd30430689d435445e9c98bf5": { + "balance": "0xad201a6794ff80000" + }, + "46a30b8a808931217445c3f5a93e882c0345b426": { + "balance": "0xd8db5ebd7b2638000" + }, + "46a430a2d4a894a0d8aa3feac615361415c3f81f": { + "balance": "0x6c6b935b8bbd400000" + }, + "46aa501870677e7f0a504876b4e8801a0ad01c46": { + "balance": "0x2b5e3af16b18800000" + }, + "46bfc5b207eb2013e2e60f775fecd71810c5990c": { + "balance": "0x54069233bf7f780000" + }, + "46c1aa2244b9c8a957ca8fac431b0595a3b86824": { + "balance": "0xd8d726b7177a800000" + }, + "46d80631284203f6288ecd4e5758bb9d41d05dbe": { + "balance": "0x6c6b935b8bbd400000" + }, + "470ac5d1f3efe28f3802af925b571e63868b397d": { + "balance": "0x6c6b935b8bbd400000" + }, + "471010da492f4018833b088d9872901e06129174": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "4712540265cbeec3847022c59f1b318d43400a9e": { + "balance": "0xbdbc41e0348b300000" + }, + "4714cfa4f46bd6bd70737d75878197e08f88e631": { + "balance": "0x27f3edfb34e6e400000" + }, + "472048cc609aeb242165eaaa8705850cf3125de0": { + "balance": "0x3635c9adc5dea00000" + }, + "47219229e8cd56659a65c2a943e2dd9a8f4bfd89": { + "balance": "0x52663ccab1e1c00000" + }, + "4737d042dc6ae73ec73ae2517acea2fdd96487c5": { + "balance": "0x3635c9adc5dea00000" + }, + "474158a1a9dc693c133f65e47b5c3ae2f773a86f": { + "balance": "0xada55474b81340000" + }, + "4745ab181a36aa8cbf2289d0c45165bc7ebe2381": { + "balance": "0x222c8eb3ff6640000" + }, + "475066f9ad26655196d5535327bbeb9b7929cb04": { + "balance": "0xa4cc799563c3800000" + }, + "4752218e54de423f86c0501933917aea08c8fed5": { + "balance": "0x43c33c1937564800000" + }, + "475a6193572d4a4e59d7be09cb960ddd8c530e2f": { + "balance": "0x242cf78cdf07ff8000" + }, + "47648bed01f3cd3249084e635d14daa9e7ec3c8a": { + "balance": "0xa844a7424d9c80000" + }, + "47688410ff25d654d72eb2bc06e4ad24f833b094": { + "balance": "0x8b28d61f3d3ac0000" + }, + "476b5599089a3fb6f29c6c72e49b2e4740ea808d": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "47730f5f8ebf89ac72ef80e46c12195038ecdc49": { + "balance": "0xab4dcf399a3a600000" + }, + "477b24eee8839e4fd19d1250bd0b6645794a61ca": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "4781a10a4df5eebc82f4cfe107ba1d8a7640bd66": { + "balance": "0x61093d7c2c6d380000" + }, + "47885ababedf4d928e1c3c71d7ca40d563ed595f": { + "balance": "0x62a992e53a0af00000" + }, + "478dc09a1311377c093f9cc8ae74111f65f82f39": { + "balance": "0xd8d726b7177a800000" + }, + "478e524ef2a381d70c82588a93ca7a5fa9d51cbf": { + "balance": "0x35fa97226f8899700000" + }, + "479298a9de147e63a1c7d6d2fce089c7e64083bd": { + "balance": "0x21e19dd3c3c0d798000" + }, + "479abf2da4d58716fd973a0d13a75f530150260a": { + "balance": "0x1158e460913d00000" + }, + "47a281dff64167197855bf6e705eb9f2cef632ea": { + "balance": "0x3636c9796436740000" + }, + "47beb20f759100542aa93d41118b3211d664920e": { + "balance": "0x6c6b935b8bbd400000" + }, + "47c247f53b9fbeb17bba0703a00c009fdb0f6eae": { + "balance": "0x43c33c1937564800000" + }, + "47c7e5efb48b3aed4b7c6e824b435f357df4c723": { + "balance": "0xfc936392801c0000" + }, + "47cf9cdaf92fc999cc5efbb7203c61e4f1cdd4c3": { + "balance": "0x71f8a93d01e540000" + }, + "47d20e6ae4cad3f829eac07e5ac97b66fdd56cf5": { + "balance": "0x3635c9adc5dea00000" + }, + "47d792a756779aedf1343e8883a6619c6c281184": { + "balance": "0x6c6b935b8bbd400000" + }, + "47e25df8822538a8596b28c637896b4d143c351d": { + "balance": "0x110be9eb24b881500000" + }, + "47f4696bd462b20da09fb83ed2039818d77625b3": { + "balance": "0x813ca56906d340000" + }, + "47fef58584465248a0810d60463ee93e5a6ee8d3": { + "balance": "0xf58cd3e1269160000" + }, + "47ff6feb43212060bb1503d7a397fc08f4e70352": { + "balance": "0x6c6b935b8bbd400000" + }, + "47fff42c678551d141eb75a6ee398117df3e4a8d": { + "balance": "0x56beae51fd2d10000" + }, + "48010ef3b8e95e3f308f30a8cb7f4eb4bf60d965": { + "balance": "0x6c6b935b8bbd400000" + }, + "480af52076009ca73781b70e43b95916a62203ab": { + "balance": "0x321972f4083d878000" + }, + "480f31b989311e4124c6a7465f5a44094d36f9d0": { + "balance": "0x3790bb855137640000" + }, + "481115296ab7db52492ff7b647d63329fb5cbc6b": { + "balance": "0x368c8623a8b4d100000" + }, + "481e3a91bfdc2f1c8428a0119d03a41601417e1c": { + "balance": "0x3635c9adc5dea00000" + }, + "4828e4cbe34e1510afb72c2beeac8a4513eaebd9": { + "balance": "0xd5967be4fc3f100000" + }, + "482982ac1f1c6d1721feecd9b9c96cd949805055": { + "balance": "0x21e19e0c9bab2400000" + }, + "48302c311ef8e5dc664158dd583c81194d6e0d58": { + "balance": "0xb6676ce0bccb5c0000" + }, + "483ba99034e900e3aedf61499d3b2bce39beb7aa": { + "balance": "0x35659ef93f0fc40000" + }, + "48548b4ba62bcb2f0d34a88dc69a680e539cf046": { + "balance": "0x56cf1cbbb74320000" + }, + "4863849739265a63b0a2bf236a5913e6f959ce15": { + "balance": "0x52663ccab1e1c00000" + }, + "48659d8f8c9a2fd44f68daa55d23a608fbe500dc": { + "balance": "0x6c6b935b8bbd400000" + }, + "48669eb5a801d8b75fb6aa58c3451b7058c243bf": { + "balance": "0x68d42c138dab9f00000" + }, + "486a6c8583a84484e3df43a123837f8c7e2317d0": { + "balance": "0x1187c571ab80450000" + }, + "487adf7d70a6740f8d51cbdd68bb3f91c4a5ce68": { + "balance": "0x39fbae8d042dd0000" + }, + "487e108502b0b189ef9c8c6da4d0db6261eec6c0": { + "balance": "0x678a932062e4180000" + }, + "4888fb25cd50dbb9e048f41ca47d78b78a27c7d9": { + "balance": "0x3a9d5baa4abf1d00000" + }, + "489334c2b695c8ee0794bd864217fb9fd8f8b135": { + "balance": "0xfc936392801c0000" + }, + "48a30de1c919d3fd3180e97d5f2b2a9dbd964d2d": { + "balance": "0x2629f66e0c5300000" + }, + "48bf14d7b1fc84ebf3c96be12f7bce01aa69b03e": { + "balance": "0x68155a43676e00000" + }, + "48c2ee91a50756d8ce9abeeb7589d22c6fee5dfb": { + "balance": "0xae8e7a0bb575d00000" + }, + "48c5c6970b9161bb1c7b7adfed9cdede8a1ba864": { + "balance": "0xd8d726b7177a800000" + }, + "48d2434b7a7dbbff08223b6387b05da2e5093126": { + "balance": "0x3cfc82e37e9a7400000" + }, + "48d4f2468f963fd79a006198bb67895d2d5aa4d3": { + "balance": "0x4be4e7267b6ae00000" + }, + "48e0cbd67f18acdb7a6291e1254db32e0972737f": { + "balance": "0x56be03ca3e47d8000" + }, + "48f60a35484fe7792bcc8a7b6393d0dda1f6b717": { + "balance": "0xc328093e61ee400000" + }, + "48f883e567b436a27bb5a3124dbc84dec775a800": { + "balance": "0x29d76e869dcd800000" + }, + "490145afa8b54522bb21f352f06da5a788fa8f1d": { + "balance": "0x1f46c62901a03fb0000" + }, + "4909b31998ead414b8fb0e846bd5cbde393935be": { + "balance": "0xd8d726b7177a800000" + }, + "4912d902931676ff39fc34fe3c3cc8fb2182fa7a": { + "balance": "0x1158e460913d00000" + }, + "49136fe6e28b7453fcb16b6bbbe9aaacba8337fd": { + "balance": "0x6c6b935b8bbd400000" + }, + "491561db8b6fafb9007e62d050c282e92c4b6bc8": { + "balance": "0x65a4da25d3016c00000" + }, + "49185dd7c23632f46c759473ebae966008cd3598": { + "balance": "0xdc55fdb17647b0000" + }, + "492cb5f861b187f9df21cd4485bed90b50ffe22d": { + "balance": "0x1b19e50b44977c0000" + }, + "492de46aaf8f1d708d59d79af1d03ad2cb60902f": { + "balance": "0x6c6b935b8bbd400000" + }, + "492e70f04d18408cb41e25603730506b35a2876b": { + "balance": "0x222c8eb3ff6640000" + }, + "493a67fe23decc63b10dda75f3287695a81bd5ab": { + "balance": "0x2fb474098f67c00000" + }, + "493d48bda015a9bfcf1603936eab68024ce551e0": { + "balance": "0x138a388a43c000000" + }, + "494256e99b0f9cd6e5ebca3899863252900165c8": { + "balance": "0x2f6f10780d22cc00000" + }, + "494dec4d5ee88a2771a815f1ee7264942fb58b28": { + "balance": "0x6c6b935b8bbd400000" + }, + "495b641b1cdea362c3b4cbbd0f5cc50b1e176b9c": { + "balance": "0x3635c9adc5dea00000" + }, + "4968a2cedb457555a139295aea28776e54003c87": { + "balance": "0x2231aefc9a6628f0000" + }, + "496d365534530a5fc1577c0a5241cb88c4da7072": { + "balance": "0x61093d7c2c6d380000" + }, + "496e319592b341eaccd778dda7c8196d54cac775": { + "balance": "0x1f5718987664b480000" + }, + "496f5843f6d24cd98d255e4c23d1e1f023227545": { + "balance": "0x5f179fd4a6ee098000" + }, + "4970d3acf72b5b1f32a7003cf102c64ee0547941": { + "balance": "0x1da56a4b0835bf800000" + }, + "4977a7939d0939689455ce2639d0ee5a4cd910ed": { + "balance": "0x62a992e53a0af00000" + }, + "4979194ec9e97db9bee8343b7c77d9d7f3f1dc9f": { + "balance": "0x1158e460913d00000" + }, + "49793463e1681083d6abd6e725d5bba745dccde8": { + "balance": "0x1d98e94c4e471f0000" + }, + "4981c5ff66cc4e9680251fc4cd2ff907cb327865": { + "balance": "0x28a857425466f80000" + }, + "49897fe932bbb3154c95d3bce6d93b6d732904dd": { + "balance": "0xd8d726b7177a800000" + }, + "4989e1ab5e7cd00746b3938ef0f0d064a2025ba5": { + "balance": "0x6c6b935b8bbd400000" + }, + "498abdeb14c26b7b7234d70fceaef361a76dff72": { + "balance": "0xa2a15d09519be00000" + }, + "49a645e0667dfd7b32d075cc2467dd8c680907c4": { + "balance": "0x70601958fcb9c0000" + }, + "49b74e169265f01a89ec4c9072c5a4cd72e4e835": { + "balance": "0x368c8623a8b4d100000" + }, + "49bdbc7ba5abebb6389e91a3285220d3451bd253": { + "balance": "0x3635c9adc5dea00000" + }, + "49c941e0e5018726b7290fc473b471d41dae80d1": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "49c9771fca19d5b9d245c891f8158fe49f47a062": { + "balance": "0x21e19e0c9bab2400000" + }, + "49cf1e54be363106b920729d2d0ba46f0867989a": { + "balance": "0xe873f44133cb00000" + }, + "49d2c28ee9bc545eaaf7fd14c27c4073b4bb5f1a": { + "balance": "0x4fe9b806b40daf0000" + }, + "49ddee902e1d0c99d1b11af3cc8a96f78e4dcf1a": { + "balance": "0xacea5e4c18c530000" + }, + "49f028395b5a86c9e07f7778630e4c2e3d373a77": { + "balance": "0x6a74a5038db918000" + }, + "4a192035e2619b24b0709d56590e9183ccf2c1d9": { + "balance": "0x21e19e0c9bab2400000" + }, + "4a4053b31d0ee5dbafb1d06bd7ac7ff3222c47d6": { + "balance": "0x4be4e7267b6ae00000" + }, + "4a430170152de5172633dd8262d107a0afd96a0f": { + "balance": "0xab4dcf399a3a600000" + }, + "4a47fc3e177f567a1e3893e000e36bba23520ab8": { + "balance": "0x6c6b935b8bbd400000" + }, + "4a52bad20357228faa1e996bed790c93674ba7d0": { + "balance": "0x487a9a304539440000" + }, + "4a53dcdb56ce4cdce9f82ec0eb13d67352e7c88b": { + "balance": "0xe3aeb5737240a00000" + }, + "4a5fae3b0372c230c125d6d470140337ab915656": { + "balance": "0x56bc75e2d631000000" + }, + "4a719061f5285495b37b9d7ef8a51b07d6e6acac": { + "balance": "0xad4c8316a0b0c0000" + }, + "4a73389298031b8816cca946421c199e18b343d6": { + "balance": "0x223868b879146f0000" + }, + "4a735d224792376d331367c093d31c8794341582": { + "balance": "0x66ffcbfd5e5a300000" + }, + "4a7494cce44855cc80582842be958a0d1c0072ee": { + "balance": "0x821ab0d44149800000" + }, + "4a75c3d4fa6fccbd5dd5a703c15379a1e783e9b7": { + "balance": "0x62a992e53a0af00000" + }, + "4a81abe4984c7c6bef63d69820e55743c61f201c": { + "balance": "0x36401004e9aa3470000" + }, + "4a82694fa29d9e213202a1a209285df6e745c209": { + "balance": "0xd8d726b7177a800000" + }, + "4a835c25824c47ecbfc79439bf3f5c3481aa75cd": { + "balance": "0x4be4e7267b6ae00000" + }, + "4a918032439159bb315b6725b6830dc83697739f": { + "balance": "0x12a32ef678334c0000" + }, + "4a97e8fcf4635ea7fc5e96ee51752ec388716b60": { + "balance": "0x1d9945ab2b03480000" + }, + "4a9a26fd0a8ba10f977da4f77c31908dab4a8016": { + "balance": "0x61093d7c2c6d380000" + }, + "4aa148c2c33401e66a2b586e6577c4b292d3f240": { + "balance": "0xbb860b285f7740000" + }, + "4aa693b122f314482a47b11cc77c68a497876162": { + "balance": "0x6acb3df27e1f880000" + }, + "4ab2d34f04834fbf7479649cab923d2c4725c553": { + "balance": "0xbed1d0263d9f000000" + }, + "4ac07673e42f64c1a25ec2fa2d86e5aa2b34e039": { + "balance": "0x6c6b935b8bbd400000" + }, + "4ac5acad000b8877214cb1ae00eac9a37d59a0fd": { + "balance": "0xd8d726b7177a800000" + }, + "4ac9905a4cb6ab1cfd62546ee5917300b87c4fde": { + "balance": "0x3708baed3d68900000" + }, + "4acfa9d94eda6625c9dfa5f9f4f5d107c4031fdf": { + "balance": "0x222c8eb3ff6640000" + }, + "4ad047fae67ef162fe68fedbc27d3b65caf10c36": { + "balance": "0x6acb3df27e1f880000" + }, + "4ad95d188d6464709add2555fb4d97fe1ebf311f": { + "balance": "0x12c1b6eed03d280000" + }, + "4adbf4aae0e3ef44f7dd4d8985cfaf096ec48e98": { + "balance": "0x821ab0d4414980000" + }, + "4ae2a04d3909ef454e544ccfd614bfefa71089ae": { + "balance": "0x1801159df1eef80000" + }, + "4ae93082e45187c26160e66792f57fad3551c73a": { + "balance": "0x4961520daff82280000" + }, + "4af0db077bb9ba5e443e21e148e59f379105c592": { + "balance": "0x2086ac351052600000" + }, + "4b0619d9d8aa313a9531ac7dbe04ca0d6a5ad1b6": { + "balance": "0x6c6b935b8bbd400000" + }, + "4b0bd8acfcbc53a6010b40d4d08ddd2d9d69622d": { + "balance": "0x243d4d18229ca20000" + }, + "4b19eb0c354bc1393960eb06063b83926f0d67b2": { + "balance": "0x19274b259f6540000" + }, + "4b29437c97b4a844be71cca3b648d4ca0fdd9ba4": { + "balance": "0x824719834cfac0000" + }, + "4b31bf41abc75c9ae2cd8f7f35163b6e2b745054": { + "balance": "0x14b550a013c7380000" + }, + "4b3a7cc3a7d7b00ed5282221a60259f25bf6538a": { + "balance": "0x3635c9adc5dea00000" + }, + "4b3aab335ebbfaa870cc4d605e7d2e74c668369f": { + "balance": "0xcb49b44ba602d800000" + }, + "4b3c7388cc76da3d62d40067dabccd7ef0433d23": { + "balance": "0x56cd55fc64dfe0000" + }, + "4b3dfbdb454be5279a3b8addfd0ed1cd37a9420d": { + "balance": "0x6c6b935b8bbd400000" + }, + "4b470f7ba030bc7cfcf338d4bf0432a91e2ea5ff": { + "balance": "0x6c6b935b8bbd400000" + }, + "4b53ae59c784b6b5c43616b9a0809558e684e10c": { + "balance": "0x410d586a20a4c00000" + }, + "4b58101f44f7e389e12d471d1635b71614fdd605": { + "balance": "0x8ac7230489e800000" + }, + "4b5cdb1e428c91dd7cb54a6aed4571da054bfe52": { + "balance": "0x4c53ecdc18a600000" + }, + "4b60a3e253bf38c8d5662010bb93a473c965c3e5": { + "balance": "0x50c5e761a444080000" + }, + "4b74f5e58e2edf76daf70151964a0b8f1de0663c": { + "balance": "0x1190ae4944ba120000" + }, + "4b762166dd1118e84369f804c75f9cd657bf730c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "4b792e29683eb586e394bb33526c6001b397999e": { + "balance": "0x2086ac351052600000" + }, + "4b904e934bd0cc8b20705f879e905b93ea0ccc30": { + "balance": "0x6c6b935b8bbd400000" + }, + "4b9206ba6b549a1a7f969e1d5dba867539d1fa67": { + "balance": "0x1ab2cf7c9f87e200000" + }, + "4b984ef26c576e815a2eaed2f5177f07dbb1c476": { + "balance": "0x54915956c409600000" + }, + "4b9e068fc4680976e61504912985fd5ce94bab0d": { + "balance": "0x243d4d18229ca20000" + }, + "4ba0d9e89601772b496847a2bb4340186787d265": { + "balance": "0x3635c9adc5dea00000" + }, + "4ba53ab549e2016dfa223c9ed5a38fad91288d07": { + "balance": "0x4be4e7267b6ae00000" + }, + "4ba8e0117fc0b6a3e56b24a3a58fe6cef442ff98": { + "balance": "0x131beb925ffd3200000" + }, + "4bac846af4169f1d95431b341d8800b22180af1a": { + "balance": "0x1158e460913d00000" + }, + "4bb6d86b8314c22d8d37ea516d0019f156aae12d": { + "balance": "0x3635c9adc5dea00000" + }, + "4bb9655cfb2a36ea7c637a7b859b4a3154e26ebe": { + "balance": "0x3635c9adc5dea000000" + }, + "4bbcbf38b3c90163a84b1cd2a93b58b2a3348d87": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "4bd6dd0cff23400e1730ba7b894504577d14e74a": { + "balance": "0x2ba0ccddd0df73b00000" + }, + "4be8628a8154874e048d80c142181022b180bcc1": { + "balance": "0x340aad21b3b700000" + }, + "4be90d412129d5a4d0424361d6649d4e47a62316": { + "balance": "0x3708baed3d68900000" + }, + "4bea288eea42c4955eb9faad2a9faf4783cbddac": { + "balance": "0x618be1663c4af490000" + }, + "4bf4479799ef82eea20943374f56a1bf54001e5e": { + "balance": "0xd5967be4fc3f100000" + }, + "4bf8bf1d35a231315764fc8001809a949294fc49": { + "balance": "0x39fbae8d042dd0000" + }, + "4bf8e26f4c2790da6533a2ac9abac3c69a199433": { + "balance": "0xad78ebc5ac6200000" + }, + "4c0aca508b3caf5ee028bc707dd1e800b838f453": { + "balance": "0xfc936392801c0000" + }, + "4c0b1515dfced7a13e13ee12c0f523ae504f032b": { + "balance": "0xa968163f0a57b400000" + }, + "4c13980c32dcf3920b78a4a7903312907c1b123f": { + "balance": "0x3410015faae0c0000" + }, + "4c1579af3312e4f88ae93c68e9449c2e9a68d9c4": { + "balance": "0x6c6b935b8bbd400000" + }, + "4c23b370fc992bb67cec06e26715b62f0b3a4ac3": { + "balance": "0x21e19e0c9bab2400000" + }, + "4c24b78baf2bafc7fcc69016426be973e20a50b2": { + "balance": "0xa2a15d09519be00000" + }, + "4c2f1afef7c5868c44832fc77cb03b55f89e6d6e": { + "balance": "0x43c33c1937564800000" + }, + "4c377bb03ab52c4cb79befa1dd114982924c4ae9": { + "balance": "0x631603ccd38dd70000" + }, + "4c3e95cc3957d252ce0bf0c87d5b4f2234672e70": { + "balance": "0x878678326eac900000" + }, + "4c423c76930d07f93c47a5cc4f615745c45a9d72": { + "balance": "0x56bc75e2d63100000" + }, + "4c45d4c9a725d11112bfcbca00bf31186ccaadb7": { + "balance": "0x15af1d78b58c400000" + }, + "4c4e6f13fb5e3f70c3760262a03e317982691d10": { + "balance": "0x56bc75e2d63100000" + }, + "4c5afe40f18ffc48d3a1aec41fc29de179f4d297": { + "balance": "0x6c6b935b8bbd400000" + }, + "4c5b3dc0e2b9360f91289b1fe13ce12c0fbda3e1": { + "balance": "0x6c6b935b8bbd400000" + }, + "4c666b86f1c5ee8ca41285f5bde4f79052081406": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "4c696be99f3a690440c3436a59a7d7e937d6ba0d": { + "balance": "0xbb9125542263900000" + }, + "4c6a248fc97d705def495ca20759169ef0d36471": { + "balance": "0x29331e6558f0e00000" + }, + "4c6a9dc2cab10abb2e7c137006f08fecb5b779e1": { + "balance": "0x1b0d04202f47ec0000" + }, + "4c6b93a3bec16349540cbfcae96c9621d6645010": { + "balance": "0x6c6b935b8bbd400000" + }, + "4c759813ad1386bed27ffae9e4815e3630cca312": { + "balance": "0x6c6b935b8bbd400000" + }, + "4c760cd9e195ee4f2d6bce2500ff96da7c43ee91": { + "balance": "0xcb49b44ba602d800000" + }, + "4c767b65fd91161f4fbdcc6a69e2f6ad711bb918": { + "balance": "0x270801d946c9400000" + }, + "4c7e2e2b77ad0cd6f44acb2861f0fb8b28750ef9": { + "balance": "0x1158e460913d00000" + }, + "4c85ed362f24f6b9f04cdfccd022ae535147cbb9": { + "balance": "0x5150ae84a8cdf00000" + }, + "4c935bb250778b3c4c7f7e07fc251fa630314aab": { + "balance": "0x5150ae84a8cdf00000" + }, + "4c997992036c5b433ac33d25a8ea1dc3d4e4e6d8": { + "balance": "0x1953b3d4ab1680000" + }, + "4c99dae96481e807c1f99f8b7fbde29b7547c5bf": { + "balance": "0x821ab0d4414980000" + }, + "4c9a862ad115d6c8274ed0b944bdd6a5500510a7": { + "balance": "0x56bc75e2d63100000" + }, + "4ca783b556e5bf53aa13c8116613d65782c9b642": { + "balance": "0x5561840b4ad83c00000" + }, + "4ca7b717d9bc8793b04e051a8d23e1640f5ba5e3": { + "balance": "0x43b514549ecf620000" + }, + "4ca8db4a5efefc80f4cd9bbcccb03265931332b6": { + "balance": "0xad78ebc5ac6200000" + }, + "4cac91fb83a147d2f76c3267984b910a79933348": { + "balance": "0x75792a8abdef7c0000" + }, + "4cadf573ce4ceec78b8e1b21b0ed78eb113b2c0e": { + "balance": "0x6c6b935b8bbd400000" + }, + "4cb5c6cd713ca447b848ae2f56b761ca14d7ad57": { + "balance": "0xe7eeba3410b740000" + }, + "4cc22c9bc9ad05d875a397dbe847ed221c920c67": { + "balance": "0x6c6b935b8bbd400000" + }, + "4cd0b0a6436362595ceade052ebc9b929fb6c6c0": { + "balance": "0x6c6b935b8bbd400000" + }, + "4cda41dd533991290794e22ae324143e309b3d3d": { + "balance": "0x821ab0d44149800000" + }, + "4cee901b4ac8b156c5e2f8a6f1bef572a7dceb7e": { + "balance": "0x3635c9adc5dea00000" + }, + "4cefbe2398e47d52e78db4334c8b697675f193ae": { + "balance": "0xd96fce90cfabcc0000" + }, + "4cf5537b85842f89cfee359eae500fc449d2118f": { + "balance": "0x3635c9adc5dea00000" + }, + "4d08471d68007aff2ae279bc5e3fe4156fbbe3de": { + "balance": "0x878678326eac9000000" + }, + "4d200110124008d56f76981256420c946a6ff45c": { + "balance": "0xad6eedd17cf3b8000" + }, + "4d24b7ac47d2f27de90974ba3de5ead203544bcd": { + "balance": "0x56bc75e2d63100000" + }, + "4d29fc523a2c1629532121da9998e9b5ab9d1b45": { + "balance": "0xdb44e049bb2c0000" + }, + "4d38d90f83f4515c03cc78326a154d358bd882b7": { + "balance": "0xa076407d3f7440000" + }, + "4d4cf5807429615e30cdface1e5aae4dad3055e6": { + "balance": "0x2086ac351052600000" + }, + "4d57e716876c0c95ef5eaebd35c8f41b069b6bfe": { + "balance": "0x6c6b935b8bbd400000" + }, + "4d67f2ab8599fef5fc413999aa01fd7fce70b43d": { + "balance": "0x21e19e0c9bab2400000" + }, + "4d6e8fe109ccd2158e4db114132fe75fecc8be5b": { + "balance": "0x15b3557f1937f8000" + }, + "4d71a6eb3d7f327e1834278e280b039eddd31c2f": { + "balance": "0x14542ba12a337c00000" + }, + "4d7cfaa84cb33106800a8c802fb8aa463896c599": { + "balance": "0x61093d7c2c6d380000" + }, + "4d801093c19ca9b8f342e33cc9c77bbd4c8312cf": { + "balance": "0x12b3e7fb95cda48000" + }, + "4d828894752f6f25175daf2177094487954b6f9f": { + "balance": "0x4f212bc2c49c838000" + }, + "4d82d7700c123bb919419bbaf046799c6b0e2c66": { + "balance": "0x43c33c1937564800000" + }, + "4d836d9d3b0e2cbd4de050596faa490cffb60d5d": { + "balance": "0x1043561a8829300000" + }, + "4d8697af0fbf2ca36e8768f4af22133570685a60": { + "balance": "0x1158e460913d00000" + }, + "4d9279962029a8bd45639737e98b511eff074c21": { + "balance": "0x487a9a304539440000" + }, + "4d93696fa24859f5d2939aebfa54b4b51ae1dccc": { + "balance": "0x10910d4cdc9f60000" + }, + "4d9c77d0750c5e6fbc247f2fd79274686cb353d6": { + "balance": "0x1158e460913d00000" + }, + "4da5edc688b0cb62e1403d1700d9dcb99ffe3fd3": { + "balance": "0x6c6b935b8bbd400000" + }, + "4da8030769844bc34186b85cd4c7348849ff49e9": { + "balance": "0x21e19e0c9bab2400000" + }, + "4db1c43a0f834d7d0478b8960767ec1ac44c9aeb": { + "balance": "0x2f5181305627370000" + }, + "4db21284bcd4f787a7556500d6d7d8f36623cf35": { + "balance": "0x6928374f77a3630000" + }, + "4dc3da13b2b4afd44f5d0d3189f444d4ddf91b1b": { + "balance": "0x6c6b935b8bbd400000" + }, + "4dc4bf5e7589c47b28378d7503cf96488061dbbd": { + "balance": "0x5f68e8131ecf800000" + }, + "4dc9d5bb4b19cecd94f19ec25d200ea72f25d7ed": { + "balance": "0x6c6b935b8bbd400000" + }, + "4dcd11815818ae29b85d01367349a8a7fb12d06b": { + "balance": "0x1ac4286100191f00000" + }, + "4dcf62a3de3f061db91498fd61060f1f6398ff73": { + "balance": "0x6c6acc67d7b1d40000" + }, + "4dd131c74a068a37c90aded4f309c2409f6478d3": { + "balance": "0x15af39e4aab2740000" + }, + "4ddda7586b2237b053a7f3289cf460dc57d37a09": { + "balance": "0x21e19e0c9bab2400000" + }, + "4de3fe34a6fbf634c051997f47cc7f48791f5824": { + "balance": "0x6c5db2a4d815dc0000" + }, + "4df140ba796585dd5489315bca4bba680adbb818": { + "balance": "0x90f534608a72880000" + }, + "4e020779b5ddd3df228a00cb48c2fc979da6ae38": { + "balance": "0x6c6b935b8bbd400000" + }, + "4e0bd32473c4c51bf25654def69f797c6b29a232": { + "balance": "0x56c95de8e8ca1d0000" + }, + "4e2225a1bb59bc88a2316674d333b9b0afca6655": { + "balance": "0x8670e9ec6598c0000" + }, + "4e2310191ead8d3bc6489873a5f0c2ec6b87e1be": { + "balance": "0x3635c9adc5dea00000" + }, + "4e232d53b3e6be8f895361d31c34d4762b12c82e": { + "balance": "0x5f68e8131ecf800000" + }, + "4e2bfa4a466f82671b800eee426ad00c071ba170": { + "balance": "0xd8d726b7177a800000" + }, + "4e3edad4864dab64cae4c5417a76774053dc6432": { + "balance": "0x2008fb478cbfa98000" + }, + "4e4318f5e13e824a54edfe30a7ed4f26cd3da504": { + "balance": "0x6c6b935b8bbd400000" + }, + "4e5b77f9066159e615933f2dda7477fa4e47d648": { + "balance": "0xad78ebc5ac6200000" + }, + "4e6600806289454acda330a2a3556010dfacade6": { + "balance": "0x14542ba12a337c00000" + }, + "4e73cf2379f124860f73d6d91bf59acc5cfc845b": { + "balance": "0x22ca3587cf4eb0000" + }, + "4e7aa67e12183ef9d7468ea28ad239c2eef71b76": { + "balance": "0x10afc1ade3b4ed40000" + }, + "4e7b54474d01fefd388dfcd53b9f662624418a05": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "4e892e8081bf36e488fddb3b2630f3f1e8da30d2": { + "balance": "0x28aba30752451fc0000" + }, + "4e8a6d63489ccc10a57f885f96eb04ecbb546024": { + "balance": "0x3eae3130ecc96900000" + }, + "4e8e47ae3b1ef50c9d54a38e14208c1abd3603c2": { + "balance": "0x7928db1276660c0000" + }, + "4e90ccb13258acaa9f4febc0a34292f95991e230": { + "balance": "0xdb44e049bb2c0000" + }, + "4ea56e1112641c038d0565a9c296c463afefc17e": { + "balance": "0x9ddc1e3b901180000" + }, + "4ea70f04313fae65c3ff224a055c3d2dab28dddf": { + "balance": "0x43c30fb0884a96c0000" + }, + "4eb1454b573805c8aca37edec7149a41f61202f4": { + "balance": "0x1043561a8829300000" + }, + "4eb87ba8788eba0df87e5b9bd50a8e45368091c1": { + "balance": "0x1158e460913d00000" + }, + "4ebc5629f9a6a66b2cf3363ac4895c0348e8bf87": { + "balance": "0x3637096c4bcc690000" + }, + "4ec768295eeabafc42958415e22be216cde77618": { + "balance": "0x33b1dbc39c5480000" + }, + "4ecc19948dd9cd87b4c7201ab48e758f28e7cc76": { + "balance": "0x1b1dab61d3aa640000" + }, + "4ed14d81b60b23fb25054d8925dfa573dcae6168": { + "balance": "0x126e72a69a50d00000" + }, + "4ee13c0d41200b46d19dee5c4bcec71d82bb8e38": { + "balance": "0x1abee13ccbeefaf8000" + }, + "4eead40aad8c73ef08fc84bc0a92c9092f6a36bf": { + "balance": "0x1731790534df20000" + }, + "4eebe80cb6f3ae5904f6f4b28d907f907189fcab": { + "balance": "0x6c6acc67d7b1d40000" + }, + "4eebf1205d0cc20cee6c7f8ff3115f56d48fba26": { + "balance": "0x10d3aa536e2940000" + }, + "4ef1c214633ad9c0703b4e2374a2e33e3e429291": { + "balance": "0x487a9a304539440000" + }, + "4efcd9c79fb4334ca6247b0a33bd9cc33208e272": { + "balance": "0x487a9a304539440000" + }, + "4f06246b8d4bd29661f43e93762201d286935ab1": { + "balance": "0x105394ffc4636110000" + }, + "4f152b2fb8659d43776ebb1e81673aa84169be96": { + "balance": "0x6c6b935b8bbd400000" + }, + "4f177f9d56953ded71a5611f393322c30279895c": { + "balance": "0xd55ef90a2da180000" + }, + "4f1a2da54a4c6da19d142412e56e815741db2325": { + "balance": "0x56bc75e2d63100000" + }, + "4f23b6b817ffa5c664acdad79bb7b726d30af0f9": { + "balance": "0x5f68e8131ecf800000" + }, + "4f26690c992b7a312ab12e1385d94acd58288e7b": { + "balance": "0x2f6f10780d22cc00000" + }, + "4f2b47e2775a1fa7178dad92985a5bbe493ba6d6": { + "balance": "0xad78ebc5ac6200000" + }, + "4f3a4854911145ea01c644044bdb2e5a960a982f": { + "balance": "0xd8d726b7177a800000" + }, + "4f3f2c673069ac97c2023607152981f5cd6063a0": { + "balance": "0x2086ac351052600000" + }, + "4f4a9be10cd5d3fb5de48c17be296f895690645b": { + "balance": "0x878678326eac9000000" + }, + "4f52ad6170d25b2a2e850eadbb52413ff2303e7f": { + "balance": "0xa4cc799563c3800000" + }, + "4f5801b1eb30b712d8a0575a9a71ff965d4f34eb": { + "balance": "0x1043561a8829300000" + }, + "4f5df5b94357de948604c51b7893cddf6076baad": { + "balance": "0xcbd47b6eaa8cc00000" + }, + "4f64a85e8e9a40498c0c75fceb0337fb49083e5e": { + "balance": "0x3635c9adc5dea00000" + }, + "4f67396d2553f998785f704e07a639197dd1948d": { + "balance": "0x104472521ba7380000" + }, + "4f6d4737d7a940382487264886697cf7637f8015": { + "balance": "0x5a87e7d7f5f6580000" + }, + "4f7330096f79ed264ee0127f5d30d2f73c52b3d8": { + "balance": "0x1b1a7a420ba00d0000" + }, + "4f767bc8794aef9a0a38fea5c81f14694ff21a13": { + "balance": "0x1bc433f23f83140000" + }, + "4f85bc1fc5cbc9c001e8f1372e07505370d8c71f": { + "balance": "0x32f51edbaaa3300000" + }, + "4f88dfd01091a45a9e2676021e64286cd36b8d34": { + "balance": "0x3635c9adc5dea00000" + }, + "4f8972838f70c903c9b6c6c46162e99d6216d451": { + "balance": "0xf9e89a0f2c56c80000" + }, + "4f8ae80238e60008557075ab6afe0a7f2e74d729": { + "balance": "0x56bc75e2d63100000" + }, + "4f8e8d274fb22a3fd36a47fe72980471544b3434": { + "balance": "0xad78ebc5ac6200000" + }, + "4f9ce2af9b8c5e42c6808a3870ec576f313545d1": { + "balance": "0x21e19e0c9bab2400000" + }, + "4fa3f32ef4086448b344d5f0a9890d1ce4d617c3": { + "balance": "0x5150ae84a8cdf00000" + }, + "4fa554ab955c249217386a4d3263bbf72895434e": { + "balance": "0x1154e53217ddb0000" + }, + "4fa983bb5e3073a8edb557effeb4f9fb1d60ef86": { + "balance": "0x56b9af57e575ec0000" + }, + "4faf90b76ecfb9631bf9022176032d8b2c207009": { + "balance": "0x36363b5d9a77700000" + }, + "4fc46c396e674869ad9481638f0013630c87caac": { + "balance": "0x3635c9adc5dea00000" + }, + "4fcc19ea9f4c57dcbce893193cfb166aa914edc5": { + "balance": "0x17b8baa7f19546a0000" + }, + "4fce8429ba49caa0369d1e494db57e89eab2ad39": { + "balance": "0x2a5a058fc295ed000000" + }, + "4fdac1aa517007e0089430b3316a1badd12c01c7": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "4fe56ab3bae1b0a44433458333c4b05a248f8241": { + "balance": "0x762d93d1dd6f900000" + }, + "4feb846be43041fd6b34202897943e3f21cb7f04": { + "balance": "0x482fe260cbca90000" + }, + "4fee50c5f988206b09a573469fb1d0b42ebb6dce": { + "balance": "0x6cee06ddbe15ec0000" + }, + "4ff676e27f681a982d8fd9d20e648b3dce05e945": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "4ff67fb87f6efba9279930cfbd1b7a343c79fade": { + "balance": "0x15af1d78b58c400000" + }, + "5006fe4c22173980f00c74342b39cd231c653129": { + "balance": "0x6c6b935b8bbd400000" + }, + "500c16352e901d48ba8d04e2c767121772790b02": { + "balance": "0x1a3a6824973098000" + }, + "500c902958f6421594d1b6ded712490d52ed6c44": { + "balance": "0x6acb3df27e1f880000" + }, + "500e34cde5bd9e2b71bb92d7cf55eee188d5fa0c": { + "balance": "0x121ea68c114e5100000" + }, + "5032e4bcf7932b49fdba377b6f1499636513cfc3": { + "balance": "0x56bc75e2d63100000" + }, + "50378af7ef54043f892ab7ce97d647793511b108": { + "balance": "0x11164759ffb320000" + }, + "503bdbd8bc421c32a443032deb2e3e4cd5ba8b4e": { + "balance": "0x6c6b935b8bbd400000" + }, + "504666ce8931175e11a5ed11c1dcaa06e57f4e66": { + "balance": "0x27f3edfb34e6e400000" + }, + "50584d9206a46ce15c301117ee28f15c30e60e75": { + "balance": "0xb9f65d00f63c0000" + }, + "505a33a18634dd4800693c67f48a1d693d4833f8": { + "balance": "0x18921b79941dcd00000" + }, + "505e4f7c275588c533a20ebd2ac13b409bbdea3c": { + "balance": "0xf43fc2c04ee00000" + }, + "5062e5134c612f12694dbd0e131d4ce197d1b6a4": { + "balance": "0x3635c9adc5dea00000" + }, + "506411fd79003480f6f2b6aac26b7ba792f094b2": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5067f4549afbfe884c59cbc12b96934923d45db0": { + "balance": "0x3635c9adc5dea00000" + }, + "50763add868fd7361178342fc055eaa2b95f6846": { + "balance": "0x39f9046e0898f0000" + }, + "508cf19119db70aa86454253da764a2cb1b2be1a": { + "balance": "0x3635c9adc5dea00000" + }, + "509982f56237ee458951047e0a2230f804e2e895": { + "balance": "0x3b4ad496106b7f00000" + }, + "509a20bc48e72be1cdaf9569c711e8648d957334": { + "balance": "0x6c6b935b8bbd400000" + }, + "509c8668036d143fb8ae70b11995631f3dfcad87": { + "balance": "0x3635c9adc5dea00000" + }, + "50ad187ab21167c2b6e78be0153f44504a07945e": { + "balance": "0x56cd55fc64dfe0000" + }, + "50b9fef0a1329b02d16506255f5a2db71ec92d1f": { + "balance": "0x47da821564085c0000" + }, + "50bb67c8b8d8bd0f63c4760904f2d333f400aace": { + "balance": "0x6c6b935b8bbd400000" + }, + "50bef2756248f9a7a380f91b051ba3be28a649ed": { + "balance": "0x6c69f73e29134e0000" + }, + "50ca86b5eb1d01874df8e5f34945d49c6c1ab848": { + "balance": "0x3635c9adc5dea00000" + }, + "50cd97e9378b5cf18f173963236c9951ef7438a5": { + "balance": "0x4be4e7267b6ae00000" + }, + "50dcbc27bcad984093a212a9b4178eabe9017561": { + "balance": "0x7e362790b5ca40000" + }, + "50e13023bd9ca96ad4c53fdfd410cb6b1f420bdf": { + "balance": "0xad78ebc5ac6200000" + }, + "50e1c8ec98415bef442618708799437b86e6c205": { + "balance": "0x14542ba12a337c00000" + }, + "50f8fa4bb9e2677c990a4ee8ce70dd1523251e4f": { + "balance": "0x1693d23164f6b0000" + }, + "50fb36c27107ee2ca9a3236e2746cca19ace6b49": { + "balance": "0x6c6b935b8bbd400000" + }, + "50fef296955588caae74c62ec32a23a454e09ab8": { + "balance": "0x411dffabc507380000" + }, + "5102a4a42077e11c58df4773e3ac944623a66d9f": { + "balance": "0x6c7015fd52ed408000" + }, + "51039377eed0c573f986c5e8a95fb99a59e9330f": { + "balance": "0x6acb3df27e1f880000" + }, + "5103bc09933e9921fd53dc536f11f05d0d47107d": { + "balance": "0xd8d726b7177a800000" + }, + "5104ecc0e330dd1f81b58ac9dbb1a9fbf88a3c85": { + "balance": "0x152d02c7e14af6800000" + }, + "510d8159cc945768c7450790ba073ec0d9f89e30": { + "balance": "0x8ac7230489e8000000" + }, + "510eda5601499a0d5e1a006bfffd833672f2e267": { + "balance": "0x6c6b935b8bbd400000" + }, + "51126446ab3d8032557e8eba65597d75fadc815c": { + "balance": "0x1174a5cdf88bc80000" + }, + "5118557d600d05c2fcbf3806ffbd93d02025d730": { + "balance": "0x267d3ab6423f5800000" + }, + "511e0efb04ac4e3ff2e6550e498295bfcd56ffd5": { + "balance": "0x243d4d18229ca20000" + }, + "512116817ba9aaf843d1507c65a5ea640a7b9eec": { + "balance": "0x2b5e3af16b1880000" + }, + "5126460d692c71c9af6f05574d93998368a23799": { + "balance": "0x2d1a51c7e00500000" + }, + "51277fe7c81eebd252a03df69a6b9f326e272207": { + "balance": "0x3402e79cab44c8000" + }, + "51296f5044270d17707646129c86aad1645eadc1": { + "balance": "0x487c72b310d4648000" + }, + "512b91bbfaa9e581ef683fc90d9db22a8f49f48b": { + "balance": "0x41a522386d9b95c00000" + }, + "5135fb8757600cf474546252f74dc0746d06262c": { + "balance": "0x6c6b935b8bbd400000" + }, + "514632efbd642c04de6ca342315d40dd90a2dba6": { + "balance": "0x90f534608a72880000" + }, + "514b7512c9ae5ea63cbf11715b63f21e18d296c1": { + "balance": "0x6c6acc67d7b1d40000" + }, + "5153a0c3c8912881bf1c3501bf64b45649e48222": { + "balance": "0xd8d726b7177a800000" + }, + "515651d6db4faf9ecd103a921bbbbe6ae970fdd4": { + "balance": "0x43c33c1937564800000" + }, + "515f30bc90cdf4577ee47d65d785fbe2e837c6bc": { + "balance": "0x2271b5e018ba0580000" + }, + "5160ed612e1b48e73f3fc15bc4321b8f23b8a24b": { + "balance": "0x1e826b422865d80000" + }, + "5161fd49e847f67455f1c8bb7abb36e985260d03": { + "balance": "0x410d586a20a4c00000" + }, + "516954025fca2608f47da81c215eedfd844a09ff": { + "balance": "0x14b550a013c7380000" + }, + "5169c60aee4ceed1849ab36d664cff97061e8ea8": { + "balance": "0xa2a15d09519be00000" + }, + "517c75430de401c341032686112790f46d4d369e": { + "balance": "0x150894e849b3900000" + }, + "517cd7608e5d0d83a26b717f3603dac2277dc3a4": { + "balance": "0x6c6b935b8bbd400000" + }, + "51865db148881951f51251710e82b9be0d7eadb2": { + "balance": "0x6c6b935b8bbd400000" + }, + "51891b2ccdd2f5a44b2a8bc49a5d9bca6477251c": { + "balance": "0x10ce1d3d8cb3180000" + }, + "518cef27b10582b6d14f69483ddaa0dd3c87bb5c": { + "balance": "0x2086ac351052600000" + }, + "51a6d627f66a8923d88d6094c4715380d3057cb6": { + "balance": "0x3e73d27a35941e0000" + }, + "51a8c2163602a32ee24cf4aa97fd9ea414516941": { + "balance": "0x368f7e6b8672c0000" + }, + "51b4758e9e1450e7af4268c3c7b1e7bd6f5c7550": { + "balance": "0x3635c9adc5dea00000" + }, + "51ca8bd4dc644fac47af675563d5804a0da21eeb": { + "balance": "0x2ab7b260ff3fd00000" + }, + "51d24bc3736f88dd63b7222026886630b6eb878d": { + "balance": "0x6c6b935b8bbd400000" + }, + "51d78b178d707e396e8710965c4f41b1a1d9179d": { + "balance": "0x5fee222041e340000" + }, + "51e32f14f4ca5e287cdac057a7795ea9e0439953": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "51e43fe0d25c782860af81ea89dd793c13f0cbb1": { + "balance": "0x340aad21b3b700000" + }, + "51e7b55c2f9820eed73884361b5066a59b6f45c6": { + "balance": "0x6c6b935b8bbd400000" + }, + "51ea1c0934e3d04022ed9c95a087a150ef705e81": { + "balance": "0x1547081e7224d200000" + }, + "51ee0cca3bcb10cd3e983722ced8493d926c0866": { + "balance": "0x36356633ebd8ea0000" + }, + "51f4663ab44ff79345f427a0f6f8a6c8a53ff234": { + "balance": "0x43c33c1937564800000" + }, + "51f55ef47e6456a418ab32b9221ed27dba6608ee": { + "balance": "0xe3aeb5737240a00000" + }, + "51f9c432a4e59ac86282d6adab4c2eb8919160eb": { + "balance": "0x703b5b89c3a6e7400000" + }, + "520f66a0e2657ff0ac4195f2f064cf2fa4b24250": { + "balance": "0x22b1c8c1227a00000" + }, + "52102354a6aca95d8a2e86d5debda6de69346076": { + "balance": "0x6c6b935b8bbd400000" + }, + "5213f459e078ad3ab95a0920239fcf1633dc04ca": { + "balance": "0x8cf2187c2afb188000" + }, + "5215183b8f80a9bc03d26ce91207832a0d39e620": { + "balance": "0x3635c9adc5dea00000" + }, + "52214378b54004056a7cc08c891327798ac6b248": { + "balance": "0x337fe5feaf2d1800000" + }, + "522323aad71dbc96d85af90f084b99c3f09decb7": { + "balance": "0x14542ba12a337c00000" + }, + "523e140dc811b186dee5d6c88bf68e90b8e096fd": { + "balance": "0x6c6b935b8bbd400000" + }, + "523f6d64690fdacd942853591bb0ff20d3656d95": { + "balance": "0x62a992e53a0af00000" + }, + "524fb210522c5e23bb67dfbf8c26aa616da49955": { + "balance": "0x363562a66d34238000" + }, + "5255dc69155a45b970c604d30047e2f530690e7f": { + "balance": "0x1158e460913d00000" + }, + "5260dc51ee07bddaababb9ee744b393c7f4793a6": { + "balance": "0x1d8665fa5fa4c0000" + }, + "5267f4d41292f370863c90d793296903843625c7": { + "balance": "0x4be4e7267b6ae00000" + }, + "526bb533b76e20c8ee1ebf123f1e9ff4148e40be": { + "balance": "0xaadec983fcff40000" + }, + "526cb09ce3ada3672eec1deb46205be89a4b563e": { + "balance": "0x85ca615bf9c0100000" + }, + "52738c90d860e04cb12f498d96fdb5bf36fc340e": { + "balance": "0x1a055690d9db80000" + }, + "527a8ca1268633a6c939c5de1b929aee92aeac8d": { + "balance": "0x30ca024f987b900000" + }, + "528101ce46b720a2214dcdae6618a53177ffa377": { + "balance": "0x1b9612b9dc01ae0000" + }, + "5281733473e00d87f11e9955e589b59f4ac28e7a": { + "balance": "0x8bd62ff4eec559200000" + }, + "5298ab182a19359ffcecafd7d1b5fa212dede6dd": { + "balance": "0x1158e460913d00000" + }, + "529aa002c6962a3a8545027fd8b05f22b5bf9564": { + "balance": "0x5a87e7d7f5f6580000" + }, + "529e824fa072582b4032683ac7eecc1c04b4cac1": { + "balance": "0x6c6b935b8bbd400000" + }, + "52a5e4de4393eeccf0581ac11b52c683c76ea15d": { + "balance": "0x43c30fb0884a96c0000" + }, + "52b4257cf41b6e28878d50d57b99914ffa89873a": { + "balance": "0xd50dc9aa2c41770000" + }, + "52b8a9592634f7300b7c5c59a3345b835f01b95c": { + "balance": "0x6c6b935b8bbd400000" + }, + "52bdd9af5978850bc24110718b3723759b437e59": { + "balance": "0x5dc892aa1131c80000" + }, + "52cd20403ba7eda6bc307a3d63b5911b817c1263": { + "balance": "0x1158e460913d00000" + }, + "52d380511df19d5ec2807bbcb676581b67fd37a3": { + "balance": "0xb9f65d00f63c0000" + }, + "52e1731350f983cc2c4189842fde0613fad50ce1": { + "balance": "0x277017338a30ae00000" + }, + "52e46783329a769301b175009d346768f4c87ee4": { + "balance": "0x6c6b935b8bbd400000" + }, + "52f058d46147e9006d29bf2c09304ad1cddd6e15": { + "balance": "0x5150ae84a8cdf00000" + }, + "52f15423323c24f19ae2ab673717229d3f747d9b": { + "balance": "0x37a034cbe8e3f38000" + }, + "52f8b509fee1a874ab6f9d87367fbeaf15ac137f": { + "balance": "0x3635c9adc5dea00000" + }, + "52fb46ac5d00c3518b2c3a1c177d442f8165555f": { + "balance": "0x5150ae84a8cdf00000" + }, + "530077c9f7b907ff9cec0c77a41a70e9029add4a": { + "balance": "0x6c6b935b8bbd400000" + }, + "530319db0a8f93e5bb7d4dbf4816314fbed8361b": { + "balance": "0x6c6b935b8bbd400000" + }, + "53047dc8ac9083d90672e8b3473c100ccd278323": { + "balance": "0x22b1c8c1227a00000" + }, + "530b61e42f39426d2408d40852b9e34ab5ebebc5": { + "balance": "0xe7eeba3410b740000" + }, + "530ffac3bc3412e2ec0ea47b7981c770f5bb2f35": { + "balance": "0x73f75d1a085ba0000" + }, + "5317ecb023052ca7f5652be2fa854cfe4563df4d": { + "balance": "0x1b1ab319f5ec750000" + }, + "53194d8afa3e883502767edbc30586af33b114d3": { + "balance": "0x6c6b935b8bbd400000" + }, + "532a7da0a5ad7407468d3be8e07e69c7dd64e861": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "532d32b00f305bcc24dcef56817d622f34fb2c24": { + "balance": "0x6194049f30f7200000" + }, + "533444584082eba654e1ad30e149735c6f7ba922": { + "balance": "0x5dc892aa1131c80000" + }, + "5338ef70eac9dd9af5a0503b5efad1039e67e725": { + "balance": "0x90f534608a72880000" + }, + "53396f4a26c2b4604496306c5442e7fcba272e36": { + "balance": "0x43f2f08d40e5afc0000" + }, + "533a73a4a2228eee05c4ffd718bbf3f9c1b129a7": { + "balance": "0x14542ba12a337c00000" + }, + "533c06928f19d0a956cc28866bf6c8d8f4191a94": { + "balance": "0xfd8c14338e6300000" + }, + "534065361cb854fac42bfb5c9fcde0604ac919da": { + "balance": "0x6c6b935b8bbd400000" + }, + "53437fecf34ab9d435f4deb8ca181519e2592035": { + "balance": "0xa31062beeed700000" + }, + "535201a0a1d73422801f55ded4dfaee4fbaa6e3b": { + "balance": "0x226211f7915428000" + }, + "53608105ce4b9e11f86bf497ffca3b78967b5f96": { + "balance": "0x43c33c1937564800000" + }, + "536e4d8029b73f5579dca33e70b24eba89e11d7e": { + "balance": "0x6acb3df27e1f880000" + }, + "53700d53254d430f22781a4a76a463933b5d6b08": { + "balance": "0x6acb3df27e1f880000" + }, + "537f9d4d31ef70839d84b0d9cdb72b9afedbdf35": { + "balance": "0xed2b525841adfc00000" + }, + "5381448503c0c702542b1de7cc5fb5f6ab1cf6a5": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "53942e7949d6788bb780a7e8a0792781b1614b84": { + "balance": "0x35deb46684f10c80000" + }, + "5395a4455d95d178b4532aa4725b193ffe512961": { + "balance": "0x3635c9adc5dea00000" + }, + "53989ed330563fd57dfec9bd343c3760b0799390": { + "balance": "0x150894e849b39000000" + }, + "53a244672895480f4a2b1cdf7da5e5a242ec4dbc": { + "balance": "0x3635c9adc5dea00000" + }, + "53a714f99fa00fef758e23a2e746326dad247ca7": { + "balance": "0x50c5e761a444080000" + }, + "53af32c22fef99803f178cf90b802fb571c61cb9": { + "balance": "0xd255d112e103a00000" + }, + "53c0bb7fc88ea422d2ef7e540e2d8f28b1bb8183": { + "balance": "0x1158e460913d00000" + }, + "53c5fe0119e1e848640cee30adea96940f2a5d8b": { + "balance": "0x49ada5fa8c10c880000" + }, + "53c9eca40973f63bb5927be0bc6a8a8be1951f74": { + "balance": "0x6c6b935b8bbd400000" + }, + "53ce88e66c5af2f29bbd8f592a56a3d15f206c32": { + "balance": "0x7a28c31cc36040000" + }, + "53cec6c88092f756efe56f7db11228a2db45b122": { + "balance": "0xd8d726b7177a800000" + }, + "53e35b12231f19c3fd774c88fec8cbeedf1408b2": { + "balance": "0x1bc16d674ec8000000" + }, + "53e4d9696dcb3f4d7b3f70dcaa4eecb71782ff5c": { + "balance": "0xad78ebc5ac6200000" + }, + "53faf165be031ec18330d9fce5bd1281a1af08db": { + "balance": "0x796e3ea3f8ab00000" + }, + "540a1819bd7c35861e791804e5fbb3bc97c9abb1": { + "balance": "0x4ed7dac64230200000" + }, + "540c072802014ef0d561345aec481e8e11cb3570": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "540cf23dd95c4d558a279d778d2b3735b3164191": { + "balance": "0x21e19e0c9bab2400000" + }, + "541060fc58c750c40512f83369c0a63340c122b6": { + "balance": "0x6acb3df27e1f880000" + }, + "5413c97ffa4a6e2a7bba8961dc9fce8530a787d7": { + "balance": "0x3635c9adc5dea00000" + }, + "541db20a80cf3b17f1621f1b3ff79b882f50def3": { + "balance": "0x3635c9adc5dea00000" + }, + "542e8096bafb88162606002e8c8a3ed19814aeac": { + "balance": "0x6c6b935b8bbd400000" + }, + "54310b3aa88703a725dfa57de6e646935164802c": { + "balance": "0x678a932062e4180000" + }, + "5431b1d18751b98fc9e2888ac7759f1535a2db47": { + "balance": "0x6c6b935b8bbd400000" + }, + "5431ca427e6165a644bae326bd09750a178c650d": { + "balance": "0x6c6b935b8bbd400000" + }, + "5435c6c1793317d32ce13bba4c4ffeb973b78adc": { + "balance": "0xd8e6b1c1285ef0000" + }, + "543629c95cdef428ad37d453ca9538a9f90900ac": { + "balance": "0x92896529baddc880000" + }, + "54391b4d176d476cea164e5fb535c69700cb2535": { + "balance": "0x56cd55fc64dfe0000" + }, + "543a8c0efb8bcd15c543e2a6a4f807597631adef": { + "balance": "0x13f80e7e14f2d440000" + }, + "543f8c674e2462d8d5daa0e80195a8708e11a29e": { + "balance": "0x37758833b3a7a0000" + }, + "544b5b351d1bc82e9297439948cf4861dac9ae11": { + "balance": "0x4a89f54ef0121c00000" + }, + "544dda421dc1eb73bb24e3e56a248013b87c0f44": { + "balance": "0x6acb3df27e1f880000" + }, + "54575c3114751e3c631971da6a2a02fd3ffbfcc8": { + "balance": "0x692ae8897081d00000" + }, + "545bb070e781172eb1608af7fc2895d6cb87197e": { + "balance": "0x79a5c17ec748900000" + }, + "5475d7f174bdb1f789017c7c1705989646079d49": { + "balance": "0x1fd933494aa5fe00000" + }, + "548558d08cfcb101181dac1eb6094b4e1a896fa6": { + "balance": "0x6c6acc67d7b1d40000" + }, + "54939ff08921b467cf2946751d856378296c63ed": { + "balance": "0x3635c9adc5dea00000" + }, + "549b47649cfad993e4064d2636a4baa0623305cc": { + "balance": "0x209d922f5259c50000" + }, + "549d51af29f724c967f59423b85b2681e7b15136": { + "balance": "0xcbd47b6eaa8cc00000" + }, + "54a1370116fe22099e015d07cd2669dd291cc9d1": { + "balance": "0x1158e460913d00000" + }, + "54a62bf9233e146ffec3876e45f20ee8414adeba": { + "balance": "0x21e19e0c9bab2400000" + }, + "54b4429b182f0377be7e626939c5db6440f75d7a": { + "balance": "0x6acb3df27e1f880000" + }, + "54bcb8e7f73cda3d73f4d38b2d0847e600ba0df8": { + "balance": "0x3a70415882df180000" + }, + "54c93e03a9b2e8e4c3672835a9ee76f9615bc14e": { + "balance": "0x10d3aa536e2940000" + }, + "54ce88275956def5f9458e3b95decacd484021a0": { + "balance": "0x6c6b935b8bbd400000" + }, + "54db5e06b4815d31cb56a8719ba33af2d73e7252": { + "balance": "0x24521e2a3017b80000" + }, + "54e01283cc8b384538dd646770b357c960d6cacd": { + "balance": "0x10f0cf064dd59200000" + }, + "54ec7300b81ac84333ed1b033cd5d7a33972e234": { + "balance": "0xad78ebc5ac6200000" + }, + "54febcce20fe7a9098a755bd90988602a48c089e": { + "balance": "0x22b1c8c1227a000000" + }, + "550aadae1221b07afea39fba2ed62e05e5b7b5f9": { + "balance": "0x1158e460913d00000" + }, + "550c306f81ef5d9580c06cb1ab201b95c748a691": { + "balance": "0x2417d4c470bf140000" + }, + "551999ddd205563327b9b530785acff9bc73a4ba": { + "balance": "0x14542ba12a337c00000" + }, + "551e7784778ef8e048e495df49f2614f84a4f1dc": { + "balance": "0x2086ac351052600000" + }, + "5529830a61c1f13c197e550beddfd6bd195c9d02": { + "balance": "0x21e19e0c9bab2400000" + }, + "552987f0651b915b2e1e5328c121960d4bdd6af4": { + "balance": "0x61093d7c2c6d380000" + }, + "553b6b1c57050e88cf0c31067b8d4cd1ff80cb09": { + "balance": "0x15af1d78b58c400000" + }, + "553f37d92466550e9fd775ae74362df030179132": { + "balance": "0x6c6b935b8bbd400000" + }, + "554336ee4ea155f9f24f87bca9ca72e253e12cd2": { + "balance": "0x56bc75e2d63100000" + }, + "5543dd6d169eec8a213bbf7a8af9ffd15d4ff759": { + "balance": "0xfc936392801c0000" + }, + "5547fdb4ae11953e01292b7807fa9223d0e4606a": { + "balance": "0x55d117dcb1d260000" + }, + "5552f4b3ed3e1da79a2f78bb13e8ae5a68a9df3b": { + "balance": "0x3635c9adc5dea00000" + }, + "555ca9f05cc134ab54ae9bea1c3ff87aa85198ca": { + "balance": "0x56bc75e2d63100000" + }, + "555d8d3ce1798aca902754f164b8be2a02329c6c": { + "balance": "0x21e19e0c9bab2400000" + }, + "555df19390c16d01298772bae8bc3a1152199cbd": { + "balance": "0xad78ebc5ac6200000" + }, + "555ebe84daa42ba256ea789105cec4b693f12f18": { + "balance": "0x56bc75e2d63100000" + }, + "557f5e65e0da33998219ad4e99570545b2a9d511": { + "balance": "0x2559cbb985842400000" + }, + "558360206883dd1b6d4a59639e5629d0f0c675d0": { + "balance": "0x6c6b935b8bbd400000" + }, + "5584423050e3c2051f0bbd8f44bd6dbc27ecb62c": { + "balance": "0xa2a15d09519be00000" + }, + "55852943492970f8d629a15366cdda06a94f4513": { + "balance": "0x6c6b935b8bbd400000" + }, + "55866486ec168f79dbe0e1abb18864d98991ae2c": { + "balance": "0xdf6eb0b2d3ca0000" + }, + "558c54649a8a6e94722bd6d21d14714f71780534": { + "balance": "0x6c6b935b8bbd400000" + }, + "559194304f14b1b93afe444f0624e053c23a0009": { + "balance": "0x15af1d78b58c400000" + }, + "5593c9d4b664730fd93ca60151c25c2eaed93c3b": { + "balance": "0xad78ebc5ac6200000" + }, + "559706c332d20779c45f8a6d046a699159b74921": { + "balance": "0x149b442e85a3cf8000" + }, + "5598b3a79a48f32b1f5fc915b87b645d805d1afe": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "55a3df57b7aaec16a162fd5316f35bec082821cf": { + "balance": "0x6acb3df27e1f880000" + }, + "55a4cac0cb8b582d9fef38c5c9fff9bd53093d1f": { + "balance": "0x6acb3df27e1f880000" + }, + "55a61b109480b5b2c4fcfdef92d90584160c0d35": { + "balance": "0x26c564d2b53f60000" + }, + "55aa5d313ebb084da0e7801091e29e92c5dec3aa": { + "balance": "0x6c6b935b8bbd400000" + }, + "55ab99b0e0e55d7bb874b7cfe834de631c97ec23": { + "balance": "0x37e98ce36899e40000" + }, + "55af092f94ba6a79918b0cf939eab3f01b3f51c7": { + "balance": "0x820d5e39576120000" + }, + "55c564664166a1edf3913e0169f1cd451fdb5d0c": { + "balance": "0x8217ea49508e6c0000" + }, + "55ca6abe79ea2497f46fdbb830346010fe469cbe": { + "balance": "0x1369fb96128ac480000" + }, + "55caff4bba04d220c9a5d2018672ec85e31ef83e": { + "balance": "0x6c6b935b8bbd400000" + }, + "55d057bcc04bd0f4af9642513aa5090bb3ff93fe": { + "balance": "0x3bfe452c8edd4c0000" + }, + "55d42eb495bf46a634997b5f2ea362814918e2b0": { + "balance": "0x5c0d265b5b2a80000" + }, + "55da9dcdca61cbfe1f133c7bcefc867b9c8122f9": { + "balance": "0x2fb474098f67c00000" + }, + "55e220876262c218af4f56784798c7e55da09e91": { + "balance": "0x73d99c15645d30000" + }, + "55fd08d18064bd202c0ec3d2cce0ce0b9d169c4d": { + "balance": "0x6acb3df27e1f880000" + }, + "5600730a55f6b20ebd24811faa3de96d1662abab": { + "balance": "0x65ea3db75546600000" + }, + "5603241eb8f08f721e348c9d9ad92f48e390aa24": { + "balance": "0xad78ebc5ac6200000" + }, + "560536794a9e2b0049d10233c41adc5f418a264a": { + "balance": "0x3635c9adc5dea00000" + }, + "5607590059a9fec1881149a44b36949aef85d560": { + "balance": "0x6c6b935b8bbd400000" + }, + "560becdf52b71f3d8827d927610f1a980f33716f": { + "balance": "0x17474d705f56d08000" + }, + "560da37e956d862f81a75fd580a7135c1b246352": { + "balance": "0x21e19e0c9bab2400000" + }, + "560fc08d079f047ed8d7df75551aa53501f57013": { + "balance": "0x19bff2ff57968c00000" + }, + "561be9299b3e6b3e63b79b09169d1a948ae6db01": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "562020e3ed792d2f1835fe5f55417d5111460c6a": { + "balance": "0x43c33c1937564800000" + }, + "5620f46d1451c2353d6243a5d4b427130be2d407": { + "balance": "0x340aad21b3b700000" + }, + "562105e82b099735de49f62692cc87cd38a8edcd": { + "balance": "0x14542ba12a337c00000" + }, + "562a8dcbbeeef7b360685d27303bd69e094accf6": { + "balance": "0x21e19e0c9bab2400000" + }, + "562bced38ab2ab6c080f3b0541b8456e70824b3f": { + "balance": "0x22ca3587cf4eb00000" + }, + "562be95aba17c5371fe2ba828799b1f55d2177d6": { + "balance": "0x816d37e87b9d1e00000" + }, + "562f16d79abfcec3943e34b20f05f97bdfcda605": { + "balance": "0xd8d726b7177a800000" + }, + "56373daab46316fd7e1576c61e6affcb6559ddd7": { + "balance": "0xbac715d146c9e0000" + }, + "56397638bb3cebf1f62062794b5eb942f916171d": { + "balance": "0x6c6b935b8bbd400000" + }, + "563a03ab9c56b600f6d25b660c21e16335517a75": { + "balance": "0x3635c9adc5dea00000" + }, + "563cb8803c1d32a25b27b64114852bd04d9c20cd": { + "balance": "0xb149ead0ad9d80000" + }, + "56586391040c57eec6f5affd8cd4abde10b50acc": { + "balance": "0xd8d726b7177a800000" + }, + "566c10d638e8b88b47d6e6a414497afdd00600d4": { + "balance": "0x56b394263a40c0000" + }, + "566c28e34c3808d9766fe8421ebf4f2b1c4f7d77": { + "balance": "0x6acb3df27e1f880000" + }, + "568df31856699bb5acfc1fe1d680df9960ca4359": { + "balance": "0x4acf5552f3b2498000" + }, + "5691dd2f6745f20e22d2e1d1b955aa2903d65656": { + "balance": "0x6ac5c62d9486070000" + }, + "56a1d60d40f57f308eebf087dee3b37f1e7c2cba": { + "balance": "0x3edcaec82d06f80000" + }, + "56ac20d63bd803595cec036da7ed1dc66e0a9e07": { + "balance": "0x3772a53ccdc658000" + }, + "56b6c23dd2ec90b4728f3bb2e764c3c50c85f144": { + "balance": "0x3635c9adc5dea00000" + }, + "56df05bad46c3f00ae476ecf017bb8c877383ff1": { + "balance": "0xab15daaef70400000" + }, + "56ee197f4bbf9f1b0662e41c2bbd9aa1f799e846": { + "balance": "0x3635c9adc5dea00000" + }, + "56f493a3d108aaa2d18d98922f8efe1662cfb73d": { + "balance": "0x6d8121a194d1100000" + }, + "56fc1a7bad4047237ce116146296238e078f93ad": { + "balance": "0x9a63f08ea63880000" + }, + "56febf9e1003af15b1bd4907ec089a4a1b91d268": { + "balance": "0xad78ebc5ac6200000" + }, + "5717cc9301511d4a81b9f583148beed3d3cc8309": { + "balance": "0x8cf23f909c0fa00000" + }, + "5717f2d8f18ffcc0e5fe247d3a4219037c3a649c": { + "balance": "0xd8bb6549b02bb80000" + }, + "571950ea2c90c1427d939d61b4f2de4cf1cfbfb0": { + "balance": "0x1158e460913d00000" + }, + "5719f49b720da68856f4b9e708f25645bdbc4b41": { + "balance": "0x22b1c8c1227a000000" + }, + "572ac1aba0de23ae41a7cae1dc0842d8abfc103b": { + "balance": "0x678a932062e4180000" + }, + "572dd8cd3fe399d1d0ec281231b7cefc20b9e4bb": { + "balance": "0x233c8fe42703e800000" + }, + "574921838cc77d6c98b17d903a3ae0ee0da95bd0": { + "balance": "0xb5328178ad0f2a00000" + }, + "574ad9355390e4889ef42acd138b2a27e78c00ae": { + "balance": "0x5467b732a913340000" + }, + "574de1b3f38d915846ae3718564a5ada20c2f3ed": { + "balance": "0xd8d726b7177a800000" + }, + "575c00c2818210c28555a0ff29010289d3f82309": { + "balance": "0x21e19e0c9bab2400000" + }, + "5773b6026721a1dd04b7828cd62b591bfb34534c": { + "balance": "0x5b7ac4553de7ae00000" + }, + "5777441c83e03f0be8dd340bde636850847c620b": { + "balance": "0x21e19e0c9bab2400000" + }, + "5778ffdc9b94c5a59e224eb965b6de90f222d170": { + "balance": "0x122d7ff36603fc0000" + }, + "577aeee8d4bc08fc97ab156ed57fb970925366be": { + "balance": "0x120df1147258bf0000" + }, + "577b2d073c590c50306f5b1195a4b2ba9ecda625": { + "balance": "0x1440bdd49515f00000" + }, + "577bfe64e3a1e3800e94db1c6c184d8dc8aafc66": { + "balance": "0x5134ed17417f280000" + }, + "57825aeb09076caa477887fbc9ae37e8b27cc962": { + "balance": "0x56bc75e2d63100000" + }, + "57883010b4ac857fedac03eab2551723a8447ffb": { + "balance": "0x3635c9adc5dea00000" + }, + "5789d01db12c816ac268e9af19dc0dd6d99f15df": { + "balance": "0xad78ebc5ac6200000" + }, + "5792814f59a33a1843faa01baa089eb02ffb5cf1": { + "balance": "0x1b1ab319f5ec750000" + }, + "5793abe6f1533311fd51536891783b3f9625ef1c": { + "balance": "0x2cd8a656f23fda0000" + }, + "5797b60fd2894ab3c2f4aede86daf2e788d745ad": { + "balance": "0x14542ba12a337c00000" + }, + "57a852fdb9b1405bf53ccf9508f83299d3206c52": { + "balance": "0x6c6b935b8bbd400000" + }, + "57b23d6a1adc06c652a779c6a7fb6b95b9fead66": { + "balance": "0xad78ebc5ac6200000" + }, + "57bc20e2d62b3d19663cdb4c309d5b4f2fc2db8f": { + "balance": "0x56bc75e2d63100000" + }, + "57bddf078834009c89d88e6282759dc45335b470": { + "balance": "0x74717cfb6883100000" + }, + "57beea716cbd81700a73d67f9ff039529c2d9025": { + "balance": "0xad78ebc5ac6200000" + }, + "57d032a43d164e71aa2ef3ffd8491b0a4ef1ea5b": { + "balance": "0x6c6b935b8bbd400000" + }, + "57d3df804f2beee6ef53ab94cb3ee9cf524a18d3": { + "balance": "0x1556616b9606670000" + }, + "57d5fd0e3d3049330ffcdcd020456917657ba2da": { + "balance": "0x6bf20195f554d40000" + }, + "57dd9471cbfa262709f5f486bcb774c5f527b8f8": { + "balance": "0xaadec983fcff40000" + }, + "57df23bebdc65eb75feb9cb2fad1c073692b2baf": { + "balance": "0xd8d726b7177a800000" + }, + "5800cd8130839e94495d2d8415a8ea2c90e0c5cb": { + "balance": "0xad78ebc5ac6200000" + }, + "5803e68b34da121aef08b602badbafb4d12481ca": { + "balance": "0x3cfc82e37e9a7400000" + }, + "5816c2687777b6d7d2a2432d59a41fa059e3a406": { + "balance": "0x1c4fe43adb0a5e900000" + }, + "581a3af297efa4436a29af0072929abf9826f58b": { + "balance": "0x6c6b935b8bbd400000" + }, + "581b9fd6eae372f3501f42eb9619eec820b78a84": { + "balance": "0x42be2c00ca53b8d8000" + }, + "581bdf1bb276dbdd86aedcdb397a01efc0e00c5b": { + "balance": "0x3635c9adc5dea00000" + }, + "581f34b523e5b41c09c87c298e299cbc0e29d066": { + "balance": "0x3d5833aafd39758000" + }, + "5824a7e22838277134308c5f4b50dab65e43bb31": { + "balance": "0x14542ba12a337c00000" + }, + "582b70669c97aab7d68148d8d4e90411e2810d56": { + "balance": "0x36356633ebd8ea0000" + }, + "582e7cc46f1d7b4e6e9d95868bfd370573178f4c": { + "balance": "0x6c6b935b8bbd400000" + }, + "583e83ba55e67e13e0e76f8392d873cd21fbf798": { + "balance": "0x1158e460913d00000" + }, + "5869fb867d71f1387f863b698d09fdfb87c49b5c": { + "balance": "0xc6bbf858b316080000" + }, + "587d6849b168f6c3332b7abae7eb6c42c37f48bf": { + "balance": "0x2fb474098f67c00000" + }, + "5887dc6a33dfed5ac1edefe35ef91a216231ac96": { + "balance": "0xd8d726b7177a80000" + }, + "588ed990a2aff44a94105d58c305257735c868ac": { + "balance": "0x368c8623a8b4d100000" + }, + "58ae2ddc5f4c8ada97e06c0086171767c423f5d7": { + "balance": "0x57473d05dabae80000" + }, + "58aed6674affd9f64233272a578dd9386b99c263": { + "balance": "0xb8507a820728200000" + }, + "58b808a65b51e6338969afb95ec70735e451d526": { + "balance": "0x8784bc1b9837a380000" + }, + "58b8ae8f63ef35ed0762f0b6233d4ac14e64b64d": { + "balance": "0x6c6b935b8bbd400000" + }, + "58ba1569650e5bbbb21d35d3e175c0d6b0c651a9": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "58c555bc293cdb16c6362ed97ae9550b92ea180e": { + "balance": "0x1158e460913d00000" + }, + "58c650ced40bb65641b8e8a924a039def46854df": { + "balance": "0x100bd33fb98ba0000" + }, + "58c90754d2f20a1cb1dd330625e04b45fa619d5c": { + "balance": "0x6c6b935b8bbd400000" + }, + "58e2f11223fc8237f69d99c6289c148c0604f742": { + "balance": "0x5150ae84a8cdf000000" + }, + "58e554af3d87629620da61d538c7f5b4b54c4afe": { + "balance": "0x46509d694534728000" + }, + "58e5c9e344c806650dacfc904d33edba5107b0de": { + "balance": "0x10910d4cdc9f60000" + }, + "58e661d0ba73d6cf24099a5562b808f7b3673b68": { + "balance": "0x6c6b935b8bbd400000" + }, + "58f05b262560503ca761c61890a4035f4c737280": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "58fb947364e7695765361ebb1e801ffb8b95e6d0": { + "balance": "0xad78ebc5ac6200000" + }, + "590181d445007bd0875aaf061c8d51153900836a": { + "balance": "0x6c6b935b8bbd400000" + }, + "5902e44af769a87246a21e079c08bf36b06efeb3": { + "balance": "0x3635c9adc5dea00000" + }, + "590acbda37290c0d3ec84fc2000d7697f9a4b15d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "590ccb5911cf78f6f622f535c474375f4a12cfcf": { + "balance": "0x43c33c1937564800000" + }, + "5910106debd291a1cd80b0fbbb8d8d9e93a7cc1e": { + "balance": "0x6c6b935b8bbd400000" + }, + "59161749fedcf1c721f2202d13ade2abcf460b3d": { + "balance": "0x6c6b935b8bbd400000" + }, + "591bef3171d1c5957717a4e98d17eb142c214e56": { + "balance": "0x43c33c1937564800000" + }, + "59203cc37599b648312a7cc9e06dacb589a9ae6a": { + "balance": "0x80f7971b6400e8000" + }, + "59268171b833e0aa13c54b52ccc0422e4fa03aeb": { + "balance": "0xa2a15d09519be00000" + }, + "592777261e3bd852c48eca95b3a44c5b7f2d422c": { + "balance": "0x43c33c1937564800000" + }, + "593044670faeff00a55b5ae051eb7be870b11694": { + "balance": "0x73f75d1a085ba0000" + }, + "593b45a1864ac5c7e8f0caaeba0d873cd5d113b2": { + "balance": "0x14542ba12a337c00000" + }, + "593c48935beaff0fde19b04d309cd530a28e52ce": { + "balance": "0xd8d726b7177a800000" + }, + "59473cd300fffae240f5785626c65dfec792b9af": { + "balance": "0x1158e460913d00000" + }, + "5948bc3650ed519bf891a572679fd992f8780c57": { + "balance": "0xaadec983fcff40000" + }, + "594a76f06935388dde5e234696a0668bc20d2ddc": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "59569a21d28fba4bda37753405a081f2063da150": { + "balance": "0xd8d726b7177a800000" + }, + "5956b28ec7890b76fc061a1feb52d82ae81fb635": { + "balance": "0x6c6b935b8bbd400000" + }, + "595e23d788a2d4bb85a15df7136d264a635511b3": { + "balance": "0xd5967be4fc3f100000" + }, + "597038ff91a0900cbbab488af483c790e6ec00a0": { + "balance": "0x21e19e0c9bab2400000" + }, + "5970fb1b144dd751e4ce2eca7caa20e363dc4da3": { + "balance": "0x21e19e0c9bab2400000" + }, + "5975b9528f23af1f0e2ec08ac8ebaa786a2cb8e0": { + "balance": "0x12bf50503ae3038000" + }, + "5975d78d974ee5bb9e4d4ca2ae77c84b9c3b4b82": { + "balance": "0x4a4491bd6dcd280000" + }, + "5985c59a449dfc5da787d8244e746c6d70caa55f": { + "balance": "0x56bc75e2d63100000" + }, + "598aaabae9ed833d7bc222e91fcaa0647b77580b": { + "balance": "0x6194049f30f7200000" + }, + "5992624c54cdec60a5ae938033af8be0c50cbb0a": { + "balance": "0xc454e0f8870f2b0000" + }, + "599728a78618d1a17b9e34e0fed8e857d5c40622": { + "balance": "0x2f6f10780d22cc00000" + }, + "5997ffefb3c1d9d10f1ae2ac8ac3c8e2d2292783": { + "balance": "0x3635c9adc5dea00000" + }, + "59a087b9351ca42f58f36e021927a22988284f38": { + "balance": "0x100bd33fb98ba0000" + }, + "59a12df2e3ef857aceff9306b309f6a500f70134": { + "balance": "0x3635c9adc5dea00000" + }, + "59b96deb8784885d8d3b4a166143cc435d2555a1": { + "balance": "0x487a9a304539440000" + }, + "59b9e733cba4be00429b4bd9dfa64732053a7d55": { + "balance": "0x1158e460913d00000" + }, + "59c5d06b170ee4d26eb0a0eb46cb7d90c1c91019": { + "balance": "0x21e19e0c9bab2400000" + }, + "59c7f785c93160e5807ed34e5e534bc6188647a7": { + "balance": "0x22b1c8c1227a000000" + }, + "59d139e2e40c7b97239d23dfaca33858f602d22b": { + "balance": "0x6c6b935b8bbd400000" + }, + "59f6247b0d582aaa25e5114765e4bf3c774f43c2": { + "balance": "0x2b5e3af16b1880000" + }, + "59fe00696dbd87b7976b29d1156c8842a2e17914": { + "balance": "0x6c6b935b8bbd400000" + }, + "5a0d609aae2332b137ab3b2f26615a808f37e433": { + "balance": "0x21e19e0c9bab24000000" + }, + "5a192b964afd80773e5f5eda6a56f14e25e0c6f3": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5a1a336962d6e0c63031cc83c6a5c6a6f4478ecb": { + "balance": "0x3635c9adc5dea00000" + }, + "5a1d2d2d1d520304b6208849570437eb3091bb9f": { + "balance": "0x6acb3df27e1f880000" + }, + "5a267331facb262daaecd9dd63a9700c5f5259df": { + "balance": "0x56bc75e2d63100000" + }, + "5a285755391e914e58025faa48cc685f4fd4f5b8": { + "balance": "0x581767ba6189c400000" + }, + "5a2916b8d2e8cc12e207ab464d433e2370d823d9": { + "balance": "0x6c6b935b8bbd400000" + }, + "5a2b1c853aeb28c45539af76a00ac2d8a8242896": { + "balance": "0x15af1d78b58c40000" + }, + "5a2daab25c31a61a92a4c82c9925a1d2ef58585e": { + "balance": "0xc380da9c7950c0000" + }, + "5a30feac37ac9f72d7b4af0f2bc73952c74fd5c3": { + "balance": "0x6c6b935b8bbd400000" + }, + "5a5468fa5ca226c7532ecf06e1bc1c45225d7ec9": { + "balance": "0x678a932062e4180000" + }, + "5a565285374a49eedd504c957d510874d00455bc": { + "balance": "0x56bc75e2d63100000" + }, + "5a5ee8e9bb0e8ab2fecb4b33d29478be50bbd44b": { + "balance": "0x2a1129d09367200000" + }, + "5a5f8508da0ebebb90be9033bd4d9e274105ae00": { + "balance": "0x16a6502f15a1e540000" + }, + "5a6071bcebfcba4ab57f4db96fc7a68bece2ba5b": { + "balance": "0x6c6b935b8bbd400000" + }, + "5a60c924162873fc7ea4da7f972e350167376031": { + "balance": "0x487f277a885798000" + }, + "5a6686b0f17e07edfc59b759c77d5bef164d3879": { + "balance": "0x50c5e761a444080000" + }, + "5a70106f20d63f875265e48e0d35f00e17d02bc9": { + "balance": "0x1158e460913d00000" + }, + "5a74ba62e7c81a3474e27d894fed33dd24ad95fe": { + "balance": "0xfc936392801c0000" + }, + "5a7735007d70b06844da9901cdfadb11a2582c2f": { + "balance": "0x14542ba12a337c00000" + }, + "5a82f96cd4b7e2d93d10f3185dc8f43d4b75aa69": { + "balance": "0x6c633fbab98c040000" + }, + "5a87f034e6f68f4e74ffe60c64819436036cf7d7": { + "balance": "0x1158e460913d00000" + }, + "5a891155f50e42074374c739baadf7df2651153a": { + "balance": "0x102da6fd0f73a3c0000" + }, + "5a9c8b69fc614d69564999b00dcb42db67f97e90": { + "balance": "0xb9e615abad3a778000" + }, + "5aaf1c31254a6e005fba7f5ab0ec79d7fc2b630e": { + "balance": "0x14061b9d77a5e980000" + }, + "5ab1a5615348001c7c775dc75748669b8be4de14": { + "balance": "0x256a72fb29e69c0000" + }, + "5abfec25f74cd88437631a7731906932776356f9": { + "balance": "0x9d83cc0dfa11177ff8000" + }, + "5ac2908b0f398c0df5bac2cb13ca7314fba8fa3d": { + "balance": "0xad4c8316a0b0c0000" + }, + "5ac99ad7816ae9020ff8adf79fa9869b7cea6601": { + "balance": "0x472698b413b43200000" + }, + "5ad12c5ed4fa827e2150cfa0d68c0aa37b1769b8": { + "balance": "0x2b5e3af16b18800000" + }, + "5ad5e420755613886f35aa56ac403eebdfe4b0d0": { + "balance": "0x10f0cf064dd592000000" + }, + "5ade77fd81c25c0af713b10702768c1eb2f975e7": { + "balance": "0x1158e460913d00000" + }, + "5ae64e853ba0a51282cb8db52e41615e7c9f733f": { + "balance": "0x6c6b935b8bbd400000" + }, + "5aed0e6cfe95f9d680c76472a81a2b680a7f93e2": { + "balance": "0xaadec983fcff40000" + }, + "5aef16a226dd68071f2483e1da42598319f69b2c": { + "balance": "0x6c6b935b8bbd400000" + }, + "5af46a25ac09cb73616b53b14fb42ff0a51cddb2": { + "balance": "0xd8d726b7177a800000" + }, + "5af7c072b2c5acd71c76addcce535cf7f8f93585": { + "balance": "0x1158e460913d00000" + }, + "5afda9405c8e9736514574da928de67456010918": { + "balance": "0x145b8b0239a46920000" + }, + "5b06d1e6930c1054692b79e3dbe6ecce53966420": { + "balance": "0xb227f63be813c0000" + }, + "5b25cae86dcafa2a60e7723631fc5fa49c1ad87d": { + "balance": "0x870c58510e85200000" + }, + "5b287c7e734299e727626f93fb1187a60d5057fe": { + "balance": "0x57cd934a914cb0000" + }, + "5b290c01967c812e4dc4c90b174c1b4015bae71e": { + "balance": "0x820eb348d52b90000" + }, + "5b2b64e9c058e382a8b299224eecaa16e09c8d92": { + "balance": "0x8ba52e6fc45e40000" + }, + "5b2e2f1618552eab0db98add55637c2951f1fb19": { + "balance": "0x28a857425466f800000" + }, + "5b30608c678e1ac464a8994c3b33e5cdf3497112": { + "balance": "0x15af1d78b58c400000" + }, + "5b333696e04cca1692e71986579c920d6b2916f9": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5b430d779696a3653fc60e74fbcbacf6b9c2baf1": { + "balance": "0x2f6f10780d22cc00000" + }, + "5b437365ae3a9a2ff97c68e6f90a7620188c7d19": { + "balance": "0x6c8754c8f30c080000" + }, + "5b49afcd75447838f6e7ceda8d21777d4fc1c3c0": { + "balance": "0xd8d726b7177a800000" + }, + "5b4c0c60f10ed2894bdb42d9dd1d210587810a0d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5b4ea16db6809b0352d4b6e81c3913f76a51bb32": { + "balance": "0x15af1d78b58c400000" + }, + "5b5be0d8c67276baabd8edb30d48ea75640b8b29": { + "balance": "0x2cb1f55fb7be100000" + }, + "5b5d517029321562111b43086d0b043591109a70": { + "balance": "0x8cf23f909c0fa00000" + }, + "5b5d8c8eed6c85ac215661de026676823faa0a0c": { + "balance": "0x43c33c1937564800000" + }, + "5b6d55f6712967405c659129f4b1de09acf2cb7b": { + "balance": "0xe7eeba3410b740000" + }, + "5b70c49cc98b3df3fbe2b1597f5c1b6347a388b7": { + "balance": "0x34957444b840e80000" + }, + "5b736eb18353629bde9676dadd165034ce5ecc68": { + "balance": "0x6acb3df27e1f880000" + }, + "5b759fa110a31c88469f54d44ba303d57dd3e10f": { + "balance": "0x5b46dd2f0ea3b80000" + }, + "5b7784caea01799ca30227827667ce207c5cbc76": { + "balance": "0x6c6b935b8bbd400000" + }, + "5b78eca27fbdea6f26befba8972b295e7814364b": { + "balance": "0x6c6b935b8bbd400000" + }, + "5b800bfd1b3ed4a57d875aed26d42f1a7708d72a": { + "balance": "0x15a82d1d5bb88e00000" + }, + "5b85e60e2af0544f2f01c64e2032900ebd38a3c7": { + "balance": "0x6c6b935b8bbd400000" + }, + "5ba2c6c35dfaec296826591904d544464aeabd5e": { + "balance": "0x1158e460913d00000" + }, + "5baf6d749620803e8348af3710e5c4fbf20fc894": { + "balance": "0x10f4002615dfe900000" + }, + "5bc1f95507b1018642e45cd9c0e22733b9b1a326": { + "balance": "0x56bc75e2d63100000" + }, + "5bd23547477f6d09d7b2a005c5ee650c510c56d7": { + "balance": "0x21e19e0c9bab2400000" + }, + "5bd24aac3612b20c609eb46779bf95698407c57c": { + "balance": "0x6acb3df27e1f880000" + }, + "5bd6862d517d4de4559d4eec0a06cad05e2f946e": { + "balance": "0xad78ebc5ac6200000" + }, + "5be045512a026e3f1cebfd5a7ec0cfc36f2dc16b": { + "balance": "0x68155a43676e00000" + }, + "5bf9f2226e5aeacf1d80ae0a59c6e38038bc8db5": { + "balance": "0x14542ba12a337c00000" + }, + "5bfafe97b1dd1d712be86d41df79895345875a87": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5c0f2e51378f6b0d7bab617331580b6e39ad3ca5": { + "balance": "0x2086ac3510526000000" + }, + "5c29f9e9a523c1f8669448b55c48cbd47c25e610": { + "balance": "0x3446a0dad04cb00000" + }, + "5c308bac4857d33baea074f3956d3621d9fa28e1": { + "balance": "0x10f08eda8e555098000" + }, + "5c312a56c784b122099b764d059c21ece95e84ca": { + "balance": "0x52663ccab1e1c0000" + }, + "5c31996dcac015f9be985b611f468730ef244d90": { + "balance": "0xad78ebc5ac6200000" + }, + "5c323457e187761a8276e359b7b7af3f3b6e3df6": { + "balance": "0x21e19e0c9bab2400000" + }, + "5c3c1c645b917543113b3e6c1c054da1fe742b9a": { + "balance": "0x2b5e3af16b18800000" + }, + "5c3d19441d196cb443662020fcad7fbb79b29e78": { + "balance": "0xc673ce3c40160000" + }, + "5c3f567faff7bad1b5120022e8cbcaa82b4917b3": { + "balance": "0x6c6b935b8bbd400000" + }, + "5c4368918ace6409c79eca80cdaae4391d2b624e": { + "balance": "0xd8d726b7177a800000" + }, + "5c464197791c8a3da3c925436f277ab13bf2faa2": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "5c4881165cb42bb82e97396c8ef44adbf173fb99": { + "balance": "0x5fee222041e340000" + }, + "5c4892907a0720df6fd3413e63ff767d6b398023": { + "balance": "0x2cb009fd3b5790f8000" + }, + "5c4f24e994ed8f850ea7818f471c8fac3bcf0452": { + "balance": "0x5d80688d9e31c00000" + }, + "5c5419565c3aad4e714e0739328e3521c98f05cc": { + "balance": "0x1c9f78d2893e400000" + }, + "5c6136e218de0a61a137b2b3962d2a6112b809d7": { + "balance": "0xff3dbb65ff4868000" + }, + "5c61ab79b408dd3229f662593705d72f1e147bb8": { + "balance": "0x4d0243d3498cd840000" + }, + "5c6d041da7af4487b9dc48e8e1f60766d0a56dbc": { + "balance": "0x4f070a003e9c740000" + }, + "5c6f36af90ab1a656c6ec8c7d521512762bba3e1": { + "balance": "0x6c68ccd09b022c0000" + }, + "5c7b9ec7a2438d1e3c7698b545b9c3fd77b7cd55": { + "balance": "0x3635c9adc5dea00000" + }, + "5c936f3b9d22c403db5e730ff177d74eef42dbbf": { + "balance": "0x410d586a20a4c0000" + }, + "5cb731160d2e8965670bde925d9de5510935347d": { + "balance": "0x22b1c8c1227a00000" + }, + "5cb953a0e42f5030812226217fffc3ce230457e4": { + "balance": "0x56bc75e2d63100000" + }, + "5cbd8daf27ddf704cdd0d909a789ba36ed4f37b2": { + "balance": "0xb9f65d00f63c0000" + }, + "5cc4cba621f220637742057f6055b80dffd77e13": { + "balance": "0x878477b7d253b660000" + }, + "5cc7d3066d45d27621f78bb4b339473e442a860f": { + "balance": "0x21e1899f0377aea0000" + }, + "5cccf1508bfd35c20530aa642500c10dee65eaed": { + "balance": "0x2e141ea081ca080000" + }, + "5cce72d068c7c3f55b1d2819545e77317cae8240": { + "balance": "0x692ae8897081d00000" + }, + "5cd0e475b54421bdfc0c12ea8e082bd7a5af0a6a": { + "balance": "0x332ca1b67940c0000" + }, + "5cd588a14ec648ccf64729f9167aa7bf8be6eb3d": { + "balance": "0x3635c9adc5dea00000" + }, + "5cd8af60de65f24dc3ce5730ba92653022dc5963": { + "balance": "0x61093d7c2c6d380000" + }, + "5cdc4708f14f40dcc15a795f7dc8cb0b7faa9e6e": { + "balance": "0x1d1c5f3eda20c40000" + }, + "5ce0b6862cce9162e87e0849e387cb5df4f9118c": { + "balance": "0x5a87e7d7f5f6580000" + }, + "5ce2e7ceaaa18af0f8aafa7fbad74cc89e3cd436": { + "balance": "0x43c33c1937564800000" + }, + "5ce44068b8f4a3fe799e6a8311dbfdeda29dee0e": { + "balance": "0x6c6b935b8bbd400000" + }, + "5cebe30b2a95f4aefda665651dc0cf7ef5758199": { + "balance": "0xfc936392801c0000" + }, + "5cf18fa7c8a7c0a2b3d5efd1990f64ddc569242c": { + "balance": "0x3635c9adc5dea00000" + }, + "5cf44e10540d65716423b1bcb542d21ff83a94cd": { + "balance": "0x21e19e0c9bab2400000" + }, + "5cf8c03eb3e872e50f7cfd0c2f8d3b3f2cb5183a": { + "balance": "0xad78ebc5ac6200000" + }, + "5cfa8d568575658ca4c1a593ac4c5d0e44c60745": { + "balance": "0xfc66fae3746ac0000" + }, + "5cfa9877f719c79d9e494a08d1e41cf103fc87c9": { + "balance": "0xad78ebc5ac6200000" + }, + "5d1dc3387b47b8451e55106c0cc67d6dc72b7f0b": { + "balance": "0x6c6b935b8bbd400000" + }, + "5d231a70c1dfeb360abd97f616e2d10d39f3cab5": { + "balance": "0x15af1d78b58c400000" + }, + "5d24bdbc1c47f0eb83d128cae48ac33c4817e91f": { + "balance": "0x3635c9adc5dea00000" + }, + "5d2819e8d57821922ee445650ccaec7d40544a8d": { + "balance": "0xad78ebc5ac6200000" + }, + "5d2f7f0b04ba4be161e19cb6f112ce7a5e7d7fe4": { + "balance": "0x1e87f85809dc00000" + }, + "5d32f6f86e787ff78e63d78b0ef95fe6071852b8": { + "balance": "0x15be6174e1912e0000" + }, + "5d39ef9ea6bdfff15d11fe91f561a6f9e31f5da5": { + "balance": "0x6c6b935b8bbd400000" + }, + "5d3f3b1f7130b0bb21a0fd32396239179a25657f": { + "balance": "0xd3ab8ea5e8fd9e80000" + }, + "5d5751819b4f3d26ed0c1ac571552735271dbefa": { + "balance": "0x3635c9adc5dea00000" + }, + "5d5c2c1099bbeefb267e74b58880b444d94449e0": { + "balance": "0xdbf0bd181e2e70000" + }, + "5d5cdbe25b2a044b7b9be383bcaa5807b06d3c6b": { + "balance": "0x6c6b935b8bbd400000" + }, + "5d5d6e821c6eef96810c83c491468560ef70bfb5": { + "balance": "0x6c6b935b8bbd400000" + }, + "5d68324bcb776d3ffd0bf9fea91d9f037fd6ab0f": { + "balance": "0x6c6b935b8bbd400000" + }, + "5d6ae8cbd6b3393c22d16254100d0238e808147c": { + "balance": "0x2707e56d51a30c0000" + }, + "5d6c5c720d66a6abca8397142e63d26818eaab54": { + "balance": "0x22b1c8c1227a00000" + }, + "5d6ccf806738091042ad97a6e095fe8c36aa79c5": { + "balance": "0xa31062beeed700000" + }, + "5d71799c8df3bccb7ee446df50b8312bc4eb71c5": { + "balance": "0xad78ebc5ac6200000" + }, + "5d822d9b3ef4b502627407da272f67814a6becd4": { + "balance": "0x1158e460913d00000" + }, + "5d83b21bd2712360436b67a597ee3378db3e7ae4": { + "balance": "0x6c6b935b8bbd400000" + }, + "5d872b122e994ef27c71d7deb457bf65429eca6c": { + "balance": "0x1b1aded81d394108000" + }, + "5d8d31faa864e22159cd6f5175ccecc53fa54d72": { + "balance": "0x5b696b70dd567100000" + }, + "5d958a9bd189c2985f86c58a8c69a7a78806e8da": { + "balance": "0x228f16f861578600000" + }, + "5da2a9a4c2c0a4a924cbe0a53ab9d0c627a1cfa0": { + "balance": "0x27bf38c6544df50000" + }, + "5da4ca88935c27f55c311048840e589e04a8a049": { + "balance": "0x4563918244f400000" + }, + "5da54785c9bd30575c89deb59d2041d20a39e17b": { + "balance": "0x6aa209f0b91d658000" + }, + "5db69fe93e6fb6fbd450966b97238b110ad8279a": { + "balance": "0x878678326eac9000000" + }, + "5db7bba1f9573f24115d8c8c62e9ce8895068e9f": { + "balance": "0x2b5aad72c65200000" + }, + "5db84400570069a9573cab04b4e6b69535e202b8": { + "balance": "0x20dd68aaf3289100000" + }, + "5dc36de5359450a1ec09cb0c44cf2bb42b3ae435": { + "balance": "0x3c946d893b33060000" + }, + "5dc6f45fef26b06e3302313f884daf48e2746fb9": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5dcdb6b87a503c6d8a3c65c2cf9a9aa883479a1e": { + "balance": "0x1f2bba5d84f99c00000" + }, + "5dd112f368c0e6ceff77a9df02a5481651a02fb7": { + "balance": "0x93472c85c6d540000" + }, + "5dd53ae897526b167d39f1744ef7c3da5b37a293": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "5dded049a6e1f329dc4b971e722c9c1f2ade83f0": { + "balance": "0x3635c9adc5dea00000" + }, + "5de598aba344378cab4431555b4f79992dc290c6": { + "balance": "0x487a9a304539440000" + }, + "5de9e7d5d1b667d095dd34099c85b0421a0bc681": { + "balance": "0x1158e460913d00000" + }, + "5df3277ca85936c7a0d2c0795605ad25095e7159": { + "balance": "0x6c6b935b8bbd400000" + }, + "5dff811dad819ece3ba602c383fb5dc64c0a3a48": { + "balance": "0xa1544be879ea80000" + }, + "5e031b0a724471d476f3bcd2eb078338bf67fbef": { + "balance": "0xfc936392801c0000" + }, + "5e0785532c7723e4c0af9357d5274b73bdddddde": { + "balance": "0x54b41ea9bdb61dc0000" + }, + "5e11ecf69d551d7f4f84df128046b3a13240a328": { + "balance": "0x1158e460913d00000" + }, + "5e1fbd4e58e2312b3c78d7aaaafa10bf9c3189e3": { + "balance": "0x878678326eac9000000" + }, + "5e32c72191b8392c55f510d8e3326e3a60501d62": { + "balance": "0x9513ea9de0243800000" + }, + "5e51b8a3bb09d303ea7c86051582fd600fb3dc1a": { + "balance": "0x1158e460913d00000" + }, + "5e58e255fc19870a04305ff2a04631f2ff294bb1": { + "balance": "0xf43fc2c04ee00000" + }, + "5e5a441974a83d74c687ebdc633fb1a49e7b1ad7": { + "balance": "0xa2a15d09519be00000" + }, + "5e65458be964ae449f71773704979766f8898761": { + "balance": "0x1ca7cc735b6f7c0000" + }, + "5e67df8969101adabd91accd6bb1991274af8df2": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5e6e9747e162f8b45c656e0f6cae7a84bac80e4e": { + "balance": "0x6c6b935b8bbd400000" + }, + "5e731b55ced452bb3f3fe871ddc3ed7ee6510a8f": { + "balance": "0xa2a15d09519be00000" + }, + "5e74ed80e9655788e1bb269752319667fe754e5a": { + "balance": "0x30927f74c9de00000" + }, + "5e772e27f28800c50dda973bb33e10762e6eea20": { + "balance": "0x61093d7c2c6d380000" + }, + "5e7b8c54dc57b0402062719dee7ef5e37ea35d62": { + "balance": "0x9bf9810fd05c840000" + }, + "5e7f70378775589fc66a81d3f653e954f55560eb": { + "balance": "0x83f289181d84c80000" + }, + "5e806e845730f8073e6cc9018ee90f5c05f909a3": { + "balance": "0x201e96dacceaf200000" + }, + "5e8e4df18cf0af770978a8df8dac90931510a679": { + "balance": "0x6c6b935b8bbd400000" + }, + "5e90c85877198756b0366c0e17b28e52b446505a": { + "balance": "0x144a4a18efeb680000" + }, + "5e95fe5ffcf998f9f9ac0e9a81dab83ead77003d": { + "balance": "0x1d42c20d32797f0000" + }, + "5ead29037a12896478b1296ab714e9cb95428c81": { + "balance": "0x3e043072d406e0000" + }, + "5eb371c407406c427b3b7de271ad3c1e04269579": { + "balance": "0xa2a15d09519be00000" + }, + "5ecdbaeab9106ffe5d7b519696609a05baeb85ad": { + "balance": "0x1158e460913d00000" + }, + "5ed0d6338559ef44dc7a61edeb893fa5d83fa1b5": { + "balance": "0xbed1d0263d9f00000" + }, + "5ed3bbc05240e0d399eb6ddfe60f62de4d9509af": { + "balance": "0x2914c02475f9d6d30000" + }, + "5ed3f1ebe2ae6756b5d8dc19cad02c419aa5778b": { "balance": "0x0" }, + "5ed56115bd6505a88273df5c56839470d24a2db7": { + "balance": "0x38e6591ee56668000" + }, + "5ef8c96186b37984cbfe04c598406e3b0ac3171f": { + "balance": "0x1fd933494aa5fe00000" + }, + "5efbdfe5389999633c26605a5bfc2c1bb5959393": { + "balance": "0x3c057c95cd9080000" + }, + "5f13154631466dcb1353c890932a7c97e0878e90": { + "balance": "0x14542ba12a337c00000" + }, + "5f167aa242bc4c189adecb3ac4a7c452cf192fcf": { + "balance": "0x6c6b4c4da6ddbe0000" + }, + "5f1c8a04c90d735b8a152909aeae636fb0ce1665": { + "balance": "0x17b7827618c5a370000" + }, + "5f23ba1f37a96c45bc490259538a54c28ba3b0d5": { + "balance": "0x410d586a20a4c00000" + }, + "5f26cf34599bc36ea67b9e7a9f9b4330c9d542a3": { + "balance": "0x3635c9adc5dea00000" + }, + "5f29c9de765dde25852af07d33f2ce468fd20982": { + "balance": "0x6c6b935b8bbd400000" + }, + "5f2f07d2d697e8c567fcfdfe020f49f360be2139": { + "balance": "0x6c6b935b8bbd400000" + }, + "5f321b3daaa296cadf29439f9dab062a4bffedd6": { + "balance": "0x47025903ea7ae0000" + }, + "5f333a3b2310765a0d1832b9be4c0a03704c1c09": { + "balance": "0x3635c9adc5dea00000" + }, + "5f344b01c7191a32d0762ac188f0ec2dd460911d": { + "balance": "0x3635c9adc5dea00000" + }, + "5f363e0ab747e02d1b3b66abb69ea53c7baf523a": { + "balance": "0x277017338a30ae00000" + }, + "5f375b86600c40cca8b2676b7a1a1d1644c5f52c": { + "balance": "0x44618d74c623f0000" + }, + "5f3e1e6739b0c62200e00a003691d9efb238d89f": { + "balance": "0xa2a15d09519be00000" + }, + "5f483ffb8f680aedf2a38f7833afdcde59b61e4b": { + "balance": "0x6c6b935b8bbd400000" + }, + "5f4ace4c1cc13391e01f00b198e1f20b5f91cbf5": { + "balance": "0x10f0fa8b9d3811a0000" + }, + "5f521282e9b278dc8c034c72af53ee29e5443d78": { + "balance": "0x161732d2f8f3ae00000" + }, + "5f68a24c7eb4117667737b33393fb3c2148a53b6": { + "balance": "0x2cede918d453c0000" + }, + "5f708eaf39d823946c51b3a3e9b7b3c003e26341": { + "balance": "0x62a992e53a0af00000" + }, + "5f742e487e3ab81af2f94afdbe1b9b8f5ccc81bc": { + "balance": "0x75c445d41163e60000" + }, + "5f74ed0e24ff80d9b2c4a44baa9975428cd6b935": { + "balance": "0xa18bcec34888100000" + }, + "5f76f0a306269c78306b3d650dc3e9c37084db61": { + "balance": "0x821ab0d44149800000" + }, + "5f77a107ab1226b3f95f10ee83aefc6c5dff3edc": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "5f7b3bbac16dab831a4a0fc53b0c549dc36c31ca": { + "balance": "0x692ae8897081d00000" + }, + "5f93ff832774db5114c55bb4bf44ccf3b58f903f": { + "balance": "0x28a9c91a263458290000" + }, + "5f9616c47b4a67f406b95a14fe6fc268396f1721": { + "balance": "0xad78ebc5ac6200000" + }, + "5f981039fcf50225e2adf762752112d1cc26b6e3": { + "balance": "0x1b1a416a2153a50000" + }, + "5f99dc8e49e61d57daef606acdd91b4d7007326a": { + "balance": "0xa2a15d09519be00000" + }, + "5fa61f152de6123516c751242979285f796ac791": { + "balance": "0xb0f11972963b00000" + }, + "5fa7bfe043886127d4011d8356a47e947963aca8": { + "balance": "0x62a992e53a0af00000" + }, + "5fa8a54e68176c4fe2c01cf671c515bfbdd528a8": { + "balance": "0x45e155fa0110fa400000" + }, + "5fad960f6b2c84569c9f4d47bf1985fcb2c65da6": { + "balance": "0x36356633ebd8ea0000" + }, + "5fc6c11426b4a1eae7e51dd512ad1090c6f1a85b": { + "balance": "0x93fe5c57d710680000" + }, + "5fcd84546896dd081db1a320bd4d8c1dd1528c4c": { + "balance": "0x1158e460913d00000" + }, + "5fcda847aaf8d7fa8bca08029ca2849166aa15a3": { + "balance": "0x21cab81259a3bf0000" + }, + "5fd1c3e31778276cb42ea740f5eae9c641dbc701": { + "balance": "0xa844a7424d9c80000" + }, + "5fd3d6777ec2620ae83a05528ed425072d3ca8fd": { + "balance": "0x6c6b935b8bbd400000" + }, + "5fd973af366aa5157c54659bcfb27cbfa5ac15d6": { + "balance": "0xd8d726b7177a800000" + }, + "5fe77703808f823e6c399352108bdb2c527cb87c": { + "balance": "0x6a4076cf7995a00000" + }, + "5fec49c665e64ee89dd441ee74056e1f01e92870": { + "balance": "0x1569b9e733474c00000" + }, + "5ff326cd60fd136b245e29e9087a6ad3a6527f0d": { + "balance": "0x65ea3db75546600000" + }, + "5ff93de6ee054cad459b2d5eb0f6870389dfcb74": { + "balance": "0xbed1d0263d9f00000" + }, + "6006e36d929bf45d8f16231b126a011ae283d925": { + "balance": "0x98a7d9b8314c00000" + }, + "6021e85a8814fce1e82a41abd1d3b2dad2faefe0": { + "balance": "0x6c6b935b8bbd400000" + }, + "6038740ae28d66ba93b0be08482b3205a0f7a07b": { + "balance": "0x11216185c29f700000" + }, + "603f2fab7afb6e017b94766069a4b43b38964923": { + "balance": "0x59d2db2414da990000" + }, + "6042276df2983fe2bc4759dc1943e18fdbc34f77": { + "balance": "0x6acb3df27e1f880000" + }, + "6042c644bae2b96f25f94d31f678c90dc96690db": { + "balance": "0x6c6b935b8bbd400000" + }, + "604cdf18628dbfa8329194d478dd5201eecc4be7": { + "balance": "0x13f306a2409fc0000" + }, + "604e9477ebf4727c745bcabbedcb6ccf29994022": { + "balance": "0x36369ed7747d260000" + }, + "60676d1fa21fca052297e24bf96389c5b12a70d7": { + "balance": "0xd177c5a7a68d60000" + }, + "60676e92d18b000509c61de540e6c5ddb676d509": { + "balance": "0x410d586a20a4c00000" + }, + "606f177121f7855c21a5062330c8762264a97b31": { + "balance": "0xd8d726b7177a800000" + }, + "60864236930d04d8402b5dcbeb807f3caf611ea2": { + "balance": "0xd8d726b7177a800000" + }, + "60ab71cd26ea6d6e59a7a0f627ee079c885ebbf6": { + "balance": "0x1731790534df20000" + }, + "60af0ee118443c9b37d2fead77f5e521debe1573": { + "balance": "0x678a932062e4180000" + }, + "60b358cb3dbefa37f47df2d7365840da8e3bc98c": { + "balance": "0x1158e460913d00000" + }, + "60b8d6b73b79534fb08bb8cbcefac7f393c57bfe": { + "balance": "0x5f68e8131ecf800000" + }, + "60be6f953f2a4d25b6256ffd2423ac1438252e4e": { + "balance": "0x821ab0d4414980000" + }, + "60c3714fdddb634659e4a2b1ea42c4728cc7b8ba": { + "balance": "0xb98bc829a6f90000" + }, + "60cc3d445ebdf76a7d7ae571c6971dff68cc8585": { + "balance": "0x3635c9adc5dea00000" + }, + "60d5667140d12614b21c8e5e8a33082e32dfcf23": { + "balance": "0x43c33c1937564800000" + }, + "60de22a1507432a47b01cc68c52a0bf8a2e0d098": { + "balance": "0x10910d4cdc9f60000" + }, + "60e0bdd0a259bb9cb09d3f37e5cd8b9daceabf8a": { + "balance": "0x4a4491bd6dcd280000" + }, + "60e3cc43bcdb026aad759c7066f555bbf2ac66f5": { + "balance": "0x6c6b935b8bbd400000" + }, + "61042b80fd6095d1b87be2f00f109fabafd157a6": { + "balance": "0x56bc75e2d63100000" + }, + "6107d71dd6d0eefb11d4c916404cb98c753e117d": { + "balance": "0x6c6b935b8bbd400000" + }, + "610fd6ee4eebab10a8c55d0b4bd2e7d6ef817156": { + "balance": "0x1159561065d5d0000" + }, + "6114b0eae5576903f80bfb98842d24ed92237f1e": { + "balance": "0x56bc75e2d63100000" + }, + "6121af398a5b2da69f65c6381aec88ce9cc6441f": { + "balance": "0x22b1c8c1227a000000" + }, + "612667f172135b950b2cd1de10afdece6857b873": { + "balance": "0x3635c9adc5dea00000" + }, + "612ced8dc0dc9e899ee46f7962333315f3f55e44": { + "balance": "0x125e35f9cd3d9b0000" + }, + "6134d942f037f2cc3d424a230c603d67abd3edf7": { + "balance": "0x6c6b935b8bbd400000" + }, + "613ac53be565d46536b820715b9b8d3ae68a4b95": { + "balance": "0xcbd47b6eaa8cc00000" + }, + "613fab44b16bbe554d44afd178ab1d02f37aeaa5": { + "balance": "0x6c6b935b8bbd400000" + }, + "614e8bef3dd2c59b59a4145674401018351884ea": { + "balance": "0x1158e460913d00000" + }, + "61518464fdd8b73c1bb6ac6db600654938dbf17a": { + "balance": "0xad78ebc5ac6200000" + }, + "61547d376e5369bcf978fc162c3c56ae453547e8": { + "balance": "0xad78ebc5ac6200000" + }, + "6158e107c5eb54cb7604e0cd8dc1e07500d91c3c": { + "balance": "0x2b5e3af16b1880000" + }, + "615a6f36777f40d6617eb5819896186983fd3731": { + "balance": "0x14061b9d77a5e980000" + }, + "615f82365c5101f071e7d2cb6af14f7aad2c16c6": { + "balance": "0x1158e460913d00000" + }, + "6170dd0687bd55ca88b87adef51cfdc55c4dd458": { + "balance": "0x6cb32f5c34fe440000" + }, + "61733947fab820dbd351efd67855ea0e881373a0": { + "balance": "0x1158e460913d00000" + }, + "6179979907fe7f037e4c38029d60bcbab832b3d6": { + "balance": "0x57473d05dabae80000" + }, + "617f20894fa70e94a86a49cd74e03238f64d3cd9": { + "balance": "0x10f0dbae61009528000" + }, + "617ff2cc803e31c9082233b825d025be3f7b1056": { + "balance": "0x6acb3df27e1f880000" + }, + "6191ddc9b64a8e0890b4323709d7a07c48b92a64": { + "balance": "0x2a034919dfbfbc0000" + }, + "6196c3d3c0908d254366b7bca55745222d9d4db1": { + "balance": "0xd8d726b7177a800000" + }, + "619f171445d42b02e2e07004ad8afe694fa53d6a": { + "balance": "0x1158e460913d00000" + }, + "61adf5929a5e2981684ea243baa01f7d1f5e148a": { + "balance": "0x5fabf6c984f230000" + }, + "61b1b8c012cd4c78f698e470f90256e6a30f48dd": { + "balance": "0xad78ebc5ac6200000" + }, + "61b3df2e9e9fd968131f1e88f0a0eb5bd765464d": { + "balance": "0xd8d726b7177a800000" + }, + "61b902c5a673885826820d1fe14549e4865fbdc2": { + "balance": "0x1224efed2ae1918000" + }, + "61b905de663fc17386523b3a28e2f7d037a655cd": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "61ba87c77e9b596de7ba0e326fddfeec2163ef66": { + "balance": "0xad78ebc5ac6200000" + }, + "61bf84d5ab026f58c873f86ff0dfca82b55733ae": { + "balance": "0x6c6b935b8bbd400000" + }, + "61c4ee7c864c4d6b5e37ea1331c203739e826b2f": { + "balance": "0x1a1353b382a918000" + }, + "61c830f1654718f075ccaba316faacb85b7d120b": { + "balance": "0x15af1d78b58c400000" + }, + "61c8f1fa43bf846999ecf47b2b324dfb6b63fe3a": { + "balance": "0x2b5e3af16b18800000" + }, + "61c9dce8b2981cb40e98b0402bc3eb28348f03ac": { + "balance": "0xaacacd9b9e22b0000" + }, + "61cea71fa464d62a07063f920b0cc917539733d8": { + "balance": "0x5a87e7d7f5f6580000" + }, + "61d101a033ee0e2ebb3100ede766df1ad0244954": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "61ed5596c697207f3d55b2a51aa7d50f07fa09e8": { + "balance": "0x6c6b935b8bbd400000" + }, + "61ff8e67b34d9ee6f78eb36ffea1b9f7c15787af": { + "balance": "0x58e7926ee858a00000" + }, + "6205c2d5647470848a3840f3887e9b015d34755c": { + "balance": "0x6194049f30f7200000" + }, + "6228ade95e8bb17d1ae23bfb0518414d497e0eb8": { + "balance": "0x15af1d78b58c400000" + }, + "6229dcc203b1edccfdf06e87910c452a1f4d7a72": { + "balance": "0x6e1d41a8f9ec3500000" + }, + "622be4b45495fcd93143efc412d699d6cdc23dc5": { + "balance": "0xf015f25736420000" + }, + "62331df2a3cbee3520e911dea9f73e905f892505": { + "balance": "0x6c6b935b8bbd400000" + }, + "625644c95a873ef8c06cdb9e9f6d8d7680043d62": { + "balance": "0x6194049f30f7200000" + }, + "6265b2e7730f36b776b52d0c9d02ada55d8e3cb6": { + "balance": "0x3635c9adc5dea00000" + }, + "62680a15f8ccb8bdc02f7360c25ad8cfb57b8ccd": { + "balance": "0x3635c9adc5dea00000" + }, + "6294eae6e420a3d5600a39c4141f838ff8e7cc48": { + "balance": "0xa030dcebbd2f4c0000" + }, + "62971bf2634cee0be3c9890f51a56099dbb9519b": { + "balance": "0x238fd42c5cf0400000" + }, + "629be7ab126a5398edd6da9f18447e78c692a4fd": { + "balance": "0x6c6b935b8bbd400000" + }, + "62b4a9226e61683c72c183254690daf511b4117a": { + "balance": "0xe18398e7601900000" + }, + "62b9081e7710345e38e02e16449ace1b85bcfc4e": { + "balance": "0x3154c9729d05780000" + }, + "62c37c52b97f4b040b1aa391d6dec152893c4707": { + "balance": "0x3635c9adc5dea00000" + }, + "62c9b271ffd5b770a5eee4edc9787b5cdc709714": { + "balance": "0x6c6b935b8bbd400000" + }, + "62d5cc7117e18500ac2f9e3c26c86b0a94b0de15": { + "balance": "0x5b12aefafa8040000" + }, + "62dc72729024375fc37cbb9c7c2393d10233330f": { + "balance": "0x6c6b935b8bbd400000" + }, + "62e6b2f5eb94fa7a43831fc87e254a3fe3bf8f89": { + "balance": "0xd8d726b7177a80000" + }, + "62f2e5ccecd52cc4b95e0597df27cc079715608c": { + "balance": "0x7c0860e5a80dc0000" + }, + "62fb8bd1f0e66b90533e071e6cbe6111fef0bc63": { + "balance": "0x3ba1910bf341b000000" + }, + "630a913a9031c9492abd4c41dbb15054cfec4416": { + "balance": "0x13458db67af35e00000" + }, + "630c5273126d517ce67101811cab16b8534cf9a8": { + "balance": "0x1feccc62573bbd38000" + }, + "631030a5b27b07288a45696f189e1114f12a81c0": { + "balance": "0x1b1a7a420ba00d0000" + }, + "6310b020fd98044957995092090f17f04e52cdfd": { + "balance": "0x55a6e79ccd1d300000" + }, + "632b9149d70178a7333634275e82d5953f27967b": { + "balance": "0x25f273933db5700000" + }, + "632cecb10cfcf38ec986b43b8770adece9200221": { + "balance": "0x1158e460913d00000" + }, + "6331028cbb5a21485bc51b565142993bdb2582a9": { + "balance": "0x1cfdd7468216e80000" + }, + "63334fcf1745840e4b094a3bb40bb76f9604c04c": { + "balance": "0xd7a5d703a717e80000" + }, + "63340a57716bfa63eb6cd133721202575bf796f0": { + "balance": "0xb61e0a20c12718000" + }, + "634efc24371107b4cbf03f79a93dfd93e431d5fd": { + "balance": "0x423582e08edc5c8000" + }, + "635c00fdf035bca15fa3610df3384e0fb79068b1": { + "balance": "0x1e7e4171bf4d3a00000" + }, + "63612e7862c27b587cfb6daf9912cb051f030a9f": { + "balance": "0x25b19d4bfe8ed0000" + }, + "63666755bd41b5986997783c13043008242b3cb5": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "637be71b3aa815ff453d5642f73074450b64c82a": { + "balance": "0x6c6b935b8bbd400000" + }, + "637d67d87f586f0a5a479e20ee13ea310a10b647": { + "balance": "0xa3a5926afa1e7300000" + }, + "637f5869d6e4695f0eb9e27311c4878aff333380": { + "balance": "0x6ac04e68aaec860000" + }, + "63977cad7d0dcdc52b9ac9f2ffa136e8642882b8": { + "balance": "0x410d586a20a4c0000" + }, + "63a61dc30a8e3b30a763c4213c801cbf98738178": { + "balance": "0x3635c9adc5dea00000" + }, + "63ac545c991243fa18aec41d4f6f598e555015dc": { + "balance": "0x2086ac351052600000" + }, + "63b9754d75d12d384039ec69063c0be210d5e0e3": { + "balance": "0x920b860cc8ecfd8000" + }, + "63bb664f9117037628594da7e3c5089fd618b5b5": { + "balance": "0x1158e460913d00000" + }, + "63c2a3d235e5eeabd0d4a6afdb89d94627396495": { + "balance": "0x434ef05b9d84820000" + }, + "63c8dfde0b8e01dadc2e748c824cc0369df090b3": { + "balance": "0xd255d112e103a00000" + }, + "63d55ad99b9137fd1b20cc2b4f03d42cbaddf334": { + "balance": "0x15af1d78b58c400000" + }, + "63d80048877596e0c28489e650cd4ac180096a49": { + "balance": "0xf2dc7d47f15600000" + }, + "63e414603e80d4e5a0f5c18774204642258208e4": { + "balance": "0x10f0cf064dd59200000" + }, + "63e88e2e539ffb450386b4e46789b223f5476c45": { + "balance": "0x155170a778e25d00000" + }, + "63ef2fbc3daf5edaf4a295629ccf31bcdf4038e5": { + "balance": "0x4f2591f896a6500000" + }, + "63f0e5a752f79f67124eed633ad3fd2705a397d4": { + "balance": "0xd5967be4fc3f100000" + }, + "63f5b53d79bf2e411489526530223845fac6f601": { + "balance": "0x65a4da25d3016c00000" + }, + "63fc93001305adfbc9b85d29d9291a05f8f1410b": { + "balance": "0x3635c9adc5dea00000" + }, + "63fe6bcc4b8a9850abbe75803730c932251f145b": { + "balance": "0xfc936392801c0000" + }, + "6403d062549690c8e8b63eae41d6c109476e2588": { + "balance": "0x6c6b935b8bbd400000" + }, + "64042ba68b12d4c151651ca2813b7352bd56f08e": { + "balance": "0x2086ac351052600000" + }, + "6405dd13e93abcff377e700e3c1a0086eca27d29": { + "balance": "0xfc936392801c0000" + }, + "640aba6de984d94517377803705eaea7095f4a11": { + "balance": "0x21e19e0c9bab2400000" + }, + "640bf87415e0cf407301e5599a68366da09bbac8": { + "balance": "0x1abc9f416098158000" + }, + "6420f8bcc8164a6152a99d6b99693005ccf7e053": { + "balance": "0x36356633ebd8ea0000" + }, + "64241a7844290e0ab855f1d4aa75b55345032224": { + "balance": "0x56bc75e2d631000000" + }, + "64264aedd52dcae918a012fbcd0c030ee6f71821": { + "balance": "0x3635c9adc5dea00000" + }, + "64370e87202645125a35b207af1231fb6072f9a7": { + "balance": "0xad78ebc5ac6200000" + }, + "643d9aeed4b180947ed2b9207cce4c3ddc55e1f7": { + "balance": "0xad78ebc5ac6200000" + }, + "6443b8ae639de91cf73c5ae763eeeed3ddbb9253": { + "balance": "0x6c6b935b8bbd400000" + }, + "64457fa33b0832506c4f7d1180dce48f46f3e0ff": { + "balance": "0x6c6b935b8bbd400000" + }, + "64464a6805b462412a901d2db8174b06c22deea6": { + "balance": "0x19c846a029c7c80000" + }, + "644ba6c61082e989109f5c11d4b40e991660d403": { + "balance": "0xd8d726b7177a800000" + }, + "64628c6fb8ec743adbd87ce5e018d531d9210437": { + "balance": "0x1731790534df20000" + }, + "6463f715d594a1a4ace4bb9c3b288a74decf294d": { + "balance": "0x6acb3df27e1f880000" + }, + "646628a53c2c4193da88359ce718dadd92b7a48d": { + "balance": "0xad8006c2f5ef00000" + }, + "64672da3ab052821a0243d1ce4b6e0a36517b8eb": { + "balance": "0xad78ebc5ac6200000" + }, + "646afba71d849e80c0ed59cac519b278e7f7abe4": { + "balance": "0x3635c9adc5dea00000" + }, + "646e043d0597a664948fbb0dc15475a3a4f3a6ed": { + "balance": "0x1158e460913d00000" + }, + "6470a4f92ec6b0fccd01234fa59023e9ff1f3aac": { + "balance": "0xa2a15d09519be00000" + }, + "647b85044df2cf0b4ed4882e88819fe22ae5f793": { + "balance": "0x36363b5d9a77700000" + }, + "6485470e61db110aebdbafd536769e3c599cc908": { + "balance": "0x2086ac351052600000" + }, + "648f5bd2a2ae8902db37847d1cb0db9390b06248": { + "balance": "0x1a535ecf0760a048000" + }, + "649a2b9879cd8fb736e6703b0c7747849796f10f": { + "balance": "0x18ee22da01ad34f0000" + }, + "649a85b93653075fa6562c409a565d087ba3e1ba": { + "balance": "0x6c6b935b8bbd400000" + }, + "64adcceec53dd9d9dd15c8cc1a9e736de4241d2c": { + "balance": "0x30927f74c9de00000" + }, + "64cf0935bf19d2cebbecd8780d27d2e2b2c34166": { + "balance": "0x6acb3df27e1f880000" + }, + "64d80c3b8ba68282290b75e65d8978a15a87782c": { + "balance": "0x6acb3df27e1f880000" + }, + "64dba2d6615b8bd7571836dc75bc79d314f5ecee": { + "balance": "0x21e19e0c9bab2400000" + }, + "64e0217a5b38aa40583625967fa9883690388b6f": { + "balance": "0xad78ebc5ac6200000" + }, + "64e02abb016cc23a2934f6bcddb681905021d563": { + "balance": "0x3635c9adc5dea00000" + }, + "64e03ef070a54703b7184e48276c5c0077ef4b34": { + "balance": "0x1158e460913d000000" + }, + "64e2de21200b1899c3a0c0653b5040136d0dc842": { + "balance": "0x43c33c1937564800000" + }, + "64ec8a5b743f3479e707dae9ee20ddaa4f40f1d9": { + "balance": "0xad78ebc5ac6200000" + }, + "6503860b191008c15583bfc88158099301762828": { + "balance": "0x3635c9adc5dea00000" + }, + "65053191319e067a25e6361d47f37f6318f83419": { + "balance": "0x155bd9307f9fe80000" + }, + "65093b239bbfba23c7775ca7da5a8648a9f54cf7": { + "balance": "0x15af1d78b58c400000" + }, + "6509eeb1347e842ffb413e37155e2cbc738273fd": { + "balance": "0x6c6b935b8bbd400000" + }, + "650b425555e4e4c51718146836a2c1ee77a5b421": { + "balance": "0x43c33c1937564800000" + }, + "650cf67db060cce17568d5f2a423687c49647609": { + "balance": "0x56bc75e2d63100000" + }, + "6510df42a599bcb0a519cca961b488759a6f6777": { + "balance": "0x6c6b935b8bbd400000" + }, + "653675b842d7d8b461f722b4117cb81dac8e639d": { + "balance": "0x1ae361fc1451c0000" + }, + "654b7e808799a83d7287c67706f2abf49a496404": { + "balance": "0x6acb3df27e1f880000" + }, + "654f524847b3a6acc0d3d5f1f362b603edf65f96": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "655934da8e744eaa3de34dbbc0894c4eda0b61f2": { + "balance": "0xad78ebc5ac6200000" + }, + "655d5cd7489629e2413c2105b5a172d933c27af8": { + "balance": "0xdb03186cd840a60000" + }, + "656018584130db83ab0591a8128d9381666a8d0e": { + "balance": "0x3779f912019fc0000" + }, + "6560941328ff587cbc56c38c78238a7bb5f442f6": { + "balance": "0x2861906b59c47a0000" + }, + "656579daedd29370d9b737ee3f5cd9d84bc2b342": { + "balance": "0x4d853c8f8908980000" + }, + "657473774f63ac3d6279fd0743d5790c4f161503": { + "balance": "0xad78ebc5ac6200000" + }, + "6580b1bc94390f04b397bd73e95d96ef11eaf3a8": { + "balance": "0x1158e460913d00000" + }, + "65849be1af20100eb8a3ba5a5be4d3ae8db5a70e": { + "balance": "0x15af1d78b58c400000" + }, + "659c0a72c767a3a65ced0e1ca885a4c51fd9b779": { + "balance": "0x6c6b935b8bbd400000" + }, + "65a52141f56bef98991724c6e7053381da8b5925": { + "balance": "0x3429c335d57fe0000" + }, + "65a9dad42e1632ba3e4e49623fab62a17e4d3611": { + "balance": "0x50c4cb2a10c600000" + }, + "65af8d8b5b1d1eedfa77bcbc96c1b133f83306df": { + "balance": "0x55005f0c614480000" + }, + "65af9087e05167715497c9a5a749189489004def": { + "balance": "0x2d43f3ebfafb2c0000" + }, + "65b42faecc1edfb14283ca979af545f63b30e60c": { + "balance": "0xfc936392801c0000" + }, + "65d33eb39cda6453b19e61c1fe4db93170ef9d34": { + "balance": "0xb98bc829a6f90000" + }, + "65d8dd4e251cbc021f05b010f2d5dc520c3872e0": { + "balance": "0x2d43579a36a90e0000" + }, + "65ea26eabbe2f64ccccfe06829c25d4637520225": { + "balance": "0x25f273933db5700000" + }, + "65ea67ad3fb56ad5fb94387dd38eb383001d7c68": { + "balance": "0x56bc75e2d63100000" + }, + "65ebaed27edb9dcc1957aee5f452ac2105a65c0e": { + "balance": "0x937dfadae25e29b8000" + }, + "65ee20b06d9ad589a7e7ce04b9f5f795f402aece": { + "balance": "0x6c6b935b8bbd400000" + }, + "65f534346d2ffb787fa9cf185d745ba42986bd6e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "65f5870f26bce089677dfc23b5001ee492483428": { + "balance": "0x112b1f155aa32a30000" + }, + "65fd02d704a12a4dace9471b0645f962a89671c8": { + "balance": "0x18d1ce6e427cd8000" + }, + "65ff874fafce4da318d6c93d57e2c38a0d73e820": { + "balance": "0x3638021cecdab00000" + }, + "660557bb43f4be3a1b8b85e7df7b3c5bcd548057": { + "balance": "0x14542ba12a337c00000" + }, + "66082c75a8de31a53913bbd44de3a0374f7faa41": { + "balance": "0x4f2591f896a6500000" + }, + "6611ce59a98b072ae959dc49ad511daaaaa19d6b": { + "balance": "0xad78ebc5ac6200000" + }, + "66201bd227ae6dc6bdfed5fbde811fecfe5e9dd9": { + "balance": "0x203e9e8492788c0000" + }, + "662334814724935b7931ddca6100e00d467727cd": { + "balance": "0x2288269d0783d40000" + }, + "66274fea82cd30b6c29b23350e4f4f3d310a5899": { + "balance": "0x70370550ab82980000" + }, + "662cfa038fab37a01745a364e1b98127c503746d": { + "balance": "0xd5967be4fc3f100000" + }, + "6635b46f711d2da6f0e16370cd8ee43efb2c2d52": { + "balance": "0x6c6b935b8bbd400000" + }, + "663604b0503046e624cd26a8b6fb4742dce02a6f": { + "balance": "0x38b9b797ef68c0000" + }, + "6636d7ac637a48f61d38b14cfd4865d36d142805": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "6640ccf053555c130ae2b656647ea6e31637b9ab": { + "balance": "0x6acb3df27e1f880000" + }, + "66424bd8785b8cb461102a900283c35dfa07ef6a": { + "balance": "0x22e2db26666fc8000" + }, + "664cd67dccc9ac8228b45c55db8d76550b659cdc": { + "balance": "0x155bd9307f9fe80000" + }, + "664e43119870af107a448db1278b044838ffcdaf": { + "balance": "0x15af1d78b58c400000" + }, + "6651736fb59b91fee9c93aa0bd6ea2f7b2506180": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "665b000f0b772750cc3c217a5ef429a92bf1ccbb": { + "balance": "0xd8d726b7177a800000" + }, + "66662006015c1f8e3ccfcaebc8ee6807ee196303": { + "balance": "0x1b1b3a1ac261ec0000" + }, + "666746fb93d1935c5a3c684e725010c4fad0b1d8": { + "balance": "0x1158e460913d00000" + }, + "666b4f37d55d63b7d056b615bb74c96b3b01991a": { + "balance": "0xd8d726b7177a800000" + }, + "66719c0682b2ac7f9e27abebec7edf8decf0ae0d": { + "balance": "0x1158e460913d00000" + }, + "6671b182c9f741a0cd3c356c73c23126d4f9e6f4": { + "balance": "0xad78ebc5ac6200000" + }, + "6679aeecd87a57a73f3356811d2cf49d0c4d96dc": { + "balance": "0x2086ac351052600000" + }, + "667b61c03bb937a9f5d0fc5a09f1ea3363c77035": { + "balance": "0xe664992288f2280000" + }, + "6685fd2e2544702c360b8bb9ee78f130dad16da5": { + "balance": "0x6c6b935b8bbd400000" + }, + "668b6ba8ab08eace39c502ef672bd5ccb6a67a20": { + "balance": "0x697d95d4201333c0000" + }, + "66925de3e43f4b41bf9dadde27d5488ef569ea0d": { + "balance": "0x222c8eb3ff6640000" + }, + "66b0c100c49149935d14c0dc202cce907cea1a3d": { + "balance": "0x6acb3df27e1f880000" + }, + "66b1a63da4dcd9f81fe54f5e3fcb4055ef7ec54f": { + "balance": "0xaeb272adf9cfa0000" + }, + "66b39837cb3cac8a802afe3f12a258bbca62dacd": { + "balance": "0x15af1d78b58c400000" + }, + "66c8331efe7198e98b2d32b938688e3241d0e24f": { + "balance": "0x2098051970e39d00000" + }, + "66cc8ab23c00d1b82acd7d73f38c99e0d05a4fa6": { + "balance": "0x56bc75e2d63100000" + }, + "66dcc5fb4ee7fee046e141819aa968799d644491": { + "balance": "0x487a9a304539440000" + }, + "66e09427c1e63deed7e12b8c55a6a19320ef4b6a": { + "balance": "0x93739534d28680000" + }, + "66ec16ee9caab411c55a6629e318de6ee216491d": { + "balance": "0x2ee449550898e40000" + }, + "66f50406eb1b11a946cab45927cca37470e5a208": { + "balance": "0x6c6b935b8bbd400000" + }, + "66fdc9fee351fa1538eb0d87d819fcf09e7c106a": { + "balance": "0x14627b5d93781b20000" + }, + "67048f3a12a4dd1f626c64264cb1d7971de2ca38": { + "balance": "0x9c2007651b2500000" + }, + "6704f169e0d0b36b57bbc39f3c45437b5ee3d28d": { + "balance": "0x155bd9307f9fe80000" + }, + "671015b97670b10d5e583f3d62a61c1c79c5143f": { + "balance": "0x15af1d78b58c400000" + }, + "6710c2c03c65992b2e774be52d3ab4a6ba217ef7": { + "balance": "0x274d656ac90e3400000" + }, + "671110d96aaff11523cc546bf9940eedffb2faf7": { + "balance": "0xd8d726b7177a800000" + }, + "6715c14035fb57bb3d667f7b707498c41074b855": { + "balance": "0x25f273933db5700000" + }, + "671bbca099ff899bab07ea1cf86965c3054c8960": { + "balance": "0x2b5e3af16b1880000" + }, + "6727daf5b9d68efcab489fedec96d7f7325dd423": { + "balance": "0x6c6b935b8bbd400000" + }, + "672cbca8440a8577097b19aff593a2ad9d28a756": { + "balance": "0x4563918244f400000" + }, + "672ec42faa8cd69aaa71b32cc7b404881d52ff91": { + "balance": "0x21e19e0c9bab2400000" + }, + "672fa0a019088db3166f6119438d07a99f8ba224": { + "balance": "0x2d4ca05e2b43ca80000" + }, + "673144f0ec142e770f4834fee0ee311832f3087b": { + "balance": "0x1b1b6bd7af64c70000" + }, + "67350b5331926f5e28f3c1e986f96443809c8b8c": { + "balance": "0x1314fb370629800000" + }, + "673706b1b0e4dc7a949a7a796258a5b83bb5aa83": { + "balance": "0x368c8623a8b4d100000" + }, + "6742a2cfce8d79a2c4a51b77747498912245cd6a": { + "balance": "0xdfd5b80b7e4680000" + }, + "674adb21df4c98c7a347ac4c3c24266757dd7039": { + "balance": "0x6c6b935b8bbd400000" + }, + "67518e5d02b205180f0463a32004471f753c523e": { + "balance": "0x6b918aac494b168000" + }, + "675d5caa609bf70a18aca580465d8fb7310d1bbb": { + "balance": "0x43c33c1937564800000" + }, + "67632046dcb25a54936928a96f423f3320cbed92": { + "balance": "0x6c6b935b8bbd400000" + }, + "6765df25280e8e4f38d4b1cf446fc5d7eb659e34": { + "balance": "0x56bc75e2d63100000" + }, + "6776e133d9dc354c12a951087b639650f539a433": { + "balance": "0x68155a43676e00000" + }, + "6785513cf732e47e87670770b5419be10cd1fc74": { + "balance": "0x6c6b935b8bbd400000" + }, + "679437eacf437878dc293d48a39c87b7421a216c": { + "balance": "0x37f81821db2680000" + }, + "679b9a109930517e8999099ccf2a914c4c8dd934": { + "balance": "0x340aad21b3b700000" + }, + "67a80e0190721f94390d6802729dd12c31a895ad": { + "balance": "0x6c6b1375bc91560000" + }, + "67b8a6e90fdf0a1cac441793301e8750a9fa7957": { + "balance": "0x30849ebe16369c0000" + }, + "67bc85e87dc34c4e80aafa066ba8d29dbb8e438e": { + "balance": "0x15d1cf4176aeba0000" + }, + "67c926093e9b8927933810d98222d62e2b8206bb": { + "balance": "0x678a932062e4180000" + }, + "67cfda6e70bf7657d39059b59790e5145afdbe61": { + "balance": "0x23050d095866580000" + }, + "67d682a282ef73fb8d6e9071e2614f47ab1d0f5e": { + "balance": "0x3635c9adc5dea00000" + }, + "67d6a8aa1bf8d6eaf7384e993dfdf10f0af68a61": { + "balance": "0xabcbb5718974b8000" + }, + "67da922effa472a6b124e84ea8f86b24e0f515aa": { + "balance": "0x1158e460913d00000" + }, + "67df242d240dd4b8071d72f8fcf35bb3809d71e8": { + "balance": "0xd8d726b7177a800000" + }, + "67ee406ea4a7ae6a3a381eb4edd2f09f174b4928": { + "balance": "0x3829635f0968b00000" + }, + "67f2bb78b8d3e11f7c458a10b5c8e0a1d374467d": { + "balance": "0x61093d7c2c6d380000" + }, + "67fc527dce1785f0fb8bc7e518b1c669f7ecdfb5": { + "balance": "0xd02ab486cedc00000" + }, + "68027d19558ed7339a08aee8de3559be063ec2ea": { + "balance": "0x6c6b935b8bbd400000" + }, + "680640838bd07a447b168d6d923b90cf6c43cdca": { + "balance": "0x5dc892aa1131c80000" + }, + "6807ddc88db489b033e6b2f9a81553571ab3c805": { + "balance": "0x19f8e7559924c0000" + }, + "680d5911ed8dd9eec45c060c223f89a7f620bbd5": { + "balance": "0x43c33c1937564800000" + }, + "6811b54cd19663b11b94da1de2448285cd9f68d9": { + "balance": "0x3ba1910bf341b00000" + }, + "68190ca885da4231874c1cfb42b1580a21737f38": { + "balance": "0xcf152640c5c8300000" + }, + "682897bc4f8e89029120fcffb787c01a93e64184": { + "balance": "0x21e19e0c9bab2400000" + }, + "68295e8ea5afd9093fc0a465d157922b5d2ae234": { + "balance": "0x1154e53217ddb0000" + }, + "682e96276f518d31d7e56e30dfb009c1218201bd": { + "balance": "0x1158e460913d00000" + }, + "6835c8e8b74a2ca2ae3f4a8d0f6b954a3e2a8392": { + "balance": "0x3429c335d57fe0000" + }, + "683633010a88686bea5a98ea53e87997cbf73e69": { + "balance": "0x56b394263a40c0000" + }, + "683dba36f7e94f40ea6aea0d79b8f521de55076e": { + "balance": "0x796e3ea3f8ab00000" + }, + "68419c6dd2d3ce6fcbb3c73e2fa079f06051bde6": { + "balance": "0x6acb3df27e1f880000" + }, + "68473b7a7d965904bedba556dfbc17136cd5d434": { + "balance": "0x56bc75e2d63100000" + }, + "6847825bdee8240e28042c83cad642f286a3bddc": { + "balance": "0x5150ae84a8cdf00000" + }, + "684a44c069339d08e19a75668bdba303be855332": { + "balance": "0xed2b525841adfc00000" + }, + "68531f4dda808f5320767a03113428ca0ce2f389": { + "balance": "0x10d3aa536e2940000" + }, + "687927e3048bb5162ae7c15cf76bd124f9497b9e": { + "balance": "0x6c6b935b8bbd400000" + }, + "68809af5d532a11c1a4d6e32aac75c4c52b08ead": { + "balance": "0x21e19e0c9bab2400000" + }, + "6886ada7bbb0617bda842191c68c922ea3a8ac82": { + "balance": "0x3ee23bde0e7d200000" + }, + "68883e152e5660fee59626e7e3b4f05110e6222f": { + "balance": "0xb94633be975a62a0000" + }, + "688a569e965524eb1d0ac3d3733eab909fb3d61e": { + "balance": "0x478eae0e571ba00000" + }, + "688eb3853bbcc50ecfee0fa87f0ab693cabdef02": { + "balance": "0x6b10a18400647c00000" + }, + "68a7425fe09eb28cf86eb1793e41b211e57bd68d": { + "balance": "0x243d4d18229ca20000" + }, + "68a86c402388fddc59028fec7021e98cbf830eac": { + "balance": "0x10910d4cdc9f60000" + }, + "68acdaa9fb17d3c309911a77b05f5391fa034ee9": { + "balance": "0x1e52e336cde22180000" + }, + "68addf019d6b9cab70acb13f0b3117999f062e12": { + "balance": "0x2b51212e6b7c88000" + }, + "68b31836a30a016ada157b638ac15da73f18cfde": { + "balance": "0x168d28e3f00280000" + }, + "68b6854788a7c6496cdbf5f84b9ec5ef392b78bb": { + "balance": "0x42bf06b78ed3b500000" + }, + "68c08490c89bf0d6b6f320b1aca95c8312c00608": { + "balance": "0xd8d726b7177a800000" + }, + "68c7d1711b011a33f16f1f55b5c902cce970bdd7": { + "balance": "0x83d6c7aab63600000" + }, + "68c8791dc342c373769ea61fb7b510f251d32088": { + "balance": "0x3635c9adc5dea00000" + }, + "68df947c495bebaeb8e889b3f953d533874bf106": { + "balance": "0x1d9945ab2b03480000" + }, + "68e8022740f4af29eb48db32bcecddfd148d3de3": { + "balance": "0x3635c9adc5dea00000" + }, + "68ec79d5be7155716c40941c79d78d17de9ef803": { + "balance": "0x1b233877b5208c0000" + }, + "68eec1e288ac31b6eaba7e1fbd4f04ad579a6b5d": { + "balance": "0x6c6b935b8bbd400000" + }, + "68f525921dc11c329b754fbf3e529fc723c834cd": { + "balance": "0x57473d05dabae80000" + }, + "68f719ae342bd7fef18a05cbb02f705ad38ed5b2": { + "balance": "0x38ebad5cdc90280000" + }, + "68f7573cd457e14c03fea43e302d30347c10705c": { + "balance": "0x10f0cf064dd59200000" + }, + "68f8f45155e98c5029a4ebc5b527a92e9fa83120": { + "balance": "0xf07b44b40793208000" + }, + "68fe1357218d095849cd579842c4aa02ff888d93": { + "balance": "0x6c6b935b8bbd400000" + }, + "690228e4bb12a8d4b5e0a797b0c5cf2a7509131e": { + "balance": "0x65ea3db75546600000" + }, + "690594d306613cd3e2fd24bca9994ad98a3d73f8": { + "balance": "0x6c6b935b8bbd400000" + }, + "69073269729e6414b26ec8dc0fd935c73b579f1e": { + "balance": "0x65a4da25d3016c00000" + }, + "6919dd5e5dfb1afa404703b9faea8cee35d00d70": { + "balance": "0x14061b9d77a5e980000" + }, + "693492a5c51396a482881669ccf6d8d779f00951": { + "balance": "0x12bf50503ae3038000" + }, + "693d83be09459ef8390b2e30d7f7c28de4b4284e": { + "balance": "0x6c6b935b8bbd400000" + }, + "69517083e303d4fbb6c2114514215d69bc46a299": { + "balance": "0x56bc75e2d63100000" + }, + "695550656cbf90b75d92ad9122d90d23ca68ca4d": { + "balance": "0x3635c9adc5dea00000" + }, + "6958f83bb2fdfb27ce0409cd03f9c5edbf4cbedd": { + "balance": "0x43c33c1937564800000" + }, + "695b0f5242753701b264a67071a2dc880836b8db": { + "balance": "0xe398811bec680000" + }, + "695b4cce085856d9e1f9ff3e79942023359e5fbc": { + "balance": "0x10f0cf064dd59200000" + }, + "6966063aa5de1db5c671f3dd699d5abe213ee902": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "6974c8a414ceaefd3c2e4dfdbef430568d9a960b": { + "balance": "0x121ea68c114e510000" + }, + "6978696d5150a9a263513f8f74c696f8b1397cab": { + "balance": "0x167f482d3c5b1c00000" + }, + "69797bfb12c9bed682b91fbc593591d5e4023728": { + "balance": "0x21e19e0c9bab2400000" + }, + "697f55536bf85ada51841f0287623a9f0ed09a17": { + "balance": "0x21e19e0c9bab2400000" + }, + "6982fe8a867e93eb4a0bd051589399f2ec9a5292": { + "balance": "0x6c6b935b8bbd400000" + }, + "698a8a6f01f9ab682f637c7969be885f6c5302bf": { + "balance": "0x10d3aa536e2940000" + }, + "698ab9a2f33381e07c0c47433d0d21d6f336b127": { + "balance": "0x1158e460913d00000" + }, + "6994fb3231d7e41d491a9d68d1fa4cae2cc15960": { + "balance": "0xd8d726b7177a800000" + }, + "699c9ee47195511f35f862ca4c22fd35ae8ffbf4": { + "balance": "0x4563918244f400000" + }, + "699fc6d68a4775573c1dcdaec830fefd50397c4e": { + "balance": "0x340aad21b3b700000" + }, + "69af28b0746cac0da17084b9398c5e36bb3a0df2": { + "balance": "0x3677036edf0af60000" + }, + "69b80ed90f84834afa3ff82eb964703b560977d6": { + "balance": "0x1731790534df20000" + }, + "69b81d5981141ec7a7141060dfcf8f3599ffc63e": { + "balance": "0x10f0cf064dd59200000" + }, + "69bcfc1d43b4ba19de7b274bdffb35139412d3d7": { + "balance": "0x35659ef93f0fc40000" + }, + "69bd25ade1a3346c59c4e930db2a9d715ef0a27a": { + "balance": "0xd8d726b7177a800000" + }, + "69c08d744754de709ce96e15ae0d1d395b3a2263": { + "balance": "0x3635c9adc5dea00000" + }, + "69c2d835f13ee90580408e6a3283c8cca6a434a2": { + "balance": "0x238fd42c5cf0400000" + }, + "69c94e07c4a9be3384d95dfa3cb9290051873b7b": { + "balance": "0x3cb71f51fc5580000" + }, + "69cb3e2153998d86e5ee20c1fcd1a6baeeb2863f": { + "balance": "0xd8d726b7177a800000" + }, + "69d39d510889e552a396135bfcdb06e37e387633": { + "balance": "0xd8d726b7177a800000" + }, + "69d98f38a3ba3dbc01fa5c2c1427d862832f2f70": { + "balance": "0x152d02c7e14af6800000" + }, + "69e2e2e704307ccc5b5ca3f164fece2ea7b2e512": { + "balance": "0x17b7883c06916600000" + }, + "69ff429074cb9b6c63bc914284bce5f0c8fbf7d0": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "69ff8901b541763f817c5f2998f02dcfc1df2997": { + "balance": "0x22b1c8c1227a00000" + }, + "6a023af57d584d845e698736f130db9db40dfa9a": { + "balance": "0x55b201c8900980000" + }, + "6a04f5d53fc0f515be942b8f12a9cb7ab0f39778": { + "balance": "0xa9aab3459be1940000" + }, + "6a05b21c4f17f9d73f5fb2b0cb89ff5356a6cc7e": { + "balance": "0x5150ae84a8cdf00000" + }, + "6a0f056066c2d56628850273d7ecb7f8e6e9129e": { + "balance": "0x10f0d293cc7a5880000" + }, + "6a13d5e32c1fd26d7e91ff6e053160a89b2c8aad": { + "balance": "0x2e62f20a69be40000" + }, + "6a2e86469a5bf37cee82e88b4c3863895d28fcaf": { + "balance": "0x1c229266385bbc0000" + }, + "6a3694424c7cc6b8bcd9bccaba540cc1f5df18d7": { + "balance": "0x6c6b935b8bbd400000" + }, + "6a42ca971c6578d5ade295c3e7f4ad331dd3424e": { + "balance": "0x14542ba12a337c00000" + }, + "6a44af96b3f032ae641beb67f4b6c83342d37c5d": { + "balance": "0x19274b259f6540000" + }, + "6a4c8907b600248057b1e46354b19bdc859c991a": { + "balance": "0x1158e460913d00000" + }, + "6a514e6242f6b68c137e97fea1e78eb555a7e5f7": { + "balance": "0x1158e460913d00000" + }, + "6a53d41ae4a752b21abed5374649953a513de5e5": { + "balance": "0x6c6b935b8bbd400000" + }, + "6a6159074ab573e0ee581f0f3df2d6a594629b74": { + "balance": "0x10ce1d3d8cb3180000" + }, + "6a6337833f8f6a6bf10ca7ec21aa810ed444f4cb": { + "balance": "0x37bd24345ce8a40000" + }, + "6a6353b971589f18f2955cba28abe8acce6a5761": { + "balance": "0xa2a15d09519be00000" + }, + "6a63fc89abc7f36e282d80787b7b04afd6553e71": { + "balance": "0x8ac7230489e800000" + }, + "6a679e378fdce6bfd97fe62f043c6f6405d79e99": { + "balance": "0xd8d726b7177a800000" + }, + "6a686bf220b593deb9b7324615fb9144ded3f39d": { + "balance": "0x4f2591f896a6500000" + }, + "6a6b18a45a76467e2e5d5a2ef911c3e12929857b": { + "balance": "0x115d3a99a9614f400000" + }, + "6a74844d8e9cb5581c45079a2e94462a6cee8821": { + "balance": "0x3ab53a552dd4c90000" + }, + "6a7b2e0d88867ff15d207c222bebf94fa6ce8397": { + "balance": "0xcb49b44ba602d800000" + }, + "6a7c252042e7468a3ff773d6450bba85efa26391": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "6a8a4317c45faa0554ccdb482548183e295a24b9": { + "balance": "0x3635c9adc5dea00000" + }, + "6a8cea2de84a8df997fd3f84e3083d93de57cda9": { + "balance": "0x56be03ca3e47d8000" + }, + "6a9758743b603eea3aa0524b42889723c4153948": { + "balance": "0x22385a827e815500000" + }, + "6aa5732f3b86fb8c81efbe6b5b47b563730b06c8": { + "balance": "0x3635c9adc5dea00000" + }, + "6ab323ae5056ed0a453072c5abe2e42fcf5d7139": { + "balance": "0x2fb474098f67c00000" + }, + "6ab5b4c41cddb829690c2fda7f20c85e629dd5d5": { + "balance": "0x64d4af714c32900000" + }, + "6ac40f532dfee5118117d2ad352da77d4f6da2c8": { + "balance": "0x15af1d78b58c400000" + }, + "6ac4d4be2db0d99da3faaaf7525af282051d6a90": { + "balance": "0x458ca58a962b28000" + }, + "6acddca3cd2b4990e25cd65c24149d0912099e79": { + "balance": "0xa2a1e07c9f6c908000" + }, + "6ad90be252d9cd464d998125fab693060ba8e429": { + "balance": "0xd8d726b7177a800000" + }, + "6add932193cd38494aa3f03aeccc4b7ab7fabca2": { + "balance": "0x4db73254763000000" + }, + "6ae57f27917c562a132a4d1bf7ec0ac785832926": { + "balance": "0x14542ba12a337c00000" + }, + "6aeb9f74742ea491813dbbf0d6fcde1a131d4db3": { + "balance": "0x17e554308aa0300000" + }, + "6af235d2bbe050e6291615b71ca5829658810142": { + "balance": "0xa2a15d09519be00000" + }, + "6af6c7ee99df271ba15bf384c0b764adcb4da182": { + "balance": "0x36356633ebd8ea0000" + }, + "6af8e55969682c715f48ad4fc0fbb67eb59795a3": { + "balance": "0x6c6b935b8bbd400000" + }, + "6af940f63ec9b8d876272aca96fef65cdacecdea": { + "balance": "0xa2a15d09519be00000" + }, + "6af9f0dfeeaebb5f64bf91ab771669bf05295553": { + "balance": "0x15af1d78b58c400000" + }, + "6aff1466c2623675e3cb0e75e423d37a25e442eb": { + "balance": "0x5dc892aa1131c80000" + }, + "6b0da25af267d7836c226bcae8d872d2ce52c941": { + "balance": "0x14542ba12a337c00000" + }, + "6b10f8f8b3e3b60de90aa12d155f9ff5ffb22c50": { + "balance": "0x6c6b935b8bbd400000" + }, + "6b17598a8ef54f797ae515ccb6517d1859bf8011": { + "balance": "0x56bc75e2d63100000" + }, + "6b20c080606a79c73bd8e75b11717a4e8db3f1c3": { + "balance": "0x103f735803f0140000" + }, + "6b2284440221ce16a8382de5ff0229472269deec": { + "balance": "0x3635c9adc5dea00000" + }, + "6b30f1823910b86d3acb5a6afc9defb6f3a30bf8": { + "balance": "0xe3aeb5737240a00000" + }, + "6b38de841fad7f53fe02da115bd86aaf662466bd": { + "balance": "0x5dc892aa1131c80000" + }, + "6b4b99cb3fa9f7b74ce3a48317b1cd13090a1a7a": { + "balance": "0x31b327e695de20000" + }, + "6b5ae7bf78ec75e90cb503c778ccd3b24b4f1aaf": { + "balance": "0x2b5e3af16b18800000" + }, + "6b63a2dfb2bcd0caec0022b88be30c1451ea56aa": { + "balance": "0x2bdb6bf91f7f4c8000" + }, + "6b6577f3909a4d6de0f411522d4570386400345c": { + "balance": "0x65ea3db75546600000" + }, + "6b72a8f061cfe6996ad447d3c72c28c0c08ab3a7": { + "balance": "0xe78c6ac79912620000" + }, + "6b760d4877e6a627c1c967bee451a8507ddddbab": { + "balance": "0x3154c9729d05780000" + }, + "6b83bae7b565244558555bcf4ba8da2011891c17": { + "balance": "0x6c6b935b8bbd400000" + }, + "6b925dd5d8ed6132ab6d0860b82c44e1a51f1fee": { + "balance": "0x503b203e9fba200000" + }, + "6b94615db750656ac38c7e1cf29a9d13677f4e15": { + "balance": "0x28a857425466f800000" + }, + "6b951a43274eeafc8a0903b0af2ec92bf1efc839": { + "balance": "0x56bc75e2d63100000" + }, + "6b992521ec852370848ad697cc2df64e63cc06ff": { + "balance": "0x3635c9adc5dea00000" + }, + "6ba8f7e25fc2d871618e24e40184199137f9f6aa": { + "balance": "0x15af64869a6bc20000" + }, + "6ba9b21b35106be159d1c1c2657ac56cd29ffd44": { + "balance": "0xf2dc7d47f156000000" + }, + "6baf7a2a02ae78801e8904ad7ac05108fc56cff6": { + "balance": "0x3635c9adc5dea00000" + }, + "6bb2aca23fa1626d18efd6777fb97db02d8e0ae4": { + "balance": "0x878678326eac9000000" + }, + "6bb4a661a33a71d424d49bb5df28622ed4dffcf4": { + "balance": "0x222c8eb3ff66400000" + }, + "6bb50813146a9add42ee22038c9f1f7469d47f47": { + "balance": "0xada55474b81340000" + }, + "6bbc3f358a668dd1a11f0380f3f73108426abd4a": { + "balance": "0xd8d726b7177a800000" + }, + "6bbd1e719390e6b91043f8b6b9df898ea8001b34": { + "balance": "0x6c6c4fa6c3da588000" + }, + "6bc85acd5928722ef5095331ee88f484b8cf8357": { + "balance": "0x9c2007651b2500000" + }, + "6bd3e59f239fafe4776bb9bddd6bee83ba5d9d9f": { + "balance": "0x3635c9adc5dea00000" + }, + "6bd457ade051795df3f2465c3839aed3c5dee978": { + "balance": "0x3634bf39ab98788000" + }, + "6be16313643ebc91ff9bb1a2e116b854ea933a45": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "6be7595ea0f068489a2701ec4649158ddc43e178": { + "balance": "0x6c6b935b8bbd400000" + }, + "6be9030ee6e2fbc491aca3de4022d301772b7b7d": { + "balance": "0x1731790534df20000" + }, + "6bec311ad05008b4af353c958c40bd06739a3ff3": { + "balance": "0x377f62a0f0a62700000" + }, + "6bf7b3c065f2c1e7c6eb092ba0d15066f393d1b8": { + "balance": "0x15af1d78b58c400000" + }, + "6bf86f1e2f2b8032a95c4d7738a109d3d0ed8104": { + "balance": "0x62a992e53a0af00000" + }, + "6c05e34e5ef2f42ed09deff1026cd66bcb6960bb": { + "balance": "0x6c6b935b8bbd400000" + }, + "6c08a6dc0173c7342955d1d3f2c065d62f83aec7": { + "balance": "0x1158e460913d00000" + }, + "6c0ae9f043c834d44271f13406593dfe094f389f": { + "balance": "0x52442ae133b62a8000" + }, + "6c0cc917cbee7d7c099763f14e64df7d34e2bf09": { + "balance": "0xd8d726b7177a80000" + }, + "6c0e712f405c59725fe829e9774bf4df7f4dd965": { + "balance": "0xc2868889ca68a440000" + }, + "6c101205b323d77544d6dc52af37aca3cec6f7f1": { + "balance": "0x21e19e0c9bab2400000" + }, + "6c15ec3520bf8ebbc820bd0ff19778375494cf9d": { + "balance": "0x6cb7e74867d5e60000" + }, + "6c1ddd33c81966dc8621776071a4129482f2c65f": { + "balance": "0x878678326eac9000000" + }, + "6c25327f8dcbb2f45e561e86e35d8850e53ab059": { + "balance": "0x3bcdf9bafef2f00000" + }, + "6c2e9be6d4ab450fd12531f33f028c614674f197": { + "balance": "0xc2127af858da700000" + }, + "6c359e58a13d4578a9338e335c67e7639f5fb4d7": { + "balance": "0xbd15b94fc8b280000" + }, + "6c3d18704126aa99ee3342ce60f5d4c85f1867cd": { + "balance": "0x2b5e3af16b1880000" + }, + "6c474bc66a54780066aa4f512eefa773abf919c7": { + "balance": "0x5188315f776b80000" + }, + "6c4e426e8dc005dfa3516cb8a680b02eea95ae8e": { + "balance": "0x487a9a304539440000" + }, + "6c52cf0895bb35e656161e4dc46ae0e96dd3e62c": { + "balance": "0xd8d8583fa2d52f0000" + }, + "6c5422fb4b14e6d98b6091fdec71f1f08640419d": { + "balance": "0x15af1d78b58c400000" + }, + "6c5c3a54cda7c2f118edba434ed81e6ebb11dd7a": { + "balance": "0xad78ebc5ac6200000" + }, + "6c63f84556d290bfcd99e434ee9997bfd779577a": { + "balance": "0x6c6b935b8bbd400000" + }, + "6c63fc85029a2654d79b2bea4de349e4524577c5": { + "balance": "0x23c757072b8dd00000" + }, + "6c6564e5c9c24eaaa744c9c7c968c9e2c9f1fbae": { + "balance": "0x499b42a21139640000" + }, + "6c67d6db1d03516c128b8ff234bf3d49b26d2941": { + "balance": "0x152d02c7e14af6800000" + }, + "6c67e0d7b62e2a08506945a5dfe38263339f1f22": { + "balance": "0x6acb3df27e1f880000" + }, + "6c6aa0d30b64721990b9504a863fa0bfb5e57da7": { + "balance": "0x925e06eec972b00000" + }, + "6c714a58fff6e97d14b8a5e305eb244065688bbd": { + "balance": "0xd8d726b7177a800000" + }, + "6c800d4b49ba07250460f993b8cbe00b266a2553": { + "balance": "0x1ab2cf7c9f87e20000" + }, + "6c808cabb8ff5fbb6312d9c8e84af8cf12ef0875": { + "balance": "0xd8d8583fa2d52f0000" + }, + "6c822029218ac8e98a260c1e064029348839875b": { + "balance": "0x10f97b787e1e3080000" + }, + "6c84cba77c6db4f7f90ef13d5ee21e8cfc7f8314": { + "balance": "0x6c6b935b8bbd400000" + }, + "6c8687e3417710bb8a93559021a1469e6a86bc77": { + "balance": "0x25b2da278d96b7b8000" + }, + "6c882c27732cef5c7c13a686f0a2ea77555ac289": { + "balance": "0x152d02c7e14af6800000" + }, + "6ca5de00817de0cedce5fd000128dede12648b3c": { + "balance": "0x1158e460913d00000" + }, + "6ca6a132ce1cd288bee30ec7cfeffb85c1f50a54": { + "balance": "0x6c6b935b8bbd400000" + }, + "6cb11ecb32d3ce829601310636f5a10cf7cf9b5f": { + "balance": "0x43fe8949c3801f50000" + }, + "6cc1c878fa6cde8a9a0b8311247e741e4642fe6d": { + "balance": "0x35659ef93f0fc40000" + }, + "6ccb03acf7f53ce87aadcc21a9932de915f89804": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "6cd212aee04e013f3d2abad2a023606bfb5c6ac7": { + "balance": "0x6c6acc67d7b1d40000" + }, + "6cd228dc712169307fe27ceb7477b48cfc8272e5": { + "balance": "0x434ea94db8a500000" + }, + "6ce1b0f6adc47051e8ab38b39edb4186b03babcc": { + "balance": "0x41799794cd24cc0000" + }, + "6ceae3733d8fa43d6cd80c1a96e8eb93109c83b7": { + "balance": "0x102794ad20da680000" + }, + "6d0569e5558fc7df2766f2ba15dc8aeffc5beb75": { + "balance": "0xd8e6001e6c302b0000" + }, + "6d120f0caae44fd94bcafe55e2e279ef96ba5c7a": { + "balance": "0xd8d726b7177a800000" + }, + "6d1456fff0104ee844a3314737843338d24cd66c": { + "balance": "0x7b06ce87fdd680000" + }, + "6d20ef9704670a500bb269b5832e859802049f01": { + "balance": "0x70c1cc73b00c80000" + }, + "6d2f976734b9d0070d1883cf7acab8b3e4920fc1": { + "balance": "0x21e19e0c9bab2400000" + }, + "6d39a9e98f81f769d73aad2cead276ac1387babe": { + "balance": "0x155bd9307f9fe80000" + }, + "6d3b7836a2b9d899721a4d237b522385dce8dfcd": { + "balance": "0x3636c25e66ece70000" + }, + "6d3f2ba856ccbb0237fa7661156b14b013f21240": { + "balance": "0x3635c9adc5dea00000" + }, + "6d4008b4a888a826f248ee6a0b0dfde9f93210b9": { + "balance": "0x127fcb8afae20d00000" + }, + "6d40ca27826d97731b3e86effcd7b92a4161fe89": { + "balance": "0x6c6b935b8bbd400000" + }, + "6d44974a31d187eda16ddd47b9c7ec5002d61fbe": { + "balance": "0x32f51edbaaa3300000" + }, + "6d4b5c05d06a20957e1748ab6df206f343f92f01": { + "balance": "0x21f360699bf825f8000" + }, + "6d4cbf3d8284833ae99344303e08b4d614bfda3b": { + "balance": "0x28a857425466f800000" + }, + "6d59b21cd0e2748804d9abe064eac2bef0c95f27": { + "balance": "0x6c6b935b8bbd400000" + }, + "6d63d38ee8b90e0e6ed8f192eda051b2d6a58bfd": { + "balance": "0x1a055690d9db80000" + }, + "6d6634b5b8a40195d949027af4828802092ceeb6": { + "balance": "0xa2a15d09519be00000" + }, + "6d7d1c949511f88303808c60c5ea0640fcc02683": { + "balance": "0x21e19e0c9bab2400000" + }, + "6d846dc12657e91af25008519c3e857f51707dd6": { + "balance": "0xf8d30bc92342f80000" + }, + "6d9193996b194617211106d1635eb26cc4b66c6c": { + "balance": "0x15aa1e7e9dd51c0000" + }, + "6d9997509882027ea947231424bedede2965d0ba": { + "balance": "0x6c81c7b31195e00000" + }, + "6da0ed8f1d69339f059f2a0e02471cb44fb8c3bb": { + "balance": "0x32bc38bb63a8160000" + }, + "6db72bfd43fef465ca5632b45aab7261404e13bf": { + "balance": "0x6c6b935b8bbd400000" + }, + "6dbe8abfa1742806263981371bf3d35590806b6e": { + "balance": "0x43c33c1937564800000" + }, + "6dc3f92baa1d21dab7382b893261a0356fa7c187": { + "balance": "0x5dc892aa1131c80000" + }, + "6dc7053a718616cfc78bee6382ee51add0c70330": { + "balance": "0x6c6b935b8bbd400000" + }, + "6dcc7e64fcafcbc2dc6c0e5e662cb347bffcd702": { + "balance": "0x43c33c1937564800000" + }, + "6dda5f788a6c688ddf921fa3852eb6d6c6c62966": { + "balance": "0x22b1c8c1227a00000" + }, + "6ddb6092779d5842ead378e21e8120fd4c6bc132": { + "balance": "0x6c6b935b8bbd400000" + }, + "6ddfef639155daab0a5cb4953aa8c5afaa880453": { + "balance": "0x62a992e53a0af00000" + }, + "6de02f2dd67efdb7393402fa9eaacbcf589d2e56": { + "balance": "0x40138b917edfb80000" + }, + "6de4b581385cf7fc9fe8c77d131fe2ee7724c76a": { + "balance": "0x7d2997733dcce40000" + }, + "6de4d15219182faf3aa2c5d4d2595ff23091a727": { + "balance": "0x55a6e79ccd1d300000" + }, + "6dedf62e743f4d2c2a4b87a787f5424a7aeb393c": { + "balance": "0x9c2007651b2500000" + }, + "6df24f6685a62f791ba337bf3ff67e91f3d4bc3a": { + "balance": "0x756b49d40a48180000" + }, + "6df5c84f7b909aab3e61fe0ecb1b3bf260222ad2": { + "balance": "0xd8d726b7177a800000" + }, + "6dff90e6dc359d2590882b1483edbcf887c0e423": { + "balance": "0x3635c9adc5dea00000" + }, + "6e01e4ad569c95d007ada30d5e2db12888492294": { + "balance": "0xd8d726b7177a800000" + }, + "6e073b66d1b8c66744d88096a8dd99ec7e0228da": { + "balance": "0xd8d726b7177a800000" + }, + "6e0ee70612c976287d499ddfa6c0dcc12c06deea": { + "balance": "0x70bd5b95621460000" + }, + "6e12b51e225b4a4372e59ad7a2a1a13ea3d3a137": { + "balance": "0x30046c8cc775f040000" + }, + "6e1a046caf5b4a57f4fd4bc173622126b4e2fd86": { + "balance": "0x61093d7c2c6d380000" + }, + "6e1ea4b183e252c9bb7767a006d4b43696cb8ae9": { + "balance": "0xff3783c85eed08000" + }, + "6e255b700ae7138a4bacf22888a9e2c00a285eec": { + "balance": "0xd8d726b7177a800000" + }, + "6e270ad529f1f0b8d9cb6d2427ec1b7e2dc64a74": { + "balance": "0xad78ebc5ac6200000" + }, + "6e2eab85dc89fe29dc0aa1853247dab43a523d56": { + "balance": "0x4563918244f400000" + }, + "6e3a51db743d334d2fe88224b5fe7c008e80e624": { + "balance": "0x5bf0ba6634f680000" + }, + "6e4c2ab7db026939dbd3bc68384af660a61816b2": { + "balance": "0x90d972f32323c0000" + }, + "6e4d2e39c8836629e5b487b1918a669aebdd9536": { + "balance": "0x3635c9adc5dea00000" + }, + "6e5c2d9b1c546a86eefd5d0a5120c9e4e730190e": { + "balance": "0xad201a6794ff80000" + }, + "6e60aee1a78f8eda8b424c73e353354ae67c3042": { + "balance": "0xbd35a48d9919e60000" + }, + "6e64e6129f224e378c0e6e736a7e7a06c211e9ec": { + "balance": "0x3635c9adc5dea00000" + }, + "6e6d5bbbb9053b89d744a27316c2a7b8c09b547d": { + "balance": "0x3152710a023e6d8000" + }, + "6e72b2a1186a8e2916543b1cb36a68870ea5d197": { + "balance": "0xa1544be879ea80000" + }, + "6e761eaa0f345f777b5441b73a0fa5b56b85f22d": { + "balance": "0x6c6b935b8bbd400000" + }, + "6e79edd4845b076e4cd88d188b6e432dd93f35aa": { + "balance": "0x33c5499031720c0000" + }, + "6e8212b722afd408a7a73ed3e2395ee6454a0330": { + "balance": "0x89e917994f71c0000" + }, + "6e84876dbb95c40b6656e42ba9aea08a993b54dc": { + "balance": "0x3bbc60e3b6cbbe0000" + }, + "6e84c2fd18d8095714a96817189ca21cca62bab1": { + "balance": "0x127b6c702621cd8000" + }, + "6e866d032d405abdd65cf651411d803796c22311": { + "balance": "0x6c6b935b8bbd400000" + }, + "6e899e59a9b41ab7ea41df7517860f2acb59f4fd": { + "balance": "0x43c33c1937564800000" + }, + "6e89c51ea6de13e06cdc748b67c4410fe9bcab03": { + "balance": "0xd8d726b7177a800000" + }, + "6e8a26689f7a2fdefd009cbaaa5310253450daba": { + "balance": "0x6f213717bad8d30000" + }, + "6e96faeda3054302c45f58f161324c99a3eebb62": { + "balance": "0x1158e460913d00000" + }, + "6eb0a5a9ae96d22cf01d8fd6483b9f38f08c2c8b": { + "balance": "0xd8d726b7177a800000" + }, + "6eb3819617404058268f0c3cff3596bfe9148c1c": { + "balance": "0x5a87e7d7f5f6580000" + }, + "6eb5578a6bb7c32153195b0d8020a6914852c059": { + "balance": "0x8bc2abf40221f4800000" + }, + "6ebb5e6957aa821ef659b6018a393a504cae4450": { + "balance": "0x6c6b935b8bbd400000" + }, + "6ebcf9957f5fc5e985add475223b04b8c14a7aed": { + "balance": "0x5dc892aa1131c80000" + }, + "6ec3659571b11f889dd439bcd4d67510a25be57e": { + "balance": "0x6aaf7c8516d0c0000" + }, + "6ec89b39f9f5276a553e8da30e6ec17aa47eefc7": { + "balance": "0x18424f5f0b1b4e0000" + }, + "6ec96d13bdb24dc7a557293f029e02dd74b97a55": { + "balance": "0xd8d726b7177a800000" + }, + "6ecaefa6fc3ee534626db02c6f85a0c395571e77": { + "balance": "0x2086ac351052600000" + }, + "6ed2a12b02f8c688c7b5d3a6ea14d63687dab3b6": { + "balance": "0x6c6b935b8bbd400000" + }, + "6ed884459f809dfa1016e770edaf3e9fef46fa30": { + "balance": "0xb852d6782093f10000" + }, + "6edf7f5283725c953ee64317f66188af1184b033": { + "balance": "0x1b464311d45a6880000" + }, + "6ee8aad7e0a065d8852d7c3b9a6e5fdc4bf50c00": { + "balance": "0x1158e460913d00000" + }, + "6eefdc850e87b715c72791773c0316c3559b58a4": { + "balance": "0xd8d726b7177a800000" + }, + "6ef9e8c9b6217d56769af97dbb1c8e1b8be799d2": { + "balance": "0x9ddc1e3b901180000" + }, + "6efba8fb2ac5b6730729a972ec224426a287c3ad": { + "balance": "0xf5985fbcbe1680000" + }, + "6efd90b535e00bbd889fda7e9c3184f879a151db": { + "balance": "0x22385a827e815500000" + }, + "6f051666cb4f7bd2b1907221b829b555d7a3db74": { + "balance": "0x5f68e8131ecf800000" + }, + "6f0edd23bcd85f6015f9289c28841fe04c83efeb": { + "balance": "0x10910d4cdc9f60000" + }, + "6f137a71a6f197df2cbbf010dcbd3c444ef5c925": { + "balance": "0x6c6b935b8bbd400000" + }, + "6f176065e88e3c6fe626267d18a088aaa4db80bc": { + "balance": "0xbed1d0263d9f000000" + }, + "6f18ec767e320508195f1374500e3f2e125689ff": { + "balance": "0x3635c9adc5dea00000" + }, + "6f1f4907b8f61f0c51568d692806b382f50324f5": { + "balance": "0x6c6b935b8bbd400000" + }, + "6f24c9af2b763480515d1b0951bb77a540f1e3f9": { + "balance": "0x6acb3df27e1f880000" + }, + "6f2576da4de283bbe8e3ee69ddd66e5e711db3f5": { + "balance": "0x44591d67fecc800000" + }, + "6f29bb375be5ed34ed999bb830ee2957dde76d16": { + "balance": "0x6c6b935b8bbd400000" + }, + "6f2a31900e240395b19f159c1d00dfe4d898ebdf": { + "balance": "0x6c660645aa47180000" + }, + "6f2a42e6e033d01061131929f7a6ee1538021e52": { + "balance": "0x6c6b935b8bbd400000" + }, + "6f39cc37caaa2ddc9b610f6131e0619fae772a3c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "6f44ca09f0c6a8294cbd519cdc594ad42c67579f": { + "balance": "0x2b5e3af16b1880000" + }, + "6f50929777824c291a49c46dc854f379a6bea080": { + "balance": "0x138400eca364a00000" + }, + "6f6cf20649a9e973177ac67dbadee4ebe5c7bdda": { + "balance": "0x11363297d01a8600000" + }, + "6f791d359bc3536a315d6382b88311af8ed6da47": { + "balance": "0x4fcc1a89027f00000" + }, + "6f794dbdf623daa6e0d00774ad6962737c921ea4": { + "balance": "0x6c6b935b8bbd400000" + }, + "6f7ac681d45e418fce8b3a1db5bc3be6f06c9849": { + "balance": "0x6c6b935b8bbd400000" + }, + "6f81f3abb1f933b1df396b8e9cc723a89b7c9806": { + "balance": "0xf2dc7d47f15600000" + }, + "6f8f0d15cc96fb7fe94f1065bc6940f8d12957b2": { + "balance": "0x3635c9adc5dea00000" + }, + "6f92d6e4548c78996509ee684b2ee29ba3c532b4": { + "balance": "0x3635c9adc5dea00000" + }, + "6fa60df818a5446418b1bbd62826e0b9825e1318": { + "balance": "0x2cb92cc8f6714400000" + }, + "6fa6388d402b30afe59934c3b9e13d1186476018": { + "balance": "0x24521e2a3017b80000" + }, + "6fa72015fa78696efd9a86174f7f1f21019286b1": { + "balance": "0x487a9a304539440000" + }, + "6fc25e7e00ca4f60a9fe6f28d1fde3542e2d1079": { + "balance": "0x2aef353bcddd600000" + }, + "6fc53662371dca587b59850de78606e2359df383": { + "balance": "0x9c2007651b2500000" + }, + "6fcc2c732bdd934af6ccd16846fb26ef89b2aa9b": { + "balance": "0x21e2b1d42261d490000" + }, + "6fd4e0f3f32bee6d3767fdbc9d353a6d3aab7899": { + "balance": "0x25b064a875ea940000" + }, + "6fd947d5a73b175008ae6ee8228163da289b167d": { + "balance": "0x65a4da25d3016c00000" + }, + "6fd98e563d12ce0fd60f4f1f850ae396a9823c02": { + "balance": "0x445be3f2ef87940000" + }, + "6fddbd9bca66e28765c2162c8433548c1052ed11": { + "balance": "0x1184429b82a818800000" + }, + "6ff5d361b52ad0b68b1588607ec304ae5665fc98": { + "balance": "0x692ae8897081d00000" + }, + "6ff6cc90d649de4e96cffee1077a5b302a848dcb": { + "balance": "0x18ce79c78802c0000" + }, + "6ffe5cf82cc9ea5e36cad7c2974ce7249f3749e6": { + "balance": "0x692ae8897081d00000" + }, + "7005a772282b1f62afda63f89b5dc6ab64c84cb9": { + "balance": "0x3cfc82e37e9a7400000" + }, + "700711e311bb947355f755b579250ca7fd765a3e": { + "balance": "0x61093d7c2c6d380000" + }, + "7010be2df57bd0ab9ae8196cd50ab0c521aba9f9": { + "balance": "0x6acb3df27e1f880000" + }, + "7023c70956e04a92d70025aad297b539af355869": { + "balance": "0x6c6b935b8bbd400000" + }, + "7025965d2b88da197d4459be3dc9386344cc1f31": { + "balance": "0x6cb7e74867d5e60000" + }, + "702802f36d00250fab53adbcd696f0176f638a49": { + "balance": "0x6c6b935b8bbd400000" + }, + "704819d2e44d6ed1da25bfce84c49fcca25613e5": { + "balance": "0x15af1d78b58c400000" + }, + "704a6eb41ba34f13addde7d2db7df04915c7a221": { + "balance": "0x62a992e53a0af00000" + }, + "704ab1150d5e10f5e3499508f0bf70650f028d4b": { + "balance": "0xd8d726b7177a800000" + }, + "704ae21d762d6e1dde28c235d13104597236db1a": { + "balance": "0x6c6b935b8bbd400000" + }, + "704d243c2978e46c2c86adbecd246e3b295ff633": { + "balance": "0x6d121bebf795f00000" + }, + "704d5de4846d39b53cd21d1c49f096db5c19ba29": { + "balance": "0x83d6c7aab63600000" + }, + "705ddd38355482b8c7d3b515bda1500dd7d7a817": { + "balance": "0x15af1d78b58c400000" + }, + "70616e2892fa269705b2046b8fe3e72fa55816d3": { + "balance": "0x43c33c1937564800000" + }, + "70670fbb05d33014444b8d1e8e7700258b8caa6d": { + "balance": "0x6c6b935b8bbd400000" + }, + "7081fa6baad6cfb7f51b2cca16fb8970991a64ba": { + "balance": "0xcaec005f6c0f68000" + }, + "7085ae7e7e4d932197b5c7858c00a3674626b7a5": { + "balance": "0x14542ba12a337c00000" + }, + "7086b4bde3e35d4aeb24b825f1a215f99d85f745": { + "balance": "0x6c68ccd09b022c0000" + }, + "708a2af425ceb01e87ffc1be54c0f532b20eacd6": { + "balance": "0x745d483b1f5a18000" + }, + "708ea707bae4357f1ebea959c3a250acd6aa21b3": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "708fa11fe33d85ad1befcbae3818acb71f6a7d7e": { + "balance": "0xfc936392801c0000" + }, + "7091303116d5f2389b23238b4d656a8596d984d3": { + "balance": "0x3b4e7e80aa58330000" + }, + "7099d12f6ec656899b049a7657065d62996892c8": { + "balance": "0x15af1d78b58c400000" + }, + "709fe9d2c1f1ce42207c9585044a60899f35942f": { + "balance": "0x6c6b935b8bbd400000" + }, + "70a03549aa6168e97e88a508330a5a0bea74711a": { + "balance": "0x487a9a304539440000" + }, + "70a4067d448cc25dc8e70e651cea7cf84e92109e": { + "balance": "0x98a7d9b8314c00000" + }, + "70ab34bc17b66f9c3b63f151274f2a727c539263": { + "balance": "0x6c6b935b8bbd400000" + }, + "70c213488a020c3cfb39014ef5ba6404724bcaa3": { + "balance": "0x692ae8897081d00000" + }, + "70d25ed2c8ada59c088cf70dd22bf2db93acc18a": { + "balance": "0x39474545e4adbc0000" + }, + "70e5e9da735ff077249dcb9aaf3db2a48d9498c0": { + "balance": "0x3635c9adc5dea00000" + }, + "70fee08b00c6c2c04a3c625c1ff77caf1c32df01": { + "balance": "0xad78ebc5ac6200000" + }, + "7101bd799e411cde14bdfac25b067ac890eab8e8": { + "balance": "0x4e9b8aae48de470000" + }, + "7109dd011d15f3122d9d3a27588c10d77744508b": { + "balance": "0x6c6b935b8bbd400000" + }, + "710b0274d712c77e08a5707d6f3e70c0ce3d92cf": { + "balance": "0x15af1d78b58c4000000" + }, + "710be8fd5e2918468be2aabea80d828435d79612": { + "balance": "0xf43fc2c04ee00000" + }, + "71135d8f05963c905a4a07922909235a896a52ea": { + "balance": "0xa2a15d09519be00000" + }, + "711ecf77d71b3d0ea95ce4758afecdb9c131079d": { + "balance": "0x29331e6558f0e00000" + }, + "71213fca313404204ecba87197741aa9dfe96338": { + "balance": "0x340aad21b3b700000" + }, + "712b76510214dc620f6c3a1dd29aa22bf6d214fb": { + "balance": "0x14542ba12a337c00000" + }, + "712ff7370a13ed360973fedc9ff5d2c93a505e9e": { + "balance": "0xd5967be4fc3f100000" + }, + "7133843a78d939c69d4486e10ebc7b602a349ff7": { + "balance": "0x11d5cacce21f840000" + }, + "7148aef33261d8031fac3f7182ff35928daf54d9": { + "balance": "0xde42ee1544dd900000" + }, + "7163758cbb6c4c525e0414a40a049dcccce919bb": { + "balance": "0xad78ebc5ac6200000" + }, + "7168b3bb8c167321d9bdb023a6e9fd11afc9afd9": { + "balance": "0x61093d7c2c6d380000" + }, + "7169724ee72271c534cad6420fb04ee644cb86fe": { + "balance": "0x163c2b40dba5520000" + }, + "716ad3c33a9b9a0a18967357969b94ee7d2abc10": { + "balance": "0x1a2117fe412a480000" + }, + "716ba01ead2a91270635f95f25bfaf2dd610ca23": { + "balance": "0x979e7012056aa780000" + }, + "716d50cca01e938500e6421cc070c3507c67d387": { + "balance": "0x6c6b935b8bbd400000" + }, + "71762c63678c18d1c6378ce068e666381315147e": { + "balance": "0x6c6b935b8bbd400000" + }, + "71784c105117c1f68935797fe159abc74e43d16a": { + "balance": "0x6c81c7b31195e00000" + }, + "7179726f5c71ae1b6d16a68428174e6b34b23646": { + "balance": "0x18ea250097cbaf60000" + }, + "717cf9beab3638308ded7e195e0c86132d163fed": { + "balance": "0x3326ee6f865f4220000" + }, + "7180b83ee5574317f21c8072b191d895d46153c3": { + "balance": "0x18efc84ad0c7b00000" + }, + "71946b7117fc915ed107385f42d99ddac63249c2": { + "balance": "0x6c6b935b8bbd400000" + }, + "719e891fbcc0a33e19c12dc0f02039ca05b801df": { + "balance": "0x14f5538463a1b540000" + }, + "71c7230a1d35bdd6819ed4b9a88e94a0eb0786dd": { + "balance": "0xeca08b353d24140000" + }, + "71d2cc6d02578c65f73c575e76ce8fbcfadcf356": { + "balance": "0x3ecc078688a480000" + }, + "71d9494e50c5dd59c599dba3810ba1755e6537f0": { + "balance": "0xd8d726b7177a800000" + }, + "71e38ff545f30fe14ca863d4f5297fd48c73a5ce": { + "balance": "0xc2127af858da700000" + }, + "71ea5b11ad8d29b1a4cb67bf58ca6c9f9c338c16": { + "balance": "0x56bc75e2d631000000" + }, + "71ec3aec3f8f9221f9149fede06903a0f9a232f2": { + "balance": "0xad78ebc5ac6200000" + }, + "71f2cdd1b046e2da2fbb5a26723422b8325e25a3": { + "balance": "0x56b394263a40c0000" + }, + "71fa22cc6d33206b7d701a163a0dab31ae4d31d6": { + "balance": "0x57473d05dabae80000" + }, + "7201d1c06920cd397ae8ad869bcda6e47ffb1b5a": { + "balance": "0x1158e460913d00000" + }, + "72072a0ef1cff3d567cdd260e708ddc11cbc9a31": { + "balance": "0x56bc75e2d63100000" + }, + "72094f3951ffc9771dced23ada080bcaf9c7cca7": { + "balance": "0x14542ba12a337c00000" + }, + "720994dbe56a3a95929774e20e1fe525cf3704e4": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "720e6b22bf430966fa32b6acb9a506eebf662c61": { + "balance": "0x83d6c7aab63600000" + }, + "721158be5762b119cc9b2035e88ee4ee78f29b82": { + "balance": "0x21e19e0c9bab2400000" + }, + "721f9d17e5a0e74205947aeb9bc6a7938961038f": { + "balance": "0x2d041d705a2c60000" + }, + "7222fec7711781d26eaa4e8485f7aa3fac442483": { + "balance": "0x18b84570022a200000" + }, + "72393d37b451effb9e1ff3b8552712e2a970d8c2": { + "balance": "0x35659ef93f0fc40000" + }, + "723d8baa2551d2addc43c21b45e8af4ca2bfb2c2": { + "balance": "0x5f68e8131ecf800000" + }, + "72402300e81d146c2e644e2bbda1da163ca3fb56": { + "balance": "0x17b7883c06916600000" + }, + "72480bede81ad96423f2228b5c61be44fb523100": { + "balance": "0x15af1d78b58c4000000" + }, + "724ce858857ec5481c86bd906e83a04882e5821d": { + "balance": "0xa2a15d09519be00000" + }, + "726a14c90e3f84144c765cffacba3e0df11b48be": { + "balance": "0x21e19e0c9bab2400000" + }, + "7283cd4675da58c496556151dafd80c7f995d318": { + "balance": "0x29331e6558f0e00000" + }, + "7286e89cd9de8f7a8a00c86ffdb53992dd9251d1": { + "balance": "0x692ae8897081d00000" + }, + "728f9ab080157db3073156dbca1a169ef3179407": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "7294c918b1aefb4d25927ef9d799e71f93a28e85": { + "balance": "0xaadec983fcff40000" + }, + "7294ec9da310bc6b4bbdf543b0ef45abfc3e1b4d": { + "balance": "0x4a89f54ef0121c00000" + }, + "729aad4627744e53f5d66309aa74448b3acdf46f": { + "balance": "0x6c6b935b8bbd400000" + }, + "72a2fc8675feb972fa41b50dffdbbae7fa2adfb7": { + "balance": "0x9ab4fc67b528c80000" + }, + "72a8260826294726a75bf39cd9aa9e07a3ea14cd": { + "balance": "0x6c6b935b8bbd400000" + }, + "72b05962fb2ad589d65ad16a22559eba1458f387": { + "balance": "0x73f75d1a085ba0000" + }, + "72b5633fe477fe542e742facfd690c137854f216": { + "balance": "0x5a87e7d7f5f6580000" + }, + "72b7a03dda14ca9c661a1d469fd33736f673c8e8": { + "balance": "0x6c6b935b8bbd400000" + }, + "72b904440e90e720d6ac1c2ad79c321dcc1c1a86": { + "balance": "0x54069233bf7f780000" + }, + "72b90a4dc097239492c5b9777dcd1e52ba2be2c2": { + "balance": "0x14542ba12a337c00000" + }, + "72bb27cb99f3e2c2cf90a98f707d30e4a201a071": { + "balance": "0x58e7926ee858a00000" + }, + "72c083beadbdc227c5fb43881597e32e83c26056": { + "balance": "0x43c33c1937564800000" + }, + "72cd048a110574482983492dfb1bd27942a696ba": { + "balance": "0x6c6b935b8bbd400000" + }, + "72d03d4dfab3500cf89b86866f15d4528e14a195": { + "balance": "0xf34b82fd8e91200000" + }, + "72dabb5b6eed9e99be915888f6568056381608f8": { + "balance": "0xb4c96c52cb4fe8000" + }, + "72fb49c29d23a18950c4b2dc0ddf410f532d6f53": { + "balance": "0x6c6b935b8bbd400000" + }, + "72feaf124579523954645b7fafff0378d1c8242e": { + "balance": "0x3635c9adc5dea00000" + }, + "7301dc4cf26d7186f2a11bf8b08bf229463f64a3": { + "balance": "0x6c6b935b8bbd400000" + }, + "730447f97ce9b25f22ba1afb36df27f9586beb9b": { + "balance": "0x2c73c937742c500000" + }, + "7306de0e288b56cfdf987ef0d3cc29660793f6dd": { + "balance": "0x1b8abfb62ec8f60000" + }, + "730d8763c6a4fd824ab8b859161ef7e3a96a1200": { + "balance": "0x43c33c1937564800000" + }, + "73128173489528012e76b41a5e28c68ba4e3a9d4": { + "balance": "0x3635c9adc5dea00000" + }, + "7313461208455455465445a459b06c3773b0eb30": { + "balance": "0x6c6b935b8bbd400000" + }, + "732fead60f7bfdd6a9dec48125e3735db1b6654f": { + "balance": "0x1158e460913d00000" + }, + "734223d27ff23e5906caed22595701bb34830ca1": { + "balance": "0x6c6b935b8bbd400000" + }, + "73473e72115110d0c3f11708f86e77be2bb0983c": { + "balance": "0x1158e460913d00000" + }, + "7352586d021ad0cf77e0e928404a59f374ff4582": { + "balance": "0xb8507a820728200000" + }, + "73550beb732ba9ddafda7ae406e18f7feb0f8bb2": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "735b97f2fc1bd24b12076efaf3d1288073d20c8c": { + "balance": "0x1158e460913d00000" + }, + "735e328666ed5637142b3306b77ccc5460e72c3d": { + "balance": "0x6ab8f37879c9910000" + }, + "7363cd90fbab5bb8c49ac20fc62c398fe6fb744c": { + "balance": "0x6c6b935b8bbd400000" + }, + "736b44503dd2f6dd5469ff4c5b2db8ea4fec65d0": { + "balance": "0x1104ee759f21e30000" + }, + "736bf1402c83800f893e583192582a134eb532e9": { + "balance": "0x21e19d293c01f260000" + }, + "738ca94db7ce8be1c3056cd6988eb376359f3353": { + "balance": "0x5665b96cf35acf00000" + }, + "73914b22fc2f131584247d82be4fecbf978ad4ba": { + "balance": "0x6c6b935b8bbd400000" + }, + "73932709a97f02c98e51b091312865122385ae8e": { + "balance": "0x4d853c8f8908980000" + }, + "7393cbe7f9ba2165e5a7553500b6e75da3c33abf": { + "balance": "0x56bc75e2d63100000" + }, + "73b4d499de3f38bf35aaf769a6e318bc6d123692": { + "balance": "0x6c6b935b8bbd400000" + }, + "73bedd6fda7ba3272185087b6351fc133d484e37": { + "balance": "0x11226bf9dce59780000" + }, + "73bfe7710f31cab949b7a2604fbf5239cee79015": { + "balance": "0x6c6b935b8bbd400000" + }, + "73cf80ae9688e1580e68e782cd0811f7aa494d2c": { + "balance": "0x1a4aba225c207400000" + }, + "73d7269ff06c9ffd33754ce588f74a966abbbbba": { + "balance": "0x165c96647b38a200000" + }, + "73d8fee3cb864dce22bb26ca9c2f086d5e95e63b": { + "balance": "0x3635c9adc5dea00000" + }, + "73df3c3e7955f4f2d859831be38000b1076b3884": { + "balance": "0x6acb3df27e1f880000" + }, + "73e4a2b60cf48e8baf2b777e175a5b1e4d0c2d8f": { + "balance": "0x56bc75e2d63100000" + }, + "740af1eefd3365d78ba7b12cb1a673e06a077246": { + "balance": "0x42bf06b78ed3b500000" + }, + "740bfd52e01667a3419b029a1b8e45576a86a2db": { + "balance": "0x38ebad5cdc902800000" + }, + "740f641614779dcfa88ed1d425d60db42a060ca6": { + "balance": "0x3622c6760810570000" + }, + "7412c9bc30b4df439f023100e63924066afd53af": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "741693c30376508513082020cc2b63e9fa92131b": { + "balance": "0x410d586a20a4c00000" + }, + "7421ce5be381738ddc83f02621974ff0686c79b8": { + "balance": "0x58788cb94b1d800000" + }, + "74316adf25378c10f576d5b41a6f47fa98fce33d": { + "balance": "0x1238131e5c7ad50000" + }, + "743651b55ef8429df50cf81938c2508de5c8870f": { + "balance": "0x6c6b935b8bbd400000" + }, + "743de50026ca67c94df54f066260e1d14acc11ac": { + "balance": "0x6c6b935b8bbd400000" + }, + "7445202f0c74297a004eb3726aa6a82dd7c02fa1": { + "balance": "0x6c6b935b8bbd400000" + }, + "744b03bba8582ae5498e2dc22d19949467ab53fc": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "744c0c77ba7f236920d1e434de5da33e48ebf02c": { + "balance": "0x6acb3df27e1f880000" + }, + "7450ff7f99eaa9116275deac68e428df5bbcd8b9": { + "balance": "0x6c6b935b8bbd400000" + }, + "7456c5b2c5436e3e571008933f1805ccfe34e9ec": { + "balance": "0x3635c9adc5dea00000" + }, + "745ad3abc6eeeb2471689b539e789ce2b8268306": { + "balance": "0x3d4194bea011928000" + }, + "745aecbaf9bb39b74a67ea1ce623de368481baa6": { + "balance": "0x21e19e0c9bab2400000" + }, + "745ccf2d819edbbddea8117b5c49ed3c2a066e93": { + "balance": "0xd8d726b7177a800000" + }, + "7462c89caa9d8d7891b2545def216f7464d5bb21": { + "balance": "0x5eaed54a28b310000" + }, + "74648caac748dd135cd91ea14c28e1bd4d7ff6ae": { + "balance": "0xa80d24677efef00000" + }, + "7471f72eeb300624eb282eab4d03723c649b1b58": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "747abc9649056d3926044d28c3ad09ed17b67d70": { + "balance": "0x10f0dbae61009528000" + }, + "747ff7943b71dc4dcdb1668078f83dd7cc4520c2": { + "balance": "0x340aad21b3b700000" + }, + "7480de62254f2ba82b578219c07ba5be430dc3cb": { + "balance": "0x17da3a04c7b3e000000" + }, + "7484d26becc1eea8c6315ec3ee0a450117dc86a0": { + "balance": "0x28a857425466f800000" + }, + "74863acec75d03d53e860e64002f2c165e538377": { + "balance": "0x3635c9adc5dea00000" + }, + "7489cc8abe75cda4ef0d01cef2605e47eda67ab1": { + "balance": "0x73f75d1a085ba0000" + }, + "748c285ef1233fe4d31c8fb1378333721c12e27a": { + "balance": "0x6c6b935b8bbd400000" + }, + "749087ac0f5a97c6fad021538bf1d6cda18e0daa": { + "balance": "0x3635c9adc5dea00000" + }, + "7495ae78c0d90261e2140ef2063104731a60d1ed": { + "balance": "0x1db50718925210000" + }, + "749a4a768b5f237248938a12c623847bd4e688dc": { + "balance": "0x3e733628714200000" + }, + "749ad6f2b5706bbe2f689a44c4b640b58e96b992": { + "balance": "0x56bc75e2d63100000" + }, + "74a17f064b344e84db6365da9591ff1628257643": { + "balance": "0x1158e460913d00000" + }, + "74aeec915de01cc69b2cb5a6356feea14658c6c5": { + "balance": "0xc9a95ee2986520000" + }, + "74afe54902d615782576f8baac13ac970c050f6e": { + "balance": "0x9a1aaa3a9fba70000" + }, + "74b7e0228baed65957aebb4d916d333aae164f0e": { + "balance": "0x6c6b935b8bbd400000" + }, + "74bc4a5e2045f4ff8db184cf3a9b0c065ad807d2": { + "balance": "0x6c6b935b8bbd400000" + }, + "74bce9ec38362d6c94ccac26d5c0e13a8b3b1d40": { + "balance": "0x363526410442f50000" + }, + "74bf7a5ab59293149b5c60cf364263e5ebf1aa0d": { + "balance": "0x6470c3e771e3c0000" + }, + "74c73c90528a157336f1e7ea20620ae53fd24728": { + "balance": "0x1e63a2e538f16e30000" + }, + "74d1a4d0c7524e018d4e06ed3b648092b5b6af2c": { + "balance": "0x2b5e3af16b1880000" + }, + "74d366b07b2f56477d7c7077ac6fe497e0eb6559": { + "balance": "0x10f0cf064dd59200000" + }, + "74d37a51747bf8b771bfbf43943933d100d21483": { + "balance": "0x3635c9adc5dea00000" + }, + "74d671d99cbea1ab57906375b63ff42b50451d17": { + "balance": "0x3635c9adc5dea00000" + }, + "74ebf4425646e6cf81b109ce7bf4a2a63d84815f": { + "balance": "0x22b1c8c1227a00000" + }, + "74ed33acf43f35b98c9230b9e6642ecb5330839e": { + "balance": "0x24f6dffb498d280000" + }, + "74ef2869cbe608856045d8c2041118579f2236ea": { + "balance": "0x33cd64591956e0000" + }, + "74fc5a99c0c5460503a13b0509459da19ce7cd90": { + "balance": "0xad78ebc5ac6200000" + }, + "750bbb8c06bbbf240843cc75782ee02f08a97453": { + "balance": "0x2d43f3ebfafb2c0000" + }, + "7514adbdc63f483f304d8e94b67ff3309f180b82": { + "balance": "0x21c4a06e2d13598000" + }, + "7517f16c28d132bb40e3ba36c6aef131c462da17": { + "balance": "0xfc936392801c0000" + }, + "751a2ca34e7187c163d28e3618db28b13c196d26": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "751abcb6cc033059911815c96fd191360ab0442d": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "7526e482529f0a14eec98871dddd0e721b0cd9a2": { + "balance": "0x1158e460913d00000" + }, + "7529f3797bb6a20f7ea6492419c84c867641d81c": { + "balance": "0x6c6b935b8bbd400000" + }, + "752a5ee232612cd3005fb26e5b597de19f776be6": { + "balance": "0x127fcb8afae20d00000" + }, + "752c9febf42f66c4787bfa7eb17cf5333bba5070": { + "balance": "0x6a99f2b54fdd580000" + }, + "7539333046deb1ef3c4daf50619993f444e1de68": { + "balance": "0x40138b917edfb80000" + }, + "7553aa23b68aa5f57e135fe39fdc235eaca8c98c": { + "balance": "0x3635c9adc5dea00000" + }, + "755a60bf522fbd8fff9723446b7e343a7068567e": { + "balance": "0x43c33c1937564800000" + }, + "755f587e5efff773a220726a13d0f2130d9f896b": { + "balance": "0x3635c9adc5dea00000" + }, + "75621865b6591365606ed378308c2d1def4f222c": { + "balance": "0xa80d24677efef00000" + }, + "75636cdb109050e43d5d6ec47e359e218e857eca": { + "balance": "0x4d8b2276c8962280000" + }, + "7566496162ba584377be040a4f87777a707acaeb": { + "balance": "0xd8d726b7177a800000" + }, + "756b84eb85fcc1f4fcdcc2b08db6a86e135fbc25": { + "balance": "0xae8e7a0bb575d00000" + }, + "756f45e3fa69347a9a973a725e3c98bc4db0b5a0": { + "balance": "0xad78ebc5ac6200000" + }, + "757b65876dbf29bf911d4f0692a2c9beb1139808": { + "balance": "0xdf93a59337d6dd8000" + }, + "757fa55446c460968bb74b5ebca96c4ef2c709c5": { + "balance": "0x3708baed3d68900000" + }, + "75804aac64b4199083982902994d9c5ed8828f11": { + "balance": "0x1e3d07b0a620e40000" + }, + "7592c69d067b51b6cc639d1164d5578c60d2d244": { + "balance": "0x1158e460913d00000" + }, + "75abe5270f3a78ce007cf37f8fbc045d489b7bb1": { + "balance": "0x6c6acc67d7b1d40000" + }, + "75ac547017134c04ae1e11d60e63ec04d18db4ef": { + "balance": "0x14542ba12a337c00000" + }, + "75b0e9c942a4f0f6f86d3f95ff998022fa67963b": { + "balance": "0x50c5e761a444080000" + }, + "75b95696e8ec4510d56868a7c1a735c68b244890": { + "balance": "0x15af1d78b58c4000000" + }, + "75be8ff65e5788aec6b2a52d5fa7b1e7a03ba675": { + "balance": "0x3abcdc5343d740000" + }, + "75c11d024d12ae486c1095b7a7b9c4af3e8edeb9": { + "balance": "0x1158e460913d00000" + }, + "75c1ad23d23f24b384d0c3149177e86697610d21": { + "balance": "0x15c5bcd6c288bbd0000" + }, + "75c2ffa1bef54919d2097f7a142d2e14f9b04a58": { + "balance": "0x90f358504032a10000" + }, + "75d67ce14e8d29e8c2ffe381917b930b1aff1a87": { + "balance": "0xa2a15d09519be00000" + }, + "75de7e9352e90b13a59a5878ffecc7831cac4d82": { + "balance": "0x9489237adb9a500000" + }, + "75f7539d309e9039989efe2e8b2dbd865a0df088": { + "balance": "0x855b5ba65c84f00000" + }, + "7608f437b31f18bc0b64d381ae86fd978ed7b31f": { + "balance": "0x2b5e3af16b1880000" + }, + "760ff3354e0fde938d0fb5b82cef5ba15c3d2916": { + "balance": "0x21e19e0c9bab2400000" + }, + "761a6e362c97fbbd7c5977acba2da74687365f49": { + "balance": "0x9f74ae1f953d00000" + }, + "761e6caec189c230a162ec006530193e67cf9d19": { + "balance": "0x6c6b935b8bbd400000" + }, + "761f8a3a2af0a8bdbe1da009321fb29764eb62a1": { + "balance": "0x21e19e0c9bab2400000" + }, + "762998e1d75227fced7a70be109a4c0b4ed86414": { + "balance": "0x1158e460913d00000" + }, + "762d6f30dab99135e4eca51d5243d6c8621102d5": { + "balance": "0xf498941e664280000" + }, + "76331e30796ce664b2700e0d4153700edc869777": { + "balance": "0x6c6b935b8bbd400000" + }, + "763886e333c56feff85be3951ab0b889ce262e95": { + "balance": "0x6c6b935b8bbd400000" + }, + "763a7cbab70d7a64d0a7e52980f681472593490c": { + "balance": "0x2086ac351052600000" + }, + "763eece0b08ac89e32bfa4bece769514d8cb5b85": { + "balance": "0xd8d726b7177a800000" + }, + "7640a37f8052981515bce078da93afa4789b5734": { + "balance": "0x6c6b935b8bbd400000" + }, + "7641f7d26a86cddb2be13081810e01c9c83c4b20": { + "balance": "0xb98bc829a6f90000" + }, + "764692cccb33405dd0ab0c3379b49caf8e6221ba": { + "balance": "0x1158e460913d00000" + }, + "764d5212263aff4a2a14f031f04ec749dc883e45": { + "balance": "0x6449e84e47a8a80000" + }, + "764fc46d428b6dbc228a0f5f55c9508c772eab9f": { + "balance": "0x581767ba6189c400000" + }, + "76506eb4a780c951c74a06b03d3b8362f0999d71": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "765be2e12f629e6349b97d21b62a17b7c830edab": { + "balance": "0x14542ba12a337c00000" + }, + "76628150e2995b5b279fc83e0dd5f102a671dd1c": { + "balance": "0x878678326eac9000000" + }, + "766b3759e8794e926dac473d913a8fb61ad0c2c9": { + "balance": "0x4b06dbbb40f4a0000" + }, + "7670b02f2c3cf8fd4f4730f3381a71ea431c33c7": { + "balance": "0xe7eeba3410b740000" + }, + "767a03655af360841e810d83f5e61fb40f4cd113": { + "balance": "0x35659ef93f0fc40000" + }, + "767ac690791c2e23451089fe6c7083fe55deb62b": { + "balance": "0x2c73c937742c500000" + }, + "767fd7797d5169a05f7364321c19843a8c348e1e": { + "balance": "0x104e70464b1580000" + }, + "76846f0de03b5a76971ead298cdd08843a4bc6c6": { + "balance": "0xd71b0fe0a28e0000" + }, + "768498934e37e905f1d0e77b44b574bcf3ec4ae8": { + "balance": "0x43c33c1937564800000" + }, + "768ce0daa029b7ded022e5fc574d11cde3ecb517": { + "balance": "0x1174a5cdf88bc80000" + }, + "7693bdeb6fc82b5bca721355223175d47a084b4d": { + "balance": "0x4a89f54ef0121c00000" + }, + "76aaf8c1ac012f8752d4c09bb46607b6651d5ca8": { + "balance": "0x1158e460913d00000" + }, + "76ab87dd5a05ad839a4e2fc8c85aa6ba05641730": { + "balance": "0x6c6b935b8bbd400000" + }, + "76afc225f4fa307de484552bbe1d9d3f15074c4a": { + "balance": "0xa290b5c7ad39680000" + }, + "76becae4a31d36f3cb577f2a43594fb1abc1bb96": { + "balance": "0x543a9ce0e1332f00000" + }, + "76c27535bcb59ce1fa2d8c919cabeb4a6bba01d1": { + "balance": "0x6c6b935b8bbd400000" + }, + "76ca22bcb8799e5327c4aa2a7d0949a1fcce5f29": { + "balance": "0x52a03f228c5ae20000" + }, + "76cac488111a4fd595f568ae3a858770fc915d5f": { + "balance": "0xad78ebc5ac6200000" + }, + "76cb9c8b69f4387675c48253e234cb7e0d74a426": { + "balance": "0x190f4482eb91dae0000" + }, + "76f83ac3da30f7092628c7339f208bfc142cb1ee": { + "balance": "0x9a18ffe7427d640000" + }, + "76f9ad3d9bbd04ae055c1477c0c35e7592cb2a20": { + "balance": "0x8833f11e3458f200000" + }, + "76ffc157ad6bf8d56d9a1a7fddbc0fea010aabf4": { + "balance": "0x3635c9adc5dea00000" + }, + "77028e409cc43a3bd33d21a9fc53ec606e94910e": { + "balance": "0xd255d112e103a00000" + }, + "770c2fb2c4a81753ac0182ea460ec09c90a516f8": { + "balance": "0x1158e460913d00000" + }, + "770d98d31b4353fceee8560c4ccf803e88c0c4e0": { + "balance": "0x2086ac351052600000" + }, + "7713ab8037411c09ba687f6f9364f0d3239fac28": { + "balance": "0x21e19e0c9bab2400000" + }, + "771507aeee6a255dc2cd9df55154062d0897b297": { + "balance": "0x121ea68c114e510000" + }, + "7719888795ad745924c75760ddb1827dffd8cda8": { + "balance": "0x6c6b4c4da6ddbe0000" + }, + "7727af101f0aaba4d23a1cafe17c6eb5dab1c6dc": { + "balance": "0x6c6b935b8bbd400000" + }, + "772c297f0ad194482ee8c3f036bdeb01c201d5cc": { + "balance": "0xad78ebc5ac6200000" + }, + "77306ffe2e4a8f3ca826c1a249f7212da43aeffd": { + "balance": "0x43c33c1937564800000" + }, + "773141127d8cf318aebf88365add3d5527d85b6a": { + "balance": "0x3636d7af5ec98e0000" + }, + "7746b6c6699c8f34ca2768a820f1ffa4c207fe05": { + "balance": "0xd8d8583fa2d52f0000" + }, + "7751f363a0a7fd0533190809ddaf9340d8d11291": { + "balance": "0x1158e460913d00000" + }, + "7757a4b9cc3d0247ccaaeb9909a0e56e1dd6dcc2": { + "balance": "0x1158e460913d00000" + }, + "775c10c93e0db7205b2643458233c64fc33fd75b": { + "balance": "0x6c6b935b8bbd400000" + }, + "77617ebc4bebc5f5ddeb1b7a70cdeb6ae2ffa024": { + "balance": "0x6acb3df27e1f880000" + }, + "776943ffb2ef5cdd35b83c28bc046bd4f4677098": { + "balance": "0xa2a15d09519be00000" + }, + "77701e2c493da47c1b58f421b5495dee45bea39b": { + "balance": "0x148f649cf6142a58000" + }, + "77798f201257b9c35204957057b54674aefa51df": { + "balance": "0x813ca56906d340000" + }, + "778c43d11afe3b586ff374192d96a7f23d2b9b7f": { + "balance": "0x8bb4fcfa3b7d6b8000" + }, + "778c79f4de1953ebce98fe8006d53a81fb514012": { + "balance": "0x36330322d5238c0000" + }, + "779274bf1803a336e4d3b00ddd93f2d4f5f4a62e": { + "balance": "0x3635c9adc5dea00000" + }, + "77a17122fa31b98f1711d32a99f03ec326f33d08": { + "balance": "0x5c283d410394100000" + }, + "77a34907f305a54c85db09c363fde3c47e6ae21f": { + "balance": "0x35659ef93f0fc40000" + }, + "77a769fafdecf4a638762d5ba3969df63120a41d": { + "balance": "0x6c6b935b8bbd400000" + }, + "77be6b64d7c733a436adec5e14bf9ad7402b1b46": { + "balance": "0x3635c9adc5dea00000" + }, + "77bfe93ccda750847e41a1affee6b2da96e7214e": { + "balance": "0x1043561a8829300000" + }, + "77c4a697e603d42b12056cbba761e7f51d0443f5": { + "balance": "0x24dce54d34a1a00000" + }, + "77cc02f623a9cf98530997ea67d95c3b491859ae": { + "balance": "0x497303c36ea0c20000" + }, + "77d43fa7b481dbf3db530cfbf5fdced0e6571831": { + "balance": "0x6c6b935b8bbd400000" + }, + "77da5e6c72fb36bce1d9798f7bcdf1d18f459c2e": { + "balance": "0x13695bb6cf93e0000" + }, + "77f4e3bdf056883cc87280dbe640a18a0d02a207": { + "balance": "0xa81993a2bfb5b0000" + }, + "77f609ca8720a023262c55c46f2d26fb3930ac69": { + "balance": "0xf015f25736420000" + }, + "77f81b1b26fc84d6de97ef8b9fbd72a33130cc4a": { + "balance": "0x3635c9adc5dea00000" + }, + "7819b0458e314e2b53bfe00c38495fd4b9fdf8d6": { + "balance": "0x1158e460913d00000" + }, + "781b1501647a2e06c0ed43ff197fccec35e1700b": { + "balance": "0xa2a15d09519be00000" + }, + "782f52f0a676c77716d574c81ec4684f9a020a97": { + "balance": "0x2e14e206b730ad8000" + }, + "78355df0a230f83d032c703154414de3eedab557": { + "balance": "0x6c6b935b8bbd400000" + }, + "7836f7ef6bc7bd0ff3acaf449c84dd6b1e2c939f": { + "balance": "0xe08de7a92cd97c0000" + }, + "7837fcb876da00d1eb3b88feb3df3fa4042fac82": { + "balance": "0x5f68e8131ecf800000" + }, + "783eec8aa5dac77b2e6623ed5198a431abbaee07": { + "balance": "0x17da3a04c7b3e00000" + }, + "785c8ea774d73044a734fa790a1b1e743e77ed7c": { + "balance": "0xcf152640c5c830000" + }, + "7860a3de38df382ae4a4dce18c0c07b98bce3dfa": { + "balance": "0x3635c9adc5dea00000" + }, + "78634371e17304cbf339b1452a4ce438dc764cce": { + "balance": "0x21e19e0c9bab2400000" + }, + "7864dc999fe4f8e003c0f43decc39aae1522dc0f": { + "balance": "0x51e102bd8ece00000" + }, + "78746a958dced4c764f876508c414a68342cecb9": { + "balance": "0x2be374fe8e2c40000" + }, + "787d313fd36b053eeeaedbce74b9fb0678333289": { + "balance": "0x5c058b7842719600000" + }, + "78859c5b548b700d9284cee4b6633c2f52e529c2": { + "balance": "0xa030dcebbd2f4c0000" + }, + "788e809741a3b14a22a4b1d937c82cfea489eebe": { + "balance": "0x17b7883c06916600000" + }, + "78a1e254409fb1b55a7cb4dd8eba3b30c8bad9ef": { + "balance": "0x56bc75e2d63100000" + }, + "78a5e89900bd3f81dd71ba869d25fec65261df15": { + "balance": "0xafd812fee03d5700000" + }, + "78b978a9d7e91ee529ea4fc4b76feaf8762f698c": { + "balance": "0x6c6b935b8bbd4000000" + }, + "78ce3e3d474a8a047b92c41542242d0a08c70f99": { + "balance": "0x21e19e0c9bab2400000" + }, + "78cf8336b328db3d87813a472b9e89b75e0cf3bc": { + "balance": "0x3635c9adc5dea00000" + }, + "78d4f8c71c1e68a69a98f52fcb45da8af56ea1a0": { + "balance": "0x6c6b935b8bbd400000" + }, + "78df2681d6d602e22142d54116dea15d454957aa": { + "balance": "0x102794ad20da680000" + }, + "78e08bc533413c26e291b3143ffa7cc9afb97b78": { + "balance": "0xad78ebc5ac6200000" + }, + "78e83f80b3678c7a0a4e3e8c84dccde064426277": { + "balance": "0x61093d7c2c6d380000" + }, + "78f5c74785c5668a838072048bf8b453594ddaab": { + "balance": "0x15af1d78b58c400000" + }, + "790f91bd5d1c5cc4739ae91300db89e1c1303c93": { + "balance": "0x6c6b935b8bbd400000" + }, + "7917e5bd82a9790fd650d043cdd930f7799633db": { + "balance": "0xd8d4602c26bf6c0000" + }, + "7919e7627f9b7d54ea3b14bb4dd4649f4f39dee0": { + "balance": "0x5a87e7d7f5f6580000" + }, + "791f6040b4e3e50dcf3553f182cd97a90630b75d": { + "balance": "0xd8d726b7177a800000" + }, + "7930c2d9cbfa87f510f8f98777ff8a8448ca5629": { + "balance": "0xad6eedd17cf3b8000" + }, + "794529d09d017271359730027075b87ad83dae6e": { + "balance": "0x10ce1d3d8cb3180000" + }, + "794b51c39e53d9e762b0613b829a44b472f4fff3": { + "balance": "0x2435e0647841cc8000" + }, + "79551cede376f747e3716c8d79400d766d2e0195": { + "balance": "0x9cb37afa4ff78680000" + }, + "795ebc2626fc39b0c86294e0e837dcf523553090": { + "balance": "0x3635c9adc5dea00000" + }, + "796ebbf49b3e36d67694ad79f8ff36767ac6fab0": { + "balance": "0x34bc4fdde27c00000" + }, + "796f87ba617a2930b1670be92ed1281fb0b346e1": { + "balance": "0x6f5e86fb528280000" + }, + "797427e3dbf0feae7a2506f12df1dc40326e8505": { + "balance": "0x3635c9adc5dea00000" + }, + "797510e386f56393ced8f477378a444c484f7dad": { + "balance": "0x3635c9adc5dea00000" + }, + "797bb7f157d9feaa17f76da4f704b74dc1038341": { + "balance": "0xb50fcfafebecb00000" + }, + "7988901331e387f713faceb9005cb9b65136eb14": { + "balance": "0x6acb3df27e1f880000" + }, + "7989d09f3826c3e5af8c752a8115723a84d80970": { + "balance": "0x1686f8614cf0ad0000" + }, + "7995bd8ce2e0c67bf1c7a531d477bca1b2b97561": { + "balance": "0x14248d617829ece0000" + }, + "79aeb34566b974c35a5881dec020927da7df5d25": { + "balance": "0x6c6b935b8bbd400000" + }, + "79b120eb8806732321288f675a27a9225f1cd2eb": { + "balance": "0x85a0bf37dec9e40000" + }, + "79b48d2d6137c3854d611c01ea42427a0f597bb7": { + "balance": "0xa5aa85009e39c0000" + }, + "79b8aad879dd30567e8778d2d231c8f37ab8734e": { + "balance": "0x6c6b935b8bbd400000" + }, + "79bf2f7b6e328aaf26e0bb093fa22da29ef2f471": { + "balance": "0x61093d7c2c6d380000" + }, + "79c130c762b8765b19d2abc9a083ab8f3aad7940": { + "balance": "0xd5967be4fc3f100000" + }, + "79c1be19711f73bee4e6316ae7549459aacea2e0": { + "balance": "0x15af1d78b58c400000" + }, + "79c6002f8452ca157f1317e80a2faf24475559b7": { + "balance": "0x1158e460913d00000" + }, + "79cac6494f11ef2798748cb53285bd8e22f97cda": { + "balance": "0x6c6b935b8bbd400000" + }, + "79cfa9780ae6d87b2c31883f09276986c89a6735": { + "balance": "0x3635c9adc5dea00000" + }, + "79dba256472db4e058f2e4cdc3ea4e8a42773833": { + "balance": "0x4f2591f896a6500000" + }, + "79ed10cf1f6db48206b50919b9b697081fbdaaf3": { + "balance": "0x6c6b935b8bbd400000" + }, + "79f08e01ce0988e63c7f8f2908fade43c7f9f5c9": { + "balance": "0xfc936392801c0000" + }, + "79fd6d48315066c204f9651869c1096c14fc9781": { + "balance": "0x6c6b935b8bbd400000" + }, + "79ffb4ac13812a0b78c4a37b8275223e176bfda5": { + "balance": "0xf015f25736420000" + }, + "7a0589b143a8e5e107c9ac66a9f9f8597ab3e7ab": { + "balance": "0x51e932d76e8f7b0000" + }, + "7a0a78a9cc393f91c3d9e39a6b8c069f075e6bf5": { + "balance": "0x487a9a304539440000" + }, + "7a1370a742ec2687e761a19ac5a794329ee67404": { + "balance": "0xa2a1326761e2920000" + }, + "7a2dfc770e24368131b7847795f203f3d50d5b56": { + "balance": "0x269fec7f0361d200000" + }, + "7a33834e8583733e2d52aead589bd1affb1dd256": { + "balance": "0x3635c9adc5dea00000" + }, + "7a36aba5c31ea0ca7e277baa32ec46ce93cf7506": { + "balance": "0x43c33c1937564800000" + }, + "7a381122bada791a7ab1f6037dac80432753baad": { + "balance": "0x21e19e0c9bab2400000" + }, + "7a48d877b63a8f8f9383e9d01e53e80c528e955f": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "7a4f9b850690c7c94600dbee0ca4b0a411e9c221": { + "balance": "0x678a932062e4180000" + }, + "7a63869fc767a4c6b1cd0e0649f3634cb121d24b": { + "balance": "0x433874f632cc60000" + }, + "7a67dd043a504fc2f2fc7194e9becf484cecb1fb": { + "balance": "0xd8d726b7177a80000" + }, + "7a6b26f438d9a352449155b8876cbd17c9d99b64": { + "balance": "0x14542ba12a337c00000" + }, + "7a6d781c77c4ba1fcadf687341c1e31799e93d27": { + "balance": "0xeda838c4929080000" + }, + "7a7068e1c3375c0e599db1fbe6b2ea23b8f407d2": { + "balance": "0x6c6b935b8bbd400000" + }, + "7a74cee4fa0f6370a7894f116cd00c1147b83e59": { + "balance": "0x2b5e3af16b18800000" + }, + "7a79e30ff057f70a3d0191f7f53f761537af7dff": { + "balance": "0x15af1d78b58c400000" + }, + "7a7a4f807357a4bbe68e1aa806393210c411ccb3": { + "balance": "0x65a4da25d3016c00000" + }, + "7a8563867901206f3f2bf0fa3e1c8109cabccd85": { + "balance": "0x76d41c62494840000" + }, + "7a8797690ab77b5470bf7c0c1bba612508e1ac7d": { + "balance": "0x1e09296c3378de40000" + }, + "7a8c89c014509d56d7b68130668ff6a3ecec7370": { + "balance": "0x1043561a8829300000" + }, + "7a94b19992ceb8ce63bc92ee4b5aded10c4d9725": { + "balance": "0x38d1a8064bb64c80000" + }, + "7aa79ac04316cc8d08f20065baa6d4142897d54e": { + "balance": "0x4be4e7267b6ae00000" + }, + "7aad4dbcd3acf997df93586956f72b64d8ad94ee": { + "balance": "0xd8d726b7177a800000" + }, + "7ab256b204800af20137fabcc916a23258752501": { + "balance": "0x43c33c1937564800000" + }, + "7aba56f63a48bc0817d6b97039039a7ad62fae2e": { + "balance": "0x2086ac351052600000" + }, + "7abb10f5bd9bc33b8ec1a82d64b55b6b18777541": { + "balance": "0x43c33c1937564800000" + }, + "7ac48d40c664cc9a6d89f1c5f5c80a1c70e744e6": { + "balance": "0xa31062beeed7000000" + }, + "7ac58f6ffc4f8107ae6e30378e4e9f99c57fbb24": { + "balance": "0x22b1c8c1227a00000" + }, + "7ad3f307616f19dcb143e6444dab9c3c33611f52": { + "balance": "0x2b5e3af16b1880000" + }, + "7ad82caea1a8b4ed05319b9c9870173c814e06ee": { + "balance": "0x2164b7a04ac8a00000" + }, + "7ade5d66b944bb860c0efdc86276d58f4653f711": { + "balance": "0x6c6b935b8bbd400000" + }, + "7adfedb06d91f3cc7390450b85550270883c7bb7": { + "balance": "0x1178fa40515db40000" + }, + "7ae1c19e53c71cee4c73fae2d7fc73bf9ab5e392": { + "balance": "0x3635c9adc5dea00000" + }, + "7ae659eb3bc46852fa86fac4e21c768d50388945": { + "balance": "0xf810c1cb501b80000" + }, + "7aea25d42b2612286e99c53697c6bc4100e2dbbf": { + "balance": "0x6c6b935b8bbd400000" + }, + "7aef7b551f0b9c46e755c0f38e5b3a73fe1199f5": { + "balance": "0x50c5e761a444080000" + }, + "7b0b31ff6e24745ead8ed9bb85fc0bf2fe1d55d4": { + "balance": "0x2b5e3af16b18800000" + }, + "7b0fea1176d52159333a143c294943da36bbddb4": { + "balance": "0x1fc7da64ea14c100000" + }, + "7b11673cc019626b290cbdce26046f7e6d141e21": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "7b122162c913e7146cad0b7ed37affc92a0bf27f": { + "balance": "0x51af096b2301d18000" + }, + "7b1bf53a9cbe83a7dea434579fe72aac8d2a0cd0": { + "balance": "0xad4c8316a0b0c0000" + }, + "7b1daf14891b8a1e1bd429d8b36b9a4aa1d9afbf": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "7b1fe1ab4dfd0088cdd7f60163ef59ec2aee06f5": { + "balance": "0x6c6b935b8bbd400000" + }, + "7b25bb9ca8e702217e9333225250e53c36804d48": { + "balance": "0x65ea3db75546600000" + }, + "7b27d0d1f3dd3c140294d0488b783ebf4015277d": { + "balance": "0x15af1d78b58c400000" + }, + "7b4007c45e5a573fdbb6f8bd746bf94ad04a3c26": { + "balance": "0x33821f5135d259a0000" + }, + "7b43c7eea8d62355b0a8a81da081c6446b33e9e0": { + "balance": "0xd8d726b7177a800000" + }, + "7b4d2a38269069c18557770d591d24c5121f5e83": { + "balance": "0x25f273933db5700000" + }, + "7b6175ec9befc738249535ddde34688cd36edf25": { + "balance": "0x21e19e0c9bab2400000" + }, + "7b66126879844dfa34fe65c9f288117fefb449ad": { + "balance": "0x14542ba12a337c00000" + }, + "7b6a84718dd86e63338429ac811d7c8a860f21f1": { + "balance": "0x61093d7c2c6d380000" + }, + "7b712c7af11676006a66d2fc5c1ab4c479ce6037": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "7b73242d75ca9ad558d650290df17692d54cd8b8": { + "balance": "0x6c6e59e67c78540000" + }, + "7b761feb7fcfa7ded1f0eb058f4a600bf3a708cb": { + "balance": "0xf95dd2ec27cce00000" + }, + "7b827cae7ff4740918f2e030ab26cb98c4f46cf5": { + "balance": "0x194684c0b39de100000" + }, + "7b893286427e72db219a21fc4dcd5fbf59283c31": { + "balance": "0x21e19e0c9bab2400000" + }, + "7b9226d46fe751940bc416a798b69ccf0dfab667": { + "balance": "0xe3aeb5737240a00000" + }, + "7b98e23cb96beee80a168069ebba8f20edd55ccf": { + "balance": "0xba0c91587c14a0000" + }, + "7bb0fdf5a663b5fba28d9c902af0c811e252f298": { + "balance": "0xad78ebc5ac6200000" + }, + "7bb9571f394b0b1a8eba5664e9d8b5e840677bea": { + "balance": "0x11164759ffb320000" + }, + "7bb984c6dbb9e279966afafda59c01d02627c804": { + "balance": "0x1b464311d45a6880000" + }, + "7bbbec5e70bdead8bb32b42805988e9648c0aa97": { + "balance": "0x3636d7af5ec98e0000" + }, + "7bca1da6c80a66baa5db5ac98541c4be276b447d": { + "balance": "0x24cf049680fa3c0000" + }, + "7bddb2ee98de19ee4c91f661ee8e67a91d054b97": { + "balance": "0x3635c9adc5dea00000" + }, + "7be2f7680c802da6154c92c0194ae732517a7169": { + "balance": "0xfc936392801c0000" + }, + "7be7f2456971883b9a8dbe4c91dec08ac34e8862": { + "balance": "0xa2a15d09519be00000" + }, + "7be8ccb4f11b66ca6e1d57c0b5396221a31ba53a": { + "balance": "0x1158e460913d00000" + }, + "7beb81fb2f5e91526b2ac9795e76c69bcff04bc0": { + "balance": "0xeb22e794f0a8d600000" + }, + "7c0883054c2d02bc7a852b1f86c42777d0d5c856": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "7c0f5e072043c9ee740242197e78cc4b98cdf960": { + "balance": "0xad78ebc5ac6200000" + }, + "7c1df24a4f7fb2c7b472e0bb006cb27dcd164156": { + "balance": "0x3635c9adc5dea00000" + }, + "7c29d47d57a733f56b9b217063b513dc3b315923": { + "balance": "0xd8d726b7177a800000" + }, + "7c2b9603884a4f2e464eceb97d17938d828bc02c": { + "balance": "0xa2a15d09519be00000" + }, + "7c382c0296612e4e97e440e02d3871273b55f53b": { + "balance": "0xab640391201300000" + }, + "7c3eb713c4c9e0381cd8154c7c9a7db8645cde17": { + "balance": "0xad78ebc5ac6200000" + }, + "7c4401ae98f12ef6de39ae24cf9fc51f80eba16b": { + "balance": "0xad78ebc5ac6200000" + }, + "7c45f0f8442a56dbd39dbf159995415c52ed479b": { + "balance": "0x6c6b935b8bbd400000" + }, + "7c532db9e0c06c26fd40acc56ac55c1ee92d3c3a": { + "balance": "0x3f870857a3e0e3800000" + }, + "7c60a05f7a4a5f8cf2784391362e755a8341ef59": { + "balance": "0x6694f0182a37ae0000" + }, + "7c60e51f0be228e4d56fdd2992c814da7740c6bc": { + "balance": "0xad78ebc5ac6200000" + }, + "7c6924d07c3ef5891966fe0a7856c87bef9d2034": { + "balance": "0x6c6b935b8bbd400000" + }, + "7c8bb65a6fbb49bd413396a9d7e31053bbb37aa9": { + "balance": "0x14542ba12a337c00000" + }, + "7c9a110cb11f2598b2b20e2ca400325e41e9db33": { + "balance": "0x581767ba6189c400000" + }, + "7cbca88fca6a0060b960985c9aa1b02534dc2208": { + "balance": "0x19127a1391ea2a0000" + }, + "7cbeb99932e97e6e02058cfc62d0b26bc7cca52b": { + "balance": "0x6c6b935b8bbd400000" + }, + "7cc24a6a958c20c7d1249660f7586226950b0d9a": { + "balance": "0x6acb3df27e1f880000" + }, + "7cd20eccb518b60cab095b720f571570caaa447e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "7cd5d81eab37e11e6276a3a1091251607e0d7e38": { + "balance": "0x3684d5ef981f40000" + }, + "7cdf74213945953db39ad0e8a9781add792e4d1d": { + "balance": "0x6c6b935b8bbd400000" + }, + "7ce4686446f1949ebed67215eb0d5a1dd72c11b8": { + "balance": "0x7839d321b81ab80000" + }, + "7cef4d43aa417f9ef8b787f8b99d53f1fea1ee88": { + "balance": "0x678a932062e4180000" + }, + "7d0350e40b338dda736661872be33f1f9752d755": { + "balance": "0x2b4f5a6f191948000" + }, + "7d04d2edc058a1afc761d9c99ae4fc5c85d4c8a6": { + "balance": "0x42a9c4675c9467d00000" + }, + "7d0b255efb57e10f7008aa22d40e9752dfcf0378": { + "balance": "0x19f8e7559924c0000" + }, + "7d13d6705884ab2157dd8dcc7046caf58ee94be4": { + "balance": "0x1d0da07cbb3ee9c00000" + }, + "7d273e637ef1eac481119413b91c989dc5eac122": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "7d2a52a7cf0c8436a8e007976b6c26b7229d1e15": { + "balance": "0x17bf06b32a241c0000" + }, + "7d34803569e00bd6b59fff081dfa5c0ab4197a62": { + "balance": "0x5cd87cb7b9fb860000" + }, + "7d34ff59ae840a7413c6ba4c5bb2ba2c75eab018": { + "balance": "0xa2a15d09519be00000" + }, + "7d392852f3abd92ff4bb5bb26cb60874f2be6795": { + "balance": "0x3636c25e66ece70000" + }, + "7d445267c59ab8d2a2d9e709990e09682580c49f": { + "balance": "0x3635c9adc5dea00000" + }, + "7d551397f79a2988b064afd0efebee802c7721bc": { + "balance": "0x857e0d6f1da76a00000" + }, + "7d5aa33fc14b51841a06906edb2bb49c2a117269": { + "balance": "0x104400a2470e680000" + }, + "7d5d2f73949dadda0856b206989df0078d51a1e5": { + "balance": "0x23c757072b8dd000000" + }, + "7d6e990daa7105de2526339833f77b5c0b85d84f": { + "balance": "0x43c33c1937564800000" + }, + "7d73863038ccca22f96affda10496e51e1e6cd48": { + "balance": "0x1158e460913d00000" + }, + "7d7dd5ee614dbb6fbfbcd26305247a058c41faa1": { + "balance": "0x6c6b935b8bbd400000" + }, + "7d7e7c61779adb7706c94d32409a2bb4e994bf60": { + "balance": "0x2ef20d9fc71a140000" + }, + "7d82e523cc2dc591da3954e8b6bb2caf6461e69c": { + "balance": "0x7d8dc2efffb1a90000" + }, + "7d858493f07415e0912d05793c972113eae8ae88": { + "balance": "0x628dd177d2bc280000" + }, + "7d901b28bf7f88ef73d8f73cca97564913ea8a24": { + "balance": "0x33c5499031720c0000" + }, + "7d980f4b566bb045517e4c14c87750de9346744b": { + "balance": "0x487a9a304539440000" + }, + "7d9c59631e2ba2e8e82891f3979922aaa3b567a1": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "7d9d221a3df89ddd7b5f61c1468c6787d6b333e6": { + "balance": "0x77b227cd83be80000" + }, + "7da7613445a21299aa74f0ad71431ec43fbb1be9": { + "balance": "0x3afb087b876900000" + }, + "7db4c7d5b797e9296e6382f203693db409449d62": { + "balance": "0x15af1d78b58c400000" + }, + "7db9eacc52e429dc83b461c5f4d86010e5383a28": { + "balance": "0x3635c9adc5dea00000" + }, + "7dd46da677e161825e12e80dc446f58276e1127c": { + "balance": "0x2c73c937742c500000" + }, + "7dd8d7a1a34fa1f8e73ccb005fc2a03a15b8229c": { + "balance": "0xad78ebc5ac6200000" + }, + "7ddd57165c87a2707f025dcfc2508c09834759bc": { + "balance": "0x4be4e7267b6ae00000" + }, + "7de442c82386154d2e993cbd1280bb7ca6b12ada": { + "balance": "0xd8f2e8247ec9480000" + }, + "7de7fe419cc61f91f408d234cc80d5ca3d054d99": { + "balance": "0x1158e460913d00000" + }, + "7dece6998ae1900dd3770cf4b93812bad84f0322": { + "balance": "0x56bc75e2d63100000" + }, + "7dfc342dffcf45dfee74f84c0995397bd1a63172": { + "balance": "0xd8d726b7177a80000" + }, + "7dfd2962b575bcbeee97f49142d63c30ab009f66": { + "balance": "0xd8d726b7177a800000" + }, + "7e1e29721d6cb91057f6c4042d8a0bbc644afe73": { + "balance": "0x8a9aba557e36c0000" + }, + "7e236666b2d06e63ea4e2ab84357e2dfc977e50e": { + "balance": "0x36356633ebd8ea0000" + }, + "7e24d9e22ce1da3ce19f219ccee523376873f367": { + "balance": "0x13fd9079caa60ff0000" + }, + "7e24fbdad290175eb2df6d180a19b9a9f41370be": { + "balance": "0x3635c9adc5dea00000" + }, + "7e268f131ddf687cc325c412f78ba961205e9112": { + "balance": "0x36364ee7d301b3c0000" + }, + "7e29290038493559194e946d4e460b96fc38a156": { + "balance": "0x10c13c527763880000" + }, + "7e2ba86da52e785d8625334f3397ba1c4bf2e8d1": { + "balance": "0xaadec983fcff40000" + }, + "7e3f63e13129a221ba1ab06326342cd98b5126ae": { + "balance": "0x56a02659a523340000" + }, + "7e47637e97c14622882be057bea229386f4052e5": { + "balance": "0x17da3a04c7b3e00000" + }, + "7e4e9409704121d1d77997026ff06ea9b19a8b90": { + "balance": "0x8d16549ed58fa40000" + }, + "7e59dc60be8b2fc19abd0a5782c52c28400bce97": { + "balance": "0x3635c9adc5dea00000" + }, + "7e5b19ae1be94ff4dee635492a1b012d14db0213": { + "balance": "0x56bc75e2d63100000" + }, + "7e5d9993104e4cb545e179a2a3f971f744f98482": { + "balance": "0x6c6b935b8bbd400000" + }, + "7e71171f2949fa0c3ac254254b1f0440e5e6a038": { + "balance": "0x22b1c8c1227a00000" + }, + "7e7c1e9a61a08a83984835c70ec31d34d3eaa87f": { + "balance": "0xa5aa85009e39c0000" + }, + "7e7f18a02eccaa5d61ab8fbf030343c434a25ef7": { + "balance": "0x39fbae8d042dd0000" + }, + "7e81f6449a03374191f3b7cb05d938b72e090dff": { + "balance": "0x56bc75e2d63100000" + }, + "7e8649e690fc8c1bfda1b5e186581f649b50fe33": { + "balance": "0x556f64c1fe7fa0000" + }, + "7e87863ec43a481df04d017762edcb5caa629b5a": { + "balance": "0x222c8eb3ff6640000" + }, + "7e8f96cc29f57b0975120cb593b7dd833d606b53": { + "balance": "0xaadec983fcff40000" + }, + "7e972a8a7c2a44c93b21436c38d21b9252c345fe": { + "balance": "0x61093d7c2c6d380000" + }, + "7e99dfbe989d3ba529d19751b7f4317f8953a3e2": { + "balance": "0x15af1d78b58c400000" + }, + "7ea0f96ee0a573a330b56897761f3d4c0130a8e3": { + "balance": "0x487a9a304539440000" + }, + "7ea791ebab0445a00efdfc4e4a8e9a7e7565136d": { + "balance": "0xfc936392801c0000" + }, + "7eaba035e2af3793fd74674b102540cf190addb9": { + "balance": "0x45026c835b60440000" + }, + "7eb4b0185c92b6439a08e7322168cb353c8a774a": { + "balance": "0x227196ca04983ca0000" + }, + "7ebd95e9c470f7283583dc6e9d2c4dce0bea8f84": { + "balance": "0x2f6f10780d22cc00000" + }, + "7ed0a5a847bef9a9da7cba1d6411f5c316312619": { + "balance": "0x228eb37e8751d0000" + }, + "7edafba8984baf631a820b6b92bbc2c53655f6bd": { + "balance": "0x6c6b935b8bbd400000" + }, + "7edb02c61a227287611ad950696369cc4e647a68": { + "balance": "0xeda838c4929080000" + }, + "7ee5ca805dce23af89c2d444e7e40766c54c7404": { + "balance": "0xd0bd412edbd820000" + }, + "7ee604c7a9dc2909ce321de6b9b24f5767577555": { + "balance": "0x12bf9c7985cf62d8000" + }, + "7ef16fd8d15b378a0fba306b8d03dd98fc92619f": { + "balance": "0x25f273933db5700000" + }, + "7ef98b52bee953bef992f305fda027f8911c5851": { + "balance": "0x1be722206996bc8000" + }, + "7efc90766a00bc52372cac97fabd8a3c831f8ecd": { + "balance": "0x890b0c2e14fb80000" + }, + "7efec0c6253caf397f71287c1c07f6c9582b5b86": { + "balance": "0x1a2cbcb84f30d58000" + }, + "7f01dc7c3747ca608f983dfc8c9b39e755a3b914": { + "balance": "0xb386cad5f7a5a0000" + }, + "7f0662b410298c99f311d3a1454a1eedba2fea76": { + "balance": "0xad78ebc5ac6200000" + }, + "7f06c89d59807fa60bc60136fcf814cbaf2543bd": { + "balance": "0x21e19e0c9bab2400000" + }, + "7f0b90a1fdd48f27b268feb38382e55ddb50ef0f": { + "balance": "0x32f51edbaaa3300000" + }, + "7f0ec3db804692d4d1ea3245365aab0590075bc4": { + "balance": "0xd8d726b7177a800000" + }, + "7f0f04fcf37a53a4e24ede6e93104e78be1d3c9e": { + "balance": "0x6c6b935b8bbd400000" + }, + "7f13d760498d7193ca6859bc95c901386423d76c": { + "balance": "0x10f0cf064dd59200000" + }, + "7f150afb1a77c2b45928c268c1e9bdb4641d47d8": { + "balance": "0x6c6b935b8bbd400000" + }, + "7f1619988f3715e94ff1d253262dc5581db3de1c": { + "balance": "0x30ca024f987b900000" + }, + "7f1c81ee1697fc144b7c0be5493b5615ae7fddca": { + "balance": "0x1b1dab61d3aa640000" + }, + "7f2382ffd8f83956467937f9ba72374623f11b38": { + "balance": "0x2086ac351052600000" + }, + "7f3709391f3fbeba3592d175c740e87a09541d02": { + "balance": "0x1a055690d9db800000" + }, + "7f389c12f3c6164f6446566c77669503c2792527": { + "balance": "0x556f64c1fe7fa0000" + }, + "7f3a1e45f67e92c880e573b43379d71ee089db54": { + "balance": "0x152d02c7e14af6800000" + }, + "7f3d7203c8a447f7bf36d88ae9b6062a5eee78ae": { + "balance": "0x14542ba12a337c00000" + }, + "7f46bb25460dd7dae4211ca7f15ad312fc7dc75c": { + "balance": "0x16a6502f15a1e540000" + }, + "7f49e7a4269882bd8722d4a6f566347629624079": { + "balance": "0x6c6b935b8bbd400000" + }, + "7f49f20726471ac1c7a83ef106e9775ceb662566": { + "balance": "0x14061b9d77a5e980000" + }, + "7f4b5e278578c046cceaf65730a0e068329ed5b6": { + "balance": "0x65ea3db75546600000" + }, + "7f4f593b618c330ba2c3d5f41eceeb92e27e426c": { + "balance": "0x966edc756b7cfc0000" + }, + "7f541491d2ac00d2612f94aa7f0bcb014651fbd4": { + "balance": "0x14620c57dddae00000" + }, + "7f5ae05ae0f8cbe5dfe721f044d7a7bef4c27997": { + "balance": "0x340aad21b3b700000" + }, + "7f603aec1759ea5f07c7f8d41a1428fbbaf9e762": { + "balance": "0x1158e460913d00000" + }, + "7f616c6f008adfa082f34da7d0650460368075fb": { + "balance": "0x3635c9adc5dea00000" + }, + "7f61fa6cf5f898b440dac5abd8600d6d691fdef9": { + "balance": "0xf2dc7d47f15600000" + }, + "7f655c6789eddf455cb4b88099720639389eebac": { + "balance": "0x14542ba12a337c00000" + }, + "7f6b28c88421e4857e459281d78461692489d3fb": { + "balance": "0x6c6b935b8bbd400000" + }, + "7f6efb6f4318876d2ee624e27595f44446f68e93": { + "balance": "0x54069233bf7f780000" + }, + "7f7192c0df1c7db6d9ed65d71184d8e4155a17ba": { + "balance": "0x453728d33942c0000" + }, + "7f7a3a21b3f5a65d81e0fcb7d52dd00a1aa36dba": { + "balance": "0x56bc75e2d63100000" + }, + "7f8dbce180ed9c563635aad2d97b4cbc428906d9": { + "balance": "0x90f534608a72880000" + }, + "7f993ddb7e02c282b898f6155f680ef5b9aff907": { + "balance": "0x43c33c1937564800000" + }, + "7f9f9b56e4289dfb58e70fd5f12a97b56d35c6a5": { + "balance": "0x6acb3df27e1f880000" + }, + "7fa37ed67887751a471f0eb306be44e0dbcd6089": { + "balance": "0x3976747fe11a100000" + }, + "7faa30c31519b584e97250ed2a3cf3385ed5fd50": { + "balance": "0x6c6b935b8bbd400000" + }, + "7fcf5ba6666f966c5448c17bf1cb0bbcd8019b06": { + "balance": "0x56bc3d0aebe498000" + }, + "7fd679e5fb0da2a5d116194dcb508318edc580f3": { + "balance": "0x1639e49bba162800000" + }, + "7fdba031c78f9c096d62d05a369eeab0bccc55e5": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "7fdbc3a844e40d96b2f3a635322e6065f4ca0e84": { + "balance": "0x6c6b935b8bbd400000" + }, + "7fdfc88d78bf1b285ac64f1adb35dc11fcb03951": { + "balance": "0x7c06fda02fb0360000" + }, + "7fea1962e35d62059768c749bedd96cab930d378": { + "balance": "0x6c6b935b8bbd400000" + }, + "7fef8c38779fb307ec6f044bebe47f3cfae796f1": { + "balance": "0x92340f86cf09e8000" + }, + "7ff0c63f70241bece19b737e5341b12b109031d8": { + "balance": "0x12c1b6eed03d280000" + }, + "7ffabfbc390cbe43ce89188f0868b27dcb0f0cad": { + "balance": "0x1595182224b26480000" + }, + "7ffd02ed370c7060b2ae53c078c8012190dfbb75": { + "balance": "0x21e19e0c9bab2400000" + }, + "80022a1207e910911fc92849b069ab0cdad043d3": { + "balance": "0xb98bc829a6f90000" + }, + "8009a7cbd192b3aed4adb983d5284552c16c7451": { + "balance": "0xd8d726b7177a800000" + }, + "800e7d631c6e573a90332f17f71f5fd19b528cb9": { + "balance": "0x83d6c7aab63600000" + }, + "80156d10efa8b230c99410630d37e269d4093cea": { + "balance": "0x6c6b935b8bbd400000" + }, + "801732a481c380e57ed62d6c29de998af3fa3b13": { + "balance": "0x56bc75e2d63100000" + }, + "801d65c518b11d0e3f4f470221417013c8e53ec5": { + "balance": "0xd8d726b7177a800000" + }, + "8026435aac728d497b19b3e7e57c28c563954f2b": { + "balance": "0x5dc892aa1131c80000" + }, + "802dc3c4ff2d7d925ee2859f4a06d7ba60f1308c": { + "balance": "0x550940c8fd34c0000" + }, + "8030b111c6983f0485ddaca76224c6180634789f": { + "balance": "0x4563918244f400000" + }, + "8035bcffaefdeeea35830c497d14289d362023de": { + "balance": "0x1043561a8829300000" + }, + "8035fe4e6b6af27ae492a578515e9d39fa6fa65b": { + "balance": "0xd8d726b7177a800000" + }, + "8043ed22f997e5a2a4c16e364486ae64975692c4": { + "balance": "0x3d4904ffc9112e8000" + }, + "8043fdd0bc4c973d1663d55fc135508ec5d4f4fa": { + "balance": "0x1158e460913d00000" + }, + "804ca94972634f633a51f3560b1d06c0b293b3b1": { + "balance": "0xad78ebc5ac6200000" + }, + "80522ddf944ec52e27d724ed4c93e1f7be6083d6": { + "balance": "0xad78ebc5ac6200000" + }, + "80591a42179f34e64d9df75dcd463b28686f5574": { + "balance": "0x43c33c1937564800000" + }, + "805ce51297a0793b812067f017b3e7b2df9bb1f9": { + "balance": "0x56bc75e2d63100000" + }, + "805d846fb0bc02a7337226d685be9ee773b9198a": { + "balance": "0x43c30fb0884a96c0000" + }, + "8063379a7bf2cb923a84c5093e68dac7f75481c5": { + "balance": "0x1176102e6e32df0000" + }, + "806854588ecce541495f81c28a290373df0274b2": { + "balance": "0x1f8cdf5c6e8d580000" + }, + "806f44bdeb688037015e84ff218049e382332a33": { + "balance": "0x6c5db2a4d815dc0000" + }, + "80744618de396a543197ee4894abd06398dd7c27": { + "balance": "0x6c6b935b8bbd400000" + }, + "8077c3e4c445586e094ce102937fa05b737b568c": { + "balance": "0x56bc75e2d63100000" + }, + "80907f593148b57c46c177e23d25abc4aae18361": { + "balance": "0x56bc75e2d63100000" + }, + "80977316944e5942e79b0e3abad38da746086519": { + "balance": "0x21a754a6dc5280000" + }, + "80a0f6cc186cf6201400736e065a391f52a9df4a": { + "balance": "0x21e19e0c9bab2400000" + }, + "80abec5aa36e5c9d098f1b942881bd5acac6963d": { + "balance": "0x6c6b935b8bbd400000" + }, + "80b23d380b825c46e0393899a85556462da0e18c": { + "balance": "0x6c6b935b8bbd400000" + }, + "80b42de170dbd723f454e88f7716452d92985092": { + "balance": "0x104623c0762dd10000" + }, + "80b79f338390d1ba1b3737a29a0257e5d91e0731": { + "balance": "0x1158e460913d00000" + }, + "80bf995ed8ba92701d10fec49f9e7d014dbee026": { + "balance": "0x1f0437ca1a7e128000" + }, + "80c04efd310f440483c73f744b5b9e64599ce3ec": { + "balance": "0x410d586a20a4c00000" + }, + "80c3a9f695b16db1597286d1b3a8b7696c39fa27": { + "balance": "0x56bc75e2d63100000" + }, + "80c53ee7e3357f94ce0d7868009c208b4a130125": { + "balance": "0x6c6b935b8bbd400000" + }, + "80cc21bd99f39005c58fe4a448909220218f66cb": { + "balance": "0x3636c9796436740000" + }, + "80d5c40c59c7f54ea3a55fcfd175471ea35099b3": { + "balance": "0x3635c9adc5dea00000" + }, + "80da2fdda29a9e27f9e115975e69ae9cfbf3f27e": { + "balance": "0xad78ebc5ac6200000" + }, + "80e7b3205230a566a1f061d922819bb4d4d2a0e1": { + "balance": "0x2f6f10780d22cc00000" + }, + "80ea1acc136eca4b68c842a95adf6b7fee7eb8a2": { + "balance": "0xd8d726b7177a800000" + }, + "80f07ac09e7b2c3c0a3d1e9413a544c73a41becb": { + "balance": "0x1158e460913d00000" + }, + "810db25675f45ea4c7f3177f37ce29e22d67999c": { + "balance": "0xad78ebc5ac6200000" + }, + "81139bfdcca656c430203f72958c543b6580d40c": { + "balance": "0x6c6b935b8bbd400000" + }, + "811461a2b0ca90badac06a9ea16e787b33b196cc": { + "balance": "0x8e3f50b173c100000" + }, + "81164deb10814ae08391f32c08667b6248c27d7a": { + "balance": "0x155bd9307f9fe80000" + }, + "81186931184137d1192ac88cd3e1e5d0fdb86a74": { + "balance": "0x9d3595ab2438d00000" + }, + "812a55c43caedc597218379000ce510d548836fd": { + "balance": "0xfc936392801c0000" + }, + "812ea7a3b2c86eed32ff4f2c73514cc63bacfbce": { + "balance": "0x3635c9adc5dea00000" + }, + "8134dd1c9df0d6c8a5812426bb55c761ca831f08": { + "balance": "0x6a2160bb57ccc0000" + }, + "814135da8f9811075783bf1ab67062af8d3e9f40": { + "balance": "0x1158e460913d00000" + }, + "81498ca07b0f2f17e8bbc7e61a7f4ae7be66b78b": { + "balance": "0x581fbb5b33bb00000" + }, + "81556db27349ab8b27004944ed50a46e941a0f5f": { + "balance": "0xd8bb6549b02bb80000" + }, + "8155fa6c51eb31d808412d748aa086105018122f": { + "balance": "0x65ea3db75546600000" + }, + "8156360bbd370961ceca6b6691d75006ad204cf2": { + "balance": "0x878678326eac9000000" + }, + "8161d940c3760100b9080529f8a60325030f6edc": { + "balance": "0x1043561a8829300000" + }, + "8164e78314ae16b28926cc553d2ccb16f356270d": { + "balance": "0x1ca134e95fb32c80000" + }, + "8165cab0eafb5a328fc41ac64dae715b2eef2c65": { + "balance": "0x3635c9adc5dea00000" + }, + "8168edce7f2961cf295b9fcd5a45c06cdeda6ef5": { + "balance": "0xad78ebc5ac6200000" + }, + "816d9772cf11399116cc1e72c26c6774c9edd739": { + "balance": "0xad78ebc5ac6200000" + }, + "8173c835646a672e0152be10ffe84162dd256e4c": { + "balance": "0x1aabdf2145b4300000" + }, + "817493cd9bc623702a24a56f9f82e3fd48f3cd31": { + "balance": "0x9e4b23f12d4ca00000" + }, + "8179c80970182cc5b7d82a4df06ea94db63a25f3": { + "balance": "0x276f259de66bf40000" + }, + "817ac33bd8f847567372951f4a10d7a91ce3f430": { + "balance": "0xad7c406c66dc18000" + }, + "818ffe271fc3973565c303f213f6d2da89897ebd": { + "balance": "0x136e05342fee1b98000" + }, + "8197948121732e63d9c148194ecad46e30b749c8": { + "balance": "0xd8d726b7177a800000" + }, + "819af9a1c27332b1c369bbda1b3de1c6e933d640": { + "balance": "0x1109e654b98f7a0000" + }, + "819cdaa5303678ef7cec59d48c82163acc60b952": { + "balance": "0x31351545f79816c0000" + }, + "819eb4990b5aba5547093da12b6b3c1093df6d46": { + "balance": "0x3635c9adc5dea00000" + }, + "81a88196fac5f23c3e12a69dec4b880eb7d97310": { + "balance": "0x6c6b935b8bbd400000" + }, + "81bccbff8f44347eb7fca95b27ce7c952492aaad": { + "balance": "0x840c12165dd780000" + }, + "81bd75abd865e0c3f04a0b4fdbcb74d34082fbb7": { + "balance": "0xd8d726b7177a800000" + }, + "81c18c2a238ddc4cba230a072dd7dc101e620273": { + "balance": "0x487a9a304539440000" + }, + "81c9e1aee2d3365d53bcfdcd96c7c538b0fd7eec": { + "balance": "0x62a992e53a0af00000" + }, + "81cfad760913d3c322fcc77b49c2ae3907e74f6e": { + "balance": "0xaadec983fcff40000" + }, + "81d619ff5726f2405f12904c72eb1e24a0aaee4f": { + "balance": "0x43c33c1937564800000" + }, + "81efe296ae76c860d1c5fbd33d47e8ce9996d157": { + "balance": "0x3635c9adc5dea00000" + }, + "81f8de2c283d5fd4afbda85dedf9760eabbbb572": { + "balance": "0xa2a15d09519be00000" + }, + "820c19291196505b65059d9914b7090be1db87de": { + "balance": "0x796e3ea3f8ab00000" + }, + "821cb5cd05c7ef909fe1be60733d8963d760dc41": { + "balance": "0xd8d726b7177a800000" + }, + "821d798af19989c3ae5b84a7a7283cd7fda1fabe": { + "balance": "0x43c33c1937564800000" + }, + "821eb90994a2fbf94bdc3233910296f76f9bf6e7": { + "balance": "0x21e19e0c9bab2400000" + }, + "82249fe70f61c6b16f19a324840fdc020231bb02": { + "balance": "0x20336b08a93635b0000" + }, + "8228ebc087480fd64547ca281f5eace3041453b9": { + "balance": "0x6acb3df27e1f880000" + }, + "8229ceb9f0d70839498d44e6abed93c5ca059f5d": { + "balance": "0x1a1c1b3c989a20100000" + }, + "822edff636563a6106e52e9a2598f7e6d0ef2782": { + "balance": "0x1f4f9693d42d38000" + }, + "823219a25976bb2aa4af8bad41ac3526b493361f": { + "balance": "0x6c6b935b8bbd400000" + }, + "8232d1f9742edf8dd927da353b2ae7b4cbce7592": { + "balance": "0x243d4d18229ca20000" + }, + "8234f463d18485501f8f85ace4972c9b632dbccc": { + "balance": "0x6c6b935b8bbd400000" + }, + "823768746737ce6da312d53e54534e106f967cf3": { + "balance": "0x1158e460913d00000" + }, + "823ba7647238d113bce9964a43d0a098118bfe4d": { + "balance": "0xad78ebc5ac6200000" + }, + "824074312806da4748434266ee002140e3819ac2": { + "balance": "0x51b1d3839261ac0000" + }, + "82438fd2b32a9bdd674b49d8cc5fa2eff9781847": { + "balance": "0x1158e460913d00000" + }, + "82485728d0e281563758c75ab27ed9e882a0002d": { + "balance": "0x7f808e9291e6c0000" + }, + "824b3c3c443e19295d7ef6faa7f374a4798486a8": { + "balance": "0x1158e460913d00000" + }, + "8251358ca4e060ddb559ca58bc0bddbeb4070203": { + "balance": "0x6c6b935b8bbd400000" + }, + "825135b1a7fc1605614c8aa4d0ac6dbad08f480e": { + "balance": "0x4d853c8f8908980000" + }, + "825309a7d45d1812f51e6e8df5a7b96f6c908887": { + "balance": "0x8034f7d9b166d40000" + }, + "825a7f4e10949cb6f8964268f1fa5f57e712b4c4": { + "balance": "0x1158e460913d00000" + }, + "8261fa230c901d43ff579f4780d399f31e6076bc": { + "balance": "0x6c6b935b8bbd400000" + }, + "8262169b615870134eb4ac6c5f471c6bf2f789fc": { + "balance": "0x19127a1391ea2a0000" + }, + "8263ece5d709e0d7ae71cca868ed37cd2fef807b": { + "balance": "0x35ab028ac154b80000" + }, + "826ce5790532e0548c6102a30d3eac836bd6388f": { + "balance": "0x3cfc82e37e9a7400000" + }, + "826eb7cd7319b82dd07a1f3b409071d96e39677f": { + "balance": "0x3635c9adc5dea00000" + }, + "827531a6c5817ae35f82b00b9754fcf74c55e232": { + "balance": "0xc328093e61ee400000" + }, + "8275cd684c3679d5887d03664e338345dc3cdde1": { + "balance": "0xdb44e049bb2c0000" + }, + "8284923b62e68bbf7c2b9f3414d13ef6c812a904": { + "balance": "0xd255d112e103a00000" + }, + "828ba651cb930ed9787156299a3de44cd08b7212": { + "balance": "0x487a9a304539440000" + }, + "82a15cef1d6c8260eaf159ea3f0180d8677dce1c": { + "balance": "0x6c6b935b8bbd400000" + }, + "82a8b96b6c9e13ebec1e9f18ac02a60ea88a48ff": { + "balance": "0x6c6b8c408e73b30000" + }, + "82a8cbbfdff02b2e38ae4bbfca15f1f0e83b1aea": { + "balance": "0x49b991c27ef6d8000" + }, + "82e4461eb9d849f0041c1404219e4272c4900ab4": { + "balance": "0x6c6b935b8bbd400000" + }, + "82e577b515cb2b0860aafe1ce09a59e09fe7d040": { + "balance": "0x2086ac351052600000" + }, + "82ea01e3bf2e83836e71704e22a2719377efd9c3": { + "balance": "0xa4cc799563c3800000" + }, + "82f2e991fd324c5f5d17768e9f61335db6319d6c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "82f39b2758ae42277b86d69f75e628d958ebcab0": { + "balance": "0x878678326eac9000000" + }, + "82f854c9c2f087dffa985ac8201e626ca5467686": { + "balance": "0x152d02c7e14af6800000" + }, + "82ff716fdf033ec7e942c909d9831867b8b6e2ef": { + "balance": "0x61093d7c2c6d380000" + }, + "8308ed0af7f8a3c1751fafc877b5a42af7d35882": { + "balance": "0x3635c9adc5dea00000" + }, + "831c44b3084047184b2ad218680640903750c45d": { + "balance": "0x6acb3df27e1f880000" + }, + "83210583c16a4e1e1dac84ebd37e3d0f7c57eba4": { + "balance": "0x6c6b935b8bbd400000" + }, + "832c54176bdf43d2c9bcd7b808b89556b89cbf31": { + "balance": "0xad78ebc5ac6200000" + }, + "833316985d47742bfed410604a91953c05fb12b0": { + "balance": "0x6c6b935b8bbd400000" + }, + "8334764b7b397a4e578f50364d60ce44899bff94": { + "balance": "0x503b203e9fba20000" + }, + "833b6a8ec8da408186ac8a7d2a6dd61523e7ce84": { + "balance": "0x3635c9adc5dea000000" + }, + "833d3fae542ad5f8b50ce19bde2bec579180c88c": { + "balance": "0x12c1b6eed03d280000" + }, + "833db42c14163c7be4cab86ac593e06266d699d5": { + "balance": "0x24e40d2b6943ef900000" + }, + "83563bc364ed81a0c6da3b56ff49bbf267827a9c": { + "balance": "0x3ab91d17b20de500000" + }, + "837a645dc95c49549f899c4e8bcf875324b2f57c": { + "balance": "0x208c394af1c8880000" + }, + "838bd565f99fde48053f7917fe333cf84ad548ab": { + "balance": "0xad78ebc5ac6200000" + }, + "83908aa7478a6d1c9b9b0281148f8f9f242b9fdc": { + "balance": "0x6c6b935b8bbd400000" + }, + "8392e53776713578015bff4940cf43849d7dcba1": { + "balance": "0x84df0355d56170000" + }, + "8397a1bc47acd647418159b99cea57e1e6532d6e": { + "balance": "0x1f10fa827b550b40000" + }, + "8398e07ebcb4f75ff2116de77c1c2a99f303a4cf": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "83a3148833d9644984f7c475a7850716efb480ff": { + "balance": "0xb8507a820728200000" + }, + "83a402438e0519773d5448326bfb61f8b20cf52d": { + "balance": "0x52663ccab1e1c00000" + }, + "83a93b5ba41bf88720e415790cdc0b67b4af34c4": { + "balance": "0xad78ebc5ac6200000" + }, + "83c23d8a502124ee150f08d71dc6727410a0f901": { + "balance": "0x7331f3bfe661b180000" + }, + "83c897a84b695eebe46679f7da19d776621c2694": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "83d532d38d6dee3f60adc68b936133c7a2a1b0dd": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "83dbf8a12853b40ac61996f8bf1dc8fdbaddd329": { + "balance": "0x34957444b840e80000" + }, + "83dbfd8eda01d0de8e158b16d0935fc2380a5dc7": { + "balance": "0x2086ac351052600000" + }, + "83e48055327c28b5936fd9f4447e73bdb2dd3376": { + "balance": "0x90f534608a72880000" + }, + "83fe5a1b328bae440711beaf6aad6026eda6d220": { + "balance": "0x43c33c1937564800000" + }, + "84008a72f8036f3feba542e35078c057f32a8825": { + "balance": "0x56bc75e2d63100000" + }, + "840ec83ea93621f034e7bb3762bb8e29ded4c479": { + "balance": "0x878678326eac900000" + }, + "841145b44840c946e21dbc190264b8e0d5029369": { + "balance": "0x3f870857a3e0e3800000" + }, + "84232107932b12e03186583525ce023a703ef8d9": { + "balance": "0x6c6b935b8bbd400000" + }, + "84244fc95a6957ed7c1504e49f30b8c35eca4b79": { + "balance": "0x6c6b935b8bbd400000" + }, + "8431277d7bdd10457dc017408c8dbbbd414a8df3": { + "balance": "0x222c8eb3ff6640000" + }, + "84375afbf59b3a1d61a1be32d075e0e15a4fbca5": { + "balance": "0xad78ebc5ac6200000" + }, + "843bd3502f45f8bc4da370b323bdac3fcf5f19a6": { + "balance": "0x50039d63d11c900000" + }, + "84503334630d77f74147f68b2e086613c8f1ade9": { + "balance": "0x56bc75e2d631000000" + }, + "845203750f7148a9aa262921e86d43bf641974fd": { + "balance": "0x56bc75e2d63100000" + }, + "8461ecc4a6a45eb1a5b947fb86b88069b91fcd6f": { + "balance": "0x6c6b935b8bbd400000" + }, + "84675e9177726d45eaa46b3992a340ba7f710c95": { + "balance": "0x3635c9adc5dea00000" + }, + "84686c7bad762c54b667d59f90943cd14d117a26": { + "balance": "0x1158e460913d00000" + }, + "8489f6ad1d9a94a297789156899db64154f1dbb5": { + "balance": "0x137407c03c8c268000" + }, + "848c994a79003fe7b7c26cc63212e1fc2f9c19eb": { + "balance": "0x6c6b935b8bbd400000" + }, + "848fbd29d67cf4a013cb02a4b176ef244e9ee68d": { + "balance": "0x1172a636bbdc20000" + }, + "84949dba559a63bfc845ded06e9f2d9b7f11ef24": { + "balance": "0x6c6b935b8bbd400000" + }, + "849ab80790b28ff1ffd6ba394efc7463105c36f7": { + "balance": "0x1e02be4ae6c840000" + }, + "849b116f596301c5d8bb62e0e97a8248126e39f3": { + "balance": "0x1043561a8829300000" + }, + "84a74ceecff65cb93b2f949d773ef1ad7fb4a245": { + "balance": "0x50a9b444685c70000" + }, + "84aac7fa197ff85c30e03b7a5382b957f41f3afb": { + "balance": "0x88b23acffd9900000" + }, + "84af1b157342d54368260d17876230a534b54b0e": { + "balance": "0x35659ef93f0fc40000" + }, + "84b0ee6bb837d3a4c4c5011c3a228c0edab4634a": { + "balance": "0x1158e460913d00000" + }, + "84b4b74e6623ba9d1583e0cfbe49643f16384149": { + "balance": "0x1158e460913d00000" + }, + "84b6b6adbe2f5b3e2d682c66af1bc4905340c3ed": { + "balance": "0x2192f8d22215008000" + }, + "84b91e2e2902d05e2b591b41083bd7beb2d52c74": { + "balance": "0x215e5128b4504648000" + }, + "84bcbf22c09607ac84341d2edbc03bfb1739d744": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "84bfcef0491a0ae0694b37ceac024584f2aa0467": { + "balance": "0x6c6acc67d7b1d40000" + }, + "84cb7da0502df45cf561817bbd2362f451be02da": { + "balance": "0x487a9a304539440000" + }, + "84cc7878da605fdb019fab9b4ccfc157709cdda5": { + "balance": "0x48798513af04c90000" + }, + "84db1459bb00812ea67ecb3dc189b72187d9c501": { + "balance": "0x811b8fbda85ab8000" + }, + "84e9949680bece6841b9a7e5250d08acd87d16cd": { + "balance": "0xad78ebc5ac6200000" + }, + "84e9cf8166c36abfa49053b7a1ad4036202681ef": { + "balance": "0x6c6b935b8bbd400000" + }, + "84ec06f24700fe42414cb9897c154c88de2f6132": { + "balance": "0x487a9a304539440000" + }, + "84f522f0520eba52dd18ad21fa4b829f2b89cb97": { + "balance": "0x10c5106d5134f130000" + }, + "850b9db18ff84bf0c7da49ea3781d92090ad7e64": { + "balance": "0x8cf23f909c0fa00000" + }, + "8510ee934f0cbc900e1007eb38a21e2a5101b8b2": { + "balance": "0x5bf0ba6634f680000" + }, + "8516fcaf77c893970fcd1a958ba9a00e49044019": { + "balance": "0xaa3eb1691bce58000" + }, + "851aa91c82f42fad5dd8e8bb5ea69c8f3a5977d1": { + "balance": "0x80e561f2578798000" + }, + "851c0d62be4635d4777e8035e37e4ba8517c6132": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "851dc38adb4593729a76f33a8616dab6f5f59a77": { + "balance": "0x56bc75e2d63100000" + }, + "8532490897bbb4ce8b7f6b837e4cba848fbe9976": { + "balance": "0x56bc75e2d63100000" + }, + "853e6abaf44469c72f151d4e223819aced4e3728": { + "balance": "0x6c6b935b8bbd400000" + }, + "854691ce714f325ced55ce5928ce9ba12facd1b8": { + "balance": "0xed70b5e9c3f2f00000" + }, + "854c0c469c246b83b5d1b3eca443b39af5ee128a": { + "balance": "0x56bc75e2d631000000" + }, + "855d9aef2c39c6230d09c99ef6494989abe68785": { + "balance": "0x8ba52e6fc45e40000" + }, + "8563c49361b625e768771c96151dbfbd1c906976": { + "balance": "0x6c6b935b8bbd400000" + }, + "8566610901aace38b83244f3a9c831306a67b9dc": { + "balance": "0xb08213bcf8ffe00000" + }, + "856aa23c82d7215bec8d57f60ad75ef14fa35f44": { + "balance": "0x43c33c1937564800000" + }, + "856e5ab3f64c9ab56b009393b01664fc0324050e": { + "balance": "0x61093d7c2c6d380000" + }, + "856eb204241a87830fb229031343dc30854f581a": { + "balance": "0x3635c9adc5dea00000" + }, + "85732c065cbd64119941aed430ac59670b6c51c4": { + "balance": "0x27a57362ab0a0e8000" + }, + "8578e10212ca14ff0732a8241e37467db85632a9": { + "balance": "0x14542ba12a337c00000" + }, + "8579dadf1a395a3471e20b6f763d9a0ff19a3f6f": { + "balance": "0xd8d726b7177a800000" + }, + "857f100b1a5930225efc7e9020d78327b41c02cb": { + "balance": "0x6c6b935b8bbd400000" + }, + "85946d56a4d371a93368539690b60ec825107454": { + "balance": "0x5dc892aa1131c80000" + }, + "8599cbd5a6a9dcd4b966be387d69775da5e33c6f": { + "balance": "0xc51f1b1d52622900000" + }, + "859c600cf13d1d0273d5d1da3cd789e495899f27": { + "balance": "0x90f534608a72880000" + }, + "85a2f6ea94d05e8c1d9ae2f4910338a358e98ded": { + "balance": "0x6c6b935b8bbd400000" + }, + "85b16f0b8b34dff3804f69e2168a4f7b24d1042b": { + "balance": "0x112f423c7646d40000" + }, + "85b2998d0c73302cb2ba13f489313301e053be15": { + "balance": "0x21e19e0c9bab2400000" + }, + "85bb51bc3bfe9a1b2a2f6b1cda95bca8b38c8d5e": { + "balance": "0x11712da04ba1ef0000" + }, + "85c8f3cc7a354feac99a5e7bfe7cdfa351cfe355": { + "balance": "0x15af1d78b58c400000" + }, + "85ca1e727e9d1a87991cc2c41840ebb9edf21d1b": { + "balance": "0xb98bc829a6f90000" + }, + "85ca8bc6da2803d0725f5e1a456c89f9bc774e2f": { + "balance": "0x2086ac351052600000" + }, + "85d0d88754ac84b8b21ba93dd2bfec72626faba8": { + "balance": "0x3635c9adc5dea00000" + }, + "85eb256b51c819d60ea61a82d12c9358d59c1cae": { + "balance": "0x18efc84ad0c7b00000" + }, + "85f0e7c1e3aff805a627a2aaf2cff6b4c0dbe9cb": { + "balance": "0x1158e460913d00000" + }, + "86026cad3fe4ea1ce7fca260d3d45eb09ea6a364": { + "balance": "0xad78ebc5ac6200000" + }, + "860f5ffc10de767ded807f71e861d647dfd219b1": { + "balance": "0x21e19e0c9bab2400000" + }, + "86153063a1ae7f02f1a88136d4d69c7c5e3e4327": { + "balance": "0x3635c9adc5dea00000" + }, + "86245f596691093ece3f3d3ca2263eace81941d9": { + "balance": "0xa31062beeed700000" + }, + "862569211e8c6327b5415e3a67e5738b15baaf6e": { + "balance": "0x796e3ea3f8ab00000" + }, + "86297d730fe0f7a9ee24e08fb1087b31adb306a7": { + "balance": "0x6c6b935b8bbd400000" + }, + "8644cc281be332ccced36da483fb2a0746d9ba2e": { + "balance": "0x15af1d78b58c400000" + }, + "86499a1228ff2d7ee307759364506f8e8c8307a5": { + "balance": "0x6acb3df27e1f880000" + }, + "864bec5069f855a4fd5892a6c4491db07c88ff7c": { + "balance": "0x3635c9adc5dea00000" + }, + "86570ab259c9b1c32c9729202f77f590c07dd612": { + "balance": "0xad78ebc5ac6200000" + }, + "8663a241a0a89e70e182c845e2105c8ad7264bcf": { + "balance": "0x323b13d8398f3238000" + }, + "8667fa1155fed732cfb8dca5a0d765ce0d0705ed": { + "balance": "0x46ec965c393b10000" + }, + "8668af868a1e98885f937f2615ded6751804eb2d": { + "balance": "0x1158e460913d00000" + }, + "86740a46648e845a5d96461b18091ff57be8a16f": { + "balance": "0x14c0973485bf39400000" + }, + "867eba56748a5904350d2ca2a5ce9ca00b670a9b": { + "balance": "0x43c33c1937564800000" + }, + "86806474c358047d9406e6a07f40945bc8328e67": { + "balance": "0x1752eb0f7013d100000" + }, + "86883d54cd3915e549095530f9ab1805e8c5432d": { + "balance": "0xd8d726b7177a800000" + }, + "868c23be873466d4c74c220a19b245d1787e807f": { + "balance": "0x4a13bbbd92c88e8000" + }, + "86924fb211aad23cf5ce600e0aae806396444087": { + "balance": "0x21e19e0c9bab2400000" + }, + "8693e9b8be94425eef7969bc69f9d42f7cad671e": { + "balance": "0x3637096c4bcc690000" + }, + "869f1aa30e4455beb1822091de5cadec79a8f946": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "86a1eadeeb30461345d9ef6bd05216fa247c0d0c": { + "balance": "0x6c6b935b8bbd400000" + }, + "86a5f8259ed5b09e188ce346ee92d34aa5dd93fa": { + "balance": "0xad78ebc5ac6200000" + }, + "86b7bd563ceab686f96244f9ddc02ad7b0b14bc2": { + "balance": "0x21e19e0c9bab2400000" + }, + "86c28b5678af37d727ec05e4447790f15f71f2ea": { + "balance": "0xad78ebc5ac6200000" + }, + "86c4ce06d9ac185bb148d96f7b7abe73f441006d": { + "balance": "0x21e19e0c9bab2400000" + }, + "86c8d0d982b539f48f9830f9891f9d607a942659": { + "balance": "0x2ced37761824fb00000" + }, + "86c934e38e53be3b33f274d0539cfca159a4d0d1": { + "balance": "0x34957444b840e80000" + }, + "86ca0145957e6b0dfe36875fbe7a0dec55e17a28": { + "balance": "0x21e19e0c9bab2400000" + }, + "86caafacf32aa0317c032ac36babed974791dc03": { + "balance": "0x878678326eac9000000" + }, + "86cdb7e51ac44772be3690f61d0e59766e8bfc18": { + "balance": "0xd8d726b7177a800000" + }, + "86df73bd377f2c09de63c45d67f283eaefa0f4ab": { + "balance": "0x3635c9adc5dea00000" + }, + "86e3fe86e93da486b14266eadf056cbfa4d91443": { + "balance": "0x6c6b935b8bbd400000" + }, + "86e8670e27598ea09c3899ab7711d3b9fe901c17": { + "balance": "0xad78ebc5ac6200000" + }, + "86ef6426211949cc37f4c75e7850369d0cf5f479": { + "balance": "0x2d65f32ea045af60000" + }, + "86f05d19063e9369c6004eb3f123943a7cff4eab": { + "balance": "0x6c6acc67d7b1d40000" + }, + "86f23e9c0aafc78b9c404dcd60339a925bffa266": { + "balance": "0x15af1d78b58c400000" + }, + "86f4f40ad984fbb80933ae626e0e42f9333fdd41": { + "balance": "0x3635c9adc5dea00000" + }, + "86f95c5b11a293940e35c0b898d8b75f08aab06d": { + "balance": "0x644e3e875fccf740000" + }, + "86fff220e59305c09f483860d6f94e96fbe32f57": { + "balance": "0x2535b6ab4c0420000" + }, + "870796abc0db84af82da52a0ed68734de7e636f5": { + "balance": "0x1043561a8829300000" + }, + "870f15e5df8b0eabd02569537a8ef93b56785c42": { + "balance": "0x150894e849b3900000" + }, + "87183160d172d2e084d327b86bcb7c1d8e6784ef": { + "balance": "0xd8d8583fa2d52f0000" + }, + "871b8a8b51dea1989a5921f13ec1a955a515ad47": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "8725e8c753b3acbfdca55f3c62dfe1a59454968a": { + "balance": "0x3637096c4bcc690000" + }, + "8737dae671823a8d5917e0157ace9c43468d946b": { + "balance": "0x6c6acc67d7b1d40000" + }, + "873b7f786d3c99ff012c4a7cae2677270240b9c5": { + "balance": "0x5dc892aa1131c80000" + }, + "873c6f70efb6b1d0f2bbc57eebcd70617c6ce662": { + "balance": "0x36f0d5275d09570000" + }, + "873e49135c3391991060290aa7f6ccb8f85a78db": { + "balance": "0x1158e460913d00000" + }, + "875061ee12e820041a01942cb0e65bb427b00060": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "87584a3f613bd4fac74c1e780b86d6caeb890cb2": { + "balance": "0x5c283d410394100000" + }, + "8764d02722000996ecd475b433298e9f540b05bf": { + "balance": "0xad78ebc5ac6200000" + }, + "876c3f218b4776df3ca9dbfb270de152d94ed252": { + "balance": "0x56bc75e2d63100000" + }, + "8775a610c502b9f1e6ad4cdadb8ce29bff75f6e4": { + "balance": "0x2086ac351052600000" + }, + "87764e3677eef604cbc59aed24abdc566b09fc25": { + "balance": "0xa2a15d09519be00000" + }, + "8787d12677a5ec291e57e31ffbfad105c3324b87": { + "balance": "0x2a24eb53208f3128000" + }, + "8794bf47d54540ece5c72237a1ffb511ddb74762": { + "balance": "0x6c6b935b8bbd400000" + }, + "87a53ea39f59a35bada8352521645594a1a714cb": { + "balance": "0x678a932062e4180000" + }, + "87a7c508ef71582dd9a54372f89cb01f252fb180": { + "balance": "0xad78ebc5ac6200000" + }, + "87af25d3f6f8eea15313d5fe4557e810c524c083": { + "balance": "0x42bf06b78ed3b500000" + }, + "87b10f9c280098179a2b76e9ce90be61fc844d0d": { + "balance": "0x487a9a304539440000" + }, + "87bf7cd5d8a929e1c785f9e5449106ac232463c9": { + "balance": "0x437b11fcc45640000" + }, + "87c498170934b8233d1ad1e769317d5c475f2f40": { + "balance": "0x3708baed3d68900000" + }, + "87cf36ad03c9eae9053abb5242de9117bb0f2a0b": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "87d7ac0653ccc67aa9c3469eef4352193f7dbb86": { + "balance": "0x2a5a058fc295ed000000" + }, + "87e3062b2321e9dfb0875ce3849c9b2e3522d50a": { + "balance": "0x21e19e0c9bab2400000" + }, + "87e6034ecf23f8b5639d5f0ea70a22538a920423": { + "balance": "0x11c7ea162e78200000" + }, + "87ef6d8b6a7cbf9b5c8c97f67ee2adc2a73b3f77": { + "balance": "0xadd1bd23c3c480000" + }, + "87fb26c31e48644d693134205cae43b21f18614b": { + "balance": "0x4a4491bd6dcd280000" + }, + "87fc4635263944ce14a46c75fa4a821f39ce7f72": { + "balance": "0x1158e460913d00000" + }, + "87fcbe7c4193ffcb08143779c9bec83fe7fda9fc": { + "balance": "0x56f985d38644b8000" + }, + "88015d7203c5e0224aeda286ed12f1a51b789333": { + "balance": "0x10f08eda8e555098000" + }, + "88106c27d20b74b4b98ca62b232bd5c97411171f": { + "balance": "0xaadec983fcff40000" + }, + "881230047c211d2d5b00d8de4c5139de5e3227c7": { + "balance": "0x21e19e0c9bab2400000" + }, + "882aa798bf41df179f85520130f15ccdf59b5e58": { + "balance": "0x6c6b935b8bbd400000" + }, + "882bd3a2e9d74110b24961c53777f22f1f46dc5d": { + "balance": "0x2d4ca05e2b43ca80000" + }, + "882c8f81872c79fed521cb5f950d8b032322ea69": { + "balance": "0x878678326eac9000000" + }, + "882f75708386653c80171d0663bfe30b017ed0ad": { + "balance": "0x6c6b935b8bbd400000" + }, + "88344909644c7ad4930fd873ca1c0da2d434c07f": { + "balance": "0x727739fcb004d0000" + }, + "8834b2453471f324fb26be5b25166b5b5726025d": { + "balance": "0x1f0ff8f01daad40000" + }, + "883a78aeabaa50d8ddd8570bcd34265f14b19363": { + "balance": "0xd25522fda379a18000" + }, + "8845e9f90e96336bac3c616be9d88402683e004c": { + "balance": "0x6c6b935b8bbd400000" + }, + "8846928d683289a2d11df8db7a9474988ef01348": { + "balance": "0x21e19e0c9bab2400000" + }, + "884980eb4565c1048317a8f47fdbb461965be481": { + "balance": "0xd8d6119a8146050000" + }, + "884a7a39d0916e05f1c242df55607f37df8c5fda": { + "balance": "0x4f4843c157c8ca00000" + }, + "885493bda36a0432976546c1ddce71c3f4570021": { + "balance": "0xbbf510ddfcb260000" + }, + "88609e0a465b6e99fce907166d57e9da0814f5c8": { + "balance": "0x43c33c1937564800000" + }, + "886d0a9e17c9c095af2ea2358b89ec705212ee94": { + "balance": "0x18493fba64ef00000" + }, + "88797e58675ed5cc4c19980783dbd0c956085153": { + "balance": "0x6c6b935b8bbd400000" + }, + "887cac41cd706f3345f2d34ac34e01752a6e5909": { + "balance": "0x20465cee9da1370000" + }, + "88888a57bd9687cbf950aeeacf9740dcc4d1ef59": { + "balance": "0x62a992e53a0af00000" + }, + "8889448316ccf14ed86df8e2f478dc63c4338340": { + "balance": "0xd2f13f7789f00000" + }, + "888c16144933197cac26504dd76e06fd6600c789": { + "balance": "0x56bc75e2d63100000" + }, + "888e94917083d152202b53163939869d271175b4": { + "balance": "0xd8d726b7177a800000" + }, + "889087f66ff284f8b5efbd29493b706733ab1447": { + "balance": "0x215f835bc769da80000" + }, + "8895eb726226edc3f78cc6a515077b3296fdb95e": { + "balance": "0xd5967be4fc3f100000" + }, + "88975a5f1ef2528c300b83c0c607b8e87dd69315": { + "balance": "0x486cb9799191e0000" + }, + "889da40fb1b60f9ea9bd7a453e584cf7b1b4d9f7": { + "balance": "0x22b1c8c1227a00000" + }, + "889da662eb4a0a2a069d2bc24b05b4ee2e92c41b": { + "balance": "0x5a2c8c5456c9f28000" + }, + "88a122a2382c523931fb51a0ccad3beb5b7259c3": { + "balance": "0x6c6b935b8bbd400000" + }, + "88a2154430c0e41147d3c1fee3b3b006f851edbd": { + "balance": "0x36356633ebd8ea0000" + }, + "88b217ccb786a254cf4dc57f5d9ac3c455a30483": { + "balance": "0x3224f42723d4540000" + }, + "88bc43012edb0ea9f062ac437843250a39b78fbb": { + "balance": "0x43c33c1937564800000" + }, + "88c2516a7cdb09a6276d7297d30f5a4db1e84b86": { + "balance": "0xd8d726b7177a800000" + }, + "88c361640d6b69373b081ce0c433bd590287d5ec": { + "balance": "0xa968163f0a57b400000" + }, + "88d541c840ce43cefbaf6d19af6b9859b573c145": { + "balance": "0x93739534d28680000" + }, + "88de13b09931877c910d593165c364c8a1641bd3": { + "balance": "0xa2a15d09519be00000" + }, + "88dec5bd3f4eba2d18b8aacefa7b721548c319ba": { + "balance": "0x4a4491bd6dcd280000" + }, + "88e6f9b247f988f6c0fc14c56f1de53ec69d43cc": { + "balance": "0x56bc75e2d63100000" + }, + "88ee7f0efc8f778c6b687ec32be9e7d6f020b674": { + "balance": "0x6c6b935b8bbd400000" + }, + "88f1045f19f2d3191816b1df18bb6e1435ad1b38": { + "balance": "0xd02ab486cedc00000" + }, + "89009e3c6488bd5e570d1da34eabe28ed024de1b": { + "balance": "0x43c33c1937564800000" + }, + "89054430dcdc28ac15fa635ef87c105e602bf70c": { + "balance": "0x5dacd13ca9e300000" + }, + "8908760cd39b9c1e8184e6a752ee888e3f0b7045": { + "balance": "0x14542ba12a337c00000" + }, + "890fe11f3c24db8732d6c2e772e2297c7e65f139": { + "balance": "0xd5627137da8b5900000" + }, + "8914a680a5aec5226d4baaec2e5552b44dd7c874": { + "balance": "0x56cd55fc64dfe0000" + }, + "891cb8238c88e93a1bcf61db49bd82b47a7f4f84": { + "balance": "0x914878a8c05ee00000" + }, + "8925da4549e15155e57a628522cea9dddf627d81": { + "balance": "0x3636c25e66ece70000" + }, + "893017ff1adad499aa065401b4236ce6e92b625a": { + "balance": "0x6c6acc67d7b1d40000" + }, + "8933491760c8f0b4df8caac78ed835caee21046d": { + "balance": "0x43c33c1937564800000" + }, + "893608751d68d046e85802926673cdf2f57f7cb8": { + "balance": "0x11164759ffb320000" + }, + "8938d1b4daee55a54d738cf17e4477f6794e46f7": { + "balance": "0xfc936392801c0000" + }, + "893a6c2eb8b40ab096b4f67e74a897b840746e86": { + "balance": "0x5dc892aa1131c80000" + }, + "893cdddf5377f3c751bf2e541120045a47cba101": { + "balance": "0x56bc75e2d63100000" + }, + "895613236f3584216ad75c5d3e07e3fa6863a778": { + "balance": "0x6c6b935b8bbd400000" + }, + "8957727e72cf629020f4e05edf799aa7458062d0": { + "balance": "0x77432217e683600000" + }, + "895d694e880b13ccd0848a86c5ce411f88476bbf": { + "balance": "0xad6eedd17cf3b8000" + }, + "895ec5545644e0b78330fffab8ddeac9e833156c": { + "balance": "0x2086ac351052600000" + }, + "896009526a2c7b0c09a6f63a80bdf29d9c87de9c": { + "balance": "0xbbb86b8223edeb0000" + }, + "8967d7b9bdb7b4aed22e65a15dc803cb7a213f10": { + "balance": "0x15af1d78b58c400000" + }, + "896e335ca47af57962fa0f4dbf3e45e688cba584": { + "balance": "0x4a2fc0ab6052120000" + }, + "8973aefd5efaee96095d9e288f6a046c97374b43": { + "balance": "0x7a4c4a0f332140000" + }, + "898c72dd736558ef9e4be9fdc34fef54d7fc7e08": { + "balance": "0x3635c9adc5dea00000" + }, + "899b3c249f0c4b81df75d212004d3d6d952fd223": { + "balance": "0x6c6b935b8bbd400000" + }, + "89ab13ee266d779c35e8bb04cd8a90cc2103a95b": { + "balance": "0xcb49b44ba602d800000" + }, + "89c433d601fad714da6369308fd26c1dc9942bbf": { + "balance": "0x6c6b935b8bbd400000" + }, + "89d75b8e0831e46f80bc174188184e006fde0eae": { + "balance": "0x3635c9adc5dea00000" + }, + "89e3b59a15864737d493c1d23cc53dbf8dcb1362": { + "balance": "0xd8d726b7177a800000" + }, + "89fc8e4d386b0d0bb4a707edf3bd560df1ad8f4e": { + "balance": "0xa030dcebbd2f4c0000" + }, + "89fee30d1728d96cecc1dab3da2e771afbcfaa41": { + "balance": "0x6c6acc67d7b1d40000" + }, + "8a1cc5ac111c49bfcfd848f37dd768aa65c88802": { + "balance": "0x21e19e0c9bab2400000" + }, + "8a20e5b5cee7cd1f5515bace3bf4f77ffde5cc07": { + "balance": "0x4563918244f400000" + }, + "8a217db38bc35f215fd92906be42436fe7e6ed19": { + "balance": "0x14542ba12a337c00000" + }, + "8a243a0a9fea49b839547745ff2d11af3f4b0522": { + "balance": "0x35659ef93f0fc40000" + }, + "8a247d186510809f71cffc4559471c3910858121": { + "balance": "0x61093d7c2c6d380000" + }, + "8a3470282d5e2a2aefd7a75094c822c4f5aeef8a": { + "balance": "0xd28bc606478a58000" + }, + "8a36869ad478997cbf6d8924d20a3c8018e9855b": { + "balance": "0x1158e460913d00000" + }, + "8a4314fb61cd938fc33e15e816b113f2ac89a7fb": { + "balance": "0x17764e7aed65100000" + }, + "8a4f4a7f52a355ba105fca2072d3065fc8f7944b": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "8a5831282ce14a657a730dc18826f7f9b99db968": { + "balance": "0xeabe8a5b41c1360000" + }, + "8a5fb75793d043f1bcd43885e037bd30a528c927": { + "balance": "0x13536e6d2e9ac20000" + }, + "8a66abbc2d30ce21a833b0db8e561d5105e0a72c": { + "balance": "0x25f1de5c76acdf0000" + }, + "8a746c5d67064711bfca685b95a4fe291a27028e": { + "balance": "0x22b1c8c1227a00000" + }, + "8a780ab87a9145fe10ed60fa476a740af4cab1d2": { + "balance": "0x121b2e5e6464780000" + }, + "8a7a06be199a3a58019d846ac9cbd4d95dd757de": { + "balance": "0xa2a423944256f40000" + }, + "8a810114b2025db9fbb50099a6e0cb9e2efa6bdc": { + "balance": "0x678a932062e4180000" + }, + "8a86e4a51c013b1fb4c76bcf30667c78d52eedef": { + "balance": "0x6c6b935b8bbd400000" + }, + "8a9eca9c5aba8e139f8003edf1163afb70aa3aa9": { + "balance": "0x23c757072b8dd00000" + }, + "8ab839aeaf2ad37cb78bacbbb633bcc5c099dc46": { + "balance": "0x6c6b935b8bbd400000" + }, + "8ac89bd9b8301e6b0677fa25fcf0f58f0cc7b611": { + "balance": "0x1158e460913d00000" + }, + "8adc53ef8c18ed3051785d88e996f3e4b20ecd51": { + "balance": "0x8e4d316827686400000" + }, + "8ae6f80b70e1f23c91fbd5a966b0e499d95df832": { + "balance": "0xaadec983fcff40000" + }, + "8ae9ef8c8a8adfa6ab798ab2cdc405082a1bbb70": { + "balance": "0x6c6b935b8bbd400000" + }, + "8af626a5f327d7506589eeb7010ff9c9446020d2": { + "balance": "0x4be4e7267b6ae00000" + }, + "8b01da34d470c1d115acf4d8113c4dd8a8c338e4": { + "balance": "0x5572dcefab697900000" + }, + "8b07d050754dc9ba230db01c310afdb5395aa1b3": { + "balance": "0x666b06e62a6200000" + }, + "8b20ad3b94656dbdc0dd21a393d8a7d9e02138cb": { + "balance": "0xa2a15d09519be00000" + }, + "8b27392206b958cd375d7ef8af2cf8ef0598c0bc": { + "balance": "0x3635c9adc5dea00000" + }, + "8b30c04098d7a7e6420c357ea7bfa49bac9a8a18": { + "balance": "0x1b1b113f91fb0140000" + }, + "8b338411f26ccf37658cc75521d77629099e467d": { + "balance": "0x6c6b935b8bbd400000" + }, + "8b36224c7356e751f0c066c35e3b44860364bfc2": { + "balance": "0x3627bac7a3d9278000" + }, + "8b3696f3c60de32432a2e4c395ef0303b7e81e75": { + "balance": "0x65a4da25d3016c00000" + }, + "8b393fb0813ee101db1e14ecc7d322c72b8c0473": { + "balance": "0x18b26a313e8ae90000" + }, + "8b48e19d39dd35b66e6e1bb6b9c657cb2cf59d04": { + "balance": "0x3c755ac9c024a018000" + }, + "8b505e2871f7deb7a63895208e8227dcaa1bff05": { + "balance": "0xcf68efc308d79bc0000" + }, + "8b57b2bc83cc8d4de331204e893f2f3b1db1079a": { + "balance": "0x22b1c8c1227a00000" + }, + "8b5c914b128bf1695c088923fa467e7911f351fa": { + "balance": "0x556f64c1fe7fa0000" + }, + "8b5f29cc2faa262cdef30ef554f50eb488146eac": { + "balance": "0x13b68705c9720810000" + }, + "8b7056f6abf3b118d026e944d5c073433ca451d7": { + "balance": "0x3635c6204739d98000" + }, + "8b714522fa2839620470edcf0c4401b713663df1": { + "balance": "0xad78ebc5ac6200000" + }, + "8b74a7cb1bb8c58fce267466a30358adaf527f61": { + "balance": "0x2e257784e25b4500000" + }, + "8b7e9f6f05f7e36476a16e3e7100c9031cf404af": { + "balance": "0x3635c9adc5dea00000" + }, + "8b81156e698639943c01a75272ad3d35851ab282": { + "balance": "0x12b3165f65d3e50000" + }, + "8b9577920053b1a00189304d888010d9ef2cb4bf": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "8b9841862e77fbbe919470935583a93cf027e450": { + "balance": "0x6c6c5334427f1f0000" + }, + "8b997dbc078ad02961355da0a159f2927ed43d64": { + "balance": "0xaadec983fcff40000" + }, + "8b9fda7d981fe9d64287f85c94d83f9074849fcc": { + "balance": "0x2f6f10780d22cc00000" + }, + "8bb0212f3295e029cab1d961b04133a1809e7b91": { + "balance": "0x6c6b935b8bbd400000" + }, + "8bbeacfc29cfe93402db3c41d99ab759662e73ec": { + "balance": "0x6c6b935b8bbd400000" + }, + "8bc1ff8714828bf286ff7e8a7709106548ed1b18": { + "balance": "0x21e19e0c9bab2400000" + }, + "8bd0b65a50ef5cef84fec420be7b89ed1470ceb9": { + "balance": "0x28a77936e92c81c0000" + }, + "8bd6b1c6d74d010d1008dba6ef835d4430b35c32": { + "balance": "0x2b5e3af16b1880000" + }, + "8bd8d4c4e943f6c8073921dc17e3e8d7a0761627": { + "balance": "0x9f04219d8d34950000" + }, + "8bdfda6c215720eda2136f91052321af4e936c1f": { + "balance": "0x3635e619bb04d40000" + }, + "8bea40379347a5c891d59a6363315640f5a7e07a": { + "balance": "0x6c6b76ef96970c0000" + }, + "8bf02bd748690e1fd1c76d270833048b66b25fd3": { + "balance": "0x27fade568eba9600000" + }, + "8bf297f8f453523ed66a1acb7676856337b93bf0": { + "balance": "0xd8d726b7177a800000" + }, + "8bf373d076814cbc57e1c6d16a82c5be13c73d37": { + "balance": "0xad78ebc5ac6200000" + }, + "8c1023fde1574db8bb54f1739670157ca47da652": { + "balance": "0x179cf9ac3a1b1770000" + }, + "8c1fbe5f0aea359c5aa1fa08c8895412ca8e05a6": { + "balance": "0x3635c9adc5dea00000" + }, + "8c22426055b76f11f0a2de1a7f819a619685fe60": { + "balance": "0x6b56051582a9700000" + }, + "8c2b7d8b608d28b77f5caa9cd645242a823e4cd9": { + "balance": "0x62a992e53a0af00000" + }, + "8c2fbeee8eacc5c5d77c16abd462ee9c8145f34b": { + "balance": "0x692ae8897081d00000" + }, + "8c3a9ee71f729f236cba3867b4d79d8ceee25dbc": { + "balance": "0x56bc75e2d63100000" + }, + "8c50aa2a9212bcde56418ae261f0b35e7a9dbb82": { + "balance": "0x15af1d78b58c400000" + }, + "8c54c7f8b9896e75d7d5f5c760258699957142ad": { + "balance": "0x22b1c8c1227a00000" + }, + "8c5d16ed65e3ed7e8b96ca972bc86173e3500b03": { + "balance": "0x6c6b935b8bbd400000" + }, + "8c6aa882ee322ca848578c06cb0fa911d3608305": { + "balance": "0x2086ac351052600000" + }, + "8c6ae7a05a1de57582ae2768204276c0ff47ed03": { + "balance": "0x2c0bb3dd30c4e2000000" + }, + "8c6f9f4e5b7ae276bf58497bd7bf2a7d25245f64": { + "balance": "0x93fe5c57d710680000" + }, + "8c75956e8fed50f5a7dd7cfd27da200f6746aea6": { + "balance": "0x3635c9adc5dea00000" + }, + "8c7cb4e48b25031aa1c4f92925d631a8c3edc761": { + "balance": "0x3635c9adc5dea00000" + }, + "8c7fa5cae82fedb69ab189d3ff27ae209293fb93": { + "balance": "0x15af880d8cdb830000" + }, + "8c81410ea8354cc5c65c41be8bd5de733c0b111d": { + "balance": "0x205b4dfa1ee74780000" + }, + "8c83d424a3cf24d51f01923dd54a18d6b6fede7b": { + "balance": "0xd8d726b7177a800000" + }, + "8c900a8236b08c2b65405d39d75f20062a7561fd": { + "balance": "0x58e7926ee858a00000" + }, + "8c93c3c6db9d37717de165c3a1b4fe51952c08de": { + "balance": "0x15af1d78b58c400000" + }, + "8c999591fd72ef7111efca7a9e97a2356b3b000a": { + "balance": "0xdd64e2aa0a67500000" + }, + "8ca6989746b06e32e2487461b1ce996a273acfd7": { + "balance": "0x1158e460913d00000" + }, + "8cb3aa3fcd212854d7578fcc30fdede6742a312a": { + "balance": "0x1043561a8829300000" + }, + "8cc0d7c016fa7aa950114aa1db094882eda274ea": { + "balance": "0x8a9aba557e36c0000" + }, + "8cc652dd13e7fe14dabbb36d5d320db9ffee8a54": { + "balance": "0x61093d7c2c6d380000" + }, + "8ccabf25077f3aa41545344d53be1b2b9c339000": { + "balance": "0x5be866c562c5440000" + }, + "8ccf3aa21ab742576ad8c422f71bb188591dea8a": { + "balance": "0x3635c9adc5dea00000" + }, + "8cd0cd22e620eda79c0461e896c93c44837e2968": { + "balance": "0x6c6b935b8bbd400000" + }, + "8cde8b732e6023878eb23ed16229124b5f7afbec": { + "balance": "0x73f75d1a085ba0000" + }, + "8ce22f9fa372449a420610b47ae0c8d565481232": { + "balance": "0x6c6b935b8bbd400000" + }, + "8ce4949d8a16542d423c17984e6739fa72ceb177": { + "balance": "0x54b405926f4a63d8000" + }, + "8ce5e3b5f591d5eca38abf228f2e3c35134bdac0": { + "balance": "0x7dc35b84897c380000" + }, + "8cee38d6595788a56e3fb94634b3ffe1fbdb26d6": { + "balance": "0x43c33c1937564800000" + }, + "8ceea15eec3bdad8023f98ecf25b2b8fef27db29": { + "balance": "0x6c6b935b8bbd400000" + }, + "8cf3546fd1cda33d58845fc8fcfecabca7c5642a": { + "balance": "0x1f1e39932cb3278000" + }, + "8cf6da0204dbc4860b46ad973fc111008d9e0c46": { + "balance": "0xad78ebc5ac6200000" + }, + "8cfedef198db0a9143f09129b3fd64dcbb9b4956": { + "balance": "0x6c6b935b8bbd400000" + }, + "8d04a5ebfb5db409db0617c9fa5631c192861f4a": { + "balance": "0x34957444b840e80000" + }, + "8d06e464245cad614939e0af0845e6d730e20374": { + "balance": "0xadc8a28f3d87d8000" + }, + "8d07d42d831c2d7c838aa1872b3ad5d277176823": { + "balance": "0x12ee1f9ddbee680000" + }, + "8d0b9ea53fd263415eac11391f7ce9123c447062": { + "balance": "0x6c6b935b8bbd400000" + }, + "8d1794da509cb297053661a14aa892333231e3c1": { + "balance": "0xad201a6794ff80000" + }, + "8d1abd897dacd4312e18080c88fb9647eab44052": { + "balance": "0xbb59a27953c600000" + }, + "8d2303341e1e1eb5e8189bde03f73a60a2a54861": { + "balance": "0x56bc75e2d63100000" + }, + "8d238e036596987643d73173c37b0ad06055b96c": { + "balance": "0x7148bf0a2af0660000" + }, + "8d2e31b08803b2c5f13d398ecad88528209f6057": { + "balance": "0x21db8bbcad11e840000" + }, + "8d378f0edc0bb0f0686d6a20be6a7692c4fa24b8": { + "balance": "0x56bc75e2d63100000" + }, + "8d4b603c5dd4570c34669515fdcc665890840c77": { + "balance": "0xfc936392801c0000" + }, + "8d51a4cc62011322c696fd725b9fb8f53feaaa07": { + "balance": "0x3635c9adc5dea00000" + }, + "8d544c32c07fd0842c761d53a897d6c950bb7599": { + "balance": "0xad78ebc5ac6200000" + }, + "8d5ef172bf77315ea64e85d0061986c794c6f519": { + "balance": "0xd5967be4fc3f100000" + }, + "8d616b1eee77eef6f176e0698db3c0c141b2fc8f": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "8d6170ff66978e773bb621bf72b1ba7be3a7f87e": { + "balance": "0xad78ebc5ac6200000" + }, + "8d620bde17228f6cbba74df6be87264d985cc179": { + "balance": "0x56bc75e2d63100000" + }, + "8d629c20608135491b5013f1002586a0383130e5": { + "balance": "0x4a4491bd6dcd280000" + }, + "8d6657f59711b1f803c6ebef682f915b62f92dc9": { + "balance": "0x6c6b935b8bbd400000" + }, + "8d667637e29eca05b6bfbef1f96d460eefbf9984": { + "balance": "0xd8d726b7177a800000" + }, + "8d6df209484d7b94702b03a53e56b9fb0660f6f0": { + "balance": "0x6c6b935b8bbd400000" + }, + "8d795c5f4a5689ad62da961671f028065286d554": { + "balance": "0x6f05b59d3b20000000" + }, + "8d7f3e61299c2db9b9c0487cf627519ed00a9123": { + "balance": "0x5e74a8505e80a00000" + }, + "8d89170b92b2be2c08d57c48a7b190a2f146720f": { + "balance": "0x42bf06b78ed3b500000" + }, + "8d93dac785f88f1a84bf927d53652b45a154ccdd": { + "balance": "0x890b0c2e14fb80000" + }, + "8d9952d0bb4ebfa0efd01a3aa9e8e87f0525742e": { + "balance": "0xbb9125542263900000" + }, + "8d9a0c70d2262042df1017d6c303132024772712": { + "balance": "0x6c6b935b8bbd400000" + }, + "8d9ed7f4553058c26f7836a3802d3064eb1b363d": { + "balance": "0x4e1003b28d9280000" + }, + "8da1178f55d97772bb1d24111a404a4f8715b95d": { + "balance": "0x2f9ac3f6de00808000" + }, + "8da1d359ba6cb4bcc57d7a437720d55db2f01c72": { + "balance": "0x4563918244f400000" + }, + "8dab948ae81da301d972e3f617a912e5a753712e": { + "balance": "0x15af1d78b58c400000" + }, + "8daddf52efbd74da95b969a5476f4fbbb563bfd2": { + "balance": "0x2d43f3ebfafb2c0000" + }, + "8db185fe1b70a94a6a080e7e23a8bedc4acbf34b": { + "balance": "0x4be4e7267b6ae00000" + }, + "8db58e406e202df9bc703c480bd8ed248d52a032": { + "balance": "0x6c6b935b8bbd400000" + }, + "8dbc3e6cb433e194f40f82b40faadb1f8b856116": { + "balance": "0x678a932062e4180000" + }, + "8dc1d5111d09af25fdfcac455c7cec283e6d6775": { + "balance": "0x6c6b935b8bbd400000" + }, + "8dd484ff8a307364eb66c525a571aac701c5c318": { + "balance": "0xd8d726b7177a800000" + }, + "8dd6a9bae57f518549ada677466fea8ab04fd9b4": { + "balance": "0xd8d726b7177a800000" + }, + "8dde3cb8118568ef4503fe998ccdf536bf19a098": { + "balance": "0xd8d726b7177a800000" + }, + "8dde60eb08a099d7daa356daaab2470d7b025a6b": { + "balance": "0xaadec983fcff40000" + }, + "8df339214b6ad1b24663ce716034749d6ef838d9": { + "balance": "0x2544faa778090e00000" + }, + "8df53d96191471e059de51c718b983e4a51d2afd": { + "balance": "0x6c6b935b8bbd4000000" + }, + "8dfbafbc0e5b5c86cd1ad697feea04f43188de96": { + "balance": "0x15252b7f5fa0de0000" + }, + "8e073bad25e42218615f4a0e6b2ea8f8de2230c0": { + "balance": "0x823d629d026bfa0000" + }, + "8e0fee38685a94aabcd7ce857b6b1409824f75b8": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "8e23facd12c765c36ab81a6dd34d8aa9e68918ae": { + "balance": "0x911e4868dba9b0000" + }, + "8e2f9034c9254719c38e50c9aa64305ed696df1e": { + "balance": "0x1004e2e45fb7ee00000" + }, + "8e3240b0810e1cf407a500804740cf8d616432a4": { + "balance": "0x22f6655ef0b388000" + }, + "8e486a0442d171c8605be348fee57eb5085eff0d": { + "balance": "0xd8d726b7177a800000" + }, + "8e6156336be2cdbe32140df08a2ba55fd0a58463": { + "balance": "0x4099e1d6357180000" + }, + "8e670815fb67aeaea57b86534edc00cdf564fee5": { + "balance": "0xb2e4b323d9c5100000" + }, + "8e6d7485cbe990acc1ad0ee9e8ccf39c0c93440e": { + "balance": "0x33c5499031720c0000" + }, + "8e74e0d1b77ebc823aca03f119854cb12027f6d7": { + "balance": "0x16b352da5e0ed3000000" + }, + "8e78f351457d016f4ad2755ec7424e5c21ba6d51": { + "balance": "0x7ea28327577080000" + }, + "8e7936d592008fdc7aa04edeeb755ab513dbb89d": { + "balance": "0x1158e460913d00000" + }, + "8e7fd23848f4db07906a7d10c04b21803bb08227": { + "balance": "0x3635c9adc5dea00000" + }, + "8e92aba38e72a098170b92959246537a2e5556c0": { + "balance": "0xe7eeba3410b740000" + }, + "8e98766524b0cf2747c50dd43b9567594d9731de": { + "balance": "0x6c44b7c26182280000" + }, + "8e9b35ad4a0a86f758446fffde34269d940ceacd": { + "balance": "0xd8d726b7177a800000" + }, + "8e9c08f738661f9676236eff82ba6261dd3f4822": { + "balance": "0x56bc75e2d63100000" + }, + "8e9c429266df057efa78dd1d5f77fc40742ad466": { + "balance": "0x10442ed1b56c7c8000" + }, + "8ea656e71ec651bfa17c5a5759d86031cc359977": { + "balance": "0x56bc75e2d63100000" + }, + "8eae29435598ba8f1c93428cdb3e2b4d31078e00": { + "balance": "0x6c6b935b8bbd400000" + }, + "8eb1fbe4e5d3019cd7d30dae9c0d5b4c76fb6331": { + "balance": "0x6c6b935b8bbd400000" + }, + "8eb51774af206b966b8909c45aa6722748802c0c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "8eb8c71982a00fb84275293253f8044544b66b49": { + "balance": "0x15af1d78b58c400000" + }, + "8ecbcfacbfafe9f00c3922a24e2cf0026756ca20": { + "balance": "0x131beb925ffd3200000" + }, + "8eceb2e124536c5b5ffc640ed14ff15ed9a8cb71": { + "balance": "0x6c6b935b8bbd400000" + }, + "8ed0af11ff2870da0681004afe18b013f7bd3882": { + "balance": "0xd8d726b7177a800000" + }, + "8ed143701f2f72280fd04a7b4164281979ea87c9": { + "balance": "0xc249fdd327780000" + }, + "8ed1528b447ed4297902f639c514d0944a88f8c8": { + "balance": "0xac6e77ab663a80000" + }, + "8ed4284c0f47449c15b8d9b3245de8beb6ce80bf": { + "balance": "0x2b5e3af16b18800000" + }, + "8ede7e3dc50749c6c50e2e28168478c34db81946": { + "balance": "0x43c30fb0884a96c0000" + }, + "8ee584337ddbc80f9e3498df55f0a21eacb57fb1": { + "balance": "0x1158e460913d00000" + }, + "8eebec1a62c08b05a7d1d59180af9ff0d18e3f36": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "8ef4d8a2c23c5279187b64e96f741404085385f3": { + "balance": "0x103dc1e9a9697b0000" + }, + "8ef711e43a13918f1303e81d0ea78c9eefd67eb2": { + "balance": "0xd8d726b7177a800000" + }, + "8efec058cc546157766a632775404a334aaada87": { + "balance": "0x6c5db2a4d815dc0000" + }, + "8f02bda6c36922a6be6a509be51906d393f7b99b": { + "balance": "0x37490dc12ebe7f8000" + }, + "8f0538ed71da1155e0f3bde5667ceb84318a1a87": { + "balance": "0x692ae8897081d00000" + }, + "8f067c7c1bbd57780b7b9eeb9ec0032f90d0dcf9": { + "balance": "0x43c33c1937564800000" + }, + "8f0ab894bd3f4e697dbcfb859d497a9ba195994a": { + "balance": "0x85d638b65472aa20000" + }, + "8f0af37566d152802f1ae8f928b25af9b139b448": { + "balance": "0xad78ebc5ac6200000" + }, + "8f1952eed1c548d9ee9b97d0169a07933be69f63": { + "balance": "0x3635c9adc5dea00000" + }, + "8f1fcc3c51e252b693bc5b0ec3f63529fe69281e": { + "balance": "0x14542ba12a337c00000" + }, + "8f226096c184ebb40105e08dac4d22e1c2d54d30": { + "balance": "0x109e437bd1618c0000" + }, + "8f29a14a845ad458f2d108b568d813166bcdf477": { + "balance": "0x21e19e0c9bab2400000" + }, + "8f31c7005197ec997a87e69bec48649ab94bb2a5": { + "balance": "0xd8d726b7177a800000" + }, + "8f41b1fbf54298f5d0bc2d122f4eb95da4e5cd3d": { + "balance": "0x1333832f5e335c0000" + }, + "8f47328ee03201c9d35ed2b5412b25decc859362": { + "balance": "0x6c6b935b8bbd400000" + }, + "8f473d0ab876ddaa15608621d7013e6ff714b675": { + "balance": "0x19801c83b6c7c00000" + }, + "8f4d1d41693e462cf982fd81d0aa701d3a5374c9": { + "balance": "0xd8d726b7177a800000" + }, + "8f4d1e7e4561284a34fef9673c0d34e12af4aa03": { + "balance": "0x6c6b935b8bbd400000" + }, + "8f4fb1aea7cd0f570ea5e61b40a4f4510b6264e4": { + "balance": "0xd8d726b7177a800000" + }, + "8f561b41b209f248c8a99f858788376250609cf3": { + "balance": "0x5c283d410394100000" + }, + "8f58d8348fc1dc4e0dd8343b6543c857045ee940": { + "balance": "0x2e3038df47303280000" + }, + "8f60895fbebbb5017fcbff3cdda397292bf25ba6": { + "balance": "0x174406ff9f6fd28000" + }, + "8f64b9c1246d857831643107d355b5c75fef5d4f": { + "balance": "0x6c6acc67d7b1d40000" + }, + "8f660f8b2e4c7cc2b4ac9c47ed28508d5f8f8650": { + "balance": "0x43c33c1937564800000" + }, + "8f69eafd0233cadb4059ab779c46edf2a0506e48": { + "balance": "0x60f06620a849450000" + }, + "8f717ec1552f4c440084fba1154a81dc003ebdc0": { + "balance": "0x21e19e0c9bab2400000" + }, + "8f8acb107607388479f64baaabea8ff007ada97d": { + "balance": "0x5c6f3080ad423f40000" + }, + "8f8cd26e82e7c6defd02dfad07979021cbf7150c": { + "balance": "0xa2a15d09519be00000" + }, + "8f8f37d0ad8f335d2a7101b41156b688a81a9cbe": { + "balance": "0x3cb71f51fc5580000" + }, + "8f92844f282a92999ee5b4a8d773d06b694dbd9f": { + "balance": "0x692ae8897081d00000" + }, + "8fac748f784a0fed68dba43319b42a75b4649c6e": { + "balance": "0x3154c9729d05780000" + }, + "8fd9a5c33a7d9edce0997bdf77ab306424a11ea9": { + "balance": "0x6c6b935b8bbd400000" + }, + "8feffadb387a1547fb284da9b8147f3e7c6dc6da": { + "balance": "0x2d627be45305080000" + }, + "8ff46045687723dc33e4d099a06904f1ebb584dc": { + "balance": "0x6c6b935b8bbd400000" + }, + "8ffa062122ac307418821adb9311075a3703bfa3": { + "balance": "0x3635c9adc5dea00000" + }, + "8ffe322997b8e404422d19c54aadb18f5bc8e9b7": { + "balance": "0xd5967be4fc3f100000" + }, + "900194c4b1074305d19de405b0ac78280ecaf967": { + "balance": "0x3635c9adc5dea00000" + }, + "9003d270891ba2df643da8341583193545e3e000": { + "balance": "0xd8d726b7177a800000" + }, + "90057af9aa66307ec9f033b29724d3b2f41eb6f9": { + "balance": "0x19d1d6aadb2c52e80000" + }, + "900f0b8e35b668f81ef252b13855aa5007d012e7": { + "balance": "0x170a0f5040e5040000" + }, + "9018cc1f48d2308e252ab6089fb99a7c1d569410": { + "balance": "0xad78ebc5ac6200000" + }, + "901d99b699e5c6911519cb2076b4c76330c54d22": { + "balance": "0x6c6b935b8bbd400000" + }, + "902d74a157f7d2b9a3378b1f56703730e03a1719": { + "balance": "0xd8d726b7177a800000" + }, + "903413878aea3bc1086309a3fe768b65559e8cab": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "904966cc2213b5b8cb5bd6089ef9cddbef7edfcc": { + "balance": "0x6c6b935b8bbd400000" + }, + "904caa429c619d940f8e6741826a0db692b19728": { + "balance": "0x3635c9adc5dea00000" + }, + "9052f2e4a3e3c12dd1c71bf78a4ec3043dc88b7e": { + "balance": "0xe7eeba3410b740000" + }, + "905526568ac123afc0e84aa715124febe83dc87c": { + "balance": "0xf8699329677e0000" + }, + "9092918707c621fdbd1d90fb80eb787fd26f7350": { + "balance": "0x855b5ba65c84f00000" + }, + "909b5e763a39dcc795223d73a1dbb7d94ca75ac8": { + "balance": "0x6c6b935b8bbd400000" + }, + "90acced7e48c08c6b934646dfa0adf29dc94074f": { + "balance": "0x30b4b157bbd490000" + }, + "90b1f370f9c1eb0be0fb8e2b8ad96a416371dd8a": { + "balance": "0x30ca024f987b900000" + }, + "90b62f131a5f29b45571513ee7a74a8f0b232202": { + "balance": "0x890b0c2e14fb80000" + }, + "90bd62a050845261fa4a9f7cf241ea630b05efb8": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "90c41eba008e20cbe927f346603fc88698125969": { + "balance": "0x246ddf97976680000" + }, + "90d2809ae1d1ffd8f63eda01de49dd552df3d1bc": { + "balance": "0xd8bb6549b02bb80000" + }, + "90dc09f717fc2a5b69fd60ba08ebf40bf4e8246c": { + "balance": "0xd8d8583fa2d52f0000" + }, + "90e300ac71451e401f887f6e7728851647a80e07": { + "balance": "0x15af1d78b58c400000" + }, + "90e35aabb2deef408bb9b5acef714457dfde6272": { + "balance": "0x56cd55fc64dfe0000" + }, + "90e7070f4d033fe6910c9efe5a278e1fc6234def": { + "balance": "0x571380819b3040000" + }, + "90e93e4dc17121487952333614002be42356498e": { + "balance": "0x678a932062e4180000" + }, + "90e9a9a82edaa814c284d232b6e9ba90701d4952": { + "balance": "0x56be03ca3e47d8000" + }, + "90f774c9147dde90853ddc43f08f16d455178b8c": { + "balance": "0xd8d726b7177a800000" + }, + "90fc537b210658660a83baa9ac4a8402f65746a8": { + "balance": "0x65ea3db75546600000" + }, + "91050a5cffadedb4bb6eaafbc9e5013428e96c80": { + "balance": "0x5c283d410394100000" + }, + "91051764af6b808e4212c77e30a5572eaa317070": { + "balance": "0x3635c9adc5dea00000" + }, + "910b7d577a7e39aa23acf62ad7f1ef342934b968": { + "balance": "0x21e19e0c9bab2400000" + }, + "910e996543344c6815fb97cda7af4b8698765a5b": { + "balance": "0x59af69829cf640000" + }, + "911feea61fe0ed50c5b9e5a0d66071399d28bdc6": { + "balance": "0x340aad21b3b700000" + }, + "911ff233e1a211c0172c92b46cf997030582c83a": { + "balance": "0x6acb3df27e1f880000" + }, + "9120e71173e1ba19ba8f9f4fdbdcaa34e1d6bb78": { + "balance": "0x6c6b935b8bbd400000" + }, + "91211712719f2b084d3b3875a85069f466363141": { + "balance": "0x3635c9adc5dea00000" + }, + "912304118b80473d9e9fe3ee458fbe610ffda2bb": { + "balance": "0xad78ebc5ac6200000" + }, + "91546b79ecf69f936b5a561508b0d7e50cc5992f": { + "balance": "0xe7eeba3410b740000" + }, + "9156d18029350e470408f15f1aa3be9f040a67c6": { + "balance": "0x3635c9adc5dea00000" + }, + "91620f3eb304e813d28b0297556d65dc4e5de5aa": { + "balance": "0xcf152640c5c8300000" + }, + "916bf7e3c545921d3206d900c24f14127cbd5e70": { + "balance": "0x3d0ddbc7df2bb100000" + }, + "916cf17d71412805f4afc3444a0b8dd1d9339d16": { + "balance": "0xc673ce3c40160000" + }, + "917b8f9f3a8d09e9202c52c29e724196b897d35e": { + "balance": "0x8ba52e6fc45e40000" + }, + "918967918cd897dd0005e36dc6c883ef438fc8c7": { + "balance": "0x796e3ea3f8ab00000" + }, + "91898eab8c05c0222883cd4db23b7795e1a24ad7": { + "balance": "0x6c6b935b8bbd400000" + }, + "9191f94698210516cf6321a142070e20597674ed": { + "balance": "0xee9d5be6fc110000" + }, + "91a4149a2c7b1b3a67ea28aff34725e0bf8d7524": { + "balance": "0x692ae8897081d00000" + }, + "91a787bc5196f34857fe0c372f4df376aaa76613": { + "balance": "0x6c6b935b8bbd400000" + }, + "91a8baaed012ea2e63803b593d0d0c2aab4c5b0a": { + "balance": "0x5150ae84a8cdf00000" + }, + "91ac5cfe67c54aa7ebfba448666c461a3b1fe2e1": { + "balance": "0x15c93492bf9dfc0000" + }, + "91bb3f79022bf3c453f4ff256e269b15cf2c9cbd": { + "balance": "0x52585c13fe3a5c0000" + }, + "91c75e3cb4aa89f34619a164e2a47898f5674d9c": { + "balance": "0x6c6b935b8bbd400000" + }, + "91c80caa081b38351d2a0e0e00f80a34e56474c1": { + "balance": "0x3635c9adc5dea00000" + }, + "91cc46aa379f856a6640dccd5a648a7902f849d9": { + "balance": "0xad78ebc5ac6200000" + }, + "91d2a9ee1a6db20f5317cca7fbe2313895db8ef8": { + "balance": "0x1ccc3a52f306e280000" + }, + "91d66ea6288faa4b3d606c2aa45c7b6b8a252739": { + "balance": "0x6c6b935b8bbd400000" + }, + "91dbb6aaad149585be47375c5d6de5ff09191518": { + "balance": "0x43c33c1937564800000" + }, + "91e8810652e8e6161525d63bb7751dc20f676076": { + "balance": "0x274d656ac90e340000" + }, + "91f516146cda20281719978060c6be4149067c88": { + "balance": "0x6c6b935b8bbd400000" + }, + "91f624b24a1fa5a056fe571229e7379db14b9a1e": { + "balance": "0x28a8517c669b3570000" + }, + "91fe8a4c6164df8fa606995d6ba7adcaf1c893ce": { + "balance": "0x39992648a23c8a00000" + }, + "921f5261f4f612760706892625c75e7bce96b708": { + "balance": "0x6c6b935b8bbd400000" + }, + "9221c9ce01232665741096ac07235903ad1fe2fc": { + "balance": "0x6db63335522628000" + }, + "9225983860a1cb4623c72480ac16272b0c95e5f5": { + "balance": "0x6c6b935b8bbd400000" + }, + "9225d46a5a80943924a39e5b84b96da0ac450581": { + "balance": "0x878678326eac9000000" + }, + "922a20c79a1d3a26dd3829677bf1d45c8f672bb6": { + "balance": "0xd8d726b7177a800000" + }, + "92438e5203b6346ff886d7c36288aacccc78ceca": { + "balance": "0x3635c9adc5dea00000" + }, + "9243d7762d77287b12638688b9854e88a769b271": { + "balance": "0x3635c9adc5dea00000" + }, + "924bce7a853c970bb5ec7bb759baeb9c7410857b": { + "balance": "0xbe202d6a0eda0000" + }, + "924efa6db595b79313277e88319625076b580a10": { + "balance": "0x6c6b935b8bbd400000" + }, + "92558226b384626cad48e09d966bf1395ee7ea5d": { + "balance": "0x121ea68c114e510000" + }, + "926082cb7eed4b1993ad245a477267e1c33cd568": { + "balance": "0x144a74badfa4b60000" + }, + "926209b7fda54e8ddb9d9e4d3d19ebdc8e88c29f": { + "balance": "0x6c6b935b8bbd400000" + }, + "9268d62646563611dc3b832a30aa2394c64613e3": { + "balance": "0x6c6b935b8bbd400000" + }, + "92698e345378c62d8eda184d94366a144b0c105b": { + "balance": "0x4be4e7267b6ae00000" + }, + "92793ac5b37268774a7130de2bbd330405661773": { + "balance": "0x22ca3587cf4eb0000" + }, + "9279b2228cec8f7b4dda3f320e9a0466c2f585ca": { + "balance": "0x10f0cf064dd59200000" + }, + "927cb7dc187036b5427bc7e200c5ec450c1d27d4": { + "balance": "0xbb59a27953c600000" + }, + "927cc2bfda0e088d02eff70b38b08aa53cc30941": { + "balance": "0x646f60a1f986360000" + }, + "9284f96ddb47b5186ee558aa31324df5361c0f73": { + "balance": "0x3635c9adc5dea000000" + }, + "929d368eb46a2d1fbdc8ffa0607ede4ba88f59ad": { + "balance": "0x6c6b935b8bbd400000" + }, + "92a7c5a64362e9f842a23deca21035857f889800": { + "balance": "0x6c6acc67d7b1d40000" + }, + "92a898d46f19719c38126a8a3c27867ae2cee596": { + "balance": "0x6c6b935b8bbd400000" + }, + "92a971a739799f8cb48ea8475d72b2d2474172e6": { + "balance": "0xd5967be4fc3f100000" + }, + "92aae59768eddff83cfe60bb512e730a05a161d7": { + "balance": "0x5c9778410c76d18000" + }, + "92ad1b3d75fba67d54663da9fc848a8ade10fa67": { + "balance": "0x6c6b935b8bbd400000" + }, + "92ae5b7c7eb492ff1ffa16dd42ad9cad40b7f8dc": { + "balance": "0x2ee449550898e40000" + }, + "92c0f573eccf62c54810ee6ba8d1f113542b301b": { + "balance": "0xb7726f16ccb1e00000" + }, + "92c13fe0d6ce87fd50e03def9fa6400509bd7073": { + "balance": "0x22b1c8c1227a00000" + }, + "92c94c2820dfcf7156e6f13088ece7958b3676fd": { + "balance": "0x52d542804f1ce0000" + }, + "92cfd60188efdfb2f8c2e7b1698abb9526c1511f": { + "balance": "0x6c6b935b8bbd400000" + }, + "92d8ad9a4d61683b80d4a6672e84c20d62421e80": { + "balance": "0x1158e460913d00000" + }, + "92dca5e102b3b81b60f1a504634947c374a88ccb": { + "balance": "0x6c6b935b8bbd400000" + }, + "92e435340e9d253c00256389f52b067d55974e76": { + "balance": "0xe873f44133cb00000" + }, + "92e4392816e5f2ef5fb65837cec2c2325cc64922": { + "balance": "0x21e19e0c9bab2400000" + }, + "92e6581e1da1f9b846e09347333dc818e2d2ac66": { + "balance": "0xc55325ca7415e00000" + }, + "931df34d1225bcd4224e63680d5c4c09bce735a6": { + "balance": "0x3afb087b876900000" + }, + "931fe712f64207a2fd5022728843548bfb8cbb05": { + "balance": "0x6c6b935b8bbd400000" + }, + "93235f340d2863e18d2f4c52996516138d220267": { + "balance": "0x4002e44fda7d40000" + }, + "93258255b37c7f58f4b10673a932dd3afd90f4f2": { + "balance": "0x3635c9adc5dea00000" + }, + "9328d55ccb3fce531f199382339f0e576ee840a3": { + "balance": "0xd8d726b7177a800000" + }, + "9329ffdc268babde8874b366406c81445b9b2d35": { + "balance": "0x16e62f8c730ca18000" + }, + "932b9c04d40d2ac83083d94298169dae81ab2ed0": { + "balance": "0x6c6b935b8bbd400000" + }, + "933436c8472655f64c3afaaf7c4c621c83a62b38": { + "balance": "0x3635c9adc5dea00000" + }, + "933bf33f8299702b3a902642c33e0bfaea5c1ca3": { + "balance": "0xd2f13f7789f00000" + }, + "9340345ca6a3eabdb77363f2586043f29438ce0b": { + "balance": "0x1cc805da0dfff10000" + }, + "9340b5f678e45ee05eb708bb7abb6ec8f08f1b6b": { + "balance": "0x14542ba12a337c00000" + }, + "934af21b7ebfa467e2ced65aa34edd3a0ec71332": { + "balance": "0x7801f3e80cc0ff00000" + }, + "935069444a6a984de2084e46692ab99f671fc727": { + "balance": "0x1e7e4171bf4d3a00000" + }, + "93507e9e8119cbceda8ab087e7ecb071383d6981": { + "balance": "0x2f6f10780d22cc00000" + }, + "93678a3c57151aeb68efdc43ef4d36cb59a009f3": { + "balance": "0x1a12a92bc3c3e0000" + }, + "936dcf000194e3bff50ac5b4243a3ba014d661d8": { + "balance": "0x21e19e0c9bab2400000" + }, + "936f3813f5f6a13b8e4ffec83fe7f826186a71cd": { + "balance": "0x1c30731cec03200000" + }, + "9374869d4a9911ee1eaf558bc4c2b63ec63acfdd": { + "balance": "0x3635c9adc5dea00000" + }, + "937563d8a80fd5a537b0e66d20a02525d5d88660": { + "balance": "0x878678326eac900000" + }, + "9376dce2af2ec8dcda741b7e7345664681d93668": { + "balance": "0x3635c9adc5dea00000" + }, + "93868ddb2a794d02ebda2fa4807c76e3609858dc": { + "balance": "0x6dee15fc7c24a78000" + }, + "939c4313d2280edf5e071bced846063f0a975d54": { + "balance": "0x1969368974c05b000000" + }, + "93a6b3ab423010f981a7489d4aad25e2625c5741": { + "balance": "0x44680fe6a1ede4e8000" + }, + "93aa8f92ebfff991fc055e906e651ac768d32bc8": { + "balance": "0x32f51edbaaa3300000" + }, + "93b4bf3fdff6de3f4e56ba6d7799dc4b93a6548f": { + "balance": "0x10910d4cdc9f60000" + }, + "93bc7d9a4abd44c8bbb8fe8ba804c61ad8d6576c": { + "balance": "0xd8d6119a8146050000" + }, + "93c2e64e5de5589ed25006e843196ee9b1cf0b3e": { + "balance": "0x5a87e7d7f5f6580000" + }, + "93c88e2d88621e30f58a9586bed4098999eb67dd": { + "balance": "0x69b5afac750bb800000" + }, + "93e0f37ecdfb0086e3e862a97034447b1e4dec1a": { + "balance": "0x1a055690d9db80000" + }, + "93e303411afaf6c107a44101c9ac5b36e9d6538b": { + "balance": "0xdf9ddfecd0365400000" + }, + "93f18cd2526040761488c513174d1e7963768b2c": { + "balance": "0x82ffac9ad593720000" + }, + "940f715140509ffabf974546fab39022a41952d2": { + "balance": "0x4be4e7267b6ae00000" + }, + "942c6b8c955bc0d88812678a236725b32739d947": { + "balance": "0x54069233bf7f780000" + }, + "943d37864a4a537d35c8d99723cd6406ce2562e6": { + "balance": "0x6c6b935b8bbd400000" + }, + "94439ca9cc169a79d4a09cae5e67764a6f871a21": { + "balance": "0xd02ab486cedc00000" + }, + "94449c01b32a7fa55af8104f42cdd844aa8cbc40": { + "balance": "0x38111a1f4f03c100000" + }, + "9445ba5c30e98961b8602461d0385d40fbd80311": { + "balance": "0x21e19e0c9bab2400000" + }, + "944f07b96f90c5f0d7c0c580533149f3f585a078": { + "balance": "0x402f4cfee62e80000" + }, + "9454b3a8bff9709fd0e190877e6cb6c89974dbd6": { + "balance": "0x90f534608a72880000" + }, + "945d96ea573e8df7262bbfa572229b4b16016b0f": { + "balance": "0xb589ef914c1420000" + }, + "945e18769d7ee727c7013f92de24d117967ff317": { + "balance": "0x6c6b935b8bbd400000" + }, + "94612781033b57b146ee74e753c672017f5385e4": { + "balance": "0xc328093e61ee400000" + }, + "94644ad116a41ce2ca7fbec609bdef738a2ac7c7": { + "balance": "0x10f0cf064dd59200000" + }, + "9470cc36594586821821c5c996b6edc83b6d5a32": { + "balance": "0x14d1120d7b1600000" + }, + "9475c510ec9a26979247744c3d8c3b0e0b5f44d3": { + "balance": "0x21e19e0c9bab2400000" + }, + "947e11e5ea290d6fc3b38048979e0cd44ec7c17f": { + "balance": "0x6c6b935b8bbd400000" + }, + "9483d98f14a33fdc118d403955c29935edfc5f70": { + "balance": "0x18ea3b34ef51880000" + }, + "949131f28943925cfc97d41e0cea0b262973a730": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "949f84f0b1d7c4a7cf49ee7f8b2c4a134de32878": { + "balance": "0x252248deb6e6940000" + }, + "949f8c107bc7f0aceaa0f17052aadbd2f9732b2e": { + "balance": "0x6c6b935b8bbd400000" + }, + "94a7cda8f481f9d89d42c303ae1632b3b709db1d": { + "balance": "0x1043561a8829300000" + }, + "94a9a71691317c2064271b51c9353fbded3501a8": { + "balance": "0xb50fcfafebecb00000" + }, + "94ad4bad824bd0eb9ea49c58cebcc0ff5e08346b": { + "balance": "0x692ae8897081d00000" + }, + "94bbc67d13f89ebca594be94bc5170920c30d9f3": { + "balance": "0x458ffa3150a540000" + }, + "94be3ae54f62d663b0d4cc9e1ea8fe9556ea9ebf": { + "balance": "0x143132ca843180000" + }, + "94c055e858357aaa30cf2041fa9059ce164a1f91": { + "balance": "0x43c25e0dcc1bd1c0000" + }, + "94c742fd7a8b7906b3bfe4f8904fc0be5c768033": { + "balance": "0x43c33c1937564800000" + }, + "94ca56de777fd453177f5e0694c478e66aff8a84": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "94d81074db5ae197d2bb1373ab80a87d121c4bd3": { + "balance": "0x1fd933494aa5fe00000" + }, + "94db807873860aac3d5aea1e885e52bff2869954": { + "balance": "0xae8e7a0bb575d00000" + }, + "94e1f5cb9b8abace03a1a6428256553b690c2355": { + "balance": "0x1158e460913d00000" + }, + "94ef8be45077c7d4c5652740de946a62624f713f": { + "balance": "0x56cf5593a18f88000" + }, + "94f13f9f0836a3ee2437a84922d2984dc0f7d53b": { + "balance": "0xa2a0329bc38abe0000" + }, + "94f8f057db7e60e675ad940f155885d1a477348e": { + "balance": "0x15be6174e1912e0000" + }, + "94fcceadfe5c109c5eaeaf462d43873142c88e22": { + "balance": "0x1043561a88293000000" + }, + "95034e1621865137cd4739b346dc17da3a27c34e": { + "balance": "0x55a6e79ccd1d300000" + }, + "950c68a40988154d2393fff8da7ccda99614f72c": { + "balance": "0xf94146fd8dcde58000" + }, + "950fe9c6cad50c18f11a9ed9c45740a6180612d0": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "952183cfd38e352e579d36decec5b18450f7fba0": { + "balance": "0x6c6b935b8bbd400000" + }, + "95278b08dee7c0f2c8c0f722f9fcbbb9a5241fda": { + "balance": "0x829309f64f0db00000" + }, + "952c57d2fb195107d4cd5ca300774119dfad2f78": { + "balance": "0x6c6b935b8bbd400000" + }, + "953572f0ea6df9b197cae40e4b8ecc056c4371c5": { + "balance": "0x3635c9adc5dea00000" + }, + "953ef652e7b769f53d6e786a58952fa93ee6abe7": { + "balance": "0x9b0a791f1211300000" + }, + "95447046313b2f3a5e19b948fd3b8bedc82c717c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "955db3b74360b9a268677e73cea821668af6face": { + "balance": "0x65a4da25d3016c00000" + }, + "9560e8ac6718a6a1cdcff189d603c9063e413da6": { + "balance": "0xd8d726b7177a800000" + }, + "9567a0de811de6ff095b7ee64e7f1b83c2615b80": { + "balance": "0xe7eeba3410b740000" + }, + "95681cdae69b2049ce101e325c759892cac3f811": { + "balance": "0x9ae92a9bc94c400000" + }, + "9568b7de755628af359a84543de23504e15e41e6": { + "balance": "0x878678326eac9000000" + }, + "9569c63a9284a805626db3a32e9d236393476151": { + "balance": "0x6acb3df27e1f880000" + }, + "95809e8da3fbe4b7f281f0b8b1715f420f7d7d63": { + "balance": "0x6c6b935b8bbd400000" + }, + "959f57fded6ae37913d900b81e5f48a79322c627": { + "balance": "0xddb26104749118000" + }, + "959ff17f1d51b473b44010052755a7fa8c75bd54": { + "balance": "0x6acb3df27e1f880000" + }, + "95a577dc2eb3ae6cb9dfc77af697d7efdfe89a01": { + "balance": "0x75f610f70ed200000" + }, + "95cb6d8a6379f94aba8b885669562c4d448e56a7": { + "balance": "0x6c6b935b8bbd400000" + }, + "95d550427b5a514c751d73a0f6d29fb65d22ed10": { + "balance": "0x1043561a8829300000" + }, + "95d98d0c1069908f067a52acac2b8b534da37afd": { + "balance": "0x6f59b630a929708000" + }, + "95df4e3445d7662624c48eba74cf9e0a53e9f732": { + "balance": "0xbdbc41e0348b3000000" + }, + "95e6a54b2d5f67a24a4875af75107ca7ea9fd2fa": { + "balance": "0x487a9a304539440000" + }, + "95e6f93dac228bc7585a25735ac2d076cc3a4017": { + "balance": "0x14542ba12a337c00000" + }, + "95e7616424cd0961a71727247437f0069272280e": { + "balance": "0x15af1d78b58c400000" + }, + "95e80a82c20cbe3d2060242cb92d735810d034a2": { + "balance": "0x1c32e463fd4b98000" + }, + "95f62d0243ede61dad9a3165f53905270d54e242": { + "balance": "0x57473d05dabae80000" + }, + "95fb5afb14c1ef9ab7d179c5c300503fd66a5ee2": { + "balance": "0x1daf7a02b0dbe8000" + }, + "9610592202c282ab9bd8a884518b3e0bd4758137": { + "balance": "0xe873f44133cb00000" + }, + "961c59adc74505d1864d1ecfcb8afa0412593c93": { + "balance": "0x878678326eac9000000" + }, + "962c0dec8a3d464bf39b1215eafd26480ae490cd": { + "balance": "0x6c82e3eaa513e80000" + }, + "962cd22a8edf1e4f4e55b4b15ddbfb5d9d541971": { + "balance": "0x6c6b935b8bbd400000" + }, + "96334bfe04fffa590213eab36514f338b864b736": { + "balance": "0x15af1d78b58c400000" + }, + "9637dc12723d9c78588542eab082664f3f038d9d": { + "balance": "0x3635c9adc5dea00000" + }, + "964eab4b276b4cd8983e15ca72b106900fe41fce": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "9662ee021926682b31c5f200ce457abea76c6ce9": { + "balance": "0x24590e8589eb6a0000" + }, + "966c04781cb5e67dde3235d7f8620e1ab663a9a5": { + "balance": "0x100d2050da6351600000" + }, + "967076a877b18ec15a415bb116f06ef32645dba3": { + "balance": "0x6c6b935b8bbd400000" + }, + "967bfaf76243cdb9403c67d2ceefdee90a3feb73": { + "balance": "0x349d87f2a2dc2f0000" + }, + "967d4142af770515dd7062af93498dbfdff29f20": { + "balance": "0x11854d0f9cee40000" + }, + "968b14648f018333687cd213fa640aec04ce6323": { + "balance": "0x3635c9adc5dea00000" + }, + "968dea60df3e09ae3c8d3505e9c080454be0e819": { + "balance": "0x14542ba12a337c00000" + }, + "96924191b7df655b3319dc6d6137f481a73a0ff3": { + "balance": "0xd9ecb4fd208e500000" + }, + "9696052138338c722f1140815cf7749d0d3b3a74": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "96a55f00dff405dc4de5e58c57f6f6f0cac55d2f": { + "balance": "0x6a6616379c87b58000" + }, + "96aa573fed2f233410dbae5180145b23c31a02f0": { + "balance": "0x5dc892aa1131c80000" + }, + "96ad579bbfa8db8ebec9d286a72e4661eed8e356": { + "balance": "0x3a0ba42bec61830000" + }, + "96b434fe0657e42acc8212b6865139dede15979c": { + "balance": "0xd8d726b7177a800000" + }, + "96b906ea729f4655afe3e57d35277c967dfa1577": { + "balance": "0x3635c9adc5dea00000" + }, + "96d62dfd46087f62409d93dd606188e70e381257": { + "balance": "0x6c6b935b8bbd400000" + }, + "96d9cca8f55eea0040ec6eb348a1774b95d93ef4": { + "balance": "0xd8d726b7177a800000" + }, + "96e7c0c9d5bf10821bf140c558a145b7cac21397": { + "balance": "0x393ef1a5127c800000" + }, + "96ea6ac89a2bac95347b51dba63d8bd5ebdedce1": { + "balance": "0x6c6b935b8bbd400000" + }, + "96eafbf2fb6f4db9a436a74c45b5654452e23819": { + "balance": "0x1158e460913d00000" + }, + "96eb523e832f500a017de13ec27f5d366c560eff": { + "balance": "0x10acceba43ee280000" + }, + "96f0462ae6f8b96088f7e9c68c74b9d8ad34b347": { + "balance": "0x61093d7c2c6d380000" + }, + "96f820500b70f4a3e3239d619cff8f222075b135": { + "balance": "0xad78ebc5ac6200000" + }, + "96fe59c3dbb3aa7cc8cb62480c65e56e6204a7e2": { + "balance": "0x43c33c1937564800000" + }, + "96ff6f509968f36cb42cba48db32f21f5676abf8": { + "balance": "0x6acb3df27e1f880000" + }, + "970938522afb5e8f994873c9fbdc26e3b37e314c": { + "balance": "0x3635c9adc5dea00000" + }, + "970abd53a54fca4a6429207c182d4d57bb39d4a0": { + "balance": "0x6c6b935b8bbd400000" + }, + "970d8b8a0016d143054f149fb3b8e550dc0797c7": { + "balance": "0x3635c9adc5dea00000" + }, + "972c2f96aa00cf8a2f205abcf8937c0c75f5d8d9": { + "balance": "0xad78ebc5ac6200000" + }, + "973f4e361fe5decd989d4c8f7d7cc97990385daf": { + "balance": "0x150f8543a387420000" + }, + "974d0541ab4a47ec7f75369c0069b64a1b817710": { + "balance": "0x15af1d78b58c400000" + }, + "974d2f17895f2902049deaaecf09c3046507402d": { + "balance": "0xcc19c29437ab8000" + }, + "9752d14f5e1093f071711c1adbc4e3eb1e5c57f3": { + "balance": "0x6c6b935b8bbd400000" + }, + "9756e176c9ef693ee1eec6b9f8b151d313beb099": { + "balance": "0x410d586a20a4c00000" + }, + "975f3764e97bbccf767cbd3b795ba86d8ba9840e": { + "balance": "0x12c1b6eed03d280000" + }, + "976a18536af41874426308871bcd1512a775c9f8": { + "balance": "0x21e19e0c9bab2400000" + }, + "976e3ceaf3f1af51f8c29aff5d7fa21f0386d8ee": { + "balance": "0xd02ab486cedc00000" + }, + "9777cc61cf756be3b3c20cd4491c69d275e7a120": { + "balance": "0x21e19e0c9bab2400000" + }, + "97810bafc37e84306332aacb35e92ad911d23d24": { + "balance": "0x3635c9adc5dea00000" + }, + "978c430ce4359b06bc2cdf5c2985fc950e50d5c8": { + "balance": "0x1a055690d9db800000" + }, + "9795f64319fc17dd0f8261f9d206fb66b64cd0c9": { + "balance": "0xad78ebc5ac6200000" + }, + "9799ca21dbcf69bfa1b3f72bac51b9e3ca587cf9": { + "balance": "0x5c283d410394100000" + }, + "979cbf21dfec8ace3f1c196d82df962534df394f": { + "balance": "0x9991d478dd4d160000" + }, + "979d681c617da16f21bcaca101ed16ed015ab696": { + "balance": "0x65ea3db75546600000" + }, + "979f30158b574b999aab348107b9eed85b1ff8c1": { + "balance": "0x34957444b840e80000" + }, + "97a86f01ce3f7cfd4441330e1c9b19e1b10606ef": { + "balance": "0x6c6b935b8bbd400000" + }, + "97b91efe7350c2d57e7e406bab18f3617bcde14a": { + "balance": "0x21e1999bbd5d2be0000" + }, + "97d0d9725e3b70e675843173938ed371b62c7fac": { + "balance": "0x93739534d28680000" + }, + "97d9e46a7604d7b5a4ea4ee61a42b3d2350fc3ed": { + "balance": "0x6c6b935b8bbd400000" + }, + "97dc26ec670a31e0221d2a75bc5dc9f90c1f6fd4": { + "balance": "0x2b5e3af16b1880000" + }, + "97de21e421c37fe4b8025f9a51b7b390b5df7804": { + "balance": "0x10f0cf064dd592000000" + }, + "97e28973b860c567402800fbb63ce39a048a3d79": { + "balance": "0x542253a126ce40000" + }, + "97e5cc6127c4f885be02f44b42d1c8b0ac91e493": { + "balance": "0xad78ebc5ac6200000" + }, + "97f1fe4c8083e596212a187728dd5cf80a31bec5": { + "balance": "0x1158e460913d00000" + }, + "97f7760657c1e202759086963eb4211c5f8139b9": { + "balance": "0xa8a097fcb3d17680000" + }, + "97f99b6ba31346cd98a9fe4c308f87c5a58c5151": { + "balance": "0x14542ba12a337c00000" + }, + "980a84b686fc31bdc83c221058546a71b11f838a": { + "balance": "0x2a415548af86818000" + }, + "9810e34a94db6ed156d0389a0e2b80f4fd6b0a8a": { + "balance": "0x6c6b935b8bbd400000" + }, + "981ddf0404e4d22dda556a0726f00b2d98ab9569": { + "balance": "0x36356633ebd8ea0000" + }, + "981f712775c0dad97518ffedcb47b9ad1d6c2762": { + "balance": "0x16a6502f15a1e540000" + }, + "9834682180b982d166badb9d9d1d9bbf016d87ee": { + "balance": "0x6c6b935b8bbd400000" + }, + "9836b4d30473641ab56aeee19242761d72725178": { + "balance": "0x6c6b935b8bbd400000" + }, + "98397342ec5f3d4cb877e54ef5d6f1d366731bd4": { + "balance": "0x14061b9d77a5e980000" + }, + "9846648836a307a057184fd51f628a5f8c12427c": { + "balance": "0x40b69bf43dce8f00000" + }, + "984a7985e3cc7eb5c93691f6f8cc7b8f245d01b2": { + "balance": "0x14542ba12a337c00000" + }, + "985d70d207892bed398590024e2421b1cc119359": { + "balance": "0x43c33c1937564800000" + }, + "986df47e76e4d7a789cdee913cc9831650936c9d": { + "balance": "0x10f0cf064dd59200000" + }, + "9874803fe1f3a0365e7922b14270eaeb032cc1b5": { + "balance": "0x3cf5928824c6c20000" + }, + "9875623495a46cdbf259530ff838a1799ec38991": { + "balance": "0x6c6b935b8bbd400000" + }, + "987618c85656207c7bac1507c0ffefa2fb64b092": { + "balance": "0x37dfe433189e38000" + }, + "987c9bcd6e3f3990a52be3eda4710c27518f4f72": { + "balance": "0x15af1d78b58c400000" + }, + "9882967cee68d2a839fad8ab4a7c3dddf6c0adc8": { + "balance": "0x4878be1ffaf95d0000" + }, + "98855c7dfbee335344904a12c40c731795b13a54": { + "balance": "0x39fbae8d042dd00000" + }, + "989c0ccff654da03aeb11af701054561d6297e1d": { + "balance": "0xd8d726b7177a800000" + }, + "98a0e54c6d9dc8be96276cebf4fec460f6235d85": { + "balance": "0x6ac882100952c78000" + }, + "98b769cc305cecfb629a00c907069d7ef9bc3a12": { + "balance": "0x168d28e3f00280000" + }, + "98ba4e9ca72fddc20c69b4396f76f8183f7a2a4e": { + "balance": "0x2b5e3af16b188000000" + }, + "98be696d51e390ff1c501b8a0f6331b628ddc5ad": { + "balance": "0x6c6b935b8bbd400000" + }, + "98bed3a72eccfbafb923489293e429e703c7e25b": { + "balance": "0x6c6b935b8bbd400000" + }, + "98bf4af3810b842387db70c14d46099626003d10": { + "balance": "0xd8d726b7177a800000" + }, + "98c10ebf2c4f97cba5a1ab3f2aafe1cac423f8cb": { + "balance": "0x1043561a8829300000" + }, + "98c19dba810ba611e68f2f83ee16f6e7744f0c1f": { + "balance": "0xad78ebc5ac6200000" + }, + "98c5494a03ac91a768dffc0ea1dde0acbf889019": { + "balance": "0x2a5a058fc295ed000000" + }, + "98d204f9085f8c8e7de23e589b64c6eff692cc63": { + "balance": "0x6c6b935b8bbd400000" + }, + "98d3731992d1d40e1211c7f735f2189afa0702e0": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "98e2b6d606fd2d6991c9d6d4077fdf3fdd4585da": { + "balance": "0x30df1a6f8ad6280000" + }, + "98e3e90b28fccaee828779b8d40a5568c4116e21": { + "balance": "0x22b1c8c1227a00000" + }, + "98e6f547db88e75f1f9c8ac2c5cf1627ba580b3e": { + "balance": "0x3635c9adc5dea00000" + }, + "98f4af3af0aede5fafdc42a081ecc1f89e3ccf20": { + "balance": "0x1fd933494aa5fe00000" + }, + "98f6b8e6213dbc9a5581f4cce6655f95252bdb07": { + "balance": "0x115872b0bca4300000" + }, + "9909650dd5b1397b8b8b0eb69499b291b0ad1213": { + "balance": "0xad78ebc5ac6200000" + }, + "991173601947c2084a62d639527e961512579af9": { + "balance": "0x2086ac351052600000" + }, + "99129d5b3c0cde47ea0def4dfc070d1f4a599527": { + "balance": "0x6c6b935b8bbd400000" + }, + "9917d68d4af341d651e7f0075c6de6d7144e7409": { + "balance": "0x132d4476c08e6f00000" + }, + "991ac7ca7097115f26205eee0ef7d41eb4e311ae": { + "balance": "0x1158e460913d00000" + }, + "992365d764c5ce354039ddfc912e023a75b8e168": { + "balance": "0xfc936392801c0000" + }, + "992646ac1acaabf5ddaba8f9429aa6a94e7496a7": { + "balance": "0x3637507a30abeb0000" + }, + "99268327c373332e06c3f6164287d455b9d5fa4b": { + "balance": "0x6c6b935b8bbd400000" + }, + "9928ff715afc3a2b60f8eb4cc4ba4ee8dab6e59d": { + "balance": "0x17da3a04c7b3e00000" + }, + "9932ef1c85b75a9b2a80057d508734c51085becc": { + "balance": "0x2b83fa5301d590000" + }, + "993f146178605e66d517be782ef0b3c61a4e1925": { + "balance": "0x17c1f0535d7a5830000" + }, + "99413704b1a32e70f3bc0d69dd881c38566b54cb": { + "balance": "0x5cc6b694631f7120000" + }, + "994152fc95d5c1ca8b88113abbad4d710e40def6": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "9944fee9d34a4a880023c78932c00b59d5c82a82": { + "balance": "0x28a8a56b3690070000" + }, + "994cc2b5227ec3cf048512467c41b7b7b748909f": { + "balance": "0x6c6b935b8bbd400000" + }, + "9971df60f0ae66dce9e8c84e17149f09f9c52f64": { + "balance": "0xad78ebc5ac6200000" + }, + "9976947eff5f6ae5da08dd541192f378b428ff94": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "997d6592a31589acc31b9901fbeb3cc3d65b3215": { + "balance": "0x6c6b935b8bbd400000" + }, + "9982a5890ffb5406d3aca8d2bfc1dd70aaa80ae0": { + "balance": "0x6c6b935b8bbd400000" + }, + "99878f9d6e0a7ed9aec78297b73879a80195afe0": { + "balance": "0xd7c198710e66b00000" + }, + "998c1f93bcdb6ff23c10d0dc924728b73be2ff9f": { + "balance": "0x365bf3a433eaf30000" + }, + "9991614c5baa47dd6c96874645f97add2c3d8380": { + "balance": "0x6acb3df27e1f880000" + }, + "99924a9816bb7ddf3fec1844828e9ad7d06bf4e6": { + "balance": "0x5f68e8131ecf800000" + }, + "99997668f7c1a4ff9e31f9977ae3224bcb887a85": { + "balance": "0xfc936392801c00000" + }, + "999c49c174ca13bc836c1e0a92bff48b271543ca": { + "balance": "0xb1cf24ddd0b1400000" + }, + "99a4de19ded79008cfdcd45d014d2e584b8914a8": { + "balance": "0x5150ae84a8cdf00000" + }, + "99a96bf2242ea1b39ece6fcc0d18aed00c0179f3": { + "balance": "0x1043561a8829300000" + }, + "99b018932bcad355b6792b255db6702dec8ce5dd": { + "balance": "0xd8d8583fa2d52f0000" + }, + "99b743d1d9eff90d9a1934b4db21d519d89b4a38": { + "balance": "0x56bc75e2d63100000" + }, + "99b8c824869de9ed24f3bff6854cb6dd45cc3f9f": { + "balance": "0x65ea3db75546600000" + }, + "99c0174cf84e0783c220b4eb6ae18fe703854ad3": { + "balance": "0x7079a2573d0c780000" + }, + "99c1d9f40c6ab7f8a92fce2fdce47a54a586c53f": { + "balance": "0x35659ef93f0fc40000" + }, + "99c236141daec837ece04fdaee1d90cf8bbdc104": { + "balance": "0x766516acac0d200000" + }, + "99c31fe748583787cdd3e525b281b218961739e3": { + "balance": "0x3708baed3d68900000" + }, + "99c475bf02e8b9214ada5fad02fdfd15ba365c0c": { + "balance": "0x2009c5c8bf6fdc0000" + }, + "99c883258546cc7e4e971f522e389918da5ea63a": { + "balance": "0xd8d726b7177a800000" + }, + "99c9f93e45fe3c1418c353e4c5ac3894eef8121e": { + "balance": "0x585baf145050b0000" + }, + "99d1579cd42682b7644e1d4f7128441eeffe339d": { + "balance": "0x43c33c1937564800000" + }, + "99d1b585965f406a42a49a1ca70f769e765a3f98": { + "balance": "0x3894f0e6f9b9f700000" + }, + "99dfd0504c06c743e46534fd7b55f1f9c7ec3329": { + "balance": "0x6c6b935b8bbd400000" + }, + "99f4147ccc6bcb80cc842e69f6d00e30fa4133d9": { + "balance": "0x15af1d78b58c400000" + }, + "99f77f998b20e0bcdcd9fc838641526cf25918ef": { + "balance": "0x61093d7c2c6d380000" + }, + "99fad50038d0d9d4c3fbb4bce05606ecadcd5121": { + "balance": "0x6c6b935b8bbd400000" + }, + "99fe0d201228a753145655d428eb9fd94985d36d": { + "balance": "0x6920bff3515a3a0000" + }, + "9a079c92a629ca15c8cafa2eb28d5bc17af82811": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "9a0d3cee3d9892ea3b3700a27ff84140d9025493": { + "balance": "0x340aad21b3b700000" + }, + "9a24ce8d485cc4c86e49deb39022f92c7430e67e": { + "balance": "0x46791fc84e07d00000" + }, + "9a2ce43b5d89d6936b8e8c354791b8afff962425": { + "balance": "0x6c6b935b8bbd400000" + }, + "9a390162535e398877e416787d6239e0754e937c": { + "balance": "0x3635c9adc5dea00000" + }, + "9a3da65023a13020d22145cfc18bab10bd19ce4e": { + "balance": "0x18bf6ea3464a3a0000" + }, + "9a3e2b1bf346dd070b027357feac44a4b2c97db8": { + "balance": "0x21e19e0c9bab2400000" + }, + "9a4ca8b82117894e43db72b9fa78f0b9b93ace09": { + "balance": "0x2b5e3af16b1880000" + }, + "9a522e52c195bfb7cf5ffaaedb91a3ba7468161d": { + "balance": "0x3635c9adc5dea00000" + }, + "9a5af31c7e06339ac8b4628d7c4db0ce0f45c8a4": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "9a633fcd112cceeb765fe0418170732a9705e79c": { + "balance": "0xfc936392801c0000" + }, + "9a63d185a79129fdab19b58bb631ea36a420544e": { + "balance": "0x246ddf97976680000" + }, + "9a6708ddb8903c289f83fe889c1edcd61f854423": { + "balance": "0x3635c9adc5dea00000" + }, + "9a6ff5f6a7af7b7ae0ed9c20ecec5023d281b786": { + "balance": "0x8a12b9bd6a67ec0000" + }, + "9a82826d3c29481dcc2bd2950047e8b60486c338": { + "balance": "0x43c33c1937564800000" + }, + "9a8eca4189ff4aa8ff7ed4b6b7039f0902219b15": { + "balance": "0x1158e460913d00000" + }, + "9a953b5bcc709379fcb559d7b916afdaa50cadcc": { + "balance": "0x56bc75e2d63100000" + }, + "9a990b8aeb588d7ee7ec2ed8c2e64f7382a9fee2": { + "balance": "0x1d127db69fd8b0000" + }, + "9a9d1dc0baa77d6e20c3d849c78862dd1c054c87": { + "balance": "0x2fb474098f67c00000" + }, + "9aa48c66e4fb4ad099934e32022e827427f277ba": { + "balance": "0x21e19e0c9bab2400000" + }, + "9aa8308f42910e5ade09c1a5e282d6d91710bdbf": { + "balance": "0xad78ebc5ac6200000" + }, + "9aaafa0067647ed999066b7a4ca5b4b3f3feaa6f": { + "balance": "0x3635c9adc5dea00000" + }, + "9ab988b505cfee1dbe9cd18e9b5473b9a2d4f536": { + "balance": "0x1158e460913d000000" + }, + "9ab98d6dbb1eaae16d45a04568541ad3d8fe06cc": { + "balance": "0xec50464fe23f38000" + }, + "9aba2b5e27ff78baaab5cdc988b7be855cebbdce": { + "balance": "0x21e0c0013070adc0000" + }, + "9ac4da51d27822d1e208c96ea64a1e5b55299723": { + "balance": "0x56c5579f722140000" + }, + "9ac85397792a69d78f286b86432a07aeceb60e64": { + "balance": "0xc673ce3c40160000" + }, + "9ac907ee85e6f3e223459992e256a43fa08fa8b2": { + "balance": "0x21e19e0c9bab2400000" + }, + "9ad47fdcf9cd942d28effd5b84115b31a658a13e": { + "balance": "0xb259ec00d53b280000" + }, + "9adbd3bc7b0afc05d1d2eda49ff863939c48db46": { + "balance": "0xad6eedd17cf3b8000" + }, + "9adf458bff3599eee1a26398853c575bc38c6313": { + "balance": "0xf2dc7d47f15600000" + }, + "9ae13bd882f2576575921a94974cbea861ba0d35": { + "balance": "0xab4dcf399a3a600000" + }, + "9ae9476bfecd3591964dd325cf8c2a24faed82c1": { + "balance": "0xd8d726b7177a800000" + }, + "9af100cc3dae83a33402051ce4496b16615483f6": { + "balance": "0x6c6b935b8bbd400000" + }, + "9af11399511c213181bfda3a8b264c05fc81b3ce": { + "balance": "0x2f6f10780d22cc00000" + }, + "9af5c9894c33e42c2c518e3ac670ea9505d1b53e": { + "balance": "0xfc936392801c0000" + }, + "9af9dbe47422d177f945bdead7e6d82930356230": { + "balance": "0xd5967be4fc3f100000" + }, + "9afa536b4c66bc38d875c4b30099d9261fdb38eb": { + "balance": "0xb2a8f842a77bc8000" + }, + "9b06ad841dffbe4ccf46f1039fc386f3c321446e": { + "balance": "0x6c6b935b8bbd400000" + }, + "9b1168de8ab64b47552f3389800a9cc08b4666cf": { + "balance": "0x5dc892aa1131c80000" + }, + "9b1811c3051f46e664ae4bc9c824d18592c4574a": { + "balance": "0xad6eedd17cf3b8000" + }, + "9b18478655a4851cc906e660feac61f7f4c8bffc": { + "balance": "0xe2478d38907d840000" + }, + "9b22a80d5c7b3374a05b446081f97d0a34079e7f": { + "balance": "0xa2a15d09519be00000" + }, + "9b2be7f56754f505e3441a10f7f0e20fd3ddf849": { + "balance": "0x126e72a69a50d00000" + }, + "9b32cf4f5115f4b34a00a64c617de06387354323": { + "balance": "0x5b81ed888207c8000" + }, + "9b43dcb95fde318075a567f1e6b57617055ef9e8": { + "balance": "0xd5967be4fc3f100000" + }, + "9b444fd337e5d75293adcfff70e1ea01db023222": { + "balance": "0x56bc75e2d63100000" + }, + "9b4824ff9fb2abda554dee4fb8cf549165570631": { + "balance": "0x1158e460913d00000" + }, + "9b4c2715780ca4e99e60ebf219f1590c8cad500a": { + "balance": "0x56bc75e2d631000000" + }, + "9b59eb213b1e7565e45047e04ea0374f10762d16": { + "balance": "0x6c6b935b8bbd400000" + }, + "9b5c39f7e0ac168c8ed0ed340477117d1b682ee9": { + "balance": "0x55005f0c614480000" + }, + "9b5ec18e8313887df461d2902e81e67a8f113bb1": { + "balance": "0x56bc75e2d63100000" + }, + "9b64d3cd8d2b73f66841b5c46bb695b88a9ab75d": { + "balance": "0x1203a4f760c168000" + }, + "9b658fb361e046d4fcaa8aef6d02a99111223625": { + "balance": "0x6c6b935b8bbd400000" + }, + "9b6641b13e172fc072ca4b8327a3bc28a15b66a9": { + "balance": "0x68155a43676e00000" + }, + "9b68f67416a63bf4451a31164c92f672a68759e9": { + "balance": "0xcb49b44ba602d800000" + }, + "9b773669e87d76018c090f8255e54409b9dca8b2": { + "balance": "0x1158e460913d00000" + }, + "9b77ebced7e215f0920e8c2b870024f6ecb2ff31": { + "balance": "0x3635c9adc5dea00000" + }, + "9b7c8810cc7cc89e804e6d3e38121850472877fe": { + "balance": "0x6c6b935b8bbd400000" + }, + "9ba53dc8c95e9a472feba2c4e32c1dc4dd7bab46": { + "balance": "0x487a9a304539440000" + }, + "9bacd3d40f3b82ac91a264d9d88d908eac8664b9": { + "balance": "0x43c33c1937564800000" + }, + "9bb760d5c289a3e1db18db095345ca413b9a43c2": { + "balance": "0xaadec983fcff40000" + }, + "9bb76204186af2f63be79168601687fc9bad661f": { + "balance": "0x1043561a8829300000" + }, + "9bb9b02a26bfe1ccc3f0c6219e261c397fc5ca78": { + "balance": "0x487a9a304539440000" + }, + "9bc573bcda23b8b26f9073d90c230e8e71e0270b": { + "balance": "0x362f75a4305d0c0000" + }, + "9bd7c38a4210304a4d653edeff1b3ce45fce7843": { + "balance": "0xf498941e664280000" + }, + "9bd88068e13075f3a8cac464a5f949d6d818c0f6": { + "balance": "0x14542ba12a337c00000" + }, + "9bd905f1719fc7acd0159d4dc1f8db2f21472338": { + "balance": "0x3635c9adc5dea00000" + }, + "9bdbdc9b973431d13c89a3f9757e9b3b6275bfc7": { + "balance": "0x1b1a7dcf8a44d38000" + }, + "9be3c329b62a28b8b0886cbd8b99f8bc930ce3e6": { + "balance": "0x409e52b48369a0000" + }, + "9bf58efbea0784eb068adecfa0bb215084c73a35": { + "balance": "0x13a6b2b564871a00000" + }, + "9bf672d979b36652fc5282547a6a6bc212ae4368": { + "balance": "0x238fd42c5cf0400000" + }, + "9bf703b41c3624e15f4054962390bcba3052f0fd": { + "balance": "0x1483e01533c2e3c0000" + }, + "9bf71f7fb537ac54f4e514947fa7ff6728f16d2f": { + "balance": "0x1cf84a30a0a0c0000" + }, + "9bf9b3b2f23cf461eb591f28340bc719931c8364": { + "balance": "0x3635c9adc5dea00000" + }, + "9bfc659c9c601ea42a6b21b8f17084ec87d70212": { + "balance": "0x21e19e0c9bab2400000" + }, + "9bfff50db36a785555f07652a153b0c42b1b8b76": { + "balance": "0x6c6b935b8bbd400000" + }, + "9c05e9d0f0758e795303717e31da213ca157e686": { + "balance": "0x3635c9adc5dea00000" + }, + "9c1b771f09af882af0643083de2aa79dc097c40e": { + "balance": "0x8670e9ec6598c00000" + }, + "9c28a2c4086091cb5da226a657ce3248e8ea7b6f": { + "balance": "0xf2dc7d47f15600000" + }, + "9c2fd54089af665df5971d73b804616039647375": { + "balance": "0x3635c9adc5dea00000" + }, + "9c344098ba615a398f11d009905b177c44a7b602": { + "balance": "0x3635c9adc5dea00000" + }, + "9c3d0692ceeef80aa4965ceed262ffc7f069f2dc": { + "balance": "0xad78ebc5ac6200000" + }, + "9c405cf697956138065e11c5f7559e67245bd1a5": { + "balance": "0xad78ebc5ac6200000" + }, + "9c45202a25f6ad0011f115a5a72204f2f2198866": { + "balance": "0x10fcf3a62b080980000" + }, + "9c49deff47085fc09704caa2dca8c287a9a137da": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "9c4bbcd5f1644a6f075824ddfe85c571d6abf69c": { + "balance": "0x6194049f30f7200000" + }, + "9c526a140683edf1431cfaa128a935e2b614d88b": { + "balance": "0x6046f37e5945c0000" + }, + "9c54e4ed479a856829c6bb42da9f0b692a75f728": { + "balance": "0x197a8f6dd5519800000" + }, + "9c581a60b61028d934167929b22d70b313c34fd0": { + "balance": "0xa968163f0a57b400000" + }, + "9c5cc111092c122116f1a85f4ee31408741a7d2f": { + "balance": "0x1ab2cf7c9f87e20000" + }, + "9c6bc9a46b03ae5404f043dfcf21883e4110cc33": { + "balance": "0xad78ebc5ac6200000" + }, + "9c78963fbc263c09bd72e4f8def74a9475f7055c": { + "balance": "0x2eb8eb1a172dcb80000" + }, + "9c78fbb4df769ce2c156920cfedfda033a0e254a": { + "balance": "0x6acb3df27e1f880000" + }, + "9c7b6dc5190fe2912963fcd579683ec7395116b0": { + "balance": "0x2a1129d09367200000" + }, + "9c80bc18e9f8d4968b185da8c79fa6e11ffc3e23": { + "balance": "0xd02ab486cedc00000" + }, + "9c98fdf1fdcd8ba8f4c5b04c3ae8587efdf0f6e6": { + "balance": "0x14542ba12a337c00000" + }, + "9c99a1da91d5920bc14e0cb914fdf62b94cb8358": { + "balance": "0x43c33c1937564800000" + }, + "9c99b62606281b5cefabf36156c8fe62839ef5f3": { + "balance": "0xd8d726b7177a800000" + }, + "9c9a07a8e57c3172a919ef64789474490f0d9f51": { + "balance": "0x21e19e0c9bab2400000" + }, + "9c9de44724a4054da0eaa605abcc802668778bea": { + "balance": "0xad7d5ca3fa5a20000" + }, + "9c9f3b8a811b21f3ff3fe20fe970051ce66a824f": { + "balance": "0x3ec2debc07d4be0000" + }, + "9c9f89a3910f6a2ae8a91047a17ab788bddec170": { + "balance": "0x21e19e0c9bab2400000" + }, + "9ca0429f874f8dcee2e9c062a9020a842a587ab9": { + "balance": "0x6c6b935b8bbd400000" + }, + "9ca42ee7a0b898f6a5cc60b5a5d7b1bfa3c33231": { + "balance": "0x6c6b935b8bbd400000" + }, + "9cb28ac1a20a106f7f373692c5ce4c73f13732a1": { + "balance": "0x3635c9adc5dea00000" + }, + "9ccddcb2cfc2b25b08729a0a98d9e6f0202ea2c1": { + "balance": "0x56bc75e2d63100000" + }, + "9ce27f245e02d1c312c1d500788c9def7690453b": { + "balance": "0xad78ebc5ac6200000" + }, + "9ce5363b13e8238aa4dd15acd0b2e8afe0873247": { + "balance": "0xad78ebc5ac6200000" + }, + "9cf2928beef09a40f9bfc953be06a251116182fb": { + "balance": "0x14542ba12a337c00000" + }, + "9d069197d1de50045a186f5ec744ac40e8af91c6": { + "balance": "0x6c6b935b8bbd400000" + }, + "9d0e7d92fb305853d798263bf15e97c72bf9d7e0": { + "balance": "0x3635c9adc5dea00000" + }, + "9d0f347e826b7dceaad279060a35c0061ecf334b": { + "balance": "0xd8d726b7177a800000" + }, + "9d207517422cc0d60de7c237097a4d4fce20940c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "9d250ae4f110d71cafc7b0adb52e8d9acb6679b8": { + "balance": "0x2156d6e997213c00000" + }, + "9d2bfc36106f038250c01801685785b16c86c60d": { + "balance": "0x5077d75df1b675800000" + }, + "9d30cb237bc096f17036fc80dd21ca68992ca2d9": { + "balance": "0x66ee7318fdc8f300000" + }, + "9d32962ea99700d93228e9dbdad2cc37bb99f07e": { + "balance": "0xb4632bedd4ded40000" + }, + "9d34dac25bd15828faefaaf28f710753b39e89dc": { + "balance": "0x3b1c56fed02df00000" + }, + "9d369165fb70b81a3a765f188fd60cbe5e7b0968": { + "balance": "0x6c6b935b8bbd400000" + }, + "9d40e012f60425a340d82d03a1c757bfabc706fb": { + "balance": "0x9346f3addc88d8000" + }, + "9d4174aa6af28476e229dadb46180808c67505c1": { + "balance": "0x421afda42ed6970000" + }, + "9d4213339a01551861764c87a93ce8f85f87959a": { + "balance": "0xad78ebc5ac6200000" + }, + "9d460c1b379ddb19a8c85b4c6747050ddf17a875": { + "balance": "0xb50fcfafebecb00000" + }, + "9d47ba5b4c8505ad8da42934280b61a0e1e8b971": { + "balance": "0x56bc75e2d63100000" + }, + "9d4d321177256ebd9afbda304135d517c3dc5693": { + "balance": "0x2164b7a04ac8a00000" + }, + "9d4ff989b7bed9ab109d10c8c7e55f02d76734ad": { + "balance": "0x3635c9adc5dea00000" + }, + "9d511543b3d9dc60d47f09d49d01b6c498d82078": { + "balance": "0x26197b9516fc3940000" + }, + "9d6ecfa03af2c6e144b7c4692a86951e902e9e1f": { + "balance": "0xa2a5aa60ad243f0000" + }, + "9d7655e9f3e5ba5d6e87e412aebe9ee0d49247ee": { + "balance": "0x8e09311c1d80fa0000" + }, + "9d7831e834c20b1baa697af1d8e0c621c5afff9a": { + "balance": "0x4b06dbbb40f4a0000" + }, + "9d78a975b7db5e4d8e28845cfbe7e31401be0dd9": { + "balance": "0x48a43c54602f700000" + }, + "9d799e943e306ba2e5b99c8a6858cbb52c0cf735": { + "balance": "0x1043561a8829300000" + }, + "9d7fda7070bf3ee9bbd9a41f55cad4854ae6c22c": { + "balance": "0x255cba3c46fcf120000" + }, + "9d81aea69aed6ad07089d61445348c17f34bfc5b": { + "balance": "0x1043561a8829300000" + }, + "9d911f3682f32fe0792e9fb6ff3cfc47f589fca5": { + "balance": "0xd8d726b7177a800000" + }, + "9d913b5d339c95d87745562563fea98b23c60cc4": { + "balance": "0x941302c7f4d230000" + }, + "9d93fab6e22845f8f45a07496f11de71530debc7": { + "balance": "0x6c4fd1ee246e780000" + }, + "9d99b189bbd9a48fc2e16e8fcda33bb99a317bbb": { + "balance": "0x3d16e10b6d8bb20000" + }, + "9d9c4efe9f433989e23be94049215329fa55b4cb": { + "balance": "0xde3b28903c6b58000" + }, + "9d9e57fde30e5068c03e49848edce343b7028358": { + "balance": "0x5dc892aa1131c80000" + }, + "9da3302240af0511c6fd1857e6ddb7394f77ab6b": { + "balance": "0xa80d24677efef00000" + }, + "9da4ec407077f4b9707b2d9d2ede5ea5282bf1df": { + "balance": "0xd8d726b7177a800000" + }, + "9da609fa3a7e6cf2cc0e70cdabe78dc4e382e11e": { + "balance": "0x410d586a20a4c00000" + }, + "9da61ccd62bf860656e0325d7157e2f160d93bb5": { + "balance": "0x10f0ca956f8799e0000" + }, + "9da6e075989c7419094cc9f6d2e49393bb199688": { + "balance": "0x259bb71d5adf3f00000" + }, + "9da8e22ca10e67fea44e525e4751eeac36a31194": { + "balance": "0xe18398e7601900000" + }, + "9db2e15ca681f4c66048f6f9b7941ed08b1ff506": { + "balance": "0xd8d726b7177a800000" + }, + "9dc10fa38f9fb06810e11f60173ec3d2fd6a751e": { + "balance": "0x6acb3df27e1f880000" + }, + "9dd2196624a1ddf14a9d375e5f07152baf22afa2": { + "balance": "0x41b05e2463a5438000" + }, + "9dd46b1c6d3f05e29e9c6f037eed9a595af4a9aa": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "9ddd355e634ee9927e4b7f6c97e7bf3a2f1e687a": { + "balance": "0x2b5e3af16b1880000" + }, + "9de20ae76aa08263b205d5142461961e2408d266": { + "balance": "0xda933d8d8c6700000" + }, + "9de20bc37e7f48a80ffd7ad84ffbf1a1abe1738c": { + "balance": "0xad78ebc5ac6200000" + }, + "9de7386dde401ce4c67b71b6553f8aa34ea5a17d": { + "balance": "0x340aad21b3b700000" + }, + "9deb39027af877992b89f2ec4a1f822ecdf12693": { + "balance": "0x6c6b935b8bbd400000" + }, + "9defe56a0ff1a1947dba0923f7dd258d8f12fa45": { + "balance": "0x5b12aefafa804000000" + }, + "9df057cd03a4e27e8e032f857985fd7f01adc8d7": { + "balance": "0x6c6b935b8bbd400000" + }, + "9df32a501c0b781c0281022f42a1293ffd7b892a": { + "balance": "0x1e7e4171bf4d3a00000" + }, + "9e01765aff08bc220550aca5ea2e1ce8e5b09923": { + "balance": "0x3635c9adc5dea00000" + }, + "9e20e5fd361eabcf63891f5b87b09268b8eb3793": { + "balance": "0x56bc75e2d63100000" + }, + "9e232c08c14dc1a6ed0b8a3b2868977ba5c17d10": { + "balance": "0x1158e460913d00000" + }, + "9e23c5e4b782b00a5fadf1aead87dacf5b0367a1": { + "balance": "0x1158e460913d00000" + }, + "9e35399071a4a101e9194daa3f09f04a0b5f9870": { + "balance": "0xd8d726b7177a800000" + }, + "9e3eb509278fe0dcd8e0bbe78a194e06b6803943": { + "balance": "0x32f51edbaaa3300000" + }, + "9e427272516b3e67d4fcbf82f59390d04c8e28e5": { + "balance": "0xd8d726b7177a800000" + }, + "9e4cec353ac3e381835e3c0991f8faa5b7d0a8e6": { + "balance": "0x21e18b9e9ab45e48000" + }, + "9e5811b40be1e2a1e1d28c3b0774acde0a09603d": { + "balance": "0xa2a15d09519be00000" + }, + "9e5a311d9f69898a7c6a9d6360680438e67a7b2f": { + "balance": "0x50c5e761a444080000" + }, + "9e7c2050a227bbfd60937e268cea3e68fea8d1fe": { + "balance": "0x56bc75e2d63100000" + }, + "9e7f65a90e8508867bccc914256a1ea574cf07e3": { + "balance": "0x433874f632cc600000" + }, + "9e8144e08e89647811fe6b72d445d6a5f80ad244": { + "balance": "0x21e19e0c9bab2400000" + }, + "9e8f64ddcde9b8b451bafaa235a9bf511a25ac91": { + "balance": "0x90f534608a72880000" + }, + "9e951f6dc5e352afb8d04299d2478a451259bf56": { + "balance": "0x3e7419881a73a0000" + }, + "9e960dcd03d5ba99cb115d17ff4c09248ad4d0be": { + "balance": "0xad78ebc5ac6200000" + }, + "9eaf6a328a4076024efa6b67b48b21eedcc0f0b8": { + "balance": "0x890b0c2e14fb80000" + }, + "9eb1ff71798f28d6e989fa1ea0588e27ba86cb7d": { + "balance": "0x7a1fe160277000000" + }, + "9eb281c32719c40fdb3e216db0f37fbc73a026b7": { + "balance": "0x1158e460913d00000" + }, + "9eb3a7cb5e6726427a3a361cfa8d6164dbd0ba16": { + "balance": "0x2b95bdcc39b6100000" + }, + "9eb7834e171d41e069a77947fca87622f0ba4e48": { + "balance": "0x56bc75e2d63100000" + }, + "9ec03e02e587b7769def538413e97f7e55be71d8": { + "balance": "0x42bf06b78ed3b500000" + }, + "9ecbabb0b22782b3754429e1757aaba04b81189f": { + "balance": "0x2ca7bb061f5e998000" + }, + "9ece1400800936c7c6485fcdd3626017d09afbf6": { + "balance": "0x10ce1d3d8cb3180000" + }, + "9ed4e63f526542d44fddd34d59cd25388ffd6bda": { + "balance": "0xd29b34a46348940000" + }, + "9ed80eda7f55054db9fb5282451688f26bb374c1": { + "balance": "0x1043561a8829300000" + }, + "9edc90f4be210865214ab5b35e5a8dd77415279d": { + "balance": "0xd8d726b7177a800000" + }, + "9edeac4c026b93054dc5b1d6610c6f3960f2ad73": { + "balance": "0x410d586a20a4c00000" + }, + "9ee93f339e6726ec65eea44f8a4bfe10da3d3282": { + "balance": "0x6c6b935b8bbd400000" + }, + "9ee9760cc273d4706aa08375c3e46fa230aff3d5": { + "balance": "0x1e52e336cde22180000" + }, + "9eeb07bd2b7890195e7d46bdf2071b6617514ddb": { + "balance": "0x6c6b935b8bbd400000" + }, + "9eef442d291a447d74c5d253c49ef324eac1d8f0": { + "balance": "0xb96608c8103bf00000" + }, + "9ef1896b007c32a15114fb89d73dbd47f9122b69": { + "balance": "0xd8d726b7177a800000" + }, + "9f017706b830fb9c30efb0a09f506b9157457534": { + "balance": "0x6c6b935b8bbd400000" + }, + "9f10f2a0463b65ae30b070b3df18cf46f51e89bd": { + "balance": "0x678a932062e4180000" + }, + "9f19fac8a32437d80ac6837a0bb7841729f4972e": { + "balance": "0x233df3299f61720000" + }, + "9f1aa8fcfc89a1a5328cbd6344b71f278a2ca4a0": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "9f21302ca5096bea7402b91b0fd506254f999a3d": { + "balance": "0x4397451a003dd80000" + }, + "9f271d285500d73846b18f733e25dd8b4f5d4a8b": { + "balance": "0x2723c346ae18080000" + }, + "9f3497f5ef5fe63095836c004eb9ce02e9013b4b": { + "balance": "0x2256861bf9cf080000" + }, + "9f3a74fd5e7edcc1162993171381cbb632b7cff0": { + "balance": "0x21e19e0c9bab2400000" + }, + "9f46e7c1e9078cae86305ac7060b01467d6685ee": { + "balance": "0x243d4d18229ca20000" + }, + "9f496cb2069563144d0811677ba0e4713a0a4143": { + "balance": "0x3cd2e0bf63a4480000" + }, + "9f4a7195ac7c151ca258cafda0cab083e049c602": { + "balance": "0x53538c32185cee0000" + }, + "9f4ac9c9e7e24cb2444a0454fa5b9ad9d92d3853": { + "balance": "0x2d43f3ebfafb2c0000" + }, + "9f5f44026b576a4adb41e95961561d41039ca391": { + "balance": "0xd8d726b7177a80000" + }, + "9f607b3f12469f446121cebf3475356b71b4328c": { + "balance": "0xd8d726b7177a800000" + }, + "9f61beb46f5e853d0a8521c7446e68e34c7d0973": { + "balance": "0x1e5b8fa8fe2ac00000" + }, + "9f64a8e8dacf4ade30d10f4d59b0a3d5abfdbf74": { + "balance": "0x36369ed7747d260000" + }, + "9f662e95274121f177566e636d23964cf1fd686f": { + "balance": "0x6c6b935b8bbd400000" + }, + "9f6a322a6d469981426ae844865d7ee0bb15c7b3": { + "balance": "0x2b5ee57929fdb8000" + }, + "9f7986924aeb02687cd64189189fb167ded2dd5c": { + "balance": "0x35659ef93f0fc40000" + }, + "9f7a0392f857732e3004a375e6b1068d49d83031": { + "balance": "0x6c6b935b8bbd400000" + }, + "9f8245c3ab7d173164861cd3991b94f1ba40a93a": { + "balance": "0x9b0a791f1211300000" + }, + "9f83a293c324d4106c18faa8888f64d299054ca0": { + "balance": "0xad78ebc5ac6200000" + }, + "9f86a066edb61fcb5856de93b75c8c791864b97b": { + "balance": "0x6c6b935b8bbd400000" + }, + "9f98eb34d46979b0a6de8b05aa533a89b825dcf1": { + "balance": "0x4b06dbbb40f4a0000" + }, + "9f9fe0c95f10fee87af1af207236c8f3614ef02f": { + "balance": "0x14542ba12a337c00000" + }, + "9faea13c733412dc4b490402bfef27a0397a9bc3": { + "balance": "0x10ce1d3d8cb3180000" + }, + "9fbe066de57236dc830725d32a02aef9246c6c5e": { + "balance": "0x6c6b935b8bbd400000" + }, + "9fd1052a60506bd1a9ef003afd9d033c267d8e99": { + "balance": "0x3635c9adc5dea00000" + }, + "9fd64373f2fbcd9c0faca60547cad62e26d9851f": { + "balance": "0x3635c9adc5dea00000" + }, + "9fe501aa57ead79278937cd6308c5cfa7a5629fe": { + "balance": "0x2b5ee57929fdb8000" + }, + "9ffc5fe06f33f5a480b75aa94eb8556d997a16c0": { + "balance": "0x1158e460913d00000" + }, + "9ffcf5ef46d933a519d1d16c6ba3189b27496224": { + "balance": "0x3635c9adc5dea00000" + }, + "9ffedcc36b7cc312ad2a9ede431a514fccb49ba3": { + "balance": "0x244f579f3f5ca40000" + }, + "a006268446643ec5e81e7acb3f17f1c351ee2ed9": { + "balance": "0xd8d726b7177a800000" + }, + "a008019863c1a77c1499eb39bbd7bf2dd7a31cb9": { + "balance": "0x76d41c62494840000" + }, + "a009bf076f1ba3fa57d2a7217218bed5565a7a7a": { + "balance": "0x3635c9adc5dea00000" + }, + "a01e9476df84431825c836e8803a97e22fa5a0cd": { + "balance": "0x14542ba12a337c00000" + }, + "a01f12d70f44aa7b113b285c22dcdb45873454a7": { + "balance": "0xfc936392801c0000" + }, + "a01fd1906a908506dedae1e208128872b56ee792": { + "balance": "0xa2a15d09519be00000" + }, + "a0228240f99e1de9cb32d82c0f2fa9a3d44b0bf3": { + "balance": "0x56bc75e2d631000000" + }, + "a02bde6461686e19ac650c970d0672e76dcb4fc2": { + "balance": "0x1e09296c3378de40000" + }, + "a02c1e34064f0475f7fa831ccb25014c3aa31ca2": { + "balance": "0x340aad21b3b700000" + }, + "a02dc6aa328b880de99eac546823fccf774047fb": { + "balance": "0x6acb3df27e1f880000" + }, + "a02e3f8f5959a7aab7418612129b701ca1b80010": { + "balance": "0x1158e460913d00000" + }, + "a0347f0a98776390165c166d32963bf74dcd0a2f": { + "balance": "0x3635c9adc5dea00000" + }, + "a035a3652478f82dbd6d115faa8ca946ec9e681d": { + "balance": "0x5f4e42dd4afec0000" + }, + "a03a3dc7c533d1744295be955d61af3f52b51af5": { + "balance": "0x22b1c8c1227a00000" + }, + "a0459ef3693aacd1647cd5d8929839204cef53be": { + "balance": "0x3635c9adc5dea00000" + }, + "a04f2ae02add14c12faf65cb259022d0830a8e26": { + "balance": "0x152d02c7e14af6800000" + }, + "a06cd1f396396c0a64464651d7c205efaf387ca3": { + "balance": "0x6c6acc67d7b1d40000" + }, + "a072691c8dd7cd4237ff72a75c1a9506d0ce5b9e": { + "balance": "0x140ec80fa7ee880000" + }, + "a072cebe62a9e9f61cc3fbf88a9efbfe3e9a8d70": { + "balance": "0x15af1d78b58c400000" + }, + "a07682000b1bcf3002f85c80c0fa2949bd1e82fd": { + "balance": "0xd8d726b7177a800000" + }, + "a07aa16d74aee8a9a3288d52db1551d593883297": { + "balance": "0x2086ac351052600000" + }, + "a08d215b5b6aac4861a281ac7e400b78fef04cbf": { + "balance": "0x1158e460913d00000" + }, + "a0951970dfd0832fb83bda12c23545e79041756c": { + "balance": "0x2086ac351052600000" + }, + "a09f4d5eaa65a2f4cb750a49923401dae59090af": { + "balance": "0x796e3ea3f8ab00000" + }, + "a0a0e65204541fca9b2fb282cd95138fae16f809": { + "balance": "0x21e19e0c9bab2400000" + }, + "a0aa5f0201f04d3bbeb898132f7c11679466d901": { + "balance": "0x1fbed5215bb4c0000" + }, + "a0aadbd9509722705f6d2358a5c79f37970f00f6": { + "balance": "0xad78ebc5ac6200000" + }, + "a0b771951ce1deee363ae2b771b73e07c4b5e800": { + "balance": "0x4be4e7267b6ae00000" + }, + "a0de5c601e696635c698b7ae9ca4539fc7b941ec": { + "balance": "0x12c3cbd704c9770000" + }, + "a0e8ba661b48154cf843d4c2a5c0f792d528ee29": { + "balance": "0x15af1d78b58c400000" + }, + "a0fc7e53c5ebd27a2abdac45261f84ab3b51aefb": { + "balance": "0xa313daec9bc0d90000" + }, + "a0ff5b4cf016027e8323497d4428d3e5a83b8795": { + "balance": "0x16598d3c83ec0420000" + }, + "a106465bbd19e1b6bce50d1b1157dc59095a3630": { + "balance": "0x6c6b935b8bbd400000" + }, + "a106e6923edd53ca8ed650968a9108d6ccfd9670": { + "balance": "0x202fe1505afec898000" + }, + "a109e18bb0a39c9ef82fa19597fc5ed8e9eb6d58": { + "balance": "0x58e7926ee858a00000" + }, + "a11a03c4bb26d21eff677d5d555c80b25453ee7a": { + "balance": "0x3cb2759bc410f8000" + }, + "a11effab6cf0f5972cffe4d56596e98968144a8f": { + "balance": "0x5a87e7d7f5f6580000" + }, + "a1204dad5f560728a35c0d8fc79481057bf77386": { + "balance": "0x3635c9adc5dea00000" + }, + "a12623e629df93096704b16084be2cd89d562da4": { + "balance": "0x1ccc9324511e4500000" + }, + "a12a6c2d985daf0e4f5f207ae851aaf729b332cd": { + "balance": "0x152d02c7e14af6800000" + }, + "a1336dfb96b6bcbe4b3edf3205be5723c90fad52": { + "balance": "0x10f0cf064dd59200000" + }, + "a13b9d82a99b3c9bba5ae72ef2199edc7d3bb36c": { + "balance": "0x6c6acc67d7b1d40000" + }, + "a13cfe826d6d1841dcae443be8c387518136b5e8": { + "balance": "0x1da56a4b0835bf800000" + }, + "a1432ed2c6b7777a88e8d46d388e70477f208ca5": { + "balance": "0x1b1a7e413a196c50000" + }, + "a144f6b60f72d64a21e330dadb62d8990ade2b09": { + "balance": "0x3635c9adc5dea00000" + }, + "a15025f595acdbf3110f77c5bf24477e6548f9e8": { + "balance": "0x6c6b935b8bbd400000" + }, + "a158148a2e0f3e92dc2ce38febc20107e3253c96": { + "balance": "0x6c6b935b8bbd400000" + }, + "a16160851d2b9c349b92e46f829abfb210943595": { + "balance": "0x61093d7c2c6d380000" + }, + "a166f911c644ac3213d29e0e1ae010f794d5ad26": { + "balance": "0x6c6b935b8bbd400000" + }, + "a16d9e3d63986159a800b46837f45e8bb980ee0b": { + "balance": "0x6e1175da7ad1200000" + }, + "a17070c2e9c5a940a4ec0e4954c4d7d643be8f49": { + "balance": "0x6c6b17033b361c8000" + }, + "a17c9e4323069518189d5207a0728dcb92306a3f": { + "balance": "0x3635c9adc5dea00000" + }, + "a18360e985f2062e8f8efe02ad2cbc91ad9a5aad": { + "balance": "0xa2a15d09519be00000" + }, + "a1911405cf6e999ed011f0ddcd2a4ff7c28f2526": { + "balance": "0x22b1c8c1227a00000" + }, + "a192698007cc11aa603d221d5feea076bcf7c30d": { + "balance": "0x6c6b935b8bbd400000" + }, + "a192f06ab052d5fd7f94eea8318e827815fe677a": { + "balance": "0x71f8a93d01e540000" + }, + "a1998144968a5c70a6415554cefec2824690c4a5": { + "balance": "0x1158e460913d00000" + }, + "a1a1f0fa6d20b50a794f02ef52085c9d036aa6ca": { + "balance": "0x3635c9adc5dea00000" + }, + "a1ae8d4540d4db6fdde7146f415b431eb55c7983": { + "balance": "0xaadec983fcff40000" + }, + "a1b47c4d0ed6018842e6cfc8630ac3a3142e5e6b": { + "balance": "0x1158e460913d00000" + }, + "a1c4f45a82e1c478d845082eb18875c4ea6539ab": { + "balance": "0x2a5a058fc295ed000000" + }, + "a1dcd0e5b05a977c9623e5ae2f59b9ada2f33e31": { + "balance": "0x56bc75e2d63100000" + }, + "a1e4380a3b1f749673e270229993ee55f35663b4": { + "balance": "0x6c6b935b8bbd400000" + }, + "a1f193a0592f1feb9fdfc90aa813784eb80471c9": { + "balance": "0x4be4e7267b6ae00000" + }, + "a1f2854050f872658ed82e52b0ad7bbc1cb921f6": { + "balance": "0x6d0317e2b326f70000" + }, + "a1f5b840140d5a9acef402ac3cc3886a68cad248": { + "balance": "0x6c6b935b8bbd400000" + }, + "a1f765c44fe45f790677944844be4f2d42165fbd": { + "balance": "0xc7e9cfde768ec70000" + }, + "a1f7dde1d738d8cd679ea1ee965bee224be7d04d": { + "balance": "0x3d184450e5e93c0000" + }, + "a1f8d8bcf90e777f19b3a649759ad95027abdfc3": { + "balance": "0xad78ebc5ac6200000" + }, + "a202547242806f6e70e74058d6e5292defc8c8d4": { + "balance": "0x6c8754c8f30c080000" + }, + "a20d071b1b003063497d7990e1249dabf36c35f7": { + "balance": "0x3635c9adc5dea00000" + }, + "a20d8ff60caae31d02e0b665fa435d76f77c9442": { + "balance": "0x1a8a909dfcef400000" + }, + "a211da03cc0e31ecce5309998718515528a090df": { + "balance": "0xad78ebc5ac6200000" + }, + "a21442ab05340ade68c915f3c3399b9955f3f7eb": { + "balance": "0x2a034919dfbfbc0000" + }, + "a2222259dd9c3e3ded127084f808e92a1887302c": { + "balance": "0x8c8339dafed480000" + }, + "a22ade0ddb5c6ef8d0cd8de94d82b11082cb2e91": { + "balance": "0x374b57f3cef2700000" + }, + "a24c3ab62181e9a15b78c4621e4c7c588127be26": { + "balance": "0x8cde43a83d3310000" + }, + "a257ad594bd88328a7d90fc0a907df95eecae316": { + "balance": "0x1c3786ff3846930000" + }, + "a25b086437fd2192d0a0f64f6ed044f38ef3da32": { + "balance": "0x12290f15180bdc0000" + }, + "a276b058cb98d88beedb67e543506c9a0d9470d8": { + "balance": "0x90aafc76e02fbe0000" + }, + "a282e969cac9f7a0e1c0cd90f5d0c438ac570da3": { + "balance": "0x2207eb89fc27380000" + }, + "a291e9c7990d552dd1ae16cebc3fca342cbaf1d1": { + "balance": "0x43c33c1937564800000" + }, + "a29319e81069e5d60df00f3de5adee3505ecd5fb": { + "balance": "0x6c6b935b8bbd400000" + }, + "a2968fc1c64bac0b7ae0d68ba949874d6db253f4": { + "balance": "0x43c33c1937564800000" + }, + "a29d5bda74e003474872bd5894b88533ff64c2b5": { + "balance": "0x21e19e0c9bab2400000" + }, + "a29d661a6376f66d0b74e2fe9d8f26c0247ec84c": { + "balance": "0xdf3304079c13d20000" + }, + "a2a435de44a01bd0ecb29e44e47644e46a0cdffb": { + "balance": "0x1b1d445a7affe78000" + }, + "a2ace4c993bb1e5383f8ac74e179066e814f0591": { + "balance": "0x56bc75e2d63100000" + }, + "a2b701f9f5cdd09e4ba62baebae3a88257105885": { + "balance": "0x3635c9adc5dea00000" + }, + "a2c5854ff1599f98892c5725d262be1da98aadac": { + "balance": "0x1109ff333010e78000" + }, + "a2c7eaffdc2c9d937345206c909a52dfb14c478f": { + "balance": "0x7c0860e5a80dc0000" + }, + "a2d2aa626b09d6d4e4b13f7ffc5a88bd7ad36742": { + "balance": "0xfb8078507553830000" + }, + "a2d38de1c73906f6a7ca6efeb97cf6f69cc421be": { + "balance": "0x3635c9adc5dea00000" + }, + "a2dc65ee256b59a5bd7929774f904b358df3ada1": { + "balance": "0x483bce28beb09f80000" + }, + "a2e0683a805de6a05edb2ffbb5e96f0570b637c3": { + "balance": "0x1158e460913d00000" + }, + "a2e1b8aa900e9c139b3fa122354f6156d92a18b1": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "a2e2b5941e0c01944bfe1d5fb4e8a34b922ccfb1": { + "balance": "0xad78ebc5ac6200000" + }, + "a2e460a989cb15565f9ecca7d121a18e4eb405b6": { + "balance": "0x6c6b935b8bbd400000" + }, + "a2ecce2c49f72a0995a0bda57aacf1e9f001e22a": { + "balance": "0xd8d726b7177a800000" + }, + "a2f472fe4f22b77db489219ea4023d11582a9329": { + "balance": "0x878678326eac9000000" + }, + "a2f798e077b07d86124e1407df32890dbb4b6379": { + "balance": "0xad78ebc5ac6200000" + }, + "a2f86bc061884e9eef05640edd51a2f7c0596c69": { + "balance": "0x6c6c44fe47ec050000" + }, + "a2fa17c0fb506ce494008b9557841c3f641b8cae": { + "balance": "0x1158e460913d00000" + }, + "a304588f0d850cd8d38f76e9e83c1bf63e333ede": { + "balance": "0x2285601216c8c0000" + }, + "a3058c51737a4e96c55f2ef6bd7bb358167ec2a7": { + "balance": "0x20db3ae4481ad48000" + }, + "a309df54cabce70c95ec3033149cd6678a6fd4cf": { + "balance": "0xc1f12c75101580000" + }, + "a30a45520e5206d9004070e6af3e7bb2e8dd5313": { + "balance": "0x15af1d78b58c400000" + }, + "a30e0acb534c9b3084e8501da090b4eb16a2c0cd": { + "balance": "0x6c6b935b8bbd400000" + }, + "a3203095edb7028e6871ce0a84f548459f83300a": { + "balance": "0xd8d726b7177a800000" + }, + "a321091d3018064279db399d2b2a88a6f440ae24": { + "balance": "0xad78ebc5ac62000000" + }, + "a3232d068d50064903c9ebc563b515acc8b7b097": { + "balance": "0x6c8754c8f30c080000" + }, + "a3241d890a92baf52908dc4aa049726be426ebd3": { + "balance": "0x43c2da661ca2f540000" + }, + "a3294626ec2984c43b43da4d5d8e4669b11d4b59": { + "balance": "0x36a4cf636319c00000" + }, + "a32cf7dde20c3dd5679ff5e325845c70c5962662": { + "balance": "0x1158e460913d00000" + }, + "a339a3d8ca280e27d2415b26d1fc793228b66043": { + "balance": "0x36f28695b78ff00000" + }, + "a33cb450f95bb46e25afb50fe05feee6fb8cc8ea": { + "balance": "0x2a1129d09367200000" + }, + "a33f70da7275ef057104dfa7db64f472e9f5d553": { + "balance": "0x45946b0f9e9d60000" + }, + "a34076f84bd917f20f8342c98ba79e6fb08ecd31": { + "balance": "0xe3aeb5737240a00000" + }, + "a3430e1f647f321ed34739562323c7d623410b56": { + "balance": "0x3634fb9f1489a70000" + }, + "a34f9d568bf7afd94c2a5b8a5ff55c66c4087999": { + "balance": "0x847d503b220eb00000" + }, + "a35606d51220ee7f2146d411582ee4ee4a45596e": { + "balance": "0xd8aabe080bc9400000" + }, + "a356551bb77d4f45a6d7e09f0a089e79cca249cb": { + "balance": "0x126e72a69a50d00000" + }, + "a35c19132cac1935576abfed6c0495fb07881ba0": { + "balance": "0x6c6b935b8bbd400000" + }, + "a365918bfe3f2627b9f3a86775d8756e0fd8a94b": { + "balance": "0x15af1d78b58c400000" + }, + "a36e0d94b95364a82671b608cb2d373245612909": { + "balance": "0x821d221b5291f8000" + }, + "a375b4bc24a24e1f797593cc302b2f331063fa5c": { + "balance": "0xad78ebc5ac6200000" + }, + "a37622ac9bbdc4d82b75015d745b9f8de65a28ec": { + "balance": "0x9dc05cce28c2b80000" + }, + "a379a5070c503d2fac89b8b3afa080fd45ed4bec": { + "balance": "0x42bf06b78ed3b500000" + }, + "a3802d8a659e89a2c47e905430b2a827978950a7": { + "balance": "0x3635c9adc5dea00000" + }, + "a38306cb70baa8e49186bd68aa70a83d242f2907": { + "balance": "0x6c6b935b8bbd400000" + }, + "a38476691d34942eea6b2f76889223047db4617a": { + "balance": "0x6c6b935b8bbd400000" + }, + "a387ce4e961a7847f560075c64e1596b5641d21c": { + "balance": "0x243d4d18229ca20000" + }, + "a387ecde0ee4c8079499fd8e03473bd88ad7522a": { + "balance": "0x6acb3df27e1f880000" + }, + "a3883a24f7f166205f1a6a9949076c26a76e7178": { + "balance": "0x62a992e53a0af00000" + }, + "a38b5bd81a9db9d2b21d5ec7c60552cd02ed561b": { + "balance": "0x14542ba12a337c00000" + }, + "a390ca122b8501ee3e5e07a8ca4b419f7e4dae15": { + "balance": "0x56bc75e2d63100000" + }, + "a3932a31d6ff75fb3b1271ace7caa7d5e1ff1051": { + "balance": "0x43c33c1937564800000" + }, + "a394ad4fd9e6530e6f5c53faecbede81cb172da1": { + "balance": "0x12f939c99edab800000" + }, + "a3979a92760a135adf69d72f75e167755f1cb8c3": { + "balance": "0x56bc75e2d63100000" + }, + "a39bfee4aec9bd75bd22c6b672898ca9a1e95d32": { + "balance": "0x21e19e0c9bab2400000" + }, + "a3a262afd2936819230892fde84f2d5a594ab283": { + "balance": "0x65ea3db75546600000" + }, + "a3a2e319e7d3a1448b5aa2468953160c2dbcba71": { + "balance": "0x6c6b935b8bbd400000" + }, + "a3a57b0716132804d60aac281197ff2b3d237b01": { + "balance": "0x4be4e7267b6ae00000" + }, + "a3a93ef9dbea2636263d06d8492f6a41de907c22": { + "balance": "0x340aad21b3b700000" + }, + "a3ae1879007d801cb5f352716a4dd8ba2721de3d": { + "balance": "0x2a5a058fc295ed000000" + }, + "a3ba0d3a3617b1e31b4e422ce269e873828d5d69": { + "balance": "0x2e141ea081ca080000" + }, + "a3bc979b7080092fa1f92f6e0fb347e28d995045": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "a3bff1dfa9971668360c0d82828432e27bf54e67": { + "balance": "0xad78ebc5ac6200000" + }, + "a3c14ace28b192cbb062145fcbbd5869c67271f6": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "a3c33afc8cb4704e23153de2049d35ae71332472": { + "balance": "0x2b58addb89a2580000" + }, + "a3d0b03cffbb269f796ac29d80bfb07dc7c6ad06": { + "balance": "0x6c6b935b8bbd400000" + }, + "a3d583a7b65b23f60b7905f3e4aa62aac87f4227": { + "balance": "0x38befa126d5a9f8000" + }, + "a3db364a332d884ba93b2617ae4d85a1489bea47": { + "balance": "0x5c283d410394100000" + }, + "a3e051fb744aa3410c3b88f899f5d57f168df12d": { + "balance": "0xa030dcebbd2f4c0000" + }, + "a3e3a6ea509573e21bd0239ece0523a7b7d89b2f": { + "balance": "0x6acb3df27e1f880000" + }, + "a3f4ad14e0bb44e2ce2c14359c75b8e732d37054": { + "balance": "0xad78ebc5ac6200000" + }, + "a3facc50195c0b4933c85897fecc5bbd995c34b8": { + "balance": "0x1158e460913d00000" + }, + "a4035ab1e5180821f0f380f1131b7387c8d981cd": { + "balance": "0x1158e460913d00000" + }, + "a40aa2bbce0c72b4d0dfffcc42715b2b54b01bfa": { + "balance": "0x3635c9adc5dea00000" + }, + "a419a984142363267575566089340eea0ea20819": { + "balance": "0x6c6acc67d7b1d40000" + }, + "a421dbb89b3a07419084ad10c3c15dfe9b32d0c2": { + "balance": "0x43c33c1937564800000" + }, + "a422e4bf0bf74147cc895bed8f16d3cef3426154": { + "balance": "0x12ef3f62ee11368000" + }, + "a4259f8345f7e3a8b72b0fec2cf75e321fda4dc2": { + "balance": "0x678a932062e4180000" + }, + "a42908e7fe53980a9abf4044e957a54b70e99cbe": { + "balance": "0x6c6b935b8bbd400000" + }, + "a429fa88731fdd350e8ecd6ea54296b6484fe695": { + "balance": "0x6ac5c62d9486070000" + }, + "a430995ddb185b9865dbe62539ad90d22e4b73c2": { + "balance": "0x21e19e0c9bab2400000" + }, + "a436c75453ccca4a1f1b62e5c4a30d86dde4be68": { + "balance": "0x6c6b935b8bbd400000" + }, + "a437fe6ec103ca8d158f63b334224eccac5b3ea3": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "a43b6da6cb7aac571dff27f09d39f846f53769b1": { + "balance": "0x14998f32ac78700000" + }, + "a43b81f99356c0af141a03010d77bd042c71c1ee": { + "balance": "0x6c6b935b8bbd400000" + }, + "a43e1947a9242b355561c30a829dfeeca2815af8": { + "balance": "0xd23d99969fd6918000" + }, + "a4489a50ead5d5445a7bee4d2d5536c2a76c41f8": { + "balance": "0xad78ebc5ac6200000" + }, + "a44fe800d96fcad73b7170d0f610cb8c0682d6ce": { + "balance": "0xd8d726b7177a800000" + }, + "a45432a6f2ac9d56577b938a37fabac8cc7c461c": { + "balance": "0x3635c9adc5dea00000" + }, + "a466d770d898d8c9d405e4a0e551efafcde53cf9": { + "balance": "0x1ab2cf7c9f87e20000" + }, + "a4670731175893bbcff4fa85ce97d94fc51c4ba8": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "a46b4387fb4dcce011e76e4d73547d4481e09be5": { + "balance": "0x487a9a304539440000" + }, + "a46cd237b63eea438c8e3b6585f679e4860832ac": { + "balance": "0x3635c9adc5dea00000" + }, + "a47779d8bc1c7bce0f011ccb39ef68b854f8de8f": { + "balance": "0x6c6b935b8bbd400000" + }, + "a4826b6c3882fad0ed5c8fbb25cc40cc4f33759f": { + "balance": "0x701b43e34433d00000" + }, + "a4875928458ec2005dbb578c5cd33580f0cf1452": { + "balance": "0x3635c9adc5dea00000" + }, + "a49f523aa51364cbc7d995163d34eb590ded2f08": { + "balance": "0x9027421b2a9fbc0000" + }, + "a4a49f0bc8688cc9e6dc04e1e08d521026e65574": { + "balance": "0xad78ebc5ac6200000" + }, + "a4a7d306f510cd58359428c0d2f7c3609d5674d7": { + "balance": "0xb58cb61c3ccf340000" + }, + "a4a83a0738799b971bf2de708c2ebf911ca79eb2": { + "balance": "0x2086ac351052600000" + }, + "a4b09de6e713dc69546e76ef0acf40b94f0241e6": { + "balance": "0x117dc0627ec8700000" + }, + "a4d2b429f1ad5349e31704969edc5f25ee8aca10": { + "balance": "0x21e19e0c9bab2400000" + }, + "a4d6c82eddae5947fbe9cdfbd548ae33d91a7191": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "a4da34450d22ec0ffcede0004b02f7872ee0b73a": { + "balance": "0x50f616673f0830000" + }, + "a4dd59ab5e517d398e49fa537f899fed4c15e95d": { + "balance": "0x43c33c1937564800000" + }, + "a4e623451e7e94e7e89ba5ed95c8a83a62ffc4ea": { + "balance": "0x1158e460913d00000" + }, + "a4ed11b072d89fb136759fc69b428c48aa5d4ced": { + "balance": "0xe3f1527a03ca80000" + }, + "a4fb14409a67b45688a8593e5cc2cf596ced6f11": { + "balance": "0x61093d7c2c6d380000" + }, + "a514d00edd7108a6be839a638db2415418174196": { + "balance": "0x65a4da25d3016c00000" + }, + "a522de7eb6ae1250522a513133a93bd42849475c": { + "balance": "0x43c33c1937564800000" + }, + "a524a8cccc49518d170a328270a2f88133fbaf5d": { + "balance": "0xff7022dac108a0000" + }, + "a539b4a401b584dfe0f344b1b422c65543167e2e": { + "balance": "0xad78ebc5ac6200000" + }, + "a53ead54f7850af21438cbe07af686279a315b86": { + "balance": "0x21e19e0c9bab2400000" + }, + "a543a066fb32a8668aa0736a0c9cd40d78098727": { + "balance": "0x3635c9adc5dea00000" + }, + "a567770b6ae320bdde50f904d663e746a61dace6": { + "balance": "0x6c6b935b8bbd400000" + }, + "a568db4d57e4d67462d733c69a9e0fe26e218327": { + "balance": "0x3b6bff9266c0ae0000" + }, + "a5698035391e67a49013c0002079593114feb353": { + "balance": "0xd02ab486cedc00000" + }, + "a570223ae3caa851418a9843a1ac55db4824f4fd": { + "balance": "0xad78ebc5ac6200000" + }, + "a57360f002e0d64d2d74457d8ca4857ee00bcddf": { + "balance": "0x1233e232f618aa0000" + }, + "a575f2891dcfcda83c5cf01474af11ee01b72dc2": { + "balance": "0x56cd55fc64dfe0000" + }, + "a5783bf33432ff82ac498985d7d460ae67ec3673": { + "balance": "0x62a992e53a0af00000" + }, + "a5874d754635a762b381a5c4c792483af8f23d1d": { + "balance": "0x2b5e3af16b1880000" + }, + "a5a4227f6cf98825c0d5baff5315752ccc1a1391": { + "balance": "0x21e19e0c9bab2400000" + }, + "a5ab4bd3588f46cb272e56e93deed386ba8b753d": { + "balance": "0x4842f04105872c8000" + }, + "a5bad86509fbe0e0e3c0e93f6d381f1af6e9d481": { + "balance": "0x14542ba12a337c00000" + }, + "a5c336083b04f9471b8c6ed73679b74d66c363ec": { + "balance": "0xa3650a4c9d20e20000" + }, + "a5cd123992194b34c4781314303b03c54948f4b9": { + "balance": "0x6cfcc3d91da5630000" + }, + "a5d5b8b62d002def92413710d13b6ff8d4fc7dd3": { + "balance": "0x15af1d78b58c400000" + }, + "a5d96e697d46358d119af7819dc7087f6ae47fef": { + "balance": "0x317bee8af3315a78000" + }, + "a5de5e434fdcdd688f1c31b6fb512cb196724701": { + "balance": "0x2b5e3af16b18800000" + }, + "a5e0fc3c3affed3db6710947d1d6fb017f3e276d": { + "balance": "0x6c6b935b8bbd400000" + }, + "a5e93b49ea7c509de7c44d6cfeddef5910deaaf2": { + "balance": "0x6c6b935b8bbd400000" + }, + "a5e9cd4b74255d22b7d9b27ae8dd43ed6ed0252b": { + "balance": "0x298db2f54411d98000" + }, + "a5f0077b351f6c505cd515dfa6d2fa7f5c4cd287": { + "balance": "0x878678326eac9000000" + }, + "a5f075fd401335577b6683c281e6d101432dc6e0": { + "balance": "0x914878a8c05ee00000" + }, + "a5fe2ce97f0e8c3856be0de5f4dcb2ce5d389a16": { + "balance": "0x13db0b8b6863e0000" + }, + "a5ff62222d80c013cec1a0e8850ed4d354dac16d": { + "balance": "0xb41075c168b180000" + }, + "a609c26dd350c235e44b2b9c1dddccd0a9d9f837": { + "balance": "0x3635c9adc5dea00000" + }, + "a60c1209754f5d87b181da4f0817a81859ef9fd8": { + "balance": "0x2b5e3af16b1880000" + }, + "a6101c961e8e1c15798ffcd0e3201d7786ec373a": { + "balance": "0x14542ba12a337c00000" + }, + "a613456996408af1c2e93e177788ab55895e2b32": { + "balance": "0x15919ff477c88b80000" + }, + "a61887818f914a20e31077290b83715a6b2d6ef9": { + "balance": "0x65ea3db75546600000" + }, + "a61a54df784a44d71b771b87317509211381f200": { + "balance": "0x3635c9adc5dea00000" + }, + "a61cdbadf04b1e54c883de6005fcdf16beb8eb2f": { + "balance": "0x6c6b935b8bbd400000" + }, + "a639acd96b31ba53b0d08763229e1f06fd105e9d": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "a642501004c90ea9c9ed1998ba140a4cd62c6f5f": { + "balance": "0xd94fb8b10f8b18000" + }, + "a644ed922cc237a3e5c4979a995477f36e50bc62": { + "balance": "0x1fa73d845d7e960000" + }, + "a646a95c6d6f59f104c6541d7760757ab392b08c": { + "balance": "0xe3aeb5737240a00000" + }, + "a6484cc684c4c91db53eb68a4da45a6a6bda3067": { + "balance": "0x14542ba12a337c00000" + }, + "a64e5ffb704c2c9139d77ef61d8cdfa31d7a88e9": { + "balance": "0x7c0860e5a80dc0000" + }, + "a65426cff378ed23253513b19f496de45fa7e18f": { + "balance": "0x18650127cc3dc800000" + }, + "a66a4963b27f1ee1932b172be5964e0d3ae54b51": { + "balance": "0x960db77681e940000" + }, + "a67f38819565423aa85f3e3ab61bc763cbab89dd": { + "balance": "0x7377b022c6be080000" + }, + "a68c313445c22d919ee46cc2d0cdff043a755825": { + "balance": "0x41374fd21b0d88000" + }, + "a68e0c30cba3bc5a883e540320f999c7cd558e5c": { + "balance": "0x6192333762a58c8000" + }, + "a690f1a4b20ab7ba34628620de9ca040c43c1963": { + "balance": "0xd8d726b7177a800000" + }, + "a69d7cd17d4842fe03f62a90b2fbf8f6af7bb380": { + "balance": "0x56bc75e2d63100000" + }, + "a6a08252c8595177cc2e60fc27593e2379c81fb1": { + "balance": "0x11651ac3e7a758000" + }, + "a6a0de421ae54f6d17281308f5646d2f39f7775d": { + "balance": "0x6c6b935b8bbd400000" + }, + "a6b2d573297360102c07a18fc21df2e7499ff4eb": { + "balance": "0xd96fce90cfabcc0000" + }, + "a6c910ce4d494a919ccdaaa1fc3b82aa74ba06cf": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "a6e3baa38e104a1e27a4d82869afb1c0ae6eff8d": { + "balance": "0x11140eead8b710000" + }, + "a6eebbe464d39187bf80ca9c13d72027ec5ba8be": { + "balance": "0xa2a15d09519be00000" + }, + "a6f62b8a3d7f11220701ab9ffffcb327959a2785": { + "balance": "0x1b6e291f18dba80000" + }, + "a6f93307f8bce03195fece872043e8a03f7bd11a": { + "balance": "0x9c734bad5111580000" + }, + "a701df79f594901afe1444485e6b20c3bda2b9b3": { + "balance": "0x3635c9adc5dea00000" + }, + "a7024cfd742c1ec13c01fea18d3042e65f1d5dee": { + "balance": "0x263119a28abd0b08000" + }, + "a718aaad59bf395cba2b23e09b02fe0c89816247": { + "balance": "0x36303c97e468780000" + }, + "a7247c53d059eb7c9310f628d7fc6c6a0a773f08": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "a7253763cf4a75df92ca1e766dc4ee8a2745147b": { + "balance": "0x2463770e90a8f500000" + }, + "a72ee666c4b35e82a506808b443cebd5c632c7dd": { + "balance": "0x2b5e3af16b18800000" + }, + "a74444f90fbb54e56f3ac9b6cfccaa4819e4614a": { + "balance": "0x1158e460913d00000" + }, + "a747439ad0d393b5a03861d77296326de8bb9db9": { + "balance": "0x3635c9adc5dea00000" + }, + "a7607b42573bb6f6b4d4f23c7e2a26b3a0f6b6f0": { + "balance": "0x57473d05dabae80000" + }, + "a76929890a7b47fb859196016c6fdd8289ceb755": { + "balance": "0x10f0cf064dd59200000" + }, + "a76b743f981b693072a131b22ba510965c2fefd7": { + "balance": "0xfc936392801c0000" + }, + "a76d3f156251b72c0ccf4b47a3393cbd6f49a9c5": { + "balance": "0x487a9a304539440000" + }, + "a77428bcb2a0db76fc8ef1e20e461a0a32c5ac15": { + "balance": "0x15be6174e1912e0000" + }, + "a7758cecb60e8f614cce96137ef72b4fbd07774a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "a7775e4af6a23afa201fb78b915e51a515b7a728": { + "balance": "0x68155a43676e00000" + }, + "a77f3ee19e9388bbbb2215c62397b96560132360": { + "balance": "0xad78ebc5ac6200000" + }, + "a7859fc07f756ea7dcebbccd42f05817582d973f": { + "balance": "0x21e19e0c9bab2400000" + }, + "a7966c489f4c748a7ae980aa27a574251767caf9": { + "balance": "0xa2a15d09519be00000" + }, + "a7a3bb6139b0ada00c1f7f1f9f56d994ba4d1fa8": { + "balance": "0x6c6b935b8bbd400000" + }, + "a7a3f153cdc38821c20c5d8c8241b294a3f82b24": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "a7a517d7ad35820b09d497fa7e5540cde9495853": { + "balance": "0x6c6b935b8bbd400000" + }, + "a7c9d388ebd873e66b1713448397d0f37f8bd3a8": { + "balance": "0x10f0cf064dd59200000" + }, + "a7dcbba9b9bf6762c145416c506a71e3b497209c": { + "balance": "0x6c6acc67d7b1d40000" + }, + "a7e74f0bdb278ff0a805a648618ec52b166ff1be": { + "balance": "0x56bc75e2d63100000" + }, + "a7e83772bc200f9006aa2a260dbaa8483dc52b30": { + "balance": "0xb42d5366637e50000" + }, + "a7ef35ce87eda6c28df248785815053ec97a5045": { + "balance": "0x10f0ce949e00f930000" + }, + "a7f9220c8047826bd5d5183f4e676a6d77bfed36": { + "balance": "0x85068976be81c0000" + }, + "a807104f2703d679f8deafc442befe849e42950b": { + "balance": "0x6c6b935b8bbd400000" + }, + "a80cb1738bac08d4f9c08b4deff515545fa8584f": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "a819d2ece122e028c8e8a04a064d02b9029b08b9": { + "balance": "0x3635c9adc5dea00000" + }, + "a825fd5abb7926a67cf36ba246a24bd27be6f6ed": { + "balance": "0xf43fc2c04ee00000" + }, + "a8285539869d88f8a961533755717d7eb65576ae": { + "balance": "0xad78ebc5ac6200000" + }, + "a83382b6e15267974a8550b98f7176c1a353f9be": { + "balance": "0xbffdaf2fc1b1a40000" + }, + "a8446c4781a737ac4328b1e15b8a0b3fbb0fd668": { + "balance": "0x48794d1f246192a0000" + }, + "a8455b411765d6901e311e726403091e42c56683": { + "balance": "0xb73aec3bfe14500000" + }, + "a86613e6c4a4c9c55f5c10bcda32175dcbb4af60": { + "balance": "0x243d6c2e36be6ae0000" + }, + "a86db07d9f812f4796622d40e03d135874a88a74": { + "balance": "0x1158e460913d00000" + }, + "a87f7abd6fa31194289678efb63cf584ee5e2a61": { + "balance": "0xd8d726b7177a800000" + }, + "a880e2a8bf88a1a82648b4013c49c4594c433cc8": { + "balance": "0x1004e2e45fb7ee00000" + }, + "a88577a073fbaf33c4cd202e00ea70ef711b4006": { + "balance": "0x6c6b935b8bbd400000" + }, + "a8914c95b560ec13f140577338c32bcbb77d3a7a": { + "balance": "0x9c2007651b2500000" + }, + "a89ac93b23370472daac337e9afdf642543f3e57": { + "balance": "0x21e19e0c9bab2400000" + }, + "a89df34859edd7c820db887740d8ff9e15157c7b": { + "balance": "0x6c6b935b8bbd400000" + }, + "a8a43c009100616cb4ae4e033f1fc5d7e0b6f152": { + "balance": "0xd588d078b43f4d8000" + }, + "a8a708e84f82db86a35502193b4c6ee9a76ebe8f": { + "balance": "0x3708baed3d68900000" + }, + "a8a7b68adab4e3eadff19ffa58e34a3fcec0d96a": { + "balance": "0x14542ba12a337c00000" + }, + "a8a8dbdd1a85d1beee2569e91ccc4d09ae7f6ea1": { + "balance": "0x13a6b2b564871a00000" + }, + "a8aca748f9d312ec747f8b6578142694c7e9f399": { + "balance": "0x6c6b935b8bbd400000" + }, + "a8b65ba3171a3f77a6350b9daf1f8d55b4d201eb": { + "balance": "0x2862f3b0d222040000" + }, + "a8beb91c2b99c8964aa95b6b4a184b1269fc3483": { + "balance": "0x15af1d78b58c400000" + }, + "a8c0b02faf02cb5519dda884de7bbc8c88a2da81": { + "balance": "0xe7c2518505060000" + }, + "a8c1d6aa41fe3d65f67bd01de2a866ed1ed9ae52": { + "balance": "0x1a055690d9db80000" + }, + "a8cafac32280d021020bf6f2a9782883d7aabe12": { + "balance": "0x56bc75e2d63100000" + }, + "a8db0b9b201453333c757f6ad9bcb555c02da93b": { + "balance": "0x7742b7830f341d0000" + }, + "a8e42a4e33d7526cca19d9a36dcd6e8040d0ea73": { + "balance": "0x3a8c02c5ea2de00000" + }, + "a8e7201ff619faffc332e6ad37ed41e301bf014a": { + "balance": "0x2086ac351052600000" + }, + "a8ee1df5d44b128469e913569ef6ac81eeda4fc8": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "a8ef9ad274436042903e413c3b0c62f5f52ed584": { + "balance": "0x21e19e0c9bab2400000" + }, + "a8f37f0ab3a1d448a9e3ce40965f97a646083a34": { + "balance": "0x11e0e4f8a50bd40000" + }, + "a8f89dd5cc6e64d7b1eeace00702022cd7d2f03d": { + "balance": "0x25f273933db5700000" + }, + "a90476e2efdfee4f387b0f32a50678b0efb573b5": { + "balance": "0x21e19e0c9bab2400000" + }, + "a9145046fa3628cf5fd4c613927be531e6db1fdd": { + "balance": "0x6124fee993bc00000" + }, + "a914cdb571bfd93d64da66a4e108ea134e50d000": { + "balance": "0x4d8738994713798000" + }, + "a91a5a7b341f99c535144e20be9c6b3bb4c28e4d": { + "balance": "0x126753aa224a70b0000" + }, + "a9252551a624ae513719dabe5207fbefb2fd7749": { + "balance": "0x22b1c8c1227a00000" + }, + "a927d48bb6cb814bc609cbcaa9151f5d459a27e1": { + "balance": "0xeb935090064180000" + }, + "a929c8bd71db0c308dac06080a1747f21b1465aa": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "a94bbb8214cf8da0c2f668a2ac73e86248528d4b": { + "balance": "0x340aad21b3b7000000" + }, + "a951b244ff50cfae591d5e1a148df6a938ef2a1a": { + "balance": "0x5e001584dfcf580000" + }, + "a960b1cadd3b5c1a8e6cb3abcaf52ee7c3d9fa88": { + "balance": "0x528bc3545e52680000" + }, + "a961171f5342b173dd70e7bfe5b5ca238b13bcdd": { + "balance": "0xb82794a9244f0c8000" + }, + "a975b077fcb4cc8efcbf838459b6fa243a4159d6": { + "balance": "0x22b1c8c1227a00000" + }, + "a97beb3a48c45f1528284cb6a95f7de453358ec6": { + "balance": "0x690836c0af5f5600000" + }, + "a97e072144499fe5ebbd354acc7e7efb58985d08": { + "balance": "0x90f534608a72880000" + }, + "a986762f7a4f294f2e0b173279ad2c81a2223458": { + "balance": "0x1158e460913d00000" + }, + "a98f109835f5eacd0543647c34a6b269e3802fac": { + "balance": "0x15af1d78b58c400000" + }, + "a997dfc7986a27050848fa1c64d7a7d6e07acca2": { + "balance": "0x7c0860e5a80dc0000" + }, + "a99991cebd98d9c838c25f7a7416d9e244ca250d": { + "balance": "0x3635c9adc5dea00000" + }, + "a9a1cdc33bfd376f1c0d76fb6c84b6b4ac274d68": { + "balance": "0x10f0cf064dd59200000" + }, + "a9a8eca11a23d64689a2aa3e417dbb3d336bb59a": { + "balance": "0xe3453cd3b67ba8000" + }, + "a9acf600081bb55bb6bfbab1815ffc4e17e85a95": { + "balance": "0xad78ebc5ac6200000" + }, + "a9ad1926bc66bdb331588ea8193788534d982c98": { + "balance": "0x65a4da25d3016c00000" + }, + "a9af21acbe482f8131896a228036ba51b19453c3": { + "balance": "0x2b5e021980cc18000" + }, + "a9b2d2e0494eab18e07d37bbb856d80e80f84cd3": { + "balance": "0x21e19e0c9bab2400000" + }, + "a9ba6f413b82fcddf3affbbdd09287dcf50415ca": { + "balance": "0xd8d726b7177a800000" + }, + "a9be88ad1e518b0bbb024ab1d8f0e73f790e0c76": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "a9bfc410dddb20711e45c07387eab30a054e19ac": { + "balance": "0x3e99601edf4e530000" + }, + "a9d4a2bcbe5b9e0869d70f0fe2e1d6aacd45edc5": { + "balance": "0xac6e77ab663a80000" + }, + "a9d64b4f3bb7850722b58b478ba691375e224e42": { + "balance": "0x14542ba12a337c00000" + }, + "a9d6f871ca781a759a20ac3adb972cf12829a208": { + "balance": "0x3224f42723d4540000" + }, + "a9dc0424c6969d798358b393b1933a1f51bee00a": { + "balance": "0x43c33c1937564800000" + }, + "a9e194661aac704ee9dea043974e9692ded84a5d": { + "balance": "0x1a26a51422a0700000" + }, + "a9e28337e6357193d9e2cb236b01be44b81427df": { + "balance": "0x77432217e683600000" + }, + "a9e6e25e656b762558619f147a21985b8874edfe": { + "balance": "0x6c6b935b8bbd400000" + }, + "a9e9dbce7a2cb03694799897bed7c54d155fdaa8": { + "balance": "0xab5ae8fc99d658000" + }, + "a9ed377b7d6ec25971c1a597a3b0f3bead57c98f": { + "balance": "0x15af1d78b58c400000" + }, + "aa0200f1d17e9c54da0647bb96395d57a78538d8": { + "balance": "0x393ef1a5127c800000" + }, + "aa0ca3737337178a0caac3099c584b056c56301c": { + "balance": "0x2fb474098f67c00000" + }, + "aa136b47962bb8b4fb540db4ccf5fdd042ffb8cf": { + "balance": "0x1b1b6bd7af64c70000" + }, + "aa14422d6f0ae5a758194ed15780c838d67f1ee1": { + "balance": "0x60932056c449de80000" + }, + "aa16269aac9c0d803068d82fc79151dadd334b66": { + "balance": "0xd8d726b7177a800000" + }, + "aa167026d39ab7a85635944ed9edb2bfeba11850": { + "balance": "0x1c1d5e21b4fcf680000" + }, + "aa1b3768c16d821f580e76c8e4c8e86d7dc78853": { + "balance": "0x15af1d78b58c400000" + }, + "aa1df92e51dff70b1973e0e924c66287b494a178": { + "balance": "0x1cf84a30a0a0c00000" + }, + "aa2c670096d3f939305325427eb955a8a60db3c5": { + "balance": "0x6c95590699232d0000" + }, + "aa3135cb54f102cbefe09e96103a1a796718ff54": { + "balance": "0x32222d9c331940000" + }, + "aa321fdbd449180db8ddd34f0fe906ec18ee0914": { + "balance": "0x252248deb6e6940000" + }, + "aa3925dc220bb4ae2177b2883078b6dc346ca1b2": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "aa3f29601a1331745e05c42830a15e71938a6237": { + "balance": "0x5c283d410394100000" + }, + "aa47a4ffc979363232c99b99fada0f2734b0aeee": { + "balance": "0x1b8489df4dbff940000" + }, + "aa493d3f4fb866491cf8f800efb7e2324ed7cfe5": { + "balance": "0x5c283d410394100000" + }, + "aa56a65dc4abb72f11bae32b6fbb07444791d5c9": { + "balance": "0x2894e975bf496c0000" + }, + "aa5afcfd8309c2df9d15be5e6a504e7d706624c5": { + "balance": "0x13cf422e305a1378000" + }, + "aa8eb0823b07b0e6d20aadda0e95cf3835be192e": { + "balance": "0x1bc16d674ec800000" + }, + "aa91237e740d25a92f7fa146faa18ce56dc6e1f3": { + "balance": "0x3224f42723d4540000" + }, + "aa960e10c52391c54e15387cc67af827b5316dcc": { + "balance": "0x6c6b935b8bbd400000" + }, + "aa9bd4589535db27fa2bc903ca17d679dd654806": { + "balance": "0x6c6b935b8bbd400000" + }, + "aaa8defe11e3613f11067fb983625a08995a8dfc": { + "balance": "0xad78ebc5ac6200000" + }, + "aaaae68b321402c8ebc13468f341c63c0cf03fce": { + "balance": "0x52663ccab1e1c00000" + }, + "aaad1baade5af04e2b17439e935987bf8c2bb4b9": { + "balance": "0x6c6b935b8bbd400000" + }, + "aab00abf5828d7ebf26b47ceaccdb8ba03325166": { + "balance": "0x21e19e0c9bab2400000" + }, + "aabdb35c1514984a039213793f3345a168e81ff1": { + "balance": "0x10cac896d239000000" + }, + "aaca60d9d700e78596bbbbb1f1e2f70f4627f9d8": { + "balance": "0x3635bb77cb4b860000" + }, + "aaced8a9563b1bc311dbdffc1ae7f57519c4440c": { + "balance": "0x6c6b935b8bbd400000" + }, + "aad2b7f8106695078e6c138ec81a7486aaca1eb2": { + "balance": "0xad78ebc5ac6200000" + }, + "aae61e43cb0d0c96b30699f77e00d711d0a3979b": { + "balance": "0x3635c9adc5dea00000" + }, + "aae732eda65988c3a00c7f472f351c463b1c968e": { + "balance": "0x6c6b935b8bbd400000" + }, + "aaf023fef290a49bb78bb7abc95d669c50d528b0": { + "balance": "0xad78ebc5ac6200000" + }, + "aaf5b207b88b0de4ac40d747cee06e172df6e745": { + "balance": "0x6a7b71d7f51d0900000" + }, + "aaf9ee4b886c6d1e95496fd274235bf4ecfcb07d": { + "balance": "0x4be4e7267b6ae00000" + }, + "aafb7b013aa1f8541c7e327bf650adbd194c208f": { + "balance": "0x499e092d01f4780000" + }, + "ab098633eeee0ccefdf632f9575456f6dd80fc86": { + "balance": "0x2a5a058fc295ed000000" + }, + "ab0ced762e1661fae1a92afb1408889413794825": { + "balance": "0x678a932062e4180000" + }, + "ab14d221e33d544629198cd096ed63dfa28d9f47": { + "balance": "0x14542ba12a337c00000" + }, + "ab209fdca979d0a647010af9a8b52fc7d20d8cd1": { + "balance": "0x1eee2532c7c2d040000" + }, + "ab27ba78c8e5e3daef31ad05aef0ff0325721e08": { + "balance": "0x195ece006e02d00000" + }, + "ab2871e507c7be3965498e8fb462025a1a1c4264": { + "balance": "0x2a034919dfbfbc0000" + }, + "ab3861226ffec1289187fb84a08ec3ed043264e8": { + "balance": "0x3635c9adc5dea00000" + }, + "ab3d86bc82927e0cd421d146e07f919327cdf6f9": { + "balance": "0x678a932062e4180000" + }, + "ab3e62e77a8b225e411592b1af300752fe412463": { + "balance": "0x215f835bc769da80000" + }, + "ab3e78294ba886a0cfd5d3487fb3a3078d338d6e": { + "balance": "0x6acb3df27e1f880000" + }, + "ab4004c0403f7eabb0ea586f212156c4203d67f1": { + "balance": "0x6c6acc67d7b1d40000" + }, + "ab416fe30d58afe5d9454c7fce7f830bcc750356": { + "balance": "0x6353701c605db8000" + }, + "ab4572fbb1d72b575d69ec6ad17333873e8552fc": { + "balance": "0x6c6ac54cda68470000" + }, + "ab5a79016176320973e8cd38f6375530022531c0": { + "balance": "0x3635c9adc5dea00000" + }, + "ab5dfc1ea21adc42cf8c3f6e361e243fd0da61e5": { + "balance": "0x1043561a8829300000" + }, + "ab6b65eab8dfc917ec0251b9db0ecfa0fa032849": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ab7091932e4bc39dbb552380ca934fd7166d1e6e": { + "balance": "0xb50fcfafebecb00000" + }, + "ab7416ff32254951cbbc624ec7fb45fc7ecaa872": { + "balance": "0x126e72a69a50d00000" + }, + "ab7c42c5e52d641a07ad75099c62928b7f86622f": { + "balance": "0x12361aa21d14ba0000" + }, + "ab7d54c7c6570efca5b4b8ce70f52a5773e5d53b": { + "balance": "0xf283abe9d9f380000" + }, + "ab7e0b83ed9a424c6d1e6a6f87a4dbf06409c7d6": { + "balance": "0x821ab0d44149800000" + }, + "ab84a0f147ad265400002b85029a41fc9ce57f85": { + "balance": "0x3635c9adc5dea00000" + }, + "ab93b26ece0a0aa21365afed1fa9aea31cd54468": { + "balance": "0x572b7b98736c200000" + }, + "ab948a4ae3795cbca13126e19253bdc21d3a8514": { + "balance": "0xad78ebc5ac6200000" + }, + "ab9ad36e5c74ce2e96399f57839431d0e79f96ab": { + "balance": "0x8e3f50b173c100000" + }, + "abb2e6a72a40ba6ed908cdbcec3c5612583132fe": { + "balance": "0x4f2591f896a6500000" + }, + "abc068b4979b0ea64a62d3b7aa897d73810dc533": { + "balance": "0x6acb3df27e1f880000" + }, + "abc45f84db7382dde54c5f7d8938c42f4f3a3bc4": { + "balance": "0xad78ebc5ac6200000" + }, + "abc4caeb474d4627cb6eb456ecba0ecd08ed8ae1": { + "balance": "0xd5967be4fc3f100000" + }, + "abc74706964960dfe0dca3dca79e9216056f1cf4": { + "balance": "0x878678326eac9000000" + }, + "abc9a99e8a2148a55a6d82bd51b98eb5391fdbaf": { + "balance": "0x14542ba12a337c00000" + }, + "abcdbc8f1dd13af578d4a4774a62182bedf9f9be": { + "balance": "0x1fcc27bc459d20000" + }, + "abd154903513b8da4f019f68284b0656a1d0169b": { + "balance": "0x3635c9adc5dea00000" + }, + "abd21eff954fc6a7de26912a7cbb303a6607804e": { + "balance": "0x523c9aa696eb940000" + }, + "abd4d6c1666358c0406fdf3af248f78ece830104": { + "balance": "0x727de34a24f9000000" + }, + "abd9605b3e91acfd777830d16463478ae0fc7720": { + "balance": "0x73f75d1a085ba0000" + }, + "abdc9f1bcf4d19ee96591030e772c334302f7d83": { + "balance": "0x87e5e11a81cb5f80000" + }, + "abde147b2af789eaa586547e66c4fa2664d328a4": { + "balance": "0xd6b6081f34c128000" + }, + "abe07ced6ac5ddf991eff6c3da226a741bd243fe": { + "balance": "0x21e19e0c9bab2400000" + }, + "abf12fa19e82f76c718f01bdca0003674523ef30": { + "balance": "0x6c6b935b8bbd400000" + }, + "abf728cf9312f22128024e7046c251f5dc5901ed": { + "balance": "0x641e8a13563d8f80000" + }, + "abf8ffe0708a99b528cc1ed4e9ce4b0d0630be8c": { + "balance": "0x7ab5c2aeeee6380000" + }, + "abfcf5f25091ce57875fc674dcf104e2a73dd2f2": { + "balance": "0x11164759ffb320000" + }, + "abfe936425dcc7b74b955082bbaaf2a11d78bc05": { + "balance": "0x4be4e7267b6ae00000" + }, + "ac024f594f9558f04943618eb0e6b2ee501dc272": { + "balance": "0x6c6b935b8bbd400000" + }, + "ac122a03cd058c122e5fe17b872f4877f9df9572": { + "balance": "0x6ac5c62d9486070000" + }, + "ac142eda1157b9a9a64390df7e6ae694fac98905": { + "balance": "0xad78ebc5ac6200000" + }, + "ac1dfc984b71a19929a81d81f04a7cbb14073703": { + "balance": "0x2086ac351052600000" + }, + "ac21c1e5a3d7e0b50681679dd6c792dbca87decb": { + "balance": "0x152d02c7e14af6800000" + }, + "ac2889b5966f0c7f9edb42895cb69d1c04f923a2": { + "balance": "0x10f0cf064dd59200000" + }, + "ac28b5edea05b76f8c5f97084541277c96696a4c": { + "balance": "0x3635c9adc5dea00000" + }, + "ac2c8e09d06493a63858437bd20be01962450365": { + "balance": "0x678a932062e4180000" + }, + "ac2e766dac3f648f637ac6713fddb068e4a4f04d": { + "balance": "0xaadec983fcff40000" + }, + "ac3900298dd14d7cc96d4abb428da1bae213ffed": { + "balance": "0x53ca12974851c010000" + }, + "ac3da526cfce88297302f34c49ca520dc271f9b2": { + "balance": "0x2b5e3af16b18800000" + }, + "ac4460a76e6db2b9fcd152d9c7718d9ac6ed8c6f": { + "balance": "0xad78ebc5ac6200000" + }, + "ac4acfc36ed6094a27e118ecc911cd473e8fb91f": { + "balance": "0x61913e14403c0c0000" + }, + "ac4cc256ae74d624ace80db078b2207f57198f6b": { + "balance": "0x6c7974123f64a40000" + }, + "ac4ee9d502e7d2d2e99e59d8ca7d5f00c94b4dd6": { + "balance": "0x3635c9adc5dea00000" + }, + "ac52b77e15664814f39e4f271be641308d91d6cc": { + "balance": "0xbed1d0263d9f00000" + }, + "ac5999a89d2dd286d5a80c6dee7e86aad40f9e12": { + "balance": "0xd255d112e103a00000" + }, + "ac5f627231480d0d95302e6d89fc32cb1d4fe7e3": { + "balance": "0xad78ebc5ac6200000" + }, + "ac608e2bac9dd20728d2947effbbbf900a9ce94b": { + "balance": "0x1454b0db37568fc0000" + }, + "ac6d02e9a46b379fac4ac9b1d7b5d47bc850ce16": { + "balance": "0x5f68e8131ecf800000" + }, + "ac6f68e837cf1961cb14ab47446da168a16dde89": { + "balance": "0x487a9a304539440000" + }, + "ac77bdf00fd5985b5db12bbef800380abc2a0677": { + "balance": "0x3635c9adc5dea00000" + }, + "ac7e03702723cb16ee27e22dd0b815dc2d5cae9f": { + "balance": "0x3635c9adc5dea000000" + }, + "ac8b509aefea1dbfaf2bb33500d6570b6fd96d51": { + "balance": "0x62a992e53a0af00000" + }, + "ac8e87ddda5e78fcbcb9fa7fc3ce038f9f7d2e34": { + "balance": "0x6c6b935b8bbd400000" + }, + "ac9fff68c61b011efbecf038ed72db97bb9e7281": { + "balance": "0x205b4dfa1ee74780000" + }, + "aca1e6bc64cc3180f620e94dc5b1bcfd8158e45d": { + "balance": "0x6c6b935b8bbd400000" + }, + "aca2a838330b17302da731d30db48a04f0f207c1": { + "balance": "0x487a9a304539440000" + }, + "acaaddcbf286cb0e215dda55598f7ff0f4ada5c6": { + "balance": "0x3635c9adc5dea00000" + }, + "acb94338554bc488cc88ae2d9d94080d6bdf8410": { + "balance": "0x3635c9adc5dea00000" + }, + "acbc2d19e06c3babbb5b6f052b6bf7fc37e07229": { + "balance": "0xad78ebc5ac6200000" + }, + "acbd185589f7a68a67aa4b1bd65077f8c64e4e21": { + "balance": "0xad78ebc5ac6200000" + }, + "acc062702c59615d3444ef6214b8862b009a02ed": { + "balance": "0x514fcb24ff9c500000" + }, + "acc0909fda2ea6b7b7a88db7a0aac868091ddbf6": { + "balance": "0x133765f1e26c78000" + }, + "acc1c78786ab4d2b3b277135b5ba123e0400486b": { + "balance": "0x44591d67fecc80000" + }, + "acc46a2a555c74ded4a2bd094e821b97843b40c0": { + "balance": "0x692ae8897081d00000" + }, + "acc59f3b30ceffc56461cc5b8df48902240e0e7b": { + "balance": "0x6c6b935b8bbd400000" + }, + "acce01e0a70610dc70bb91e9926fa9957f372fba": { + "balance": "0x1d1c5f3eda20c40000" + }, + "acd8dd91f714764c45677c63d852e56eb9eece2e": { + "balance": "0x6c6b935b8bbd400000" + }, + "ace2abb63b0604409fbde3e716d2876d44e8e5dd": { + "balance": "0x83d6c7aab63600000" + }, + "acec91ef6941cf630ba9a3e787a012f4a2d91dd4": { + "balance": "0x10f0cf064dd592000000" + }, + "ad0a4ae478e9636e88c604f242cf5439c6d45639": { + "balance": "0xbed1d0263d9f000000" + }, + "ad1799aad7602b4540cd832f9db5f11150f1687a": { + "balance": "0x6c6b935b8bbd400000" + }, + "ad1d68a038fd2586067ef6d135d9628e79c2c924": { + "balance": "0xfe09a5279e2abc0000" + }, + "ad2a5c00f923aaf21ab9f3fb066efa0a03de2fb2": { + "balance": "0x3635bb77cb4b860000" + }, + "ad3565d52b688added08168b2d3872d17d0a26ae": { + "balance": "0x56bc75e2d63100000" + }, + "ad377cd25eb53e83ae091a0a1d2b4516f484afde": { + "balance": "0x692ae8897081d00000" + }, + "ad414d29cb7ee973fec54e22a388491786cf5402": { + "balance": "0x2f6f10780d22cc00000" + }, + "ad44357e017e244f476931c7b8189efee80a5d0a": { + "balance": "0x1043561a8829300000" + }, + "ad57aa9d00d10c439b35efcc0becac2e3955c313": { + "balance": "0xad78ebc5ac6200000" + }, + "ad59a78eb9a74a7fbdaefafa82eada8475f07f95": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ad5a8d3c6478b69f657db3837a2575ef8e1df931": { + "balance": "0x20156e104c1b30000" + }, + "ad660dec825522a9f62fcec3c5b731980dc286ea": { + "balance": "0xa2a15d09519be00000" + }, + "ad6628352ed3390bafa86d923e56014cfcb360f4": { + "balance": "0x6c6b935b8bbd400000" + }, + "ad728121873f0456d0518b80ab6580a203706595": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ad732c976593eec4783b4e2ecd793979780bfedb": { + "balance": "0x6c6b935b8bbd400000" + }, + "ad7dd053859edff1cb6f9d2acbed6dd5e332426f": { + "balance": "0x6acb3df27e1f880000" + }, + "ad80d865b85c34d2e6494b2e7aefea6b9af184db": { + "balance": "0xd8d726b7177a800000" + }, + "ad8bfef8c68a4816b3916f35cb7bfcd7d3040976": { + "balance": "0x878678326eac9000000" + }, + "ad8e48a377695de014363a523a28b1a40c78f208": { + "balance": "0x3635c9adc5dea00000" + }, + "ad910a23d6850613654af786337ad2a70868ac6d": { + "balance": "0x6c68ccd09b022c0000" + }, + "ad927e03d1599a78ca2bf0cad2a183dceb71eac0": { + "balance": "0x6acb3df27e1f880000" + }, + "ad92ca066edb7c711dfc5b166192d1edf8e77185": { + "balance": "0x79f905c6fd34e800000" + }, + "ad94235fc3b3f47a2413af31e884914908ef0c45": { + "balance": "0x1b1b0142d815840000" + }, + "ad9e97a0482f353a05c0f792b977b6c7e811fa5f": { + "balance": "0xad78ebc5ac6200000" + }, + "ad9f4c890a3b511cee51dfe6cfd7f1093b76412c": { + "balance": "0x1b767cbfeb0ce40000" + }, + "adaa0e548c035affed64ca678a963fabe9a26bfd": { + "balance": "0x3cb71f51fc5580000" + }, + "adb948b1b6fefe207de65e9bbc2de98e605d0b57": { + "balance": "0x6c6b935b8bbd400000" + }, + "adc19ec835afe3e58d87dc93a8a9213c90451326": { + "balance": "0x6adbe5342282000000" + }, + "adc8228ef928e18b2a807d00fb3c6c79cd1d9e96": { + "balance": "0x13c69df334ee80000" + }, + "addb26317227f45c87a2cb90dc4cfd02fb23caf8": { + "balance": "0x3635c9adc5dea00000" + }, + "ade6f8163bf7c7bb4abe8e9893bd0cc112fe8872": { + "balance": "0x11c25d004d01f80000" + }, + "adeb204aa0c38e179e81a94ed8b3e7d53047c26b": { + "balance": "0x20f5b1eaad8d800000" + }, + "adeb52b604e5f77faaac88275b8d6b49e9f9f97f": { + "balance": "0x71426b00956ed20000" + }, + "adf1acfe99bc8c14b304c8d905ba27657b8a7bc4": { + "balance": "0x43c33c1937564800000" + }, + "adf85203c8376a5fde9815384a350c3879c4cb93": { + "balance": "0x3e31fc675815aa0000" + }, + "adff0d1d0b97471e76d789d2e49c8a74f9bd54ff": { + "balance": "0x65ea3db75546600000" + }, + "ae062c448618643075de7a0030342dced63dbad7": { + "balance": "0x2cc6cd8cc282b30000" + }, + "ae10e27a014f0d306baf266d4897c89aeee2e974": { + "balance": "0x43c33c1937564800000" + }, + "ae126b382cf257fad7f0bc7d16297e54cc7267da": { + "balance": "0x1043561a8829300000" + }, + "ae13a08511110f32e53be4127845c843a1a57c7b": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ae179a460db66326743d24e67523a57b246daf7f": { + "balance": "0x10007ae7ce5bbe40000" + }, + "ae222865799079aaf4f0674a0cdaab02a6d570ff": { + "balance": "0x6c6b935b8bbd400000" + }, + "ae239acffd4ebe2e1ba5b4170572dc79cc6533ec": { + "balance": "0x28a857425466f800000" + }, + "ae2f9c19ac76136594432393b0471d08902164d3": { + "balance": "0x25df05c6a897e40000" + }, + "ae34861d342253194ffc6652dfde51ab44cad3fe": { + "balance": "0x194608686316bd8000" + }, + "ae36f7452121913e800e0fcd1a65a5471c23846f": { + "balance": "0x8e3f50b173c100000" + }, + "ae3f98a443efe00f3e711d525d9894dc9a61157b": { + "balance": "0x1004e2e45fb7ee0000" + }, + "ae47e2609cfafe369d66d415d939de05081a9872": { + "balance": "0x5baecf025f9b6500000" + }, + "ae4f122e35c0b1d1e4069291457c83c07f965fa3": { + "balance": "0x3635c9adc5dea00000" + }, + "ae5055814cb8be0c117bb8b1c8d2b63b4698b728": { + "balance": "0x1bc932ec573a38000" + }, + "ae538c73c5b38d8d584d7ebdadefb15cabe48357": { + "balance": "0x3627e8f712373c0000" + }, + "ae57cc129a96a89981dac60d2ffb877d5dc5e432": { + "balance": "0x3c3a2394b396550000" + }, + "ae5aa1e6c2b60f6fd3efe721bb4a719cbe3d6f5d": { + "balance": "0x2b24c6b55a5e620000" + }, + "ae5c9bdad3c5c8a1220444aea5c229c1839f1d64": { + "balance": "0x19e2a4c818b9060000" + }, + "ae5ce3355a7ba9b332760c0950c2bc45a85fa9a0": { + "balance": "0x15af1d78b58c400000" + }, + "ae5d221afcd3d29355f508eadfca408ce33ca903": { + "balance": "0x152d02c7e14af6800000" + }, + "ae635bf73831119d2d29c0d04ff8f8d8d0a57a46": { + "balance": "0x487a9a304539440000" + }, + "ae648155a658370f929be384f7e001047e49dd46": { + "balance": "0x2df24ae32be20440000" + }, + "ae6f0c73fdd77c489727512174d9b50296611c4c": { + "balance": "0x14542ba12a337c00000" + }, + "ae70e69d2c4a0af818807b1a2705f79fd0b5dbc4": { + "balance": "0x35659ef93f0fc40000" + }, + "ae7739124ed153052503fc101410d1ffd8cd13b7": { + "balance": "0x3634fb9f1489a70000" + }, + "ae78bb849139a6ba38ae92a09a69601cc4cb62d1": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ae842210f44d14c4a4db91fc9d3b3b50014f7bf7": { + "balance": "0xd8d726b7177a800000" + }, + "ae842e81858ecfedf6506c686dc204ac15bf8b24": { + "balance": "0x22b1c8c1227a00000" + }, + "ae8954f8d6166de507cf61297d0fc7ca6b9e7128": { + "balance": "0x1043561a8829300000" + }, + "ae9ecd6bdd952ef497c0050ae0ab8a82a91898ce": { + "balance": "0x1a055690d9db80000" + }, + "ae9f5c3fbbe0c9bcbf1af8ff74ea280b3a5d8b08": { + "balance": "0x5dc892aa1131c80000" + }, + "aead88d689416b1c91f2364421375b7d3c70fb2e": { + "balance": "0x6c6b935b8bbd400000" + }, + "aeadfcd0978edad74a32bd01a0a51d37f246e661": { + "balance": "0xe18398e7601900000" + }, + "aeb916ebf49d0f86c13f7331cef19e129937512d": { + "balance": "0x2085655b8d1b0a0000" + }, + "aebd4f205de799b64b3564b256d42a711d37ef99": { + "balance": "0x3fcf8b4574f84e0000" + }, + "aec27ce2133e82d052520afb5c576d9f7eb93ed2": { + "balance": "0xdd04120ba09cfe60000" + }, + "aec27ff5d7f9ddda91183f46f9d52543b6cd2b2f": { + "balance": "0x18650127cc3dc80000" + }, + "aee49d68adedb081fd43705a5f78c778fb90de48": { + "balance": "0x1158e460913d00000" + }, + "aef5b12258a18dec07d5ec2e316574919d79d6d6": { + "balance": "0x6c6b935b8bbd400000" + }, + "aefcfe88c826ccf131d54eb4ea9eb80e61e1ee25": { + "balance": "0x126e72a69a50d00000" + }, + "af06f5fa6d1214ec43967d1bd4dde74ab814a938": { + "balance": "0x4c53ecdc18a600000" + }, + "af1148ef6c8e103d7530efc91679c9ac27000993": { + "balance": "0xad78ebc5ac6200000" + }, + "af203e229d7e6d419df4378ea98715515f631485": { + "balance": "0x6acb3df27e1f880000" + }, + "af2058c7282cf67c8c3cf930133c89617ce75d29": { + "balance": "0x177224aa844c7200000" + }, + "af26f7c6bf453e2078f08953e4b28004a2c1e209": { + "balance": "0x56bc75e2d63100000" + }, + "af3087e62e04bf900d5a54dc3e946274da92423b": { + "balance": "0x1158e460913d00000" + }, + "af3614dcb68a36e45a4e911e62796247222d595b": { + "balance": "0x7a81065f1103bc0000" + }, + "af3615c789d0b1152ad4db25fe5dcf222804cf62": { + "balance": "0x3635c9adc5dea00000" + }, + "af3cb5965933e7dad883693b9c3e15beb68a4873": { + "balance": "0x6c6b935b8bbd400000" + }, + "af4493e8521ca89d95f5267c1ab63f9f45411e1b": { + "balance": "0xad78ebc5ac6200000" + }, + "af4cf41785161f571d0ca69c94f8021f41294eca": { + "balance": "0x215f835bc769da80000" + }, + "af529bdb459cc185bee5a1c58bf7e8cce25c150d": { + "balance": "0xaadec983fcff40000" + }, + "af67fd3e127fd9dc36eb3fcd6a80c7be4f7532b2": { + "balance": "0x5a87e7d7f5f6580000" + }, + "af771039345a343001bc0f8a5923b126b60d509c": { + "balance": "0x35659ef93f0fc40000" + }, + "af7f79cb415a1fb8dbbd094607ee8d41fb7c5a3b": { + "balance": "0x21e19e0c9bab2400000" + }, + "af87d2371ef378957fbd05ba2f1d66931b01e2b8": { + "balance": "0x25f273933db5700000" + }, + "af880fc7567d5595cacce15c3fc14c8742c26c9e": { + "balance": "0x73f75d1a085ba0000" + }, + "af8e1dcb314c950d3687434d309858e1a8739cd4": { + "balance": "0xe7eeba3410b740000" + }, + "af992dd669c0883e5515d3f3112a13f617a4c367": { + "balance": "0x6c6b935b8bbd400000" + }, + "afa1d5ad38fed44759c05b8993c1aa0dace19f40": { + "balance": "0x4563918244f400000" + }, + "afa539586e4719174a3b46b9b3e663a7d1b5b987": { + "balance": "0x10f0cf064dd59200000" + }, + "afa6946effd5ff53154f82010253df47ae280ccc": { + "balance": "0x6acb3df27e1f880000" + }, + "afc8ebe8988bd4105acc4c018e546a1e8f9c7888": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "afcc7dbb8356d842d43ae7e23c8422b022a30803": { + "balance": "0x66ffcbfd5e5a3000000" + }, + "afd019ff36a09155346b69974815a1c912c90aa4": { + "balance": "0x6c6b935b8bbd400000" + }, + "afdac5c1cb56e245bf70330066a817eaafac4cd1": { + "balance": "0x1158e460913d00000" + }, + "afdd1b786162b8317e20f0e979f4b2ce486d765d": { + "balance": "0x1158e460913d00000" + }, + "aff1045adf27a1aa329461b24de1bae9948a698b": { + "balance": "0x1cf84a30a0a0c0000" + }, + "aff107960b7ec34ed690b665024d60838c190f70": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "aff11ccf699304d5f5862af86083451c26e79ae5": { + "balance": "0x6c5db2a4d815dc0000" + }, + "aff161740a6d909fe99c59a9b77945c91cc91448": { + "balance": "0x340aad21b3b700000" + }, + "affc99d5ebb4a84fe7788d97dce274b038240438": { + "balance": "0x10f0cf064dd59200000" + }, + "affea0473722cb7f0e0e86b9e11883bf428d8d54": { + "balance": "0x692ae8897081d00000" + }, + "b00996b0566ecb3e7243b8227988dcb352c21899": { + "balance": "0x28a857425466f800000" + }, + "b01e389b28a31d8e4995bdd7d7c81beeab1e4119": { + "balance": "0x3635c9adc5dea00000" + }, + "b02d062873334545cea29218e4057760590f7423": { + "balance": "0xacb6a1c7d93a880000" + }, + "b02fa29387ec12e37f6922ac4ce98c5b09e0b00f": { + "balance": "0x6c6b935b8bbd400000" + }, + "b036916bdacf94b69e5a8a65602975eb026104dd": { + "balance": "0x1158e460913d00000" + }, + "b041310fe9eed6864cedd4bee58df88eb4ed3cac": { + "balance": "0x21e19e0c9bab2400000" + }, + "b055af4cadfcfdb425cf65ba6431078f07ecd5ab": { + "balance": "0x56bc75e2d63100000" + }, + "b0571153db1c4ed7acaefe13ecdfdb72e7e4f06a": { + "balance": "0x110cff796ac195200000" + }, + "b06eab09a610c6a53d56a946b2c43487ac1d5b2d": { + "balance": "0x3635c9adc5dea00000" + }, + "b07249e055044a9155359a402937bbd954fe48b6": { + "balance": "0x56bc75e2d63100000" + }, + "b07618328a901307a1b7a0d058fcd5786e9e72fe": { + "balance": "0x667495d4a4330ce0000" + }, + "b079bb4d9866143a6da72ae7ac0022062981315c": { + "balance": "0x29331e6558f0e00000" + }, + "b07bcc085ab3f729f24400416837b69936ba8873": { + "balance": "0x6c6d84bccdd9ce0000" + }, + "b07bcf1cc5d4462e5124c965ecf0d70dc27aca75": { + "balance": "0x56bc75e2d631000000" + }, + "b07cb9c12405b711807543c4934465f87f98bd2d": { + "balance": "0x6c6b935b8bbd400000" + }, + "b07fdeaff91d4460fe6cd0e8a1b0bd8d22a62e87": { + "balance": "0x11d2529f3535ab00000" + }, + "b09fe6d4349b99bc37938054022d54fca366f7af": { + "balance": "0x2a5a058fc295ed000000" + }, + "b0aa00950c0e81fa3210173e729aaf163a27cd71": { + "balance": "0x878678326eac9000000" + }, + "b0ac4eff6680ee14169cdadbffdb30804f6d25f5": { + "balance": "0x6c6b935b8bbd400000" + }, + "b0b36af9aeeedf97b6b02280f114f13984ea3260": { + "balance": "0x35659ef93f0fc40000" + }, + "b0b779b94bfa3c2e1f587bcc9c7e21789222378f": { + "balance": "0x54069233bf7f780000" + }, + "b0baeb30e313776c4c6d247402ba4167afcda1cc": { + "balance": "0x6acb3df27e1f880000" + }, + "b0bb29a861ea1d424d45acd4bfc492fb8ed809b7": { + "balance": "0x4563918244f400000" + }, + "b0c1b177a220e41f7c74d07cde8569c21c75c2f9": { + "balance": "0x12f939c99edab800000" + }, + "b0c7ce4c0dc3c2bbb99cc1857b8a455f611711ce": { + "balance": "0xd8d726b7177a800000" + }, + "b0cef8e8fb8984a6019f01c679f272bbe68f5c77": { + "balance": "0x83d6c7aab63600000" + }, + "b0d32bd7e4e695b7b01aa3d0416f80557dba9903": { + "balance": "0x3739ff0f6e613300000" + }, + "b0d3c9872b85056ea0c0e6d1ecf7a77e3ce6ab85": { + "balance": "0x10f08eda8e555098000" + }, + "b0e469c886593815b3495638595daef0665fae62": { + "balance": "0x692ae8897081d00000" + }, + "b0e760bb07c081777345e0578e8bc898226d4e3b": { + "balance": "0x6c6b935b8bbd400000" + }, + "b1043004ec1941a8cf4f2b00b15700ddac6ff17e": { + "balance": "0x3635c9adc5dea00000" + }, + "b105dd3d987cffd813e9c8500a80a1ad257d56c6": { + "balance": "0x6c6acc67d7b1d40000" + }, + "b10fd2a647102f881f74c9fbc37da632949f2375": { + "balance": "0x22b1c8c1227a00000" + }, + "b115ee3ab7641e1aa6d000e41bfc1ec7210c2f32": { + "balance": "0x2c0bb3dd30c4e200000" + }, + "b1178ad47383c31c8134a1941cbcd474d06244e2": { + "balance": "0x3635c9adc5dea00000" + }, + "b1179589e19db9d41557bbec1cb24ccc2dec1c7f": { + "balance": "0x152d02c7e14af6800000" + }, + "b119e79aa9b916526581cbf521ef474ae84dcff4": { + "balance": "0x4fba1001e5befe0000" + }, + "b11fa7fb270abcdf5a2eab95aa30c4b53636efbf": { + "balance": "0x2b5e3af16b18800000" + }, + "b124bcb6ffa430fcae2e86b45f27e3f21e81ee08": { + "balance": "0x6c6b935b8bbd400000" + }, + "b129a5cb7105fe810bd895dc7206a991a4545488": { + "balance": "0x1a055690d9db80000" + }, + "b12ed07b8a38ad5506363fc07a0b6d799936bdaf": { + "balance": "0x21e19e0c9bab2400000" + }, + "b134c004391ab4992878337a51ec242f42285742": { + "balance": "0x6c6b935b8bbd400000" + }, + "b13f93af30e8d7667381b2b95bc1a699d5e3e129": { + "balance": "0x16c4abbebea0100000" + }, + "b1459285863ea2db3759e546ceb3fb3761f5909c": { + "balance": "0x3cd72a894087e08000" + }, + "b146a0b925553cf06fcaf54a1b4dfea621290757": { + "balance": "0x6c6e59e67c78540000" + }, + "b14a7aaa8f49f2fb9a8102d6bbe4c48ae7c06fb2": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "b14bbeff70720975dc6191b2a44ff49f2672873c": { + "balance": "0x7c0860e5a80dc0000" + }, + "b14cc8de33d6338236539a489020ce4655a32bc6": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "b14ddb0386fb606398b8cc47565afae00ff1d66a": { + "balance": "0xa12aff083e66f00000" + }, + "b153f828dd076d4a7c1c2574bb2dee1a44a318a8": { + "balance": "0x15af1d78b58c400000" + }, + "b1540e94cff3465cc3d187e7c8e3bdaf984659e2": { + "balance": "0xa215e44390e3330000" + }, + "b158db43fa62d30e65f3d09bf781c7b67372ebaa": { + "balance": "0x6c5db2a4d815dc0000" + }, + "b161725fdcedd17952d57b23ef285b7e4b1169e8": { + "balance": "0x2b6dfed3664958000" + }, + "b16479ba8e7df8f63e1b95d149cd8529d735c2da": { + "balance": "0x2de33a6aac32548000" + }, + "b166e37d2e501ae73c84142b5ffb5aa655dd5a99": { + "balance": "0x6c5db2a4d815dc0000" + }, + "b183ebee4fcb42c220e47774f59d6c54d5e32ab1": { + "balance": "0x56f7a9c33c04d10000" + }, + "b188078444027e386798a8ae68698919d5cc230d": { + "balance": "0xe7eeba3410b740000" + }, + "b1896a37e5d8825a2d01765ae5de629977de8352": { + "balance": "0xad78ebc5ac6200000" + }, + "b18e67a5050a1dc9fb190919a33da838ef445014": { + "balance": "0x1158e460913d00000" + }, + "b1a2b43a7433dd150bb82227ed519cd6b142d382": { + "balance": "0x946d620d744b880000" + }, + "b1c0d08b36e184f9952a4037e3e53a667d070a4e": { + "balance": "0x3635c9adc5dea00000" + }, + "b1c328fb98f2f19ab6646f0a7c8c566fda5a8540": { + "balance": "0x878678326eac900000" + }, + "b1c751786939bba0d671a677a158c6abe7265e46": { + "balance": "0x21e19e0c9bab2400000" + }, + "b1cd4bdfd104489a026ec99d597307a04279f173": { + "balance": "0x43c33c1937564800000" + }, + "b1cf94f8091505055f010ab4bac696e0ca0f67a1": { + "balance": "0x55a6e79ccd1d300000" + }, + "b1d6b01b94d854fe8b374aa65e895cf22aa2560e": { + "balance": "0x32f51edbaaa3300000" + }, + "b1dba5250ba9625755246e067967f2ad2f0791de": { + "balance": "0x10f0cf064dd592000000" + }, + "b1e2dd95e39ae9775c55aeb13f12c2fa233053ba": { + "balance": "0x6c6b935b8bbd400000" + }, + "b1e6e810c24ab0488de9e01e574837829f7c77d0": { + "balance": "0x15af1d78b58c400000" + }, + "b1e9c5f1d21e61757a6b2ee75913fc5a1a4101c3": { + "balance": "0x6c6b935b8bbd400000" + }, + "b203d29e6c56b92699c4b92d1f6f84648dc4cfbc": { + "balance": "0x15af1d78b58c400000" + }, + "b216dc59e27c3d7279f5cd5bb2becfb2606e14d9": { + "balance": "0x15af1d78b58c400000" + }, + "b21b7979bf7c5ca01fa82dd640b41c39e6c6bc75": { + "balance": "0x6c6acc67d7b1d40000" + }, + "b223bf1fbf80485ca2b5567d98db7bc3534dd669": { + "balance": "0xd8d726b7177a800000" + }, + "b22d5055d9623135961e6abd273c90deea16a3e7": { + "balance": "0x4be4e7267b6ae00000" + }, + "b22dadd7e1e05232a93237baed98e0df92b1869e": { + "balance": "0x6c6b935b8bbd400000" + }, + "b234035f7544463ce1e22bc553064684c513cd51": { + "balance": "0xd89fa3dc48dcf0000" + }, + "b247cf9c72ec482af3eaa759658f793d670a570c": { + "balance": "0x31708ae00454400000" + }, + "b2676841ee9f2d31c172e82303b0fe9bbf9f1e09": { + "balance": "0xad78ebc5ac6200000" + }, + "b279c7d355c2880392aad1aa21ee867c3b3507df": { + "balance": "0x445be3f2ef87940000" + }, + "b27c1a24204c1e118d75149dd109311e07c073ab": { + "balance": "0xa80d24677efef00000" + }, + "b28181a458a440f1c6bb1de8400281a3148f4c35": { + "balance": "0x14620c57dddae00000" + }, + "b28245037cb192f75785cb86cbfe7c930da258b0": { + "balance": "0x3635c9adc5dea000000" + }, + "b287f7f8d8c3872c1b586bcd7d0aedbf7e732732": { + "balance": "0x1158e460913d00000" + }, + "b28bb39f3466517cd46f979cf59653ee7d8f152e": { + "balance": "0x18650127cc3dc80000" + }, + "b28dbfc6499894f73a71faa00abe0f4bc9d19f2a": { + "balance": "0x56bc75e2d63100000" + }, + "b2968f7d35f208871631c6687b3f3daeabc6616c": { + "balance": "0x875c47f289f760000" + }, + "b29f5b7c1930d9f97a115e067066f0b54db44b3b": { + "balance": "0x3635c9adc5dea00000" + }, + "b2a144b1ea67b9510f2267f9da39d3f93de26642": { + "balance": "0x6c6b935b8bbd400000" + }, + "b2a2c2111612fb8bbb8e7dd9378d67f1a384f050": { + "balance": "0x1158e460913d00000" + }, + "b2a498f03bd7178bd8a789a00f5237af79a3e3f8": { + "balance": "0x41bad155e6512200000" + }, + "b2aa2f1f8e93e79713d92cea9ffce9a40af9c82d": { + "balance": "0x6c6b935b8bbd400000" + }, + "b2b516fdd19e7f3864b6d2cf1b252a4156f1b03b": { + "balance": "0x2e983c76115fc0000" + }, + "b2b7cdb4ff4b61d5b7ce0b2270bbb5269743ec04": { + "balance": "0x6c6b935b8bbd400000" + }, + "b2bdbedf95908476d7148a370cc693743628057f": { + "balance": "0xd8d726b7177a800000" + }, + "b2bfaa58b5196c5cb7f89de15f479d1838de713d": { + "balance": "0x1236efcbcbb340000" + }, + "b2c53efa33fe4a3a1a80205c73ec3b1dbcad0602": { + "balance": "0x6801dab35918938000" + }, + "b2d0360515f17daba90fcbac8205d569b915d6ac": { + "balance": "0x14542ba12a337c00000" + }, + "b2d1e99af91231858e7065dd1918330dc4c747d5": { + "balance": "0x3894f0e6f9b9f700000" + }, + "b2d9ab9664bcf6df203c346fc692fd9cbab9205e": { + "balance": "0x17be78976065180000" + }, + "b2ddb786d3794e270187d0451ad6c8b79e0e8745": { + "balance": "0x15af1d78b58c400000" + }, + "b2e085fddd1468ba07415b274e734e11237fb2a9": { + "balance": "0x56bc75e2d63100000" + }, + "b2e9d76bf50fc36bf7d3944b63e9ca889b699968": { + "balance": "0x9032ea62b74b100000" + }, + "b2f9c972c1e9737755b3ff1b3088738396395b26": { + "balance": "0x43c33c1937564800000" + }, + "b2fc84a3e50a50af02f94da0383ed59f71ff01d7": { + "balance": "0x65a4da25d3016c00000" + }, + "b3050beff9de33c80e1fa15225e28f2c413ae313": { + "balance": "0x25f273933db5700000" + }, + "b31196714a48dff726ea9433cd2912f1a414b3b3": { + "balance": "0x914878a8c05ee00000" + }, + "b3145b74506d1a8d047cdcdc55392a7b5350799a": { + "balance": "0x1b6229741c0d3d5d8000" + }, + "b320834836d1dbfda9e7a3184d1ad1fd4320ccc0": { + "balance": "0x3635c9adc5dea00000" + }, + "b323dcbf2eddc5382ee4bbbb201ca3931be8b438": { + "balance": "0x6c6b935b8bbd400000" + }, + "b32400fd13c5500917cb037b29fe22e7d5228f2d": { + "balance": "0x878678326eac9000000" + }, + "b325674c01e3f7290d5226339fbeac67d221279f": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "b32825d5f3db249ef4e85cc4f33153958976e8bc": { + "balance": "0x1b2df9d219f5798000" + }, + "b32af3d3e8d075344926546f2e32887bf93b16bd": { + "balance": "0xad78ebc5ac6200000" + }, + "b32f1c2689a5ce79f1bc970b31584f1bcf2283e7": { + "balance": "0x1158e460913d00000" + }, + "b33c0323fbf9c26c1d8ac44ef74391d0804696da": { + "balance": "0x1158e460913d00000" + }, + "b34f04b8db65bba9c26efc4ce6efc50481f3d65d": { + "balance": "0x43c33c1937564800000" + }, + "b3557d39b5411b84445f5f54f38f62d2714d0087": { + "balance": "0x2086ac351052600000" + }, + "b358e97c70b605b1d7d729dfb640b43c5eafd1e7": { + "balance": "0x43c33c1937564800000" + }, + "b35e8a1c0dac7e0e66dbac736a592abd44012561": { + "balance": "0xcfce55aa12b30000" + }, + "b3667894b7863c068ad344873fcff4b5671e0689": { + "balance": "0x43c33c1937564800000" + }, + "b3717731dad65132da792d876030e46ac227bb8a": { + "balance": "0x3635c9adc5dea00000" + }, + "b3731b046c8ac695a127fd79d0a5d5fa6ae6d12e": { + "balance": "0x6c4fd1ee246e780000" + }, + "b37c2b9f50637bece0ca959208aefee6463ba720": { + "balance": "0x15af1d78b58c400000" + }, + "b388b5dfecd2c5e4b596577c642556dbfe277855": { + "balance": "0x1158e460913d00000" + }, + "b38c4e537b5df930d65a74d043831d6b485bbde4": { + "balance": "0x15af1d78b58c400000" + }, + "b39139576194a0866195151f33f2140ad1cc86cf": { + "balance": "0x152d02c7e14af6800000" + }, + "b39f4c00b2630cab7db7295ef43d47d501e17fd7": { + "balance": "0xd8d726b7177a800000" + }, + "b3a64b1176724f5409e1414a3523661baee74b4a": { + "balance": "0x16368ff4ff9c10000" + }, + "b3a6bd41f9d9c3201e050b87198fbda399342210": { + "balance": "0xc461e1dd1029b58000" + }, + "b3a8c2cb7d358e5739941d945ba9045a023a8bbb": { + "balance": "0x3635c9adc5dea00000" + }, + "b3ae54fba09d3ee1d6bdd1e957923919024c35fa": { + "balance": "0x38d2cee65b22a8000" + }, + "b3b7f493b44a2c8d80ec78b1cdc75a652b73b06c": { + "balance": "0x6c6b935b8bbd400000" + }, + "b3c228731d186d2ded5b5fbe004c666c8e469b86": { + "balance": "0x19274b259f6540000" + }, + "b3c260609b9df4095e6c5dff398eeb5e2df49985": { + "balance": "0xdc55fdb17647b0000" + }, + "b3c65b845aba6cd816fbaae983e0e46c82aa8622": { + "balance": "0x3635c9adc5dea00000" + }, + "b3c94811e7175b148b281c1a845bfc9bb6fbc115": { + "balance": "0xad78ebc5ac6200000" + }, + "b3e20eb4de18bd060221689894bee5aeb25351ee": { + "balance": "0x3fc80cce516598000" + }, + "b3e3c439069880156600c2892e448d4136c92d9b": { + "balance": "0x2e141ea081ca080000" + }, + "b3f82a87e59a39d0d2808f0751eb72c2329cdcc5": { + "balance": "0x10f0cf064dd59200000" + }, + "b3fc1d6881abfcb8becc0bb021b8b73b7233dd91": { + "balance": "0x2b5e3af16b1880000" + }, + "b40594c4f3664ef849cca6227b8a25aa690925ee": { + "balance": "0xd8d726b7177a800000" + }, + "b41eaf5d51a5ba1ba39bb418dbb54fab750efb1f": { + "balance": "0x3635c9adc5dea00000" + }, + "b424d68d9d0d00cec1938c854e15ffb880ba0170": { + "balance": "0xad78ebc5ac6200000" + }, + "b4256273962bf631d014555cc1da0dcc31616b49": { + "balance": "0x6c6b935b8bbd400000" + }, + "b43067fe70d9b55973ba58dc64dd7f311e554259": { + "balance": "0xad78ebc5ac6200000" + }, + "b43657a50eecbc3077e005d8f8d94f377876bad4": { + "balance": "0x1ec1b3a1ff75a0000" + }, + "b43c27f7a0a122084b98f483922541c8836cee2c": { + "balance": "0x26c29e47c4844c0000" + }, + "b4413576869c08f9512ad311fe925988a52d3414": { + "balance": "0x21e19e0c9bab2400000" + }, + "b44605552471a6eee4daab71ff3bb41326d473e0": { + "balance": "0x2d7e3d51ba53d00000" + }, + "b447571dacbb3ecbb6d1cf0b0c8f3838e52324e2": { + "balance": "0x1a318667fb4058000" + }, + "b44783c8e57b480793cbd69a45d90c7b4f0c48ac": { + "balance": "0x1158e460913d00000" + }, + "b44815a0f28e569d0e921a4ade8fb2642526497a": { + "balance": "0x302379bf2ca2e0000" + }, + "b4496ddb27799a222457d73979116728e8a1845b": { + "balance": "0x8d819ea65fa62f8000" + }, + "b4524c95a7860e21840296a616244019421c4aba": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "b45cca0d36826662683cf7d0b2fdac687f02d0c4": { + "balance": "0x3635c9adc5dea00000" + }, + "b46440c797a556e04c7d9104660491f96bb076bf": { + "balance": "0xcec76f0e71520000" + }, + "b46ace865e2c50ea4698d216ab455dff5a11cd72": { + "balance": "0x3635c9adc5dea00000" + }, + "b46d1182e5aacaff0d26b2fcf72f3c9ffbcdd97d": { + "balance": "0xaa2a603cdd7f2c0000" + }, + "b48921c9687d5510744584936e8886bdbf2df69b": { + "balance": "0x3635c9adc5dea00000" + }, + "b498bb0f520005b6216a4425b75aa9adc52d622b": { + "balance": "0xd8d726b7177a800000" + }, + "b4b11d109f608fa8edd3fea9f8c315649aeb3d11": { + "balance": "0x10f0cf064dd59200000" + }, + "b4b14bf45455d0ab0803358b7524a72be1a2045b": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "b4b185d943ee2b58631e33dff5af6854c17993ac": { + "balance": "0x3635c9adc5dea00000" + }, + "b4bf24cb83686bc469869fefb044b909716993e2": { + "balance": "0x6c6b935b8bbd400000" + }, + "b4c20040ccd9a1a3283da4d4a2f365820843d7e2": { + "balance": "0x3635c9adc5dea00000" + }, + "b4c8170f7b2ab536d1d9a25bdd203ae1288dc3d5": { + "balance": "0xad78ebc5ac6200000" + }, + "b4d82f2e69943f7de0f5f7743879406fac2e9cec": { + "balance": "0x22b1c8c1227a00000" + }, + "b4dd460cd016725a64b22ea4f8e06e06674e033e": { + "balance": "0x1231bb8748547a80000" + }, + "b4dd5499daeb2507fb2de12297731d4c72b16bb0": { + "balance": "0x1158e460913d00000" + }, + "b5046cb3dc1dedbd364514a2848e44c1de4ed147": { + "balance": "0x37b7d9bb820405e0000" + }, + "b508f987b2de34ae4cf193de85bff61389621f88": { + "balance": "0x14542ba12a337c00000" + }, + "b50955aa6e341571986608bdc891c2139f540cdf": { + "balance": "0x6acb3df27e1f880000" + }, + "b50c149a1906fad2786ffb135aab501737e9e56f": { + "balance": "0x150894e849b3900000" + }, + "b50c9f5789ae44e2dce017c714caf00c830084c2": { + "balance": "0x155bd9307f9fe80000" + }, + "b514882c979bb642a80dd38754d5b8c8296d9a07": { + "balance": "0x33c5499031720c0000" + }, + "b51ddcb4dd4e8ae6be336dd9654971d9fec86b41": { + "balance": "0x16d464f83de2948000" + }, + "b51e558eb5512fbcfa81f8d0bd938c79ebb5242b": { + "balance": "0x26c29e47c4844c0000" + }, + "b523fff9749871b35388438837f7e6e0dea9cb6b": { + "balance": "0x6c6b935b8bbd400000" + }, + "b52dfb45de5d74e3df208332bc571c809b8dcf32": { + "balance": "0x14542ba12a337c00000" + }, + "b535f8db879fc67fec58824a5cbe6e5498aba692": { + "balance": "0x678a932062e4180000" + }, + "b537d36a70eeb8d3e5c80de815225c1158cb92c4": { + "balance": "0x5150ae84a8cdf00000" + }, + "b53bcb174c2518348b818aece020364596466ba3": { + "balance": "0x6c6b935b8bbd400000" + }, + "b5493ef173724445cf345c035d279ba759f28d51": { + "balance": "0x1158e460913d00000" + }, + "b553d25d6b5421e81c2ad05e0b8ba751f8f010e3": { + "balance": "0x6c6b935b8bbd400000" + }, + "b55474ba58f0f2f40e6cbabed4ea176e011fcad6": { + "balance": "0x6acb3df27e1f880000" + }, + "b555d00f9190cc3677aef314acd73fdc39399259": { + "balance": "0x6c6b935b8bbd400000" + }, + "b557ab9439ef50d237b553f02508364a466a5c03": { + "balance": "0xad78ebc5ac6200000" + }, + "b56a780028039c81caf37b6775c620e786954764": { + "balance": "0x6c6b935b8bbd400000" + }, + "b56ad2aec6c8c3f19e1515bbb7dd91285256b639": { + "balance": "0x3635c9adc5dea00000" + }, + "b57413060af3f14eb479065f1e9d19b3757ae8cc": { + "balance": "0x22b1c8c1227a00000" + }, + "b57549bfbc9bdd18f736b22650e48a73601fa65c": { + "balance": "0x182d7e4cfda0380000" + }, + "b577b6befa054e9c040461855094b002d7f57bd7": { + "balance": "0x1823f3cf621d23400000" + }, + "b57b04fa23d1203fae061eac4542cb60f3a57637": { + "balance": "0xa5aa85009e39c0000" + }, + "b5870ce342d43343333673038b4764a46e925f3e": { + "balance": "0x3635c9adc5dea00000" + }, + "b587b44a2ca79e4bc1dd8bfdd43a207150f2e7e0": { + "balance": "0x222c8eb3ff66400000" + }, + "b589676d15a04448344230d4ff27c95edf122c49": { + "balance": "0x3635c9adc5dea00000" + }, + "b58b52865ea55d8036f2fab26098b352ca837e18": { + "balance": "0xfc936392801c0000" + }, + "b5906b0ae9a28158e8ac550e39da086ee3157623": { + "balance": "0xad78ebc5ac6200000" + }, + "b5a4679685fa14196c2e9230c8c4e33bffbc10e2": { + "balance": "0x4be4e7267b6ae00000" + }, + "b5a589dd9f4071dbb6fba89b3f5d5dae7d96c163": { + "balance": "0x6c6b935b8bbd400000" + }, + "b5a606f4ddcbb9471ec67f658caf2b00ee73025e": { + "balance": "0xea756ea92afc740000" + }, + "b5ad5157dda921e6bafacd9086ae73ae1f611d3f": { + "balance": "0x6c6b935b8bbd400000" + }, + "b5add1e7809f7d03069bfe883b0a932210be8712": { + "balance": "0x3635c9adc5dea00000" + }, + "b5ba29917c78a1d9e5c5c713666c1e411d7f693a": { + "balance": "0xa80d24677efef00000" + }, + "b5c816a8283ca4df68a1a73d63bd80260488df08": { + "balance": "0xad78ebc5ac6200000" + }, + "b5cac5ed03477d390bb267d4ebd46101fbc2c3da": { + "balance": "0xaadec983fcff40000" + }, + "b5cdbc4115406f52e5aa85d0fea170d2979cc7ba": { + "balance": "0x487a9a304539440000" + }, + "b5d9934d7b292bcf603b2880741eb760288383a0": { + "balance": "0xe7c2518505060000" + }, + "b5dd50a15da34968890a53b4f13fe1af081baaaa": { + "balance": "0xd8d726b7177a800000" + }, + "b5fa8184e43ed3e0b8ab91216461b3528d84fd09": { + "balance": "0x914878a8c05ee00000" + }, + "b5fb7ea2ddc1598b667a9d57dd39e85a38f35d56": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "b600429752f399c80d0734744bae0a022eca67c6": { + "balance": "0x1158e460913d00000" + }, + "b600feab4aa96c537504d96057223141692c193a": { + "balance": "0x15af1d78b58c400000" + }, + "b6047cdf932db3e4045f4976122341537ed5961e": { + "balance": "0x1158e460913d00000" + }, + "b615e940143eb57f875893bc98a61b3d618c1e8c": { + "balance": "0x1158e460913d00000" + }, + "b61c34fcacda701a5aa8702459deb0e4ae838df8": { + "balance": "0x7695a92c20d6fe00000" + }, + "b63064bd3355e6e07e2d377024125a33776c4afa": { + "balance": "0x8375a2abcca24400000" + }, + "b635a4bc71fb28fdd5d2c322983a56c284426e69": { + "balance": "0x93739534d28680000" + }, + "b646df98b49442746b61525c81a3b04ba3106250": { + "balance": "0x6acb3df27e1f880000" + }, + "b65941d44c50d24666670d364766e991c02e11c2": { + "balance": "0x2086ac351052600000" + }, + "b65bd780c7434115162027565223f44e5498ff8c": { + "balance": "0x43c30fb0884a96c0000" + }, + "b66411e3a02dedb726fa79107dc90bc1cae64d48": { + "balance": "0x6c6b935b8bbd400000" + }, + "b66675142e3111a1c2ea1eb2419cfa42aaf7a234": { + "balance": "0x3635c9adc5dea00000" + }, + "b66f92124b5e63035859e390628869dbdea9485e": { + "balance": "0x215f835bc769da80000" + }, + "b672734afcc224e2e609fc51d4f059732744c948": { + "balance": "0x1004e2e45fb7ee0000" + }, + "b6771b0bf3427f9ae7a93e7c2e61ee63941fdb08": { + "balance": "0x3fb26692954bfc00000" + }, + "b67a80f170197d96cdcc4ab6cba627b4afa6e12c": { + "balance": "0x821ab0d44149800000" + }, + "b68899e7610d4c93a23535bcc448945ba1666f1c": { + "balance": "0xad78ebc5ac6200000" + }, + "b6a82933c9eadabd981e5d6d60a6818ff806e36b": { + "balance": "0x15af1d78b58c400000" + }, + "b6aacb8cb30bab2ae4a2424626e6e12b02d04605": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "b6b34a263f10c3d2eceb0acc559a7b2ab85ce565": { + "balance": "0xd8d726b7177a800000" + }, + "b6bfe1c3ef94e1846fb9e3acfe9b50c3e9069233": { + "balance": "0x6c6acc67d7b1d40000" + }, + "b6cd7432d5161be79768ad45de3e447a07982063": { + "balance": "0xd8d726b7177a800000" + }, + "b6ce4dc560fc73dc69fb7a62e388db7e72ea764f": { + "balance": "0x345df169e9a3580000" + }, + "b6decf82969819ba02de29b9b593f21b64eeda0f": { + "balance": "0x281d901f4fdd100000" + }, + "b6e6c3222b6b6f9be2875d2a89f127fb64100fe2": { + "balance": "0x1b21d5323cc30200000" + }, + "b6e8afd93dfa9af27f39b4df06076710bee3dfab": { + "balance": "0x15af1d78b58c40000" + }, + "b6f78da4f4d041b3bc14bc5ba519a5ba0c32f128": { + "balance": "0x247dd32c3fe195048000" + }, + "b6fb39786250081426a342c70d47ee521e5bc563": { + "balance": "0x32d26d12e980b600000" + }, + "b70dba9391682b4a364e77fe99256301a6c0bf1f": { + "balance": "0xad78ebc5ac6200000" + }, + "b71623f35107cf7431a83fb3d204b29ee0b1a7f4": { + "balance": "0x11164759ffb320000" + }, + "b71a13ba8e95167b80331b52d69e37054fe7a826": { + "balance": "0xad78ebc5ac6200000" + }, + "b71b62f4b448c02b1201cb5e394ae627b0a560ee": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "b72220ade364d0369f2d2da783ca474d7b9b34ce": { + "balance": "0x1b1ab319f5ec750000" + }, + "b7230d1d1ff2aca366963914a79df9f7c5ea2c98": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "b7240af2af90b33c08ae9764103e35dce3638428": { + "balance": "0x1cadd2fe9686e638000" + }, + "b727a9fc82e1cffc5c175fa1485a9befa2cdbdd1": { + "balance": "0x3627e8f712373c0000" + }, + "b72c2a011c0df50fbb6e28b20ae1aad217886790": { + "balance": "0xd8d726b7177a800000" + }, + "b7382d37db0398ac72410cf9813de9f8e1ec8dad": { + "balance": "0x3636c25e66ece70000" + }, + "b73b4ff99eb88fd89b0b6d57a9bc338e886fa06a": { + "balance": "0x1bc16d674ec800000" + }, + "b73d6a77559c86cf6574242903394bacf96e3570": { + "balance": "0x4f1a77ccd3ba00000" + }, + "b74372dbfa181dc9242f39bf1d3731dffe2bdacf": { + "balance": "0x6c6b935b8bbd400000" + }, + "b7479dab5022c4d5dbaaf8de171b4e951dd1a457": { + "balance": "0x4563918244f400000" + }, + "b749b54e04d5b19bdcedfb84da7701ab478c27ae": { + "balance": "0x914878a8c05ee00000" + }, + "b74ed2666001c16333cf7af59e4a3d4860363b9c": { + "balance": "0xa7ebd5e4363a00000" + }, + "b75149e185f6e3927057739073a1822ae1cf0df2": { + "balance": "0xd8d8583fa2d52f0000" + }, + "b753a75f9ed10b21643a0a3dc0517ac96b1a4068": { + "balance": "0x15c8185b2c1ff40000" + }, + "b756ad52f3bf74a7d24c67471e0887436936504c": { + "balance": "0x43c33c1937564800000" + }, + "b7576e9d314df41ec5506494293afb1bd5d3f65d": { + "balance": "0x1158e460913d00000" + }, + "b758896f1baa864f17ebed16d953886fee68aae6": { + "balance": "0x3635c9adc5dea00000" + }, + "b768b5234eba3a9968b34d6ddb481c8419b3655d": { + "balance": "0xcfce55aa12b30000" + }, + "b782bfd1e2de70f467646f9bc09ea5b1fcf450af": { + "balance": "0xe7eeba3410b740000" + }, + "b7a2c103728b7305b5ae6e961c94ee99c9fe8e2b": { + "balance": "0xa968163f0a57b400000" + }, + "b7a31a7c38f3db09322eae11d2272141ea229902": { + "balance": "0x6c6b935b8bbd400000" + }, + "b7a6791c16eb4e2162f14b6537a02b3d63bfc602": { + "balance": "0x2a526391ac93760000" + }, + "b7a7f77c348f92a9f1100c6bd829a8ac6d7fcf91": { + "balance": "0x62a992e53a0af00000" + }, + "b7c077946674ba9341fb4c747a5d50f5d2da6415": { + "balance": "0x3635c9adc5dea00000" + }, + "b7c0d0cc0b4d342d4062bac624ccc3c70cc6da3f": { + "balance": "0xd8d726b7177a800000" + }, + "b7c9f12b038e73436d17e1c12ffe1aeccdb3f58c": { + "balance": "0x1d460162f516f00000" + }, + "b7cc6b1acc32d8b295df68ed9d5e60b8f64cb67b": { + "balance": "0x1043561a8829300000" + }, + "b7ce684b09abda53389a875369f71958aeac3bdd": { + "balance": "0x6c6b935b8bbd400000" + }, + "b7d12e84a2e4c4a6345af1dd1da9f2504a2a996e": { + "balance": "0xad78ebc5ac6200000" + }, + "b7d252ee9402b0eef144295f0e69f0db586c0871": { + "balance": "0x23c757072b8dd00000" + }, + "b7d581fe0af1ec383f3b3c416783f385146a7612": { + "balance": "0x43c33c1937564800000" + }, + "b7f67314cb832e32e63b15a40ce0d7ffbdb26985": { + "balance": "0x398279264a818d0000" + }, + "b8040536958d5998ce4bec0cfc9c2204989848e9": { + "balance": "0x52ea70d498fd50a0000" + }, + "b8310a16cc6abc465007694b930f978ece1930bd": { + "balance": "0x281d901f4fdd100000" + }, + "b834acf3015322c58382eeb2b79638906e88b6de": { + "balance": "0x5150ae84a8cdf000000" + }, + "b84b53d0bb125656cddc52eb852ab71d7259f3d5": { + "balance": "0x3635c9adc5dea000000" + }, + "b84c8b9fd33ece00af9199f3cf5fe0cce28cd14a": { + "balance": "0xcf152640c5c8300000" + }, + "b85218f342f8012eda9f274e63ce2152b2dcfdab": { + "balance": "0xa80d24677efef00000" + }, + "b8555010776e3c5cb311a5adeefe9e92bb9a64b9": { + "balance": "0xd8d726b7177a800000" + }, + "b85f26dd0e72d9c29ebaf697a8af77472c2b58b5": { + "balance": "0x28519acc7190c700000" + }, + "b85ff03e7b5fc422981fae5e9941dacbdaba7584": { + "balance": "0x487a9a304539440000" + }, + "b86607021b62d340cf2652f3f95fd2dc67698bdf": { + "balance": "0x10f0cf064dd59200000" + }, + "b87de1bcd29269d521b8761cc39cfb4319d2ead5": { + "balance": "0x3635c9adc5dea00000" + }, + "b87f5376c2de0b6cc3c179c06087aa473d6b4674": { + "balance": "0x487a9a304539440000" + }, + "b884add88d83dc564ab8e0e02cbdb63919aea844": { + "balance": "0x6c6b935b8bbd400000" + }, + "b88a37c27f78a617d5c091b7d5b73a3761e65f2a": { + "balance": "0x6c6b935b8bbd400000" + }, + "b8947822d5ace7a6ad8326e95496221e0be6b73d": { + "balance": "0x1158e460913d00000" + }, + "b89c036ed7c492879921be41e10ca1698198a74c": { + "balance": "0x62a992e53a0af00000" + }, + "b89f4632df5909e58b2a9964f74feb9a3b01e0c5": { + "balance": "0x48875bcc6e7cbeb8000" + }, + "b8a79c84945e47a9c3438683d6b5842cff7684b1": { + "balance": "0x6c6b935b8bbd400000" + }, + "b8a979352759ba09e35aa5935df175bff678a108": { + "balance": "0x1158e460913d00000" + }, + "b8ab39805bd821184f6cbd3d2473347b12bf175c": { + "balance": "0x6685ac1bfe32c0000" + }, + "b8ac117d9f0dba80901445823c4c9d4fa3fedc6e": { + "balance": "0x3564c4427a8fc7d8000" + }, + "b8bc9bca7f71b4ed12e620438d620f53c114342f": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "b8bedd576a4b4c2027da735a5bc3f533252a1808": { + "balance": "0x6c6b935b8bbd400000" + }, + "b8c2703d8c3f2f44c584bc10e7c0a6b64c1c097e": { + "balance": "0x12cddb8ead6f9f80000" + }, + "b8cc0f060aad92d4eb8b36b3b95ce9e90eb383d7": { + "balance": "0x1fc3842bd1f071c00000" + }, + "b8d2ddc66f308c0158ae3ccb7b869f7d199d7b32": { + "balance": "0x2dcbf4840eca000000" + }, + "b8d389e624a3a7aebce4d3e5dbdf6cdc29932aed": { + "balance": "0xad78ebc5ac6200000" + }, + "b8d531a964bcea13829620c0ced72422dadb4cca": { + "balance": "0x93715cc5ab8a70000" + }, + "b8d5c324a8209d7c8049d0d4aede02ba80ab578b": { + "balance": "0x393928629fff75e8000" + }, + "b8f20005b61352ffa7699a1b52f01f5ab39167f1": { + "balance": "0x21e19e0c9bab2400000" + }, + "b8f30758faa808dbc919aa7b425ec922b93b8129": { + "balance": "0x3636d7af5ec98e0000" + }, + "b9013c51bd078a098fae05bf2ace0849c6be17a5": { + "balance": "0x4563918244f400000" + }, + "b9144b677c2dc614ceefdf50985f1183208ea64c": { + "balance": "0x6c6b935b8bbd400000" + }, + "b916b1a01cdc4e56e7657715ea37e2a0f087d106": { + "balance": "0x826e3181e027068000" + }, + "b91d9e916cd40d193db60e79202778a0087716fc": { + "balance": "0x15f1ba7f4716200000" + }, + "b9231eb26e5f9e4b4d288f03906704fab96c87d6": { + "balance": "0x42bf06b78ed3b500000" + }, + "b92427ad7578b4bfe20a9f63a7c5506d5ca12dc8": { + "balance": "0x6c6b935b8bbd400000" + }, + "b927abd2d28aaaa24db31778d27419df8e1b04bb": { + "balance": "0x17e11c2a26f478000" + }, + "b94d47b3c052a5e50e4261ae06a20f45d8eee297": { + "balance": "0x6c6b935b8bbd400000" + }, + "b95396daaa490df2569324fcc6623be052f132ca": { + "balance": "0x6c6b935b8bbd400000" + }, + "b959dce02e91d9db02b1bd8b7d17a9c41a97af09": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "b95c9b10aa981cf4a67a71cc52c504dee8cf58bd": { + "balance": "0xd8d726b7177a800000" + }, + "b95cfda8465ba9c2661b249fc3ab661bdfa35ff0": { + "balance": "0x114a4e79a2c2108000" + }, + "b96841cabbc7dbd69ef0cf8f81dff3c8a5e21570": { + "balance": "0x28a857425466f800000" + }, + "b97a6733cd5fe99864b3b33460d1672434d5cafd": { + "balance": "0x6c65bbaa46c2cf8000" + }, + "b981ad5e6b7793a23fc6c1e8692eb2965d18d0da": { + "balance": "0x21e18d2c821c7520000" + }, + "b98ca31785ef06be49a1e47e864f60d076ca472e": { + "balance": "0xd8d726b7177a800000" + }, + "b9920fd0e2c735c256463caa240fb7ac86a93dfa": { + "balance": "0x5f68e8131ecf800000" + }, + "b992a967308c02b98af91ee760fd3b6b4824ab0e": { + "balance": "0x6c6b935b8bbd400000" + }, + "b9a985501ee950829b17fae1c9cf348c3156542c": { + "balance": "0xff17517ca9a620000" + }, + "b9b0a3219a3288d9b35b091b14650b8fe23dce2b": { + "balance": "0x2f6f10780d22cc00000" + }, + "b9cf71b226583e3a921103a5316f855a65779d1b": { + "balance": "0x5150ae84a8cdf000000" + }, + "b9e90c1192b3d5d3e3ab0700f1bf655f5dd4347a": { + "balance": "0x1b19e50b44977c0000" + }, + "b9fd3833e88e7cf1fa9879bdf55af4b99cd5ce3f": { + "balance": "0x3635c9adc5dea00000" + }, + "ba0249e01d945bef93ee5ec61925e03c5ca509fd": { + "balance": "0xd8d726b7177a800000" + }, + "ba0f39023bdb29eb1862a9f9059cab5d306e662f": { + "balance": "0x6c6b935b8bbd400000" + }, + "ba10f2764290f875434372f79dbf713801caac01": { + "balance": "0x33c5499031720c0000" + }, + "ba1531fb9e791896bcf3a80558a359f6e7c144bd": { + "balance": "0xd5967be4fc3f100000" + }, + "ba176dbe3249e345cd4fa967c0ed13b24c47e586": { + "balance": "0x15aef9f1c31c7f0000" + }, + "ba1f0e03cb9aa021f4dcebfa94e5c889c9c7bc9e": { + "balance": "0x6d190c475169a200000" + }, + "ba1fcaf223937ef89e85675503bdb7ca6a928b78": { + "balance": "0x22b1c8c1227a000000" + }, + "ba24fc436753a739db2c8d40e6d4d04c528e86fa": { + "balance": "0x2c0bb3dd30c4e200000" + }, + "ba42f9aace4c184504abf5425762aca26f71fbdc": { + "balance": "0x207077dd8a79c0000" + }, + "ba469aa5c386b19295d4a1b5473b540353390c85": { + "balance": "0x6c6b935b8bbd400000" + }, + "ba6440aeb3737b8ef0f1af9b0c15f4c214ffc7cf": { + "balance": "0x3635c9adc5dea00000" + }, + "ba6d31b9a261d640b5dea51ef2162c3109f1eba8": { + "balance": "0x10f0cf064dd59200000" + }, + "ba70e8b4759c0c3c82cc00ac4e9a94dd5bafb2b8": { + "balance": "0x3043fa33c412d70000" + }, + "ba8a63f3f40de4a88388bc50212fea8e064fbb86": { + "balance": "0x6c6b935b8bbd400000" + }, + "ba8e46d69d2e2343d86c60d82cf42c2041a0c1c2": { + "balance": "0x56bc75e2d63100000" + }, + "baa4b64c2b15b79f5f204246fd70bcbd86e4a92a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "bac8922c4acc7d2cb6fd59a14eb45cf3e702214b": { + "balance": "0x2b5e3af16b18800000" + }, + "bad235d5085dc7b068a67c412677b03e1836884c": { + "balance": "0x6c6b935b8bbd400000" + }, + "bad4425e171c3e72975eb46ac0a015db315a5d8f": { + "balance": "0x6c6b935b8bbd400000" + }, + "badc2aef9f5951a8d78a6b35c3d0b3a4e6e2e739": { + "balance": "0x14542ba12a337c00000" + }, + "bade43599e02f84f4c3014571c976b13a36c65ab": { + "balance": "0xd8d726b7177a800000" + }, + "bae9b82f7299631408659dd74e891cb8f3860fe5": { + "balance": "0x6acb3df27e1f880000" + }, + "bb0366a7cfbd3445a70db7fe5ae34885754fd468": { + "balance": "0x14def2c42ebd6400000" + }, + "bb076aac92208069ea318a31ff8eeb14b7e996e3": { + "balance": "0x813ca56906d340000" + }, + "bb0857f1c911b24b86c8a70681473fe6aaa1cce2": { + "balance": "0x56bc75e2d63100000" + }, + "bb19bf91cbad74cceb5f811db27e411bc2ea0656": { + "balance": "0xf43fc2c04ee00000" + }, + "bb27c6a7f91075475ab229619040f804c8ec7a6a": { + "balance": "0x21e19e0c9bab2400000" + }, + "bb371c72c9f0316cea2bd9c6fbb4079e775429ef": { + "balance": "0x5f68e8131ecf800000" + }, + "bb3b010b18e6e2be1135871026b7ba15ea0fde24": { + "balance": "0x2207c80309b77700000" + }, + "bb3b9005f46fd2ca3b30162599928c77d9f6b601": { + "balance": "0x1b1ae7f2b1bf7db0000" + }, + "bb3fc0a29c034d710812dcc775c8cab9d28d6975": { + "balance": "0x39d4e844d1cf5f0000" + }, + "bb48eaf516ce2dec3e41feb4c679e4957641164f": { + "balance": "0xcf152640c5c8300000" + }, + "bb4b4a4b548070ff41432c9e08a0ca6fa7bc9f76": { + "balance": "0x2e141ea081ca080000" + }, + "bb56a404723cff20d0685488b05a02cdc35aacaa": { + "balance": "0x1158e460913d00000" + }, + "bb618e25221ad9a740b299ed1406bc3934b0b16d": { + "balance": "0x3635c9adc5dea00000" + }, + "bb61a04bffd57c10470d45c39103f64650347616": { + "balance": "0x3635c9adc5dea00000" + }, + "bb6823a1bd819f13515538264a2de052b4442208": { + "balance": "0x16368ff4ff9c10000" + }, + "bb6c284aac8a69b75cddb00f28e145583b56bece": { + "balance": "0x6c6b935b8bbd400000" + }, + "bb75cb5051a0b0944b4673ca752a97037f7c8c15": { + "balance": "0xad78ebc5ac6200000" + }, + "bb993b96ee925ada7d99d786573d3f89180ce3aa": { + "balance": "0x6c6b935b8bbd400000" + }, + "bba3c68004248e489573abb2743677066b24c8a7": { + "balance": "0x6c6b935b8bbd400000" + }, + "bba4fac3c42039d828e742cde0efffe774941b39": { + "balance": "0x6c6ad382d4fb610000" + }, + "bba8ab22d2fedbcfc63f684c08afdf1c175090b5": { + "balance": "0x55f29f37e4e3b8000" + }, + "bba976f1a1215f7512871892d45f7048acd356c8": { + "balance": "0x6c6b935b8bbd400000" + }, + "bbab000b0408ed015a37c04747bc461ab14e151b": { + "balance": "0x14542ba12a337c00000" + }, + "bbabf6643beb4bd01c120bd0598a0987d82967d1": { + "balance": "0xb5328178ad0f2a0000" + }, + "bbb4ee1d82f2e156442cc93338a2fc286fa28864": { + "balance": "0x4a4491bd6dcd280000" + }, + "bbb5a0f4802c8648009e8a6998af352cde87544f": { + "balance": "0x52d542804f1ce0000" + }, + "bbb643d2187b364afc10a6fd368d7d55f50d1a3c": { + "balance": "0x3635c9adc5dea00000" + }, + "bbb8ffe43f98de8eae184623ae5264e424d0b8d7": { + "balance": "0x5d53ffde928080000" + }, + "bbbd6ecbb5752891b4ceb3cce73a8f477059376f": { + "balance": "0x1f399b1438a100000" + }, + "bbbf39b1b67995a42241504f9703d2a14a515696": { + "balance": "0x55a6e79ccd1d300000" + }, + "bbc8eaff637e94fcc58d913c7770c88f9b479277": { + "balance": "0xad78ebc5ac6200000" + }, + "bbc9d8112e5beb02dd29a2257b1fe69b3536a945": { + "balance": "0x6c6b935b8bbd400000" + }, + "bbca65b3266ea2fb73a03f921635f912c7bede00": { + "balance": "0x6acb3df27e1f880000" + }, + "bbf84292d954acd9e4072fb860b1504106e077ae": { + "balance": "0x5150ae84a8cdf00000" + }, + "bbf85aaaa683738f073baef44ac9dc34c4c779ea": { + "balance": "0x6c6b935b8bbd400000" + }, + "bbf8616d97724af3def165d0e28cda89b800009a": { + "balance": "0x62ef12e2b17618000" + }, + "bbfe0a830cace87b7293993a7e9496ce64f8e394": { + "balance": "0x14542ba12a337c00000" + }, + "bc0ca4f217e052753614d6b019948824d0d8688b": { + "balance": "0x15af1d78b58c400000" + }, + "bc0e8745c3a549445c2be900f52300804ab56289": { + "balance": "0x7029bf5dd4c53b28000" + }, + "bc0f98598f88056a26339620923b8f1eb074a9fd": { + "balance": "0xad78ebc5ac6200000" + }, + "bc1609d685b76b48ec909aa099219022f89b2ccd": { + "balance": "0x40138b917edfb80000" + }, + "bc171e53d17ac9b61241ae436deec7af452e7496": { + "balance": "0x121ea68c114e5100000" + }, + "bc1b021a78fde42d9b5226d6ec26e06aa3670090": { + "balance": "0x4563918244f400000" + }, + "bc1e80c181616342ebb3fb3992072f1b28b802c6": { + "balance": "0xd8d726b7177a800000" + }, + "bc237148d30c13836ffa2cad520ee4d2e5c4eeff": { + "balance": "0x6acb3df27e1f880000" + }, + "bc46d537cf2edd403565bde733b2e34b215001bd": { + "balance": "0x43c33c1937564800000" + }, + "bc4e471560c99c8a2a4b1b1ad0c36aa6502b7c4b": { + "balance": "0x28a857425466f800000" + }, + "bc62b3096a91e7dc11a1592a293dd2542150d751": { + "balance": "0x3635c9adc5dea00000" + }, + "bc69a0d2a31c3dbf7a9122116901b2bdfe9802a0": { + "balance": "0xa2a15d09519be00000" + }, + "bc6b58364bf7f1951c309e0cba0595201cd73f9a": { + "balance": "0x62401a457e45f80000" + }, + "bc73f7b1ca3b773b34249ada2e2c8a9274cc17c2": { + "balance": "0x6c6b935b8bbd400000" + }, + "bc7afc8477412274fc265df13c054473427d43c6": { + "balance": "0x70c95920ce3250000" + }, + "bc967fe4418c18b99858966d870678dca2b88879": { + "balance": "0x1d9cbdd8d7ed2100000" + }, + "bc999e385c5aebcac8d6f3f0d60d5aa725336d0d": { + "balance": "0x6c6b935b8bbd400000" + }, + "bc9c95dfab97a574cea2aa803b5caa197cef0cff": { + "balance": "0x16c4abbebea0100000" + }, + "bc9e0ec6788f7df4c7fc210aacd220c27e45c910": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "bca3ffd4683fba0ad3bbc90734b611da9cfb457e": { + "balance": "0xad78ebc5ac6200000" + }, + "bcaed0acb6a76f113f7c613555a2c3b0f5bf34a5": { + "balance": "0xa7ebd5e4363a00000" + }, + "bcaf347918efb2d63dde03e39275bbe97d26df50": { + "balance": "0x56bc75e2d63100000" + }, + "bcb422dc4dd2aae94abae95ea45dd1731bb6b0ba": { + "balance": "0x18424f5f0b1b4e0000" + }, + "bcbd31252ec288f91e298cd812c92160e738331a": { + "balance": "0x6b1bc2cac09a590000" + }, + "bcbf6ba166e2340db052ea23d28029b0de6aa380": { + "balance": "0xd255d112e103a00000" + }, + "bcc84597b91e73d5c5b4d69c80ecf146860f779a": { + "balance": "0xed70b5e9c3f2f00000" + }, + "bcc9593b2da6df6a34d71b1aa38dacf876f95b88": { + "balance": "0x1158e460913d00000" + }, + "bcd95ef962462b6edfa10fda87d72242fe3edb5c": { + "balance": "0x121d06e12fff988000" + }, + "bcd99edc2160f210a05e3a1fa0b0434ced00439b": { + "balance": "0x6c6b935b8bbd400000" + }, + "bcdfacb9d9023c3417182e9100e8ea1d373393a3": { + "balance": "0x3342d60dff1960000" + }, + "bce13e22322acfb355cd21fd0df60cf93add26c6": { + "balance": "0xad78ebc5ac6200000" + }, + "bce40475d345b0712dee703d87cd7657fc7f3b62": { + "balance": "0x1a420db02bd7d580000" + }, + "bcedc4267ccb89b31bb764d7211171008d94d44d": { + "balance": "0xad78ebc5ac6200000" + }, + "bcfc98e5c82b6adb180a3fcb120b9a7690c86a3f": { + "balance": "0x6acb3df27e1f880000" + }, + "bd043b67c63e60f841ccca15b129cdfe6590c8e3": { + "balance": "0xad78ebc5ac6200000" + }, + "bd047ff1e69cc6b29ad26497a9a6f27a903fc4dd": { + "balance": "0x2ee449550898e40000" + }, + "bd08e0cddec097db7901ea819a3d1fd9de8951a2": { + "balance": "0x1158e460913d00000" + }, + "bd09126c891c4a83068059fe0e15796c4661a9f4": { + "balance": "0x2b5e3af16b18800000" + }, + "bd0c5cd799ebc48642ef97d74e8e429064fee492": { + "balance": "0x11ac28a8c729580000" + }, + "bd17eed82b9a2592019a1b1b3c0fbad45c408d22": { + "balance": "0xd8d726b7177a80000" + }, + "bd1803370bddb129d239fd16ea8526a6188ae58e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "bd2b70fecc37640f69514fc7f3404946aad86b11": { + "balance": "0x410d586a20a4c00000" + }, + "bd3097a79b3c0d2ebff0e6e86ab0edadbed47096": { + "balance": "0x5a87e7d7f5f6580000" + }, + "bd325d4029e0d8729f6d399c478224ae9e7ae41e": { + "balance": "0xd255d112e103a00000" + }, + "bd432a3916249b4724293af9146e49b8280a7f2a": { + "balance": "0xd8d726b7177a800000" + }, + "bd47f5f76e3b930fd9485209efa0d4763da07568": { + "balance": "0x3635c9adc5dea00000" + }, + "bd4b60faec740a21e3071391f96aa534f7c1f44e": { + "balance": "0x9ddc1e3b901180000" + }, + "bd4bd5b122d8ef7b7c8f0667450320db2116142e": { + "balance": "0x2086ac351052600000" + }, + "bd51ee2ea143d7b1d6b77e7e44bdd7da12f485ac": { + "balance": "0x477e06ccb2b9280000" + }, + "bd59094e074f8d79142ab1489f148e32151f2089": { + "balance": "0x1158e460913d00000" + }, + "bd5a8c94bd8be6470644f70c8f8a33a8a55c6341": { + "balance": "0xad78ebc5ac6200000" + }, + "bd5e473abce8f97a6932f77c2facaf9cc0a00514": { + "balance": "0x3c9258a106a6b70000" + }, + "bd5f46caab2c3d4b289396bbb07f203c4da82530": { + "balance": "0x4563918244f400000" + }, + "bd66ffedb530ea0b2e856dd12ac2296c31fe29e0": { + "balance": "0xad78ebc5ac6200000" + }, + "bd67d2e2f82da8861341bc96a2c0791fddf39e40": { + "balance": "0xad7c07947c8fb0000" + }, + "bd6a474d66345bcdd707594adb63b30c7822af54": { + "balance": "0xd8d726b7177a800000" + }, + "bd723b289a7367b6ece2455ed61edb49670ab9c4": { + "balance": "0x10f0cdea164213f8000" + }, + "bd73c3cbc26a175062ea0320dd84b253bce64358": { + "balance": "0x155bd9307f9fe80000" + }, + "bd7419dc2a090a46e2873d7de6eaaad59e19c479": { + "balance": "0x170bcb671759f080000" + }, + "bd8765f41299c7f479923c4fd18f126d7229047d": { + "balance": "0xd8d726b7177a800000" + }, + "bd93e550403e2a06113ed4c3fba1a8913b19407e": { + "balance": "0x6c6b935b8bbd400000" + }, + "bd9e56e902f4be1fc8768d8038bac63e2acbbf8e": { + "balance": "0x36356633ebd8ea0000" + }, + "bda4be317e7e4bed84c0495eee32d607ec38ca52": { + "balance": "0x7d32277978ef4e8000" + }, + "bdb60b823a1173d45a0792245fb496f1fd3301cf": { + "balance": "0x6c6b935b8bbd400000" + }, + "bdbaf6434d40d6355b1e80e40cc4ab9c68d96116": { + "balance": "0x56bc75e2d63100000" + }, + "bdc02cd4330c93d6fbda4f6db2a85df22f43c233": { + "balance": "0x6c6b935b8bbd400000" + }, + "bdc461462b6322b462bdb33f22799e8108e2417d": { + "balance": "0x243d4d18229ca20000" + }, + "bdc739a699700b2e8e2c4a4c7b058a0e513ddebe": { + "balance": "0x6c6b935b8bbd400000" + }, + "bdc74873af922b9df474853b0fa7ff0bf8c82695": { + "balance": "0xd8c9460063d31c0000" + }, + "bdca2a0ff34588af625fa8e28fc3015ab5a3aa00": { + "balance": "0x7ed73f773552fc0000" + }, + "bdd3254e1b3a6dc6cc2c697d45711aca21d516b2": { + "balance": "0x6c6b935b8bbd400000" + }, + "bddfa34d0ebf1b04af53b99b82494a9e3d8aa100": { + "balance": "0x28a857425466f800000" + }, + "bde4c73f969b89e9ceae66a2b51844480e038e9a": { + "balance": "0x3635c9adc5dea00000" + }, + "bde9786a84e75b48f18e726dd78d70e4af3ed802": { + "balance": "0x1369fb96128ac480000" + }, + "bded11612fb5c6da99d1e30e320bc0995466141e": { + "balance": "0x15af1d78b58c400000" + }, + "bded7e07d0711e684de65ac8b2ab57c55c1a8645": { + "balance": "0x2009c5c8bf6fdc0000" + }, + "bdf693f833c3fe471753184788eb4bfe4adc3f96": { + "balance": "0x6acb3df27e1f880000" + }, + "bdf6e68c0cd7584080e847d72cbb23aad46aeb1d": { + "balance": "0x6acb3df27e1f880000" + }, + "be0a2f385f09dbfce96732e12bb40ac349871ba8": { + "balance": "0x574c115e02b8be0000" + }, + "be0c2a80b9de084b172894a76cf4737a4f529e1a": { + "balance": "0x6c6acc67d7b1d40000" + }, + "be1cd7f4c472070968f3bde268366b21eeea8321": { + "balance": "0xe91a7cd19fa3b00000" + }, + "be2346a27ff9b702044f500deff2e7ffe6824541": { + "balance": "0x1158e460913d00000" + }, + "be2471a67f6047918772d0e36839255ed9d691ae": { + "balance": "0xd8d726b7177a800000" + }, + "be2b2280523768ea8ac35cd9e888d60a719300d4": { + "balance": "0x6c6b935b8bbd400000" + }, + "be2b326e78ed10e550fee8efa8f8070396522f5a": { + "balance": "0x857e0d6f1da76a00000" + }, + "be305a796e33bbf7f9aeae6512959066efda1010": { + "balance": "0x24dce54d34a1a000000" + }, + "be478e8e3dde6bd403bb2d1c657c4310ee192723": { + "balance": "0x1ab2cf7c9f87e20000" + }, + "be4e7d983f2e2a636b1102ec7039efebc842e98d": { + "balance": "0x393ef1a5127c80000" + }, + "be4fd073617022b67f5c13499b827f763639e4e3": { + "balance": "0x6c6b935b8bbd400000" + }, + "be525a33ea916177f17283fca29e8b350b7f530b": { + "balance": "0x8f019aaf46e8780000" + }, + "be53322f43fbb58494d7cce19dda272b2450e827": { + "balance": "0xad7ceaf425c150000" + }, + "be538246dd4e6f0c20bf5ad1373c3b463a131e86": { + "balance": "0xad78ebc5ac6200000" + }, + "be5a60689998639ad75bc105a371743eef0f7940": { + "balance": "0x1b327c73e1257a0000" + }, + "be5cba8d37427986e8ca2600e858bb03c359520f": { + "balance": "0xa030dcebbd2f4c0000" + }, + "be60037e90714a4b917e61f193d834906703b13a": { + "balance": "0x5c283d410394100000" + }, + "be633a3737f68439bac7c90a52142058ee8e8a6f": { + "balance": "0x340aad21b3b7000000" + }, + "be659d85e7c34f8833ea7f488de1fbb5d4149bef": { + "balance": "0x1ebd23ad9d5bb720000" + }, + "be73274d8c5aa44a3cbefc8263c37ba121b20ad3": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "be86d0b0438419ceb1a038319237ba5206d72e46": { + "balance": "0x3634fb9f1489a70000" + }, + "be8d7f18adfe5d6cc775394989e1930c979d007d": { + "balance": "0x3635c9adc5dea00000" + }, + "be9186c34a52514abb9107860f674f97b821bd5b": { + "balance": "0x1ba01ee40603100000" + }, + "be935793f45b70d8045d2654d8dd3ad24b5b6137": { + "balance": "0x2fb474098f67c00000" + }, + "be98a77fd41097b34f59d7589baad021659ff712": { + "balance": "0x30ca024f987b900000" + }, + "be9b8c34b78ee947ff81472eda7af9d204bc8466": { + "balance": "0x821ab0d4414980000" + }, + "bea00df17067a43a82bc1daecafb6c14300e89e6": { + "balance": "0x62a992e53a0af00000" + }, + "bea0afc93aae2108a3fac059623bf86fa582a75e": { + "balance": "0x5c283d410394100000" + }, + "beb3358c50cf9f75ffc76d443c2c7f55075a0589": { + "balance": "0x90f534608a72880000" + }, + "beb4fd315559436045dcb99d49dcec03f40c42dc": { + "balance": "0x6c6b935b8bbd400000" + }, + "bec2e6de39c07c2bae556acfbee2c4728b9982e3": { + "balance": "0x1f0ff8f01daad40000" + }, + "bec6640f4909b58cbf1e806342961d607595096c": { + "balance": "0x6c6acc67d7b1d40000" + }, + "bec8caf7ee49468fee552eff3ac5234eb9b17d42": { + "balance": "0x6c6b935b8bbd400000" + }, + "becef61c1c442bef7ce04b73adb249a8ba047e00": { + "balance": "0x363b56c3a754c80000" + }, + "bed4649df646e2819229032d8868556fe1e053d3": { + "balance": "0xfc936392801c0000" + }, + "bed4c8f006a27c1e5f7ce205de75f516bfb9f764": { + "balance": "0x3635c9adc5dea000000" + }, + "bee8d0b008421954f92d000d390fb8f8e658eaee": { + "balance": "0x3635c9adc5dea00000" + }, + "beecd6af900c8b064afcc6073f2d85d59af11956": { + "balance": "0x6c6b935b8bbd400000" + }, + "beef94213879e02622142bea61290978939a60d7": { + "balance": "0x136857b32ad86048000" + }, + "bef07d97c3481f9d6aee1c98f9d91a180a32442b": { + "balance": "0x152d02c7e14af6800000" + }, + "befb448c0c5f683fb67ee570baf0db5686599751": { + "balance": "0x6acb3df27e1f880000" + }, + "bf05070c2c34219311c4548b2614a438810ded6d": { + "balance": "0x6c6b935b8bbd400000" + }, + "bf05ff5ecf0df2df887759fb8274d93238ac267d": { + "balance": "0x2b5e3af16b18800000" + }, + "bf09d77048e270b662330e9486b38b43cd781495": { + "balance": "0x5c539b7bf4ff28800000" + }, + "bf17f397f8f46f1bae45d187148c06eeb959fa4d": { + "balance": "0x3649c59624bb300000" + }, + "bf183641edb886ce60b8190261e14f42d93cce01": { + "balance": "0x15b3557f1937f8000" + }, + "bf2aea5a1dcf6ed3b5e8323944e983fedfd1acfb": { + "balance": "0x55a6e79ccd1d300000" + }, + "bf4096bc547dbfc4e74809a31c039e7b389d5e17": { + "balance": "0xd5967be4fc3f100000" + }, + "bf49c14898316567d8b709c2e50594b366c6d38c": { + "balance": "0x27bf38c6544df50000" + }, + "bf4c73a7ede7b164fe072114843654e4d8781dde": { + "balance": "0x6c6b935b8bbd400000" + }, + "bf50ce2e264b9fe2b06830617aedf502b2351b45": { + "balance": "0x3635c9adc5dea00000" + }, + "bf59aee281fa43fe97194351a9857e01a3b897b2": { + "balance": "0x2086ac351052600000" + }, + "bf68d28aaf1eeefef646b65e8cc8d190f6c6da9c": { + "balance": "0x6c6b935b8bbd400000" + }, + "bf6925c00751008440a6739a02bf2b6cdaab5e3a": { + "balance": "0x3635c9adc5dea00000" + }, + "bf7701fc6225d5a17815438a8941d21ebc5d059d": { + "balance": "0x65ea3db75546600000" + }, + "bf8b8005d636a49664f74275ef42438acd65ac91": { + "balance": "0xad78ebc5ac6200000" + }, + "bf92418a0c6c31244d220260cb3e867dd7b4ef49": { + "balance": "0x56900d33ca7fc0000" + }, + "bf9acd4445d9c9554689cabbbab18800ff1741c2": { + "balance": "0x3635c9adc5dea00000" + }, + "bf9f271f7a7e12e36dd2fe9facebf385fe6142bd": { + "balance": "0x366f84f7bb7840000" + }, + "bfa8c858df102cb12421008b0a31c4c7190ad560": { + "balance": "0xad78ebc5ac6200000" + }, + "bfaeb91067617dcf8b44172b02af615674835dba": { + "balance": "0x8b59e884813088000" + }, + "bfb0ea02feb61dec9e22a5070959330299c43072": { + "balance": "0x43c33c1937564800000" + }, + "bfbca418d3529cb393081062032a6e1183c6b2dc": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "bfbe05e88c9cbbcc0e92a405fac1d85de248ee24": { + "balance": "0x56bc75e2d63100000" + }, + "bfbfbcb656c2992be8fcde8219fbc54aadd59f29": { + "balance": "0x21e18d2c821c7520000" + }, + "bfc57aa666fae28e9f107a49cb5089a4e22151dd": { + "balance": "0x3635c9adc5dea00000" + }, + "bfcb9730246304700da90b4153e71141622e1c41": { + "balance": "0x3635c9adc5dea00000" + }, + "bfd93c90c29c07bc5fb5fc49aeea55a40e134f35": { + "balance": "0x5ede20f01a459800000" + }, + "bfe3a1fc6e24c8f7b3250560991f93cba2cf8047": { + "balance": "0x10f0cf064dd592000000" + }, + "bfe6bcb0f0c07852643324aa5df5fd6225abc3ca": { + "balance": "0x409e52b48369a0000" + }, + "bff5df769934b8943ca9137d0efef2fe6ebbb34e": { + "balance": "0x56bc75e2d63100000" + }, + "bffb6929241f788693273e7022e60e3eab1fe84f": { + "balance": "0x6c6b935b8bbd400000" + }, + "c0064f1d9474ab915d56906c9fb320a2c7098c9b": { + "balance": "0x13683f7f3c15d80000" + }, + "c007f0bdb6e7009202b7af3ea90902697c721413": { + "balance": "0xa2a0e43e7fb9830000" + }, + "c00ab080b643e1c2bae363e0d195de2efffc1c44": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c02077449a134a7ad1ef7e4d927affeceeadb5ae": { + "balance": "0xfc936392801c0000" + }, + "c02471e3fc2ea0532615a7571d493289c13c36ef": { + "balance": "0x1158e460913d00000" + }, + "c02d6eadeacf1b78b3ca85035c637bb1ce01f490": { + "balance": "0xd8d726b7177a800000" + }, + "c033b1325a0af45472c25527853b1f1c21fa35de": { + "balance": "0x6c6b935b8bbd400000" + }, + "c033be10cb48613bd5ebcb33ed4902f38b583003": { + "balance": "0xa2a15d09519be00000" + }, + "c0345b33f49ce27fe82cf7c84d141c68f590ce76": { + "balance": "0x3635c9adc5dea00000" + }, + "c03de42a109b657a64e92224c08dc1275e80d9b2": { + "balance": "0x1158e460913d00000" + }, + "c04069dfb18b096c7867f8bee77a6dc7477ad062": { + "balance": "0x90f534608a72880000" + }, + "c0413f5a7c2d9a4b8108289ef6ecd271781524f4": { + "balance": "0xa968163f0a57b400000" + }, + "c043f2452dcb9602ef62bd360e033dd23971fe84": { + "balance": "0x6c6b935b8bbd400000" + }, + "c04f4bd4049f044685b883b62959ae631d667e35": { + "balance": "0x13b80b99c5185700000" + }, + "c056d4bd6bf3cbacac65f8f5a0e3980b852740ae": { + "balance": "0x56bc75e2d63100000" + }, + "c05b740620f173f16e52471dc38b9c514a0b1526": { + "balance": "0x796e3ea3f8ab00000" + }, + "c069ef0eb34299abd2e32dabc47944b272334824": { + "balance": "0x68155a43676e00000" + }, + "c06cebbbf7f5149a66f7eb976b3e47d56516da2f": { + "balance": "0x6c6b935b8bbd400000" + }, + "c0725ec2bdc33a1d826071dea29d62d4385a8c25": { + "balance": "0x8a08513463aa6100000" + }, + "c07e3867ada096807a051a6c9c34cc3b3f4ad34a": { + "balance": "0x60f06620a849450000" + }, + "c0895efd056d9a3a81c3da578ada311bfb9356cf": { + "balance": "0xad78ebc5ac6200000" + }, + "c090fe23dcd86b358c32e48d2af91024259f6566": { + "balance": "0xad78ebc5ac6200000" + }, + "c09a66172aea370d9a63da04ff71ffbbfcff7f94": { + "balance": "0x6c6b935b8bbd400000" + }, + "c09e3cfc19f605ff3ec9c9c70e2540d7ee974366": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c0a02ab94ebe56d045b41b629b98462e3a024a93": { + "balance": "0x56bc75e2d63100000" + }, + "c0a39308a80e9e84aaaf16ac01e3b01d74bd6b2d": { + "balance": "0x7664ddd4c1c0b8000" + }, + "c0a6cbad77692a3d88d141ef769a99bb9e3c9951": { + "balance": "0x56bc75e2d63100000" + }, + "c0a7e8435dff14c25577739db55c24d5bf57a3d9": { + "balance": "0xa6dd90cae5114480000" + }, + "c0ae14d724832e2fce2778de7f7b8daf7b12a93e": { + "balance": "0x1158e460913d00000" + }, + "c0afb7d8b79370cfd663c68cc6b9702a37cd9eff": { + "balance": "0x3635c9adc5dea00000" + }, + "c0b0b7a8a6e1acdd05e47f94c09688aa16c7ad8d": { + "balance": "0x37b6d02ac76710000" + }, + "c0b3f244bca7b7de5b48a53edb9cbeab0b6d88c0": { + "balance": "0x13b80b99c5185700000" + }, + "c0c04d0106810e3ec0e54a19f2ab8597e69a573d": { + "balance": "0x2b5e3af16b1880000" + }, + "c0ca3277942e7445874be31ceb902972714f1823": { + "balance": "0xd8d726b7177a80000" + }, + "c0cbad3ccdf654da22cbcf5c786597ca1955c115": { + "balance": "0x6c6b935b8bbd400000" + }, + "c0cbf6032fa39e7c46ff778a94f7d445fe22cf30": { + "balance": "0x10ce1d3d8cb3180000" + }, + "c0e0b903088e0c63f53dd069575452aff52410c3": { + "balance": "0xa2a15d09519be00000" + }, + "c0e457bd56ec36a1246bfa3230fff38e5926ef22": { + "balance": "0x692ae8897081d00000" + }, + "c0ed0d4ad10de03435b153a0fc25de3b93f45204": { + "balance": "0xab4dcf399a3a600000" + }, + "c0f29ed0076611b5e55e130547e68a48e26df5e4": { + "balance": "0xa2a15d09519be00000" + }, + "c1132878235c5ddba5d9f3228b5236e47020dc6f": { + "balance": "0x3635c9adc5dea00000" + }, + "c1170dbaadb3dee6198ea544baec93251860fda5": { + "balance": "0x410d586a20a4c00000" + }, + "c126573d87b0175a5295f1dd07c575cf8cfa15f2": { + "balance": "0x21e19e0c9bab2400000" + }, + "c127aab59065a28644a56ba3f15e2eac13da2995": { + "balance": "0x2086ac351052600000" + }, + "c12b7f40df9a2f7bf983661422ab84c9c1f50858": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "c12cfb7b3df70fceca0ede263500e27873f8ed16": { + "balance": "0x3635c9adc5dea00000" + }, + "c12f881fa112b8199ecbc73ec4185790e614a20f": { + "balance": "0x6c6b935b8bbd400000" + }, + "c1384c6e717ebe4b23014e51f31c9df7e4e25b31": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c1438c99dd51ef1ca8386af0a317e9b041457888": { + "balance": "0xc1daf81d8a3ce0000" + }, + "c1631228efbf2a2e3a4092ee8900c639ed34fbc8": { + "balance": "0x33c5499031720c0000" + }, + "c175be3194e669422d15fee81eb9f2c56c67d9c9": { + "balance": "0xad78ebc5ac6200000" + }, + "c1827686c0169485ec15b3a7c8c01517a2874de1": { + "balance": "0x22b1c8c1227a00000" + }, + "c18ab467feb5a0aadfff91230ff056464d78d800": { + "balance": "0x6c6b935b8bbd400000" + }, + "c1950543554d8a713003f662bb612c10ad4cdf21": { + "balance": "0xfc936392801c0000" + }, + "c1a41a5a27199226e4c7eb198b031b59196f9842": { + "balance": "0xa5aa85009e39c0000" + }, + "c1b2a0fb9cad45cd699192cd27540b88d3384279": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c1b2aa8cb2bf62cdc13a47ecc4657facaa995f98": { + "balance": "0x363793fa96e6a68000" + }, + "c1b500011cfba95d7cd636e95e6cbf6167464b25": { + "balance": "0xad78ebc5ac6200000" + }, + "c1b9a5704d351cfe983f79abeec3dbbbae3bb629": { + "balance": "0x1158e460913d00000" + }, + "c1cbd2e2332a524cf219b10d871ccc20af1fb0fa": { + "balance": "0x3635c9adc5dea00000" + }, + "c1cdc601f89c0428b31302d187e0dc08ad7d1c57": { + "balance": "0x14542ba12a337c00000" + }, + "c1d4af38e9ba799040894849b8a8219375f1ac78": { + "balance": "0x43c33c1937564800000" + }, + "c1e1409ca52c25435134d006c2a6a8542dfb7273": { + "balance": "0x1dd1e4bd8d1ee0000" + }, + "c1eba5684aa1b24cba63150263b7a9131aeec28d": { + "balance": "0x1158e460913d00000" + }, + "c1ec81dd123d4b7c2dd9b4d438a7072c11dc874c": { + "balance": "0x6c6b935b8bbd400000" + }, + "c1f39bd35dd9cec337b96f47c677818160df37b7": { + "balance": "0x1158e460913d00000" + }, + "c1ffad07db96138c4b2a530ec1c7de29b8a0592c": { + "balance": "0xf43fc2c04ee00000" + }, + "c21fa6643a1f14c02996ad7144b75926e87ecb4b": { + "balance": "0x43c33c1937564800000" + }, + "c2340a4ca94c9678b7494c3c852528ede5ee529f": { + "balance": "0x2a36b05a3fd7c8000" + }, + "c239abdfae3e9af5457f52ed2b91fd0ab4d9c700": { + "balance": "0x6c6b935b8bbd400000" + }, + "c23b2f921ce4a37a259ee4ad8b2158d15d664f59": { + "balance": "0x1608995e8bd3f8000" + }, + "c24399b4bf86f7338fbf645e3b22b0e0b7973912": { + "balance": "0x6c6b935b8bbd400000" + }, + "c24ccebc2344cce56417fb684cf81613f0f4b9bd": { + "balance": "0x54069233bf7f780000" + }, + "c25266c7676632f13ef29be455ed948add567792": { + "balance": "0x487a9a304539440000" + }, + "c25cf826550c8eaf10af2234fef904ddb95213be": { + "balance": "0x3635c9adc5dea00000" + }, + "c2663f8145dbfec6c646fc5c49961345de1c9f11": { + "balance": "0x2567ac70392b880000" + }, + "c270456885342b640b4cfc1b520e1a544ee0d571": { + "balance": "0x62a992e53a0af00000" + }, + "c27376f45d21e15ede3b26f2655fcee02ccc0f2a": { + "balance": "0x1158e460913d00000" + }, + "c2779771f0536d79a8708f6931abc44b3035e999": { + "balance": "0x43c4f8300dcb3480000" + }, + "c27f4e08099d8cf39ee11601838ef9fc06d7fc41": { + "balance": "0x61093d7c2c6d380000" + }, + "c282e6993fbe7a912ea047153ffd9274270e285b": { + "balance": "0x7960b331247638000" + }, + "c2836188d9a29253e0cbda6571b058c289a0bb32": { + "balance": "0x6c6b935b8bbd400000" + }, + "c2aa74847e86edfdd3f3db22f8a2152feee5b7f7": { + "balance": "0x6f118886b784a20000" + }, + "c2b2cbe65bc6c2ee7a3c75b2e47c189c062e8d8b": { + "balance": "0x43c33c1937564800000" + }, + "c2bae4a233c2d85724f0dabebda0249d833e37d3": { + "balance": "0x10f0cf064dd59200000" + }, + "c2c13e72d268e7150dc799e7c6cf03c88954ced7": { + "balance": "0x25f273933db5700000" + }, + "c2cb1ada5da9a0423873814793f16144ef36b2f3": { + "balance": "0x48557e3b7017df0000" + }, + "c2d1778ef6ee5fe488c145f3586b6ebbe3fbb445": { + "balance": "0x3e1ff1e03b55a80000" + }, + "c2d9eedbc9019263d9d16cc5ae072d1d3dd9db03": { + "balance": "0x43c33c1937564800000" + }, + "c2e0584a71348cc314b73b2029b6230b92dbb116": { + "balance": "0x6c6b935b8bbd400000" + }, + "c2e2d498f70dcd0859e50b023a710a6d4b2133bd": { + "balance": "0x383911f00cbce10000" + }, + "c2ed5ffdd1add855a2692fe062b5d618742360d4": { + "balance": "0x410d586a20a4c00000" + }, + "c2ee91d3ef58c9d1a589844ea1ae3125d6c5ba69": { + "balance": "0x34957444b840e80000" + }, + "c2fafdd30acb6d6706e9293cb02641f9edbe07b5": { + "balance": "0x5100860b430f480000" + }, + "c2fd0bf7c725ef3e047e5ae1c29fe18f12a7299c": { + "balance": "0x487a9a304539440000" + }, + "c2fe7d75731f636dcd09dbda0671393ba0c82a7d": { + "balance": "0x77432217e683600000" + }, + "c3107a9af3322d5238df0132419131629539577d": { + "balance": "0x1ab4e464d414310000" + }, + "c3110be01dc9734cfc6e1ce07f87d77d1345b7e1": { + "balance": "0x10f0ce949e00f930000" + }, + "c32038ca52aee19745be5c31fcdc54148bb2c4d0": { + "balance": "0x2b5aad72c65200000" + }, + "c325c352801ba883b3226c5feb0df9eae2d6e653": { + "balance": "0xd5967be4fc3f100000" + }, + "c32ec7e42ad16ce3e2555ad4c54306eda0b26758": { + "balance": "0x6c6b935b8bbd400000" + }, + "c332df50b13c013490a5d7c75dbfa366da87b6d6": { + "balance": "0xd8d726b7177a800000" + }, + "c33acdb3ba1aab27507b86b15d67faf91ecf6293": { + "balance": "0x6c6b935b8bbd400000" + }, + "c33ece935a8f4ef938ea7e1bac87cb925d8490ca": { + "balance": "0x7038c16781f78480000" + }, + "c340f9b91c26728c31d121d5d6fc3bb56d3d8624": { + "balance": "0x6c6b935b8bbd400000" + }, + "c346cb1fbce2ab285d8e5401f42dd7234d37e86d": { + "balance": "0x486cb9799191e0000" + }, + "c3483d6e88ac1f4ae73cc4408d6c03abe0e49dca": { + "balance": "0x39992648a23c8a00000" + }, + "c348fc5a461323b57be303cb89361b991913df28": { + "balance": "0x152d02c7e14af6800000" + }, + "c34e3ba1322ed0571183a24f94204ee49c186641": { + "balance": "0x327afefa4a7bc0000" + }, + "c35b95a2a3737cb8f0f596b34524872bd30da234": { + "balance": "0x198be85235e2d500000" + }, + "c3631c7698b6c5111989bf452727b3f9395a6dea": { + "balance": "0x243275896641dbe0000" + }, + "c36c0b63bfd75c2f8efb060883d868cccd6cbdb4": { + "balance": "0xa2a15d09519be00000" + }, + "c3756bcdcc7eec74ed896adfc335275930266e08": { + "balance": "0x14542ba12a337c00000" + }, + "c384ac6ee27c39e2f278c220bdfa5baed626d9d3": { + "balance": "0x2086ac351052600000" + }, + "c3a046e3d2b2bf681488826e32d9c061518cfe8c": { + "balance": "0x8cf23f909c0fa00000" + }, + "c3a9226ae275df2cab312b911040634a9c9c9ef6": { + "balance": "0xd8d726b7177a800000" + }, + "c3b928a76fad6578f04f0555e63952cd21d1520a": { + "balance": "0x6c6b935b8bbd400000" + }, + "c3c2297329a6fd99117e54fc6af379b4d556547e": { + "balance": "0x14542ba12a337c00000" + }, + "c3c3c2510d678020485a63735d1307ec4ca6302b": { + "balance": "0x3635c9adc5dea00000" + }, + "c3cb6b36af443f2c6e258b4a39553a818747811f": { + "balance": "0x57473d05dabae80000" + }, + "c3db5657bb72f10d58f231fddf11980aff678693": { + "balance": "0x14061b9d77a5e980000" + }, + "c3db9fb6f46c480af34465d79753b4e2b74a67ce": { + "balance": "0x43c33c1937564800000" + }, + "c3dd58903886303b928625257ae1a013d71ae216": { + "balance": "0x6c6b935b8bbd400000" + }, + "c3e0471c64ff35fa5232cc3121d1d38d1a0fb7de": { + "balance": "0x6c6b935b8bbd400000" + }, + "c3e20c96df8d4e38f50b265a98a906d61bc51a71": { + "balance": "0x6c6b935b8bbd400000" + }, + "c3e387b03ce95ccfd7fa51dd840183bc43532809": { + "balance": "0x6c6b935b8bbd400000" + }, + "c3f8f67295a5cd049364d05d23502623a3e52e84": { + "balance": "0x14542ba12a337c00000" + }, + "c401c427cccff10decb864202f36f5808322a0a8": { + "balance": "0xb47b51a69cd4020000" + }, + "c4088c025f3e85013f5439fb3440a17301e544fe": { + "balance": "0x7e09db4d9f3f340000" + }, + "c41461a3cfbd32c9865555a4813137c076312360": { + "balance": "0x3635c6204739d98000" + }, + "c420388fbee84ad656dd68cdc1fbaa9392780b34": { + "balance": "0xa2dca63aaf4c58000" + }, + "c42250b0fe42e6b7dcd5c890a6f0c88f5f5fb574": { + "balance": "0x81ee4825359840000" + }, + "c42d6aeb710e3a50bfb44d6c31092969a11aa7f3": { + "balance": "0x82263cafd8cea0000" + }, + "c440c7ca2f964b6972ef664a2261dde892619d9c": { + "balance": "0x43c33c1937564800000" + }, + "c44bdec8c36c5c68baa2ddf1d431693229726c43": { + "balance": "0x152d02c7e14af6800000" + }, + "c44f4ab5bc60397c737eb0683391b633f83c48fa": { + "balance": "0x3635c9adc5dea00000" + }, + "c452e0e4b3d6ae06b836f032ca09db409ddfe0fb": { + "balance": "0x2b5e3af16b18800000" + }, + "c45a1ca1036b95004187cdac44a36e33a94ab5c3": { + "balance": "0xdd00f720301880000" + }, + "c45d47ab0c9aa98a5bd62d16223ea2471b121ca4": { + "balance": "0x202e68f2c2aee40000" + }, + "c4681e73bb0e32f6b726204831ff69baa4877e32": { + "balance": "0x62a992e53a0af00000" + }, + "c46bbdef76d4ca60d316c07f5d1a780e3b165f7e": { + "balance": "0x6c6b935b8bbd400000" + }, + "c47d610b399250f70ecf1389bab6292c91264f23": { + "balance": "0xfa7e7b5df3cd00000" + }, + "c4803bb407c762f90b7596e6fde194931e769590": { + "balance": "0xd8d726b7177a800000" + }, + "c48651c1d9c16bff4c9554886c3f3f26431f6f68": { + "balance": "0x23ab9599c43f080000" + }, + "c489c83ffbb0252ac0dbe3521217630e0f491f14": { + "balance": "0xd8d726b7177a800000" + }, + "c48b693cacefdbd6cb5d7895a42e3196327e261c": { + "balance": "0x3635c9adc5dea00000" + }, + "c493489e56c3bdd829007dc2f956412906f76bfa": { + "balance": "0x2a791488e71540000" + }, + "c496cbb0459a6a01600fc589a55a32b454217f9d": { + "balance": "0xeda838c4929080000" + }, + "c49cfaa967f3afbf55031061fc4cef88f85da584": { + "balance": "0x6c6b935b8bbd400000" + }, + "c4b6e5f09cc1b90df07803ce3d4d13766a9c46f4": { + "balance": "0x14542ba12a337c00000" + }, + "c4bec96308a20f90cab18399c493fd3d065abf45": { + "balance": "0x2f6f10780d22cc00000" + }, + "c4c01afc3e0f045221da1284d7878574442fb9ac": { + "balance": "0x1923c688b73ab040000" + }, + "c4c15318d370c73318cc18bdd466dbaa4c6603bf": { + "balance": "0x11164759ffb320000" + }, + "c4c6cb723dd7afa7eb535615e53f3cef14f18118": { + "balance": "0x6c6b8fce0d18798000" + }, + "c4cc45a2b63c27c0b4429e58cd42da59be739bd6": { + "balance": "0x3635c9adc5dea00000" + }, + "c4cf930e5d116ab8d13b9f9a7ec4ab5003a6abde": { + "balance": "0x1158e460913d000000" + }, + "c4d916574e68c49f7ef9d3d82d1638b2b7ee0985": { + "balance": "0x55a6e79ccd1d300000" + }, + "c4dac5a8a0264fbc1055391c509cc3ee21a6e04c": { + "balance": "0x1606b7fa039ce740000" + }, + "c4dd048bfb840e2bc85cb53fcb75abc443c7e90f": { + "balance": "0xc971dc07c9c7900000" + }, + "c4f2913b265c430fa1ab8adf26c333fc1d9b66f2": { + "balance": "0x1158e460913d00000" + }, + "c4f7b13ac6d4eb4db3d4e6a252af8a07bd5957da": { + "balance": "0xad78ebc5ac6200000" + }, + "c4f7d2e2e22084c44f70feaab6c32105f3da376f": { + "balance": "0x6acb3df27e1f880000" + }, + "c4ff6fbb1f09bd9e102ba033d636ac1c4c0f5304": { + "balance": "0x3635c9adc5dea00000" + }, + "c4ffadaaf2823fbea7bff702021bffc4853eb5c9": { + "balance": "0x24a19c1bd6f128000" + }, + "c500b720734ed22938d78c5e48b2ba9367a575ba": { + "balance": "0x7129e1cdf373ee00000" + }, + "c50fe415a641b0856c4e75bf960515441afa358d": { + "balance": "0x6c6b935b8bbd400000" + }, + "c5134cfbb1df7a20b0ed7057622eeed280947dad": { + "balance": "0xcdff97fabcb4600000" + }, + "c517d0315c878813c717e18cafa1eab2654e01da": { + "balance": "0x21e19e0c9bab2400000" + }, + "c518799a5925576213e21896e0539abb85b05ae3": { + "balance": "0x3635c9adc5dea00000" + }, + "c522e20fbf04ed7f6b05a37b4718d6fce0142e1a": { + "balance": "0xd8d726b7177a800000" + }, + "c524086d46c8112b128b2faf6f7c7d8160a8386c": { + "balance": "0x15af1d78b58c400000" + }, + "c52d1a0c73c2a1be84915185f8b34faa0adf1de3": { + "balance": "0x4be4eab3fa0fa68000" + }, + "c53594c7cfb2a08f284cc9d7a63bbdfc0b319732": { + "balance": "0xa6b2328ff3a62c00000" + }, + "c5374928cdf193705443b14cc20da423473cd9cf": { + "balance": "0x77d10509bb3af8000" + }, + "c538a0ff282aaa5f4b75cfb62c70037ee67d4fb5": { + "balance": "0x6c6b935b8bbd400000" + }, + "c53b50fd3b2b72bc6c430baf194a515585d3986d": { + "balance": "0x1158e460913d00000" + }, + "c53d79f7cb9b70952fd30fce58d54b9f0b59f647": { + "balance": "0x113e2d6744345f80000" + }, + "c549df83c6f65eec0f1dc9a0934a5c5f3a50fd88": { + "balance": "0x9dc05cce28c2b80000" + }, + "c55005a6c37e8ca7e543ce259973a3cace961a4a": { + "balance": "0x6c6b935b8bbd400000" + }, + "c555b93156f09101233c6f7cf6eb3c4f196d3346": { + "balance": "0xa2a15d09519be00000" + }, + "c55a6b4761fd11e8c85f15174d74767cd8bd9a68": { + "balance": "0x73f75d1a085ba0000" + }, + "c56e6b62ba6e40e52aab167d21df025d0055754b": { + "balance": "0x6c6b935b8bbd400000" + }, + "c573e841fa08174a208b060ccb7b4c0d7697127f": { + "balance": "0x243d4d18229ca20000" + }, + "c57612de91110c482e6f505bcd23f3c5047d1d61": { + "balance": "0xc2127af858da700000" + }, + "c5843399d150066bf7979c34ba294620368ad7c0": { + "balance": "0xad78ebc5ac6200000" + }, + "c58b9cc61dedbb98c33f224d271f0e228b583433": { + "balance": "0xd255d112e103a00000" + }, + "c58f62fee9711e6a05dc0910b618420aa127f288": { + "balance": "0xd7c198710e66b00000" + }, + "c593b546b7698710a205ad468b2c13152219a342": { + "balance": "0x54069233bf7f780000" + }, + "c593d6e37d14b566643ac4135f243caa0787c182": { + "balance": "0x28a857425466f800000" + }, + "c5a3b98e4593fea0b38c4f455a5065f051a2f815": { + "balance": "0x44cf468af25bf770000" + }, + "c5a48a8500f9b4e22f0eb16c6f4649687674267d": { + "balance": "0x2c0ec50385043e8000" + }, + "c5a629a3962552cb8eded889636aafbd0c18ce65": { + "balance": "0x21e19e0c9bab2400000" + }, + "c5ae86b0c6c7e3900f1368105c56537faf8d743e": { + "balance": "0xa31062beeed700000" + }, + "c5b009baeaf788a276bd35813ad65b400b849f3b": { + "balance": "0x3635c9adc5dea00000" + }, + "c5b56cd234267c28e89c6f6b2266b086a12f970c": { + "balance": "0xd8d726b7177a800000" + }, + "c5c6a4998a33feb764437a8be929a73ba34a0764": { + "balance": "0xa968163f0a57b400000" + }, + "c5c73d61cce7c8fe4c8fce29f39092cd193e0fff": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "c5c7590b5621ecf8358588de9b6890f2626143f1": { + "balance": "0xa2a15d09519be00000" + }, + "c5cdcee0e85d117dabbf536a3f4069bf443f54e7": { + "balance": "0x6ac5c62d9486070000" + }, + "c5d48ca2db2f85d8c555cb0e9cfe826936783f9e": { + "balance": "0xad78ebc5ac6200000" + }, + "c5de1203d3cc2cea31c82ee2de5916880799eafd": { + "balance": "0x10f0cf064dd59200000" + }, + "c5e488cf2b5677933971f64cb8202dd05752a2c0": { + "balance": "0x3635c9adc5dea00000" + }, + "c5e812f76f15f2e1f2f9bc4823483c8804636f67": { + "balance": "0x3f514193abb840000" + }, + "c5e9939334f1252ed2ba26814487dfd2982b3128": { + "balance": "0x3cb71f51fc5580000" + }, + "c5eb42295e9cadeaf2af12dede8a8d53c579c469": { + "balance": "0xcf152640c5c8300000" + }, + "c5edbbd2ca0357654ad0ea4793f8c5cecd30e254": { + "balance": "0x14542ba12a337c00000" + }, + "c5f64babb7033142f20e46d7aa6201ed86f67103": { + "balance": "0x6c6b935b8bbd400000" + }, + "c5f687717246da8a200d20e5e9bcac60b67f3861": { + "balance": "0x18d993f34aef10000" + }, + "c6045b3c350b4ce9ca0c6b754fb41a69b97e9900": { + "balance": "0x3224f42723d4540000" + }, + "c60b04654e003b4683041f1cbd6bc38fda7cdbd6": { + "balance": "0x6c6b935b8bbd400000" + }, + "c61446b754c24e3b1642d9e51765b4d3e46b34b6": { + "balance": "0x6c6b935b8bbd400000" + }, + "c618521321abaf5b26513a4a9528086f220adc6f": { + "balance": "0x176b344f2a78c0000" + }, + "c6234657a807384126f8968ca1708bb07baa493c": { + "balance": "0x1158e460913d00000" + }, + "c625f8c98d27a09a1bcabd5128b1c2a94856af30": { + "balance": "0xad78ebc5ac6200000" + }, + "c6355ec4768c70a49af69513cd83a5bca7e3b9cd": { + "balance": "0x14542ba12a337c00000" + }, + "c63ac417992e9f9b60386ed953e6d7dff2b090e8": { + "balance": "0xd8d8583fa2d52f0000" + }, + "c63cd7882118b8a91e074d4c8f4ba91851303b9a": { + "balance": "0xe18398e7601900000" + }, + "c652871d192422c6bc235fa063b44a7e1d43e385": { + "balance": "0x8670e9ec6598c0000" + }, + "c667441e7f29799aba616451d53b3f489f9e0f48": { + "balance": "0x2f29ace68addd800000" + }, + "c66ae4cee87fb3353219f77f1d6486c580280332": { + "balance": "0x19a16b06ff8cb0000" + }, + "c674f28c8afd073f8b799691b2f0584df942e844": { + "balance": "0x6c6b935b8bbd400000" + }, + "c697b70477cab42e2b8b266681f4ae7375bb2541": { + "balance": "0x12e5732baba5c980000" + }, + "c69b855539ce1b04714728eec25a37f367951de7": { + "balance": "0x6c6b935b8bbd400000" + }, + "c69be440134d6280980144a9f64d84748a37f349": { + "balance": "0x26c29e47c4844c0000" + }, + "c69d663c8d60908391c8d236191533fdf7775613": { + "balance": "0x1a4aba225c20740000" + }, + "c6a286e065c85f3af74812ed8bd3a8ce5d25e21d": { + "balance": "0xfc936392801c0000" + }, + "c6a30ef5bb3320f40dc5e981230d52ae3ac19322": { + "balance": "0x9ddc1e3b901180000" + }, + "c6ae287ddbe1149ba16ddcca4fe06aa2eaa988a9": { + "balance": "0x15af1d78b58c400000" + }, + "c6c7c191379897dd9c9d9a33839c4a5f62c0890d": { + "balance": "0xd8d854b22430688000" + }, + "c6cd68ec35362c5ad84c82ad4edc232125912d99": { + "balance": "0x5e0549c9632e1d80000" + }, + "c6d8954e8f3fc533d2d230ff025cb4dce14f3426": { + "balance": "0x15af1d78b58c400000" + }, + "c6dbdb9efd5ec1b3786e0671eb2279b253f215ed": { + "balance": "0x3635c9adc5dea00000" + }, + "c6df2075ebd240d44869c2be6bdf82e63d4ef1f5": { + "balance": "0x1158e460913d00000" + }, + "c6e2f5af979a03fd723a1b6efa728318cf9c1800": { + "balance": "0x243d4d18229ca20000" + }, + "c6e324beeb5b36765ecd464260f7f26006c5c62e": { + "balance": "0x6c6b935b8bbd400000" + }, + "c6e4cc0c7283fc1c85bc4813effaaf72b49823c0": { + "balance": "0xf031ec9c87dd30000" + }, + "c6ee35934229693529dc41d9bb71a2496658b88e": { + "balance": "0x42bf06b78ed3b500000" + }, + "c6fb1ee37417d080a0d048923bdabab095d077c6": { + "balance": "0xad78ebc5ac6200000" + }, + "c70527d444c490e9fc3f5cc44e66eb4f306b380f": { + "balance": "0xd8d726b7177a800000" + }, + "c70d856d621ec145303c0a6400cd17bbd6f5eaf7": { + "balance": "0x1158e460913d00000" + }, + "c70fa45576bf9c865f983893002c414926f61029": { + "balance": "0x15b4aa8e9702680000" + }, + "c71145e529c7a714e67903ee6206e4c3042b6727": { + "balance": "0x4d853c8f8908980000" + }, + "c71b2a3d7135d2a85fb5a571dcbe695e13fc43cd": { + "balance": "0x3635c9adc5dea00000" + }, + "c71f1d75873f33dcb2dd4b3987a12d0791a5ce27": { + "balance": "0x3708baed3d68900000" + }, + "c71f92a3a54a7b8c2f5ea44305fccb84eee23148": { + "balance": "0x2b59ca131d2060000" + }, + "c721b2a7aa44c21298e85039d00e2e460e670b9c": { + "balance": "0x7a1fe160277000000" + }, + "c72cb301258e91bc08998a805dd192f25c2f9a35": { + "balance": "0x2009c5c8bf6fdc0000" + }, + "c7368b9709a5c1b51c0adf187a65df14e12b7dba": { + "balance": "0x2026fc77f03e5ae8000" + }, + "c739259e7f85f2659bef5f609ed86b3d596c201e": { + "balance": "0xad78ebc5ac6200000" + }, + "c73e2112282215dc0762f32b7e807dcd1a7aae3e": { + "balance": "0x1760cbc623bb3500000" + }, + "c749668042e71123a648975e08ed6382f83e05e2": { + "balance": "0x2f6f10780d22cc00000" + }, + "c74a3995f807de1db01a2eb9c62e97d0548f696f": { + "balance": "0x3635c9adc5dea00000" + }, + "c7506c1019121ff08a2c8c1591a65eb4bdfb4a3f": { + "balance": "0x2086ac351052600000" + }, + "c75c37ce2da06bbc40081159c6ba0f976e3993b1": { + "balance": "0x3a7923151ecf580000" + }, + "c75d2259306aec7df022768c69899a652185dbc4": { + "balance": "0xd8d726b7177a800000" + }, + "c760971bbc181c6a7cf77441f24247d19ce9b4cf": { + "balance": "0x6c6b935b8bbd400000" + }, + "c76130c73cb9210238025c9df95d0be54ac67fbe": { + "balance": "0x5150ae84a8cdf00000" + }, + "c765e00476810947816af142d46d2ee7bca8cc4f": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c7675e5647b9d8daf4d3dff1e552f6b07154ac38": { + "balance": "0x9c2007651b2500000" + }, + "c77b01a6e911fa988d01a3ab33646beef9c138f3": { + "balance": "0x271b6fa5dbe6cc0000" + }, + "c7837ad0a0bf14186937ace06c5546a36aa54f46": { + "balance": "0xd8d726b7177a800000" + }, + "c79806032bc7d828f19ac6a640c68e3d820fa442": { + "balance": "0x1158e460913d00000" + }, + "c799e34e88ff88be7de28e15e4f2a63d0b33c4cb": { + "balance": "0xad78ebc5ac6200000" + }, + "c79d5062c796dd7761f1f13e558d73a59f82f38b": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "c7a018f0968a51d1f6603c5c49dc545bcb0ff293": { + "balance": "0xd8d726b7177a800000" + }, + "c7aff91929797489555a2ff1d14d5c695a108355": { + "balance": "0x3635c9adc5dea00000" + }, + "c7b1c83e63203f9547263ef6282e7da33b6ed659": { + "balance": "0xfc936392801c0000" + }, + "c7b39b060451000ca1049ba154bcfa00ff8af262": { + "balance": "0x152d02c7e14af6800000" + }, + "c7bf17c4c11f98941f507e77084fffbd2dbd3db5": { + "balance": "0x3635c9adc5dea00000" + }, + "c7bf2ed1ed312940ee6aded1516e268e4a604856": { + "balance": "0x14542ba12a337c00000" + }, + "c7d44fe32c7f8cd5f1a97427b6cd3afc9e45023e": { + "balance": "0x55a6e79ccd1d300000" + }, + "c7d5c7054081e918ec687b5ab36e973d18132935": { + "balance": "0x9ddc1e3b901180000" + }, + "c7de5e8eafb5f62b1a0af2195cf793c7894c9268": { + "balance": "0x3635c9adc5dea00000" + }, + "c7e330cd0c890ac99fe771fcc7e7b009b7413d8a": { + "balance": "0xd8d726b7177a800000" + }, + "c7eac31abce6d5f1dea42202b6a674153db47a29": { + "balance": "0x2009c5c8bf6fdc0000" + }, + "c7ec62b804b1f69b1e3070b5d362c62fb309b070": { + "balance": "0x2c46bf5416066110000" + }, + "c7f72bb758016b374714d4899bce22b4aec70a31": { + "balance": "0x3a26c9478f5e2d0000" + }, + "c80b36d1beafba5fcc644d60ac6e46ed2927e7dc": { + "balance": "0xb98bc829a6f90000" + }, + "c811c2e9aa1ac3462eba5e88fcb5120e9f6e2ca2": { + "balance": "0x4be6d887bd876e0000" + }, + "c817df1b91faf30fe3251571727c9711b45d8f06": { + "balance": "0x6c6acc67d7b1d40000" + }, + "c81fb7d20fd2800192f0aac198d6d6a37d3fcb7d": { + "balance": "0xe1149331c2dde0000" + }, + "c820c711f07705273807aaaa6de44d0e4b48be2e": { + "balance": "0x8670e9ec6598c0000" + }, + "c8231ba5a411a13e222b29bfc1083f763158f226": { + "balance": "0x3637096c4bcc690000" + }, + "c836e24a6fcf29943b3608e662290a215f6529ea": { + "balance": "0xfd45064eaee100000" + }, + "c83ba6dd9549be1d3287a5a654d106c34c6b5da2": { + "balance": "0x17b7883c06916600000" + }, + "c83e9d6a58253beebeb793e6f28b054a58491b74": { + "balance": "0xf46c2b6f5a9140000" + }, + "c841884fa4785fb773b28e9715fae99a5134305d": { + "balance": "0x6c6b935b8bbd400000" + }, + "c84d9bea0a7b9f140220fd8b9097cfbfd5edf564": { + "balance": "0x6ab9ec291ad7d8000" + }, + "c852428d2b586497acd30c56aa13fb5582f84402": { + "balance": "0x3342d60dff19600000" + }, + "c853215b9b9f2d2cd0741e585e987b5fb80c212e": { + "balance": "0x54069233bf7f780000" + }, + "c85325eab2a59b3ed863c86a5f2906a04229ffa9": { + "balance": "0x193d7f7d253de00000" + }, + "c85ef27d820403805fc9ed259fff64acb8d6346a": { + "balance": "0x6c6b935b8bbd400000" + }, + "c8616b4ec09128cdff39d6e4b9ac86eec471d5f2": { + "balance": "0x10d3aa536e2940000" + }, + "c86190904b8d079ec010e462cbffc90834ffaa5c": { + "balance": "0x22385a827e815500000" + }, + "c8710d7e8b5a3bd69a42fe0fa8b87c357fddcdc8": { + "balance": "0xd8d726b7177a800000" + }, + "c87352dba582ee2066b9c002a962e003134f78b1": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c87c77e3c24adecdcd1038a38b56e18dead3b702": { + "balance": "0x1dd0c885f9a0d800000" + }, + "c87d3ae3d88704d9ab0009dcc1a0067131f8ba3c": { + "balance": "0x6ac5c62d9486070000" + }, + "c8814e34523e38e1f927a7dce8466a447a093603": { + "balance": "0x21e19e0c9bab2400000" + }, + "c88255eddcf521c6f81d97f5a42181c9073d4ef1": { + "balance": "0xfc39044d00a2a8000" + }, + "c885a18aabf4541b7b7b7ecd30f6fae6869d9569": { + "balance": "0x6c6b935b8bbd400000" + }, + "c88ca1e6e5f4d558d13780f488f10d4ad3130d34": { + "balance": "0x54069233bf7f780000" + }, + "c88eec54d305c928cc2848c2fee23531acb96d49": { + "balance": "0x6c6ad382d4fb610000" + }, + "c89cf504b9f3f835181fd8424f5ccbc8e1bddf7d": { + "balance": "0x21e19e0c9bab2400000" + }, + "c8a2c4e59e1c7fc54805580438aed3e44afdf00e": { + "balance": "0x2629f66e0c5300000" + }, + "c8aa49e3809f0899f28ab57e6743709d58419033": { + "balance": "0x2fb474098f67c00000" + }, + "c8ab1a3cf46cb8b064df2e222d39607394203277": { + "balance": "0x6c6b935b8bbd400000" + }, + "c8b1850525d946f2ae84f317b15188c536a5dc86": { + "balance": "0x918ddc3a42a3d40000" + }, + "c8d4e1599d03b79809e0130a8dc38408f05e8cd3": { + "balance": "0x9fad06241279160000" + }, + "c8dd27f16bf22450f5771b9fe4ed4ffcb30936f4": { + "balance": "0xaadec983fcff40000" + }, + "c8de7a564c7f4012a6f6d10fd08f47890fbf07d4": { + "balance": "0x1043561a8829300000" + }, + "c8e2adeb545e499d982c0c117363ceb489c5b11f": { + "balance": "0x35659ef93f0fc40000" + }, + "c8e558a3c5697e6fb23a2594c880b7a1b68f9860": { + "balance": "0x21e19e0c9bab2400000" + }, + "c8f2b320e6dfd70906c597bad2f9501312c78259": { + "balance": "0x51934b8b3a57d00000" + }, + "c90300cb1d4077e6a6d7e169a460468cf4a492d7": { + "balance": "0x6c6b935b8bbd400000" + }, + "c90c3765156bca8e4897ab802419153cbe5225a9": { + "balance": "0xad78ebc5ac6200000" + }, + "c910a970556c9716ea53af66ddef93143124913d": { + "balance": "0x55a6e79ccd1d300000" + }, + "c9127b7f6629ee13fc3f60bc2f4467a20745a762": { + "balance": "0x37c9aa4e7ce421d8000" + }, + "c91bb562e42bd46130e2d3ae4652b6a4eb86bc0f": { + "balance": "0x1d460162f516f00000" + }, + "c9308879056dfe138ef8208f79a915c6bc7e70a8": { + "balance": "0x21e19e0c9bab2400000" + }, + "c934becaf71f225f8b4a4bf7b197f4ac9630345c": { + "balance": "0x43c33c1937564800000" + }, + "c93fbde8d46d2bcc0fa9b33bd8ba7f8042125565": { + "balance": "0x4be4e7267b6ae00000" + }, + "c94089553ae4c22ca09fbc98f57075cf2ec59504": { + "balance": "0xd8d726b7177a800000" + }, + "c94110e71afe578aa218e4fc286403b0330ace8d": { + "balance": "0x6c6b935b8bbd400000" + }, + "c946d5acc1346eba0a7279a0ac1d465c996d827e": { + "balance": "0x3783d545fdf0aa40000" + }, + "c94a28fb3230a9ddfa964e770f2ce3c253a7be4f": { + "balance": "0xad78ebc5ac6200000" + }, + "c94a585203da7bbafd93e15884e660d4b1ead854": { + "balance": "0x17b7883c06916600000" + }, + "c94f7c35c027d47df8ef4f9df85a9248a17dd23b": { + "balance": "0x19f8e7559924c0000" + }, + "c951900c341abbb3bafbf7ee2029377071dbc36a": { + "balance": "0x11c25d004d01f80000" + }, + "c953f934c0eb2d0f144bdab00483fd8194865ce7": { + "balance": "0x6c6b935b8bbd400000" + }, + "c96626728aaa4c4fb3d31c26df3af310081710d1": { + "balance": "0xb50fcfafebecb00000" + }, + "c96751656c0a8ef4357b7344322134b983504aca": { + "balance": "0x6c6b935b8bbd400000" + }, + "c98048687f2bfcc9bd90ed18736c57edd352b65d": { + "balance": "0x3635c9adc5dea00000" + }, + "c981d312d287d558871edd973abb76b979e5c35e": { + "balance": "0x6acb3df27e1f880000" + }, + "c982586d63b0d74c201b1af8418372e30c7616be": { + "balance": "0x56bc75e2d63100000" + }, + "c989434f825aaf9c552f685eba7c11db4a5fc73a": { + "balance": "0x1b28c58d9696b40000" + }, + "c989eec307e8839b9d7237cfda08822962abe487": { + "balance": "0x15af1d78b58c400000" + }, + "c992be59c6721caf4e028f9e8f05c25c55515bd4": { + "balance": "0x1158e460913d00000" + }, + "c9957ba94c1b29e5277ec36622704904c63dc023": { + "balance": "0x683efc6782642c0000" + }, + "c99a9cd6c9c1be3534eecd92ecc22f5c38e9515b": { + "balance": "0x105593b3a169d770000" + }, + "c9ac01c3fb0929033f0ccc7e1acfeaaba7945d47": { + "balance": "0x2a36a9e9ca4d2038000" + }, + "c9b698e898d20d4d4f408e4e4d061922aa856307": { + "balance": "0x22b1c8c1227a00000" + }, + "c9b6b686111691ee6aa197c7231a88dc60bd295d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c9c7ac0bdd9342b5ead4360923f68c72a6ba633a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "c9c80dc12e7bab86e949d01e4c3ed35f2b9bba5f": { + "balance": "0x6c6b935b8bbd400000" + }, + "c9d76446d5aadff80b68b91b08cd9bc8f5551ac1": { + "balance": "0x26b4bd9110dce80000" + }, + "c9dcbb056f4db7d9da39936202c5bd8230b3b477": { + "balance": "0x43c33c1937564800000" + }, + "c9e02608066828848aeb28c73672a12925181f4d": { + "balance": "0x1b1b6bd7af64c70000" + }, + "ca0432cb157b5179f02ebba5c9d1b54fec4d88ca": { + "balance": "0x3635c9adc5dea00000" + }, + "ca122cf0f2948896b74843f49afed0ba1618eed7": { + "balance": "0x1e5b8fa8fe2ac00000" + }, + "ca22cda3606da5cad013b8074706d7e9e721a50c": { + "balance": "0x17181c6fa3981940000" + }, + "ca23f62dff0d6460036c62e840aec5577e0befd2": { + "balance": "0x7a1fe160277000000" + }, + "ca25ff34934c1942e22a4e7bd56f14021a1af088": { + "balance": "0xaadec983fcff40000" + }, + "ca373fe3c906b8c6559ee49ccd07f37cd4fb5266": { + "balance": "0x61093d7c2c6d380000" + }, + "ca41ccac30172052d522cd2f2f957d248153409f": { + "balance": "0x6acb3df27e1f880000" + }, + "ca4288014eddc5632f5facb5e38517a8f8bc5d98": { + "balance": "0x126e72a69a50d00000" + }, + "ca428863a5ca30369892d612183ef9fb1a04bcea": { + "balance": "0x52663ccab1e1c00000" + }, + "ca49a5f58adbefae23ee59eea241cf0482622eaa": { + "balance": "0x4d853c8f8908980000" + }, + "ca4ca9e4779d530ecbacd47e6a8058cfde65d98f": { + "balance": "0x2b5e3af16b18800000" + }, + "ca657ec06fe5bc09cf23e52af7f80cc3689e6ede": { + "balance": "0x30ca024f987b900000" + }, + "ca66b2280fa282c5b67631ce552b62ee55ad8474": { + "balance": "0x6ac422f53492880000" + }, + "ca6c818befd251361e02744068be99d8aa60b84a": { + "balance": "0x14542ba12a337c00000" + }, + "ca70f4ddbf069d2143bd6bbc7f696b52789b32e7": { + "balance": "0xa2a15d09519be00000" + }, + "ca747576446a4c8f30b08340fee198de63ec92cf": { + "balance": "0x17c8e1206722a300000" + }, + "ca7ba3ff536c7e5f0e153800bd383db8312998e0": { + "balance": "0x931ac3d6bb2400000" + }, + "ca8276c477b4a07b80107b843594189607b53bec": { + "balance": "0x14542ba12a337c00000" + }, + "ca8409083e01b397cf12928a05b68455ce6201df": { + "balance": "0x56bc75e2d631000000" + }, + "ca98c7988efa08e925ef9c9945520326e9f43b99": { + "balance": "0xd8d726b7177a800000" + }, + "ca9a042a6a806ffc92179500d24429e8ab528117": { + "balance": "0x3ba1910bf341b00000" + }, + "ca9dec02841adf5cc920576a5187edd2bd434a18": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ca9faa17542fafbb388eab21bc4c94e8a7b34788": { + "balance": "0x6c6b8fce0d18798000" + }, + "caaa68ee6cdf0d34454a769b0da148a1faaa1865": { + "balance": "0x1872e1de7fe52c00000" + }, + "caad9dc20d589ce428d8fda3a9d53a607b7988b5": { + "balance": "0xd8d726b7177a800000" + }, + "cab0d32cf3767fa6b3537c84328baa9f50458136": { + "balance": "0x1e5b8fa8fe2ac000000" + }, + "cab9a301e6bd46e940355028eccd40ce4d5a1ac3": { + "balance": "0x15af1d78b58c400000" + }, + "cab9a97ada065c87816e6860a8f1426fe6b3d775": { + "balance": "0x3635c9adc5dea00000" + }, + "cabab6274ed15089737e287be878b757934864e2": { + "balance": "0x43c33c1937564800000" + }, + "cabdaf354f4720a466a764a528d60e3a482a393c": { + "balance": "0x3635c9adc5dea00000" + }, + "cacb675e0996235404efafbb2ecb8152271b55e0": { + "balance": "0x25f273933db5700000" + }, + "cad14f9ebba76680eb836b079c7f7baaf481ed6d": { + "balance": "0xcef3d7bd7d0340000" + }, + "cae3a253bcb2cf4e13ba80c298ab0402da7c2aa0": { + "balance": "0x124bc0ddd92e5600000" + }, + "caef027b1ab504c73f41f2a10979b474f97e309f": { + "balance": "0xad78ebc5ac6200000" + }, + "caf4481d9db78dc4f25f7b4ac8bd3b1ca0106b31": { + "balance": "0x10f0cf064dd59200000" + }, + "cafde855864c2598da3cafc05ad98df2898e8048": { + "balance": "0x300a8ed96ff4a940000" + }, + "cb0dd7cf4e5d8661f6028943a4b9b75c914436a7": { + "balance": "0x1969368974c05b000000" + }, + "cb1bb6f1da5eb10d4899f7e61d06c1b00fdfb52d": { + "balance": "0x384524cc70b7780000" + }, + "cb3d766c983f192bcecac70f4ee03dd9ff714d51": { + "balance": "0x56bc75e2d63100000" + }, + "cb42b44eb5fd60b5837e4f9eb47267523d1a229c": { + "balance": "0x2ee449550898e40000" + }, + "cb47bd30cfa8ec5468aaa6a94642ced9c819c8d4": { + "balance": "0xd8d726b7177a800000" + }, + "cb48fe8265d9af55eb7006bc335645b0a3a183be": { + "balance": "0xa2a15d09519be00000" + }, + "cb4a914d2bb029f32e5fef5c234c4fec2d2dd577": { + "balance": "0x6194049f30f7200000" + }, + "cb4abfc282aed76e5d57affda542c1f382fcacf4": { + "balance": "0x1b90f11c3183faa0000" + }, + "cb4ad0c723da46ab56d526da0c1d25c73daff10a": { + "balance": "0x1ba5abf9e779380000" + }, + "cb4bb1c623ba28dc42bdaaa6e74e1d2aa1256c2a": { + "balance": "0x6c6acc67d7b1d40000" + }, + "cb50587412822304ebcba07dab3a0f09fffee486": { + "balance": "0x4a4491bd6dcd280000" + }, + "cb58990bcd90cfbf6d8f0986f6fa600276b94e2d": { + "balance": "0x3634bf39ab98788000" + }, + "cb68ae5abe02dcf8cbc5aa719c25814651af8b85": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "cb7479109b43b26657f4465f4d18c6f974be5f42": { + "balance": "0x62a992e53a0af00000" + }, + "cb7d2b8089e9312cc9aeaa2773f35308ec6c2a7b": { + "balance": "0x21e19e0c9bab2400000" + }, + "cb86edbc8bbb1f9131022be649565ebdb09e32a1": { + "balance": "0x6c6b935b8bbd400000" + }, + "cb93199b9c90bc4915bd859e3d42866dc8c18749": { + "balance": "0xc90df07def78c0000" + }, + "cb94e76febe208116733e76e805d48d112ec9fca": { + "balance": "0x3635c9adc5dea00000" + }, + "cb9b5103e4ce89af4f64916150bff9eecb9faa5c": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "cba25c7a503cc8e0d04971ca05c762f9b762b48b": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "cba288cd3c1eb4d59ddb06a6421c14c345a47b24": { + "balance": "0xd8d726b7177a800000" + }, + "cbb3189e4bd7f45f178b1c30c76e26314d4a4b0a": { + "balance": "0xffe0b677c65a98000" + }, + "cbb7be17953f2ccc93e1bc99805bf45511434e4c": { + "balance": "0xaae5b9df56d2f200000" + }, + "cbc04b4d8b82caf670996f160c362940d66fcf1a": { + "balance": "0x14542ba12a337c00000" + }, + "cbde9734b8e6aa538c291d6d7facedb0f338f857": { + "balance": "0x6c6b935b8bbd400000" + }, + "cbe1b948864d8474e765145858fca4550f784b92": { + "balance": "0x21e19e0c9bab2400000" + }, + "cbe52fc533d7dd608c92a260b37c3f45deb4eb33": { + "balance": "0x3635c9adc5dea00000" + }, + "cbe810fe0fecc964474a1db97728bc87e973fcbd": { + "balance": "0x21e19e0c9bab2400000" + }, + "cbf16a0fe2745258cd52db2bf21954c975fc6a15": { + "balance": "0x1043561a8829300000" + }, + "cbf37ff854a2f1ce53934494777892d3ec655782": { + "balance": "0x21e19e0c9bab2400000" + }, + "cbfa6af6c283b046e2772c6063b0b21553c40106": { + "balance": "0x6c6b935b8bbd400000" + }, + "cbfa76db04ce38fb205d37b8d377cf1380da0317": { + "balance": "0x4d853c8f8908980000" + }, + "cc034985d3f28c2d39b1a34bced4d3b2b6ca234e": { + "balance": "0x9ddc1e3b901180000" + }, + "cc043c4388d345f884c6855e71142a9f41fd6935": { + "balance": "0x1158e460913d00000" + }, + "cc1d6ead01aada3e8dc7b95dca25df26eefa639d": { + "balance": "0x6c6b935b8bbd400000" + }, + "cc2b5f448f3528d3fe41cc7d1fa9c0dc76f1b776": { + "balance": "0x340aad21b3b700000" + }, + "cc2d04f0a4017189b340ca77198641dcf6456b91": { + "balance": "0xd5967be4fc3f100000" + }, + "cc419fd9912b85135659e77a93bc3df182d45115": { + "balance": "0x21e19e0c9bab2400000" + }, + "cc45fb3a555bad807b388a0357c855205f7c75e8": { + "balance": "0x2ee449550898e40000" + }, + "cc48414d2ac4d42a5962f29eee4497092f431352": { + "balance": "0x8ba52e6fc45e40000" + }, + "cc4a2f2cf86cf3e43375f360a4734691195f1490": { + "balance": "0x4915053bd129098000" + }, + "cc4f0ff2aeb67d54ce3bc8c6510b9ae83e9d328b": { + "balance": "0x15af1d78b58c400000" + }, + "cc4faac00be6628f92ef6b8cb1b1e76aac81fa18": { + "balance": "0xb22a2eab0f0fd0000" + }, + "cc4feb72df98ff35a138e01761d1203f9b7edf0a": { + "balance": "0x17b7883c06916600000" + }, + "cc606f511397a38fc7872bd3b0bd03c71bbd768b": { + "balance": "0x3635c9adc5dea00000" + }, + "cc60f836acdef3548a1fefcca13ec6a937db44a0": { + "balance": "0x4b06dbbb40f4a0000" + }, + "cc6c03bd603e09de54e9c4d5ac6d41cbce715724": { + "balance": "0x556f64c1fe7fa0000" + }, + "cc6c2df00e86eca40f21ffda1a67a1690f477c65": { + "balance": "0xab4dcf399a3a600000" + }, + "cc6d7b12061bc96d104d606d65ffa32b0036eb07": { + "balance": "0x21e19e0c9bab2400000" + }, + "cc73dd356b4979b579b401d4cc7a31a268ddce5a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "cc758d071d25a6320af68c5dc9c4f6955ba94520": { + "balance": "0x14542ba12a337c00000" + }, + "cc7b0481cc32e6faef2386a07022bcb6d2c3b4fc": { + "balance": "0xab4dcf399a3a600000" + }, + "cc943be1222cd1400a2399dd1b459445cf6d54a9": { + "balance": "0x2a740ae6536fc880000" + }, + "cc9519d1f3985f6b255eaded12d5624a972721e1": { + "balance": "0x3635c9adc5dea00000" + }, + "cc9ac715cd6f2610c52b58676456884297018b29": { + "balance": "0xb98bc829a6f90000" + }, + "cca07bb794571d4acf041dad87f0d1ef3185b319": { + "balance": "0x6c6b935b8bbd400000" + }, + "ccabc6048a53464424fcf76eeb9e6e1801fa23d4": { + "balance": "0x2ab7b260ff3fd0000" + }, + "ccae0d3d852a7da3860f0636154c0a6ca31628d4": { + "balance": "0x5c6d12b6bc1a00000" + }, + "ccca24d8c56d6e2c07db086ec07e585be267ac8d": { + "balance": "0xad78ebc5ac6200000" + }, + "ccd521132d986cb96869842622a7dda26c3ed057": { + "balance": "0x6c6b935b8bbd400000" + }, + "ccf43975b76bfe735fec3cb7d4dd24f805ba0962": { + "balance": "0x340aad21b3b700000" + }, + "ccf62a663f1353ba2ef8e6521dc1ecb673ec8ef7": { + "balance": "0x83d6c7aab63600000" + }, + "ccf7110d1bd9a74bfd1d7d7d2d9d55607e7b837d": { + "balance": "0x30ca024f987b900000" + }, + "ccfd725760a68823ff1e062f4cc97e1360e8d997": { + "balance": "0x15ac56edc4d12c0000" + }, + "cd020f8edfcf524798a9b73a640334bbf72f80a5": { + "balance": "0x73f75d1a085ba0000" + }, + "cd06f8c1b5cdbd28e2d96b6346c3e85a0483ba24": { + "balance": "0x3635c9adc5dea00000" + }, + "cd072e6e1833137995196d7bb1725fef8761f655": { + "balance": "0x14542ba12a337c00000" + }, + "cd0a161bc367ae0927a92aac9cf6e5086714efca": { + "balance": "0x6c6b935b8bbd400000" + }, + "cd0af3474e22f069ec3407870dd770443d5b12b0": { + "balance": "0x8e5eb4ee77b2ef0000" + }, + "cd0b0257e783a3d2c2e3ba9d6e79b75ef98024d4": { + "balance": "0x9fad06241279160000" + }, + "cd102cd6db3df14ad6af0f87c72479861bfc3d24": { + "balance": "0x6c6b935b8bbd400000" + }, + "cd1e66ed539dd92fc40bbaa1fa16de8c02c14d45": { + "balance": "0xc77e4256863d80000" + }, + "cd1ed263fbf6f6f7b48aef8f733d329d4382c7c7": { + "balance": "0x100bd33fb98ba0000" + }, + "cd2a36d753e9e0ed012a584d716807587b41d56a": { + "balance": "0xe2ba75b0b1f1c0000" + }, + "cd32a4a8a27f1cc63954aa634f7857057334c7a3": { + "balance": "0x3ad166576c72d40000" + }, + "cd35ff010ec501a721a1b2f07a9ca5877dfcf95a": { + "balance": "0xd96fce90cfabcc0000" + }, + "cd4306d7f6947ac1744d4e13b8ef32cb657e1c00": { + "balance": "0x1b1ab319f5ec750000" + }, + "cd43258b7392a930839a51b2ef8ad23412f75a9f": { + "balance": "0x6c6b935b8bbd400000" + }, + "cd49bf185e70d04507999f92a4de4455312827d0": { + "balance": "0x3635c9adc5dea00000" + }, + "cd5510a242dfb0183de925fba866e312fabc1657": { + "balance": "0x821ab0d44149800000" + }, + "cd566ad7b883f01fd3998a9a58a9dee4724ddca5": { + "balance": "0x330ae1835be300000" + }, + "cd59f3dde77e09940befb6ee58031965cae7a336": { + "balance": "0x21e19e0c9bab2400000" + }, + "cd725d70be97e677e3c8e85c0b26ef31e9955045": { + "balance": "0x487a9a304539440000" + }, + "cd7e47909464d871b9a6dc76a8e9195db3485e7a": { + "balance": "0x215f835bc769da80000" + }, + "cd7ece086b4b619b3b369352ee38b71ddb06439a": { + "balance": "0xad78ebc5ac6200000" + }, + "cd7f09d7ed66d0c38bc5ad4e32b7f2b08dc1b30d": { + "balance": "0x3e3bb34da2a4700000" + }, + "cd9529492b5c29e475acb941402b3d3ba50686b0": { + "balance": "0x6acb3df27e1f880000" + }, + "cd95fa423d6fc120274aacde19f4eeb766f10420": { + "balance": "0xad78ebc5ac6200000" + }, + "cd9b4cef73390c83a8fd71d7b540a7f9cf8b8c92": { + "balance": "0x4e1003b28d9280000" + }, + "cda1741109c0265b3fb2bf8d5ec9c2b8a3346b63": { + "balance": "0x1158e460913d00000" + }, + "cda1b886e3a795c9ba77914e0a2fe5676f0f5ccf": { + "balance": "0x5bf60ea42c2040000" + }, + "cda4530f4b9bc50905b79d17c28fc46f95349bdf": { + "balance": "0x3310e04911f1f80000" + }, + "cdab46a5902080646fbf954204204ae88404822b": { + "balance": "0x1d8a96e5c606eb0000" + }, + "cdb597299030183f6e2d238533f4642aa58754b6": { + "balance": "0x15af1d78b58c400000" + }, + "cdd5d881a7362c9070073bdfbc75e72453ac510e": { + "balance": "0x2da518eae48ee80000" + }, + "cdd60d73efaad873c9bbfb178ca1b7105a81a681": { + "balance": "0x1bc16d674ec800000" + }, + "cdd9efac4d6d60bd71d95585dce5d59705c13564": { + "balance": "0x56bc75e2d63100000" + }, + "cde36d81d128c59da145652193eec2bfd96586ef": { + "balance": "0xd8d726b7177a800000" + }, + "cdea386f9d0fd804d02818f237b7d9fa7646d35e": { + "balance": "0xa349d36d80ec578000" + }, + "cdecf5675433cdb0c2e55a68db5d8bbe78419dd2": { + "balance": "0x1158e460913d00000" + }, + "cdfd8217339725d7ebac11a63655f265eff1cc3d": { + "balance": "0x10f0c696410e3a90000" + }, + "ce079f51887774d8021cb3b575f58f18e9acf984": { + "balance": "0x9c2007651b2500000" + }, + "ce1884ddbbb8e10e4dba6e44feeec2a7e5f92f05": { + "balance": "0xd8d726b7177a800000" + }, + "ce1b0cb46aaecfd79b880cad0f2dda8a8dedd0b1": { + "balance": "0x1158e460913d00000" + }, + "ce26f9a5305f8381094354dbfc92664e84f902b5": { + "balance": "0xc7aaab0591eec0000" + }, + "ce2deab51c0a9ae09cd212c4fa4cc52b53cc0dec": { + "balance": "0x6c6b935b8bbd400000" + }, + "ce2e0da8934699bb1a553e55a0b85c169435bea3": { + "balance": "0x10f0c696410e3a90000" + }, + "ce3a61f0461b00935e85fa1ead82c45e5a64d488": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ce4b065dbcb23047203262fb48c1188364977470": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ce53c8cdd74296aca987b2bc19c2b875a48749d0": { + "balance": "0xa2a15d09519be00000" + }, + "ce5e04f0184369bcfa06aca66ffa91bf59fa0fb9": { + "balance": "0x22b1c8c1227a00000" + }, + "ce5eb63a7bf4fbc2f6e4baa0c68ab1cb4cf98fb4": { + "balance": "0x6c6b935b8bbd400000" + }, + "ce62125adec3370ac52110953a4e760be9451e3b": { + "balance": "0x83d6c7aab63600000" + }, + "ce71086d4c602554b82dcbfce88d20634d53cc4d": { + "balance": "0x92896529baddc880000" + }, + "ce8a6b6d5033b1498b1ffeb41a41550405fa03a2": { + "balance": "0xd8d726b7177a800000" + }, + "ce9786d3712fa200e9f68537eeaa1a06a6f45a4b": { + "balance": "0x61093d7c2c6d380000" + }, + "ce9d21c692cd3c01f2011f505f870036fa8f6cd2": { + "balance": "0x15af1d78b58c400000" + }, + "cea2896623f4910287a2bdc5be83aea3f2e6de08": { + "balance": "0x1fb5a3751e490dc0000" + }, + "cea34a4dd93dd9aefd399002a97d997a1b4b89cd": { + "balance": "0x5150ae84a8cdf00000" + }, + "cea43f7075816b60bbfce68b993af0881270f6c4": { + "balance": "0x6c6b935b8bbd400000" + }, + "cea8743341533cb2f0b9c6efb8fda80d77162825": { + "balance": "0x56bc75e2d63100000" + }, + "ceb089ec8a78337e8ef88de11b49e3dd910f748f": { + "balance": "0x3635c9adc5dea00000" + }, + "ceb33d78e7547a9da2e87d51aec5f3441c87923a": { + "balance": "0x1158e460913d00000" + }, + "ceb389381d48a8ae4ffc483ad0bb5e204cfdb1ec": { + "balance": "0x2827e6e4dd62ba8000" + }, + "cec6fc65853f9cce5f8e844676362e1579015f02": { + "balance": "0x6c6b935b8bbd400000" + }, + "ced3c7be8de7585140952aeb501dc1f876ecafb0": { + "balance": "0xd8d726b7177a800000" + }, + "ced81ec3533ff1bfebf3e3843ee740ad11758d3e": { + "balance": "0x6acb3df27e1f880000" + }, + "cedcb3a1d6843fb6bef643617deaf38f8e98dd5f": { + "balance": "0x19e2a4c818b9060000" + }, + "cee699c0707a7836252b292f047ce8ad289b2f55": { + "balance": "0x119a1e21aa69560000" + }, + "ceed47ca5b899fd1623f21e9bd4db65a10e5b09d": { + "balance": "0x73877404c1eee0000" + }, + "cef77451dfa2c643e00b156d6c6ff84e2373eb66": { + "balance": "0xa31062beeed700000" + }, + "cf1169041c1745e45b172435a2fc99b49ace2b00": { + "balance": "0x1bb88baab2d7c0000" + }, + "cf157612764e0fd696c8cb5fba85df4c0ddc3cb0": { + "balance": "0x65a4da25d3016c00000" + }, + "cf1bdb799b2ea63ce134668bdc198b54840f180b": { + "balance": "0xfc936392801c0000" + }, + "cf2288ef4ebf88e86db13d8a0e0bf52a056582c3": { + "balance": "0x89506fbf9740740000" + }, + "cf264e6925130906c4d7c18591aa41b2a67f6f58": { + "balance": "0x6c6b935b8bbd400000" + }, + "cf26b47bd034bc508e6c4bcfd6c7d30034925761": { + "balance": "0x6194049f30f7200000" + }, + "cf2e2ad635e9861ae95cb9bafcca036b5281f5ce": { + "balance": "0x77432217e6836000000" + }, + "cf2e734042a355d05ffb2e3915b16811f45a695e": { + "balance": "0x6c6b935b8bbd400000" + }, + "cf348f2fe47b7e413c077a7baf3a75fbf8428692": { + "balance": "0x6c6b935b8bbd400000" + }, + "cf3f9128b07203a3e10d7d5755c0c4abc6e2cac2": { + "balance": "0x10f0cf064dd59200000" + }, + "cf3fbfa1fd32d7a6e0e6f8ef4eab57be34025c4c": { + "balance": "0x39a1c0f7594d480000" + }, + "cf4166746e1d3bc1f8d0714b01f17e8a62df1464": { + "balance": "0x3677036edf0af60000" + }, + "cf4f1138f1bd6bf5b6d485cce4c1017fcb85f07d": { + "balance": "0x2fd0bc77c32bff0000" + }, + "cf5a6f9df75579c644f794711215b30d77a0ce40": { + "balance": "0x6c6b935b8bbd400000" + }, + "cf5e0eacd1b39d0655f2f77535ef6608eb950ba0": { + "balance": "0x6c6b935b8bbd400000" + }, + "cf684dfb8304729355b58315e8019b1aa2ad1bac": { + "balance": "0x177224aa844c720000" + }, + "cf694081c76d18c64ca71382be5cd63b3cb476f8": { + "balance": "0x3635c9adc5dea00000" + }, + "cf6e52e6b77480b1867efec6446d9fc3cc3577e8": { + "balance": "0xc0901f6bd98790000" + }, + "cf883a20329667ea226a1e3c765dbb6bab32219f": { + "balance": "0xa4be3564d616660000" + }, + "cf8882359c0fb23387f5674074d8b17ade512f98": { + "balance": "0x14542ba12a337c00000" + }, + "cf89f7460ba3dfe83c5a1d3a019ee1250f242f0f": { + "balance": "0x356813cdcefd028000" + }, + "cf923a5d8fbc3d01aa079d1cfe4b43ce071b1611": { + "balance": "0x6c6b935b8bbd400000" + }, + "cf9be9b9ab86c66b59968e67b8d4dcff46b1814a": { + "balance": "0x23c757072b8dd00000" + }, + "cfa8b37127149bdbfee25c34d878510951ea10eb": { + "balance": "0x6c6b935b8bbd400000" + }, + "cfac2e1bf33205b05533691a02267ee19cd81836": { + "balance": "0x3635c9adc5dea00000" + }, + "cfbb32b7d024350e3321fa20c9a914035372ffc6": { + "balance": "0x15be6174e1912e0000" + }, + "cfc4e6f7f8b011414bfba42f23adfaa78d4ecc5e": { + "balance": "0x6449e84e47a8a80000" + }, + "cfd2728dfb8bdbf3bf73598a6e13eaf43052ea2b": { + "balance": "0x93739534d28680000" + }, + "cfd47493c9f89fe680bda5754dd7c9cfe7cb5bbe": { + "balance": "0x2f473513448fe0000" + }, + "cfde0fc75d6f16c443c3038217372d99f5d907f7": { + "balance": "0x83225e6396b5ec0000" + }, + "cfe2caaf3cec97061d0939748739bffe684ae91f": { + "balance": "0x21e19e0c9bab2400000" + }, + "cfeacaaed57285e0ac7268ce6a4e35ecfdb242d7": { + "balance": "0x3ae4d4240190600000" + }, + "cfecbea07c27002f65fe534bb8842d0925c78402": { + "balance": "0xd8d726b7177a800000" + }, + "cfee05c69d1f29e7714684c88de5a16098e91399": { + "balance": "0x6acb3df27e1f880000" + }, + "cff6a6fe3e9a922a12f21faa038156918c4fcb9c": { + "balance": "0x44591d67fecc80000" + }, + "cff7f89a4d4219a38295251331568210ffc1c134": { + "balance": "0x5f68e8131ecf800000" + }, + "cff8d06b00e3f50c191099ad56ba6ae26571cd88": { + "balance": "0x3635c9adc5dea00000" + }, + "cffc49c1787eebb2b56cabe92404b636147d4558": { + "balance": "0x133e0308f40a3da8000" + }, + "d008513b27604a89ba1763b6f84ce688b346945b": { + "balance": "0x3635c9adc5dea00000" + }, + "d00f067286c0fbd082f9f4a61083ec76deb3cee6": { + "balance": "0x3635c9adc5dea00000" + }, + "d015f6fcb84df7bb410e8c8f04894a881dcac237": { + "balance": "0x384524cc70b7780000" + }, + "d01af9134faf5257174e8b79186f42ee354e642d": { + "balance": "0x3635c9adc5dea00000" + }, + "d02108d2ae3cab10cbcf1657af223e027c8210f6": { + "balance": "0x6c6d84bccdd9ce0000" + }, + "d02afecf8e2ec2b62ac8ad204161fd1fae771d0e": { + "balance": "0x6c6b935b8bbd400000" + }, + "d0319139fbab2e8e2accc1d924d4b11df6696c5a": { + "balance": "0xad78ebc5ac6200000" + }, + "d037d215d11d1df3d54fbd321cd295c5465e273b": { + "balance": "0x4be4e7267b6ae00000" + }, + "d03a2da41e868ed3fef5745b96f5eca462ff6fda": { + "balance": "0xa2a15d09519be00000" + }, + "d03fc165576aaed525e5502c8e140f8b2e869639": { + "balance": "0x17356d8b32501c80000" + }, + "d043a011ec4270ee7ec8b968737515e503f83028": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d04b861b3d9acc563a901689941ab1e1861161a2": { + "balance": "0x1158e460913d00000" + }, + "d05a447c911dbb275bfb2e5a37e5a703a56f9997": { + "balance": "0xad78ebc5ac6200000" + }, + "d05ffb2b74f867204fe531653b0248e21c13544e": { + "balance": "0x3635c9adc5dea00000" + }, + "d062588171cf99bbeb58f126b870f9a3728d61ec": { + "balance": "0xf3f20b8dfa69d00000" + }, + "d0638ea57189a6a699024ad78c71d939c1c2ff8c": { + "balance": "0x8eae566710fc200000" + }, + "d0648a581b3508e135a2935d12c9657045d871ca": { + "balance": "0x1b2df9d219f57980000" + }, + "d071192966eb69c3520fca3aa4dd04297ea04b4e": { + "balance": "0x5f68e8131ecf80000" + }, + "d0718520eae0a4d62d70de1be0ca431c5eea2482": { + "balance": "0x6c6b935b8bbd400000" + }, + "d0775dba2af4c30a3a78365939cd71c2f9de95d2": { + "balance": "0x692ae8897081d00000" + }, + "d07be0f90997caf903c8ac1d53cde904fb190741": { + "balance": "0x36389038b699b40000" + }, + "d07e511864b1cf9969e3560602829e32fc4e71f5": { + "balance": "0x2b5e3af16b1880000" + }, + "d0809498c548047a1e2a2aa6a29cd61a0ee268bd": { + "balance": "0x6c6b935b8bbd400000" + }, + "d082275f745a2cac0276fbdb02d4b2a3ab1711fe": { + "balance": "0x1a055690d9db80000" + }, + "d08fc09a0030fd0928cd321198580182a76aae9f": { + "balance": "0x3635c9adc5dea00000" + }, + "d093e829819fd2e25b973800bb3d5841dd152d05": { + "balance": "0xd8d726b7177a800000" + }, + "d0944aa185a1337061ae20dc9dd96c83b2ba4602": { + "balance": "0xad78ebc5ac6200000" + }, + "d096565b7c7407d06536580355fdd6d239144aa1": { + "balance": "0xd8d726b7177a80000" + }, + "d09cb2e6082d693a13e8d2f68dd1dd8461f55840": { + "balance": "0x3635c9adc5dea00000" + }, + "d0a6c6f9e9c4b383d716b31de78d56414de8fa91": { + "balance": "0x1043561a8829300000" + }, + "d0a7209b80cf60db62f57d0a5d7d521a69606655": { + "balance": "0x8ac7230489e800000" + }, + "d0a8abd80a199b54b08b65f01d209c27fef0115b": { + "balance": "0x161c626dc61a2ef8000" + }, + "d0abcc70c0420e0e172f97d43b87d5e80c336ea9": { + "balance": "0x21e19e0c9bab2400000" + }, + "d0ae735d915e946866e1fea77e5ea466b5cadd16": { + "balance": "0x6c6b935b8bbd400000" + }, + "d0b11d6f2bce945e0c6a5020c3b52753f803f9d1": { + "balance": "0xad78ebc5ac6200000" + }, + "d0c101fd1f01c63f6b1d19bc920d9f932314b136": { + "balance": "0x43c33c1937564800000" + }, + "d0c55abf976fdc3db2afe9be99d499484d576c02": { + "balance": "0x3635c9adc5dea00000" + }, + "d0d0a2ad45f59a9dccc695d85f25ca46ed31a5a3": { + "balance": "0x2d89577d7d40200000" + }, + "d0d62c47ea60fb90a3639209bbfdd4d933991cc6": { + "balance": "0xa844a7424d9c80000" + }, + "d0db456178206f5c4430fe005063903c3d7a49a7": { + "balance": "0x26491e45a753c08000" + }, + "d0e194f34b1db609288509ccd2e73b6131a2538b": { + "balance": "0x36356633ebd8ea0000" + }, + "d0e35e047646e759f4517093d6408642517f084d": { + "balance": "0xd58fa46818eccb8000" + }, + "d0ee4d02cf24382c3090d3e99560de3678735cdf": { + "balance": "0x821ab0d44149800000" + }, + "d0f04f52109aebec9a7b1e9332761e9fe2b97bb5": { + "balance": "0xd8d726b7177a800000" + }, + "d0f9597811b0b992bb7d3757aa25b4c2561d32e2": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d10302faa1929a326904d376bf0b8dc93ad04c4c": { + "balance": "0x61093d7c2c6d380000" + }, + "d1100dd00fe2ddf18163ad964d0b69f1f2e9658a": { + "balance": "0x143120955b2506b0000" + }, + "d116f3dcd5db744bd008887687aa0ec9fd7292aa": { + "balance": "0x3635c9adc5dea00000" + }, + "d119417c46732cf34d1a1afb79c3e7e2cd8eece4": { + "balance": "0x6c6b935b8bbd400000" + }, + "d12d77ae01a92d35117bac705aacd982d02e74c1": { + "balance": "0x3635c9adc5dea00000" + }, + "d135794b149a18e147d16e621a6931f0a40a969a": { + "balance": "0x43c33c1937564800000" + }, + "d1432538e35b7664956ae495a32abdf041a7a21c": { + "balance": "0x42bf06b78ed3b500000" + }, + "d1438267231704fc7280d563adf4763844a80722": { + "balance": "0xad78ebc5ac6200000" + }, + "d1538e9a87e59ca9ec8e5826a5b793f99f96c4c3": { + "balance": "0x3635c9adc5dea00000" + }, + "d1648503b1ccc5b8be03fa1ec4f3ee267e6adf7b": { + "balance": "0x13befbf51eec0900000" + }, + "d1682c2159018dc3d07f08240a8c606daf65f8e1": { + "balance": "0x2a5a058fc295ed000000" + }, + "d171c3f2258aef35e599c7da1aa07300234da9a6": { + "balance": "0x6c6b935b8bbd400000" + }, + "d1778c13fbd968bc083cb7d1024ffe1f49d02caa": { + "balance": "0xd9ecb4fd208e500000" + }, + "d17fbe22d90462ed37280670a2ea0b3086a0d6d6": { + "balance": "0xad6eedd17cf3b8000" + }, + "d1811c55976980f083901d8a0db269222dfb5cfe": { + "balance": "0x54069233bf7f780000" + }, + "d18eb9e1d285dabe93e5d4bae76beefe43b521e8": { + "balance": "0x243d4d18229ca20000" + }, + "d193e583d6070563e7b862b9614a47e99489f3e5": { + "balance": "0x36356633ebd8ea0000" + }, + "d1978f2e34407fab1dc2183d95cfda6260b35982": { + "balance": "0x2ab7b260ff3fd00000" + }, + "d19caf39bb377fdf2cf19bd4fb52591c2631a63c": { + "balance": "0x3635c9adc5dea00000" + }, + "d1a396dcdab2c7494130b3fd307820340dfd8c1f": { + "balance": "0xf92250e2dfd00000" + }, + "d1a71b2d0858e83270085d95a3b1549650035e23": { + "balance": "0x327bb09d06aa8500000" + }, + "d1acb5adc1183973258d6b8524ffa28ffeb23de3": { + "balance": "0xd8d726b7177a800000" + }, + "d1b37f03cb107424e9c4dd575ccd4f4cee57e6cd": { + "balance": "0x6c6b935b8bbd400000" + }, + "d1b5a454ac3405bb4179208c6c84de006bcb9be9": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d1c45954a62b911ad701ff2e90131e8ceb89c95c": { + "balance": "0x4b91a2de457e880000" + }, + "d1c96e70f05ae0e6cd6021b2083750a7717cde56": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d1d5b17ffe2d7bbb79cc7d7930bcb2e518fb1bbf": { + "balance": "0xa2a15d09519be00000" + }, + "d1da0c8fb7c210e0f2ec618f85bdae7d3e734b1c": { + "balance": "0x6acb3df27e1f880000" + }, + "d1dd79fb158160e5b4e8e23f312e6a907fbc4d4e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d1de5aad3a5fd803f1b1aeb6103cb8e14fe723b7": { + "balance": "0x1158e460913d00000" + }, + "d1e1f2b9c16c309874dee7fac32675aff129c398": { + "balance": "0x3f24d8e4a00700000" + }, + "d1e5e234a9f44266a4a6241a84d7a1a55ad5a7fe": { + "balance": "0x43c33c1937564800000" + }, + "d1ea4d72a67b5b3e0f315559f52bd0614d713069": { + "balance": "0x6c6b935b8bbd400000" + }, + "d1ee905957fe7cc70ec8f2868b43fe47b13febff": { + "balance": "0x2629f66e0c5300000" + }, + "d1f1694d22671b5aad6a94995c369fbe6133676f": { + "balance": "0x3635c9adc5dea00000" + }, + "d1f4dc1ddb8abb8848a8b14e25f3b55a8591c266": { + "balance": "0xd8d726b7177a80000" + }, + "d1fed0aee6f5dfd7e25769254c3cfad15adeccaa": { + "balance": "0x2792c8fc4b53280000" + }, + "d2051cb3cb6704f0548cc890ab0a19db3415b42a": { + "balance": "0x121b2e5e6464780000" + }, + "d206aaddb336d45e7972e93cb075471d15897b5d": { + "balance": "0x2086ac351052600000" + }, + "d209482bb549abc4777bea6d7f650062c9c57a1c": { + "balance": "0x11651ac3e7a7580000" + }, + "d20dcb0b78682b94bc3000281448d557a20bfc83": { + "balance": "0x30849ebe16369c0000" + }, + "d2107b353726c3a2b46566eaa7d9f80b5d21dbe3": { + "balance": "0x1158e460913d00000" + }, + "d211b21f1b12b5096181590de07ef81a89537ead": { + "balance": "0x6c6b935b8bbd400000" + }, + "d218efb4db981cdd6a797f4bd48c7c26293ceb40": { + "balance": "0xa1466b31c6431c0000" + }, + "d21a7341eb84fd151054e5e387bb25d36e499c09": { + "balance": "0x2f6f10780d22cc00000" + }, + "d224f880f9479a89d32f09e52be990b288135cef": { + "balance": "0x3a9d5baa4abf1d00000" + }, + "d22f0ca4cd479e661775053bcc49e390f670dd8a": { + "balance": "0x3635c9adc5dea00000" + }, + "d231929735132102471ba59007b6644cc0c1de3e": { + "balance": "0x3637096c4bcc690000" + }, + "d235d15cb5eceebb61299e0e827fa82748911d89": { + "balance": "0xd8d726b7177a800000" + }, + "d23a24d7f9468343c143a41d73b88f7cbe63be5e": { + "balance": "0xad78ebc5ac6200000" + }, + "d23d7affacdc3e9f3dae7afcb4006f58f8a44600": { + "balance": "0xc328093e61ee400000" + }, + "d243184c801e5d79d2063f3578dbae81e7b3a9cb": { + "balance": "0x6bdca2681e1aba0000" + }, + "d24b6644f439c8051dfc64d381b8c86c75c17538": { + "balance": "0x6c6b935b8bbd400000" + }, + "d24bf12d2ddf457decb17874efde2052b65cbb49": { + "balance": "0x2f6f10780d22cc00000" + }, + "d251f903ae18727259eee841a189a1f569a5fd76": { + "balance": "0x21e19e0c9bab2400000" + }, + "d252960b0bf6b2848fdead80136db5f507f8be02": { + "balance": "0x6c6b935b8bbd400000" + }, + "d2581a55ce23ab10d8ad8c44378f59079bd6f658": { + "balance": "0x1dd0c885f9a0d800000" + }, + "d25aecd7eb8bd6345b063b5dbd271c77d3514494": { + "balance": "0x62a992e53a0af00000" + }, + "d27c234ff7accace3d996708f8f9b04970f97d36": { + "balance": "0x487a9a304539440000" + }, + "d28298524df5ec4b24b0ffb9df85170a145a9eb5": { + "balance": "0xf98a3b9b337e20000" + }, + "d283b8edb10a25528a4404de1c65e7410dbcaa67": { + "balance": "0x28a857425466f800000" + }, + "d284a50382f83a616d39b8a9c0f396e0ebbfa95d": { + "balance": "0x3636c25e66ece70000" + }, + "d288e7cb7ba9f620ab0f7452e508633d1c5aa276": { + "balance": "0xd8d726b7177a800000" + }, + "d29dc08efbb3d72e263f78ab7610d0226de76b00": { + "balance": "0x28a857425466f800000" + }, + "d2a030ac8952325f9e1db378a71485a24e1b07b2": { + "balance": "0x6c6b935b8bbd400000" + }, + "d2a479404347c5543aab292ae1bb4a6f158357fa": { + "balance": "0xd8d726b7177a800000" + }, + "d2a5a024230a57ccc666760b89b0e26cafd189c7": { + "balance": "0xa96595a5c6e8a3f8000" + }, + "d2a80327cbe55c4c7bd51ff9dde4ca648f9eb3f8": { + "balance": "0x2b5e3af16b1880000" + }, + "d2a84f75675c62d80c88756c428eee2bcb185421": { + "balance": "0x410d586a20a4c00000" + }, + "d2abd84a181093e5e229136f42d835e8235de109": { + "balance": "0x56be03ca3e47d8000" + }, + "d2ac0d3a58605e1d0f0eb3de25b2cad129ed6058": { + "balance": "0xd8d726b7177a800000" + }, + "d2bf67a7f3c6ce56b7be41675dbbadfe7ea93a33": { + "balance": "0x15af1d78b58c400000" + }, + "d2dbebe89b0357aea98bbe8e496338debb28e805": { + "balance": "0xd8d726b7177a800000" + }, + "d2e21ed56868fab28e0947927adaf29f23ebad6c": { + "balance": "0x6c184f1355d0e80000" + }, + "d2e817738abf1fb486583f80c350318bed860c80": { + "balance": "0xd02cecf5f5d810000" + }, + "d2edd1ddd6d86dc005baeb541d22b640d5c7cae5": { + "balance": "0x1158e460913d00000" + }, + "d2f1998e1cb1580cec4f6c047dcd3dcec54cf73c": { + "balance": "0xad78ebc5ac6200000" + }, + "d2f241255dd7c3f73c07043071ec08ddd9c5cde5": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d2ff672016f63b2f85398f4a6fedbb60a50d3cce": { + "balance": "0x1291246f5b734a0000" + }, + "d30d4c43adcf55b2cb53d68323264134498d89ce": { + "balance": "0x3635c9adc5dea00000" + }, + "d30ee9a12b4d68abace6baca9ad7bf5cd1faf91c": { + "balance": "0x514fcb24ff9c500000" + }, + "d3118ea3c83505a9d893bb67e2de142d537a3ee7": { + "balance": "0x1158e460913d00000" + }, + "d311bcd7aa4e9b4f383ff3d0d6b6e07e21e3705d": { + "balance": "0xad78ebc5ac6200000" + }, + "d315deea1d8c1271f9d1311263ab47c007afb6f5": { + "balance": "0x3c81d4e654b400000" + }, + "d32b2c79c36478c5431901f6d700b04dbe9b8810": { + "balance": "0x15779a9de6eeb00000" + }, + "d32b45564614516c91b07fa9f72dcf787cce4e1c": { + "balance": "0xfc66fae3746ac0000" + }, + "d330728131fe8e3a15487a34573c93457e2afe95": { + "balance": "0xd8d726b7177a800000" + }, + "d331c823825a9e5263d052d8915d4dcde07a5c37": { + "balance": "0x1e931283ccc8500000" + }, + "d333627445f2d787901ef33bb2a8a3675e27ffec": { + "balance": "0x15af1d78b58c400000" + }, + "d33cf82bf14c592640a08608914c237079d5be34": { + "balance": "0x6c6b935b8bbd400000" + }, + "d34d708d7398024533a5a2b2309b19d3c55171bb": { + "balance": "0x15af1d78b58c400000" + }, + "d34e03d36a2bd4d19a5fa16218d1d61e3ffa0b15": { + "balance": "0x1158e460913d000000" + }, + "d35075ca61fe59d123969c36a82d1ab2d918aa38": { + "balance": "0x90f534608a72880000" + }, + "d367009ab658263b62c2333a1c9e4140498e1389": { + "balance": "0x6c6b935b8bbd400000" + }, + "d3679a47df2d99a49b01c98d1c3e0c987ce1e158": { + "balance": "0xf2dc7d47f15600000" + }, + "d38fa2c4cc147ad06ad5a2f75579281f22a7cc1f": { + "balance": "0x43c33c1937564800000" + }, + "d39a5da460392b940b3c69bc03757bf3f2e82489": { + "balance": "0x17c83a97d6b6ca50000" + }, + "d39b7cbc94003fc948f0cde27b100db8ccd6e063": { + "balance": "0x15af1d78b58c400000" + }, + "d3a10ec7a5c9324999dd9e9b6bde7c911e584bda": { + "balance": "0x2086ac351052600000" + }, + "d3a941c961e8ca8b1070f23c6d6d0d2a758a4444": { + "balance": "0xad78ebc5ac6200000" + }, + "d3bb59fa31258be62f8ed232f1a7d47b4a0b41ee": { + "balance": "0x56bc75e2d63100000" + }, + "d3bc730937fa75d8452616ad1ef1fe7fffe0d0e7": { + "balance": "0x484e4ded2eae38000" + }, + "d3c24d4b3a5e0ff8a4622d518edd73f16ab28610": { + "balance": "0x1158e460913d00000" + }, + "d3c6f1e0f50ec3d2a67e6bcd193ec7ae38f1657f": { + "balance": "0x166c5480889db770000" + }, + "d3d6e9fb82542fd29ed9ea3609891e151396b6f7": { + "balance": "0xb6f588aa7bcf5c00000" + }, + "d3dad1b6d08d4581ccae65a8732db6ac69f0c69e": { + "balance": "0x14542ba12a337c00000" + }, + "d3df3b53cb3b4755de54e180451cc44c9e8ae0aa": { + "balance": "0x23c49409b977828000" + }, + "d3f873bd9956135789ab00ebc195b922e94b259d": { + "balance": "0x6c6b935b8bbd400000" + }, + "d402b4f6a099ebe716cb14df4f79c0cd01c6071b": { + "balance": "0x6c6b935b8bbd400000" + }, + "d40d0055fd9a38488aff923fd03d35ec46d711b3": { + "balance": "0x10f08eda8e555098000" + }, + "d40ed66ab3ceff24ca05ecd471efb492c15f5ffa": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d418870bc2e4fa7b8a6121ae0872d55247b62501": { + "balance": "0x55a6e79ccd1d300000" + }, + "d41d7fb49fe701baac257170426cc9b38ca3a9b2": { + "balance": "0x98a7d9b8314c00000" + }, + "d4205592844055b3c7a1f80cefe3b8eb509bcde7": { + "balance": "0x9b3bfd342a9fc8000" + }, + "d42b20bd0311608b66f8a6d15b2a95e6de27c5bf": { + "balance": "0x6c6b935b8bbd400000" + }, + "d4344f7d5cad65d17e5c2d0e7323943d6f62fe92": { + "balance": "0xe7eeba3410b740000" + }, + "d43ee438d83de9a37562bb4e286cb1bd19f4964d": { + "balance": "0x3635c9adc5dea00000" + }, + "d44334b4e23a169a0c16bd21e866bba52d970587": { + "balance": "0x8cf23f909c0fa00000" + }, + "d44d81e18f46e2cfb5c1fcf5041bc8569767d100": { + "balance": "0x7b442e684f65aa40000" + }, + "d44f4ac5fad76bdc1537a3b3af6472319b410d9d": { + "balance": "0x56bc75e2d631000000" + }, + "d44f5edf2bcf2433f211dadd0cc450db1b008e14": { + "balance": "0xe7eeba3410b740000" + }, + "d44f6ac3923b5fd731a4c45944ec4f7ec52a6ae4": { + "balance": "0x21e19e0c9bab2400000" + }, + "d45b3341e8f15c80329320c3977e3b90e7826a7e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d45d5daa138dd1d374c71b9019916811f4b20a4e": { + "balance": "0x1f399b1438a1000000" + }, + "d460a4b908dd2b056759b488850b66a838fc77a8": { + "balance": "0x6acb3df27e1f880000" + }, + "d467cf064c0871989b90d8b2eb14ccc63b360823": { + "balance": "0xad78ebc5ac6200000" + }, + "d46bae61b027e5bb422e83a3f9c93f3c8fc77d27": { + "balance": "0x6c6b935b8bbd400000" + }, + "d46f8223452982a1eea019a8816efc2d6fc00768": { + "balance": "0x76d41c62494840000" + }, + "d475477fa56390d33017518d6711027f05f28dbf": { + "balance": "0x6b111333d4fd4c0000" + }, + "d47c242edffea091bc54d57df5d1fdb93101476c": { + "balance": "0x9df7dfa8f760480000" + }, + "d47d8685faee147c520fd986709175bf2f886bef": { + "balance": "0x6c6b935b8bbd400000" + }, + "d47f50df89a1cff96513bef1b2ae3a2971accf2c": { + "balance": "0x2d89577d7d40200000" + }, + "d482e7f68e41f238fe517829de15477fe0f6dd1d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d4879fd12b1f3a27f7e109761b23ca343c48e3d8": { + "balance": "0x241a9b4f617a280000" + }, + "d48e3f9357e303513841b3f84bda83fc89727587": { + "balance": "0x3635c9adc5dea00000" + }, + "d49a75bb933fca1fca9aa1303a64b6cb44ea30e1": { + "balance": "0x21e19e0c9bab2400000" + }, + "d4b085fb086f3d0d68bf12926b1cc3142cae8770": { + "balance": "0xc893d09c8f51500000" + }, + "d4b2ff3bae1993ffea4d3b180231da439f7502a2": { + "balance": "0x6c6b935b8bbd400000" + }, + "d4b38a5fdb63e01714e9801db47bc990bd509183": { + "balance": "0x14534d95bef905c0000" + }, + "d4b8bdf3df9a51b0b91d16abbea05bb4783c8661": { + "balance": "0x3635c9adc5dea00000" + }, + "d4c4d1a7c3c74984f6857b2f5f07e8face68056d": { + "balance": "0x6c6b935b8bbd400000" + }, + "d4c6ac742e7c857d4a05a04c33d4d05c1467571d": { + "balance": "0xad78ebc5ac6200000" + }, + "d4cb21e590c5a0e06801366aff342c7d7db16424": { + "balance": "0x1ac7a08ead02f80000" + }, + "d4d92c62b280e00f626d8657f1b86166cb1f740f": { + "balance": "0xad7f23634cbd60000" + }, + "d4ebb1929a23871cf77fe049ab9602be08be0a73": { + "balance": "0x678a932062e4180000" + }, + "d4ee4919fb37f2bb970c3fff54aaf1f3dda6c03f": { + "balance": "0x878678326eac9000000" + }, + "d4feed99e8917c5c5458635f3603ecb7e817a7d0": { + "balance": "0x1043c43cde1d398000" + }, + "d4ff46203efa23064b1caf00516e28704a82a4f8": { + "balance": "0x487a9a304539440000" + }, + "d500e4d1c9824ba9f5b635cfa3a8c2c38bbd4ced": { + "balance": "0x15af1d78b58c400000" + }, + "d508d39c70916f6abc4cc7f999f011f077105802": { + "balance": "0x5724d24afe77f0000" + }, + "d50f7fa03e389876d3908b60a537a6706304fb56": { + "balance": "0x56bc75e2d63100000" + }, + "d513a45080ff2febe62cd5854abe29ee4467f996": { + "balance": "0x84e13bc4fc5d80000" + }, + "d5276f0cd5ffd5ffb63f98b5703d5594ede0838b": { + "balance": "0x15af1d78b58c400000" + }, + "d5294b666242303b6df0b1c88d37429bc8c965aa": { + "balance": "0x104d0d00d2b7f60000" + }, + "d52aecc6493938a28ca1c367b701c21598b6a02e": { + "balance": "0x3ba1910bf341b00000" + }, + "d53c567f0c3ff2e08b7d59e2b5c73485437fc58d": { + "balance": "0x2086ac351052600000" + }, + "d541ac187ad7e090522de6da3213e9a7f4439673": { + "balance": "0x6c6b935b8bbd400000" + }, + "d54ba2d85681dc130e5b9b02c4e8c851391fd9b9": { + "balance": "0xd5967be4fc3f100000" + }, + "d55508adbbbe9be81b80f97a6ea89add68da674f": { + "balance": "0x6c6b935b8bbd400000" + }, + "d5550caaf743b037c56fd2558a1c8ed235130750": { + "balance": "0x121e4d49036255b0000" + }, + "d5586da4e59583c8d86cccf71a86197f17996749": { + "balance": "0x6c6b935b8bbd400000" + }, + "d55c1c8dfbe1e02cacbca60fdbdd405b09f0b75f": { + "balance": "0x6c6b935b8bbd400000" + }, + "d561cbbc05515de73ab8cf9eae1357341e7dfdf4": { + "balance": "0x14542ba12a337c00000" + }, + "d56a144d7af0ae8df649abae535a15983aa04d02": { + "balance": "0x10f0cf064dd59200000" + }, + "d572309169b1402ec8131a17a6aac3222f89e6eb": { + "balance": "0x2ec1978c47766a00000" + }, + "d5787668c2c5175b01a8ee1ac3ecc9c8b2aba95a": { + "balance": "0x6c6acc67d7b1d40000" + }, + "d588c3a5df228185d98ee7e60748255cdea68b01": { + "balance": "0xd8d726b7177a800000" + }, + "d58a52e078a805596b0d56ea4ae1335af01c66eb": { + "balance": "0xe7eeba3410b740000" + }, + "d5903e9978ee20a38c3f498d63d57f31a39f6a06": { + "balance": "0x232b36ffc672ab00000" + }, + "d59638d3c5faa7711bf085745f9d5bdc23d498d8": { + "balance": "0x6c6b935b8bbd400000" + }, + "d59d92d2c8701980cc073c375d720af064743c0c": { + "balance": "0x405fdf7e5af85e00000" + }, + "d5a7bec332adde18b3104b5792546aa59b879b52": { + "balance": "0x6c6b935b8bbd400000" + }, + "d5b117ec116eb846418961eb7edb629cd0dd697f": { + "balance": "0xa2a15d09519be00000" + }, + "d5b284040130abf7c1d163712371cc7e28ad66da": { + "balance": "0x6acb3df27e1f880000" + }, + "d5b9d277d8aad20697a51f76e20978996bffe055": { + "balance": "0x7c3fe3c076ab50000" + }, + "d5bd5e8455c130169357c471e3e681b7996a7276": { + "balance": "0x2d9e288f8abb360000" + }, + "d5cba5b26bea5d73fabb1abafacdef85def368cc": { + "balance": "0xad78ebc5ac6200000" + }, + "d5ce55d1b62f59433c2126bcec09bafc9dfaa514": { + "balance": "0xaadec983fcff40000" + }, + "d5e55100fbd1956bbed2ca518d4b1fa376032b0b": { + "balance": "0x56bc75e2d63100000" + }, + "d5e5c135d0c4c3303934711993d0d16ff9e7baa0": { + "balance": "0x6c6b935b8bbd400000" + }, + "d5e656a1b916f9bf45afb07dd8afaf73b4c56f41": { + "balance": "0x542253a126ce40000" + }, + "d5ea472cb9466018110af00c37495b5c2c713112": { + "balance": "0x10eee686c854f440000" + }, + "d5f07552b5c693c20067b378b809cee853b8f136": { + "balance": "0x1b67c6df88c6fa0000" + }, + "d5f7c41e07729dfa6dfc64c4423160a22c609fd3": { + "balance": "0x61093d7c2c6d380000" + }, + "d604abce4330842e3d396ca73ddb5519ed3ec03f": { + "balance": "0x8e31fe1689d8a0000" + }, + "d60651e393783423e5cc1bc5f889e44ef7ea243e": { + "balance": "0x159e76371129c80000" + }, + "d609bf4f146eea6b0dc8e06ddcf4448a1fccc9fa": { + "balance": "0x6c6b935b8bbd400000" + }, + "d609ec0be70d0ad26f6e67c9d4762b52ee51122c": { + "balance": "0x3635c9adc5dea00000" + }, + "d60a52580728520df7546bc1e283291788dbae0c": { + "balance": "0x363489ef3ff0d70000" + }, + "d60b247321a32a5affb96b1e279927cc584de943": { + "balance": "0x7ad020d6ddd7760000" + }, + "d6110276cfe31e42825a577f6b435dbcc10cf764": { + "balance": "0x3635c9adc5dea00000" + }, + "d612597bc31743c78633f633f239b1e9426bd925": { + "balance": "0x1017f7df96be17800000" + }, + "d6234aaf45c6f22e66a225ffb93add629b4ef80f": { + "balance": "0x3635c9adc5dea00000" + }, + "d62edb96fce2969aaf6c545e967cf1c0bc805205": { + "balance": "0x4a565536a5ada8000" + }, + "d6300b3215b11de762ecde4b70b7927d01291582": { + "balance": "0x6c6b935b8bbd400000" + }, + "d6395db5a4bb66e60f4cfbcdf0057bb4d97862e2": { + "balance": "0x3154c9729d05780000" + }, + "d64a2d50f8858537188a24e0f50df1681ab07ed7": { + "balance": "0x8375a2abcca24400000" + }, + "d6580ab5ed4c7dfa506fa6fe64ad5ce129707732": { + "balance": "0xd8d726b7177a800000" + }, + "d6598b1386e93c5ccb9602ff4bbbecdbd3701dc4": { + "balance": "0xc25f4ecb041f00000" + }, + "d6644d40e90bc97fe7dfe7cabd3269fd579ba4b3": { + "balance": "0x89e917994f71c0000" + }, + "d6670c036df754be43dadd8f50feea289d061fd6": { + "balance": "0x144a2903448cef78000" + }, + "d668523a90f0293d65c538d2dd6c57673710196e": { + "balance": "0x2242c30b853ee0000" + }, + "d66ab79294074c8b627d842dab41e17dd70c5de5": { + "balance": "0x3635c9adc5dea00000" + }, + "d66acc0d11b689cea6d9ea5ff4014c224a5dc7c4": { + "balance": "0xfc936392801c0000" + }, + "d66ddf1159cf22fd8c7a4bc8d5807756d433c43e": { + "balance": "0x77432217e683600000" + }, + "d687cec0059087fdc713d4d2d65e77daefedc15f": { + "balance": "0x340aad21b3b700000" + }, + "d688e785c98f00f84b3aa1533355c7a258e87948": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "d6a22e598dabd38ea6e958bd79d48ddd9604f4df": { + "balance": "0x3635c9adc5dea00000" + }, + "d6a7ac4de7b510f0e8de519d973fa4c01ba83400": { + "balance": "0x65ea3db75546600000" + }, + "d6acc220ba2e51dfcf21d443361eea765cbd35d8": { + "balance": "0x1158e460913d00000" + }, + "d6acffd0bfd99c382e7bd56ff0e6144a9e52b08e": { + "balance": "0x8ac7230489e800000" + }, + "d6c0d0bc93a62e257174700e10f024c8b23f1f87": { + "balance": "0x6c6b935b8bbd400000" + }, + "d6cf5c1bcf9da662bcea2255905099f9d6e84dcc": { + "balance": "0x1c49e420157d9c20000" + }, + "d6d03572a45245dbd4368c4f82c95714bd2167e2": { + "balance": "0x3f00c3d66686fc0000" + }, + "d6d6776958ee23143a81adadeb08382009e996c2": { + "balance": "0xa2a15d09519be00000" + }, + "d6d9e30f0842012a7176a917d9d2048ca0738759": { + "balance": "0xd8d726b7177a800000" + }, + "d6e09e98fe1300332104c1ca34fbfac554364ed9": { + "balance": "0x6c6b935b8bbd400000" + }, + "d6e8e97ae9839b9ee507eedb28edfb7477031439": { + "balance": "0x6c6b935b8bbd400000" + }, + "d6eea898d4ae2b718027a19ce9a5eb7300abe3ca": { + "balance": "0x17d4aceee63db8000" + }, + "d6f1e55b1694089ebcb4fe7d7882aa66c8976176": { + "balance": "0x43c23bdbe929db30000" + }, + "d6f4a7d04e8faf20e8c6eb859cf7f78dd23d7a15": { + "balance": "0x724ded1c748140000" + }, + "d6fc0446c6a8d40ae3551db7e701d1fa876e4a49": { + "balance": "0x6c6b935b8bbd400000" + }, + "d703c6a4f11d60194579d58c2766a7ef16c30a29": { + "balance": "0x6c6b935b8bbd400000" + }, + "d7052519756af42590f15391b723a03fa564a951": { + "balance": "0xfa3631480d01fd8000" + }, + "d70a612bd6dda9eab0dddcff4aaf4122d38feae4": { + "balance": "0x1d460162f516f00000" + }, + "d70ad2c4e9eebfa637ef56bd486ad2a1e5bce093": { + "balance": "0xad78ebc5ac6200000" + }, + "d7140c8e5a4307fab0cc27badd9295018bf87970": { + "balance": "0x5f1016b5076d00000" + }, + "d7164aa261c09ad9b2b5068d453ed8eb6aa13083": { + "balance": "0xa2a15d09519be00000" + }, + "d71e43a45177ad51cbe0f72184a5cb503917285a": { + "balance": "0xad78ebc5ac6200000" + }, + "d71fb130f0150c565269e00efb43902b52a455a6": { + "balance": "0xad78ebc5ac6200000" + }, + "d7225738dcf3578438f8e7c8b3837e42e04a262f": { + "balance": "0x182b8cebbb83aa0000" + }, + "d7274d50804d9c77da93fa480156efe57ba501de": { + "balance": "0x692ae8897081d00000" + }, + "d731bb6b5f3c37395e09ceaccd14a918a6060789": { + "balance": "0xd5967be4fc3f100000" + }, + "d73ed2d985b5f21b55b274643bc6da031d8edd8d": { + "balance": "0xa6dd90cae5114480000" + }, + "d744ac7e5310be696a63b003c40bd039370561c6": { + "balance": "0x5a87e7d7f5f6580000" + }, + "d74a6e8d6aab34ce85976814c1327bd6ea0784d2": { + "balance": "0x152d02c7e14af6800000" + }, + "d75a502a5b677287470f65c5aa51b87c10150572": { + "balance": "0x3130b4646385740000" + }, + "d76dbaebc30d4ef67b03e6e6ecc6d84e004d502d": { + "balance": "0x6d76b9188e13850000" + }, + "d771d9e0ca8a08a113775731434eb3270599c40d": { + "balance": "0x1158e460913d00000" + }, + "d7788ef28658aa06cc53e1f3f0de58e5c371be78": { + "balance": "0x16a6502f15a1e540000" + }, + "d77892e2273b235d7689e430e7aeed9cbce8a1f3": { + "balance": "0x6c6b935b8bbd400000" + }, + "d781f7fc09184611568570b4986e2c72872b7ed0": { + "balance": "0x1159561065d5d0000" + }, + "d785a8f18c38b9bc4ffb9b8fa8c7727bd642ee1c": { + "balance": "0x3635c9adc5dea00000" + }, + "d78ecd25adc86bc2051d96f65364866b42a426b7": { + "balance": "0xd23058bf2f26120000" + }, + "d78f84e38944a0e0255faece48ba4950d4bd39d2": { + "balance": "0x10f0cf064dd59200000" + }, + "d79483f6a8444f2549d611afe02c432d15e11051": { + "balance": "0x1158e460913d00000" + }, + "d79835e404fb86bf845fba090d6ba25e0c8866a6": { + "balance": "0x821ab0d44149800000" + }, + "d79aff13ba2da75d46240cac0a2467c656949823": { + "balance": "0x5dc892aa1131c80000" + }, + "d79db5ab43621a7a3da795e58929f3dd25af67d9": { + "balance": "0x6c6acc67d7b1d40000" + }, + "d7a1431ee453d1e49a0550d1256879b4f5d10201": { + "balance": "0x5a87e7d7f5f6580000" + }, + "d7ad09c6d32657685355b5c6ec8e9f57b4ebb982": { + "balance": "0x6acb3df27e1f880000" + }, + "d7b740dff8c457668fdf74f6a266bfc1dcb723f9": { + "balance": "0x1158e460913d00000" + }, + "d7c2803ed7b0e0837351411a8e6637d168bc5b05": { + "balance": "0x641daf5c91bd9358000" + }, + "d7c6265dea11876c903b718e4cd8ab24fe265bde": { + "balance": "0x6c6b935b8bbd400000" + }, + "d7ca7fdcfebe4588eff5421d1522b61328df7bf3": { + "balance": "0xd8e6001e6c302b0000" + }, + "d7cdbd41fff20df727c70b6255c1ba7606055468": { + "balance": "0xad78ebc5ac6200000" + }, + "d7d157e4c0a96437a6d285741dd23ec4361fa36b": { + "balance": "0x6c6b935b8bbd400000" + }, + "d7d2c6fca8ad1f75395210b57de5dfd673933909": { + "balance": "0x126e72a69a50d00000" + }, + "d7d3c75920590438b82c3e9515be2eb6ed7a8b1a": { + "balance": "0xcb49b44ba602d800000" + }, + "d7d7f2caa462a41b3b30a34aeb3ba61010e2626f": { + "balance": "0x6c6b935b8bbd400000" + }, + "d7e74afdbad55e96cebc5a374f2c8b768680f2b0": { + "balance": "0x55de6a779bbac0000" + }, + "d7eb903162271c1afa35fe69e37322c8a4d29b11": { + "balance": "0x21e19e0c9bab2400000" + }, + "d7ebddb9f93987779b680155375438db65afcb6a": { + "balance": "0x5741afeff944c0000" + }, + "d7ef340e66b0d7afcce20a19cb7bfc81da33d94e": { + "balance": "0xa2a15d09519be00000" + }, + "d7f370d4bed9d57c6f49c999de729ee569d3f4e4": { + "balance": "0xad78ebc5ac6200000" + }, + "d7fa5ffb6048f96fb1aba09ef87b1c11dd7005e4": { + "balance": "0x3635c9adc5dea00000" + }, + "d8069f84b521493f4715037f3226b25f33b60586": { + "balance": "0x678a932062e4180000" + }, + "d815e1d9f4e2b5e57e34826b7cfd8881b8546890": { + "balance": "0xf015f25736420000" + }, + "d81bd54ba2c44a6f6beb1561d68b80b5444e6dc6": { + "balance": "0x3f170d7ee43c430000" + }, + "d82251456dc1380f8f5692f962828640ab9f2a03": { + "balance": "0x1088b53b2c202be0000" + }, + "d82c6fedbdac98af2eed10b00f32b00056ca5a6d": { + "balance": "0xad78ebc5ac6200000" + }, + "d82fd9fdf6996bedad2843159c06f37e0924337d": { + "balance": "0x5b8ccedc5aa7b00000" + }, + "d83ad260e9a6f432fb6ea28743299b4a09ad658c": { + "balance": "0x6c6b935b8bbd400000" + }, + "d843ee0863ce933e22f89c802d31287b9671e81c": { + "balance": "0xb98bc829a6f90000" + }, + "d84b922f7841fc5774f00e14604ae0df42c8551e": { + "balance": "0xd96fce90cfabcc0000" + }, + "d855b03ccb029a7747b1f07303e0a664793539c8": { + "balance": "0x6c6b935b8bbd400000" + }, + "d85fdeaf2a61f95db902f9b5a53c9b8f9266c3ac": { + "balance": "0x6cf65a7e9047280000" + }, + "d8715ef9176f850b2e30eb8e382707f777a6fbe9": { + "balance": "0x6c6b935b8bbd400000" + }, + "d874b9dfae456a929ba3b1a27e572c9b2cecdfb3": { + "balance": "0x93739534d28680000" + }, + "d8930a39c77357c30ad3a060f00b06046331fd62": { + "balance": "0x2c73c937742c500000" + }, + "d89bc271b27ba3ab6962c94a559006ae38d5f56a": { + "balance": "0x6c6b935b8bbd400000" + }, + "d8b77db9b81bbe90427b62f702b201ffc29ff618": { + "balance": "0x326d1e4396d45c0000" + }, + "d8cd64e0284eec53aa4639afc4750810b97fab56": { + "balance": "0x1158e460913d00000" + }, + "d8d64384249b776794063b569878d5e3b530a4b2": { + "balance": "0x9a043d0b2f9568000" + }, + "d8d65420c18c2327cc5af97425f857e4a9fd51b3": { + "balance": "0x5f68e8131ecf800000" + }, + "d8e5c9675ef4deed266b86956fc4590ea7d4a27d": { + "balance": "0x3635c9adc5dea00000" + }, + "d8e8474292e7a051604ca164c0707783bb2885e8": { + "balance": "0x2d4ca05e2b43ca80000" + }, + "d8eb78503ec31a54a90136781ae109004c743257": { + "balance": "0x3635c9adc5dea00000" + }, + "d8eef4cf4beb01ee20d111748b61cb4d3f641a01": { + "balance": "0x9489237adb9a500000" + }, + "d8f4bae6f84d910d6d7d5ac914b1e68372f94135": { + "balance": "0x56bc75e2d63100000" + }, + "d8f62036f03b7635b858f1103f8a1d9019a892b6": { + "balance": "0x2b5e3af16b1880000" + }, + "d8f665fd8cd5c2bcc6ddc0a8ae521e4dc6aa6060": { + "balance": "0x5c283d410394100000" + }, + "d8f9240c55cff035523c6d5bd300d370dc8f0c95": { + "balance": "0xf732b66015a540000" + }, + "d8f94579496725b5cb53d7985c989749aff849c0": { + "balance": "0x39992648a23c8a00000" + }, + "d8fdf546674738c984d8fab857880b3e4280c09e": { + "balance": "0x1158e460913d00000" + }, + "d8fe088fffce948f5137ee23b01d959e84ac4223": { + "balance": "0xc5b54a94fc0170000" + }, + "d90f3009db437e4e11c780bec8896f738d65ef0d": { + "balance": "0xd8d726b7177a800000" + }, + "d9103bb6b67a55a7fece2d1af62d457c2178946d": { + "balance": "0x3635c9adc5dea00000" + }, + "d913f0771949753c4726acaa2bd3619c5c20ff77": { + "balance": "0xa2a15d09519be00000" + }, + "d91d889164479ce436ece51763e22cda19b22d6b": { + "balance": "0xb66d88126800880000" + }, + "d929c65d69d5bbaea59762662ef418bc21ad924a": { + "balance": "0x3635c9adc5dea00000" + }, + "d930b27a78876485d0f48b70dd5336549679ca8f": { + "balance": "0x22b1c8c1227a00000" + }, + "d931ac2668ba6a84481ab139735aec14b7bfbabf": { + "balance": "0x6c6b935b8bbd400000" + }, + "d9383d4b6d17b3f9cd426e10fb944015c0d44bfb": { + "balance": "0x2b5e3af16b18800000" + }, + "d942de4784f7a48716c0fd4b9d54a6e54c5f2f3e": { + "balance": "0x43c33c1937564800000" + }, + "d944c8a69ff2ca1249690c1229c7192f36251062": { + "balance": "0x6acb3df27e1f880000" + }, + "d94a57882a52739bbe2a0647c80c24f58a2b4f1c": { + "balance": "0x48b54e2adbe12b0000" + }, + "d95342953c8a21e8b635eefac7819bea30f17047": { + "balance": "0x13f06c7ffef05d400000" + }, + "d95c90ffbe5484864780b867494a83c89256d6e4": { + "balance": "0x58e7926ee858a00000" + }, + "d96711540e2e998343d4f590b6fc8fac3bb8b31d": { + "balance": "0x5f5a4068b71cb00000" + }, + "d96ac2507409c7a383ab2eee1822a5d738b36b56": { + "balance": "0xad78ebc5ac6200000" + }, + "d96db33b7b5a950c3efa2dc31b10ba10a532ef87": { + "balance": "0x6c6b935b8bbd400000" + }, + "d9775965b716476675a8d513eb14bbf7b07cd14a": { + "balance": "0x1132e6d2d23c5e40000" + }, + "d97bc84abd47c05bbf457b2ef659d61ca5e5e48f": { + "balance": "0x69d17119dc5a80000" + }, + "d97f4526dea9b163f8e8e33a6bcf92fb907de6ec": { + "balance": "0xf654aaf4db2f00000" + }, + "d97fe6f53f2a58f6d76d752adf74a8a2c18e9074": { + "balance": "0x10cdf9b69a43570000" + }, + "d99999a2490d9494a530cae4daf38554f4dd633e": { + "balance": "0x68155a43676e00000" + }, + "d99df7421b9382e42c89b006c7f087702a0757c0": { + "balance": "0x1a055690d9db800000" + }, + "d9b783d31d32adc50fa3eacaa15d92b568eaeb47": { + "balance": "0x733af90374c1b280000" + }, + "d9d370fec63576ab15b318bf9e58364dc2a3552a": { + "balance": "0x56bc75e2d63100000" + }, + "d9d42fd13ebd4bf69cac5e9c7e82483ab46dd7e9": { + "balance": "0x121ea68c114e5100000" + }, + "d9e27eb07dfc71a706060c7f079238ca93e88539": { + "balance": "0x3635c9adc5dea00000" + }, + "d9e3857efd1e202a441770a777a49dcc45e2e0d3": { + "balance": "0xc1daf81d8a3ce0000" + }, + "d9ec2efe99ff5cf00d03a8317b92a24aef441f7e": { + "balance": "0x6c6b935b8bbd400000" + }, + "d9ec8fe69b7716c0865af888a11b2b12f720ed33": { + "balance": "0xd8d726b7177a800000" + }, + "d9f1b26408f0ec67ad1d0d6fe22e8515e1740624": { + "balance": "0x14d1120d7b1600000" + }, + "d9f547f2c1de0ed98a53d161df57635dd21a00bd": { + "balance": "0x556f64c1fe7fa0000" + }, + "d9ff115d01266c9f73b063c1c238ef3565e63b36": { + "balance": "0x24dce54d34a1a00000" + }, + "da06044e293c652c467fe74146bf185b21338a1c": { + "balance": "0x3635c9adc5dea00000" + }, + "da0b48e489d302b4b7bf204f957c1c9be383b0df": { + "balance": "0x6c6b935b8bbd400000" + }, + "da0d4b7ef91fb55ad265f251142067f10376ced6": { + "balance": "0x43c33c1937564800000" + }, + "da10978a39a46ff0bb848cf65dd9c77509a6d70e": { + "balance": "0x6c6b935b8bbd400000" + }, + "da16dd5c3d1a2714358fe3752cae53dbab2be98c": { + "balance": "0x41bad155e6512200000" + }, + "da214c023e2326ff696c00393168ce46ffac39ec": { + "balance": "0x3635c9adc5dea00000" + }, + "da2a14f9724015d79014ed8e5909681d596148f1": { + "balance": "0x2a10f0f8a91ab8000" + }, + "da2ad58e77deddede2187646c465945a8dc3f641": { + "balance": "0x23c757072b8dd00000" + }, + "da3017c150dd0dce7fcf881b0a48d0d1c756c4c7": { + "balance": "0x56bf91b1a65eb0000" + }, + "da34b2eae30bafe8daeccde819a794cd89e09549": { + "balance": "0x6c6b935b8bbd400000" + }, + "da4a5f557f3bab390a92f49b9b900af30c46ae80": { + "balance": "0x21e19e0c9bab2400000" + }, + "da505537537ffb33c415fec64e69bae090c5f60f": { + "balance": "0x8ac7230489e800000" + }, + "da698d64c65c7f2b2c7253059cd3d181d899b6b7": { + "balance": "0x1004e2e45fb7ee0000" + }, + "da7732f02f2e272eaf28df972ecc0ddeed9cf498": { + "balance": "0xb20bfbf6967890000" + }, + "da7ad025ebde25d22243cb830ea1d3f64a566323": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "da855d53477f505ec4c8d5e8bb9180d38681119c": { + "balance": "0x12f939c99edab800000" + }, + "da875e4e2f3cabe4f37e0eaed7d1f6dcc6ffef43": { + "balance": "0x6c6b935b8bbd400000" + }, + "da8bbee182e455d2098acb338a6d45b4b17ed8b6": { + "balance": "0x6c6b935b8bbd400000" + }, + "da982e9643ffece723075a40fe776e5ace04b29b": { + "balance": "0x8b8b6c9999bf20000" + }, + "da9f55460946d7bfb570ddec757ca5773b58429a": { + "balance": "0x1b845d769eb4480000" + }, + "daa1bd7a9148fb865cd612dd35f162861d0f3bdc": { + "balance": "0xa638ab72d92c138000" + }, + "daa63cbda45dd487a3f1cd4a746a01bb5e060b90": { + "balance": "0x10416d9b02a89240000" + }, + "daa776a6754469d7b9267a89b86725e740da0fa0": { + "balance": "0x6acb3df27e1f880000" + }, + "daac91c1e859d5e57ed3084b50200f9766e2c52b": { + "balance": "0x15af1d78b58c400000" + }, + "daacdaf42226d15cb1cf98fa15048c7f4ceefe69": { + "balance": "0x1043561a8829300000" + }, + "dab6bcdb83cf24a0ae1cb21b3b5b83c2f3824927": { + "balance": "0xa968163f0a57b400000" + }, + "dabb0889fc042926b05ef57b2520910abc4b4149": { + "balance": "0x6c6b935b8bbd400000" + }, + "dabc225042a6592cfa13ebe54efa41040878a5a2": { + "balance": "0xe11fad5d85ca30000" + }, + "dac0c177f11c5c3e3e78f2efd663d13221488574": { + "balance": "0x3635c9adc5dea00000" + }, + "dad136b88178b4837a6c780feba226b98569a94c": { + "balance": "0xad78ebc5ac6200000" + }, + "dadbfafd8b62b92a24efd75256dd83abdbd7bbdb": { + "balance": "0x11164759ffb320000" + }, + "dadc00ab7927603c2fcf31cee352f80e6c4d6351": { + "balance": "0x6c66e9a55378b80000" + }, + "dae0d33eaa341569fa9ff5982684854a4a328a6e": { + "balance": "0x3635c9adc5dea00000" + }, + "dae7201eab8c063302930d693929d07f95e71962": { + "balance": "0x91aec028b419810000" + }, + "daedd4ad107b271e89486cbf80ebd621dd974578": { + "balance": "0x6c6b935b8bbd400000" + }, + "db04fad9c49f9e880beb8fcf1d3a3890e4b3846f": { + "balance": "0x435ae6cc0c58e50000" + }, + "db0cc78f74d9827bdc8a6473276eb84fdc976212": { + "balance": "0x6c6b935b8bbd400000" + }, + "db1293a506e90cad2a59e1b8561f5e66961a6788": { + "balance": "0x6c6b935b8bbd400000" + }, + "db19a3982230368f0177219cb10cb259cdb2257c": { + "balance": "0x6c6b935b8bbd400000" + }, + "db23a6fef1af7b581e772cf91882deb2516fc0a7": { + "balance": "0xad78ebc5ac6200000" + }, + "db244f97d9c44b158a40ed9606d9f7bd38913331": { + "balance": "0x58788cb94b1d80000" + }, + "db288f80ffe232c2ba47cc94c763cf6fc9b82b0d": { + "balance": "0x49b9ca9a694340000" + }, + "db2a0c9ab64df58ddfb1dbacf8ba0d89c85b31b4": { + "balance": "0xd8d726b7177a800000" + }, + "db34745ede8576b499db01beb7c1ecda85cf4abe": { + "balance": "0x4563918244f400000" + }, + "db3f258ab2a3c2cf339c4499f75a4bd1d3472e9e": { + "balance": "0x5150ae84a8cdf00000" + }, + "db4bc83b0e6baadb1156c5cf06e0f721808c52c7": { + "balance": "0x2fb474098f67c00000" + }, + "db63122de7037da4971531fae9af85867886c692": { + "balance": "0xf0425b0641f340000" + }, + "db6c2a73dac7424ab0d031b66761122566c01043": { + "balance": "0xa2a15d09519be00000" + }, + "db6e560c9bc620d4bea3a94d47f7880bf47f2d5f": { + "balance": "0x4da0fdfcf05760000" + }, + "db6ff71b3db0928f839e05a7323bfb57d29c87aa": { + "balance": "0x3154c9729d05780000" + }, + "db73460b59d8e85045d5e752e62559875e42502e": { + "balance": "0x36330322d5238c0000" + }, + "db77b88dcb712fd17ee91a5b94748d720c90a994": { + "balance": "0x6c6b935b8bbd400000" + }, + "db7d4037081f6c65f9476b0687d97f1e044d0a1d": { + "balance": "0x23c757072b8dd00000" + }, + "db882eacedd0eff263511b312adbbc59c6b8b25b": { + "balance": "0x1ed4fde7a2236b00000" + }, + "db9371b30c4c844e59e03e924be606a938d1d310": { + "balance": "0x6c6b935b8bbd400000" + }, + "dba4796d0ceb4d3a836b84c96f910afc103f5ba0": { + "balance": "0x908f493f737410000" + }, + "dbadc61ed5f0460a7f18e51b2fb2614d9264a0e0": { + "balance": "0x22b1c8c1227a00000" + }, + "dbb6ac484027041642bbfd8d80f9d0c1cf33c1eb": { + "balance": "0x6c6b935b8bbd400000" + }, + "dbbcbb79bf479a42ad71dbcab77b5adfaa872c58": { + "balance": "0x5dc892aa1131c80000" + }, + "dbc1ce0e49b1a705d22e2037aec878ee0d75c703": { + "balance": "0xd8d726b7177a80000" + }, + "dbc1d0ee2bab531140de137722cd36bdb4e47194": { + "balance": "0xad78ebc5ac6200000" + }, + "dbc59ed88973dead310884223af49763c05030f1": { + "balance": "0x1158e460913d00000" + }, + "dbc66965e426ff1ac87ad6eb78c1d95271158f9f": { + "balance": "0xfc936392801c0000" + }, + "dbcbcd7a57ea9db2349b878af34b1ad642a7f1d1": { + "balance": "0xad78ebc5ac6200000" + }, + "dbd51cdf2c3bfacdff106221de2e19ad6d420414": { + "balance": "0x5f68e8131ecf800000" + }, + "dbd71efa4b93c889e76593de609c3b04cbafbe08": { + "balance": "0x1158e460913d00000" + }, + "dbf5f061a0f48e5e69618739a77d2ec19768d201": { + "balance": "0x83d6c7aab63600000" + }, + "dbf8b13967f55125272de0562536c450ba5655a0": { + "balance": "0x6ef578f06e0ccb0000" + }, + "dbfb1bb464b8a58e500d2ed8de972c45f5f1c0fb": { + "balance": "0x56bc75e2d631000000" + }, + "dc067ed3e12d711ed475f5156ef7e71a80d934b9": { + "balance": "0x205b4dfa1ee74780000" + }, + "dc087f9390fb9e976ac23ab689544a0942ec2021": { + "balance": "0x62a992e53a0af00000" + }, + "dc1eb9b6e64351f56424509645f83e79eee76cf4": { + "balance": "0xd8d726b7177a800000" + }, + "dc1f1979615f082140b8bb78c67b27a1942713b1": { + "balance": "0x340aad21b3b700000" + }, + "dc23b260fcc26e7d10f4bd044af794579460d9da": { + "balance": "0x1b1b6bd7af64c70000" + }, + "dc29119745d2337320da51e19100c948d980b915": { + "balance": "0x8ac7230489e800000" + }, + "dc2d15a69f6bb33b246aef40450751c2f6756ad2": { + "balance": "0x6c341080bd1fb00000" + }, + "dc3dae59ed0fe18b58511e6fe2fb69b219689423": { + "balance": "0x56bc75e2d63100000" + }, + "dc3f0e7672f71fe7525ba30b9755183a20b9166a": { + "balance": "0x2089cf57b5b3e968000" + }, + "dc4345d6812e870ae90c568c67d2c567cfb4f03c": { + "balance": "0x16b352da5e0ed300000" + }, + "dc44275b1715baea1b0345735a29ac42c9f51b4f": { + "balance": "0x3f19beb8dd1ab00000" + }, + "dc46c13325cd8edf0230d068896486f007bf4ef1": { + "balance": "0x487a9a304539440000" + }, + "dc51b2dc9d247a1d0e5bc36ca3156f7af21ff9f6": { + "balance": "0x3635c9adc5dea00000" + }, + "dc5305b4020a06b49d657c7ca34c35c91c5f2c56": { + "balance": "0x17df6c10dbeba970000" + }, + "dc57345b38e0f067c9a31d9deac5275a10949321": { + "balance": "0xad78ebc5ac6200000" + }, + "dc57477dafa42f705c7fe40eae9c81756e0225f1": { + "balance": "0x1b1b8128a7416e0000" + }, + "dc5f5ad663a6f263327d64cac9cb133d2c960597": { + "balance": "0x6c6b935b8bbd400000" + }, + "dc703a5f3794c84d6cb3544918cae14a35c3bd4f": { + "balance": "0x6449e84e47a8a80000" + }, + "dc738fb217cead2f69594c08170de1af10c419e3": { + "balance": "0x152d02c7e14af6800000" + }, + "dc76e85ba50b9b31ec1e2620bce6e7c8058c0eaf": { + "balance": "0x1158e460913d00000" + }, + "dc83b6fd0d512131204707eaf72ea0c8c9bef976": { + "balance": "0x6c6b935b8bbd400000" + }, + "dc8c2912f084a6d184aa73638513ccbc326e0102": { + "balance": "0x4633bc36cbc2dc0000" + }, + "dc911cf7dc5dd0813656670528e9338e67034786": { + "balance": "0x6c6b935b8bbd400000" + }, + "dcb03bfa6c1131234e56b7ea7c4f721487546b7a": { + "balance": "0x487a9a304539440000" + }, + "dcb64df43758c7cf974fa660484fbb718f8c67c1": { + "balance": "0x43c33c1937564800000" + }, + "dcc52d8f8d9fc742a8b82767f0555387c563efff": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "dccb370ed68aa922283043ef7cad1b9d403fc34a": { + "balance": "0xd8d726b7177a800000" + }, + "dccca42045ec3e16508b603fd936e7fd7de5f36a": { + "balance": "0x11164759ffb320000" + }, + "dcd10c55bb854f754434f1219c2c9a98ace79f03": { + "balance": "0xd8d8583fa2d52f0000" + }, + "dcd5bca2005395b675fde5035659b26bfefc49ee": { + "balance": "0xaadec983fcff40000" + }, + "dcdbbd4e2604e40e1710cc6730289dccfad3892d": { + "balance": "0xf95dd2ec27cce00000" + }, + "dce30c31f3ca66721ecb213c809aab561d9b52e4": { + "balance": "0x6c6b935b8bbd400000" + }, + "dcf33965531380163168fc11f67e89c6f1bc178a": { + "balance": "0x122776853406b08000" + }, + "dcf6b657266e91a4dae6033ddac15332dd8d2b34": { + "balance": "0x5f68e8131ecf800000" + }, + "dcf9719be87c6f46756db4891db9b611d2469c50": { + "balance": "0x3635c9adc5dea00000" + }, + "dcfff3e8d23c2a34b56bd1b3bd45c79374432239": { + "balance": "0x10f0cf064dd59200000" + }, + "dd04eee74e0bf30c3f8d6c2c7f52e0519210df93": { + "balance": "0x4563918244f400000" + }, + "dd26b429fd43d84ec179825324bad5bfb916b360": { + "balance": "0x116bf95bc8432980000" + }, + "dd2a233adede66fe1126d6c16823b62a021feddb": { + "balance": "0x6c6b935b8bbd400000" + }, + "dd2bdfa917c1f310e6fa35aa8af16939c233cd7d": { + "balance": "0x15af1d78b58c400000" + }, + "dd35cfdbcb993395537aecc9f59085a8d5ddb6f5": { + "balance": "0x3635c9adc5dea00000" + }, + "dd47189a3e64397167f0620e484565b762bfbbf4": { + "balance": "0x6449e84e47a8a80000" + }, + "dd4dd6d36033b0636fcc8d0938609f4dd64f4a86": { + "balance": "0x340aad21b3b700000" + }, + "dd4f5fa2111db68f6bde3589b63029395b69a92d": { + "balance": "0x8963dd8c2c5e00000" + }, + "dd63042f25ed32884ad26e3ad959eb94ea36bf67": { + "balance": "0x484d7fde7d593f00000" + }, + "dd65f6e17163b5d203641f51cc7b24b00f02c8fb": { + "balance": "0xad78ebc5ac6200000" + }, + "dd6c062193eac23d2fdbf997d5063a346bb3b470": { + "balance": "0x1158e460913d00000" + }, + "dd7bcda65924aaa49b80984ae173750258b92847": { + "balance": "0x21e19e0c9bab2400000" + }, + "dd7ff441ba6ffe3671f3c0dabbff1823a5043370": { + "balance": "0x6c6b935b8bbd400000" + }, + "dd8254121a6e942fc90828f2431f511dad7f32e6": { + "balance": "0xa39b29e1f360e80000" + }, + "dd8af9e7765223f4446f44d3d509819a3d3db411": { + "balance": "0x21e19e0c9bab2400000" + }, + "dd95dbe30f1f1877c5dd7684aeef302ab6885192": { + "balance": "0x1c5d8d6eb3e32500000" + }, + "dd967c4c5f8ae47e266fb416aad1964ee3e7e8c3": { + "balance": "0x1a420db02bd7d580000" + }, + "dd9b485a3b1cd33a6a9c62f1e5bee92701856d25": { + "balance": "0xc3383ed031b7e8000" + }, + "dda371e600d30688d4710e088e02fdf2b9524d5f": { + "balance": "0x177224aa844c7200000" + }, + "dda4ed2a58a8dd20a73275347b580d71b95bf99a": { + "balance": "0x15a13cc201e4dc0000" + }, + "dda4ff7de491c687df4574dd1b17ff8f246ba3d1": { + "balance": "0x42684a41abfd8400000" + }, + "ddab6b51a9030b40fb95cf0b748a059c2417bec7": { + "balance": "0x6c6b935b8bbd400000" + }, + "ddab75fb2ff9fecb88f89476688e2b00e367ebf9": { + "balance": "0x41bad155e6512200000" + }, + "ddabf13c3c8ea4e3d73d78ec717afafa430e5479": { + "balance": "0x8cf23f909c0fa000000" + }, + "ddac312a9655426a9c0c9efa3fd82559ef4505bf": { + "balance": "0x15be6174e1912e0000" + }, + "ddac6bf4bbdd7d597d9c686d0695593bedccc7fa": { + "balance": "0x2ee449550898e40000" + }, + "ddbd2b932c763ba5b1b7ae3b362eac3e8d40121a": { + "balance": "0x21e19e0c9bab2400000" + }, + "ddbddd1bbd38ffade0305d30f02028d92e9f3aa8": { + "balance": "0x6c6b935b8bbd400000" + }, + "ddbee6f094eae63420b003fb4757142aea6cd0fd": { + "balance": "0x6c6b935b8bbd400000" + }, + "ddd69c5b9bf5eb5a39cee7c3341a120d973fdb34": { + "balance": "0x6bc14b8f8e1b350000" + }, + "dddd7b9e6eab409b92263ac272da801b664f8a57": { + "balance": "0x69e10de76676d0800000" + }, + "dde670d01639667576a22dd05d3246d61f06e083": { + "balance": "0x1731790534df20000" + }, + "dde77a4740ba08e7f73fbe3a1674912931742eeb": { + "balance": "0x434fe4d4382f1d48000" + }, + "dde8f0c31b7415511dced1cd7d46323e4bd12232": { + "balance": "0x57473d05dabae80000" + }, + "dde969aef34ea87ac299b7597e292b4a0155cc8a": { + "balance": "0x1032f2594a01738000" + }, + "ddf0cce1fe996d917635f00712f4052091dff9ea": { + "balance": "0x6c6b935b8bbd400000" + }, + "ddf3ad76353810be6a89d731b787f6f17188612b": { + "balance": "0x43c33c1937564800000" + }, + "ddf5810a0eb2fb2e32323bb2c99509ab320f24ac": { + "balance": "0x3ca5c66d9bc44300000" + }, + "ddf95c1e99ce2f9f5698057c19d5c94027ee4a6e": { + "balance": "0x14542ba12a337c00000" + }, + "ddfafdbc7c90f1320e54b98f374617fbd01d109f": { + "balance": "0xb98bc829a6f90000" + }, + "ddfcca13f934f0cfbe231da13039d70475e6a1d0": { + "balance": "0x3638221660a5aa8000" + }, + "de027efbb38503226ed871099cb30bdb02af1335": { + "balance": "0x3635c9adc5dea00000" + }, + "de06d5ea777a4eb1475e605dbcbf43444e8037ea": { + "balance": "0xa968163f0a57b400000" + }, + "de07fb5b7a464e3ba7fbe09e9acb271af5338c58": { + "balance": "0x2b5e3af16b1880000" + }, + "de1121829c9a08284087a43fbd2fc1142a3233b4": { + "balance": "0x3635c9adc5dea00000" + }, + "de176b5284bcee3a838ba24f67fc7cbf67d78ef6": { + "balance": "0x209ce08c962b00000" + }, + "de212293f8f1d231fa10e609470d512cb8ffc512": { + "balance": "0x6c6b935b8bbd400000" + }, + "de30e49e5ab313214d2f01dcabce8940b81b1c76": { + "balance": "0xaadec983fcff40000" + }, + "de33d708a3b89e909eaf653b30fdc3a5d5ccb4b3": { + "balance": "0x99c88229fd4c20000" + }, + "de374299c1d07d79537385190f442ef9ca24061f": { + "balance": "0x73f75d1a085ba0000" + }, + "de42fcd24ce4239383304367595f068f0c610740": { + "balance": "0x2722a70f1a9a00000" + }, + "de50868eb7e3c71937ec73fa89dd8b9ee10d45aa": { + "balance": "0x3635c9adc5dea00000" + }, + "de55de0458f850b37e4d78a641dd2eb2dd8f38ce": { + "balance": "0xd8d726b7177a800000" + }, + "de5b005fe8daae8d1f05de3eda042066c6c4691c": { + "balance": "0x3ba1910bf341b00000" + }, + "de612d0724e84ea4a7feaa3d2142bd5ee82d3201": { + "balance": "0x1158e460913d00000" + }, + "de6d363106cc6238d2f092f0f0372136d1cd50c6": { + "balance": "0x121ea68c114e5100000" + }, + "de7dee220f0457a7187d56c1c41f2eb00ac56021": { + "balance": "0x2225f39c85052a0000" + }, + "de82cc8d4a1bb1d9434392965b3e80bad3c03d4f": { + "balance": "0x50186e75de97a60000" + }, + "de97f4330700b48c496d437c91ca1de9c4b01ba4": { + "balance": "0x9dcc0515b56e0c0000" + }, + "de9eff4c798811d968dccb460d9b069cf30278e0": { + "balance": "0x15af1d78b58c400000" + }, + "deb1bc34d86d4a4dde2580d8beaf074eb0e1a244": { + "balance": "0x55a6e79ccd1d300000" + }, + "deb2495d6aca7b2a6a2d138b6e1a42e2dc311fdd": { + "balance": "0x6c6b935b8bbd400000" + }, + "deb97254474c0d2f5a7970dcdb2f52fb1098b896": { + "balance": "0x3635c9adc5dea00000" + }, + "deb9a49a43873020f0759185e20bbb4cf381bb8f": { + "balance": "0xb78edb0bf2e5e0000" + }, + "debbdd831e0f20ae6e378252decdf92f7cf0c658": { + "balance": "0x6c6b935b8bbd400000" + }, + "dec3eec2640a752c466e2b7e7ee685afe9ac41f4": { + "balance": "0x47c99753596b288000" + }, + "dec82373ade8ebcf2acb6f8bc2414dd7abb70d77": { + "balance": "0xad78ebc5ac6200000" + }, + "dec8a1a898f1b895d8301fe64ab3ad5de941f689": { + "balance": "0x2ab4f67e8a730f8000" + }, + "dec99e972fca7177508c8e1a47ac22d768acab7c": { + "balance": "0x6c6b935b8bbd400000" + }, + "ded877378407b94e781c4ef4af7cfc5bc220b516": { + "balance": "0x143179d86911020000" + }, + "dee942d5caf5fac11421d86b010b458e5c392990": { + "balance": "0xd8d726b7177a800000" + }, + "deee2689fa9006b59cf285237de53b3a7fd01438": { + "balance": "0x186579f29e20250000" + }, + "defddfd59b8d2c154eecf5c7c167bf0ba2905d3e": { + "balance": "0x512cb5e2647420000" + }, + "defe9141f4704599159d7b223de42bffd80496b3": { + "balance": "0x56bc75e2d63100000" + }, + "df098f5e4e3dffa51af237bda8652c4f73ed9ca6": { + "balance": "0x1b36a6444a3e180000" + }, + "df0d08617bd252a911df8bd41a39b83ddf809673": { + "balance": "0x21e19e0c9bab2400000" + }, + "df0ff1f3d27a8ec9fb8f6b0cb254a63bba8224a5": { + "balance": "0xecc5202945d0020000" + }, + "df1fa2e20e31985ebe2c0f0c93b54c0fb67a264b": { + "balance": "0xad78ebc5ac6200000" + }, + "df211cd21288d6c56fae66c3ff54625dd4b15427": { + "balance": "0x8786cd764e1f2c0000" + }, + "df236bf6abf4f3293795bf0c28718f93e3b1b36b": { + "balance": "0x487a9a304539440000" + }, + "df31025f5649d2c6eea41ed3bdd3471a790f759a": { + "balance": "0x1158e460913d00000" + }, + "df37c22e603aedb60a627253c47d8ba866f6d972": { + "balance": "0x5150ae84a8cdf000000" + }, + "df3b72c5bd71d4814e88a62321a93d4011e3578b": { + "balance": "0xd8d726b7177a800000" + }, + "df3f57b8ee6434d047223def74b20f63f9e4f955": { + "balance": "0xd9462c6cb4b5a0000" + }, + "df44c47fc303ac76e74f97194cca67b5bb3c023f": { + "balance": "0x2009c5c8bf6fdc0000" + }, + "df47a61b72535193c561cccc75c3f3ce0804a20e": { + "balance": "0x15935c0b4e3d780000" + }, + "df47a8ef95f2f49f8e6f58184154145d11f72797": { + "balance": "0x678a932062e4180000" + }, + "df53003346d65c5e7a646bc034f2b7d32fcbe56a": { + "balance": "0x6c6b935b8bbd400000" + }, + "df57353aaff2aadb0a04f9014e8da7884e86589c": { + "balance": "0x84886a66e4fb00000" + }, + "df60f18c812a11ed4e2776e7a80ecf5e5305b3d6": { + "balance": "0x30ca024f987b900000" + }, + "df6485c4297ac152b289b19dde32c77ec417f47d": { + "balance": "0x3635c9adc5dea00000" + }, + "df660a91dab9f730f6190d50c8390561500756ca": { + "balance": "0x6c6b935b8bbd400000" + }, + "df6ed6006a6abe886ed33d95a4de28fc12183927": { + "balance": "0x3154c9729d05780000" + }, + "df8510793eee811c2dab1c93c6f4473f30fbef5b": { + "balance": "0x3635c9adc5dea00000" + }, + "df8d48b1eb07b3c217790e6c2df04dc319e7e848": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "dfa6b8b8ad3184e357da282951d79161cfb089bc": { + "balance": "0x15af1d78b58c400000" + }, + "dfaf31e622c03d9e18a0ddb8be60fbe3e661be0a": { + "balance": "0x21e171a3ec9f72c0000" + }, + "dfb1626ef48a1d7d7552a5e0298f1fc23a3b482d": { + "balance": "0x5ce895dd949efa0000" + }, + "dfb4d4ade52fcc818acc7a2c6bb2b00224658f78": { + "balance": "0x1a420db02bd7d580000" + }, + "dfbd4232c17c407a980db87ffbcda03630e5c459": { + "balance": "0x1dfc7f924923530000" + }, + "dfcbdf09454e1a5e4a40d3eef7c5cf1cd3de9486": { + "balance": "0xd8d726b7177a800000" + }, + "dfdbcec1014b96da2158ca513e9c8d3b9af1c3d0": { + "balance": "0x6c6b935b8bbd400000" + }, + "dfded2574b27d1613a7d98b715159b0d00baab28": { + "balance": "0x43c33c1937564800000" + }, + "dfdf43393c649caebe1bb18059decb39f09fb4e8": { + "balance": "0x15af1d78b58c400000" + }, + "dfe3c52a92c30396a4e33a50170dc900fcf8c9cf": { + "balance": "0x2b5e3af16b1880000" + }, + "dfe549fe8430e552c6d07cc3b92ccd43b12fb50f": { + "balance": "0x48875eaf6562a0000" + }, + "dfe929a61c1b38eddbe82c25c2d6753cb1e12d68": { + "balance": "0x15d1cf4176aeba0000" + }, + "dff1b220de3d8e9ca4c1b5be34a799bcded4f61c": { + "balance": "0x14e4e353ea39420000" + }, + "dff4007931786593b229efe5959f3a4e219e51af": { + "balance": "0x10afc1ade3b4ed40000" + }, + "dffcea5421ec15900c6ecfc777184e140e209e24": { + "balance": "0x115473824344e0000" + }, + "e001aba77c02e172086c1950fffbcaa30b83488f": { + "balance": "0x6acb3df27e1f880000" + }, + "e00484788db50fc6a48e379d123e508b0f6e5ab1": { + "balance": "0x3635c9adc5dea00000" + }, + "e0060462c47ff9679baef07159cae08c29f274a9": { + "balance": "0x6c6b935b8bbd400000" + }, + "e00d153b10369143f97f54b8d4ca229eb3e8f324": { + "balance": "0x83d6c7aab63600000" + }, + "e012db453827a58e16c1365608d36ed658720507": { + "balance": "0x6c6b935b8bbd400000" + }, + "e01547ba42fcafaf93938becf7699f74290af74f": { + "balance": "0x6c6b935b8bbd400000" + }, + "e016dc138e25815b90be3fe9eee8ffb2e105624f": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e01859f242f1a0ec602fa8a3b0b57640ec89075e": { + "balance": "0x1e162c177be5cc0000" + }, + "e020e86362b487752836a6de0bc02cd8d89a8b6a": { + "balance": "0x14542ba12a337c00000" + }, + "e023f09b2887612c7c9cf1988e3a3a602b3394c9": { + "balance": "0x6c6b935b8bbd400000" + }, + "e0272213e8d2fd3e96bd6217b24b4ba01b617079": { + "balance": "0x1158e460913d00000" + }, + "e02b74a47628be315b1f76b315054ad44ae9716f": { + "balance": "0xd8d726b7177a800000" + }, + "e03220c697bcd28f26ef0b74404a8beb06b2ba7b": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "e0352fdf819ba265f14c06a6315c4ac1fe131b2e": { + "balance": "0x3635c9adc5dea00000" + }, + "e0388aeddd3fe2ad56f85748e80e710a34b7c92e": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e03c00d00388ecbf4f263d0ac778bb41a57a40d9": { + "balance": "0x3636c9796436740000" + }, + "e04920dc6ecc1d6ecc084f88aa0af5db97bf893a": { + "balance": "0x9ddc1e3b901180000" + }, + "e04972a83ca4112bc871c72d4ae1616c2f0728db": { + "balance": "0xe81c77f29a32f0000" + }, + "e04ff5e5a7e2af995d8857ce0290b53a2b0eda5d": { + "balance": "0x3635c9adc5dea00000" + }, + "e05029aceb0778675bef1741ab2cd2931ef7c84b": { + "balance": "0x10f0dbae61009528000" + }, + "e056bf3ff41c26256fef51716612b9d39ade999c": { + "balance": "0x56be757a12e0a8000" + }, + "e061a4f2fc77b296d19ada238e49a5cb8ecbfa70": { + "balance": "0xd8d726b7177a800000" + }, + "e0663e8cd66792a641f56e5003660147880f018e": { + "balance": "0x6c6b935b8bbd400000" + }, + "e0668fa82c14d6e8d93a53113ef2862fa81581bc": { + "balance": "0x2f2f39fc6c54000000" + }, + "e069c0173352b10bf6834719db5bed01adf97bbc": { + "balance": "0x10634f8e5323b0000" + }, + "e06c29a81517e0d487b67fb0b6aabc4f57368388": { + "balance": "0x15be6174e1912e0000" + }, + "e06cb6294704eea7437c2fc3d30773b7bf38889a": { + "balance": "0x116dc3a8994b30000" + }, + "e07137ae0d116d033533c4eab496f8a9fb09569c": { + "balance": "0x4be4e7267b6ae00000" + }, + "e076db30ab486f79194ebbc45d8fab9a9242f654": { + "balance": "0x106607e3494baa00000" + }, + "e07ebbc7f4da416e42c8d4f842aba16233c12580": { + "balance": "0x6c6b935b8bbd400000" + }, + "e081ca1f4882db6043d5a9190703fde0ab3bf56d": { + "balance": "0x15af1d78b58c400000" + }, + "e083d34863e0e17f926b7928edff317e998e9c4b": { + "balance": "0x15af1d78b58c400000" + }, + "e08b9aba6bd9d28bc2056779d2fbf0f2855a3d9d": { + "balance": "0x6c6b935b8bbd400000" + }, + "e08bc29c2b48b169ff2bdc16714c586e6cb85ccf": { + "balance": "0x1158e460913d00000" + }, + "e08c60313106e3f9334fe6f7e7624d211130c077": { + "balance": "0x22b1c8c1227a00000" + }, + "e09c68e61998d9c81b14e4ee802ba7adf6d74cdb": { + "balance": "0xd8d726b7177a800000" + }, + "e09fea755aee1a44c0a89f03b5deb762ba33006f": { + "balance": "0x3ba289bc944ff70000" + }, + "e0a254ac09b9725bebc8e460431dd0732ebcabbf": { + "balance": "0x14542ba12a337c00000" + }, + "e0aa69365555b73f282333d1e30c1bbd072854e8": { + "balance": "0x17b7883c06916600000" + }, + "e0bad98eee9698dbf6d76085b7923de5754e906d": { + "balance": "0x90d972f32323c0000" + }, + "e0c4ab9072b4e6e3654a49f8a8db026a4b3386a9": { + "balance": "0x6c6b935b8bbd400000" + }, + "e0ce80a461b648a501fd0b824690c8868b0e4de8": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e0cf698a053327ebd16b7d7700092fe2e8542446": { + "balance": "0x52a34cbb61f578000" + }, + "e0d231e144ec9107386c7c9b02f1702ceaa4f700": { + "balance": "0x10f0dbae61009528000" + }, + "e0d76b7166b1f3a12b4091ee2b29de8caa7d07db": { + "balance": "0x6c6b935b8bbd400000" + }, + "e0e0b2e29dde73af75987ee4446c829a189c95bc": { + "balance": "0x813ca56906d340000" + }, + "e0e978753d982f7f9d1d238a18bd4889aefe451b": { + "balance": "0x20dd68aaf3289100000" + }, + "e0f372347c96b55f7d4306034beb83266fd90966": { + "balance": "0x15af1d78b58c400000" + }, + "e0f903c1e48ac421ab48528f3d4a2648080fe043": { + "balance": "0x3708baed3d68900000" + }, + "e0ff0bd9154439c4a5b7233e291d7d868af53f33": { + "balance": "0x1579216a51bbfb0000" + }, + "e10ac19c546fc2547c61c139f5d1f45a6666d5b0": { + "balance": "0x102da6fd0f73a3c0000" + }, + "e10c540088113fa6ec00b4b2c8824f8796e96ec4": { + "balance": "0x320f4509ab1ec7c00000" + }, + "e1173a247d29d8238df0922f4df25a05f2af77c3": { + "balance": "0x878c95d560f30478000" + }, + "e1203eb3a723e99c2220117ca6afeb66fa424f61": { + "balance": "0x200ef929e3256fe0000" + }, + "e131f87efc5ef07e43f0f2f4a747b551d750d9e6": { + "balance": "0x43c25e0dcc1bd1c0000" + }, + "e1334e998379dfe983177062791b90f80ee22d8d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e13540ecee11b212e8b775dc8e71f374aae9b3f8": { + "balance": "0x6c6b935b8bbd400000" + }, + "e13b3d2bbfdcbc8772a23315724c1425167c5688": { + "balance": "0x37f379141ed04b8000" + }, + "e1443dbd95cc41237f613a48456988a04f683282": { + "balance": "0xd8d8583fa2d52f0000" + }, + "e14617f6022501e97e7b3e2d8836aa61f0ff2dba": { + "balance": "0xad78ebc5ac6200000" + }, + "e149b5726caf6d5eb5bf2acc41d4e2dc328de182": { + "balance": "0x692ae8897081d00000" + }, + "e154daeadb545838cbc6aa0c55751902f528682a": { + "balance": "0x10afc1ade3b4ed40000" + }, + "e16ce35961cd74bd590d04c4ad4a1989e05691c6": { + "balance": "0x7ea28327577080000" + }, + "e172dfc8f80cd1f8cd8539dc26082014f5a8e3e8": { + "balance": "0xa2a15d09519be00000" + }, + "e177e0c201d335ba3956929c571588b51c5223ae": { + "balance": "0x6c6b935b8bbd400000" + }, + "e17812f66c5e65941e186c46922b6e7b2f0eeb46": { + "balance": "0x62a992e53a0af00000" + }, + "e180de9e86f57bafacd7904f9826b6b4b26337a3": { + "balance": "0x2d041d705a2c600000" + }, + "e192489b85a982c1883246d915b229cb13207f38": { + "balance": "0x10f0cf064dd59200000" + }, + "e1953c6e975814c571311c34c0f6a99cdf48ab82": { + "balance": "0x2b5e3af16b1880000" + }, + "e1ae029b17e373cde3de5a9152201a14cac4e119": { + "balance": "0x56b55ae58ca400000" + }, + "e1b2aca154b8e0766c4eba30bc10c7f35036f368": { + "balance": "0x115473824344e0000" + }, + "e1b39b88d9900dbc4a6cdc481e1060080a8aec3c": { + "balance": "0x6c6b935b8bbd400000" + }, + "e1b63201fae1f129f95c7a116bd9dde5159c6cda": { + "balance": "0x4d60573a2f0c9ef0000" + }, + "e1bfaa5a45c504428923c4a61192a55b1400b45d": { + "balance": "0x90f534608a72880000" + }, + "e1c607c0a8a060da8f02a8eb38a013ea8cda5b8c": { + "balance": "0x2ba39e82ed5d740000" + }, + "e1cb83ec5eb6f1eeb85e99b2fc63812fde957184": { + "balance": "0x43c33c1937564800000" + }, + "e1d91b0954cede221d6f24c7985fc59965fb98b8": { + "balance": "0x6c6b935b8bbd400000" + }, + "e1dfb5cc890ee8b2877e885d267c256187d019e6": { + "balance": "0x56bc75e2d63100000" + }, + "e1e8c50b80a352b240ce7342bbfdf5690cc8cb14": { + "balance": "0x155bd9307f9fe80000" + }, + "e1f63ebbc62c7b7444040eb99623964f7667b376": { + "balance": "0x1158e460913d00000" + }, + "e206fb7324e9deb79e19903496d6961b9be56603": { + "balance": "0x56bc75e2d63100000" + }, + "e207578e1f4ddb8ff6d5867b39582d71b9812ac5": { + "balance": "0xd255d112e103a00000" + }, + "e208812a684098f3da4efe6aba256256adfe3fe6": { + "balance": "0x6c6b935b8bbd400000" + }, + "e20954d0f4108c82d4dcb2148d26bbd924f6dd24": { + "balance": "0x21e19e0c9bab2400000" + }, + "e20bb9f3966419e14bbbaaaa6789e92496cfa479": { + "balance": "0xbbd825030752760000" + }, + "e20d1bcb71286dc7128a9fc7c6ed7f733892eef5": { + "balance": "0x3664f8e7c24af40000" + }, + "e2191215983f33fd33e22cd4a2490054da53fddc": { + "balance": "0xdb44e049bb2c0000" + }, + "e2198c8ca1b399f7521561fd5384a7132fba486b": { + "balance": "0x3708baed3d68900000" + }, + "e21c778ef2a0d7f751ea8c074d1f812243863e4e": { + "balance": "0x11fc70e2c8c8ae18000" + }, + "e229e746a83f2ce253b0b03eb1472411b57e5700": { + "balance": "0x1369fb96128ac480000" + }, + "e22b20c77894463baf774cc256d5bddbbf7ddd09": { + "balance": "0x3635c9adc5dea00000" + }, + "e230fe1bff03186d0219f15d4c481b7d59be286a": { + "balance": "0x1fd741e8088970000" + }, + "e237baa4dbc9926e32a3d85d1264402d54db012f": { + "balance": "0x6c6b935b8bbd400000" + }, + "e24109be2f513d87498e926a286499754f9ed49e": { + "balance": "0x300ea8ad1f27ca0000" + }, + "e246683cc99db7c4a52bcbacaab0b32f6bfc93d7": { + "balance": "0x6c6b935b8bbd400000" + }, + "e25a167b031e84616d0f013f31bda95dcc6350b9": { + "balance": "0x23c757072b8dd000000" + }, + "e25b9f76b8ad023f057eb11ad94257a0862e4e8c": { + "balance": "0x6c6b935b8bbd400000" + }, + "e26657f0ed201ea2392c9222b80a7003608ddf30": { + "balance": "0x22b1c8c1227a00000" + }, + "e26bf322774e18288769d67e3107deb7447707b8": { + "balance": "0x6c6b935b8bbd400000" + }, + "e2728a3e8c2aaac983d05dc6877374a8f446eee9": { + "balance": "0xab640391201300000" + }, + "e28b062259e96eeb3c8d4104943f9eb325893cf5": { + "balance": "0x487a9a304539440000" + }, + "e28dbc8efd5e416a762ec0e018864bb9aa83287b": { + "balance": "0x531f200ab3e030a8000" + }, + "e2904b1aefa056398b6234cb35811288d736db67": { + "balance": "0x22b1c8c1227a00000" + }, + "e29d8ae452dcf3b6ac645e630409385551faae0a": { + "balance": "0x45a0da4adf5420000" + }, + "e2bbf84641e3541f6c33e6ed683a635a70bde2ec": { + "balance": "0x1b413cfcbf59b78000" + }, + "e2cf360aa2329eb79d2bf7ca04a27a17c532e4d8": { + "balance": "0x58788cb94b1d80000" + }, + "e2df23f6ea04becf4ab701748dc0963184555cdb": { + "balance": "0x6c6b935b8bbd400000" + }, + "e2e15c60dd381e3a4be25071ab249a4c5c5264da": { + "balance": "0x7f6bc49b81b5370000" + }, + "e2e26e4e1dcf30d048cc6ecf9d51ec1205a4e926": { + "balance": "0xd8d726b7177a800000" + }, + "e2ee691f237ee6529b6557f2fcdd3dcf0c59ec63": { + "balance": "0x127729c14687c200000" + }, + "e2efa5fca79538ce6068bf31d2c516d4d53c08e5": { + "balance": "0x71cc408df63400000" + }, + "e2efd0a9bc407ece03d67e8ec8e9d283f48d2a49": { + "balance": "0x299b33bf9c584e00000" + }, + "e2f40d358f5e3fe7463ec70480bd2ed398a7063b": { + "balance": "0x1158e460913d00000" + }, + "e2f9383d5810ea7b43182b8704b62b27f5925d39": { + "balance": "0x15af1d78b58c400000" + }, + "e2ff9ee4b6ecc14141cc74ca52a9e7a2ee14d908": { + "balance": "0x4be4e7267b6ae00000" + }, + "e30212b2011bb56bdbf1bc35690f3a4e0fd905ea": { + "balance": "0x1b2df9d219f57980000" + }, + "e303167f3d4960fe881b32800a2b4aeff1b088d4": { + "balance": "0x6c6b935b8bbd400000" + }, + "e304a32f05a83762744a9542976ff9b723fa31ea": { + "balance": "0x5572f240a346200000" + }, + "e308435204793764f5fcbe65eb510f5a744a655a": { + "balance": "0xad78ebc5ac6200000" + }, + "e309974ce39d60aadf2e69673251bf0e04760a10": { + "balance": "0xdc55fdb17647b0000" + }, + "e31b4eef184c24ab098e36c802714bd4743dd0d4": { + "balance": "0xad78ebc5ac6200000" + }, + "e321bb4a946adafdade4571fb15c0043d39ee35f": { + "balance": "0x556475382b4c9e0000" + }, + "e3263ce8af6db3e467584502ed7109125eae22a5": { + "balance": "0x6c6b935b8bbd400000" + }, + "e32b1c4725a1875449e98f970eb3e54062d15800": { + "balance": "0xad78ebc5ac6200000" + }, + "e32f95766d57b5cd4b173289d6876f9e64558194": { + "balance": "0x56bc75e2d63100000" + }, + "e33840d8bca7da98a6f3d096d83de78b70b71ef8": { + "balance": "0x6c6b935b8bbd400000" + }, + "e338e859fe2e8c15554848b75caecda877a0e832": { + "balance": "0x61acff81a78ad40000" + }, + "e33d980220fab259af6a1f4b38cf0ef3c6e2ea1a": { + "balance": "0x6c6b935b8bbd400000" + }, + "e33df4ce80ccb62a76b12bcdfcecc46289973aa9": { + "balance": "0x14542ba12a337c00000" + }, + "e33ff987541dde5cdee0a8a96dcc3f33c3f24cc2": { + "balance": "0x2a5a058fc295ed000000" + }, + "e3410bb7557cf91d79fa69d0dfea0aa075402651": { + "balance": "0x6c6b935b8bbd400000" + }, + "e341642d40d2afce2e9107c67079ac7a2660086c": { + "balance": "0x15af1d78b58c400000" + }, + "e35453eef2cc3c7a044d0ac134ba615908fa82ee": { + "balance": "0x7ff1ccb7561df0000" + }, + "e36a8ea87f1e99e8a2dc1b2608d166667c9dfa01": { + "balance": "0x56bc75e2d63100000" + }, + "e3712701619ca7623c55db3a0ad30e867db0168b": { + "balance": "0x1158e460913d00000" + }, + "e37f5fdc6ec97d2f866a1cfd0d3a4da4387b22b5": { + "balance": "0x21e19e0c9bab2400000" + }, + "e3878f91ca86053fced5444686a330e09cc388fb": { + "balance": "0xa844a7424d9c80000" + }, + "e38b91b35190b6d9deed021c30af094b953fdcaa": { + "balance": "0x1ceaf795b6b860000" + }, + "e38ef28a5ed984a7db24a1ae782dfb87f397dfc6": { + "balance": "0x7c0860e5a80dc0000" + }, + "e3925509c8d0b2a6738c5f6a72f35314491248ce": { + "balance": "0x36e9a8669a44768000" + }, + "e3933d61b77dcdc716407f8250bc91e4ffaeb09d": { + "balance": "0x1256986c95891c200000" + }, + "e3951de5aefaf0458768d774c254f7157735e505": { + "balance": "0x56c95de8e8ca1d0000" + }, + "e399c81a1d701b44f0b66f3399e66b275aaaf8c1": { + "balance": "0x3635c9adc5dea00000" + }, + "e39b11a8ab1ff5e22e5ae6517214f73c5b9b55dc": { + "balance": "0x6c6b935b8bbd400000" + }, + "e39e46e15d22ce56e0c32f1877b7d1a264cf94f3": { + "balance": "0x43c33c1937564800000" + }, + "e3a4621b66004588e31206f718cb00a319889cf0": { + "balance": "0x6c6b935b8bbd400000" + }, + "e3a4f83c39f85af9c8b1b312bfe5fc3423afa634": { + "balance": "0x18d993f34aef10000" + }, + "e3a89a1927cc4e2d43fbcda1e414d324a7d9e057": { + "balance": "0xb23e2a936dec60000" + }, + "e3ab3ca9b870e3f548517306bba4de2591afafc2": { + "balance": "0x410e34aecc8cd30000" + }, + "e3b3d2c9bf570be6a2f72adca1862c310936a43c": { + "balance": "0x56d2aa3a5c09a0000" + }, + "e3c0c128327a9ad80148139e269773428e638cb0": { + "balance": "0x6c6b935b8bbd400000" + }, + "e3c812737ac606baf7522ad817428a36050e7a34": { + "balance": "0x692ae8897081d00000" + }, + "e3cffe239c64e7e20388e622117391301b298696": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e3d3eaa299887865569e88be219be507189be1c9": { + "balance": "0x18ba6fa92e93160000" + }, + "e3d8bf4efe84b1616d1b89e427ddc6c8830685ae": { + "balance": "0x6c6b935b8bbd400000" + }, + "e3d915eda3b825d6ee4af9328d32ac18ada35497": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e3da4f3240844c9b6323b4996921207122454399": { + "balance": "0x27190a952df4be58000" + }, + "e3eb2c0a132a524f72ccc0d60fee8b41685d39e2": { + "balance": "0x6acb3df27e1f880000" + }, + "e3ec18a74ed43855409a26ade7830de8e42685ef": { + "balance": "0x11164759ffb320000" + }, + "e3ece1f632711d13bfffa1f8f6840871ee58fb27": { + "balance": "0xd8d726b7177a800000" + }, + "e3f80b40fb83fb97bb0d5230af4f6ed59b1c7cc8": { + "balance": "0x487a9a304539440000" + }, + "e3ffb02cb7d9ea5243701689afd5d417d7ed2ece": { + "balance": "0x43a77aabd00780000" + }, + "e400d651bb3f2d23d5f849e6f92d9c5795c43a8a": { + "balance": "0x90f534608a72880000" + }, + "e406f5dd72cab66d8a6ecbd6bfb494a7b6b09afe": { + "balance": "0x56bc75e2d63100000" + }, + "e408aa99835307eea4a6c5eb801fe694117f707d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e408fceaa1b98f3c640f48fcba39f056066d6308": { + "balance": "0x21e19e0c9bab2400000" + }, + "e40a7c82e157540a0b00901dbb86c716e1a062da": { + "balance": "0x2b31d2425f6740000" + }, + "e41aea250b877d423a63ba2bce2f3a61c0248d56": { + "balance": "0xe18398e7601900000" + }, + "e430c0024fdbf73a82e21fccf8cbd09138421c21": { + "balance": "0xd8d726b7177a800000" + }, + "e4324912d64ea3aef76b3c2ff9df82c7e13ae991": { + "balance": "0x6c6b935b8bbd400000" + }, + "e4368bc1420b35efda95fafbc73090521916aa34": { + "balance": "0xd8d726b7177a800000" + }, + "e437acbe0f6227b0e36f36e4bcf7cf613335fb68": { + "balance": "0xad78ebc5ac6200000" + }, + "e44b7264dd836bee8e87970340ed2b9aed8ed0a5": { + "balance": "0x138e7faa01a803a0000" + }, + "e44ea51063405154aae736be2bf1ee3b9be639ae": { + "balance": "0xd8d726b7177a800000" + }, + "e4625501f52b7af52b19ed612e9d54fdd006b492": { + "balance": "0xb5a905a56ddd00000" + }, + "e4715956f52f15306ee9506bf82bccc406b3895e": { + "balance": "0xee79d4f48c5000000" + }, + "e47fbaed99fc209962604ebd20e240f74f4591f1": { + "balance": "0x6c6b935b8bbd400000" + }, + "e482d255ede56b04c3e8df151f56e9ca62aaa8c2": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e48e65125421880d42bdf1018ab9778d96928f3f": { + "balance": "0xe3aeb5737240a00000" + }, + "e492818aa684e5a676561b725d42f3cc56ae5198": { + "balance": "0x2b5e3af16b18800000" + }, + "e49936a92a8ccf710eaac342bc454b9b14ebecb1": { + "balance": "0x6c6b935b8bbd400000" + }, + "e49af4f34adaa2330b0e49dc74ec18ab2f92f827": { + "balance": "0x6c6b935b8bbd400000" + }, + "e49ba0cd96816c4607773cf8a5970bb5bc16a1e6": { + "balance": "0x5a87e7d7f5f6580000" + }, + "e4a47e3933246c3fd62979a1ea19ffdf8c72ef37": { + "balance": "0x809b383ea7d7e8000" + }, + "e4b6ae22c7735f5b89f34dd77ad0975f0acc9181": { + "balance": "0x3635c9adc5dea00000" + }, + "e4ca0a5238564dfc91e8bf22bade2901619a1cd4": { + "balance": "0x3635c9adc5dea00000" + }, + "e4cafb727fb5c6b70bb27533b8a9ccc9ef6888e1": { + "balance": "0x10497bf4af4caf8000" + }, + "e4dc22ed595bf0a337c01e03cc6be744255fc9e8": { + "balance": "0xa5aa85009e39c0000" + }, + "e4fb26d1ca1eecba3d8298d9d148119ac2bbf580": { + "balance": "0x15af1d78b58c400000" + }, + "e4fc13cfcbac1b17ce7783acd423a845943f6b3a": { + "balance": "0x1158e460913d00000" + }, + "e50b464ac9de35a5618b7cbf254674182b81b97e": { + "balance": "0xde42ee1544dd900000" + }, + "e5102c3b711b810344197419b1cd8a7059f13e32": { + "balance": "0x1043528d0984698000" + }, + "e510d6797fba3d6693835a844ea2ad540691971b": { + "balance": "0x3ae39d47383e8740000" + }, + "e51421f8ee2210c71ed870fe618276c8954afbe9": { + "balance": "0x487a9a304539440000" + }, + "e51eb87e7fb7311f5228c479b48ec9878831ac4c": { + "balance": "0x6c6b935b8bbd400000" + }, + "e5215631b14248d45a255296bed1fbfa0330ff35": { + "balance": "0x4703e6eb5291b80000" + }, + "e528a0e5a267d667e9393a6584e19b34dc9be973": { + "balance": "0x12f939c99edab800000" + }, + "e53425d8df1f11c341ff58ae5f1438abf1ca53cf": { + "balance": "0x1174a5cdf88bc80000" + }, + "e53c68796212033e4e6f9cff56e19c461eb454f9": { + "balance": "0x3635c9adc5dea00000" + }, + "e54102534de8f23effb093b31242ad3b233facfd": { + "balance": "0xd8d726b7177a800000" + }, + "e545ee84ea48e564161e9482d59bcf406a602ca2": { + "balance": "0x6449e84e47a8a80000" + }, + "e5481a7fed42b901bbed20789bd4ade50d5f83b9": { + "balance": "0x6c6b935b8bbd400000" + }, + "e559b5fd337b9c5572a9bf9e0f2521f7d446dbe4": { + "balance": "0xad78ebc5ac6200000" + }, + "e55c80520a1b0f755b9a2cd3ce214f7625653e8a": { + "balance": "0x6c6b935b8bbd400000" + }, + "e56d431324c92911a1749df292709c14b77a65cd": { + "balance": "0x1bc85dc2a89bb200000" + }, + "e57d2995b0ebdf3f3ca6c015eb04260dbb98b7c6": { + "balance": "0x6c6b935b8bbd400000" + }, + "e587b16abc8a74081e3613e14342c03375bf0847": { + "balance": "0x6c6b935b8bbd400000" + }, + "e589fa76984db5ec4004b46ee8a59492c30744ce": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "e58dd23238ee6ea7c2138d385df500c325f376be": { + "balance": "0x62a992e53a0af00000" + }, + "e5953fea497104ef9ad2d4e5841c271f073519c2": { + "balance": "0x2629f66e0c53000000" + }, + "e5968797468ef767101b761d431fce14abffdbb4": { + "balance": "0x1b3d969fa411ca00000" + }, + "e597f083a469c4591c3d2b1d2c772787befe27b2": { + "balance": "0xf2dc7d47f15600000" + }, + "e59b3bd300893f97233ef947c46f7217e392f7e9": { + "balance": "0x3635c9adc5dea00000" + }, + "e5a365343cc4eb1e770368e1f1144a77b832d7e0": { + "balance": "0x1158e460913d00000" + }, + "e5a3d7eb13b15c100177236d1beb30d17ee15420": { + "balance": "0x6c6b935b8bbd400000" + }, + "e5aa0b833bb916dc19a8dd683f0ede241d988eba": { + "balance": "0xa2a15d09519be00000" + }, + "e5b7af146986c0ff8f85d22e6cc334077d84e824": { + "balance": "0x6c6b935b8bbd400000" + }, + "e5b826196c0e1bc1119b021cf6d259a610c99670": { + "balance": "0xad78ebc5ac6200000" + }, + "e5b96fc9ac03d448c1613ac91d15978145dbdfd1": { + "balance": "0xad78ebc5ac6200000" + }, + "e5b980d28eece2c06fca6c9473068b37d4a6d6e9": { + "balance": "0x25afd68cac2b900000" + }, + "e5bab4f0afd8a9d1a381b45761aa18f3d3cce105": { + "balance": "0x51bfd7c13878d10000" + }, + "e5bcc88c3b256f6ed5fe550e4a18198b943356ad": { + "balance": "0x6c6b935b8bbd400000" + }, + "e5bdf34f4ccc483e4ca530cc7cf2bb18febe92b3": { + "balance": "0x6d835a10bbcd20000" + }, + "e5dc9349cb52e161196122cf87a38936e2c57f34": { + "balance": "0x6c6b935b8bbd400000" + }, + "e5e33800a1b2e96bde1031630a959aa007f26e51": { + "balance": "0x487a9a304539440000" + }, + "e5e37e19408f2cfbec83349dd48153a4a795a08f": { + "balance": "0xe3aeb5737240a00000" + }, + "e5edc73e626f5d3441a45539b5f7a398c593edf6": { + "balance": "0x2ee449550898e40000" + }, + "e5edf8123f2403ce1a0299becf7aac744d075f23": { + "balance": "0xada55474b81340000" + }, + "e5f8ef6d970636b0dcaa4f200ffdc9e75af1741c": { + "balance": "0x6c6b935b8bbd400000" + }, + "e5fb31a5caee6a96de393bdbf89fbe65fe125bb3": { + "balance": "0x3635c9adc5dea00000" + }, + "e5fbe34984b637196f331c679d0c0c47d83410e1": { + "balance": "0x6c6c44fe47ec050000" + }, + "e60955dc0bc156f6c41849f6bd776ba44b0ef0a1": { + "balance": "0x10431627a0933b0000" + }, + "e60a55f2df996dc3aedb696c08dde039b2641de8": { + "balance": "0x6c6b935b8bbd400000" + }, + "e6115b13f9795f7e956502d5074567dab945ce6b": { + "balance": "0x152d02c7e14af6800000" + }, + "e61f280915c774a31d223cf80c069266e5adf19b": { + "balance": "0x2fb474098f67c00000" + }, + "e62f98650712eb158753d82972b8e99ca3f61877": { + "balance": "0x6c6b935b8bbd400000" + }, + "e62f9d7c64e8e2635aeb883dd73ba684ee7c1079": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "e63e787414b9048478a50733359ecdd7e3647aa6": { + "balance": "0x55a6e79ccd1d300000" + }, + "e646665872e40b0d7aa2ff82729caaba5bc3e89e": { + "balance": "0x15af1d78b58c400000" + }, + "e64ef012658d54f8e8609c4e9023c09fe865c83b": { + "balance": "0x18493fba64ef00000" + }, + "e64f6e1d6401b56c076b64a1b0867d0b2f310d4e": { + "balance": "0x2cbad71c53ae50000" + }, + "e667f652f957c28c0e66d0b63417c80c8c9db878": { + "balance": "0x209d922f5259c50000" + }, + "e677c31fd9cb720075dca49f1abccd59ec33f734": { + "balance": "0x1a6d6beb1d42ee00000" + }, + "e67c2c1665c88338688187629f49e99b60b2d3ba": { + "balance": "0xad78ebc5ac6200000" + }, + "e69a6cdb3a8a7db8e1f30c8b84cd73bae02bc0f8": { + "balance": "0x394fdc2e452f6718000" + }, + "e69d1c378b771e0feff051db69d966ac6779f4ed": { + "balance": "0x1dfa6aaa1497040000" + }, + "e69fcc26ed225f7b2e379834c524d70c1735e5bc": { + "balance": "0x6c6b935b8bbd400000" + }, + "e6a3010f0201bc94ff67a2f699dfc206f9e76742": { + "balance": "0x2fa7cbf66464980000" + }, + "e6a6f6dd6f70a456f4ec15ef7ad5e5dbb68bd7dc": { + "balance": "0xad78ebc5ac6200000" + }, + "e6b20f980ad853ad04cbfc887ce6601c6be0b24c": { + "balance": "0xd8d726b7177a800000" + }, + "e6b3ac3f5d4da5a8857d0b3f30fc4b2b692b77d7": { + "balance": "0x4f2591f896a6500000" + }, + "e6b9545f7ed086e552924639f9a9edbbd5540b3e": { + "balance": "0xcbd47b6eaa8cc00000" + }, + "e6bcd30a8fa138c5d9e5f6c7d2da806992812dcd": { + "balance": "0x370ea0d47cf61a800000" + }, + "e6c81ffcecb47ecdc55c0b71e4855f3e5e97fc1e": { + "balance": "0x121ea68c114e510000" + }, + "e6cb260b716d4c0ab726eeeb07c8707204e276ae": { + "balance": "0x3635c9adc5dea00000" + }, + "e6cb3f3124c9c9cc3834b1274bc3336456a38bac": { + "balance": "0x172b1de0a213ff0000" + }, + "e6d22209ffd0b87509ade3a8e2ef429879cb89b5": { + "balance": "0x3a7aa9e1899ca300000" + }, + "e6d49f86c228f47367a35e886caacb271e539429": { + "balance": "0x165ec09da7a1980000" + }, + "e6e621eaab01f20ef0836b7cad47464cb5fd3c96": { + "balance": "0x11219342afa24b0000" + }, + "e6e886317b6a66a5b4f81bf164c538c264351765": { + "balance": "0x6c6b935b8bbd400000" + }, + "e6e9a39d750fe994394eb68286e5ea62a6997882": { + "balance": "0x2086ac351052600000" + }, + "e6ec5cf0c49b9c317e1e706315ef9eb7c0bf11a7": { + "balance": "0x3a469f3467e8ec00000" + }, + "e6f5eb649afb99599c414b27a9c9c855357fa878": { + "balance": "0x90f534608a72880000" + }, + "e6fe0afb9dcedd37b2e22c451ba6feab67348033": { + "balance": "0x21e19e0c9bab2400000" + }, + "e710dcd09b8101f9437bd97db90a73ef993d0bf4": { + "balance": "0x14ee36c05ac2520000" + }, + "e727e67ef911b81f6cf9c73fcbfebc2b02b5bfc6": { + "balance": "0x6c6b935b8bbd400000" + }, + "e72e1d335cc29a96b9b1c02f003a16d971e90b9d": { + "balance": "0x55a6e79ccd1d300000" + }, + "e7311c9533f0092c7248c9739b5b2c864a34b1ce": { + "balance": "0x97f97d6cc26dfe0000" + }, + "e73bfeada6f0fd016fbc843ebcf6e370a65be70c": { + "balance": "0x6acb3df27e1f880000" + }, + "e73ccf436725c151e255ccf5210cfce5a43f13e3": { + "balance": "0x1154e53217ddb0000" + }, + "e742b1e6069a8ffc3c4767235defb0d49cbed222": { + "balance": "0x2b5e3af16b18800000" + }, + "e74608f506866ada6bfbfdf20fea440be76989ef": { + "balance": "0x6c6acc67d7b1d40000" + }, + "e7533e270cc61fa164ac1553455c105d04887e14": { + "balance": "0x696d8590020bb0000" + }, + "e75c1fb177089f3e58b1067935a6596ef1737fb5": { + "balance": "0x56a879fa775470000" + }, + "e75c3b38a58a3f33d55690a5a59766be185e0284": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e761d27fa3502cc76bb1a608740e1403cf9dfc69": { + "balance": "0xf2dc7d47f15600000" + }, + "e766f34ff16f3cfcc97321721f43ddf5a38b0cf4": { + "balance": "0x54069233bf7f780000" + }, + "e76d945aa89df1e457aa342b31028a5e9130b2ce": { + "balance": "0x3708baed3d68900000" + }, + "e7735ec76518fc6aa92da8715a9ee3f625788f13": { + "balance": "0x6c4d160bafa1b78000" + }, + "e77a89bd45dc04eeb4e41d7b596b707e6e51e74c": { + "balance": "0x28a857425466f800000" + }, + "e77d7deab296c8b4fa07ca3be184163d5a6d606c": { + "balance": "0x5043904b671190000" + }, + "e77febabdf080f0f5dca1d3f5766f2a79c0ffa7c": { + "balance": "0x4b229d28a843680000" + }, + "e780a56306ba1e6bb331952c22539b858af9f77d": { + "balance": "0xa968163f0a57b400000" + }, + "e781ec732d401202bb9bd13860910dd6c29ac0b6": { + "balance": "0x433874f632cc600000" + }, + "e784dcc873aa8c1513ec26ff36bc92eac6d4c968": { + "balance": "0xad78ebc5ac6200000" + }, + "e7912d4cf4562c573ddc5b71e37310e378ef86c9": { + "balance": "0x155bd9307f9fe80000" + }, + "e791d585b89936b25d298f9d35f9f9edc25a2932": { + "balance": "0x6c6b935b8bbd400000" + }, + "e792349ce9f6f14f81d0674096befa1f9221cdea": { + "balance": "0x5b5d234a0db4388000" + }, + "e796fd4e839b4c95d7510fb7c5c72b83c6c3e3c7": { + "balance": "0x1bc433f23f83140000" + }, + "e7a42f59fee074e4fb13ea9e57ecf1cc48282249": { + "balance": "0x43c33c1937564800000" + }, + "e7a4560c84b20e0fb54c49670c2903b0a96c42a4": { + "balance": "0x206aeac7a903980000" + }, + "e7a8e471eafb798f4554cc6e526730fd56e62c7d": { + "balance": "0x3635c9adc5dea00000" + }, + "e7be82c6593c1eeddd2ae0b15001ff201ab57b2f": { + "balance": "0x10910d4cdc9f60000" + }, + "e7c6b5fc05fc748e5b4381726449a1c0ad0fb0f1": { + "balance": "0x6c6b935b8bbd400000" + }, + "e7d17524d00bad82497c0f27156a647ff51d2792": { + "balance": "0x1158e460913d00000" + }, + "e7d213947fcb904ad738480b1eed2f5c329f27e8": { + "balance": "0x103c3b1d3e9c30000" + }, + "e7d6240620f42c5edbb2ede6aec43da4ed9b5757": { + "balance": "0x3635c9adc5dea00000" + }, + "e7da609d40cde80f00ce5b4ffb6aa9d0b03494fc": { + "balance": "0x3635c9adc5dea00000" + }, + "e7f06f699be31c440b43b4db0501ec0e25261644": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e7f4d7fe6f561f7fa1da3005fd365451ad89df89": { + "balance": "0xad78ebc5ac6200000" + }, + "e7fd8fd959aed2767ea7fa960ce1db53af802573": { + "balance": "0x3635c9adc5dea00000" + }, + "e80e7fef18a5db15b01473f3ad6b78b2a2f8acd9": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e8137fc1b2ec7cc7103af921899b4a39e1d959a1": { + "balance": "0x50c5e761a444080000" + }, + "e81c2d346c0adf4cc56708f6394ba6c8c8a64a1e": { + "balance": "0x6c6b935b8bbd400000" + }, + "e82c58c579431b673546b53a86459acaf1de9b93": { + "balance": "0x3635c9adc5dea00000" + }, + "e834c64318205ca7dd4a21abcb08266cb21ff02c": { + "balance": "0x3635c6204739d98000" + }, + "e83604e4ff6be7f96f6018d3ec3072ec525dff6b": { + "balance": "0x9ddc1e3b901180000" + }, + "e845e387c4cbdf982280f6aa01c40e4be958ddb2": { + "balance": "0x54b40b1f852bda00000" + }, + "e848ca7ebff5c24f9b9c316797a43bf7c356292d": { + "balance": "0x62e115c008a880000" + }, + "e84b55b525f1039e744b918cb3332492e45eca7a": { + "balance": "0xad78ebc5ac6200000" + }, + "e84f8076a0f2969ecd333eef8de41042986291f2": { + "balance": "0x176b344f2a78c00000" + }, + "e864fec07ed1214a65311e11e329de040d04f0fd": { + "balance": "0x59ca83f5c404968000" + }, + "e87dbac636a37721df54b08a32ef4959b5e4ff82": { + "balance": "0x6c6b935b8bbd400000" + }, + "e87e9bbfbbb71c1a740c74c723426df55d063dd9": { + "balance": "0x1b1928c00c7a6380000" + }, + "e87eac6d602b4109c9671bf57b950c2cfdb99d55": { + "balance": "0x2b4f21972ecce0000" + }, + "e881bbbe69722d81efecaa48d1952a10a2bfac8f": { + "balance": "0x3635c9adc5dea000000" + }, + "e89249738b7eced7cb666a663c49cbf6de8343ea": { + "balance": "0x6c6b935b8bbd400000" + }, + "e89c22f1a4e1d4746ecfaa59ed386fee12d51e37": { + "balance": "0x26f8e87f0a7da0000" + }, + "e89da96e06beaf6bd880b378f0680c43fd2e9d30": { + "balance": "0x209a1a01a56fec0000" + }, + "e8a91da6cf1b9d65c74a02ec1f96eecb6dd241f3": { + "balance": "0x692ae8897081d00000" + }, + "e8a9a41740f44f54c3688b53e1ddd42e43c9fe94": { + "balance": "0xd8d726b7177a800000" + }, + "e8b28acda971725769db8f563d28666d41ddab6c": { + "balance": "0x21e19e0c9bab2400000" + }, + "e8be24f289443ee473bc76822f55098d89b91cc5": { + "balance": "0x6c6b935b8bbd400000" + }, + "e8c3d3b0e17f97d1e756e684f94e1470f99c95a1": { + "balance": "0x15af1d78b58c400000" + }, + "e8c3f045bb7d38c9d2f395b0ba8492b253230901": { + "balance": "0x1e7e4171bf4d3a00000" + }, + "e8cc43bc4f8acf39bff04ebfbf42aac06a328470": { + "balance": "0x15af1d78b58c400000" + }, + "e8d942d82f175ecb1c16a405b10143b3f46b963a": { + "balance": "0x1ed2e8ff6d971c0000" + }, + "e8ddbed732ebfe754096fde9086b8ea4a4cdc616": { + "balance": "0x6c6b935b8bbd400000" + }, + "e8de725eca5def805ff7941d31ac1c2e342dfe95": { + "balance": "0x857e0d6f1da76a0000" + }, + "e8e9850586e94f5299ab494bb821a5f40c00bd04": { + "balance": "0xcf152640c5c8300000" + }, + "e8ead1bb90ccc3aea2b0dcc5b58056554655d1d5": { + "balance": "0x1a4aba225c207400000" + }, + "e8eaf12944092dc3599b3953fa7cb1c9761cc246": { + "balance": "0x6194049f30f7200000" + }, + "e8ed51bbb3ace69e06024b33f86844c47348db9e": { + "balance": "0x22f9ea89f4a7d6c40000" + }, + "e8ef100d7ce0895832f2678df72d4acf8c28b8e3": { + "balance": "0x1b1b6bd7af64c70000" + }, + "e8f29969e75c65e01ce3d86154207d0a9e7c76f2": { + "balance": "0xa22fa9a73a27198000" + }, + "e8fc36b0131ec120ac9e85afc10ce70b56d8b6ba": { + "balance": "0xad78ebc5ac6200000" + }, + "e90a354cec04d69e5d96ddc0c5138d3d33150aa0": { + "balance": "0x1b1a7dcf8a44d38000" + }, + "e9133e7d31845d5f2b66a2618792e869311acf66": { + "balance": "0x517c0cbf9a390880000" + }, + "e91dac0195b19e37b59b53f7c017c0b2395ba44c": { + "balance": "0x65ea3db75546600000" + }, + "e91fa0badaddb9a97e88d3f4db7c55d6bb7430fe": { + "balance": "0x14620c57dddae00000" + }, + "e923c06177b3427ea448c0a6ff019b54cc548d95": { + "balance": "0x1f780014667f28000" + }, + "e93d47a8ca885d540c4e526f25d5c6f2c108c4b8": { + "balance": "0x17da3a04c7b3e0000000" + }, + "e9458f68bb272cb5673a04f781b403556fd3a387": { + "balance": "0x34e8b88cee2d40000" + }, + "e94941b6036019b4016a30c1037d5a6903babaad": { + "balance": "0x2a48acab6204b00000" + }, + "e9495ba5842728c0ed97be37d0e422b98d69202c": { + "balance": "0x6c6b935b8bbd400000" + }, + "e94ded99dcb572b9bb1dcba32f6dee91e057984e": { + "balance": "0x155bd9307f9fe80000" + }, + "e95179527deca5916ca9a38f215c1e9ce737b4c9": { + "balance": "0x21e19e0c9bab2400000" + }, + "e9559185f166fc9513cc71116144ce2deb0f1d4b": { + "balance": "0x43c33c1937564800000" + }, + "e95e92bbc6de07bf3a660ebf5feb1c8a3527e1c5": { + "balance": "0xfc936392801c0000" + }, + "e965daa34039f7f0df62375a37e5ab8a72b301e7": { + "balance": "0x103fddecdb3f5700000" + }, + "e969ea1595edc5c4a707cfde380929633251a2b0": { + "balance": "0xad78ebc5ac6200000" + }, + "e96b184e1f0f54924ac874f60bbf44707446b72b": { + "balance": "0x9dcc0515b56e0c0000" + }, + "e96d7d4cdd15553a4e4d316d6d6480ca3cea1e38": { + "balance": "0x2955d02e1a135a00000" + }, + "e96e2d3813efd1165f12f602f97f4a62909d3c66": { + "balance": "0x7caee97613e6700000" + }, + "e97fde0b67716325cf0ecce8a191a3761b2c791d": { + "balance": "0x3677036edf0af60000" + }, + "e982e6f28c548f5f96f45e63f7ab708724f53fa1": { + "balance": "0x157ae829a41f3b0000" + }, + "e9864c1afc8eaad37f3ba56fcb7477cc622009b7": { + "balance": "0x448586170a7dc0000" + }, + "e987e6139e6146a717fef96bc24934a5447fe05d": { + "balance": "0x6c6b935b8bbd400000" + }, + "e989733ca1d58d9e7b5029ba5d444858bec03172": { + "balance": "0x1f87408313df4f8000" + }, + "e98c91cadd924c92579e11b41217b282956cdaa1": { + "balance": "0x75c9a8480320c0000" + }, + "e99aece90541cae224b87da673965e0aeb296afd": { + "balance": "0x31df9095a18f600000" + }, + "e99de258a4173ce9ac38ede26c0b3bea3c0973d5": { + "balance": "0x59d0b805e5bb300000" + }, + "e9a2b4914e8553bf0d7c00ca532369b879f931bf": { + "balance": "0x6c6b935b8bbd400000" + }, + "e9a39a8bac0f01c349c64cedb69897f633234ed2": { + "balance": "0xd7c198710e66b00000" + }, + "e9a5ae3c9e05977dd1069e9fd9d3aefbae04b8df": { + "balance": "0x6acb3df27e1f880000" + }, + "e9ac36376efa06109d40726307dd1a57e213eaa9": { + "balance": "0xa844a7424d9c80000" + }, + "e9b1f1fca3fa47269f21b061c353b7f5e96d905a": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "e9b36fe9b51412ddca1a521d6e94bc901213dda8": { + "balance": "0x21e19e0c9bab2400000" + }, + "e9b4a4853577a9dbcc2e795be0310d1bed28641a": { + "balance": "0x3635c9adc5dea00000" + }, + "e9b6a790009bc16642c8d820b7cde0e9fd16d8f5": { + "balance": "0xc55325ca7415e00000" + }, + "e9b9a2747510e310241d2ece98f56b3301d757e0": { + "balance": "0x6c6b935b8bbd400000" + }, + "e9c35c913ca1fceab461582fe1a5815164b4fd21": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "e9c6dfae97f7099fc5f4e94b784db802923a1419": { + "balance": "0x2a53c6d724f100000" + }, + "e9c758f8da41e3346e4350e5ac3976345c6c1082": { + "balance": "0x68a0d3092826ad0000" + }, + "e9caf827be9d607915b365c83f0d3b7ea8c79b50": { + "balance": "0xa2a15d09519be00000" + }, + "e9cafe41a5e8bbd90ba02d9e06585b4eb546c57f": { + "balance": "0x6c6b935b8bbd400000" + }, + "e9d599456b2543e6db80ea9b210e908026e2146e": { + "balance": "0xad78ebc5ac6200000" + }, + "e9e1f7cb00a110edd0ebf8b377ef8a7bb856117f": { + "balance": "0xad78ebc5ac6200000" + }, + "ea14bfda0a6e76668f8788321f07df37824ec5df": { + "balance": "0x2a5a058fc295ed000000" + }, + "ea1ea0c599afb9cd36caacbbb52b5bbb97597377": { + "balance": "0x39fbae8d042dd00000" + }, + "ea1efb3ce789bedec3d67c3e1b3bc0e9aa227f90": { + "balance": "0x27ca4bd719f0b80000" + }, + "ea2c197d26e98b0da83e1b72c787618c979d3db0": { + "balance": "0x11164759ffb320000" + }, + "ea3779d14a13f6c78566bcde403591413a6239db": { + "balance": "0x29b76432b94451200000" + }, + "ea4e809e266ae5f13cdbe38f9d0456e6386d1274": { + "balance": "0xf3f20b8dfa69d00000" + }, + "ea53c954f4ed97fd4810111bdab69ef981ef25b9": { + "balance": "0x3a9d5baa4abf1d00000" + }, + "ea53d26564859d9e90bb0e53b7abf560e0162c38": { + "balance": "0x15af1d78b58c400000" + }, + "ea60436912de6bf187d3a472ff8f5333a0f7ed06": { + "balance": "0x11164759ffb320000" + }, + "ea60549ec7553f511d2149f2d4666cbd9243d93c": { + "balance": "0x6c6b935b8bbd400000" + }, + "ea66e7b84dcdbf36eea3e75b85382a75f1a15d96": { + "balance": "0x5dbc9191266f118000" + }, + "ea686c5057093c171c66db99e01b0ececb308683": { + "balance": "0x14dda85d2ce1478000" + }, + "ea6afe2cc928ac8391eb1e165fc40040e37421e7": { + "balance": "0xa27fa063b2e2e68000" + }, + "ea79057dabef5e64e7b44f7f18648e7e533718d2": { + "balance": "0xad78ebc5ac6200000" + }, + "ea7c4d6dc729cd6b157c03ad237ca19a209346c3": { + "balance": "0x6c6b935b8bbd400000" + }, + "ea8168fbf225e786459ca6bb18d963d26b505309": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ea81ca8638540cd9d4d73d060f2cebf2241ffc3e": { + "balance": "0x6acb3df27e1f880000" + }, + "ea8317197959424041d9d7c67a3ece1dbb78bb55": { + "balance": "0x155bd9307f9fe80000" + }, + "ea8527febfa1ade29e26419329d393b940bbb7dc": { + "balance": "0x6c6acc67d7b1d40000" + }, + "ea8f30b6e4c5e65290fb9864259bc5990fa8ee8a": { + "balance": "0x1158e460913d00000" + }, + "ea94f32808a2ef8a9bf0861d1d2404f7b7be258a": { + "balance": "0x1158e460913d00000" + }, + "eaa45cea02d87d2cc8fda9434e2d985bd4031584": { + "balance": "0x681fc2cc6e2b8b0000" + }, + "eab0bd148309186cf8cbd13b7232d8095acb833a": { + "balance": "0x2439a881c6a717c0000" + }, + "eabb90d37989aab31feae547e0e6f3999ce6a35d": { + "balance": "0x6c6b935b8bbd400000" + }, + "eac0827eff0c6e3ff28a7d4a54f65cb7689d7b99": { + "balance": "0x9ad9e69f9d47520000" + }, + "eac1482826acb6111e19d340a45fb851576bed60": { + "balance": "0x1be8bab04d9be8000" + }, + "eac17b81ed5191fb0802aa54337313834107aaa4": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "eac3af5784927fe9a598fc4eec38b8102f37bc58": { + "balance": "0x3635c9adc5dea00000" + }, + "eac6b98842542ea10bb74f26d7c7488f698b6452": { + "balance": "0x43c33c1937564800000" + }, + "eac768bf14b8f9432e69eaa82a99fbeb94cd0c9c": { + "balance": "0x14dbb2195ca228900000" + }, + "ead21c1deccfbf1c5cd96688a2476b69ba07ce4a": { + "balance": "0x3f24d8e4a00700000" + }, + "ead4d2eefb76abae5533961edd11400406b298fc": { + "balance": "0xd255d112e103a00000" + }, + "ead65262ed5d122df2b2751410f98c32d1238f51": { + "balance": "0x58317ed46b9b80000" + }, + "ead75016e3a0815072b6b108bcc1b799acf0383e": { + "balance": "0x6c6b935b8bbd400000" + }, + "eaea23aa057200e7c9c15e8ff190d0e66c0c0e83": { + "balance": "0x6c6b935b8bbd400000" + }, + "eaed16eaf5daab5bf0295e5e077f59fb8255900b": { + "balance": "0xd8d726b7177a800000" + }, + "eaedcc6b8b6962d5d9288c156c579d47c0a9fcff": { + "balance": "0x49b9ca9a694340000" + }, + "eaf52388546ec35aca6f6c6393d8d609de3a4bf3": { + "balance": "0x1158e460913d00000" + }, + "eb10458daca79e4a6b24b29a8a8ada711b7f2eb6": { + "balance": "0xd8bb6549b02bb80000" + }, + "eb1cea7b45d1bd4d0e2a007bd3bfb354759e2c16": { + "balance": "0xabbcd4ef377580000" + }, + "eb25481fcd9c221f1ac7e5fd1ecd9307a16215b8": { + "balance": "0xaadec983fcff40000" + }, + "eb2ef3d38fe652403cd4c9d85ed7f0682cd7c2de": { + "balance": "0x90f534608a728800000" + }, + "eb3bdd59dcdda5a9bb2ac1641fd02180f5f36560": { + "balance": "0x165c96647b38a200000" + }, + "eb3ce7fc381c51db7d5fbd692f8f9e058a4c703d": { + "balance": "0xad78ebc5ac6200000" + }, + "eb453f5a3adddd8ab56750fadb0fe7f94d9c89e7": { + "balance": "0x1158e460913d00000" + }, + "eb4f00e28336ea09942588eeac921811c522143c": { + "balance": "0x6c6b935b8bbd400000" + }, + "eb52ab10553492329c1c54833ae610f398a65b9d": { + "balance": "0x83d6c7aab63600000" + }, + "eb570dba975227b1c42d6e8dea2c56c9ad960670": { + "balance": "0x6c6b935b8bbd400000" + }, + "eb6394a7bfa4d28911d5a5b23e93f35e340c2294": { + "balance": "0x43a77aabd00780000" + }, + "eb6810691d1ae0d19e47bd22cebee0b3ba27f88a": { + "balance": "0x87856315d878150000" + }, + "eb76424c0fd597d3e341a9642ad1ee118b2b579d": { + "balance": "0xd8d726b7177a800000" + }, + "eb7c202b462b7cc5855d7484755f6e26ef43a115": { + "balance": "0x6c6b935b8bbd400000" + }, + "eb835c1a911817878a33d167569ea3cdd387f328": { + "balance": "0x3635c9adc5dea00000" + }, + "eb89a882670909cf377e9e78286ee97ba78d46c2": { + "balance": "0x2b7cc2e9c3225c0000" + }, + "eb90c793b3539761e1c814a29671148692193eb4": { + "balance": "0x28a857425466f800000" + }, + "eb9cc9fe0869d2dab52cc7aae8fd57adb35f9feb": { + "balance": "0x6a93bb17af81f80000" + }, + "eba388b0da27c87b1cc0eac6c57b2c5a0b459c1a": { + "balance": "0x170a0f5040e50400000" + }, + "ebaa216de9cc5a43031707d36fe6d5bedc05bdf0": { + "balance": "0x6ac5c62d9486070000" + }, + "ebac2b4408ef5431a13b8508e86250982114e145": { + "balance": "0xd8d726b7177a800000" + }, + "ebb62cf8e22c884b1b28c6fa88fbbc17938aa787": { + "balance": "0x2b42798403c9b80000" + }, + "ebb7d2e11bc6b58f0a8d45c2f6de3010570ac891": { + "balance": "0x1731790534df20000" + }, + "ebbb4f2c3da8be3eb62d1ffb1f950261cf98ecda": { + "balance": "0x6c6b935b8bbd400000" + }, + "ebbd4db9019952d68b1b0f6d8cf0683c00387bb5": { + "balance": "0x120401563d7d910000" + }, + "ebbeeb259184a6e01cccfc2207bbd883785ac90a": { + "balance": "0x219bc1b04783d30000" + }, + "ebd356156a383123343d48843bffed6103e866b3": { + "balance": "0x6acb3df27e1f880000" + }, + "ebd37b256563e30c6f9289a8e2702f0852880833": { + "balance": "0x6c6acc67d7b1d40000" + }, + "ebe46cc3c34c32f5add6c3195bb486c4713eb918": { + "balance": "0x3635c9adc5dea00000" + }, + "ebff84bbef423071e604c361bba677f5593def4e": { + "balance": "0x21e19e0c9bab2400000" + }, + "ec0927bac7dc36669c28354ab1be83d7eec30934": { + "balance": "0x6c6b935b8bbd400000" + }, + "ec0e18a01dc4dc5daae567c3fa4c7f8f9b590205": { + "balance": "0x111ffe404a41e60000" + }, + "ec11362cec810985d0ebbd7b73451444985b369f": { + "balance": "0x65a4e49577057318000" + }, + "ec2cb8b9378dff31aec3c22e0e6dadff314ab5dd": { + "balance": "0x6c6b935b8bbd400000" + }, + "ec30addd895b82ee319e54fb04cb2bb03971f36b": { + "balance": "0x6c6b935b8bbd400000" + }, + "ec3b8b58a12703e581ce5ffd7e21c57d1e5c663f": { + "balance": "0x5c283d410394100000" + }, + "ec4867d2175ab5b9469361595546554684cda460": { + "balance": "0xa2a15d09519be00000" + }, + "ec4d08aa2e47496dca87225de33f2b40a8a5b36f": { + "balance": "0x890b0c2e14fb80000" + }, + "ec58bc0d0c20d8f49465664153c5c196fe59e6be": { + "balance": "0x15af1d78b58c400000" + }, + "ec5b198a00cfb55a97b5d53644cffa8a04d2ab45": { + "balance": "0x6c6b935b8bbd400000" + }, + "ec5df227bfa85d7ad76b426e1cee963bc7f519dd": { + "balance": "0x3635c9adc5dea00000" + }, + "ec5feafe210c12bfc9a5d05925a123f1e73fbef8": { + "balance": "0x608fcf3d88748d000000" + }, + "ec6904bae1f69790591709b0609783733f2573e3": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ec73114c5e406fdbbe09b4fa621bd70ed54ea1ef": { + "balance": "0x53025cd216fce500000" + }, + "ec73833de4b810bb027810fc8f69f544e83c12d1": { + "balance": "0x3635c9adc5dea00000" + }, + "ec75b4a47513120ba5f86039814f1998e3817ac3": { + "balance": "0x9b0bce2e8fdba0000" + }, + "ec76f12e57a65504033f2c0bce6fc03bd7fa0ac4": { + "balance": "0xc2127af858da700000" + }, + "ec8014efc7cbe5b0ce50f3562cf4e67f8593cd32": { + "balance": "0xf015f25736420000" + }, + "ec82f50d06475f684df1b392e00da341aa145444": { + "balance": "0x6c6b935b8bbd400000" + }, + "ec83e798c396b7a55e2a2224abcd834b27ea459c": { + "balance": "0x28a857425466f800000" + }, + "ec89f2b678a1a15b9134ec5eb70c6a62071fbaf9": { + "balance": "0xad78ebc5ac6200000" + }, + "ec8c1d7b6aaccd429db3a91ee4c9eb1ca4f6f73c": { + "balance": "0xe664992288f2280000" + }, + "ec9851bd917270610267d60518b54d3ca2b35b17": { + "balance": "0x878678326eac9000000" + }, + "ec99e95dece46ffffb175eb6400fbebb08ee9b95": { + "balance": "0x56bc75e2d63100000" + }, + "eca5f58792b8c62d2af556717ee3ee3028be4dce": { + "balance": "0x6c6b935b8bbd400000" + }, + "ecab5aba5b828de1705381f38bc744b32ba1b437": { + "balance": "0x32f51edbaaa3300000" + }, + "ecaf3350b7ce144d068b186010852c84dd0ce0f0": { + "balance": "0x6c6b935b8bbd400000" + }, + "ecb94c568bfe59ade650645f4f26306c736cace4": { + "balance": "0xe7eeba3410b740000" + }, + "ecbe425e670d39094e20fb5643a9d818eed236de": { + "balance": "0x10f0cf064dd59200000" + }, + "ecbe5e1c9ad2b1dccf0a305fc9522f4669dd3ae7": { + "balance": "0x10f0cf064dd59200000" + }, + "eccf7a0457b566b346ca673a180f444130216ac3": { + "balance": "0x56bc75e2d63100000" + }, + "ecd1a62802351a41568d23033004acc6c005a5d3": { + "balance": "0x2b5e3af16b1880000" + }, + "ecd276af64c79d1bd9a92b86b5e88d9a95eb88f8": { + "balance": "0x1158e460913d00000" + }, + "ecd486fc196791b92cf612d348614f9156488b7e": { + "balance": "0x28a857425466f800000" + }, + "ecdaf93229b45ee672f65db506fb5eca00f7fce6": { + "balance": "0x5701f96dcc40ee8000" + }, + "ece111670b563ccdbebca52384290ecd68fe5c92": { + "balance": "0x1158e460913d00000" + }, + "ece1152682b7598fe2d1e21ec15533885435ac85": { + "balance": "0xd8d726b7177a800000" + }, + "ece1290877b583e361a2d41b009346e6274e2538": { + "balance": "0x1043561a8829300000" + }, + "ecf05d07ea026e7ebf4941002335baf2fed0f002": { + "balance": "0xad78ebc5ac6200000" + }, + "ecf24cdd7c22928c441e694de4aa31b0fab59778": { + "balance": "0x2086ac351052600000" + }, + "ecfd004d02f36cd4d8b4a8c1a9533b6af85cd716": { + "balance": "0x10f41acb4bb3b9c0000" + }, + "ed0206cb23315128f8caff26f6a30b985467d022": { + "balance": "0x878678326eac9000000" + }, + "ed1065dbcf9d73c04ffc7908870d881468c1e132": { + "balance": "0x6c6b935b8bbd400000" + }, + "ed1276513b6fc68628a74185c2e20cbbca7817bf": { + "balance": "0xa5aa85009e39c0000" + }, + "ed12a1ba1fb8adfcb20dfa19582e525aa3b74524": { + "balance": "0x16a6502f15a1e540000" + }, + "ed16ce39feef3bd7f5d162045e0f67c0f00046bb": { + "balance": "0x1158e460913d00000" + }, + "ed1a5c43c574d4e934299b24f1472cdc9fd6f010": { + "balance": "0xad78ebc5ac6200000" + }, + "ed1b24b6912d51b334ac0de6e771c7c0454695ea": { + "balance": "0x22b1c8c1227a00000" + }, + "ed1f1e115a0d60ce02fb25df014d289e3a0cbe7d": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "ed31305c319f9273d3936d8f5b2f71e9b1b22963": { + "balance": "0x56bc75e2d63100000" + }, + "ed327a14d5cfadd98103fc0999718d7ed70528ea": { + "balance": "0x4e1003b28d92800000" + }, + "ed3cbc3782cebd67989b305c4133b2cde32211eb": { + "balance": "0x15af1d78b58c400000" + }, + "ed4014538cee664a2fbcb6dc669f7ab16d0ba57c": { + "balance": "0xad78ebc5ac6200000" + }, + "ed41e1a28f5caa843880ef4e8b08bd6c33141edf": { + "balance": "0x2ad5ddfa7a8d830000" + }, + "ed4be04a052d7accb3dcce90319dba4020ab2c68": { + "balance": "0x7f37a70eaf362178000" + }, + "ed52a2cc0869dc9e9f842bd0957c47a8e9b0c9ff": { + "balance": "0x205b4dfa1ee74780000" + }, + "ed5b4c41e762d942404373caf21ed4615d25e6c1": { + "balance": "0x6d2d4f3d9525b40000" + }, + "ed60c4ab6e540206317e35947a63a9ca6b03e2cb": { + "balance": "0x31ad9ad0b467f8000" + }, + "ed641e06368fb0efaa1703e01fe48f4a685309eb": { + "balance": "0xad78ebc5ac6200000" + }, + "ed6643c0e8884b2d3211853785a08bf8f33ed29f": { + "balance": "0x487a9a304539440000" + }, + "ed70a37cdd1cbda9746d939658ae2a6181288578": { + "balance": "0x2086ac3510526000000" + }, + "ed7346766e1a676d0d06ec821867a276a083bf31": { + "balance": "0xd98a0931cc2d490000" + }, + "ed862616fcbfb3becb7406f73c5cbff00c940755": { + "balance": "0x5c283d410394100000" + }, + "ed9e030ca75cb1d29ea01d0d4cdfdccd3844b6e4": { + "balance": "0x1acc116cfafb18000" + }, + "ed9ebccba42f9815e78233266dd6e835b6afc31b": { + "balance": "0x14542ba12a337c00000" + }, + "ed9fb1f5af2fbf7ffc5029cee42b70ff5c275bf5": { + "balance": "0xf2dc7d47f15600000" + }, + "eda4b2fa59d684b27a810df8978a73df308a63c2": { + "balance": "0xd8d726b7177a800000" + }, + "edb473353979a206879de144c10a3c51d7d7081a": { + "balance": "0x14542ba12a337c00000" + }, + "edb71ec41bda7dce86e766e6e8c3e9907723a69b": { + "balance": "0x1158e460913d00000" + }, + "edbac9527b54d6df7ae2e000cca3613ba015cae3": { + "balance": "0x6acb3df27e1f880000" + }, + "edc22fb92c638e1e21ff5cf039daa6e734dafb29": { + "balance": "0x102794ad20da680000" + }, + "eddacd94ec89a2ef968fcf977a08f1fae2757869": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "eddbaafbc21be8f25562f1ed6d05d6afb58f02c2": { + "balance": "0x6c6b935b8bbd400000" + }, + "ede0147ec032c3618310c1ff25690bf172193dac": { + "balance": "0x6c6b935b8bbd400000" + }, + "ede5de7c7fb7eee0f36e64530a41440edfbefacf": { + "balance": "0x21755ee1ef2b180000" + }, + "ede79ae1ff4f1606d59270216fa46ab2ddd4ecaa": { + "balance": "0x7ea28327577080000" + }, + "ede8c2cb876fbe8a4cca8290361a7ea01a69fdf8": { + "balance": "0x1a78c6b44f841838000" + }, + "edeb4894aadd0081bbddd3e8846804b583d19f27": { + "balance": "0x6c6b935b8bbd400000" + }, + "edf603890228d7d5de9309942b5cad4219ef9ad7": { + "balance": "0x10f0cf064dd59200000" + }, + "edf8a3e1d40f13b79ec8e3e1ecf262fd92116263": { + "balance": "0x890b0c2e14fb80000" + }, + "edfda2d5db98f9380714664d54b4ee971a1cae03": { + "balance": "0x22bb8ddd679be0000" + }, + "ee0007b0960d00908a94432a737557876aac7c31": { + "balance": "0x2e0421e69c4cc8000" + }, + "ee049af005974dd1c7b3a9ca8d9aa77175ba53aa": { + "balance": "0x1211ecb56d13488000" + }, + "ee25b9a7032679b113588ed52c137d1a053a1e94": { + "balance": "0xad50f3f4eea8e0000" + }, + "ee31167f9cc93b3c6465609d79db0cde90e8484c": { + "balance": "0x6c6b935b8bbd400000" + }, + "ee34c7e7995db9f187cff156918cfb6f13f6e003": { + "balance": "0x6a4076cf7995a00000" + }, + "ee3564f5f1ba0f94ec7bac164bddbf31c6888b55": { + "balance": "0x56bc75e2d63100000" + }, + "ee58fb3db29070d0130188ce472be0a172b89055": { + "balance": "0x21f42dcdc58e39c0000" + }, + "ee655bb4ee0e8d5478526fb9f15e4064e09ff3dd": { + "balance": "0xad78ebc5ac6200000" + }, + "ee6959de2b67967b71948c891ab00d8c8f38c7dc": { + "balance": "0x6685ac1bfe32c0000" + }, + "ee6c03429969ca1262cb3f0a4a54afa7d348d7f5": { + "balance": "0xde219f91fc18a0000" + }, + "ee71793e3acf12a7274f563961f537529d89c7de": { + "balance": "0x6c6b935b8bbd400000" + }, + "ee7288d91086d9e2eb910014d9ab90a02d78c2a0": { + "balance": "0x6c6b935b8bbd400000" + }, + "ee7c3ded7c28f459c92fe13b4d95bafbab02367d": { + "balance": "0x25f273933db5700000" + }, + "ee867d20916bd2e9c9ece08aa04385db667c912e": { + "balance": "0xa968163f0a57b400000" + }, + "ee899b02cbcb3939cd61de1342d50482abb68532": { + "balance": "0x5f68e8131ecf800000" + }, + "ee906d7d5f1748258174be4cbc38930302ab7b42": { + "balance": "0xad78ebc5ac6200000" + }, + "ee97aa8ac69edf7a987d6d70979f8ec1fbca7a94": { + "balance": "0x14620c57dddae00000" + }, + "eea1e97988de75d821cd28ad6822b22cce988b31": { + "balance": "0x1c30731cec03200000" + }, + "eed28c3f068e094a304b853c950a6809ebcb03e0": { + "balance": "0x3a9d5baa4abf1d00000" + }, + "eed384ef2d41d9d203974e57c12328ea760e08ea": { + "balance": "0x3635c9adc5dea00000" + }, + "eedf6c4280e6eb05b934ace428e11d4231b5905b": { + "balance": "0xad78ebc5ac6200000" + }, + "eee761847e33fd61d99387ee14628694d1bfd525": { + "balance": "0x6c6b935b8bbd400000" + }, + "eee9d0526eda01e43116a395322dda8970578f39": { + "balance": "0x21e1999bbd5d2be0000" + }, + "eef1bbb1e5a83fde8248f88ee3018afa2d1332eb": { + "balance": "0xad78ebc5ac6200000" + }, + "eefba12dfc996742db790464ca7d273be6e81b3e": { + "balance": "0x3635c9adc5dea00000" + }, + "eefd05b0e3c417d55b3343060486cdd5e92aa7a6": { + "balance": "0x4d853c8f8908980000" + }, + "ef0dc7dd7a53d612728bcbd2b27c19dd4d7d666f": { + "balance": "0x26411c5b35f05a0000" + }, + "ef115252b1b845cd857f002d630f1b6fa37a4e50": { + "balance": "0x6acb3df27e1f880000" + }, + "ef1c0477f1184d60accab374d374557a0a3e10f3": { + "balance": "0x83d6c7aab63600000" + }, + "ef2c34bb487d3762c3cca782ccdd7a8fbb0a9931": { + "balance": "0x9c2007651b2500000" + }, + "ef35f6d4b1075e6aa139151c974b2f4658f70538": { + "balance": "0x3c3bc33f94e50d8000" + }, + "ef39ca9173df15531d73e6b72a684b51ba0f2bb4": { + "balance": "0x56a0b4756ee2380000" + }, + "ef463c2679fb279164e20c3d2691358773a0ad95": { + "balance": "0x6c6b935b8bbd400000" + }, + "ef47cf073e36f271d522d7fa4e7120ad5007a0bc": { + "balance": "0x878678326eac900000" + }, + "ef61155ba009dcdebef10b28d9da3d1bc6c9ced4": { + "balance": "0x3342d60dff1960000" + }, + "ef69781f32ffce33346f2c9ae3f08493f3e82f89": { + "balance": "0xfc936392801c0000" + }, + "ef76a4cd8febcbc9b818f17828f8d93473f3f3cb": { + "balance": "0xd8d726b7177a800000" + }, + "ef93818f684db0c3675ec81332b3183ecc28a495": { + "balance": "0x54069233bf7f780000" + }, + "ef9f59aeda418c1494682d941aab4924b5f4929a": { + "balance": "0x152d02c7e14af6800000" + }, + "efa6b1f0db603537826891b8b4bc163984bb40cd": { + "balance": "0x35659ef93f0fc40000" + }, + "efbd52f97da5fd3a673a46cbf330447b7e8aad5c": { + "balance": "0x56c3c9b80a0a68000" + }, + "efc8cf1963c9a95267b228c086239889f4dfd467": { + "balance": "0x21e19e0c9bab2400000" + }, + "efcaae9ff64d2cd95b5249dcffe7faa0a0c0e44d": { + "balance": "0x15be6174e1912e0000" + }, + "efcce06bd6089d0e458ef561f5a689480afe7000": { + "balance": "0x2086ac351052600000" + }, + "efe0675da98a5dda70cd96196b87f4e726b43348": { + "balance": "0x3f19beb8dd1ab00000" + }, + "efe8ff87fc260e0767638dd5d02fc4672e0ec06d": { + "balance": "0x6c6b935b8bbd400000" + }, + "efeb1997aad277cc33430e6111ed0943594048b8": { + "balance": "0x6c6b935b8bbd400000" + }, + "efeea010756f81da4ba25b721787f058170befbd": { + "balance": "0x1c29c9cf770ef0000" + }, + "eff51d72adfae143edf3a42b1aec55a2ccdd0b90": { + "balance": "0x1043561a8829300000" + }, + "eff86b5123bcdc17ed4ce8e05b7e12e51393a1f7": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "effc15e487b1beda0a8d1325bdb4172240dc540a": { + "balance": "0x3853939eee1de0000" + }, + "f01195d657ef3c942e6cb83949e5a20b5cfa8b1e": { + "balance": "0x57473d05dabae800000" + }, + "f02796295101674288c1d93467053d042219b794": { + "balance": "0x281d901f4fdd100000" + }, + "f039683d7b3d225bc7d8dfadef63163441be41e2": { + "balance": "0x1dd1e4bd8d1ee0000" + }, + "f04a6a379708b9428d722aa2b06b77e88935cf89": { + "balance": "0x1043561a8829300000" + }, + "f04d2c91efb6e9c45ffbe74b434c8c5f2b028f1f": { + "balance": "0x3635c9adc5dea00000" + }, + "f057aa66ca767ede124a1c5b9cc5fc94ef0b0137": { + "balance": "0x70a24bcab6f45d0000" + }, + "f05ba8d7b68539d933300bc9289c3d9474d0419e": { + "balance": "0x6da27024dd9600000" + }, + "f05ceeab65410564709951773c8445ad9f4ec797": { + "balance": "0x10431627a0933b0000" + }, + "f05fcd4c0d73aa167e5553c8c0d6d4f2faa39757": { + "balance": "0x2d2d66c3170b2980000" + }, + "f067e1f1d683556a4cc4fd0c0313239f32c4cfd8": { + "balance": "0x3635c9adc5dea00000" + }, + "f067fb10dfb293e998abe564c055e3348f9fbf1e": { + "balance": "0x6c6b935b8bbd400000" + }, + "f068dfe95d15cd3a7f98ffa688b4346842be2690": { + "balance": "0x440ad819e0974c0000" + }, + "f06a854a3c5dc36d1c49f4c87d6db333b57e4add": { + "balance": "0x21e19e0c9bab2400000" + }, + "f079e1b1265f50e8c8a98ec0c7815eb3aeac9eb4": { + "balance": "0x116dc3a8994b30000" + }, + "f07bd0e5c2ce69c7c4a724bd26bbfa9d2a17ca03": { + "balance": "0x14061b9d77a5e980000" + }, + "f0832a6bb25503eeca435be31b0bf905ca1fcf57": { + "balance": "0x16a6502f15a1e540000" + }, + "f09b3e87f913ddfd57ae8049c731dba9b636dfc3": { + "balance": "0x20f5b1eaad8d800000" + }, + "f0b1340b996f6f0bf0d9561c849caf7f4430befa": { + "balance": "0x56bc75e2d63100000" + }, + "f0b1f9e27832c6de6914d70afc238c749995ace4": { + "balance": "0x6c6b935b8bbd400000" + }, + "f0b469eae89d400ce7d5d66a9695037036b88903": { + "balance": "0x43c33c1937564800000" + }, + "f0b9d683cea12ba600baace219b0b3c97e8c00e4": { + "balance": "0x56bc75e2d63100000" + }, + "f0be0faf4d7923fc444622d1980cf2d990aab307": { + "balance": "0x6c6b935b8bbd400000" + }, + "f0c081da52a9ae36642adf5e08205f05c54168a6": { + "balance": "0x6046f37e5945c0000" + }, + "f0c70d0d6dab7663aa9ed9ceea567ee2c6b02765": { + "balance": "0x71438ac5a791a08000" + }, + "f0cbef84e169630098d4e301b20208ef05846ac9": { + "balance": "0xe0b8345506b4e0000" + }, + "f0d21663d8b0176e05fde1b90ef31f8530fda95f": { + "balance": "0x6c6acc67d7b1d40000" + }, + "f0d5c31ccb6cbe30c7c9ea19f268d159851f8c9c": { + "balance": "0x3894f0e6f9b9f700000" + }, + "f0d64cf9df09741133d170485fd24b005011d520": { + "balance": "0x1b089341e14fcc0000" + }, + "f0d858105e1b648101ac3f85a0f8222bf4f81d6a": { + "balance": "0x2086ac351052600000" + }, + "f0dc43f205619127507b2b1c1cfdf32d28310920": { + "balance": "0x105eb79b9417088000" + }, + "f0e1dfa42adeac2f17f6fdf584c94862fd563393": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f0e2649c7e6a3f2c5dfe33bbfbd927ca3c350a58": { + "balance": "0x6c6b935b8bbd400000" + }, + "f0e7fb9e420a5340d536f40408344feaefc06aef": { + "balance": "0x3635c9adc5dea00000" + }, + "f10462e58fcc07f39584a187639451167e859201": { + "balance": "0x934dd5d33bc970000" + }, + "f10661ff94140f203e7a482572437938bec9c3f7": { + "balance": "0x43c33c1937564800000" + }, + "f114ff0d0f24eff896edde5471dea484824a99b3": { + "balance": "0xbe202d6a0eda0000" + }, + "f116b0b4680f53ab72c968ba802e10aa1be11dc8": { + "balance": "0x1158e460913d00000" + }, + "f11cf5d363746fee6864d3ca336dd80679bb87ae": { + "balance": "0x878678326eac9000000" + }, + "f11e01c7a9d12499005f4dae7716095a34176277": { + "balance": "0x15af1d78b58c400000" + }, + "f13b083093ba564e2dc631568cf7540d9a0ec719": { + "balance": "0x6c6acc67d7b1d40000" + }, + "f14f0eb86db0eb68753f16918e5d4b807437bd3e": { + "balance": "0xad78ebc5ac6200000" + }, + "f15178ffc43aa8070ece327e930f809ab1a54f9d": { + "balance": "0xab640391201300000" + }, + "f156dc0b2a981e5b55d3f2f03b8134e331dbadb7": { + "balance": "0x56bc75e2d63100000" + }, + "f15d9d5a21b1929e790371a17f16d95f0c69655c": { + "balance": "0x6c6b935b8bbd400000" + }, + "f15e182c4fbbad79bd93342242d4dccf2be58925": { + "balance": "0x692ae8897081d00000" + }, + "f1624d980b65336feac5a6d54125005cfcf2aacb": { + "balance": "0x6c6b935b8bbd400000" + }, + "f167f5868dcf4233a7830609682caf2df4b1b807": { + "balance": "0x81e542e1a7383f0000" + }, + "f16de1891d8196461395f9b136265b3b9546f6ef": { + "balance": "0x1b28e1f98bbce8000" + }, + "f17a92e0361dbacecdc5de0d1894955af6a9b606": { + "balance": "0x6c6b935b8bbd400000" + }, + "f17adb740f45cbbde3094e7e13716f8103f563bd": { + "balance": "0x6c6b935b8bbd400000" + }, + "f18b14cbf6694336d0fe12ac1f25df2da0c05dbb": { + "balance": "0xd8d4602c26bf6c0000" + }, + "f19b39389d47b11b8a2c3f1da9124decffbefaf7": { + "balance": "0x6c6b935b8bbd400000" + }, + "f19f193508393e4d2a127b20b2031f39c82581c6": { + "balance": "0xbdbd7a83bd2f6c0000" + }, + "f1a1f320407964fd3c8f2e2cc8a4580da94f01ea": { + "balance": "0x6c6c2177557c440000" + }, + "f1b4ecc63525f7432c3d834ffe2b970fbeb87212": { + "balance": "0xa2a24068facd800000" + }, + "f1b58faffa8794f50af8e88309c7a6265455d51a": { + "balance": "0x36330322d5238c0000" + }, + "f1c8c4a941b4628c0d6c30fda56452d99c7e1b64": { + "balance": "0x4e8cea1ede75040000" + }, + "f1da40736f99d5df3b068a5d745fafc6463fc9b1": { + "balance": "0x696ca23058da10000" + }, + "f1dc8ac81042c67a9c3c6792b230c46ac016ca10": { + "balance": "0xad78ebc5ac6200000" + }, + "f1df55dcc34a051012b575cb968bc9c458ea09c9": { + "balance": "0xd8d726b7177a800000" + }, + "f1e980c559a1a8e5e50a47f8fffdc773b7e06a54": { + "balance": "0x65ffbcdea04b7480000" + }, + "f1f391ca92808817b755a8b8f4e2ca08d1fd1108": { + "balance": "0x14542ba12a337c00000" + }, + "f1f766b0e46d73fcd4d52e7a72e1b9190cc632b3": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "f2049532fd458a83ca1bff2eebacb6d5ca63f4a4": { + "balance": "0xc48c991dc1545c8000" + }, + "f206d328e471d0117b246d2a4619827709e96df3": { + "balance": "0xa2af3dc00543440000" + }, + "f20c9a99b74759d782f25c1ceca802a27e0b436c": { + "balance": "0x5a87e7d7f5f6580000" + }, + "f2127d54188fedef0f338a5f38c7ff73ad9f6f42": { + "balance": "0x43c33c1937564800000" + }, + "f2133431d1d9a37ba2f0762bc40c5acc8aa6978e": { + "balance": "0x6c6b935b8bbd400000" + }, + "f21549bdd1487912f900a7523db5f7626121bba3": { + "balance": "0x21e19e0c9bab2400000" + }, + "f218bd848ee7f9d38bfdd1c4eb2ed2496ae4305f": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f224eb900b37b4490eee6a0b6420d85c947d8733": { + "balance": "0x34957444b840e80000" + }, + "f2294adbb6f0dcc76e632ebef48ab49f124dbba4": { + "balance": "0x4e43393600a7b10000" + }, + "f22f4078febbbaa8b0e78e642c8a42f35d433905": { + "balance": "0x6c6acc67d7b1d40000" + }, + "f237ef05261c34d79cc22b860de0f17f793c3860": { + "balance": "0xad78ebc5ac6200000" + }, + "f23c7b0cb8cd59b82bd890644a57daf40c85e278": { + "balance": "0x2b66aafe326ff0000" + }, + "f23d01589eb12d439f7448ff54307529f191858d": { + "balance": "0x6c6b935b8bbd400000" + }, + "f23e5c633221a8f7363e65870c9f287424d2a960": { + "balance": "0x4acf58e07257100000" + }, + "f242da845d42d4bf779a00f295b40750fe49ea13": { + "balance": "0x3635c9adc5dea00000" + }, + "f25259a5c939cd25966c9b6303d3731c53ddbc4c": { + "balance": "0xad78ebc5ac6200000" + }, + "f25e4c70bc465632c89e5625a832a7722f6bffab": { + "balance": "0xf34b82fd8e91200000" + }, + "f26bcedce3feadcea3bc3e96eb1040dfd8ffe1a0": { + "balance": "0x2a034919dfbfbc0000" + }, + "f270792576f05d514493ffd1f5e84bec4b2df810": { + "balance": "0x3635c9adc5dea00000" + }, + "f2732cf2c13b8bb8e7492a988f5f89e38273ddc8": { + "balance": "0x2086ac351052600000" + }, + "f2742e6859c569d5f2108351e0bf4dca352a48a8": { + "balance": "0x21e19e0c9bab2400000" + }, + "f2813a64c5265d020235cb9c319b6c96f906c41e": { + "balance": "0x12f939c99edab80000" + }, + "f287ff52f461117adb3e1daa71932d1493c65f2e": { + "balance": "0xc55325ca7415e00000" + }, + "f2ab1161750244d0ecd048ee0d3e51abb143a2fd": { + "balance": "0x42fe2b907373bc0000" + }, + "f2b4ab2c9427a9015ef6eefff5edb60139b719d1": { + "balance": "0x26db992a3b18000000" + }, + "f2c03e2a38998c21648760f1e5ae7ea3077d8522": { + "balance": "0x8f3f7193ab079c0000" + }, + "f2c2904e9fa664a11ee25656d8fd2cc0d9a522a0": { + "balance": "0xb98bc829a6f90000" + }, + "f2c362b0ef991bc82fb36e66ff75932ae8dd8225": { + "balance": "0x402f4cfee62e80000" + }, + "f2d0e986d814ea13c8f466a0538c53dc922651f0": { + "balance": "0x4acf58e07257100000" + }, + "f2d1b7357724ec4c03185b879b63f57e26589153": { + "balance": "0x14542ba12a337c00000" + }, + "f2d5763ce073127e2cedde6faba786c73ca94141": { + "balance": "0x1ac4286100191f00000" + }, + "f2d59c8923759073d6f415aaf8eb065ff2f3b685": { + "balance": "0x1ab2cf7c9f87e200000" + }, + "f2e99f5cbb836b7ad36247571a302cbe4b481c69": { + "balance": "0x6acb3df27e1f880000" + }, + "f2ed3e77254acb83231dc0860e1a11242ba627db": { + "balance": "0x6b56051582a9700000" + }, + "f2edde37f9a8c39ddea24d79f4015757d06bf786": { + "balance": "0x152d02c7e14af6800000" + }, + "f2efe96560c9d97b72bd36447843885c1d90c231": { + "balance": "0x6c6b935b8bbd400000" + }, + "f2fbb6d887f8b8cc3a869aba847f3d1f643c53d6": { + "balance": "0xd8c9460063d31c0000" + }, + "f3034367f87d24d3077fa9a2e38a8b0ccb1104ef": { + "balance": "0x3635c9adc5dea00000" + }, + "f303d5a816affd97e83d9e4dac2f79072bb0098f": { + "balance": "0x340aad21b3b7000000" + }, + "f3159866c2bc86bba40f9d73bb99f1eee57bb9d7": { + "balance": "0x3635c9adc5dea00000" + }, + "f316ef1df2ff4d6c1808dba663ec8093697968e0": { + "balance": "0x61464d6cdc80f00000" + }, + "f32d25eb0ea2b8b3028a4c7a155dc1aae865784d": { + "balance": "0x13593a9297fdad60000" + }, + "f332c0f3e05a27d9126fd0b641a8c2d4060608fd": { + "balance": "0x10f1b62c4d9644e8000" + }, + "f338459f32a159b23db30ac335769ab2351aa63c": { + "balance": "0x65a4da25d3016c00000" + }, + "f33efc6397aa65fb53a8f07a0f893aae30e8bcee": { + "balance": "0x7cf2381f619f150000" + }, + "f34083ecea385017aa40bdd35ef7effb4ce7762d": { + "balance": "0x15af1d78b58c400000" + }, + "f346d7de92741c08fc58a64db55b062dde012d14": { + "balance": "0xfff6b1f761e6d0000" + }, + "f355d3ec0cfb907d8dbb1bf3464e458128190bac": { + "balance": "0x10b046e7f0d80100000" + }, + "f36df02fbd89607347afce2969b9c4236a58a506": { + "balance": "0x6c6b935b8bbd400000" + }, + "f373e9daac0c8675f53b797a160f6fc034ae6b23": { + "balance": "0x56bc75e2d63100000" + }, + "f37b426547a1642d8033324814f0ede3114fc212": { + "balance": "0x15be6174e1912e0000" + }, + "f37bf78c5875154711cb640d37ea6d28cfcb1259": { + "balance": "0xad78ebc5ac6200000" + }, + "f382df583155d8548f3f93440cd5f68cb79d6026": { + "balance": "0x38757d027fc1fd5c0000" + }, + "f382e4c20410b951089e19ba96a2fee3d91cce7e": { + "balance": "0x111fa56eec2a8380000" + }, + "f38a6ca80168537e974d14e1c3d13990a44c2c1b": { + "balance": "0x14542ba12a337c00000" + }, + "f39a9d7aa3581df07ee4279ae6c312ef21033658": { + "balance": "0xd8d726b7177a800000" + }, + "f3b668b3f14d920ebc379092db98031b67b219b3": { + "balance": "0xad6eedd17cf3b8000" + }, + "f3be99b9103ce7550aa74ff1db18e09dfe32e005": { + "balance": "0x6c6b935b8bbd400000" + }, + "f3c1abd29dc57b41dc192d0e384d021df0b4f6d4": { + "balance": "0x97ae0cdf8f86f80000" + }, + "f3c4716d1ee5279a86d0163a14618181e16136c7": { + "balance": "0x3635c9adc5dea00000" + }, + "f3cc8bcb559465f81bfe583bd7ab0a2306453b9e": { + "balance": "0x43c33c1937564800000" + }, + "f3d688f06bbdbf50f9932c4145cbe48ecdf68904": { + "balance": "0x1158e460913d00000" + }, + "f3dbcf135acb9dee1a489c593c024f03c2bbaece": { + "balance": "0x6c6b935b8bbd400000" + }, + "f3de5f26ef6aded6f06d3b911346ee70401da4a0": { + "balance": "0x133ab37d9f9d030000" + }, + "f3df63a97199933330383b3ed7570b96c4812334": { + "balance": "0x6c6b935b8bbd400000" + }, + "f3e74f470c7d3a3f0033780f76a89f3ef691e6cb": { + "balance": "0xa3cfe631d143640000" + }, + "f3eb1948b951e22df1617829bf3b8d8680ec6b68": { + "balance": "0xd8d726b7177a800000" + }, + "f3f1fa3918ca34e2cf7e84670b1f4d8eca160db3": { + "balance": "0x24dce54d34a1a00000" + }, + "f3f24fc29e20403fc0e8f5ebbb553426f78270a2": { + "balance": "0x56bc75e2d63100000" + }, + "f3fa723552a5d0512e2b62f48dca7b2b8105305b": { + "balance": "0x76d41c62494840000" + }, + "f3fe51fde34413c73318b9c85437fe7e820f561a": { + "balance": "0x3662325cd18fe00000" + }, + "f400f93d5f5c7e3fc303129ac8fb0c2f786407fa": { + "balance": "0x6c6b935b8bbd400000" + }, + "f40b134fea22c6b29c8457f49f000f9cda789adb": { + "balance": "0x2086ac351052600000" + }, + "f41557dfdfb1a1bdcefefe2eba1e21fe0a4a9942": { + "balance": "0x6acb3df27e1f880000" + }, + "f4177a0d85d48b0e264211ce2aa2efd3f1b47f08": { + "balance": "0xc2ccca26b7e80e8000" + }, + "f42f905231c770f0a406f2b768877fb49eee0f21": { + "balance": "0xaadec983fcff40000" + }, + "f432b9dbaf11bdbd73b6519fc0a904198771aac6": { + "balance": "0x83d6c7aab63600000" + }, + "f43da3a4e3f5fab104ca9bc1a0f7f3bb4a56f351": { + "balance": "0x6c6acc67d7b1d40000" + }, + "f447108b98df64b57e871033885c1ad71db1a3f9": { + "balance": "0x176f49ead3483508000" + }, + "f44f8551ace933720712c5c491cdb6f2f951736c": { + "balance": "0xd8d726b7177a800000" + }, + "f456055a11ab91ff668e2ec922961f2a23e3db25": { + "balance": "0xfc936392801c0000" + }, + "f456a75bb99655a7412ce97da081816dfdb2b1f2": { + "balance": "0xad78ebc5ac6200000" + }, + "f45b1dcb2e41dc27ffa024daadf619c11175c087": { + "balance": "0x11164759ffb320000" + }, + "f463a90cb3f13e1f0643423636beab84c123b06d": { + "balance": "0x22b1c8c1227a00000" + }, + "f468906e7edf664ab0d8be3d83eb7ab3f7ffdc78": { + "balance": "0x5c283d410394100000" + }, + "f46980e3a4a9d29a6a6e90604537a3114bcb2897": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f46b6b9c7cb552829c1d3dfd8ffb11aabae782f6": { + "balance": "0x1236efcbcbb340000" + }, + "f476e1267f86247cc908816f2e7ad5388c952db0": { + "balance": "0xd8d726b7177a800000" + }, + "f476f2cb7208a32e051fd94ea8662992638287a2": { + "balance": "0x56bc75e2d63100000" + }, + "f47bb134da30a812d003af8dccb888f44bbf5724": { + "balance": "0x11959b7fe3395580000" + }, + "f483f607a21fcc28100a018c568ffbe140380410": { + "balance": "0x3635c9adc5dea00000" + }, + "f48e1f13f6af4d84b371d7de4b273d03a263278e": { + "balance": "0x2086ac351052600000" + }, + "f49c47b3efd86b6e6a5bc9418d1f9fec814b69ef": { + "balance": "0x43c33c1937564800000" + }, + "f49f6f9baabc018c8f8e119e0115f491fc92a8a4": { + "balance": "0x21e19e0c9bab2400000" + }, + "f4a367b166d2991a2bfda9f56463a09f252c1b1d": { + "balance": "0x6acb3df27e1f880000" + }, + "f4a51fce4a1d5b94b0718389ba4e7814139ca738": { + "balance": "0x1043561a8829300000" + }, + "f4a9d00cefa97b7a58ef9417fc6267a5069039ee": { + "balance": "0x12e89287fa7840000" + }, + "f4aaa3a6163e3706577b49c0767e948a681e16ee": { + "balance": "0x6c6b935b8bbd400000" + }, + "f4b1626e24f30bcad9273c527fcc714b5d007b8f": { + "balance": "0xad78ebc5ac6200000" + }, + "f4b49100757772f33c177b9a76ba95226c8f3dd8": { + "balance": "0x16b352da5e0ed300000" + }, + "f4b6cdcfcb24230b337d770df6034dfbd4e1503f": { + "balance": "0x405fdf7e5af85e00000" + }, + "f4b759cc8a1c75f80849ebbcda878dc8f0d66de4": { + "balance": "0x15af1d78b58c400000" + }, + "f4ba6a46d55140c439cbcf076cc657136262f4f8": { + "balance": "0x6c6b935b8bbd400000" + }, + "f4d67a9044b435b66e8977ff39a28dc4bd53729a": { + "balance": "0xad78ebc5ac6200000" + }, + "f4d97664cc4eec9edbe7fa09f4750a663b507d79": { + "balance": "0xd8d726b7177a800000" + }, + "f4dc7ba85480bbb3f535c09568aaa3af6f3721c6": { + "balance": "0x1871fb6307e35e50000" + }, + "f4ebf50bc7e54f82e9b9bd24baef29438e259ce6": { + "balance": "0x21e19e0c9bab2400000" + }, + "f4ec8e97a20aa5f8dd206f55207e06b813df2cc0": { + "balance": "0xad78ebc5ac6200000" + }, + "f4ed848ec961739c2c7e352f435ba70a7cd5db38": { + "balance": "0x6acb3df27e1f880000" + }, + "f4fc4d39bc0c2c4068a36de50e4ab4d4db7e340a": { + "balance": "0x16037df87ef6a0000" + }, + "f504943aaf16796e0b341bbcdf21d11cc586cdd1": { + "balance": "0x1e7e4171bf4d3a00000" + }, + "f5061ee2e5ee26b815503677130e1de07a52db07": { + "balance": "0x56bc75e2d63100000" + }, + "f509557e90183fbf0f0651a786487bcc428ba175": { + "balance": "0xa844a7424d9c80000" + }, + "f50abbd4aa45d3eb88515465a8ba0b310fd9b521": { + "balance": "0x16a6502f15a1e540000" + }, + "f50ae7fab4cfb5a646ee04ceadf9bf9dd5a8e540": { + "balance": "0xd8d67c2f5895480000" + }, + "f50cbafd397edd556c0678988cb2af5c2617e0a2": { + "balance": "0x26d07efe782bb00000" + }, + "f51fded80acb502890e87369741f3722514cefff": { + "balance": "0x43c3456ca3c6d110000" + }, + "f52a5882e8927d944b359b26366ba2b9cacfbae8": { + "balance": "0x54b41ce2fe63ba80000" + }, + "f52c0a7877345fe0c233bb0f04fd6ab18b6f14ba": { + "balance": "0x54cbe55989f38de00000" + }, + "f5437e158090b2a2d68f82b54a5864b95dd6dbea": { + "balance": "0xd96c16703b2bfe0000" + }, + "f54c19d9ef3873bfd1f7a622d02d86249a328f06": { + "balance": "0x960ae127af32fb28000" + }, + "f5500178cb998f126417831a08c2d7abfff6ab5f": { + "balance": "0x46f4f4a5875a9f8000" + }, + "f5534815dc635efa5cc84b2ac734723e21b29372": { + "balance": "0x55a6e79ccd1d300000" + }, + "f555a27bb1e2fd4e2cc784caee92939fc06e2fc9": { + "balance": "0x6c6b935b8bbd400000" + }, + "f558a2b2dd26dd9593aae04531fd3c3cc3854b67": { + "balance": "0xabbcd4ef377580000" + }, + "f56048dd2181d4a36f64fcecc6215481e42abc15": { + "balance": "0xad78ebc5ac6200000" + }, + "f56442f60e21691395d0bffaa9194dcaff12e2b7": { + "balance": "0xe18398e7601900000" + }, + "f579714a45eb8f52c3d57bbdefd2c15b2e2f11df": { + "balance": "0x54915956c409600000" + }, + "f593c65285ee6bbd6637f3be8f89ad40d489f655": { + "balance": "0xa2a15d09519be00000" + }, + "f598db2e09a8a5ee7d720d2b5c43bb126d11ecc2": { + "balance": "0xad78ebc5ac6200000" + }, + "f59dab1bf8df11327e61f9b7a14b563a96ec3554": { + "balance": "0x14542ba12a337c00000" + }, + "f59f9f02bbc98efe097eabb78210979021898bfd": { + "balance": "0x21e171a3ec9f72c0000" + }, + "f5a5459fcdd5e5b273830df88eea4cb77ddadfb9": { + "balance": "0x409e52b48369a0000" + }, + "f5a7676ad148ae9c1ef8b6f5e5a0c2c473be850b": { + "balance": "0xad78ebc5ac6200000" + }, + "f5b068989df29c253577d0405ade6e0e7528f89e": { + "balance": "0x57473d05dabae80000" + }, + "f5b6e9061a4eb096160777e26762cf48bdd8b55d": { + "balance": "0xdc55fdb17647b0000" + }, + "f5cffbba624e7eb321bc83c60ca68199b4e36671": { + "balance": "0x6c6b935b8bbd400000" + }, + "f5d14552b1dce0d6dc1f320da6ffc8a331cd6f0c": { + "balance": "0x487a9a304539440000" + }, + "f5d61ac4ca95475e5b7bffd5f2f690b316759615": { + "balance": "0x692ae8897081d000000" + }, + "f5d9cf00d658dd45517a48a9d3f5f633541a533d": { + "balance": "0x64f5fdf494f780000" + }, + "f5eadcd2d1b8657a121f33c458a8b13e76b65526": { + "balance": "0xd8b0f5a5ac24a0000" + }, + "f607c2150d3e1b99f24fa1c7d540add35c4ebe1e": { + "balance": "0xa7f1aa07fc8faa0000" + }, + "f60bd735543e6bfd2ea6f11bff627340bc035a23": { + "balance": "0x6c6b935b8bbd400000" + }, + "f60c1b45f164b9580e20275a5c39e1d71e35f891": { + "balance": "0x6c6b935b8bbd400000" + }, + "f60f62d73937953fef35169e11d872d2ea317eec": { + "balance": "0x121ea68c114e5100000" + }, + "f61283b4bd8504058ca360e993999b62cbc8cd67": { + "balance": "0xdd2d5fcf3bc9c0000" + }, + "f617b967b9bd485f7695d2ef51fb7792d898f500": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f618d9b104411480a863e623fc55232d1a4f48aa": { + "balance": "0xe689e6d44b1668000" + }, + "f622e584a6623eaaf99f2be49e5380c5cbcf5cd8": { + "balance": "0xad78ebc5ac6200000" + }, + "f632adff490da4b72d1236d04b510f74d2faa3cd": { + "balance": "0x4be4e7267b6ae00000" + }, + "f639ac31da9f67271bd10402b7654e5ce763bd47": { + "balance": "0x15af0f42baf9260000" + }, + "f63a579bc3eac2a9490410128dbcebe6d9de8243": { + "balance": "0x50c5e761a444080000" + }, + "f645dd7c890093e8e4c8aa92a6bb353522d3dc98": { + "balance": "0x7439fa2099e580000" + }, + "f648ea89c27525710172944e79edff847803b775": { + "balance": "0x152d02c7e14af6800000" + }, + "f64a4ac8d540a9289c68d960d5fb7cc45a77831c": { + "balance": "0x6c6b935b8bbd400000" + }, + "f64ecf2117931c6d535a311e4ffeaef9d49405b8": { + "balance": "0x90f534608a72880000" + }, + "f64fe0939a8d1eea2a0ecd9a9730fd7958e33109": { + "balance": "0x11de1e6db450c0000" + }, + "f65616be9c8b797e7415227c9138faa0891742d7": { + "balance": "0x2ad373ce668e980000" + }, + "f657fcbe682eb4e8db152ecf892456000b513d15": { + "balance": "0x692ae8897081d00000" + }, + "f65819ac4cc14c137f05dd7977c7dae08d1a4ab5": { + "balance": "0x58788cb94b1d80000" + }, + "f67bb8e2118bbcd59027666eedf6943ec9f880a5": { + "balance": "0xd8d726b7177a800000" + }, + "f68464bf64f2411356e4d3250efefe5c50a5f65b": { + "balance": "0x1158e460913d00000" + }, + "f686785b89720b61145fea80978d6acc8e0bc196": { + "balance": "0xd8d726b7177a800000" + }, + "f68c5e33fa97139df5b2e63886ce34ebf3e4979c": { + "balance": "0xb3fa4169e2d8e00000" + }, + "f6a8635757c5e8c134d20d028cf778cf8609e46a": { + "balance": "0x4f1d772faec17c0000" + }, + "f6b782f4dcd745a6c0e2e030600e04a24b25e542": { + "balance": "0x15af1d78b58c400000" + }, + "f6bc37b1d2a3788d589b6de212dc1713b2f6e78e": { + "balance": "0x10f0cf064dd59200000" + }, + "f6c3c48a1ac0a34799f04db86ec7a975fe7768f3": { + "balance": "0x6acb3df27e1f880000" + }, + "f6d25d3f3d846d239f525fa8cac97bc43578dbac": { + "balance": "0x30927f74c9de000000" + }, + "f6eaac7032d492ef17fd6095afc11d634f56b382": { + "balance": "0x1b1b6bd7af64c70000" + }, + "f6ead67dbf5b7eb13358e10f36189d53e643cfcf": { + "balance": "0x878678326eac9000000" + }, + "f6f1a44309051c6b25e47dff909b179bb9ab591c": { + "balance": "0x692ae8897081d00000" + }, + "f70328ef97625fe745faa49ee0f9d4aa3b0dfb69": { + "balance": "0x3635c9adc5dea00000" + }, + "f70a998a717b338d1dd99854409b1a338deea4b0": { + "balance": "0x6c6b935b8bbd400000" + }, + "f70d637a845c06db6cdc91e6371ce7c4388a628e": { + "balance": "0x1158e460913d00000" + }, + "f7155213449892744bc60f2e04400788bd041fdd": { + "balance": "0x39fbae8d042dd0000" + }, + "f71b4534f286e43093b1e15efea749e7597b8b57": { + "balance": "0x161c13d3341c87280000" + }, + "f734ec03724ddee5bb5279aa1afcf61b0cb448a1": { + "balance": "0xe5bf2cc9b097800000" + }, + "f736dc96760012388fe88b66c06efe57e0d7cf0a": { + "balance": "0x71d75ab9b920500000" + }, + "f73ac46c203be1538111b151ec8220c786d84144": { + "balance": "0xff7377817b82b8000" + }, + "f73dd9c142b71bce11d06e30e7e7d032f2ec9c9e": { + "balance": "0x6acb3df27e1f880000" + }, + "f7418aa0e713d248228776b2e7434222ae75e3a5": { + "balance": "0x6c6b935b8bbd400000" + }, + "f74e6e145382b4db821fe0f2d98388f45609c69f": { + "balance": "0x56bc75e2d63100000" + }, + "f7500c166f8bea2f82347606e5024be9e4f4ce99": { + "balance": "0x1158e460913d00000" + }, + "f757fc8720d3c4fa5277075e60bd5c411aebd977": { + "balance": "0x6c6b935b8bbd400000" + }, + "f75bb39c799779ebc04a336d260da63146ed98d0": { + "balance": "0x15af1d78b58c40000" + }, + "f768f321fd6433d96b4f354d3cc1652c1732f57f": { + "balance": "0x21e19e0c9bab2400000" + }, + "f76f69cee4faa0a63b30ae1e7881f4f715657010": { + "balance": "0xad78ebc5ac6200000" + }, + "f777361a3dd8ab62e5f1b9b047568cc0b555704c": { + "balance": "0x3635c9adc5dea00000" + }, + "f77c7b845149efba19e261bc7c75157908afa990": { + "balance": "0x6c6b935b8bbd400000" + }, + "f77f9587ff7a2d7295f1f571c886bd33926a527c": { + "balance": "0x6c68ccd09b022c0000" + }, + "f78258c12481bcdddbb72a8ca0c043097261c6c5": { + "balance": "0x1158e460913d00000" + }, + "f798d16da4e460c460cd485fae0fa0599708eb82": { + "balance": "0x3635c9adc5dea00000" + }, + "f7a1ade2d0f529123d1055f19b17919f56214e67": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f7acff934b84da0969dc37a8fcf643b7d7fbed41": { + "balance": "0x6c6acc67d7b1d40000" + }, + "f7b151cc5e571c17c76539dbe9964cbb6fe5de79": { + "balance": "0x74717cfb6883100000" + }, + "f7b29b82195c882dab7897c2ae95e77710f57875": { + "balance": "0x7735416132dbfc0000" + }, + "f7bc4c44910d5aedd66ed2355538a6b193c361ec": { + "balance": "0x541de2c2d8d620000" + }, + "f7c00cdb1f020310d5acab7b496aaa44b779085e": { + "balance": "0x5a87e7d7f5f6580000" + }, + "f7c1b443968b117b5dd9b755572fcd39ca5ec04b": { + "balance": "0x18b968c292f1b50000" + }, + "f7c50f922ad16b61c6d1baa045ed816815bac48f": { + "balance": "0x2a9396a9784ad7d0000" + }, + "f7c708015071d4fb0a3a2a09a45d156396e3349e": { + "balance": "0xa2a15d09519be00000" + }, + "f7cbdba6be6cfe68dbc23c2b0ff530ee05226f84": { + "balance": "0x1158e460913d00000" + }, + "f7d0d310acea18406138baaabbfe0571e80de85f": { + "balance": "0x487a9a304539440000" + }, + "f7d7af204c56f31fd94398e40df1964bd8bf123c": { + "balance": "0x821d221b5291f8000" + }, + "f7dc251196fbcbb77c947d7c1946b0ff65021cea": { + "balance": "0x3635c9adc5dea00000" + }, + "f7e45a12aa711c709acefe95f33b78612d2ad22a": { + "balance": "0xe0655e2f26bc9180000" + }, + "f7f4898c4c526d955f21f055cb6e47b915e51964": { + "balance": "0x7c0860e5a80dc00000" + }, + "f7f91e7acb5b8129a306877ce3168e6f438b66a1": { + "balance": "0x98a7d9b8314c00000" + }, + "f7fc45abf76f5088e2e5b5a8d132f28a4d4ec1c0": { + "balance": "0x6c6b935b8bbd400000" + }, + "f8063af4cc1dd9619ab5d8bff3fcd1faa8488221": { + "balance": "0x6c6b935b8bbd400000" + }, + "f8086e42661ea929d2dda1ab6c748ce3055d111e": { + "balance": "0x3635c9adc5dea00000" + }, + "f8087786b42da04ed6d1e0fe26f6c0eefe1e9f5a": { + "balance": "0x21e19e0c9bab2400000" + }, + "f80d3619702fa5838c48391859a839fb9ce7160f": { + "balance": "0x6c07a7d1b16e700000" + }, + "f814799f6ddf4dcb29c7ee870e75f9cc2d35326d": { + "balance": "0x3635c9adc5dea00000" + }, + "f815c10a032d13c34b8976fa6e3bd2c9131a8ba9": { + "balance": "0x487a9a304539440000" + }, + "f81622e55757daea6675975dd93538da7d16991e": { + "balance": "0x6c6b935b8bbd400000" + }, + "f824ee331e4ac3cc587693395b57ecf625a6c0c2": { + "balance": "0x56c95de8e8ca1d0000" + }, + "f827d56ed2d32720d4abf103d6d0ef4d3bcd559b": { + "balance": "0x16c80065791a28000" + }, + "f8298591523e50b103f0b701d623cbf0f74556f6": { + "balance": "0xad78ebc5ac6200000" + }, + "f848fce9ab611c7d99206e23fac69ad488b94fe1": { + "balance": "0x2a1129d0936720000" + }, + "f84f090adf3f8db7e194b350fbb77500699f66fd": { + "balance": "0x6acb3df27e1f880000" + }, + "f851b010f633c40af1a8f06a73ebbaab65077ab5": { + "balance": "0xee86442fcd06c00000" + }, + "f858171a04d357a13b4941c16e7e55ddd4941329": { + "balance": "0x246a5218f2a000000" + }, + "f85bab1cb3710fc05fa19ffac22e67521a0ba21d": { + "balance": "0x6c95357fa6b36c0000" + }, + "f86a3ea8071f7095c7db8a05ae507a8929dbb876": { + "balance": "0x1236efcbcbb3400000" + }, + "f8704c16d2fd5ba3a2c01d0eb20484e6ecfa3109": { + "balance": "0xad78ebc5ac6200000" + }, + "f870995fe1e522321d754337a45c0c9d7b38951c": { + "balance": "0x1158e460913d00000" + }, + "f873e57a65c93b6e18cb75f0dc077d5b8933dc5c": { + "balance": "0xaadec983fcff40000" + }, + "f875619d8a23e45d8998d184d480c0748970822a": { + "balance": "0xd8d726b7177a800000" + }, + "f87bb07b289df7301e54c0efda6a2cf291e89200": { + "balance": "0x4be4e7267b6ae00000" + }, + "f88900db737955b1519b1a7d170a18864ce590eb": { + "balance": "0xfc936392801c0000" + }, + "f88b58db37420b464c0be88b45ee2b95290f8cfa": { + "balance": "0x22b1c8c1227a00000" + }, + "f8962b75db5d24c7e8b7cef1068c3e67cebb30a5": { + "balance": "0xf2dc7d47f15600000" + }, + "f8a065f287d91d77cd626af38ffa220d9b552a2b": { + "balance": "0x678a932062e4180000" + }, + "f8a49ca2390c1f6d5c0e62513b079571743f7cc6": { + "balance": "0xa2a15d09519be00000" + }, + "f8a50cee2e688ceee3aca4d4a29725d4072cc483": { + "balance": "0x6c6b935b8bbd400000" + }, + "f8ac4a39b53c11307820973b441365cffe596f66": { + "balance": "0x6c6b935b8bbd400000" + }, + "f8ae857b67a4a2893a3fbe7c7a87ff1c01c6a6e7": { + "balance": "0xd8d726b7177a800000" + }, + "f8bf9c04874e5a77f38f4c38527e80c676f7b887": { + "balance": "0x6c6b935b8bbd400000" + }, + "f8c7f34a38b31801da43063477b12b27d0f203ff": { + "balance": "0x1ad2baba6fef480000" + }, + "f8ca336c8e91bd20e314c20b2dd4608b9c8b9459": { + "balance": "0x2ddc9bc5b32c780000" + }, + "f8d17424c767bea31205739a2b57a7277214eebe": { + "balance": "0x246ddf97976680000" + }, + "f8d52dcc5f96cc28007b3ecbb409f7e22a646caa": { + "balance": "0x81690e18128480000" + }, + "f8dce867f0a39c5bef9eeba609229efa02678b6c": { + "balance": "0x6c6b935b8bbd400000" + }, + "f8f226142a428434ab17a1864a2597f64aab2f06": { + "balance": "0x9598b2fb2e9f28000" + }, + "f8f6645e0dee644b3dad81d571ef9baf840021ad": { + "balance": "0x6c6b935b8bbd400000" + }, + "f901c00fc1db88b69c4bc3252b5ca70ea6ee5cf6": { + "balance": "0x15af1d78b58c400000" + }, + "f93d5bcb0644b0cce5fcdda343f5168ffab2877d": { + "balance": "0xb6207b67d26f90000" + }, + "f9570e924c95debb7061369792cf2efec2a82d5e": { + "balance": "0x1158e460913d00000" + }, + "f9642086b1fbae61a6804dbe5fb15ec2d2b537f4": { + "balance": "0x6c6b935b8bbd400000" + }, + "f96488698590dc3b2c555642b871348dfa067ad5": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f964d98d281730ba35b2e3a314796e7b42fedf67": { + "balance": "0x53b0876098d80c0000" + }, + "f9650d6989f199ab1cc479636ded30f241021f65": { + "balance": "0x2e141ea081ca080000" + }, + "f96883582459908c827627e86f28e646f9c7fc7a": { + "balance": "0x1c4a78737cdcfb80000" + }, + "f96b4c00766f53736a8574f822e6474c2f21da2d": { + "balance": "0x15af1d78b58c400000" + }, + "f9729d48282c9e87166d5eef2d01eda9dbf78821": { + "balance": "0x56b83ddc728548000" + }, + "f9767e4ecb4a5980527508d7bec3d45e4c649c13": { + "balance": "0x678a932062e4180000" + }, + "f978b025b64233555cc3c19ada7f4199c9348bf7": { + "balance": "0x54b40b1f852bda000000" + }, + "f97b56ebd5b77abc9fbacbabd494b9d2c221cd03": { + "balance": "0x6acb3df27e1f880000" + }, + "f9811fa19dadbf029f8bfe569adb18228c80481a": { + "balance": "0xad78ebc5ac6200000" + }, + "f98250730c4c61c57f129835f2680894794542f3": { + "balance": "0xd8d726b7177a800000" + }, + "f989346772995ec1906faffeba2a7fe7de9c6bab": { + "balance": "0x16a6502f15a1e540000" + }, + "f998ca3411730a6cd10e7455b0410fb0f6d3ff80": { + "balance": "0x6c6b935b8bbd400000" + }, + "f99aee444b5783c093cfffd1c4632cf93c6f050c": { + "balance": "0x15af1d78b58c400000" + }, + "f99eeece39fa7ef5076d855061384009792cf2e0": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f9a59c3cc5ffacbcb67be0fc7256f64c9b127cb4": { + "balance": "0x6c6b935b8bbd400000" + }, + "f9a94bd56198da245ed01d1e6430b24b2708dcc0": { + "balance": "0x28a77afda87ee50000" + }, + "f9b37825f03073d31e249378c30c795c33f83af2": { + "balance": "0xad9aabf8c9bfc0000" + }, + "f9b617f752edecae3e909fbb911d2f8192f84209": { + "balance": "0x90f534608a72880000" + }, + "f9bfb59d538afc4874d4f5941b08c9730e38e24b": { + "balance": "0x22b1c8c1227a00000" + }, + "f9dd239008182fb519fb30eedd2093fed1639be8": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "f9debaecb5f339beea4894e5204bfa340d067f25": { + "balance": "0x5a42844673b1640000" + }, + "f9e37447406c412197b2e2aebc001d6e30c98c60": { + "balance": "0x1c479bb4349c0ee0000" + }, + "f9e7222faaf0f4da40c1c4a40630373a09bed7b6": { + "balance": "0x9b4fdcb09456240000" + }, + "f9ece022bccd2c92346911e79dd50303c01e0188": { + "balance": "0x3635c9adc5dea00000" + }, + "fa00c376e89c05e887817a9dd0748d96f341aa89": { + "balance": "0x104d0d00d2b7f60000" + }, + "fa0c1a988c8a17ad3528eb28b3409daa58225f26": { + "balance": "0xad78ebc5ac6200000" + }, + "fa105f1a11b6e4b1f56012a27922e2ac2da4812f": { + "balance": "0x205b4dfa1ee74780000" + }, + "fa142fe47eda97e6503b386b18a2bedd73ccb5b1": { + "balance": "0x2e153ad81548100000" + }, + "fa14b566234abee73042c31d21717182cba14aa1": { + "balance": "0x11c7ea162e78200000" + }, + "fa19d6f7a50f4f079893d167bf14e21d0073d196": { + "balance": "0x1cbb3a3ff08d080000" + }, + "fa1f1971a775c3504fef5079f640c2c4bce7ac05": { + "balance": "0x6c6b935b8bbd400000" + }, + "fa279bfd8767f956bf7fa0bd5660168da75686bd": { + "balance": "0x90f534608a72880000" + }, + "fa27cc49d00b6c987336a875ae39da58fb041b2e": { + "balance": "0x21e19e0c9bab2400000" + }, + "fa283299603d8758e8cab082125d2c8f7d445429": { + "balance": "0x15bcacb1e0501ae8000" + }, + "fa2bbca15d3fe39f8a328e91f90da14f7ac6253d": { + "balance": "0xad78ebc5ac6200000" + }, + "fa2fd29d03fee9a07893df3a269f56b72f2e1e64": { + "balance": "0x21e19e0c9bab2400000" + }, + "fa33553285a973719a0d5f956ff861b2d89ed304": { + "balance": "0x1158e460913d00000" + }, + "fa3a0c4b903f6ea52ea7ab7b8863b6a616ad6650": { + "balance": "0x1158e460913d00000" + }, + "fa3a1aa4488b351aa7560cf5ee630a2fd45c3222": { + "balance": "0x2fa47e6aa7340d0000" + }, + "fa410971ad229c3036f41acf852f2ac999281950": { + "balance": "0xd8b311a8ddfa7c0000" + }, + "fa44a855e404c86d0ca8ef3324251dfb349c539e": { + "balance": "0x542253a126ce400000" + }, + "fa5201fe1342af11307b9142a041243ca92e2f09": { + "balance": "0x2038116a3ac043980000" + }, + "fa60868aafd4ff4c5c57914b8ed58b425773dfa9": { + "balance": "0x1cfe5c808f39fbc0000" + }, + "fa67b67b4f37a0150915110ede073b05b853bda2": { + "balance": "0x2319ba947371ad0000" + }, + "fa68e0cb3edf51f0a6f211c9b2cb5e073c9bffe6": { + "balance": "0xfc936392801c00000" + }, + "fa6a37f018e97967937fc5e8617ba1d786dd5f77": { + "balance": "0x43c30fb0884a96c0000" + }, + "fa7606435b356cee257bd2fcd3d9eacb3cd1c4e1": { + "balance": "0x56bc75e2d63100000" + }, + "fa7adf660b8d99ce15933d7c5f072f3cbeb99d33": { + "balance": "0x14061b9d77a5e980000" + }, + "fa86ca27bf2854d98870837fb6f6dfe4bf6453fc": { + "balance": "0x11757e8525cf148000" + }, + "fa8cf4e627698c5d5788abb7880417e750231399": { + "balance": "0xe61a3696eef6100000" + }, + "fa8e3b1f13433900737daaf1f6299c4887f85b5f": { + "balance": "0x26c29e47c4844c0000" + }, + "fa9ec8efe08686fa58c181335872ba698560ecab": { + "balance": "0x6c6acc67d7b1d40000" + }, + "faad905d847c7b23418aeecbe3addb8dd3f8924a": { + "balance": "0x6acb3df27e1f880000" + }, + "faaeba8fc0bbda553ca72e30ef3d732e26e82041": { + "balance": "0x488d282aafc9f68000" + }, + "fab487500df20fb83ebed916791d561772adbebf": { + "balance": "0x6c6b4c4da6ddbe0000" + }, + "fac5ca94758078fbfccd19db3558da7ee8a0a768": { + "balance": "0x3728a62b0dcff60000" + }, + "fad96ab6ac768ad5099452ac4777bd1a47edc48f": { + "balance": "0x56bc75e2d63100000" + }, + "fae76719d97eac41870428e940279d97dd57b2f6": { + "balance": "0x14dbb2195ca228900000" + }, + "fae881937047895a660cf229760f27e66828d643": { + "balance": "0x9ddc1e3b901180000" + }, + "fae92c1370e9e1859a5df83b56d0f586aa3b404c": { + "balance": "0x5c5b4f3d843980000" + }, + "faf5f0b7b6d558f5090d9ea1fb2d42259c586078": { + "balance": "0x15affb8420c6b640000" + }, + "fb126f0ec769f49dcefca2f200286451583084b8": { + "balance": "0x10fcbc2350396bf0000" + }, + "fb135eb15a8bac72b69915342a60bbc06b7e077c": { + "balance": "0x43c33c1937564800000" + }, + "fb223c1e22eac1269b32ee156a5385922ed36fb8": { + "balance": "0x6c6b935b8bbd400000" + }, + "fb37cf6b4f81a9e222fba22e9bd24b5098b733cf": { + "balance": "0x21a754a6dc5280000" + }, + "fb3860f4121c432ebdc8ec6a0331b1b709792e90": { + "balance": "0x208c394af1c8880000" + }, + "fb39189af876e762c71d6c3e741893df226cedd6": { + "balance": "0xd8d726b7177a800000" + }, + "fb3a0b0d6b6a718f6fc0292a825dc9247a90a5d0": { + "balance": "0xad6dd199e975b0000" + }, + "fb3fa1ac08aba9cc3bf0fe9d483820688f65b410": { + "balance": "0x65a4da25d3016c00000" + }, + "fb3fe09bb836861529d7518da27635f538505615": { + "balance": "0x4be39216fda0700000" + }, + "fb5125bf0f5eb0b6f020e56bfc2fdf3d402c097e": { + "balance": "0x14061b9d77a5e980000" + }, + "fb5518714cefc36d04865de5915ef0ff47dfe743": { + "balance": "0x6c6b935b8bbd400000" + }, + "fb5ffaa0f7615726357891475818939d2037cf96": { + "balance": "0x1158e460913d00000" + }, + "fb685c15e439965ef626bf0d834cd1a89f2b5695": { + "balance": "0xd5967be4fc3f100000" + }, + "fb744b951d094b310262c8f986c860df9ab1de65": { + "balance": "0x2d1c515f1cb4a8000" + }, + "fb79abdb925c55b9f98efeef64cfc9eb61f51bb1": { + "balance": "0x6140c056fb0ac80000" + }, + "fb8113f94d9173eefd5a3073f516803a10b286ae": { + "balance": "0x4563918244f400000" + }, + "fb842ca2c5ef133917a236a0d4ac40690110b038": { + "balance": "0x10969a62be15880000" + }, + "fb91fb1a695553f0c68e21276decf0b83909b86d": { + "balance": "0x56c003617af780000" + }, + "fb9473cf7712350a1fa0395273fc80560752e4fb": { + "balance": "0x6af2198ba85aa0000" + }, + "fb949c647fdcfd2514c7d58e31f28a532d8c5833": { + "balance": "0x43c33c1937564800000" + }, + "fba5486d53c6e240494241abf87e43c7600d413a": { + "balance": "0x6bbf61494948340000" + }, + "fbb161fe875f09290a4b262bc60110848f0d2226": { + "balance": "0x6c6b935b8bbd400000" + }, + "fbbbebcfbe235e57dd2306ad1a9ec581c7f9f48f": { + "balance": "0x22b1c8c1227a00000" + }, + "fbc01db54e47cdc3c438694ab717a856c23fe6e9": { + "balance": "0x1ca7150ab174f470000" + }, + "fbcfcc4a7b0f26cf26e9f3332132e2fc6a230766": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "fbe71622bcbd31c1a36976e7e5f670c07ffe16de": { + "balance": "0x15af1d78b58c400000" + }, + "fbede32c349f3300ef4cd33b4de7dc18e443d326": { + "balance": "0xab4dcf399a3a600000" + }, + "fbf204c813f836d83962c7870c7808ca347fd33e": { + "balance": "0x1158e460913d00000" + }, + "fbf75933e01b75b154ef0669076be87f62dffae1": { + "balance": "0x10846372f249d4c00000" + }, + "fc0096b21e95acb8d619d176a4a1d8d529badbef": { + "balance": "0x14d9693bcbec028000" + }, + "fc00a420a36107dfd5f495128a5fe5abb2db0f34": { + "balance": "0x143179d869110200000" + }, + "fc018a690ad6746dbe3acf9712ddca52b6250039": { + "balance": "0x21e19e0c9bab2400000" + }, + "fc02734033e57f70517e0afc7ee62461f06fad8e": { + "balance": "0x155bd9307f9fe80000" + }, + "fc0ee6f7c2b3714ae9916c45566605b656f32441": { + "balance": "0x5f68e8131ecf800000" + }, + "fc10b7a67b3268d5331bfb6a14def5ea4a162ca3": { + "balance": "0xad78ebc5ac6200000" + }, + "fc15cb99a8d1030b12770add033a79ee0d0c908c": { + "balance": "0x12fa00bd52e6240000" + }, + "fc2952b4c49fedd0bc0528a308495e6d6a1c71d6": { + "balance": "0x6c6b935b8bbd400000" + }, + "fc2c1f88961d019c3e9ea33009152e0693fbf88a": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "fc361105dd90f9ede566499d69e9130395f12ac8": { + "balance": "0x53a4fe2f204e80e00000" + }, + "fc372ff6927cb396d9cf29803500110da632bc52": { + "balance": "0x6c6b935b8bbd400000" + }, + "fc39be41094b1997d2169e8264c2c3baa6c99bc4": { + "balance": "0x6c6b935b8bbd400000" + }, + "fc3d226bb36a58f526568857b0bb12d109ec9301": { + "balance": "0x6c6b935b8bbd400000" + }, + "fc43829ac787ff88aaf183ba352aadbf5a15b193": { + "balance": "0xd6ac0a2b0552e00000" + }, + "fc49c1439a41d6b3cf26bb67e0365224e5e38f5f": { + "balance": "0x3636d7af5ec98e0000" + }, + "fc5500825105cf712a318a5e9c3bfc69c89d0c12": { + "balance": "0xd8d726b7177a800000" + }, + "fc66faba277f4b5de64ad45eb19c31e00ced3ed5": { + "balance": "0x131beb925ffd3200000" + }, + "fc7e22a503ec5abe9b08c50bd14999f520fa4884": { + "balance": "0x15a477dfbe1ea148000" + }, + "fc8215a0a69913f62a43bf1c8590b9ddcd0d8ddb": { + "balance": "0x6c6b935b8bbd400000" + }, + "fc989cb487bf1a7d17e4c1b7c4b7aafdda6b0a8d": { + "balance": "0x1158e460913d00000" + }, + "fc9b347464b2f9929d807e039dae48d3d98de379": { + "balance": "0x2f6f10780d22cc00000" + }, + "fca43bbc23a0d321ba9e46b929735ce7d8ef0c18": { + "balance": "0x1158e460913d00000" + }, + "fca73eff8771c0103ba3cc1a9c259448c72abf0b": { + "balance": "0x3635c9adc5dea00000" + }, + "fcada300283f6bcc134a91456760b0d77de410e0": { + "balance": "0x6c6b935b8bbd400000" + }, + "fcbc5c71ace79741450b012cf6b8d3f17db68a70": { + "balance": "0x205b4dfa1ee74780000" + }, + "fcbd85feea6a754fcf3449449e37ff9784f7773c": { + "balance": "0xa74ada69abd7780000" + }, + "fcc9d4a4262e7a027ab7519110d802c495ceea39": { + "balance": "0x1595182224b26480000" + }, + "fccd0d1ecee27addea95f6857aeec8c7a04b28ee": { + "balance": "0x21e19e0c9bab2400000" + }, + "fcd0b4827cd208ffbf5e759dba8c3cc61d8c2c3c": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "fce089635ce97abac06b44819be5bb0a3e2e0b37": { + "balance": "0x503920a7630a78000" + }, + "fcf199f8b854222f182e4e1d099d4e323e2aae01": { + "balance": "0x3635c9adc5dea00000" + }, + "fcfc3a5004d678613f0b36a642269a7f371c3f6a": { + "balance": "0x3635c9adc5dea00000" + }, + "fd191a35157d781373fb411bf9f25290047c5eef": { + "balance": "0x3635c9adc5dea00000" + }, + "fd1faa347b0fcc804c2da86c36d5f1d18b7087bb": { + "balance": "0x2d6eb247a96f60000" + }, + "fd1fb5a89a89a721b8797068fbc47f3e9d52e149": { + "balance": "0xcd0b5837fc6580000" + }, + "fd204f4f4aba2525ba728afdf78792cbdeb735ae": { + "balance": "0x6c6b935b8bbd400000" + }, + "fd2757cc3551a095878d97875615fe0c6a32aa8a": { + "balance": "0x206db15299beac0000" + }, + "fd2872d19e57853cfa16effe93d0b1d47b4f93fb": { + "balance": "0xd8d726b7177a800000" + }, + "fd2929271e9d2095a264767e7b0df52ea0d1d400": { + "balance": "0xa2a1eb251b5ae40000" + }, + "fd377a385272900cb436a3bb7962cdffe93f5dad": { + "balance": "0x6c6b935b8bbd400000" + }, + "fd40242bb34a70855ef0fd90f3802dec2136b327": { + "balance": "0x68a875073e29240000" + }, + "fd452c3969ece3801c542020f1cdcaa1c71ed23d": { + "balance": "0x152d02c7e14af6800000" + }, + "fd4b551f6fdbcda6c511b5bb372250a6b783e534": { + "balance": "0x11de1e6db450c0000" + }, + "fd4b989558ae11be0c3b36e2d6f2a54a9343ca2e": { + "balance": "0x6c6b935b8bbd400000" + }, + "fd4de8e3748a289cf7d060517d9d38388db01fb8": { + "balance": "0xd8d726b7177a80000" + }, + "fd5a63157f914fd398eab19c137dd9550bb7715c": { + "balance": "0x56bc75e2d63100000" + }, + "fd60d2b5af3d35f7aaf0c393052e79c4d823d985": { + "balance": "0x30eb50d2e14080000" + }, + "fd686de53fa97f99639e2568549720bc588c9efc": { + "balance": "0x6ac5c62d9486070000" + }, + "fd7ede8f5240a06541eb699d782c2f9afb2170f6": { + "balance": "0x487a9a304539440000" + }, + "fd812bc69fb170ef57e2327e80affd14f8e4b6d2": { + "balance": "0x6c6b935b8bbd400000" + }, + "fd88d114220f081cb3d5e15be8152ab07366576a": { + "balance": "0x1043561a8829300000" + }, + "fd918536a8efa6f6cefe1fa1153995fef5e33d3b": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "fd920f722682afb5af451b0544d4f41b3b9d5742": { + "balance": "0x7e52056a123f3c0000" + }, + "fd9579f119bbc819a02b61e38d8803c942f24d32": { + "balance": "0x5b97e9081d9400000" + }, + "fda0ce15330707f10bce3201172d2018b9ddea74": { + "balance": "0x2d041d705a2c60000" + }, + "fda3042819af3e662900e1b92b4358eda6e92590": { + "balance": "0x1907a284d58f63e00000" + }, + "fda6810ea5ac985d6ffbf1c511f1c142edcfddf7": { + "balance": "0xd8d726b7177a800000" + }, + "fdb33944f2360615e5be239577c8a19ba52d9887": { + "balance": "0x209d922f5259c50000" + }, + "fdba5359f7ec3bc770ac49975d844ec9716256f1": { + "balance": "0x3635c9adc5dea00000" + }, + "fdc4d4765a942f5bf96931a9e8cc7ab8b757ff4c": { + "balance": "0x126c478a0e3ea8600000" + }, + "fdcd5d80b105897a57abc47865768b2900524295": { + "balance": "0x15af1d78b58c4000000" + }, + "fdd1195f797d4f35717d15e6f9810a9a3ff55460": { + "balance": "0xfc936392801c0000" + }, + "fdd502a74e813bcfa355ceda3c176f6a6871af7f": { + "balance": "0x15af1d78b58c400000" + }, + "fde395bc0b6d5cbb4c1d8fea3e0b4bff635e9db7": { + "balance": "0x6c6b935b8bbd400000" + }, + "fdeaac2acf1d138e19f2fc3f9fb74592e3ed818a": { + "balance": "0x243d4d18229ca20000" + }, + "fdecc82ddfc56192e26f563c3d68cb544a96bfed": { + "balance": "0x17da3a04c7b3e00000" + }, + "fdf42343019b0b0c6bf260b173afab7e45b9d621": { + "balance": "0x6c6acc67d7b1d40000" + }, + "fdf449f108c6fb4f5a2b081eed7e45e6919e4d25": { + "balance": "0x6c6b935b8bbd400000" + }, + "fdfd6134c04a8ab7eb16f00643f8fed7daaaecb2": { + "balance": "0x15af1d78b58c400000" + }, + "fe00bf439911a553982db638039245bcf032dbdc": { + "balance": "0x155bd9307f9fe80000" + }, + "fe016ec17ec5f10e3bb98ff4a1eda045157682ab": { + "balance": "0x145f5402e7b2e60000" + }, + "fe0e30e214290d743dd30eb082f1f0a5225ade61": { + "balance": "0xad78ebc5ac6200000" + }, + "fe210b8f04dc6d4f76216acfcbd59ba83be9b630": { + "balance": "0x1158e460913d00000" + }, + "fe22a0b388668d1ae2643e771dacf38a434223cc": { + "balance": "0xd8db5ebd7b26380000" + }, + "fe362688845fa244cc807e4b1130eb3741a8051e": { + "balance": "0x3635c9adc5dea00000" + }, + "fe3827d57630cf8761d512797b0b858e478bbd12": { + "balance": "0x1158e460913d00000" + }, + "fe418b421a9c6d373602790475d2303e11a75930": { + "balance": "0x3708baed3d68900000" + }, + "fe4249127950e2f896ec0e7e2e3d055aab10550f": { + "balance": "0x243d4d18229ca20000" + }, + "fe4d8403216fd571572bf1bdb01d00578978d688": { + "balance": "0x215f835bc769da80000" + }, + "fe53b94989d89964da2061539526bbe979dd2ea9": { + "balance": "0x68a875073e29240000" + }, + "fe549bbfe64740189892932538daaf46d2b61d4f": { + "balance": "0x22b1c8c1227a00000" + }, + "fe615d975c0887e0c9113ec7298420a793af8b96": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "fe65c4188d7922576909642044fdc52395560165": { + "balance": "0xd8d726b7177a800000" + }, + "fe697ff22ca547bfc95e33d960da605c6763f35b": { + "balance": "0x47d4119fd960940000" + }, + "fe6a895b795cb4bf85903d3ce09c5aa43953d3bf": { + "balance": "0xb8507a820728200000" + }, + "fe6f5f42b6193b1ad16206e4afb5239d4d7db45e": { + "balance": "0x5dc892aa1131c80000" + }, + "fe7011b698bf3371132d7445b19eb5b094356aee": { + "balance": "0x6c6b935b8bbd400000" + }, + "fe80e9232deaff19baf99869883a4bdf0004e53c": { + "balance": "0x2e62f20a69be400000" + }, + "fe8e6e3665570dff7a1bda697aa589c0b4e9024a": { + "balance": "0x6c6b935b8bbd400000" + }, + "fe8f1fdcab7fbec9a6a3fcc507619600505c36a3": { + "balance": "0x11164759ffb320000" + }, + "fe91eccf2bd566afa11696c5049fa84c69630a52": { + "balance": "0x692ae8897081d00000" + }, + "fe96c4cd381562401aa32a86e65b9d52fa8aee27": { + "balance": "0x8f1d5c1cae37400000" + }, + "fe98c664c3e447a95e69bd582171b7176ea2a685": { + "balance": "0xd8d726b7177a800000" + }, + "fe9ad12ef05d6d90261f96c8340a0381974df477": { + "balance": "0x6c6b935b8bbd400000" + }, + "fe9c0fffefb803081256c0cf4d6659e6d33eb4fb": { + "balance": "0x52d542804f1ce00000" + }, + "fe9cfc3bb293ddb285e625f3582f74a6b0a5a6cd": { + "balance": "0x6acb3df27e1f880000" + }, + "fe9e1197d7974a7648dcc7a03112a88edbc9045d": { + "balance": "0x10afc1ade3b4ed40000" + }, + "feaca2ac74624bf348dac9985143cfd652a4be55": { + "balance": "0x5897fcbb02914088000" + }, + "fead1803e5e737a68e18472d9ac715f0994cc2be": { + "balance": "0x1b1ae4d6e2ef500000" + }, + "feb8b8e2af716ae41fc7c04bcf29540156461e6b": { + "balance": "0x545174a528a77a0000" + }, + "feb92d30bf01ff9a1901666c5573532bfa07eeec": { + "balance": "0x3635c9adc5dea00000" + }, + "febc3173bc9072136354002b7b4fb3bfc53f22f1": { + "balance": "0x140ec80fa7ee880000" + }, + "febd48d0ffdbd5656cd5e686363a61145228f279": { + "balance": "0x97c9ce4cf6d5c00000" + }, + "febd9f81cf78bd5fb6c4b9a24bd414bb9bfa4c4e": { + "balance": "0x6be10fb8ed6e138000" + }, + "fec06fe27b44c784b2396ec92f7b923ad17e9077": { + "balance": "0x6c6b935b8bbd400000" + }, + "fec14e5485de2b3eef5e74c46146db8e454e0335": { + "balance": "0x9b41fbf9e0aec0000" + }, + "fed8476d10d584b38bfa6737600ef19d35c41ed8": { + "balance": "0x62a992e53a0af00000" + }, + "feef3b6eabc94affd3310c1c4d0e65375e131119": { + "balance": "0x1158e460913d00000" + }, + "fef09d70243f39ed8cd800bf9651479e8f4aca3c": { + "balance": "0xad78ebc5ac6200000" + }, + "fef3b3dead1a6926d49aa32b12c22af54d9ff985": { + "balance": "0x3635c9adc5dea00000" + }, + "ff0b7cb71da9d4c1ea6ecc28ebda504c63f82fd1": { + "balance": "0x388a885df2fc6c0000" + }, + "ff0c3c7798e8733dd2668152891bab80a8be955c": { + "balance": "0x45946b0f9e9d60000" + }, + "ff0cb06c42e3d88948e45bd7b0d4e291aefeea51": { + "balance": "0x678a932062e4180000" + }, + "ff0cc8dac824fa24fc3caa2169e6e057cf638ad6": { + "balance": "0xd8d726b7177a800000" + }, + "ff0e2fec304207467e1e3307f64cbf30af8fd9cd": { + "balance": "0x6c6b935b8bbd400000" + }, + "ff128f4b355be1dc4a6f94fa510d7f15d53c2aff": { + "balance": "0x93739534d286800000" + }, + "ff12e49d8e06aa20f886293c0b98ed7eff788805": { + "balance": "0xd8d726b7177a800000" + }, + "ff207308ced238a6c01ad0213ca9eb4465d42590": { + "balance": "0x6c6acc67d7b1d40000" + }, + "ff26138330274df4e0a3081e6df7dd983ec6e78f": { + "balance": "0x6c6b935b8bbd400000" + }, + "ff2726294148b86c78a9372497e459898ed3fee3": { + "balance": "0x6acb3df27e1f880000" + }, + "ff3ded7a40d3aff0d7a8c45fa6136aa0433db457": { + "balance": "0x6c68ccd09b022c0000" + }, + "ff3eee57c34d6dae970d8b311117c53586cd3502": { + "balance": "0x5c283d410394100000" + }, + "ff3ef6ba151c21b59986ae64f6e8228bc9a2c733": { + "balance": "0x6c6b935b8bbd400000" + }, + "ff41d9e1b4effe18d8b0d1f63fc4255fb4e06c3d": { + "balance": "0x487a9a304539440000" + }, + "ff45cb34c928364d9cc9d8bb00373474618f06f3": { + "balance": "0x56bc75e2d63100000" + }, + "ff49a775814ec00051a795a875de24592ea400d4": { + "balance": "0x2a5a058fc295ed000000" + }, + "ff4a408f50e9e72146a28ce4fc8d90271f116e84": { + "balance": "0x6acb3df27e1f880000" + }, + "ff4d9c8484c43c42ff2c5ab759996498d323994d": { + "balance": "0xd8d726b7177a800000" + }, + "ff4fc66069046c525658c337a917f2d4b832b409": { + "balance": "0x6c6b935b8bbd400000" + }, + "ff5162f2354dc492c75fd6e3a107268660eecb47": { + "balance": "0x5c283d410394100000" + }, + "ff545bbb66fbd00eb5e6373ff4e326f5feb5fe12": { + "balance": "0x1158e460913d00000" + }, + "ff5e7ee7d5114821e159dca5e81f18f1bfffbff9": { + "balance": "0x6c6b935b8bbd400000" + }, + "ff61c9c1b7a3d8b53bba20b34466544b7b216644": { + "balance": "0x6c6b935b8bbd400000" + }, + "ff65511cada259260c1ddc41974ecaecd32d6357": { + "balance": "0x5f68e8131ecf800000" + }, + "ff7843c7010aa7e61519b762dfe49124a76b0e4e": { + "balance": "0xc5b17924412b9bb00000" + }, + "ff78541756ab2b706e0d70b18adb700fc4f1643d": { + "balance": "0x92896529baddc880000" + }, + "ff83855051ee8ffb70b4817dba3211ed2355869d": { + "balance": "0x15af1d78b58c400000" + }, + "ff850e3be1eb6a4d726c08fa73aad358f39706da": { + "balance": "0x692ae8897081d00000" + }, + "ff86e5e8e15b53909600e41308dab75f0e24e46b": { + "balance": "0x30eb50d2e140800000" + }, + "ff88ebacc41b3687f39e4b59e159599b80cba33f": { + "balance": "0x15af1d78b58c400000" + }, + "ff8a2ca5a81333f19998255f203256e1a819c0aa": { + "balance": "0xc249fdd3277800000" + }, + "ff8eb07de3d49d9d52bbe8e5b26dbe1d160fa834": { + "balance": "0xd814dcb94453080000" + }, + "ffa4aff1a37f984b0a67272149273ae9bd41e3bc": { + "balance": "0x21e19e0c9bab2400000" + }, + "ffa696ecbd787e66abae4fe87b635f07ca57d848": { + "balance": "0x487a9a304539440000" + }, + "ffac3db879a6c7158e8dec603b407463ba0d31cf": { + "balance": "0x6acb3df27e1f880000" + }, + "ffad3dd74e2c1f796ac640de56dc99b4c792a402": { + "balance": "0x10f0cf064dd59200000" + }, + "ffb04726dfa41afdc819168418610472970d7bfc": { + "balance": "0xd8d726b7177a800000" + }, + "ffb3bcc3196a8c3cb834cec94c34fed35b3e1054": { + "balance": "0x48a43c54602f700000" + }, + "ffb974673367f5c07be5fd270dc4b7138b074d57": { + "balance": "0x85ebc8bdb9066d8000" + }, + "ffb9c7217e66743031eb377af65c77db7359dcda": { + "balance": "0x22b1c8c1227a00000" + }, + "ffbc3da0381ec339c1c049eb1ed9ee34fdcea6ca": { + "balance": "0xd8d726b7177a800000" + }, + "ffc5fc4b7e8a0293ff39a3a0f7d60d2646d37a74": { + "balance": "0x6c6b935b8bbd400000" + }, + "ffc9cc3094b041ad0e076f968a0de3b167255866": { + "balance": "0x1770c1650beee80000" + }, + "ffd5170fd1a8118d558e7511e364b24906c4f6b3": { + "balance": "0x341d8cd27f1588000" + }, + "ffd6da958eecbc016bab91058440d39b41c7be83": { + "balance": "0x43c33c1937564800000" + }, + "ffe0e997f1977a615f5a315af413fd4869343ba0": { + "balance": "0x56cd55fc64dfe0000" + }, + "ffe28db53c9044b4ecd4053fd1b4b10d7056c688": { + "balance": "0x56bc75e2d63100000" + }, + "ffe2e28c3fb74749d7e780dc8a5d422538e6e451": { + "balance": "0xdbb81e05bc12d8000" + }, + "ffe8cbc1681e5e9db74a0f93f8ed25897519120f": { + "balance": "0x51b1d3839261ac0000" + }, + "ffeac0305ede3a915295ec8e61c7f881006f4474": { + "balance": "0x556f64c1fe7fa0000" + }, + "ffec0913c635baca2f5e57a37aa9fb7b6c9b6e26": { + "balance": "0x2ba39e82ed5d740000" + }, + "fff33a3bd36abdbd412707b8e310d6011454a7ae": { + "balance": "0x1b1ae4d6e2ef5000000" + }, + "fff4bad596633479a2a29f9a8b3f78eefd07e6ee": { + "balance": "0x56bc75e2d63100000" + }, + "fff7ac99c8e4feb60c9750054bdc14ce1857f181": { + "balance": "0x3635c9adc5dea00000" + }, + + "0x1000000000000000000000000000000000000001": { + "balance": "0x0", + "code": "0x608060405234801561000f575f5ffd5b5060043610610060575f3560e01c806344c0b2bf146100645780637a737c37146100795780638da5cb5b1461009f57806391fef116146100c5578063a409c6f0146100d8578063b115ce0d146100fb575b5f5ffd5b610077610072366004610514565b61011d565b005b61008c6100873660046105b6565b6102d5565b6040519081526020015b60405180910390f35b6100ad60026001609c1b0181565b6040516001600160a01b039091168152602001610096565b61008c6100d336600461069e565b610304565b6100eb6100e636600461075c565b610316565b6040519015158152602001610096565b6100eb6101093660046107e7565b5f6020819052908152604090205460ff1681565b3360026001609c1b01146101785760405162461bcd60e51b815260206004820152601960248201527f4f6e6c79206f776e65722063616e20736574207374617475730000000000000060448201526064015b60405180910390fd5b83516030146101bf5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840dae4e8c840d8cadccee8d606b1b604482015260640161016f565b82516030146102085760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840dae4e6cac2da40d8cadccee8d605b1b604482015260640161016f565b815160201461024f5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840e0c6e46840d8cadccee8d606b1b604482015260640161016f565b60408051606081018252858152602081018590529081018390525f61027382610304565b5f8181526020819052604090819020805460ff1916861515179055519091507ffbd013ecb3bb070127bc1b1186c451c2a5778c62b56de1db228acce4c28038ea906102c590889088908890889061082c565b60405180910390a1505050505050565b5f816040516020016102e79190610878565b604051602081830303815290604052805190602001209050919050565b5f816040516020016102e791906108f5565b5f835160301461035e5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840dae4e8c840d8cadccee8d606b1b604482015260640161016f565b82516030146103a75760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840dae4e6cac2da40d8cadccee8d605b1b604482015260640161016f565b81516020146103ee5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840e0c6e46840d8cadccee8d606b1b604482015260640161016f565b60408051606081018252858152602081018590529081018390525f61041282610304565b5f9081526020819052604090205460ff169695505050505050565b634e487b7160e01b5f52604160045260245ffd5b604051608081016001600160401b03811182821017156104635761046361042d565b60405290565b604051606081016001600160401b03811182821017156104635761046361042d565b5f82601f83011261049a575f5ffd5b81356001600160401b038111156104b3576104b361042d565b604051601f8201601f19908116603f011681016001600160401b03811182821017156104e1576104e161042d565b6040528181528382016020018510156104f8575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f5f5f60808587031215610527575f5ffd5b84356001600160401b0381111561053c575f5ffd5b6105488782880161048b565b94505060208501356001600160401b03811115610563575f5ffd5b61056f8782880161048b565b93505060408501356001600160401b0381111561058a575f5ffd5b6105968782880161048b565b925050606085013580151581146105ab575f5ffd5b939692955090935050565b5f602082840312156105c6575f5ffd5b81356001600160401b038111156105db575f5ffd5b8201608081850312156105ec575f5ffd5b6105f4610441565b81356001600160401b03811115610609575f5ffd5b6106158682850161048b565b82525060208201356001600160401b03811115610630575f5ffd5b61063c8682850161048b565b60208301525060408201356001600160401b0381111561065a575f5ffd5b6106668682850161048b565b60408301525060608201356001600160401b03811115610684575f5ffd5b6106908682850161048b565b606083015250949350505050565b5f602082840312156106ae575f5ffd5b81356001600160401b038111156106c3575f5ffd5b8201606081850312156106d4575f5ffd5b6106dc610469565b81356001600160401b038111156106f1575f5ffd5b6106fd8682850161048b565b82525060208201356001600160401b03811115610718575f5ffd5b6107248682850161048b565b60208301525060408201356001600160401b03811115610742575f5ffd5b61074e8682850161048b565b604083015250949350505050565b5f5f5f6060848603121561076e575f5ffd5b83356001600160401b03811115610783575f5ffd5b61078f8682870161048b565b93505060208401356001600160401b038111156107aa575f5ffd5b6107b68682870161048b565b92505060408401356001600160401b038111156107d1575f5ffd5b6107dd8682870161048b565b9150509250925092565b5f602082840312156107f7575f5ffd5b5035919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b608081525f61083e60808301876107fe565b828103602084015261085081876107fe565b9050828103604084015261086481866107fe565b915050821515606083015295945050505050565b602081525f82516080602084015261089360a08401826107fe565b90506020840151601f198483030160408501526108b082826107fe565b9150506040840151601f198483030160608501526108ce82826107fe565b9150506060840151601f198483030160808501526108ec82826107fe565b95945050505050565b602081525f82516060602084015261091060808401826107fe565b90506020840151601f1984830301604085015261092d82826107fe565b9150506040840151601f198483030160608501526108ec82826107fe56fea2646970667358221220912d9b7cedf84c7df9914daa65319c3deb8eeed2abf06515a95fabf850c8b4ec64736f6c637828302e382e32382d646576656c6f702e323032352e322e31332b636f6d6d69742e39363462353035320059" + }, + "0x1000000000000000000000000000000000000002": { + "balance": "0x0", + "code": "0x608060405234801561000f575f5ffd5b50600436106100cb575f3560e01c8063894f449c11610088578063a169599311610063578063a1695993146101e4578063a9fcfb331461020c578063cc3c74a11461022e578063e28ba03414610236575f5ffd5b8063894f449c1461018f5780639386775a146101a25780639f2ce678146101cf575f5ffd5b806325c99ae4146100cf57806334107282146100fa57806338c0ac5f146101155780633eeb92f6146101305780634456251b1461014b57806346a675771461016e575b5f5ffd5b6100dd60016001609c1b0181565b6040516001600160a01b0390911681526020015b60405180910390f35b6100dd73f39fd6e51aad88f6f4ce6ab8827279cfffb9226681565b6100dd7370997970c51812dc3a010c7d01b50e0d17dc79c881565b6100dd733c44cdddb6a900fa2b585dd299e03d12fa4293bc81565b61015e610159366004610a46565b610249565b60405190151581526020016100f1565b61018161017c366004610b10565b610339565b6040519081526020016100f1565b61018161019d366004610bb6565b610464565b61015e6101b0366004610c55565b600160209081525f928352604080842090915290825290205460ff1681565b6101e26101dd366004610c8e565b6105d7565b005b6101f76101f2366004610a46565b610756565b604080519283526020830191909152016100f1565b61015e61021a366004610a46565b60026020525f908152604090205460ff1681565b6101815f5481565b6101e2610244366004610b10565b610850565b5f8181526002602052604081205460ff161561026657505f919050565b5f82815260016020908152604080832073f39fd6e51aad88f6f4ce6ab8827279cfffb92266845290915281205460ff16156102a957806102a581610cb8565b9150505b5f8381526001602090815260408083207370997970c51812dc3a010c7d01b50e0d17dc79c8845290915290205460ff16156102ec57806102e881610cb8565b9150505b5f838152600160209081526040808320733c44cdddb6a900fa2b585dd299e03d12fa4293bc845290915290205460ff161561032f578061032b81610cb8565b9150505b6002111592915050565b604080516060810182528681526020810186905280820185905290516348ff788b60e11b81525f9190829060016001609c1b01906391fef11690610381908590600401610d0a565b602060405180830381865afa9250505080156103ba575060408051601f3d908101601f191682019092526103b791810190610d69565b60015b6104165760405162461bcd60e51b815260206004820152602260248201527f757067726164654f70657261746f722e636f6d7075746549645631206661696c604482015261195960f21b60648201526084015b60405180910390fd5b90508085856040516020016104419392919092835290151560f81b6020830152602182015260410190565b604051602081830303815290604052805190602001209250505095945050505050565b5f84516030146104ac5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840dae4e8c840d8cadccee8d606b1b604482015260640161040d565b83516030146104f55760405162461bcd60e51b8152602060048201526015602482015274092dcecc2d8d2c840dae4e6cac2da40d8cadccee8d605b1b604482015260640161040d565b825160201461053c5760405162461bcd60e51b8152602060048201526013602482015272092dcecc2d8d2c840e0c6e46840d8cadccee8d606b1b604482015260640161040d565b5f8054908061054a83610cb8565b919050555061055d858585855f54610339565b5f8181526002602052604090205490915060ff161561058e5760405162461bcd60e51b815260040161040d90610d80565b807fc608a3fb719bb3f084c89497286b28154f3baeaf8b21efd34fafa4bab23daf0c5f54878787876040516105c7959493929190610db7565b60405180910390a2949350505050565b3373f39fd6e51aad88f6f4ce6ab8827279cfffb92266148061060c5750337370997970c51812dc3a010c7d01b50e0d17dc79c8145b8061062a575033733c44cdddb6a900fa2b585dd299e03d12fa4293bc145b61066f5760405162461bcd60e51b81526020600482015260166024820152754e6f7420617574686f72697a656420746f20766f746560501b604482015260640161040d565b5f8281526002602052604090205460ff161561069d5760405162461bcd60e51b815260040161040d90610d80565b5f82815260016020908152604080832033845290915290205460ff16156106f65760405162461bcd60e51b815260206004820152600d60248201526c105b1c9958591e481d9bdd1959609a1b604482015260640161040d565b5f8281526001602090815260408083203380855290835292819020805460ff1916851515908117909155905190815284917f8b40665146691327ee30f5bf56e9b2d6f445d2830d3b09b56385cd30f630ecfb910160405180910390a35050565b5f81815260016020908152604080832073f39fd6e51aad88f6f4ce6ab8827279cfffb922668452909152812054819060ff16156107a9578161079781610cb8565b92505080806107a590610cb8565b9150505b5f8381526001602090815260408083207370997970c51812dc3a010c7d01b50e0d17dc79c8845290915290205460ff16156107fa57816107e881610cb8565b92505080806107f690610cb8565b9150505b5f838152600160209081526040808320733c44cdddb6a900fa2b585dd299e03d12fa4293bc845290915290205460ff161561084b578161083981610cb8565b925050808061084790610cb8565b9150505b915091565b5f61085e8686868686610339565b5f8181526002602052604090205490915060ff161561088f5760405162461bcd60e51b815260040161040d90610d80565b5f81815260016020908152604080832073f39fd6e51aad88f6f4ce6ab8827279cfffb92266845290915281205460ff16156108d257806108ce81610cb8565b9150505b5f8281526001602090815260408083207370997970c51812dc3a010c7d01b50e0d17dc79c8845290915290205460ff1615610915578061091181610cb8565b9150505b5f828152600160209081526040808320733c44cdddb6a900fa2b585dd299e03d12fa4293bc845290915290205460ff1615610958578061095481610cb8565b9150505b600281101561099e5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e7420766f74657360701b604482015260640161040d565b5f8281526002602052604090819020805460ff19166001179055516344c0b2bf60e01b815260016001609c1b01906344c0b2bf906109e6908a908a908a908a90600401610e0a565b5f604051808303815f87803b1580156109fd575f5ffd5b505af1158015610a0f573d5f5f3e3d5ffd5b50506040518492507f7b1bcf1ccf901a11589afff5504d59fd0a53780eed2a952adade0348985139e091505f90a250505050505050565b5f60208284031215610a56575f5ffd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112610a80575f5ffd5b813567ffffffffffffffff811115610a9a57610a9a610a5d565b604051601f8201601f19908116603f0116810167ffffffffffffffff81118282101715610ac957610ac9610a5d565b604052818152838201602001851015610ae0575f5ffd5b816020850160208301375f918101602001919091529392505050565b80358015158114610b0b575f5ffd5b919050565b5f5f5f5f5f60a08688031215610b24575f5ffd5b853567ffffffffffffffff811115610b3a575f5ffd5b610b4688828901610a71565b955050602086013567ffffffffffffffff811115610b62575f5ffd5b610b6e88828901610a71565b945050604086013567ffffffffffffffff811115610b8a575f5ffd5b610b9688828901610a71565b935050610ba560608701610afc565b949793965091946080013592915050565b5f5f5f5f60808587031215610bc9575f5ffd5b843567ffffffffffffffff811115610bdf575f5ffd5b610beb87828801610a71565b945050602085013567ffffffffffffffff811115610c07575f5ffd5b610c1387828801610a71565b935050604085013567ffffffffffffffff811115610c2f575f5ffd5b610c3b87828801610a71565b925050610c4a60608601610afc565b905092959194509250565b5f5f60408385031215610c66575f5ffd5b8235915060208301356001600160a01b0381168114610c83575f5ffd5b809150509250929050565b5f5f60408385031215610c9f575f5ffd5b82359150610caf60208401610afc565b90509250929050565b5f60018201610cd557634e487b7160e01b5f52601160045260245ffd5b5060010190565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f825160606020840152610d256080840182610cdc565b90506020840151601f19848303016040850152610d428282610cdc565b9150506040840151601f19848303016060850152610d608282610cdc565b95945050505050565b5f60208284031215610d79575f5ffd5b5051919050565b60208082526019908201527f50726f706f73616c20616c726561647920657865637574656400000000000000604082015260600190565b85815260a060208201525f610dcf60a0830187610cdc565b8281036040840152610de18187610cdc565b90508281036060840152610df58186610cdc565b91505082151560808301529695505050505050565b608081525f610e1c6080830187610cdc565b8281036020840152610e2e8187610cdc565b90508281036040840152610e428186610cdc565b91505082151560608301529594505050505056fea26469706673582212202beb1ad330385ad9cc259962653f8cd9bbc018bdfbadf37f7bd354877517faf464736f6c637828302e382e32382d646576656c6f702e323032352e322e31332b636f6d6d69742e39363462353035320059" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +}
diff --git reth/crates/seismic/chainspec/res/genesis/manifest.toml seismic-reth/crates/seismic/chainspec/res/genesis/manifest.toml new file mode 100644 index 0000000000000000000000000000000000000000..4d9baddc8806de8b625b699445414d2503b185a8 --- /dev/null +++ seismic-reth/crates/seismic/chainspec/res/genesis/manifest.toml @@ -0,0 +1,51 @@ +[metadata] +version = "0.1.0" +description = "Seismic testnet genesis contracts" + +# Optional: defaults to main branch if not specified +# base_url = "https://raw.githubusercontent.com/SeismicSystems/seismic-contracts/intelligence-contracts" + +# NOTE: the beacon roots contract (EIP-4788) was written in etk assembly +# and doesn't have Solidity source code. +# The address is 0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02. +# NOTE: the withdrawal contract (EIP-7002) was written in etk assembly +# and doesn't have Solidity source code. +# The address is 0x00000961ef480eb55e80d19ad83579a64c007002. +# NOTE: withdrawal contract is hardcoded in genesis, +# but our deposit contract is NOT stock ETH bytecode, +# which is why we have this here. +[contracts.Deposit] +artifact = "artifacts/DepositContract.json" +address = "0x00000000219ab540356cbb839cbe05303d7705fa" + +[contracts.ProtocolParams] +artifact = "artifacts/ProtocolParams.json" +address = "0x0000000000000000000000000000506172616D73" + +[contracts.ProtocolParams.storage] +"0x0000000000000000000000000000000000000000000000000000000000000000" = "0xd412c5ecd343e264381ff15afc0ad78a67b79f35" + +[contracts.ShieldedDelegationAccount] +artifact = "artifacts/ShieldedDelegationAccount.json" +address = "0x2001" + +[contracts.UpgradeOperator] +artifact = "artifacts/UpgradeOperator.json" +address = "0x1000000000000000000000000000000000000001" + +# TODO: this has anvil keys hard-coded +[contracts.MultisigUpgradeOperator] +artifact = "artifacts/MultisigUpgradeOperator.json" +address = "0x1000000000000000000000000000000000000002" + +[contracts.AesLib] +artifact = "artifacts/AesLib.json" +address = "0x1000000000000000000000000000000000000003" + +[contracts.Directory] +artifact = "artifacts/Directory.json" +address = "0x1000000000000000000000000000000000000004" + +[contracts.Intelligence] +artifact = "artifacts/Intelligence.json" +address = "0x1000000000000000000000000000000000000005"
diff --git reth/crates/seismic/chainspec/src/lib.rs seismic-reth/crates/seismic/chainspec/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..ecaae4834242daa0181714513a90d50f9e48d038 --- /dev/null +++ seismic-reth/crates/seismic/chainspec/src/lib.rs @@ -0,0 +1,213 @@ +//! Seismic-Reth chain specs. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" +)] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +use std::sync::Arc; + +use alloy_chains::Chain; +use alloy_consensus::constants::DEV_GENESIS_HASH; +use alloy_genesis::Genesis; +use alloy_primitives::{b256, B256, U256}; +use reth_chainspec::{make_genesis_header, ChainSpec}; +use reth_primitives_traits::{sync::LazyLock, SealedHeader}; +use reth_seismic_forks::{SEISMIC_DEV_HARDFORKS, SEISMIC_MAINNET_HARDFORKS}; + +/// Genesis hash for the Seismic mainnet +/// Calculated by rlp encoding the genesis header and hashing it +pub const SEISMIC_MAINNET_GENESIS_HASH: B256 = + b256!("0xd548d4a126d72e43d893b3826c07ad24bddbaeee267489baff2f73fff2ac0976"); + +/// Genesis hash for the Seismic devnet +/// Calculated by rlp encoding the genesis header and hashing it +/// Currently matches the mainnet genesis hash because they have matching hardforks +pub const SEISMIC_DEV_GENESIS_HASH: B256 = + b256!("0x79b52ea2cc4088327fca3a7591ced55f29d13aa05c33fa7cc02e936db799727f"); + +/// Seismic devnet specification +/// +/// # Panics +/// Panics if the embedded `dev.json` genesis file cannot be deserialized. +/// Indicates a build error, not a runtime issue. +#[allow(clippy::expect_used)] // Documented panic - genesis deserialization is required +pub static SEISMIC_DEV: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| { + let mut genesis: Genesis = serde_json::from_str(include_str!("../res/genesis/dev.json")) + .expect("FATAL: Can't deserialize Dev testnet genesis json"); + + // Genesis JSON timestamps are in seconds, but when timestamp-in-seconds feature is disabled, + // we store timestamps internally as milliseconds + #[cfg(not(feature = "timestamp-in-seconds"))] + { + genesis.timestamp *= 1000; + } + + let hardforks = SEISMIC_DEV_HARDFORKS.clone(); + ChainSpec { + chain: Chain::from_id(5124), + genesis_header: SealedHeader::new( + make_genesis_header(&genesis, &hardforks), + SEISMIC_DEV_GENESIS_HASH, + ), + genesis, + paris_block_and_final_difficulty: Some((0, U256::from(0))), + hardforks, + ..Default::default() + } + .into() +}); + +// TODO: remove this once we launch devnet with consensus +/// Seismic old devnet specification +/// +/// # Panics +/// Panics if the embedded `dev.json` genesis file cannot be deserialized. +/// Indicates a build error, not a runtime issue. +#[allow(clippy::expect_used)] // Documented panic - genesis deserialization is required +pub static SEISMIC_DEV_OLD: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| { + let mut genesis: Genesis = serde_json::from_str(include_str!("../res/genesis/dev.json")) + .expect("FATAL: Can't deserialize Dev testnet genesis json"); + + // Genesis JSON timestamps are in seconds, but when timestamp-in-seconds feature is disabled, + // we store timestamps internally as milliseconds + #[cfg(not(feature = "timestamp-in-seconds"))] + { + genesis.timestamp *= 1000; + } + + let hardforks = SEISMIC_DEV_HARDFORKS.clone(); + ChainSpec { + chain: Chain::from_id(5124), + genesis_header: SealedHeader::new( + make_genesis_header(&genesis, &hardforks), + DEV_GENESIS_HASH, + ), + genesis, + paris_block_and_final_difficulty: Some((0, U256::from(0))), + hardforks, + ..Default::default() + } + .into() +}); + +/// Seismic Mainnet +/// +/// # Panics +/// Panics if the embedded `mainnet.json` genesis file cannot be deserialized. +/// Indicates a build issue, not a runtime issue. +#[allow(clippy::expect_used)] // Documented panic - genesis deserialization is required +pub static SEISMIC_MAINNET: LazyLock<Arc<ChainSpec>> = LazyLock::new(|| { + let mut genesis: Genesis = serde_json::from_str(include_str!("../res/genesis/mainnet.json")) + .expect("FATAL: Can't deserialize Mainnet genesis json"); // + + // Genesis JSON timestamps are in seconds, but when timestamp-in-seconds feature is disabled, + // we store timestamps internally as milliseconds + #[cfg(not(feature = "timestamp-in-seconds"))] + { + genesis.timestamp *= 1000; + } + + let hardforks = SEISMIC_MAINNET_HARDFORKS.clone(); + let mut spec = ChainSpec { + chain: Chain::from_id(5123), + genesis_header: SealedHeader::new( + make_genesis_header(&genesis, &hardforks), + SEISMIC_MAINNET_GENESIS_HASH, + ), + genesis, + paris_block_and_final_difficulty: Some((0, U256::from(0))), + hardforks, + ..Default::default() + }; + spec.genesis.config.dao_fork_support = true; + spec.into() +}); + +/// Returns `true` if the given chain is a seismic chain. +pub fn is_chain_seismic(chain: &Chain) -> bool { + chain.id() == SEISMIC_MAINNET.chain.id() || chain.id() == SEISMIC_DEV.chain.id() +} + +#[cfg(test)] +#[allow(clippy::expect_used)] // Test code - expect on failure is acceptable +#[allow(clippy::unwrap_used)] // Test code - unwrap on failure is acceptable +#[allow(clippy::panic)] // Test code - panic on failure is acceptable +mod tests { + use crate::*; + use alloy_consensus::constants::MAINNET_GENESIS_HASH; + use reth_chainspec::MAINNET; + use reth_ethereum_forks::EthereumHardfork; + use reth_seismic_forks::SeismicHardfork; + + #[test] + fn seismic_mainnet_genesis() { + let genesis = SEISMIC_MAINNET.genesis_header(); + let eth_genesis = MAINNET.genesis_header(); + assert_ne!( + genesis.hash_slow(), + eth_genesis.hash_slow(), + "Seismic spec should not match eth genesis" + ); + assert_eq!( + genesis.hash_slow(), + SEISMIC_MAINNET_GENESIS_HASH, + "Seismic spec has correct genesis hash" + ); + } + + // Test that the latest fork id is the latest seismic fork (mercury) + #[test] + fn latest_seismic_mainnet_fork_id_with_builder() { + let seismic_mainnet = &SEISMIC_MAINNET; + assert_eq!( + seismic_mainnet.hardfork_fork_id(SeismicHardfork::Mercury).unwrap(), + seismic_mainnet.latest_fork_id() + ) + } + + // Check display contains all eth mainnet hardforks and the seismic mercury fork + #[test] + fn display_hardforks() { + let content = SEISMIC_MAINNET.display_hardforks().to_string(); + let eth_mainnet = EthereumHardfork::mainnet(); + for (eth_hf, _) in eth_mainnet { + assert!(content.contains(eth_hf.name()), "missing hardfork {eth_hf}"); + } + assert!(content.contains("Mercury")); + } + + #[test] + fn genesis_header_hash() { + // Confirm how eth mainnet genesis header hash is calculated + let expected = MAINNET_GENESIS_HASH; + let genesis = + serde_json::from_str(include_str!("../../../chainspec/res/genesis/mainnet.json")) + .expect("Can't deserialize Mainnet genesis json"); + let hardforks = EthereumHardfork::mainnet().into(); + let genesis_header = make_genesis_header(&genesis, &hardforks); + let actual_hash = genesis_header.hash_slow(); + assert_eq!(actual_hash, expected); + + // Confirm seismic mainnet genesis header hash is calculated correctly + let expected = SEISMIC_MAINNET_GENESIS_HASH; + let genesis = serde_json::from_str(include_str!("../res/genesis/mainnet.json")) // note: same as Ethereum, needs to be updated before launch + .expect("Can't deserialize Seismic Mainnet genesis json"); + let hardforks = SEISMIC_MAINNET_HARDFORKS.clone(); + let genesis_header = make_genesis_header(&genesis, &hardforks); + let actual_hash = genesis_header.hash_slow(); + assert_eq!(actual_hash, expected); + + // Confirm seismic devnet genesis header hash is calculated correctly + let expected = SEISMIC_DEV_GENESIS_HASH; + let genesis = serde_json::from_str(include_str!("../res/genesis/dev.json")) + .expect("Can't deserialize Seismic devnet genesis json"); + let hardforks = SEISMIC_DEV_HARDFORKS.clone(); + let genesis_header = make_genesis_header(&genesis, &hardforks); + let actual_hash = genesis_header.hash_slow(); + assert_eq!(actual_hash, expected); + } +}
diff --git reth/crates/seismic/hardforks/Cargo.toml seismic-reth/crates/seismic/hardforks/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..c4ee5557f4dd2e8f7aeabc8b5243d9feb7be11e0 --- /dev/null +++ seismic-reth/crates/seismic/hardforks/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "reth-seismic-forks" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# reth +reth-ethereum-forks.workspace = true + +# ethereum +alloy-hardforks.workspace = true +alloy-chains.workspace = true +alloy-primitives.workspace = true + +# io +serde = { workspace = true, optional = true } + +# misc +auto_impl.workspace = true +once_cell.workspace = true + +[features] +default = ["std"] +std = [ + "alloy-primitives/std", + "once_cell/std", + "serde?/std", + "alloy-chains/std", + "reth-ethereum-forks/std", +] +serde = [ + "dep:serde", + "alloy-chains/serde", + "alloy-primitives/serde", + "reth-ethereum-forks/serde", + "alloy-hardforks/serde", +]
diff --git reth/crates/seismic/hardforks/src/lib.rs seismic-reth/crates/seismic/hardforks/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..3be417bff76be33e20f505b19a35b9c3c6ade37a --- /dev/null +++ seismic-reth/crates/seismic/hardforks/src/lib.rs @@ -0,0 +1,128 @@ +//! Seismic-Reth hard forks. +extern crate alloc; + +use alloc::vec; +use alloy_primitives::uint; +use once_cell::sync::Lazy as LazyLock; +use reth_ethereum_forks::{ChainHardforks, EthereumHardfork, ForkCondition, Hardfork}; + +/// Seismic hardfork enum +#[derive(Clone, Debug)] +#[allow(missing_docs)] +pub enum SeismicHardfork { + Mercury, +} + +impl Hardfork for SeismicHardfork { + fn name(&self) -> &'static str { + match self { + Self::Mercury => "Mercury", + } + } +} + +/// Mainnet hardforks +/// Based off [`EthereumHardfork::mainnet()`] +/// with existing eth hardforks activated at block 0 +pub static SEISMIC_MAINNET_HARDFORKS: LazyLock<ChainHardforks> = LazyLock::new(|| { + ChainHardforks::new(vec![ + (EthereumHardfork::Frontier.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Homestead.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Dao.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Tangerine.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::SpuriousDragon.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Byzantium.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Constantinople.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Petersburg.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Istanbul.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::MuirGlacier.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Berlin.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::London.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::ArrowGlacier.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(0)), + ( + EthereumHardfork::Paris.boxed(), + ForkCondition::TTD { + activation_block_number: 0, + fork_block: None, + total_difficulty: uint!(58_750_000_000_000_000_000_000_U256), + }, + ), + (EthereumHardfork::Shanghai.boxed(), ForkCondition::Timestamp(0)), + (EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(0)), + (EthereumHardfork::Prague.boxed(), ForkCondition::Timestamp(0)), + (SeismicHardfork::Mercury.boxed(), ForkCondition::Timestamp(0)), + ]) +}); + +/// Dev hardforks +pub static SEISMIC_DEV_HARDFORKS: LazyLock<ChainHardforks> = LazyLock::new(|| { + ChainHardforks::new(vec![ + (EthereumHardfork::Frontier.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Homestead.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Dao.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Tangerine.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::SpuriousDragon.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Byzantium.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Constantinople.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Petersburg.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Istanbul.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::MuirGlacier.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::Berlin.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::London.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::ArrowGlacier.boxed(), ForkCondition::Block(0)), + (EthereumHardfork::GrayGlacier.boxed(), ForkCondition::Block(0)), + ( + EthereumHardfork::Paris.boxed(), + ForkCondition::TTD { + activation_block_number: 0, + fork_block: None, + total_difficulty: uint!(58_750_000_000_000_000_000_000_U256), + }, + ), + (EthereumHardfork::Shanghai.boxed(), ForkCondition::Timestamp(0)), + (EthereumHardfork::Cancun.boxed(), ForkCondition::Timestamp(0)), + (EthereumHardfork::Prague.boxed(), ForkCondition::Timestamp(0)), + (SeismicHardfork::Mercury.boxed(), ForkCondition::Timestamp(0)), + ]) +}); + +#[cfg(test)] +#[allow(clippy::panic)] +mod tests { + use super::*; + use core::panic; + + #[test] + fn check_ethereum_hardforks_at_zero() { + let eth_mainnet_forks = EthereumHardfork::mainnet(); + let seismic_hardforks = SEISMIC_MAINNET_HARDFORKS.clone(); + for eth_hf in eth_mainnet_forks { + let (fork, _) = eth_hf; + let lookup = seismic_hardforks.get(fork); + match lookup { + Some(condition) => { + if fork <= EthereumHardfork::Prague { + assert!( + condition.active_at_timestamp(0) || condition.active_at_block(0), + "Hardfork {} not active at timestamp 1", + fork + ); + } + } + None => { + panic!("Hardfork {} not found in hardforks", fork); + } + } + } + } + + #[test] + fn check_seismic_hardforks_at_zero() { + let seismic_hardforks = SEISMIC_MAINNET_HARDFORKS.clone(); + assert!( + seismic_hardforks.get(SeismicHardfork::Mercury).is_some(), + "Missing hardfork mercury" + ); + } +}
diff --git reth/crates/seismic/FAILING-TESTS.md seismic-reth/crates/seismic/FAILING-TESTS.md new file mode 100644 index 0000000000000000000000000000000000000000..bae0979f2dabb362eeb74891ff8ea3eab80c4259 --- /dev/null +++ seismic-reth/crates/seismic/FAILING-TESTS.md @@ -0,0 +1,30 @@ +## Unit tests +-> all pass! + +### Need full fixing +- Refactoring envelope: TRY 4 FAIL [ 0.190s] reth-seismic-primitives transaction::signed::SeismicTransactionSignedTests::proptest + + +## Integration tests + +Summary [ 408.113s] 326 tests run: 305 passed (1 slow), 21 failed, 12 skipped +TRY 4 FAIL [ 1.546s] reth-e2e-test-utils::e2e_testsuite test_apply_with_import +TRY 4 FAIL [ 84.567s] reth-node-ethereum::e2e p2p::test_long_reorg +TRY 4 FAIL [ 14.926s] reth-node-ethereum::e2e rpc::test_flashbots_validate_v3 +TRY 4 FAIL [ 13.804s] reth-node-ethereum::e2e rpc::test_flashbots_validate_v4 +TRY 4 FAIL [ 1.152s] reth-rpc-e2e-tests::e2e_testsuite test_local_rpc_tests_compat +TRY 4 FAIL [ 10.828s] reth-trie-db::fuzz_in_memory_nodes fuzz_in_memory_account_nodes +TRY 4 FAIL [ 2.935s] reth-trie-db::proof holesky_deposit_contract_proof +TRY 4 FAIL [ 2.782s] reth-trie-db::proof mainnet_genesis_account_proof +TRY 4 FAIL [ 1.440s] reth-trie-db::proof mainnet_genesis_account_proof_nonexistent +TRY 4 FAIL [ 4.314s] reth-trie-db::proof testspec_empty_storage_proof +TRY 4 FAIL [ 2.571s] reth-trie-db::proof testspec_proofs +TRY 4 FAIL [ 3.491s] reth-trie-db::trie account_and_storage_trie +TRY 4 FAIL [ 2.423s] reth-trie-db::trie account_trie_around_extension_node +TRY 4 FAIL [ 1.566s] reth-trie-db::trie account_trie_around_extension_node_with_dbtrie +TRY 4 FAIL [ 0.857s] reth-trie-db::trie arbitrary_state_root +TRY 4 FAIL [ 0.965s] reth-trie-db::trie arbitrary_state_root_with_progress +TRY 4 FAIL [ 2.559s] reth-trie-db::trie arbitrary_storage_root +TRY 4 FAIL [ 10.377s] reth-trie-db::trie fuzz_state_root_incremental +TRY 4 FAIL [ 1.783s] reth-trie-db::trie test_empty_account +TRY 4 FAIL [ 0.843s] reth-trie-db::trie test_storage_root
diff --git reth/crates/seismic/cli/Cargo.toml seismic-reth/crates/seismic/cli/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..8852b539081232c54de22095a56415b9b23022ba --- /dev/null +++ seismic-reth/crates/seismic/cli/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "reth-seismic-cli" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# reth +reth-cli-commands.workspace = true +reth-db = { workspace = true, features = ["mdbx"] } +reth-node-core.workspace = true +reth-node-ethereum.workspace = true +reth-chainspec.workspace = true +reth-cli.workspace = true +reth-cli-runner.workspace = true +reth-node-builder.workspace = true +reth-tracing.workspace = true + +# so jemalloc metrics can be included +reth-node-metrics.workspace = true + +## seismic +reth-seismic-chainspec.workspace = true +reth-seismic-node.workspace = true + +# misc +futures-util.workspace = true +clap = { workspace = true, features = ["derive", "env"] } +tracing.workspace = true +eyre.workspace = true + +[dev-dependencies] +tempfile.workspace = true +reth-stages = { workspace = true, features = ["test-utils"] } +reth-db-common.workspace = true +reth-cli-commands.workspace = true +seismic-alloy-consensus.workspace = true +proptest.workspace = true + +[features] +asm-keccak = [ + "reth-node-core/asm-keccak", + "reth-seismic-node/asm-keccak", +] + +# Jemalloc feature for vergen to generate correct env vars +jemalloc = ["reth-node-core/jemalloc", "reth-node-metrics/jemalloc"] + +dev = ["reth-cli-commands/arbitrary"] + +serde = [ + "seismic-alloy-consensus/serde", +]
diff --git reth/crates/seismic/cli/src/chainspec.rs seismic-reth/crates/seismic/cli/src/chainspec.rs new file mode 100644 index 0000000000000000000000000000000000000000..071abbba373ddbf24c13879c4a1434f65a0c6fe9 --- /dev/null +++ seismic-reth/crates/seismic/cli/src/chainspec.rs @@ -0,0 +1,44 @@ +use reth_chainspec::ChainSpec; +use reth_cli::chainspec::{parse_genesis, ChainSpecParser}; +use reth_seismic_chainspec::{SEISMIC_DEV, SEISMIC_DEV_OLD, SEISMIC_MAINNET}; +use std::sync::Arc; + +/// Optimism chain specification parser. +#[derive(Debug, Clone, Default)] +#[non_exhaustive] +pub struct SeismicChainSpecParser; + +impl ChainSpecParser for SeismicChainSpecParser { + type ChainSpec = ChainSpec; + + const SUPPORTED_CHAINS: &'static [&'static str] = &["dev", "mainnet", "dev-old"]; + + fn parse(s: &str) -> eyre::Result<Arc<Self::ChainSpec>> { + chain_value_parser(s) + } +} + +/// Clap value parser for [`ChainSpec`]s. +/// +/// The value parser matches either a known chain, the path +/// to a json file, or a json formatted string in-memory. The json needs to be a Genesis struct. +pub fn chain_value_parser(s: &str) -> eyre::Result<Arc<ChainSpec>, eyre::Error> { + Ok(match s { + "dev" => SEISMIC_DEV.clone(), + "mainnet" => SEISMIC_MAINNET.clone(), + "dev-old" => SEISMIC_DEV_OLD.clone(), + _ => Arc::new(parse_genesis(s)?.into()), + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_known_chain_spec() { + for &chain in SeismicChainSpecParser::SUPPORTED_CHAINS { + assert!(<SeismicChainSpecParser as ChainSpecParser>::parse(chain).is_ok()); + } + } +}
diff --git reth/crates/seismic/cli/src/lib.rs seismic-reth/crates/seismic/cli/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..46da90e674fff15228cf20036ae197acf44c892a --- /dev/null +++ seismic-reth/crates/seismic/cli/src/lib.rs @@ -0,0 +1,245 @@ +//! Seismic-Reth CLI implementation. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +/// Seismic chain specification parser. +pub mod chainspec; + +use chainspec::SeismicChainSpecParser; +use clap::{value_parser, Parser, Subcommand}; +use futures_util::Future; +use reth_chainspec::{ChainSpec, EthChainSpec}; +use reth_cli::chainspec::ChainSpecParser; +use reth_cli_commands::{launcher::FnLauncher, node, stage}; +use reth_cli_runner::CliRunner; +use reth_db::DatabaseEnv; +use reth_node_builder::{NodeBuilder, WithLaunchContext}; +use reth_node_core::{ + args::{EnclaveArgs, LogArgs}, + version::version_metadata, +}; +use reth_node_ethereum::consensus::EthBeaconConsensus; +use reth_seismic_node::{ + enclave::boot_enclave_and_fetch_keys, + node::SeismicNode, + purpose_keys::{get_purpose_keys, init_purpose_keys}, + SeismicEvmConfig, +}; +use reth_tracing::FileWorkerGuard; +// This allows us to manually enable node metrics features, required for proper jemalloc metric +// reporting +use reth_node_metrics as _; +use reth_node_metrics::recorder::install_prometheus_recorder; +use std::{ffi::OsString, fmt, sync::Arc}; +use tracing::info; + +/// The main seismic-reth cli interface. +/// +/// This is the entrypoint to the executable. +#[derive(Debug, Parser)] +#[command(author, version =version_metadata().short_version.as_ref(), long_version = version_metadata().long_version.as_ref(), about = "Reth", long_about = None)] +pub struct Cli< + Spec: ChainSpecParser = SeismicChainSpecParser, + Ext: clap::Args + fmt::Debug = EnclaveArgs, +> { + /// The command to run + #[command(subcommand)] + pub command: Commands<Spec, Ext>, + + /// The chain this node is running. + /// + /// Possible values are either a built-in chain or the path to a chain specification file. + #[arg( + long, + value_name = "CHAIN_OR_PATH", + long_help = Spec::help_message(), + default_value = Spec::SUPPORTED_CHAINS[0], + value_parser = Spec::parser(), + global = true, + )] + pub chain: Arc<Spec::ChainSpec>, + + /// Add a new instance of a node. + /// + /// Configures the ports of the node to avoid conflicts with the defaults. + /// This is useful for running multiple nodes on the same machine. + /// + /// Max number of instances is 200. It is chosen in a way so that it's not possible to have + /// port numbers that conflict with each other. + /// + /// Changes to the following port numbers: + /// - `DISCOVERY_PORT`: default + `instance` - 1 + /// - `AUTH_PORT`: default + `instance` * 100 - 100 + /// - `HTTP_RPC_PORT`: default - `instance` + 1 + /// - `WS_RPC_PORT`: default + `instance` * 2 - 2 + #[arg(long, value_name = "INSTANCE", global = true, default_value_t = 1, value_parser = value_parser!(u16).range(..=200))] + pub instance: u16, + + /// The logging configuration for the CLI. + #[command(flatten)] + pub logs: LogArgs, + + /// Enclave configuration for Seismic. + #[command(flatten)] + pub enclave: Ext, +} + +impl Cli { + /// Parsers only the default CLI arguments + pub fn parse_args() -> Self { + Self::parse() + } + + /// Parsers only the default CLI arguments from the given iterator + pub fn try_parse_args_from<I, T>(itr: I) -> Result<Self, clap::error::Error> + where + I: IntoIterator<Item = T>, + T: Into<OsString> + Clone, + { + Self::try_parse_from(itr) + } +} + +impl<C, Ext> Cli<C, Ext> +where + C: ChainSpecParser<ChainSpec = ChainSpec>, + Ext: clap::Args + fmt::Debug + AsRef<EnclaveArgs>, +{ + /// Execute the configured cli command. + /// + /// This accepts a closure that is used to launch the node via the + /// [`NodeCommand`](reth_cli_commands::node::NodeCommand). + pub fn run<L, Fut>(self, launcher: L) -> eyre::Result<()> + where + L: FnOnce(WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, C::ChainSpec>>, Ext) -> Fut, + Fut: Future<Output = eyre::Result<()>>, + { + self.with_runner(CliRunner::try_default_runtime()?, launcher) + } + + /// Execute the configured cli command with the provided [`CliRunner`]. + pub fn with_runner<L, Fut>(mut self, runner: CliRunner, launcher: L) -> eyre::Result<()> + where + L: FnOnce(WithLaunchContext<NodeBuilder<Arc<DatabaseEnv>, C::ChainSpec>>, Ext) -> Fut, + Fut: Future<Output = eyre::Result<()>>, + { + // add network name to logs dir + self.logs.log_file_directory = + self.logs.log_file_directory.join(self.chain.chain().to_string()); + + let _guard = self.init_tracing()?; + info!(target: "reth::cli", "Initialized tracing, debug log directory: {}", self.logs.log_file_directory); + + // Install the prometheus recorder to be sure to record all metrics + let _ = install_prometheus_recorder(); + let enclave_args = self.enclave; + + match self.command { + Commands::Node(command) => runner.run_command_until_exit(|ctx| { + command.execute( + ctx, + FnLauncher::new::<C, Ext>(async move |builder, ext| { + launcher(builder, ext).await + }), + ) + }), + Commands::Stage(command) => { + runner.run_command_until_exit(|ctx| async move { + // For Stage commands, boot the enclave and fetch purpose keys first + let purpose_keys_response = boot_enclave_and_fetch_keys(&enclave_args).await; + + // Initialize purpose keys in global storage + init_purpose_keys(purpose_keys_response); + + // Create components with the initialized purpose keys + let components = |spec: Arc<C::ChainSpec>| { + let purpose_keys = get_purpose_keys(); + ( + SeismicEvmConfig::new(spec.clone(), purpose_keys), + EthBeaconConsensus::new(spec), + ) + }; + + // Execute the stage command + command.execute::<SeismicNode, _>(ctx, components).await + }) + } + } + } + + /// Initializes tracing with the configured options. + /// + /// If file logging is enabled, this function returns a guard that must be kept alive to ensure + /// that all logs are flushed to disk. + pub fn init_tracing(&self) -> eyre::Result<Option<FileWorkerGuard>> { + let guard = self.logs.init_tracing()?; + Ok(guard) + } +} + +/// Commands to be executed +#[derive(Debug, Subcommand)] +pub enum Commands<C: ChainSpecParser, Ext: clap::Args + fmt::Debug> { + /// Start the node + #[command(name = "node")] + Node(Box<node::NodeCommand<C, Ext>>), + /// Manipulate individual stages. + #[command(name = "stage")] + Stage(stage::Command<C>), +} + +#[cfg(test)] +mod test { + use crate::chainspec::SeismicChainSpecParser; + use clap::Parser; + use reth_cli_commands::{node::NoArgs, NodeCommand}; + use reth_seismic_chainspec::{SEISMIC_DEV, SEISMIC_DEV_OLD}; + + #[test] + fn parse_dev() { + let cmd = + NodeCommand::<SeismicChainSpecParser, NoArgs>::parse_from(["seismic-reth", "--dev"]); + let chain = SEISMIC_DEV.clone(); + assert_eq!(cmd.chain.chain, chain.chain); + assert_eq!(cmd.chain.genesis_hash(), chain.genesis_hash()); + assert_eq!( + cmd.chain.paris_block_and_final_difficulty, + chain.paris_block_and_final_difficulty + ); + assert_eq!(cmd.chain.hardforks, chain.hardforks); + + assert!(cmd.rpc.http); + assert!(cmd.network.discovery.disable_discovery); + + assert!(cmd.dev.dev); + } + + #[test] + fn parse_dev_old() { + // TODO: remove this once we launch devnet with consensus + let cmd = NodeCommand::<SeismicChainSpecParser, NoArgs>::parse_from([ + "seismic-reth", + "--chain", + "dev-old", + "--http", + "-d", + ]); + let chain = SEISMIC_DEV_OLD.clone(); + assert_eq!(cmd.chain.chain, chain.chain); + assert_eq!(cmd.chain.genesis_hash(), chain.genesis_hash()); + assert_eq!( + cmd.chain.paris_block_and_final_difficulty, + chain.paris_block_and_final_difficulty + ); + assert_eq!(cmd.chain.hardforks, chain.hardforks); + + assert!(cmd.rpc.http); + assert!(cmd.network.discovery.disable_discovery); + } +}
diff --git reth/crates/seismic/fuzz/Cargo.toml seismic-reth/crates/seismic/fuzz/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..392dbd94cdba4a1f20dc02d2da7f2e56aee6d2c2 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "reth-seismic-fuzz" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "Adversarial fuzzing framework for seismic-reth privacy features" + +[lints] +workspace = true + +[dependencies] +# seismic +seismic-enclave.workspace = true +seismic-revm.workspace = true +alloy-seismic-evm.workspace = true +seismic-alloy-consensus.workspace = true + +# reth +reth-seismic-primitives = { workspace = true, features = ["arbitrary", "reth-codec"] } +reth-seismic-evm.workspace = true +reth-seismic-chainspec.workspace = true +reth-primitives-traits.workspace = true +reth-codecs = { workspace = true, features = ["test-utils"] } + +# alloy / revm +alloy-primitives.workspace = true +alloy-eips.workspace = true +alloy-consensus.workspace = true +alloy-rlp.workspace = true +alloy-evm.workspace = true +revm.workspace = true + +# misc +arbitrary = { workspace = true, features = ["derive"] } + +[dev-dependencies] +proptest.workspace = true +proptest-arbitrary-interop.workspace = true +reth-db = { workspace = true, features = ["test-utils"] } +reth-db-api.workspace = true
diff --git reth/crates/seismic/fuzz/src/lib.rs seismic-reth/crates/seismic/fuzz/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..a7f88fdb7b8d09d35576a63c987a30728b821c08 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/src/lib.rs @@ -0,0 +1,6 @@ +//! Shared harness infrastructure for fuzzing seismic-reth. + +pub mod mock_evm; +pub mod mock_keys; +pub mod mock_state; +pub mod tx_gen;
diff --git reth/crates/seismic/fuzz/src/mock_evm.rs seismic-reth/crates/seismic/fuzz/src/mock_evm.rs new file mode 100644 index 0000000000000000000000000000000000000000..d7f58a316264f581a0859cc71f3279c6cbe101c0 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/src/mock_evm.rs @@ -0,0 +1,21 @@ +//! Pre-configured EVM factory and environment for fuzz targets. + +use alloy_evm::EvmEnv; +use alloy_seismic_evm::SeismicEvmFactory; +use revm::context::CfgEnv; +use seismic_revm::SeismicSpecId; + +use crate::{mock_keys::get_static_mock_keys, mock_state::FUZZ_CHAIN_ID}; + +/// Creates a new SeismicEvmFactory with the static mock keys. +pub fn fuzz_evm_factory() -> SeismicEvmFactory { + SeismicEvmFactory::new_with_purpose_keys(get_static_mock_keys()) +} + +/// MERCURY spec with [`FUZZ_CHAIN_ID`]. +pub fn fuzz_evm_env() -> EvmEnv<SeismicSpecId> { + EvmEnv { + cfg_env: CfgEnv::new().with_chain_id(FUZZ_CHAIN_ID).with_spec(SeismicSpecId::MERCURY), + ..Default::default() + } +}
diff --git reth/crates/seismic/fuzz/src/mock_keys.rs seismic-reth/crates/seismic/fuzz/src/mock_keys.rs new file mode 100644 index 0000000000000000000000000000000000000000..87d70479fb42523e15a0e5d75928a10cea005c7a --- /dev/null +++ seismic-reth/crates/seismic/fuzz/src/mock_keys.rs @@ -0,0 +1,22 @@ +//! Mock purpose keys for fuzz targets. +use seismic_enclave::{ + get_unsecure_sample_schnorrkel_keypair, get_unsecure_sample_secp256k1_pk, + get_unsecure_sample_secp256k1_sk, GetPurposeKeysResponse, +}; +use std::sync::OnceLock; + +/// Returns a `&'static` reference to mock purpose keys. +/// +/// Safe for use in fuzz targets — the allocation is leaked once and +/// reused across all iterations within a single process. +pub fn get_static_mock_keys() -> &'static GetPurposeKeysResponse { + static KEYS: OnceLock<&'static GetPurposeKeysResponse> = OnceLock::new(); + KEYS.get_or_init(|| { + Box::leak(Box::new(GetPurposeKeysResponse { + tx_io_sk: get_unsecure_sample_secp256k1_sk(), + tx_io_pk: get_unsecure_sample_secp256k1_pk(), + snapshot_key_bytes: [0u8; 32], + rng_keypair: get_unsecure_sample_schnorrkel_keypair(), + })) + }) +}
diff --git reth/crates/seismic/fuzz/src/mock_state.rs seismic-reth/crates/seismic/fuzz/src/mock_state.rs new file mode 100644 index 0000000000000000000000000000000000000000..c462329ed4c5495696a4a2140ab260048b3252ab --- /dev/null +++ seismic-reth/crates/seismic/fuzz/src/mock_state.rs @@ -0,0 +1,57 @@ +//! Pre-seeded state database for fuzz targets. +//! +//! Provides a `CacheDB` with funded accounts so that arbitrary transactions +//! have counterparties to interact with. + +use alloy_primitives::{Address, Bytes, U256}; +use revm::{ + database::CacheDB, + database_interface::EmptyDBTyped, + state::{AccountInfo, Bytecode}, +}; + +/// Chain ID used across all fuzz targets. +pub const FUZZ_CHAIN_ID: u64 = 5123; + +/// 1M ETH in wei. +pub const FUZZ_BALANCE: u128 = 10u128.pow(18) * 1_000_000; + +/// Creates a new funded account with the default balance. +pub fn funded_account() -> AccountInfo { + AccountInfo { + balance: U256::from(FUZZ_BALANCE), + nonce: 0, + code_hash: Default::default(), + code: None, + } +} + +/// Seeds accounts at addresses 0x01..0x0A: +/// - 0x01 and 0x03-0x0A: funded EOAs +/// - 0x02: identity contract (copies calldata to output) +pub fn seed_default_accounts(db: &mut CacheDB<EmptyDBTyped<core::convert::Infallible>>) { + db.insert_account_info(Address::with_last_byte(1), funded_account()); + + // CALLDATASIZE PUSH1 0 PUSH1 0 CALLDATACOPY CALLDATASIZE PUSH1 0 RETURN + let identity_code = + Bytes::from(vec![0x36, 0x60, 0x00, 0x60, 0x00, 0x37, 0x36, 0x60, 0x00, 0xF3]); + db.insert_account_info( + Address::with_last_byte(2), + AccountInfo { + balance: U256::ZERO, + nonce: 1, + code_hash: Default::default(), + code: Some(Bytecode::new_raw(identity_code)), + }, + ); + + for i in 3..=10 { + db.insert_account_info(Address::with_last_byte(i), funded_account()); + } +} +/// Creates a new seeded database with the default accounts seeded. +pub fn new_seeded_db() -> CacheDB<EmptyDBTyped<core::convert::Infallible>> { + let mut db = CacheDB::new(EmptyDBTyped::default()); + seed_default_accounts(&mut db); + db +}
diff --git reth/crates/seismic/fuzz/src/tx_gen.rs seismic-reth/crates/seismic/fuzz/src/tx_gen.rs new file mode 100644 index 0000000000000000000000000000000000000000..ab53cd83d9b000b204f37f2c1c87cfc9ba9fc158 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/src/tx_gen.rs @@ -0,0 +1,106 @@ +//! Structured transaction generator for fuzz targets. +//! +//! Provides `Arbitrary`-derivable input types that convert to +//! `SeismicTransaction<TxEnv>` for EVM execution fuzzing. + +use alloy_primitives::{Address, Bytes, TxKind, B256, U256}; +use arbitrary::Arbitrary; +use revm::context::TxEnv; +use seismic_revm::transaction::abstraction::SeismicTransaction; + +use crate::mock_state::FUZZ_CHAIN_ID; + +/// Fields are bounded to prevent trivial rejections (e.g. gas too low) +/// while still allowing the fuzzer to explore interesting states. +#[derive(Arbitrary, Debug, Clone)] +/// Fuzzer input that produces well-typed `SeismicTransaction<TxEnv>`. +pub struct FuzzSeismicTx { + /// The caller address. + pub caller: [u8; 20], + /// Whether to create a new contract. + pub to_create: bool, + /// The to address. + pub to_address: [u8; 20], + /// The value in wei. + pub value_low: u64, + /// The data. + pub data: Vec<u8>, + /// The gas limit. + pub gas_limit: u32, + /// The gas price. + pub gas_price: u32, + /// The nonce. + pub nonce: u64, + /// The tx type selector. + pub tx_type_selector: u8, + /// Whether to use execution mode for RNG. + pub rng_mode_execution: bool, + /// Number of blob hashes (0-6) for EIP-4844 txs. + pub blob_hash_count: u8, + /// Seed for generating blob hash bytes. + pub blob_hash_seed: [u8; 32], + /// Max fee per blob gas for EIP-4844 txs. + pub max_fee_per_blob_gas: u32, +} + +impl FuzzSeismicTx { + /// Converts the fuzzer input into a `SeismicTransaction<TxEnv>`. + pub fn into_seismic_tx(self) -> SeismicTransaction<TxEnv> { + let kind = if self.to_create { + TxKind::Create + } else { + TxKind::Call(Address::from(self.to_address)) + }; + + // 0=Legacy, 1=EIP-2930, 2=EIP-1559, 3=EIP-4844, 4=Seismic (0x4A) + let tx_type = match self.tx_type_selector % 5 { + 0 => 0u8, + 1 => 1, + 2 => 2, + 3 => 3, + _ => 0x4A, + }; + + // Populate blob fields when tx_type is EIP-4844 + let (blob_hashes, max_fee_per_blob_gas) = if tx_type == 3 { + let count = (self.blob_hash_count % 7).max(1) as usize; // 1-6 blobs + let hashes: Vec<B256> = (0..count) + .map(|i| { + let mut hash = self.blob_hash_seed; + hash[0] = i as u8; // vary each hash + B256::from(hash) + }) + .collect(); + (hashes, self.max_fee_per_blob_gas as u128) + } else { + (Vec::new(), 0) + }; + + SeismicTransaction { + base: TxEnv { + caller: Address::from(self.caller), + gas_limit: (self.gas_limit as u64).max(21_000), + gas_price: self.gas_price as u128, + gas_priority_fee: None, + kind, + value: U256::from(self.value_low), + data: Bytes::from(self.data), + chain_id: Some(FUZZ_CHAIN_ID), + nonce: self.nonce, + access_list: Default::default(), + blob_hashes, + max_fee_per_blob_gas, + authorization_list: Default::default(), + tx_type, + }, + tx_hash: Default::default(), + decryption_failed: false, + } + } + + /// Forces tx_type to non-seismic (Legacy/EIP-2930/EIP-1559/EIP-4844) for differential testing. + pub fn into_eth_compatible_tx(mut self) -> SeismicTransaction<TxEnv> { + self.tx_type_selector = self.tx_type_selector % 4; + self.into_seismic_tx() + } +}
diff --git reth/crates/seismic/fuzz/tests/db_corruption.rs seismic-reth/crates/seismic/fuzz/tests/db_corruption.rs new file mode 100644 index 0000000000000000000000000000000000000000..feb14e0a54f6db4990fe2e3c630d8abd2c615497 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/tests/db_corruption.rs @@ -0,0 +1,117 @@ +//! Integration test: corrupt database entries return `DatabaseError::Decode`. +//! +//! Validates the full production code path: +//! MDBX read → `decode_one` → `Decompress::decompress` → `catch_unwind(from_compact)` → +//! `DatabaseError` +//! +//! The zstd decompressor panics on malformed data, but `Decompress::decompress` +//! catches it and converts to `DatabaseError::Decode`. This prevents the node from +//! crashing on corrupt DB entries (see: github.com/paradigmxyz/reth/issues/16052). + +use alloy_consensus::TxLegacy; +use alloy_primitives::{Signature, TxKind, U256}; +use reth_db::{tables, test_utils::create_test_rw_db}; +use reth_db_api::{ + cursor::DbCursorRW, + table::Table, + tables::{RawKey, RawTable, RawValue}, + transaction::{DbTx, DbTxMut}, + Database, DatabaseError, +}; +use reth_seismic_primitives::SeismicTransactionSigned; +use seismic_alloy_consensus::SeismicTypedTransaction; + +/// The zstd flag in the first byte of a compact-encoded transaction. +const ZSTD_FLAG: u8 = 0b0000_1000; +/// Length of the signature (r + s) in a compact-encoded transaction. +const SIGNATURE_LEN: usize = 64; + +type TxTable = tables::Transactions<SeismicTransactionSigned>; + +fn valid_test_tx() -> SeismicTransactionSigned { + let inner = TxLegacy { + chain_id: Some(1), + nonce: 0, + gas_price: 21_000_000_000, + gas_limit: 21_000, + to: TxKind::Call(alloy_primitives::Address::ZERO), + value: U256::from(1_000_000), + input: Default::default(), + }; + SeismicTransactionSigned::new_unhashed( + SeismicTypedTransaction::Legacy(inner), + Signature::new(U256::from(1), U256::from(2), false), + ) +} + +#[test] +fn corrupt_db_entry_returns_decode_error() { + let db = create_test_rw_db(); + let tx_num: u64 = 0; + + // Write a valid transaction + { + let rw_tx = db.tx_mut().expect("failed to open write tx"); + rw_tx.put::<TxTable>(tx_num, valid_test_tx()).expect("failed to write tx"); + rw_tx.commit().expect("failed to commit"); + } + + // Verify it reads back correctly + { + let ro_tx = db.tx().expect("failed to open read tx"); + assert!(ro_tx.get::<TxTable>(tx_num).expect("failed to read tx").is_some()); + } + + // Overwrite with corrupt bytes that have the zstd flag set. + // + // `Compact` layout of `SeismicTransactionSigned`: + // byte 0: flags — bit 0: sig high bit, bits 1-2: tx type, bit 3: zstd flag + // bytes 1-64: signature (r: 32 bytes, s: 32 bytes) + // bytes 65+: transaction body (zstd compressed if bit 3 is set) + { + let rw_tx = db.tx_mut().expect("failed to open write tx"); + let key = RawKey::<u64>::new(tx_num); + + let mut corrupt_bytes = vec![ZSTD_FLAG]; + corrupt_bytes.extend_from_slice(&[0x01; SIGNATURE_LEN]); + corrupt_bytes.extend_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01]); + let corrupt_value = RawValue::<<TxTable as Table>::Value>::from_vec(corrupt_bytes); + + let mut cursor = rw_tx.cursor_write::<RawTable<TxTable>>().expect("failed to open cursor"); + cursor.upsert(key, &corrupt_value).expect("failed to write corrupt data"); + rw_tx.commit().expect("failed to commit corrupt data"); + } + + // Capture the internal panic message to verify the zstd decompressor fired + let panic_msg = std::sync::Arc::new(std::sync::Mutex::new(String::new())); + let panic_msg_clone = panic_msg.clone(); + let prev_hook = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |info| { + if let Some(msg) = info.payload().downcast_ref::<String>() { + *panic_msg_clone.lock().unwrap() = msg.clone(); + } else if let Some(msg) = info.payload().downcast_ref::<&str>() { + *panic_msg_clone.lock().unwrap() = msg.to_string(); + } + })); + + // Read through the production path — should get `DatabaseError::Decode`, not a panic + let ro_tx = db.tx().expect("failed to open read tx"); + let result: Result<Option<SeismicTransactionSigned>, DatabaseError> = + ro_tx.get::<TxTable>(tx_num); + + std::panic::set_hook(prev_hook); + + assert!(result.is_err(), "corrupt data should return an error, not succeed"); + assert!( + matches!(result, Err(DatabaseError::Decode)), + "expected DatabaseError::Decode, got: {:?}", + result, + ); + + // Verify the zstd decompressor panic actually fired inside `catch_unwind` + let captured = panic_msg.lock().unwrap(); + assert!( + captured.contains("Failed to decompress"), + "expected zstd panic to fire internally, got: '{captured}'", + ); +}
diff --git reth/crates/seismic/fuzz/tests/differential.rs seismic-reth/crates/seismic/fuzz/tests/differential.rs new file mode 100644 index 0000000000000000000000000000000000000000..2ff1cb39fee2fc2f8687b09f8ef15010bc399fbc --- /dev/null +++ seismic-reth/crates/seismic/fuzz/tests/differential.rs @@ -0,0 +1,113 @@ +//! Differential fuzz tests: plain `revm` vs `SeismicEvm`. +//! +//! DEPENDENCIES EXERCISED: [`seismic-revm`, `alloy-seismic-evm`] +//! CRASH CATEGORY: differential +//! +//! For non-seismic transaction types (Legacy, EIP-2930, EIP-1559), the +//! `SeismicEvm` should produce identical results to plain `revm`. +//! Any divergence is a regression bug. Any panic is a security bug. + +use alloy_evm::{Evm, EvmFactory}; +use alloy_primitives::Address; +use proptest::prelude::*; +use proptest_arbitrary_interop::arb; +use reth_seismic_fuzz::{ + mock_evm::{fuzz_evm_env, fuzz_evm_factory}, + mock_state::{funded_account, FUZZ_CHAIN_ID}, + tx_gen::FuzzSeismicTx, +}; +use revm::{ + database::CacheDB, + database_interface::EmptyDBTyped, + handler::{ExecuteEvm, MainBuilder, MainnetContext}, +}; +use seismic_revm::SeismicSpecId; + +fn seeded_db_with_caller(caller: Address) -> CacheDB<EmptyDBTyped<core::convert::Infallible>> { + let mut db = CacheDB::new(EmptyDBTyped::default()); + db.insert_account_info(caller, funded_account()); + db +} + +proptest! { + #![proptest_config(ProptestConfig { + cases: 128, + .. ProptestConfig::default() + })] + + /// Same non-seismic tx executed on both plain revm and SeismicEvm. + /// Success/failure outcome must match. Any panic is a security bug. + #[test] + fn differential_eth_vs_seismic_outcome(input in arb::<FuzzSeismicTx>()) { + let seismic_tx = input.clone().into_eth_compatible_tx(); + let caller = seismic_tx.base.caller; + let plain_tx = seismic_tx.base.clone(); + + let db_seismic = seeded_db_with_caller(caller); + let db_eth = seeded_db_with_caller(caller); + + // SeismicEvm (returns ResultAndState) + let mut seismic_evm = fuzz_evm_factory().create_evm(db_seismic, fuzz_evm_env()); + let seismic_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + seismic_evm.transact(seismic_tx) + })); + + // Plain revm (returns ExecutionResult) + let eth_spec = SeismicSpecId::MERCURY.into_eth_spec(); + let mut plain_evm = MainnetContext::new(db_eth, eth_spec) + .modify_cfg_chained(|cfg| { cfg.chain_id = FUZZ_CHAIN_ID; }) + .build_mainnet(); + let eth_result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + plain_evm.transact_one(plain_tx) + })); + + prop_assert!(seismic_result.is_ok(), "SeismicEvm PANIC — security bug"); + prop_assert!(eth_result.is_ok(), "Plain revm PANIC — security bug"); + + let seismic_result = seismic_result.unwrap(); + let eth_result = eth_result.unwrap(); + + match (&seismic_result, &eth_result) { + (Ok(seismic_out), Ok(eth_out)) => { + let seismic_success = seismic_out.result.is_success(); + let eth_success = eth_out.is_success(); + prop_assert_eq!( + seismic_success, eth_success, + "Divergence: SeismicEvm success={}, EthEvm success={}", + seismic_success, eth_success + ); + + if seismic_success && eth_success { + let seismic_gas = seismic_out.result.gas_used(); + let eth_gas = eth_out.gas_used(); + prop_assert_eq!( + seismic_gas, eth_gas, + "Gas divergence: SeismicEvm={}, EthEvm={}", + seismic_gas, eth_gas + ); + + let seismic_output = seismic_out.result.output().cloned().unwrap_or_default(); + let eth_output = eth_out.output().cloned().unwrap_or_default(); + prop_assert_eq!( + seismic_output, eth_output, + "Output divergence between SeismicEvm and EthEvm" + ); + } + } + (Err(seismic_err), Err(eth_err)) => { + let seismic_dbg = format!("{seismic_err:?}"); + let eth_dbg = format!("{eth_err:?}"); + prop_assert_eq!( + seismic_dbg, eth_dbg, + "Both EVMs rejected the tx, but for different reasons" + ); + } + _ => { + prop_assert!( + false, + "Divergence: one EVM succeeded and the other failed" + ); + } + } + } +}
diff --git reth/crates/seismic/fuzz/tests/evm_execution.rs seismic-reth/crates/seismic/fuzz/tests/evm_execution.rs new file mode 100644 index 0000000000000000000000000000000000000000..44d7bc0492d816ee7ffc583f4bf1eda48bc7f357 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/tests/evm_execution.rs @@ -0,0 +1,71 @@ +//! Fuzz tests for full `SeismicEvm` transaction execution. +//! +//! DEPENDENCIES EXERCISED: [`seismic-revm`, `alloy-seismic-evm`, `seismic-enclave`] +//! CRASH CATEGORY: evm_execution +//! +//! This is the highest-priority fuzz target. It exercises the full +//! `SeismicEvm.transact()` path with arbitrary transactions. Any panic +//! here means a malicious transaction could crash a node. + +use alloy_evm::{Evm, EvmFactory}; +use alloy_primitives::Address; +use proptest::prelude::*; +use proptest_arbitrary_interop::arb; +use reth_seismic_fuzz::{ + mock_evm::{fuzz_evm_env, fuzz_evm_factory}, + mock_state::{funded_account, new_seeded_db}, + tx_gen::FuzzSeismicTx, +}; + +proptest! { + #![proptest_config(ProptestConfig { + cases: 256, + .. ProptestConfig::default() + })] + + #[test] + fn evm_transact_never_panics(input in arb::<FuzzSeismicTx>()) { + let mut db = new_seeded_db(); + db.insert_account_info(Address::from(input.caller), funded_account()); + + let tx = input.into_seismic_tx(); + let mut evm = fuzz_evm_factory().create_evm(db, fuzz_evm_env()); + + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + evm.transact(tx) + })); + prop_assert!(result.is_ok(), "EVM PANIC during transact — security bug"); + } + + /// Seismic tx type (0x4A) only — tests the privacy-specific execution path. + #[test] + fn evm_transact_seismic_tx_never_panics(input in arb::<FuzzSeismicTx>()) { + let mut db = new_seeded_db(); + db.insert_account_info(Address::from(input.caller), funded_account()); + + let mut tx = input.into_seismic_tx(); + tx.base.tx_type = 0x4A; + let mut evm = fuzz_evm_factory().create_evm(db, fuzz_evm_env()); + + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + evm.transact(tx) + })); + prop_assert!(result.is_ok(), "EVM PANIC during seismic tx transact — security bug"); + } + + #[test] + fn evm_create_tx_never_panics(input in arb::<FuzzSeismicTx>()) { + let mut db = new_seeded_db(); + db.insert_account_info(Address::from(input.caller), funded_account()); + + let mut fuzz_input = input; + fuzz_input.to_create = true; + let tx = fuzz_input.into_seismic_tx(); + let mut evm = fuzz_evm_factory().create_evm(db, fuzz_evm_env()); + + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + evm.transact(tx) + })); + prop_assert!(result.is_ok(), "EVM PANIC during create tx — security bug"); + } +}
diff --git reth/crates/seismic/fuzz/tests/flagged_storage.rs seismic-reth/crates/seismic/fuzz/tests/flagged_storage.rs new file mode 100644 index 0000000000000000000000000000000000000000..d9cccae5640f373eb341929e803a5e84dec98e09 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/tests/flagged_storage.rs @@ -0,0 +1,148 @@ +//! Fuzz tests for flagged storage access control (`SLOAD`/`CLOAD`/`SSTORE`/`CSTORE`). +//! +//! DEPENDENCIES EXERCISED: [`seismic-revm`] +//! CRASH CATEGORY: flagged_storage +//! +//! Tests the privacy boundary enforcement between public and private storage. +//! Any panic here is a security bug. + +use alloy_evm::{Evm, EvmFactory}; +use alloy_primitives::{Address, Bytes, TxKind, U256}; +use proptest::prelude::*; +use reth_seismic_fuzz::{ + mock_evm::{fuzz_evm_env, fuzz_evm_factory}, + mock_state::{funded_account, new_seeded_db, FUZZ_CHAIN_ID}, +}; +use revm::{ + context::TxEnv, + database::CacheDB, + database_interface::EmptyDBTyped, + state::{AccountInfo, Bytecode}, +}; +use seismic_revm::transaction::abstraction::SeismicTransaction; + +fn call_tx(caller: Address, contract_addr: Address, gas_limit: u32) -> SeismicTransaction<TxEnv> { + SeismicTransaction { + base: TxEnv { + caller, + gas_limit: gas_limit as u64, + gas_price: 0, + gas_priority_fee: None, + kind: TxKind::Call(contract_addr), + value: U256::ZERO, + data: Bytes::new(), + chain_id: Some(FUZZ_CHAIN_ID), + nonce: 0, + access_list: Default::default(), + blob_hashes: Default::default(), + max_fee_per_blob_gas: Default::default(), + authorization_list: Default::default(), + tx_type: 0, + }, + tx_hash: Default::default(), + decryption_failed: false, + } +} + +fn deploy_contract( + db: &mut CacheDB<EmptyDBTyped<core::convert::Infallible>>, + addr_byte: u8, + bytecode: Vec<u8>, +) -> Address { + let addr = Address::with_last_byte(addr_byte); + db.insert_account_info( + addr, + AccountInfo { + balance: U256::ZERO, + nonce: 1, + code_hash: Default::default(), + code: Some(Bytecode::new_raw(Bytes::from(bytecode))), + }, + ); + addr +} + +proptest! { + #![proptest_config(ProptestConfig { + cases: 256, + .. ProptestConfig::default() + })] + + /// SLOAD on arbitrary storage slots — must not panic. + #[test] + fn sload_execution_never_panics( + slot_index in any::<[u8; 32]>(), + caller_bytes in any::<[u8; 20]>(), + gas_limit in 21_000u32..1_000_000, + ) { + let mut db = new_seeded_db(); + let caller = Address::from(caller_bytes); + db.insert_account_info(caller, funded_account()); + + // PUSH32 <slot> SLOAD STOP + let mut bytecode = vec![0x7F]; + bytecode.extend_from_slice(&slot_index); + bytecode.push(0x54); // SLOAD + bytecode.push(0x00); // STOP + let contract_addr = deploy_contract(&mut db, 0xAA, bytecode); + + let mut evm = fuzz_evm_factory().create_evm(db, fuzz_evm_env()); + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + evm.transact(call_tx(caller, contract_addr, gas_limit)) + })); + prop_assert!(result.is_ok(), "SLOAD execution PANIC — security bug"); + } + + /// CLOAD (0xB0) on arbitrary storage slots — must not panic. + #[test] + fn cload_execution_never_panics( + slot_index in any::<[u8; 32]>(), + caller_bytes in any::<[u8; 20]>(), + gas_limit in 21_000u32..1_000_000, + ) { + let mut db = new_seeded_db(); + let caller = Address::from(caller_bytes); + db.insert_account_info(caller, funded_account()); + + // PUSH32 <slot> CLOAD STOP + let mut bytecode = vec![0x7F]; + bytecode.extend_from_slice(&slot_index); + bytecode.push(0xB0); // CLOAD + bytecode.push(0x00); // STOP + let contract_addr = deploy_contract(&mut db, 0xBB, bytecode); + + let mut evm = fuzz_evm_factory().create_evm(db, fuzz_evm_env()); + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + evm.transact(call_tx(caller, contract_addr, gas_limit)) + })); + prop_assert!(result.is_ok(), "CLOAD execution PANIC — security bug"); + } + + /// CSTORE (0xB1) with arbitrary slot/value — must not panic. + #[test] + fn cstore_execution_never_panics( + slot_index in any::<[u8; 32]>(), + value_bytes in any::<[u8; 32]>(), + caller_bytes in any::<[u8; 20]>(), + gas_limit in 21_000u32..1_000_000, + ) { + let mut db = new_seeded_db(); + let caller = Address::from(caller_bytes); + db.insert_account_info(caller, funded_account()); + + // PUSH32 <value> PUSH32 <slot> CSTORE STOP + let mut bytecode = vec![0x7F]; + bytecode.extend_from_slice(&value_bytes); + bytecode.push(0x7F); + bytecode.extend_from_slice(&slot_index); + bytecode.push(0xB1); // CSTORE + bytecode.push(0x00); // STOP + let contract_addr = deploy_contract(&mut db, 0xCC, bytecode); + + let mut evm = fuzz_evm_factory().create_evm(db, fuzz_evm_env()); + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + evm.transact(call_tx(caller, contract_addr, gas_limit)) + })); + prop_assert!(result.is_ok(), "CSTORE execution PANIC — security bug"); + } +}
diff --git reth/crates/seismic/fuzz/tests/precompiles.rs seismic-reth/crates/seismic/fuzz/tests/precompiles.rs new file mode 100644 index 0000000000000000000000000000000000000000..94530ae01b8e4b4796cbd2658fa16a9618a589f7 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/tests/precompiles.rs @@ -0,0 +1,164 @@ +//! Fuzz tests for seismic precompiles. +//! +//! DEPENDENCIES EXERCISED: [`seismic-revm`, `seismic-enclave`] +//! CRASH CATEGORY: precompile +//! +//! All stateless precompiles have signature `fn(&[u8], u64) -> PrecompileResult`. +//! We feed arbitrary bytes with arbitrary gas limits to verify no panics. +//! The `.expect("must be 12 bytes")` calls in AES precompiles are theoretically +//! guarded by `validate_nonce_length`, but the fuzzer confirms this. + +use proptest::prelude::*; +use seismic_revm::precompiles::{ + aes::{aes_gcm_dec::precompile_decrypt, aes_gcm_enc::precompile_encrypt}, + ecdh_derive_sym_key::derive_symmetric_key, + hkdf_derive_sym_key::hkdf_derive_symmetric_key, + secp256k1_sign::secp256k1_sign_ecdsa_recoverable, +}; + +proptest! { + #![proptest_config(ProptestConfig { + cases: 1024, + .. ProptestConfig::default() + })] + + // ----------------------------------------------------------------------- + // AES-GCM Encryption precompile (address 102) + // + // Has `.expect("must be 12 bytes")` at aes_gcm_enc.rs:69 — theoretically + // guarded by validate_nonce_length, but we confirm via fuzzing. + // ----------------------------------------------------------------------- + + #[test] + fn precompile_aes_encrypt_never_panics( + data in proptest::collection::vec(any::<u8>(), 0..2048), + gas_limit in any::<u64>() + ) { + let result = std::panic::catch_unwind(|| { + let _ = precompile_encrypt(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in AES encrypt precompile — security bug"); + } + + // ----------------------------------------------------------------------- + // AES-GCM Decryption precompile (address 103) + // + // Has `.expect("must be 12 bytes")` at aes_gcm_dec.rs:53 + // ----------------------------------------------------------------------- + + #[test] + fn precompile_aes_decrypt_never_panics( + data in proptest::collection::vec(any::<u8>(), 0..2048), + gas_limit in any::<u64>() + ) { + let result = std::panic::catch_unwind(|| { + let _ = precompile_decrypt(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in AES decrypt precompile — security bug"); + } + + // ----------------------------------------------------------------------- + // ECDH key derivation precompile (address 101) + // + // Has `.expect("must be 32 bytes")` in derive_symmetric_key + // Expected input: 32B secret key + 33B compressed public key = 65B + // ----------------------------------------------------------------------- + + #[test] + fn precompile_ecdh_never_panics( + data in proptest::collection::vec(any::<u8>(), 0..256), + gas_limit in any::<u64>() + ) { + let result = std::panic::catch_unwind(|| { + let _ = derive_symmetric_key(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in ECDH precompile — security bug"); + } + + // ----------------------------------------------------------------------- + // HKDF key derivation precompile (address 104) + // + // Variable length input, no minimum + // ----------------------------------------------------------------------- + + #[test] + fn precompile_hkdf_never_panics( + data in proptest::collection::vec(any::<u8>(), 0..4096), + gas_limit in any::<u64>() + ) { + let result = std::panic::catch_unwind(|| { + let _ = hkdf_derive_symmetric_key(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in HKDF precompile — security bug"); + } + + // ----------------------------------------------------------------------- + // secp256k1 sign precompile (address 105) + // + // Expected input: 32B secret key + 32B message = 64B + // Has .try_into().unwrap() at secp256k1_sign.rs:47-48, guarded by length check + // ----------------------------------------------------------------------- + + #[test] + fn precompile_secp256k1_sign_never_panics( + data in proptest::collection::vec(any::<u8>(), 0..256), + gas_limit in any::<u64>() + ) { + let result = std::panic::catch_unwind(|| { + let _ = secp256k1_sign_ecdsa_recoverable(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in secp256k1_sign precompile — security bug"); + } + + // ----------------------------------------------------------------------- + // Targeted edge cases: inputs near expected boundaries + // ----------------------------------------------------------------------- + + /// AES encrypt: inputs around the 44-byte minimum boundary + #[test] + fn precompile_aes_encrypt_boundary_inputs( + data in proptest::collection::vec(any::<u8>(), 40..50), + gas_limit in 0u64..10_000 + ) { + let result = std::panic::catch_unwind(|| { + let _ = precompile_encrypt(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in AES encrypt boundary test — security bug"); + } + + /// AES decrypt: inputs around the 60-byte minimum boundary + #[test] + fn precompile_aes_decrypt_boundary_inputs( + data in proptest::collection::vec(any::<u8>(), 56..66), + gas_limit in 0u64..10_000 + ) { + let result = std::panic::catch_unwind(|| { + let _ = precompile_decrypt(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in AES decrypt boundary test — security bug"); + } + + /// ECDH: inputs around the 65-byte expected length + #[test] + fn precompile_ecdh_boundary_inputs( + data in proptest::collection::vec(any::<u8>(), 60..70), + gas_limit in 0u64..10_000 + ) { + let result = std::panic::catch_unwind(|| { + let _ = derive_symmetric_key(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in ECDH boundary test — security bug"); + } + + /// secp256k1_sign: inputs around the 64-byte expected length + #[test] + fn precompile_secp256k1_sign_boundary_inputs( + data in proptest::collection::vec(any::<u8>(), 60..70), + gas_limit in 0u64..10_000 + ) { + let result = std::panic::catch_unwind(|| { + let _ = secp256k1_sign_ecdsa_recoverable(&data, gas_limit); + }); + prop_assert!(result.is_ok(), "PANIC in secp256k1_sign boundary test — security bug"); + } +}
diff --git reth/crates/seismic/fuzz/tests/tx_encoding.proptest-regressions seismic-reth/crates/seismic/fuzz/tests/tx_encoding.proptest-regressions new file mode 100644 index 0000000000000000000000000000000000000000..519af4a720974d993b0cf68f9f94f94fe54b1d8d --- /dev/null +++ seismic-reth/crates/seismic/fuzz/tests/tx_encoding.proptest-regressions @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 736cfea56aa2414bf24c4977d89d8e5be8316019c0bbab167794ff2df1d04d11 # shrinks to data = [109, 108, 160, 56, 99, 93, 211, 203, 124, 193, 169, 221, 16, 175, 35, 83, 21, 74, 83, 118, 73, 202, 176, 255, 11, 85, 62, 163, 155, 109, 232, 54, 4, 18, 253, 101, 113, 216, 240, 204, 107, 61, 85, 204, 138, 43, 177, 143, 111, 5, 89, 226, 135, 193, 121, 29, 67, 4, 75, 190, 212, 65, 100, 134, 233, 49, 179, 218, 243, 145, 36, 83, 124, 33, 235, 227, 45, 253, 28, 177, 156, 67, 206, 245, 195, 128, 79, 86, 107, 239, 232, 225, 118, 37, 253, 88, 54, 122, 189, 247, 1, 159, 219, 25, 30, 13, 156, 5, 161, 79, 2, 60, 109, 171, 241, 254, 215, 47, 210]
diff --git reth/crates/seismic/fuzz/tests/tx_encoding.rs seismic-reth/crates/seismic/fuzz/tests/tx_encoding.rs new file mode 100644 index 0000000000000000000000000000000000000000..d0371ef49b8941dfed0a1e2628bc7fd660d57ea7 --- /dev/null +++ seismic-reth/crates/seismic/fuzz/tests/tx_encoding.rs @@ -0,0 +1,91 @@ +//! Fuzz tests for `SeismicTransactionSigned` encoding/decoding. +//! +//! DEPENDENCIES EXERCISED: [`seismic-alloy-consensus`, `seismic-alloy-core`] +//! CRASH CATEGORY: encoding_decoding +//! +//! Any panic here indicates a security bug — a malformed transaction from +//! the P2P network could crash a node. + +use alloy_eips::eip2718::{Decodable2718, Encodable2718}; +use proptest::prelude::*; +use proptest_arbitrary_interop::arb; +use reth_codecs::Compact; +use reth_seismic_primitives::SeismicTransactionSigned; + +proptest! { + #![proptest_config(ProptestConfig { + cases: 512, + .. ProptestConfig::default() + })] + + /// Feed arbitrary bytes into `Decodable2718` — must never panic. + #[test] + fn tx_decode_arbitrary_bytes_never_panics(data in proptest::collection::vec(any::<u8>(), 0..4096)) { + let result = std::panic::catch_unwind(|| { + let _ = SeismicTransactionSigned::decode_2718(&mut &data[..]); + }); + prop_assert!(result.is_ok(), "PANIC during decode — this is a security bug"); + } + + /// Roundtrip through EIP-2718 encoding: encode then decode must match. + /// Covers all tx types including EIP-4844. + #[test] + fn tx_roundtrip_2718(tx in arb::<SeismicTransactionSigned>()) { + let mut encoded = Vec::new(); + tx.encode_2718(&mut encoded); + + let result = std::panic::catch_unwind(|| { + SeismicTransactionSigned::decode_2718(&mut &encoded[..]) + }); + + match result { + Ok(Ok(decoded)) => { + prop_assert_eq!(&decoded, &tx, "2718 roundtrip mismatch"); + } + Ok(Err(e)) => { + prop_assert!(false, "Failed to decode our own encoding: {e}"); + } + Err(_) => { + prop_assert!(false, "PANIC during decode — this is a security bug"); + } + } + } + + /// Roundtrip through `Compact` codec (exercises zstd compression). + /// Covers all tx types including EIP-4844. + #[test] + fn tx_roundtrip_compact(tx in arb::<SeismicTransactionSigned>()) { + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + let mut buf = Vec::new(); + let len = tx.to_compact(&mut buf); + let (decoded, _) = SeismicTransactionSigned::from_compact(&buf, len); + decoded + })); + + match result { + Ok(decoded) => { + prop_assert_eq!(&decoded, &tx, "Compact roundtrip mismatch"); + } + Err(_) => { + prop_assert!(false, "PANIC during compact encode/decode — this is a security bug"); + } + } + } + + /// Feed arbitrary bytes into `Compact` decoder via direct `from_compact` call. + /// Panics on malformed zstd frames (`zstd-compressors/src/lib.rs:109`) and + /// short signatures (`signature.rs:18`). This direct call isn't used in + /// production — every DB read goes through `Decompress::decompress` which + /// wraps `from_compact` in `catch_unwind` and returns `DatabaseError::Decode`. + /// See `db_corruption.rs` for the production path test. + #[test] + #[should_panic] + fn tx_compact_decode_arbitrary_bytes_panics_on_corrupt_data(data in proptest::collection::vec(any::<u8>(), 0..4096)) { + let result = std::panic::catch_unwind(|| { + for len in [0, 1, 2, 3, 0x4A] { + let _ = SeismicTransactionSigned::from_compact(&data, len); + } + }); + prop_assert!(result.is_ok(), "PANIC during compact decode — this is a security bug"); + } +}
diff --git reth/crates/seismic/payload/Cargo.toml seismic-reth/crates/seismic/payload/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..fdcd8d6ac40280ec5cf1424e7c6352a0086542e4 --- /dev/null +++ seismic-reth/crates/seismic/payload/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "reth-seismic-payload-builder" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +description = "A payload builder for seismic-reth that builds optimistic payloads." + +[lints] +workspace = true + +[dependencies] +# reth +reth-chainspec.workspace = true +reth-primitives-traits.workspace = true +reth-revm = { workspace = true, features = ["witness"] } +reth-transaction-pool.workspace = true +reth-storage-api.workspace = true +reth-evm.workspace = true +reth-payload-builder.workspace = true +reth-payload-builder-primitives.workspace = true +reth-payload-primitives = { workspace = true} +reth-basic-payload-builder.workspace = true +reth-ethereum-payload-builder.workspace = true +reth-errors.workspace = true + +# seismic-reth +reth-seismic-evm.workspace = true +reth-seismic-primitives = {workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec", "arbitrary"] } +reth-ethereum-primitives = {workspace = true, features = ["serde", "serde-bincode-compat", "reth-codec"] } + +# ethereum +revm.workspace = true +alloy-primitives.workspace = true +alloy-consensus.workspace = true + +# misc +tracing.workspace = true + +[dev-dependencies] +seismic-enclave.workspace = true +reth-trie-common.workspace = true +alloy-evm.workspace = true +reth-storage-errors.workspace = true +reth-execution-errors.workspace = true +proptest.workspace = true +proptest-arbitrary-interop.workspace = true +reth-execution-types.workspace = true + +[features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"]
diff --git reth/crates/seismic/payload/src/builder.rs seismic-reth/crates/seismic/payload/src/builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..87405601dfc35fe99ea40c7d3bcf5a55af345016 --- /dev/null +++ seismic-reth/crates/seismic/payload/src/builder.rs @@ -0,0 +1,299 @@ +//! A basic Seismic payload builder implementation. + +use alloy_consensus::{Transaction, Typed2718}; +use alloy_primitives::U256; +use reth_basic_payload_builder::{ + is_better_payload, BuildArguments, BuildOutcome, MissingPayloadBehaviour, PayloadBuilder, + PayloadConfig, +}; +use reth_chainspec::{ChainSpec, ChainSpecProvider, EthereumHardforks}; +use reth_errors::{BlockExecutionError, BlockValidationError}; +use reth_evm::{ + execute::{BlockBuilder, BlockBuilderOutcome}, + ConfigureEvm, Evm, NextBlockEnvAttributes, +}; +use reth_payload_builder::{BlobSidecars, EthBuiltPayload, EthPayloadBuilderAttributes}; +use reth_payload_builder_primitives::PayloadBuilderError; +use reth_payload_primitives::PayloadBuilderAttributes; +use reth_primitives_traits::SignedTransaction; +use reth_revm::{database::StateProviderDatabase, db::State}; +use reth_seismic_evm::SeismicEvmConfig; +use reth_seismic_primitives::{SeismicPrimitives, SeismicTransactionSigned}; +use reth_storage_api::StateProviderFactory; +use reth_transaction_pool::{ + error::InvalidPoolTransactionError, BestTransactions, BestTransactionsAttributes, + PoolTransaction, TransactionPool, ValidPoolTransaction, +}; +use revm::context_interface::Block as _; +use std::sync::Arc; +use tracing::{debug, trace, warn}; + +use reth_evm::execute::InternalBlockExecutionError; +use reth_primitives_traits::transaction::error::InvalidTransactionError; + +type BestTransactionsIter<Pool> = Box< + dyn BestTransactions<Item = Arc<ValidPoolTransaction<<Pool as TransactionPool>::Transaction>>>, +>; + +use super::SeismicBuilderConfig; + +/// Seismic payload builder +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SeismicPayloadBuilder<Pool, Client, EvmConfig = SeismicEvmConfig> { + /// Client providing access to node state. + client: Client, + /// Transaction pool. + pool: Pool, + /// The type responsible for creating the evm. + evm_config: EvmConfig, + /// Payload builder configuration. + builder_config: SeismicBuilderConfig, +} + +impl<Pool, Client, EvmConfig> SeismicPayloadBuilder<Pool, Client, EvmConfig> { + /// [`SeismicPayloadBuilder`] constructor. + pub const fn new( + client: Client, + pool: Pool, + evm_config: EvmConfig, + builder_config: SeismicBuilderConfig, + ) -> Self { + Self { client, pool, evm_config, builder_config } + } +} + +// Default implementation of [`PayloadBuilder`] for unit type +impl<Pool, Client, EvmConfig> PayloadBuilder for SeismicPayloadBuilder<Pool, Client, EvmConfig> +where + EvmConfig: + ConfigureEvm<Primitives = SeismicPrimitives, NextBlockEnvCtx = NextBlockEnvAttributes>, + Client: StateProviderFactory + ChainSpecProvider<ChainSpec = ChainSpec> + Clone, + Pool: TransactionPool<Transaction: PoolTransaction<Consensus = SeismicTransactionSigned>>, +{ + type Attributes = EthPayloadBuilderAttributes; + type BuiltPayload = EthBuiltPayload<SeismicPrimitives>; + + fn try_build( + &self, + args: BuildArguments<EthPayloadBuilderAttributes, Self::BuiltPayload>, + ) -> Result<BuildOutcome<EthBuiltPayload<SeismicPrimitives>>, PayloadBuilderError> { + default_seismic_payload( + self.evm_config.clone(), + self.client.clone(), + self.pool.clone(), + self.builder_config.clone(), + args, + |attributes| self.pool.best_transactions_with_attributes(attributes), + ) + } + + fn on_missing_payload( + &self, + _args: BuildArguments<Self::Attributes, Self::BuiltPayload>, + ) -> MissingPayloadBehaviour<Self::BuiltPayload> { + if self.builder_config.await_payload_on_missing { + MissingPayloadBehaviour::AwaitInProgress + } else { + MissingPayloadBehaviour::RaceEmptyPayload + } + } + + fn build_empty_payload( + &self, + config: PayloadConfig<Self::Attributes>, + ) -> Result<Self::BuiltPayload, PayloadBuilderError> { + let args = BuildArguments::new(Default::default(), config, Default::default(), None); + + default_seismic_payload( + self.evm_config.clone(), + self.client.clone(), + self.pool.clone(), + self.builder_config.clone(), + args, + |attributes| self.pool.best_transactions_with_attributes(attributes), + )? + .into_payload() + .ok_or_else(|| PayloadBuilderError::MissingPayload) + } +} + +/// Constructs an Seismic transaction payload using the best transactions from the pool. +/// +/// Given build arguments including an Seismic client, transaction pool, +/// and configuration, this function creates a transaction payload. Returns +/// a result indicating success with the payload or an error in case of failure. +#[inline] +pub fn default_seismic_payload<EvmConfig, Client, Pool, F>( + evm_config: EvmConfig, + client: Client, + pool: Pool, + builder_config: SeismicBuilderConfig, + args: BuildArguments<EthPayloadBuilderAttributes, EthBuiltPayload<SeismicPrimitives>>, + best_txs: F, +) -> Result<BuildOutcome<EthBuiltPayload<SeismicPrimitives>>, PayloadBuilderError> +where + EvmConfig: + ConfigureEvm<Primitives = SeismicPrimitives, NextBlockEnvCtx = NextBlockEnvAttributes>, + Client: StateProviderFactory + ChainSpecProvider<ChainSpec = ChainSpec>, + Pool: TransactionPool<Transaction: PoolTransaction<Consensus = SeismicTransactionSigned>>, + F: FnOnce(BestTransactionsAttributes) -> BestTransactionsIter<Pool>, +{ + let BuildArguments { mut cached_reads, config, cancel, best_payload } = args; + let PayloadConfig { parent_header, attributes } = config; + + let state_provider = client.state_by_block_hash(parent_header.hash())?; + let state = StateProviderDatabase::new(&state_provider); + let mut db = + State::builder().with_database(cached_reads.as_db_mut(state)).with_bundle_update().build(); + + let mut builder = evm_config + .builder_for_next_block( + &mut db, + &parent_header, + NextBlockEnvAttributes { + timestamp: attributes.timestamp(), + suggested_fee_recipient: attributes.suggested_fee_recipient(), + prev_randao: attributes.prev_randao(), + gas_limit: builder_config.gas_limit(parent_header.gas_limit), + parent_beacon_block_root: attributes.parent_beacon_block_root(), + withdrawals: Some(attributes.withdrawals().clone()), + }, + ) + .map_err(PayloadBuilderError::other)?; + + let chain_spec = client.chain_spec(); + + debug!(target: "payload_builder", id=%attributes.id, parent_header = ?parent_header.hash(), parent_number = parent_header.number, "building new payload"); + let mut cumulative_gas_used = 0; + let block_gas_limit: u64 = builder.evm_mut().block().gas_limit; + let base_fee = builder.evm_mut().block().basefee; + + let mut best_txs = best_txs(BestTransactionsAttributes::new( + base_fee, + builder.evm_mut().block().blob_gasprice().map(|gasprice| gasprice as u64), + )); + let mut total_fees = U256::ZERO; + + builder.apply_pre_execution_changes().map_err(|err| { + warn!(target: "payload_builder", %err, "failed to apply pre-execution changes"); + PayloadBuilderError::Internal(err.into()) + })?; + + while let Some(pool_tx) = best_txs.next() { + // ensure we still have capacity for this transaction + if cumulative_gas_used + pool_tx.gas_limit() > block_gas_limit { + // we can't fit this transaction into the block, so we need to mark it as invalid + // which also removes all dependent transaction from the iterator before we can + // continue + best_txs.mark_invalid( + &pool_tx, + InvalidPoolTransactionError::ExceedsGasLimit(pool_tx.gas_limit(), block_gas_limit), + ); + continue + } + + // check if the job was cancelled, if so we can exit early + if cancel.is_cancelled() { + return Ok(BuildOutcome::Cancelled) + } + + // convert tx to a signed transaction + let tx = pool_tx.to_consensus(); + debug!("default_seismic_payload: tx: {:?}", tx); + + let gas_used = match builder.execute_transaction(tx.clone()) { + Ok(gas_used) => gas_used, + Err(BlockExecutionError::Validation(BlockValidationError::InvalidTx { + error, .. + })) => { + if error.is_nonce_too_low() { + // if the nonce is too low, we can skip this transaction + trace!(target: "payload_builder", %error, ?tx, "skipping nonce too low transaction"); + } else { + // if the transaction is invalid, we can skip it and all of its + // descendants + trace!(target: "payload_builder", %error, ?tx, "skipping invalid transaction and its descendants"); + best_txs.mark_invalid( + &pool_tx, + InvalidPoolTransactionError::Consensus( + InvalidTransactionError::TxTypeNotSupported, + ), + ); + } + continue + } + Err(BlockExecutionError::Internal( + InternalBlockExecutionError::FailedToDecryptSeismicTx(error), + )) => { + trace!(target: "payload_builder", %error, ?tx, "skipping seismic tx with wrong encryption"); + best_txs.mark_invalid( + &pool_tx, + InvalidPoolTransactionError::Consensus(InvalidTransactionError::SeismicTx( + "failed to decrypt seismic transaction".to_string(), + )), + ); + continue + } + // this is an error that we should treat as fatal for this attempt + Err(err) => return Err(PayloadBuilderError::evm(err)), + }; + + // update add to total fees + #[allow(clippy::expect_used)] // Fee is always valid after successful execution + let miner_fee = + tx.effective_tip_per_gas(base_fee).expect("fee is always valid; execution succeeded"); + total_fees += U256::from(miner_fee) * U256::from(gas_used); + cumulative_gas_used += gas_used; + } + + // check if we have a better block + if !is_better_payload(best_payload.as_ref(), total_fees) { + // Release db + drop(builder); + // can skip building the block + return Ok(BuildOutcome::Aborted { fees: total_fees, cached_reads }) + } + + let BlockBuilderOutcome { execution_result, block, .. } = builder.finish(&state_provider)?; + + let requests = chain_spec + .is_prague_active_at_timestamp(attributes.timestamp_seconds()) + .then_some(execution_result.requests); + + // initialize empty blob sidecars at first. If cancun is active then this will + let mut blob_sidecars = Vec::new(); + + // only determine cancun fields when active + if chain_spec.is_cancun_active_at_timestamp(attributes.timestamp_seconds()) { + // grab the blob sidecars from the executed txs + blob_sidecars = pool + .get_all_blobs_exact( + block + .body() + .transactions() + .filter(|tx| tx.is_eip4844()) + .map(|tx| *tx.tx_hash()) + .collect(), + ) + .map_err(PayloadBuilderError::other)?; + } + + let mut sidecars = BlobSidecars::Empty; + blob_sidecars + .into_iter() + .map(Arc::unwrap_or_clone) + .for_each(|s| sidecars.push_sidecar_variant(s)); + + let sealed_block = Arc::new(block.sealed_block().clone()); + debug!(target: "payload_builder", id=%attributes.id, sealed_block_header = ?sealed_block.sealed_header(), "sealed built block"); + + let payload = EthBuiltPayload::<SeismicPrimitives>::new_seismic_payload( + attributes.id, + sealed_block, + total_fees, + sidecars, + requests, + ); + + Ok(BuildOutcome::Better { payload, cached_reads }) +}
diff --git reth/crates/seismic/payload/src/lib.rs seismic-reth/crates/seismic/payload/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..77c6b40b10a8e4c9414410048bfcae33b95dc55c --- /dev/null +++ seismic-reth/crates/seismic/payload/src/lib.rs @@ -0,0 +1,20 @@ +//! Seismic's payload builder implementation. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![allow(clippy::useless_let_if_seq)] + +pub mod builder; +pub use builder::SeismicPayloadBuilder; + +pub use reth_ethereum_payload_builder::EthereumBuilderConfig as SeismicBuilderConfig; + +// Use reth_ethereum_primitives to suppress unused import warning +// We import the crate ensure features such as serde and reth-codec are enabled +// When it is pulled in by other dependencies +use reth_ethereum_primitives as _;
diff --git reth/crates/seismic/reth/Cargo.toml seismic-reth/crates/seismic/reth/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..be8838ce66521a21f51f3c6d3bbe9548b9d0ffa8 --- /dev/null +++ seismic-reth/crates/seismic/reth/Cargo.toml @@ -0,0 +1,83 @@ +[package] +name = "reth-seismic" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +# reth +reth-primitives-traits = { workspace = true} +reth-chainspec.workspace = true +reth-network = { workspace = true, optional = true } +reth-provider = { workspace = true, optional = true } +reth-db = { workspace = true, optional = true, features = ["mdbx"] } +reth-storage-api = { workspace = true, optional = true } +reth-node-api = { workspace = true, optional = true } +reth-consensus = { workspace = true, optional = true } +reth-consensus-common = { workspace = true, optional = true } +reth-evm = { workspace = true, optional = true } +reth-rpc = { workspace = true, optional = true } +reth-rpc-api = { workspace = true, optional = true } +reth-rpc-eth-types = { workspace = true, optional = true } +reth-rpc-builder = { workspace = true, optional = true } +reth-trie = { workspace = true, optional = true } + +# reth-op +reth-seismic-primitives.workspace = true +reth-seismic-chainspec.workspace = true +reth-seismic-evm = { workspace = true, optional = true } +reth-seismic-node = { workspace = true, optional = true } +reth-seismic-rpc = { workspace = true, optional = true } +reth-seismic-cli = { workspace = true, optional = true } + +[features] +default = ["std"] +std = [ + "reth-chainspec/std", + "reth-consensus?/std", + "reth-consensus-common?/std", + "reth-seismic-chainspec/std", + "reth-seismic-evm?/std", + "reth-seismic-primitives/std", + "reth-primitives-traits/std", + "reth-storage-api?/std", + "reth-evm?/std", +] +arbitrary = [ + "std", + "reth-chainspec/arbitrary", + "reth-seismic-primitives/arbitrary", + "reth-primitives-traits/arbitrary", + "reth-db?/arbitrary", +] + +test-utils = [ + "reth-chainspec/test-utils", + "reth-consensus?/test-utils", + "reth-db?/test-utils", + "reth-evm?/test-utils", + "reth-network?/test-utils", + "reth-seismic-node?/test-utils", + "reth-primitives-traits/test-utils", + "reth-provider?/test-utils", + "reth-trie?/test-utils", +] + +full = ["evm", "node", "provider", "rpc", "trie"] + +cli = ["dep:reth-seismic-cli"] +evm = ["dep:reth-evm", "dep:reth-seismic-evm"] +node-api = ["dep:reth-node-api"] +node = ["provider", "evm", "node-api", "dep:reth-seismic-node", "rpc", "trie"] +rpc = ["dep:reth-rpc", "dep:reth-rpc-builder", "dep:reth-rpc-api", "dep:reth-rpc-eth-types", "dep:reth-seismic-rpc"] +js-tracer = ["rpc", "reth-rpc/js-tracer"] +network = ["dep:reth-network"] +provider = ["storage-api", "dep:reth-provider", "dep:reth-db"] +storage-api = ["dep:reth-storage-api"] +trie = ["dep:reth-trie"]
diff --git reth/crates/seismic/reth/src/lib.rs seismic-reth/crates/seismic/reth/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..970053a1f4eaa0baea01d0063ab9072bed87a736 --- /dev/null +++ seismic-reth/crates/seismic/reth/src/lib.rs @@ -0,0 +1,97 @@ +//! Seismic meta crate that provides access to commonly used reth dependencies. + +#![doc( + html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", + html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", + issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] +#![allow(unused_crate_dependencies)] + +/// Re-exported ethereum types +#[doc(inline)] +pub use reth_seismic_primitives::*; + +/// Re-exported reth primitives +pub mod primitives { + #[doc(inline)] + pub use reth_primitives_traits::*; +} + +/// Re-exported cli types +#[cfg(feature = "cli")] +pub use reth_seismic_cli as cli; + +/// Re-exported from `reth_chainspec` +pub mod chainspec { + #[doc(inline)] + pub use reth_chainspec::*; +} + +/// Re-exported evm types +#[cfg(feature = "evm")] +pub mod evm { + #[doc(inline)] + pub use reth_seismic_evm::*; + + #[doc(inline)] + pub use reth_evm as primitives; +} + +/// Re-exported reth network types +#[cfg(feature = "network")] +pub mod network { + #[doc(inline)] + pub use reth_network::*; +} + +/// Re-exported reth provider types +#[cfg(feature = "provider")] +pub mod provider { + #[doc(inline)] + pub use reth_provider::*; + + #[doc(inline)] + pub use reth_db as db; +} + +/// Re-exported reth storage api types +#[cfg(feature = "storage-api")] +pub mod storage { + #[doc(inline)] + pub use reth_storage_api::*; +} + +/// Re-exported ethereum node +#[cfg(feature = "node-api")] +pub mod node { + #[doc(inline)] + pub use reth_node_api as api; + #[cfg(feature = "node")] + pub use reth_seismic_node::*; +} + +/// Re-exported reth trie types +#[cfg(feature = "trie")] +pub mod trie { + #[doc(inline)] + pub use reth_trie::*; +} + +/// Re-exported rpc types +#[cfg(feature = "rpc")] +pub mod rpc { + #[doc(inline)] + pub use reth_rpc::*; + #[doc(inline)] + pub use reth_seismic_rpc::*; + + #[doc(inline)] + pub use reth_rpc_api as api; + #[doc(inline)] + pub use reth_rpc_builder as builder; + #[doc(inline)] + pub use reth_rpc_eth_types as eth; +}

Changes to other crates in the repo.

diff --git reth/crates/trie/common/Cargo.toml seismic-reth/crates/trie/common/Cargo.toml index 0aa93adb59826b58c40589be296694c92bcce617..23431ce1621b96665711b7122b5969edd20d266e 100644 --- reth/crates/trie/common/Cargo.toml +++ seismic-reth/crates/trie/common/Cargo.toml @@ -30,6 +30,7 @@ nybbles = { workspace = true, features = ["rlp"] }   # reth revm-database.workspace = true +revm-state.workspace = true   # `serde` feature serde = { workspace = true, optional = true } @@ -62,7 +63,8 @@ bincode.workspace = true serde.workspace = true serde_json.workspace = true serde_with.workspace = true -revm-state.workspace = true + +seismic-alloy-genesis.workspace = true   [features] default = ["std"]
diff --git reth/crates/trie/common/src/account.rs seismic-reth/crates/trie/common/src/account.rs index b8a86907a1e80131be36c5b244ef0fcee08500c6..5244b441a9db4b12539d617d2c79e5632f90e5cb 100644 --- reth/crates/trie/common/src/account.rs +++ seismic-reth/crates/trie/common/src/account.rs @@ -47,10 +47,12 @@ // Convert the GenesisAccount to a TrieAccount let trie_account: TrieAccount = genesis_account.into();   - let expected_storage_root = storage_root_unhashed(BTreeMap::from([( + let is_private = false; // legacy test adapter value + let u: U256 = B256::from([0x02; 32]).into(); + let expected_storage_root = storage_root_unhashed(vec![( B256::from([0x01; 32]), - U256::from_be_bytes(*B256::from([0x02; 32])), - )])); + alloy_primitives::FlaggedStorage::new(u, is_private), + )]);   // Check that the fields are properly set. assert_eq!(trie_account.nonce, 10);
diff --git reth/crates/trie/common/src/added_removed_keys.rs seismic-reth/crates/trie/common/src/added_removed_keys.rs index 8e61423718aeb34bcae8ea2fd6f7224a83389e59..23f64cc4defa83c5aef41693d71f253324931c71 100644 --- reth/crates/trie/common/src/added_removed_keys.rs +++ seismic-reth/crates/trie/common/src/added_removed_keys.rs @@ -103,8 +103,8 @@ let slot2 = B256::random();   // First mark slots as removed let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::ZERO); - storage.storage.insert(slot2, U256::ZERO); + storage.storage.insert(slot1, U256::ZERO.into()); + storage.storage.insert(slot2, U256::ZERO.into()); update.storages.insert(addr, storage); multi_keys.update_with_state(&update);   @@ -115,8 +115,8 @@ // Now update with non-zero values let mut update2 = HashedPostState::default(); let mut storage2 = HashedStorage::default(); - storage2.storage.insert(slot1, U256::from(100)); - storage2.storage.insert(slot2, U256::from(200)); + storage2.storage.insert(slot1, U256::from(100).into()); + storage2.storage.insert(slot2, U256::from(200).into()); update2.storages.insert(addr, storage2); multi_keys.update_with_state(&update2);   @@ -136,7 +136,7 @@ let slot1 = B256::random();   // First add some removed keys let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::ZERO); + storage.storage.insert(slot1, U256::ZERO.into()); update.storages.insert(addr, storage); multi_keys.update_with_state(&update); assert!(multi_keys.get_storage(&addr).is_some()); @@ -162,7 +162,7 @@ let slot = B256::random();   // Add storage with zero value and empty account let mut storage = HashedStorage::default(); - storage.storage.insert(slot, U256::ZERO); + storage.storage.insert(slot, U256::ZERO.into()); update.storages.insert(addr, storage); // Account is implicitly empty (not in accounts map)   @@ -175,7 +175,7 @@ // Now clear all removed storage keys and keep account empty let mut update2 = HashedPostState::default(); let mut storage2 = HashedStorage::default(); - storage2.storage.insert(slot, U256::from(100)); // Non-zero removes from removed set + storage2.storage.insert(slot, U256::from(100).into()); // Non-zero removes from removed set update2.storages.insert(addr, storage2);   multi_keys.update_with_state(&update2);
diff --git reth/crates/trie/common/src/hash_builder/state.rs seismic-reth/crates/trie/common/src/hash_builder/state.rs index 0df582f8f5c419867188371e24918a6e214551f2..a19917a5521101fa85c08a500fb8f428dd908f1f 100644 --- reth/crates/trie/common/src/hash_builder/state.rs +++ seismic-reth/crates/trie/common/src/hash_builder/state.rs @@ -17,6 +17,8 @@ /// The current key. pub key: Vec<u8>, /// The current node value. pub value: HashBuilderValue, + /// Whether the state value is private. + pub is_private: Option<bool>, /// The builder stack. pub stack: Vec<RlpNode>,   @@ -37,6 +39,7 @@ Self { key: Nibbles::from_nibbles_unchecked(state.key), stack: state.stack, value: state.value, + is_private: state.is_private, state_masks: state.groups, tree_masks: state.tree_masks, hash_masks: state.hash_masks, @@ -54,6 +57,7 @@ Self { key: state.key.to_vec(), stack: state.stack, value: state.value, + is_private: state.is_private, groups: state.state_masks, tree_masks: state.tree_masks, hash_masks: state.hash_masks, @@ -99,9 +103,19 @@ len += 2; for item in &self.hash_masks { len += (*item).to_compact(buf); } + + // Serialize Seismic-specific `is_private: Option<bool>` + let private_byte = match self.is_private { + None => 0u8, + Some(false) => 1u8, + Some(true) => 2u8, + }; + buf.put_u8(private_byte); + len += 1;   buf.put_u8(self.stored_in_database as u8); len += 1; + len }   @@ -144,8 +158,30 @@ hash_masks.push(item); buf = rest; }   + // Deserialize Seismic-specific `is_private` + let private_byte = buf.get_u8(); + let is_private = match private_byte { + 0 => None, + 1 => Some(false), + 2 => Some(true), + _ => panic!("Invalid byte for Option<bool>: {}", private_byte), + }; + let stored_in_database = buf.get_u8() != 0; - (Self { key, stack, value, groups, tree_masks, hash_masks, stored_in_database }, buf) + + ( + Self { + key, + stack, + value, + is_private, + groups, + tree_masks, + hash_masks, + stored_in_database, + }, + buf, + ) } }   @@ -157,6 +193,17 @@ #[test] fn hash_builder_state_regression() { let mut state = HashBuilderState::default(); + state.stack.push(Default::default()); + let mut buf = vec![]; + let len = state.clone().to_compact(&mut buf); + let (decoded, _) = HashBuilderState::from_compact(&buf, len); + assert_eq!(state, decoded); + } + + #[test] + fn hash_builder_state_regression_with_private() { + let mut state = HashBuilderState::default(); + state.is_private = Some(true); state.stack.push(Default::default()); let mut buf = vec![]; let len = state.clone().to_compact(&mut buf);
diff --git reth/crates/trie/common/src/hashed_state.rs seismic-reth/crates/trie/common/src/hashed_state.rs index eba725ad5c487b93b041832d882304e33ad8b625..e72eebaac69dbaf552f213cc82bb804ae03f4468 100644 --- reth/crates/trie/common/src/hashed_state.rs +++ seismic-reth/crates/trie/common/src/hashed_state.rs @@ -20,6 +20,7 @@ #[cfg(feature = "rayon")] use rayon::prelude::{IntoParallelIterator, ParallelIterator};   use revm_database::{AccountStatus, BundleAccount}; +use revm_state::FlaggedStorage;   /// Representation of in-memory hashed state. #[derive(PartialEq, Eq, Clone, Default, Debug)] @@ -387,7 +388,7 @@ pub struct HashedStorage { /// Flag indicating whether the storage was wiped or not. pub wiped: bool, /// Mapping of hashed storage slot to storage value. - pub storage: B256Map<U256>, + pub storage: B256Map<FlaggedStorage>, }   impl HashedStorage { @@ -402,14 +403,14 @@ !self.wiped && self.storage.is_empty() }   /// Create new hashed storage from iterator. - pub fn from_iter(wiped: bool, iter: impl IntoIterator<Item = (B256, U256)>) -> Self { + pub fn from_iter(wiped: bool, iter: impl IntoIterator<Item = (B256, FlaggedStorage)>) -> Self { Self { wiped, storage: HashMap::from_iter(iter) } }   /// Create new hashed storage from account status and plain storage. pub fn from_plain_storage<'a>( status: AccountStatus, - storage: impl IntoIterator<Item = (&'a U256, &'a U256)>, + storage: impl IntoIterator<Item = (&'a U256, &'a FlaggedStorage)>, ) -> Self { Self::from_iter( status.was_destroyed(), @@ -510,7 +511,7 @@ /// Sorted hashed storage optimized for iterating during state trie calculation. #[derive(Clone, Eq, PartialEq, Debug)] pub struct HashedStorageSorted { /// Sorted hashed storage slots with non-zero value. - pub non_zero_valued_slots: Vec<(B256, U256)>, + pub non_zero_valued_slots: Vec<(B256, FlaggedStorage)>, /// Slots that have been zero valued. pub zero_valued_slots: B256Set, /// Flag indicating whether the storage was wiped or not. @@ -524,11 +525,15 @@ self.wiped }   /// Returns a sorted iterator over updated storage slots. - pub fn storage_slots_sorted(&self) -> impl Iterator<Item = (B256, U256)> { + pub fn storage_slots_sorted(&self) -> impl Iterator<Item = (B256, FlaggedStorage)> { self.non_zero_valued_slots .iter() .map(|(hashed_slot, value)| (*hashed_slot, *value)) - .chain(self.zero_valued_slots.iter().map(|hashed_slot| (*hashed_slot, U256::ZERO))) + .chain( + self.zero_valued_slots + .iter() + .map(|hashed_slot| (*hashed_slot, FlaggedStorage::ZERO)), + ) .sorted_by_key(|entry| *entry.0) } } @@ -550,7 +555,7 @@ #[derive(Debug)] enum FlattenedHashedPostStateItem { Account(Option<Account>), StorageWipe, - StorageUpdate { slot: B256, value: U256 }, + StorageUpdate { slot: B256, value: FlaggedStorage }, }   impl ChunkedHashedPostState { @@ -635,7 +640,7 @@ let hashed_slot = B256::with_last_byte(64); let hashed_slot2 = B256::with_last_byte(65);   // Initialize post state storage - let original_slot_value = U256::from(123); + let original_slot_value = FlaggedStorage::new(123, true); let mut hashed_state = HashedPostState::default().with_storages([( hashed_address, HashedStorage::from_iter( @@ -645,7 +650,7 @@ ), )]);   // Update single slot value - let updated_slot_value = U256::from(321); + let updated_slot_value = FlaggedStorage::new_from_tuple((321, false)); let extension = HashedPostState::default().with_storages([( hashed_address, HashedStorage::from_iter(false, [(hashed_slot, updated_slot_value)]), @@ -718,7 +723,7 @@ let mut storage = StorageWithOriginalValues::default(); storage.insert( U256::from(1), - StorageSlot { present_value: U256::from(4), ..Default::default() }, + StorageSlot { present_value: FlaggedStorage::public(4), ..Default::default() }, );   // Create a `BundleAccount` struct to represent the account and its storage. @@ -813,8 +818,8 @@ let mut storage = HashedStorage::default(); let slot1 = B256::random(); let slot2 = B256::random(); - storage.storage.insert(slot1, U256::ZERO); - storage.storage.insert(slot2, U256::from(1)); + storage.storage.insert(slot1, FlaggedStorage::new(0, false)); + storage.storage.insert(slot2, FlaggedStorage::new(1, false)); state.storages.insert(addr1, storage);   state @@ -917,8 +922,8 @@ state.accounts.insert(addr1, Some(Default::default())); state.accounts.insert(addr2, Some(Default::default()));   let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::ZERO); - storage.storage.insert(slot2, U256::from(1)); + storage.storage.insert(slot1, FlaggedStorage::new(0, false)); + storage.storage.insert(slot2, FlaggedStorage::new(1, false)); state.storages.insert(addr1, storage);   let mut excluded_slots = HashSet::default(); @@ -944,8 +949,8 @@ // don't add the account to state.accounts (simulating unmodified account) // but add storage updates for this account let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::from(1)); - storage.storage.insert(slot2, U256::from(2)); + storage.storage.insert(slot1, FlaggedStorage::public(1)); + storage.storage.insert(slot2, FlaggedStorage::public(2)); state.storages.insert(addr, storage);   assert!(!state.accounts.contains_key(&addr)); @@ -978,7 +983,10 @@ storages: B256Map::from_iter([( addr1, HashedStorage { wiped: true, - storage: B256Map::from_iter([(slot1, U256::ZERO), (slot2, U256::from(1))]), + storage: B256Map::from_iter([ + (slot1, FlaggedStorage::ZERO), + (slot2, FlaggedStorage::public(1)), + ]), }, )]), }; @@ -995,7 +1003,7 @@ storages: B256Map::from_iter([( addr1, HashedStorage { wiped: true, - storage: B256Map::from_iter([(slot1, U256::ZERO)]) + storage: B256Map::from_iter([(slot1, FlaggedStorage::ZERO)]) } )]), } @@ -1008,7 +1016,7 @@ storages: B256Map::from_iter([( addr1, HashedStorage { wiped: false, - storage: B256Map::from_iter([(slot2, U256::from(1))]) + storage: B256Map::from_iter([(slot2, FlaggedStorage::public(1))]) } )]), } @@ -1031,7 +1039,10 @@ storages: B256Map::from_iter([( addr2, HashedStorage { wiped: true, - storage: B256Map::from_iter([(slot1, U256::ZERO), (slot2, U256::from(1))]), + storage: B256Map::from_iter([ + (slot1, FlaggedStorage::ZERO), + (slot2, FlaggedStorage::public(1)), + ]), }, )]), }; @@ -1052,7 +1063,10 @@ storages: B256Map::from_iter([( addr2, HashedStorage { wiped: false, - storage: B256Map::from_iter([(slot1, U256::ZERO), (slot2, U256::from(1))]), + storage: B256Map::from_iter([ + (slot1, FlaggedStorage::ZERO), + (slot2, FlaggedStorage::public(1)), + ]), }, )]) })
diff --git reth/crates/trie/common/src/lib.rs seismic-reth/crates/trie/common/src/lib.rs index 7694b60c9da1958913a734459e916bb3056757db..cf732ef94071741878892f513dbf04f31df83db0 100644 --- reth/crates/trie/common/src/lib.rs +++ seismic-reth/crates/trie/common/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/trie/common/src/proofs.rs seismic-reth/crates/trie/common/src/proofs.rs index 621dcf04a3fe12c0fcd2eba4f7510ec7e9bd6936..da5897ad25dc68113e57756bd398c34de918f750 100644 --- reth/crates/trie/common/src/proofs.rs +++ seismic-reth/crates/trie/common/src/proofs.rs @@ -6,7 +6,7 @@ use alloy_consensus::constants::KECCAK_EMPTY; use alloy_primitives::{ keccak256, map::{hash_map, B256Map, B256Set, HashMap}, - Address, Bytes, B256, U256, + Address, Bytes, FlaggedStorage, B256, U256, }; use alloy_rlp::{encode_fixed_size, Decodable, EMPTY_STRING_CODE}; use alloy_trie::{ @@ -238,7 +238,7 @@ balance: account.balance, nonce: account.nonce, bytecode_hash: (account.code_hash != KECCAK_EMPTY) .then_some(account.code_hash), - }) + }); } } } @@ -368,7 +368,7 @@ balance: account.balance, nonce: account.nonce, bytecode_hash: (account.code_hash != KECCAK_EMPTY) .then_some(account.code_hash), - }) + }); } } None @@ -485,18 +485,20 @@ .collect::<Vec<_>>();   // Inspect the last node in the proof. If it's a leaf node with matching suffix, // then the node contains the encoded slot value. + let mut is_private = false; let value = 'value: { if let Some(last) = proof.last() { if let TrieNode::Leaf(leaf) = TrieNode::decode(&mut &last[..])? { if nibbles.ends_with(&leaf.key) { - break 'value U256::decode(&mut &leaf.value[..])? + is_private = leaf.is_private; + break 'value U256::decode(&mut &leaf.value[..])?; } } } U256::ZERO };   - Ok(StorageProof { key: slot, nibbles, value, proof }) + Ok(StorageProof { key: slot, nibbles, value, is_private, proof }) } }   @@ -541,7 +543,7 @@ // then the node contains the encoded slot value. let value = 'value: { if let Some(TrieNode::Leaf(leaf)) = proof.last() { if nibbles.ends_with(&leaf.key) { - break 'value U256::decode(&mut &leaf.value[..])? + break 'value U256::decode(&mut &leaf.value[..])?; } } U256::ZERO @@ -684,7 +686,8 @@ self.info.unwrap_or_default().into_trie_account(self.storage_root), )) }; let nibbles = Nibbles::unpack(keccak256(self.address)); - verify_proof(root, nibbles, expected, &self.proof) + let account_node_is_private = false; // account nodes are always public + verify_proof(root, nibbles, expected, account_node_is_private, &self.proof) } }   @@ -733,6 +736,8 @@ /// The hashed storage key nibbles. pub nibbles: Nibbles, /// The storage value. pub value: U256, + /// Whether the storge node is private. + pub is_private: bool, /// Array of rlp-serialized merkle trie nodes which starting from the storage root node and /// following the path of the hashed storage slot as key. pub proof: Vec<Bytes>, @@ -762,21 +767,40 @@ self }   /// Verify the proof against the provided storage root. + /// + /// In Seismic, storage values in the trie are encoded as [`FlaggedStorage`] which + /// includes the privacy flag byte. The expected value must be encoded the same way + /// to match what the trie actually stores. pub fn verify(&self, root: B256) -> Result<(), ProofVerificationError> { - let expected = - if self.value.is_zero() { None } else { Some(encode_fixed_size(&self.value).to_vec()) }; - verify_proof(root, self.nibbles, expected, &self.proof) + let expected = if self.value.is_zero() && !self.is_private { + None + } else { + let flagged = FlaggedStorage::new(self.value, self.is_private); + Some(encode_fixed_size(&flagged).to_vec()) + }; + verify_proof(root, self.nibbles, expected, self.is_private, &self.proof) } }   #[cfg(feature = "eip1186")] impl StorageProof { - /// Convert into an EIP-1186 storage proof + /// Convert into an EIP-1186 storage proof. + /// + /// For private storage slots, returns a zeroed value and empty proof to avoid leaking + /// private storage information, matching the behavior of `eth_getStorageAt`. pub fn into_eip1186_proof( self, slot: alloy_serde::JsonStorageKey, ) -> alloy_rpc_types_eth::EIP1186StorageProof { - alloy_rpc_types_eth::EIP1186StorageProof { key: slot, value: self.value, proof: self.proof } + if self.is_private { + alloy_rpc_types_eth::EIP1186StorageProof { key: slot, value: U256::ZERO, proof: vec![] } + } else { + alloy_rpc_types_eth::EIP1186StorageProof { + key: slot, + value: self.value, + proof: self.proof, + } + } }   /// Convert from an
diff --git reth/crates/trie/db/Cargo.toml seismic-reth/crates/trie/db/Cargo.toml index 09ccd301192bae09e821e6bd7ec5173e6f79685b..dfeb2e7873415f9637b39de183f42e7337257fe1 100644 --- reth/crates/trie/db/Cargo.toml +++ seismic-reth/crates/trie/db/Cargo.toml @@ -12,6 +12,10 @@ [lints] workspace = true   [dependencies] +# Seismic +revm.workspace = true +revm-state.workspace = true + # reth reth-primitives-traits.workspace = true reth-execution-errors.workspace = true @@ -33,6 +37,8 @@ reth-provider = { workspace = true, features = ["test-utils"] } reth-trie-common = { workspace = true, features = ["test-utils", "arbitrary"] } reth-trie = { workspace = true, features = ["test-utils"] }   +revm-primitives.workspace = true + alloy-consensus.workspace = true alloy-rlp.workspace = true revm.workspace = true @@ -48,6 +54,7 @@ serde_json.workspace = true similar-asserts.workspace = true   [features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] metrics = ["reth-trie/metrics"] serde = [ "similar-asserts/serde",
diff --git reth/crates/trie/db/src/hashed_cursor.rs seismic-reth/crates/trie/db/src/hashed_cursor.rs index 04ee663d7c02fbd6e59523ad7fce961277b38057..ccd84efc6e6b6a072524459ad45c4c53094ea739 100644 --- reth/crates/trie/db/src/hashed_cursor.rs +++ seismic-reth/crates/trie/db/src/hashed_cursor.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{B256, U256}; +use alloy_primitives::B256; use reth_db_api::{ cursor::{DbCursorRO, DbDupCursorRO}, tables, @@ -7,6 +7,7 @@ DatabaseError, }; use reth_primitives_traits::Account; use reth_trie::hashed_cursor::{HashedCursor, HashedCursorFactory, HashedStorageCursor}; +use revm_state::FlaggedStorage;   /// A struct wrapping database transaction that implements [`HashedCursorFactory`]. #[derive(Debug)] @@ -94,14 +95,14 @@ impl<C> HashedCursor for DatabaseHashedStorageCursor<C> where C: DbCursorRO<tables::HashedStorages> + DbDupCursorRO<tables::HashedStorages>, { - type Value = U256; + type Value = FlaggedStorage;   fn seek(&mut self, subkey: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> { - Ok(self.cursor.seek_by_key_subkey(self.hashed_address, subkey)?.map(|e| (e.key, e.value))) + Ok(self.cursor.seek_by_key_subkey(self.hashed_address, subkey)?.map(|e| (e.key, e.into()))) }   fn next(&mut self) -> Result<Option<(B256, Self::Value)>, DatabaseError> { - Ok(self.cursor.next_dup_val()?.map(|e| (e.key, e.value))) + Ok(self.cursor.next_dup_val()?.map(|e| (e.key, e.into()))) } }
diff --git reth/crates/trie/db/src/state.rs seismic-reth/crates/trie/db/src/state.rs index 757e0b98eb41eb66663bb5d33f2d726bf7d46f12..3fc602efe8c0f77e8d140a95dc066a4b8f9d5945 100644 --- reth/crates/trie/db/src/state.rs +++ seismic-reth/crates/trie/db/src/state.rs @@ -1,7 +1,7 @@ use crate::{DatabaseHashedCursorFactory, DatabaseTrieCursorFactory, PrefixSetLoader}; use alloy_primitives::{ map::{AddressMap, B256Map}, - Address, BlockNumber, B256, U256, + Address, BlockNumber, B256, }; use reth_db_api::{ cursor::DbCursorRO, @@ -16,6 +16,7 @@ hashed_cursor::HashedPostStateCursorFactory, trie_cursor::InMemoryTrieCursorFactory, updates::TrieUpdates, HashedPostState, HashedStorage, KeccakKeyHasher, KeyHasher, StateRoot, StateRootProgress, TrieInput, }; +use revm::state::FlaggedStorage; use std::{collections::HashMap, ops::RangeInclusive}; use tracing::debug;   @@ -230,14 +231,14 @@ accounts.entry(address).or_insert(info); }   // Iterate over storage changesets and record value before first occurring storage change. - let mut storages = AddressMap::<B256Map<U256>>::default(); + let mut storages = AddressMap::<B256Map<FlaggedStorage>>::default(); let mut storage_changesets_cursor = tx.cursor_read::<tables::StorageChangeSets>()?; for entry in storage_changesets_cursor.walk_range(BlockNumberAddress((from, Address::ZERO))..)? { let (BlockNumberAddress((_, address)), storage) = entry?; let account_storage = storages.entry(address).or_default(); - account_storage.entry(storage.key).or_insert(storage.value); + account_storage.entry(storage.key).or_insert(storage.into()); }   let hashed_accounts = @@ -286,8 +287,14 @@ let bundle_state = BundleState::builder(2..=2) .state_present_account_info(address1, account1) .state_present_account_info(address2, account2) - .state_storage(address1, HashMap::from_iter([(slot1, (U256::ZERO, U256::from(10)))])) - .state_storage(address2, HashMap::from_iter([(slot2, (U256::ZERO, U256::from(20)))])) + .state_storage( + address1, + HashMap::from_iter([(slot1, (FlaggedStorage::ZERO, FlaggedStorage::public(10)))]), + ) + .state_storage( + address2, + HashMap::from_iter([(slot2, (FlaggedStorage::ZERO, FlaggedStorage::public(20)))]), + ) .build(); assert_eq!(bundle_state.reverts.len(), 1);   @@ -299,7 +306,11 @@ let db = create_test_rw_db(); let tx = db.tx().expect("failed to create transaction"); assert_eq!( StateRoot::overlay_root(&tx, post_state).unwrap(), + // If we had the same state root calculation as ethereum when all values are public: + /* hex!("b464525710cafcf5d4044ac85b72c08b1e76231b8d91f288fe438cc41d8eaafd") + */ + hex!("64f7822621afd8a66d71e233b48e945c101ab97334e19398422f22c3fae72223") ); } }
diff --git reth/crates/trie/db/src/storage.rs seismic-reth/crates/trie/db/src/storage.rs index f7c9fdc3a9806997bd3c190c5af8491eeaa83444..00f79ebbb62599788cdc602af756b743b8dd2d24 100644 --- reth/crates/trie/db/src/storage.rs +++ seismic-reth/crates/trie/db/src/storage.rs @@ -88,7 +88,7 @@ let (BlockNumberAddress((_, storage_address)), storage_change) = entry?; if storage_address == address { let hashed_slot = keccak256(storage_change.key); if let hash_map::Entry::Vacant(entry) = storage.storage.entry(hashed_slot) { - entry.insert(storage_change.value); + entry.insert(storage_change.into()); } } }
diff --git reth/crates/trie/db/tests/fuzz_in_memory_nodes.proptest-regressions seismic-reth/crates/trie/db/tests/fuzz_in_memory_nodes.proptest-regressions new file mode 100644 index 0000000000000000000000000000000000000000..fa9abb807c8e92a2a1b4bffa234e0bf4c350f300 --- /dev/null +++ seismic-reth/crates/trie/db/tests/fuzz_in_memory_nodes.proptest-regressions @@ -0,0 +1,7 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 03c5cacb5ac7def5368e95fe7b9c444477018d3b3c48d56ed8129e5e0fbbf135 # shrinks to mut init_state = {}, state_updates = [{}, {}, {}, {}, {}, {}, {}, {}, {}, {0x02e7527fb8acfe90124b52605de201efff334a647e2f37999b60018f793af863: Some(95896044001895795736490166264465526153250989061366968658961932913205185367762), 0x05971bf3b66ea7bb075bd8cb07f3ec31f56296d4f0d0c71872377fba9c1273b0: Some(10788774338985101928453801016294836156689646137029307970701546570628948127096), 0x0841656b7a8171f3dbf6edd4fa8d06021a28e44a6ba812dd24e06911f33500f0: None, 0x10ef97fee8f58e136b4cecd8f3c82434272af8deca1e017c878773fbff997da2: None, 0x1fe0f43aa28a2f855339fb55b5662a77267e3270f7f57f70db5334a04260e2b8: None, 0x25eb27a4c11f3e0d4cf317970efb43cf783655dd1d54f190bb5404c975e0e8db: None, 0x2ae342b96b9f86a494d4906b4451c06bbba3970e904f84801e60979f147dc9b8: Some(101951868131963777471746419384265939344515125919231661439191076371723613556105), 0x30b667d078d4a58b604eae3f6b7a7f5a781319c341d946dd776e83e243e44452: None, 0x311480b5c49ba525ccb7f5667022b3ab7422c212d96fb88f4eac6207a6c5ef0e: None, 0x36dacb932edee0e0fd4c8653a04816949e6f1657d8181901b9f8646e9990132b: Some(55089561068444347696451422724009700463223626807983706256489215775710063054312), 0x3ca5f4a4ef87d76e1db65e8844e5261cb99919dca67a6dd3cd274f32f23022c3: Some(74610267400277274315432495208978199144622310407679536814006128470699293972910), 0x3d7b646fea24a8b432934b34d4aed8328ec874cfc8dd758b3604b46484f7b1c2: Some(68522120657096254032539223574338925623153460352479577071965148733094080202319), 0x3f51c56ba615496d2cc2c1401b3291c61337fc50958089f37caf2d3ac95d2572: None, 0x3ffc2744dd17fd985abd91d7c89011d676d1a67001d6d176e1451d138000986e: None, 0x40614f6d6fff275a57fc64957b2eef29caca05009854ed3a6a5d278638cf7f6c: Some(55304806495552442286808607243748815575502421164633162194714172036212968617441), 0x4ae51a28301a03648d3a3c79616df5ec747da34b1cf724be3b3e8df1a829104f: Some(103546702317824592355940666435059331785430766417591964466429541552704719912149), 0x4c64b71d5fa9b239a701e0dd6020668fd3cf630ef25aac6b7494ac7b355186b3: Some(60295074506416907083337730235706695238318684289683689594418453744914994401724), 0x4cf4e6d0d4e2289dd0133cc56ed84b18e60d60bdcb0fc5308da64dab11c04b07: None, 0x4e1ffa449f00cc964a903e409c0a30b7ad5517b80ca739edc5faf4035f739143: None, 0x4f72a13efb24ed230b0aa073bc654b26c0184724944509eecd156cb9220541b1: Some(98618271923844597628018412810075454251363119899293287126324082542089709603000), 0x527d2b98895738ab3047061208b9cd176588521a44704ec196a34d3d6ceaad6d: None, 0x52c9e4cc0b36221a0933b432f584dfa720e526ebd61e4dc6a81a0f21d61c6522: Some(40511568142973783051930880546647025738387667812861918721947015488436838151671), 0x5630068d42681a400dedf8b259c1aa30903c9557645e6eb4b085b146d258705f: None, 0x56d69ece04929f67ae78a2662786e697266e080dd51cc976c56c32c1430010c4: Some(71677319842327034159985727442317698304206309322945847924337706935532168362696), 0x598b49fd5611209fa058cd48227bff041b65f218ab39545b64fc3485dcbaf0c4: Some(110015672657272642949935732945672816718670368077505381570097604907693568017670), 0x5aaa30a6000de4298c3eb1af213b9e5a20288babbb4ac5dec79b403332af3ad8: Some(94602276474710517683827485641089473378276536440915703500443121701609505887452), 0x5bda680127e6fe3687a25f1e1f63f1dbe8c35bbb2fb1a1e31ee03664ca62315b: None, 0x65714d689f33b9bd66ba8543eb3cf06f83827a1ef245efc0eb0a1d106d3e2db9: Some(39146498524109321524133488899325021241978962304078029658620015195840455964450), 0x67a1927e8b0b5e36283edad70a964dac3e9c5c4071d9a616b582776e698e204c: Some(59205485890800729215078349763440322392504497054477070992030367025747684972567), 0x67c2044c49497c547fff086f2a245b42cb70c2da2b091604451fd00d1d5ede19: None, 0x6b81a52b391527c1773a22d764456ba04e9bbe5e10263c90d75cc6eb15a19f86: None, 0x6bc0d738594f080b992d2835f527f19779b7ed71971355b61d735f860ccaed93: None, 0x6c9054566555a0988e6935aab52a91c294c1318d603273e635e0e31e9fd9ac2a: Some(65231333619620352346918558189868172252336445660797838670261472751701999375499), 0x7218cb90773e38e5138f7f13e7acf880bc47190f9dc9776c57470cf5c9ccd532: None, 0x728280b7bb661b3ef1e90b5127d7c3155640e13a95737708ed90790ce2506517: None, 0x74c026936871b61e636b598e7931278ba9882c5638999201fbc76e0c53421829: None, 0x775ecdf222ba2ffabf89d866aed41bd61c57867e0cb0dc6035277ad5d55fea2c: None, 0x793636bde053dbc0c2f87f2c0e05499046d85da16ebcd369be8530d571db6307: None, 0x7aea4ec3cc262ea3e554f5e8b6f87acf9c4dedeff90512c1ad8785e13ac77da6: Some(11094995783556026544127939472442345427770879697913436752313629221559782791960), 0x7fb1d393d9098ed1c7b1a4169944de33e1f018ee53b79b984c705ca6ca5472d9: Some(101487864443241238148762473964701388827546033365891236199725339973725270022801), 0x857f6e259fdc6a4a16ea892b681edcb8eb3e1805694d4f9788d034e31b10b7fb: None, 0x8acac796f715635e1bd4553cc3a448339ac773f638c907ac320e2ea9b112663b: None, 0x9128b6d3bc78b21aff7afba5e86cdf215de3bbd4a99c08b5bb87946559655c69: Some(59839569134689466422139142187065267709961826362061394283581132723449966160211), 0x922f0d307177e28030840db4deacef55317e82a8353dacc9b0b79e908b9c81c3: None, 0x959cb1dc5f3dfe3d69cd18ff347fb156fb5273da4462bbad0dd2299e438d8bd7: Some(60616918711852286175599370897131426949509225645918143797287035553413214526474), 0x95d6dbd0c8664c601819a93173913c9380d31b1689bab32d0036b0af1149de1d: None, 0x995c2ddac8de1455ec2deb85059f7c0e9bf27159891a3e9c13e85a8205446c69: None, 0xa2449a0f00c56d0b26850fd28938257b5679c771f9327bdbed6df2404d23635b: None, 0xa74f9a5d414a7cba90530b1c05baf58c13c056fb1e95cf0160e61f31e00dbcea: Some(89085773398307507005201558739027242180144804825378653172903837345079633253041), 0xaaab9816010d06c91d05c28820a34e246ccdf1b40b2d2c3ba0246b5bddd18014: None, 0xb6aee19185884b7436a2a08013a935f99dbd4970365e2bbce75b26f1d57ee752: Some(48756676924900961740901156828261037632197492801715436899717666663431489967153), 0xb93422452aa6d7aae3c04111acf30a91b4ac2acbf8f89d8377adcb2f701cb06d: Some(7851540136644246022491750682384321326754319600770966079684466951677931924994), 0xc20e36209adc1cbbea4b7e9e3cf80cf2df94a52605f24932ff0060fd57dbeec0: None, 0xc21cad30901320b290e113622b6bfa04e658307f4756c8b68a2b45ed31b70ed2: None, 0xc258686d7670a9573f3935811f967d9e75f15bb47ecb84449357669371ecd4e4: None, 0xc454ccd0bf1b76c32cff4d18795a3681e0e1392451440a34b55199cf06fb52b4: None, 0xc6b924e6c562e1e8939cf0b9c3636d5f5ed580fd73f261b314ce5d4078c0c8c4: Some(18270226258822529253346620773245252155617233686188344300972193662909421339294), 0xc916765ac316983656e8af2143cc69e8626477a66ba0317e158d21d96e2d54e9: None, 0xd3ff30833ac72f9f37fce9201d21c8c1354627fa15ed27d0c67fdcd046255f5b: Some(76986521132679654467911631947847878717634019829600727688870935817545461050097), 0xd5c8a97d5ef127cdb72ce1f17c7d5f004b5cf50897fa02831a06e78946a8de04: Some(114674990964438709079637911104182935988156321475232209045957050541784413184482), 0xd83435afc26f36a617952054bd8d1bad6fd67a0a56f8fdc294ba69686c969aa9: None, 0xd95151f9c38a6fc166b62b82c0590b7ddb0224ff9761a31a3b5a43b47240ffa9: None, 0xdc40b35f544cb7ac6695caaca6b6e932c2297d69a8a41740dc81ec32cb863893: None, 0xdc45ec5f9c190c93dae5936246d9e0d8964cfff73f632f04e73ea77a7137d4d5: Some(38650679989874634276728886675128524142286196839093715697244838729678028358542), 0xdcb71c332aa06c4fd90c232f85b61ccef6e427abc116cbe6ac57139be8d8c03e: Some(65784664666899959467916568881875254193001892918961546206684808787357728922789), 0xddbd84cd6abdb9156f77f2d086f3f54e4624d67a496f916bf4faff98ae7fdd40: Some(42406421203103040193989100025354436470636004585955614236491690441857827383038), 0xe60600ff3c53ca5fe41918e779ba8c1a1ade95175a92a4029ab78388a53d3b24: Some(89959490416636351753684133167533284753454620918756388734251222312710332437269), 0xe85cd4646765e592a787c9b89196857a6e9a14ab28587cd90be6285d45c195f0: Some(63035974671951862554821315866624014637671912938792399728356462579561894591759), 0xea781cabfcf165de6bc8e32a5af6794f322c4c5741daa0ee7b8d935f5823e8e5: Some(70255841240988294914543314449763964377641212371748083140140250918454295765080), 0xf0945ec6a739de6926db5d20674338479e95d73c9a22a82bb759a428dd64ae3f: Some(91874302053986958874351709988093809971907160682592485913825351886128931948933), 0xf115d0e2b0fa27a3d7c860b59828331da9c69dceed872b44d2ebb4460cea62cb: None}]
diff --git reth/crates/trie/db/tests/fuzz_in_memory_nodes.rs seismic-reth/crates/trie/db/tests/fuzz_in_memory_nodes.rs index b7b9f3a946a999c4f6d9e815339ecb40b8d9229e..e47dec36e61cce1bfb57d39e52d4636ad51dfe60 100644 --- reth/crates/trie/db/tests/fuzz_in_memory_nodes.rs +++ seismic-reth/crates/trie/db/tests/fuzz_in_memory_nodes.rs @@ -10,7 +10,7 @@ }; use reth_primitives_traits::{Account, StorageEntry}; use reth_provider::test_utils::create_test_provider_factory; use reth_trie::{ - test_utils::{state_root_prehashed, storage_root_prehashed}, + test_utils::{state_root_prehashed, storage_root_prehashed_privacy_aware}, trie_cursor::InMemoryTrieCursorFactory, updates::TrieUpdates, HashedPostState, HashedStorage, StateRoot, StorageRoot, @@ -75,7 +75,7 @@ } }   #[test] - fn fuzz_in_memory_storage_nodes(mut init_storage: BTreeMap<B256, U256>, storage_updates: [(bool, BTreeMap<B256, U256>); 10]) { + fn fuzz_in_memory_storage_nodes(mut init_storage: BTreeMap<B256, alloy_primitives::FlaggedStorage>, storage_updates: [(bool, BTreeMap<B256, alloy_primitives::FlaggedStorage>); 10]) { let hashed_address = B256::random(); let factory = create_test_provider_factory(); let provider = factory.provider_rw().unwrap(); @@ -127,7 +127,7 @@ if is_deleted { storage.clear(); } storage.append(&mut storage_update); - let expected_root = storage_root_prehashed(storage.clone()); + let expected_root = storage_root_prehashed_privacy_aware(storage.clone()); assert_eq!(expected_root, storage_root); } }
diff --git reth/crates/trie/db/tests/post_state.rs seismic-reth/crates/trie/db/tests/post_state.rs index f5b438b4e28b938cbbba203ef24d58cbc9c610c4..21030e279472289ee456e5bf952625494ac295d7 100644 --- reth/crates/trie/db/tests/post_state.rs +++ seismic-reth/crates/trie/db/tests/post_state.rs @@ -13,6 +13,7 @@ }, HashedPostState, HashedStorage, }; use reth_trie_db::DatabaseHashedCursorFactory; +use revm::state::FlaggedStorage; use std::collections::BTreeMap;   fn assert_account_cursor_order( @@ -34,7 +35,7 @@ }   fn assert_storage_cursor_order( factory: &impl HashedCursorFactory, - expected: impl Iterator<Item = (B256, BTreeMap<B256, U256>)>, + expected: impl Iterator<Item = (B256, BTreeMap<B256, FlaggedStorage>)>, ) { for (account, storage) in expected { let mut cursor = factory.hashed_storage_cursor(account).unwrap(); @@ -228,8 +229,11 @@ (0..10).map(|key| (B256::with_last_byte(key), U256::from(key))).collect::<BTreeMap<_, _>>(); db.update(|tx| { for (slot, value) in &db_storage { // insert zero value accounts to the database - tx.put::<tables::HashedStorages>(address, StorageEntry { key: *slot, value: *value }) - .unwrap(); + tx.put::<tables::HashedStorages>( + address, + StorageEntry { key: *slot, value: FlaggedStorage::public(*value) }, + ) + .unwrap(); } }) .unwrap(); @@ -264,7 +268,7 @@ // wiped storage, but post state has zero-value entries { let wiped = true; let mut hashed_storage = HashedStorage::new(wiped); - hashed_storage.storage.insert(B256::random(), U256::ZERO); + hashed_storage.storage.insert(B256::random(), FlaggedStorage::ZERO);   let mut hashed_post_state = HashedPostState::default(); hashed_post_state.storages.insert(address, hashed_storage); @@ -281,7 +285,7 @@ // wiped storage, but post state has non-zero entries { let wiped = true; let mut hashed_storage = HashedStorage::new(wiped); - hashed_storage.storage.insert(B256::random(), U256::from(1)); + hashed_storage.storage.insert(B256::random(), FlaggedStorage::public(1));   let mut hashed_post_state = HashedPostState::default(); hashed_post_state.storages.insert(address, hashed_storage); @@ -298,18 +302,18 @@ #[test] fn storage_cursor_correct_order() { let address = B256::random(); - let db_storage = - (1..11).map(|key| (B256::with_last_byte(key), U256::from(key))).collect::<BTreeMap<_, _>>(); + let db_storage = (1..11) + .map(|key| (B256::with_last_byte(key), FlaggedStorage::public(key))) + .collect::<BTreeMap<_, _>>(); let post_state_storage = (11..21) - .map(|key| (B256::with_last_byte(key), U256::from(key))) + .map(|key| (B256::with_last_byte(key), FlaggedStorage::public(key))) .collect::<BTreeMap<_, _>>();   let db = create_test_rw_db(); db.update(|tx| { - for (slot, value) in &db_storage { + for (slot, &value) in &db_storage { // insert zero value accounts to the database - tx.put::<tables::HashedStorages>(address, StorageEntry { key: *slot, value: *value }) - .unwrap(); + tx.put::<tables::HashedStorages>(address, StorageEntry { key: *slot, value }).unwrap(); } }) .unwrap(); @@ -334,13 +338,18 @@ #[test] fn zero_value_storage_entries_are_discarded() { let address = B256::random(); - let db_storage = - (0..10).map(|key| (B256::with_last_byte(key), U256::from(key))).collect::<BTreeMap<_, _>>(); // every even number is changed to zero value + let db_storage = (0..10) + .map(|key| (B256::with_last_byte(key), FlaggedStorage::public(key))) + .collect::<BTreeMap<_, _>>(); // every even number is changed to zero value let post_state_storage = (0..10) .map(|key| { ( B256::with_last_byte(key), - if key.is_multiple_of(2) { U256::ZERO } else { U256::from(key) }, + if key.is_multiple_of(2) { + FlaggedStorage::ZERO + } else { + FlaggedStorage::public(key) + }, ) }) .collect::<BTreeMap<_, _>>(); @@ -368,7 +377,7 @@ let tx = db.tx().unwrap(); let factory = HashedPostStateCursorFactory::new(DatabaseHashedCursorFactory::new(&tx), &sorted); let expected = std::iter::once(( address, - post_state_storage.into_iter().filter(|(_, value)| *value > U256::ZERO).collect(), + post_state_storage.into_iter().filter(|(_, value)| value.value > U256::ZERO).collect(), )); assert_storage_cursor_order(&factory, expected); } @@ -376,10 +385,11 @@ #[test] fn wiped_storage_is_discarded() { let address = B256::random(); - let db_storage = - (1..11).map(|key| (B256::with_last_byte(key), U256::from(key))).collect::<BTreeMap<_, _>>(); + let db_storage = (1..11) + .map(|key| (B256::with_last_byte(key), FlaggedStorage::public(key))) + .collect::<BTreeMap<_, _>>(); let post_state_storage = (11..21) - .map(|key| (B256::with_last_byte(key), U256::from(key))) + .map(|key| (B256::with_last_byte(key), FlaggedStorage::public(key))) .collect::<BTreeMap<_, _>>();   let db = create_test_rw_db(); @@ -410,8 +420,9 @@ #[test] fn post_state_storages_take_precedence() { let address = B256::random(); - let storage = - (1..10).map(|key| (B256::with_last_byte(key), U256::from(key))).collect::<BTreeMap<_, _>>(); + let storage = (1..10) + .map(|key| (B256::with_last_byte(key), FlaggedStorage::public(key))) + .collect::<BTreeMap<_, _>>();   let db = create_test_rw_db(); db.update(|tx| { @@ -419,7 +430,7 @@ for slot in storage.keys() { // insert zero value accounts to the database tx.put::<tables::HashedStorages>( address, - StorageEntry { key: *slot, value: U256::ZERO }, + StorageEntry { key: *slot, value: FlaggedStorage::ZERO }, ) .unwrap(); } @@ -446,15 +457,15 @@ #[test] fn fuzz_hashed_storage_cursor() { proptest!(ProptestConfig::with_cases(10), |( - db_storages: BTreeMap<B256, BTreeMap<B256, U256>>, - post_state_storages: BTreeMap<B256, (bool, BTreeMap<B256, U256>)> + db_storages: BTreeMap<B256, BTreeMap<B256, FlaggedStorage>>, + post_state_storages: BTreeMap<B256, (bool, BTreeMap<B256, FlaggedStorage>)>, )| { let db = create_test_rw_db(); db.update(|tx| { for (address, storage) in &db_storages { - for (slot, value) in storage { - let entry = StorageEntry { key: *slot, value: *value }; + for (slot, &value) in storage { + let entry = StorageEntry { key: *slot, value }; tx.put::<tables::HashedStorages>(*address, entry).unwrap(); } }
diff --git reth/crates/trie/db/tests/proof.rs seismic-reth/crates/trie/db/tests/proof.rs index 401ba07b22d9ebc73b70db1094baa4b81e18628a..08f32356da52a2c901f69a0a9e1bd86398a3d003 100644 --- reth/crates/trie/db/tests/proof.rs +++ seismic-reth/crates/trie/db/tests/proof.rs @@ -4,10 +4,12 @@ use alloy_consensus::EMPTY_ROOT_HASH; use alloy_primitives::{address, b256, keccak256, Address, Bytes, B256, U256}; use alloy_rlp::EMPTY_STRING_CODE; use reth_chainspec::{Chain, ChainSpec, HOLESKY, MAINNET}; -use reth_primitives_traits::Account; +use reth_db::tables; +use reth_db_api::transaction::{DbTx, DbTxMut}; +use reth_primitives_traits::{Account, StorageEntry}; use reth_provider::test_utils::{create_test_provider_factory, insert_genesis}; -use reth_trie::{proof::Proof, AccountProof, Nibbles, StorageProof}; -use reth_trie_db::DatabaseProof; +use reth_trie::{proof::Proof, AccountProof, Nibbles, StateRoot, StorageProof}; +use reth_trie_db::{DatabaseProof, DatabaseStateRoot}; use std::{ str::FromStr, sync::{Arc, LazyLock}, @@ -170,7 +172,11 @@ assert_eq!(account_proof.verify(root), Ok(())); }   #[test] +#[ignore = "State roots use non-flagged storage"] fn holesky_deposit_contract_proof() { + // legacy test adapter + let is_private = false; + // Create test database and insert genesis accounts. let factory = create_test_provider_factory(); let root = insert_genesis(&factory, HOLESKY.clone()).unwrap(); @@ -214,6 +220,7 @@ value: U256::from_str( "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b", ) .unwrap(), + is_private, proof: convert_to_proof([ "0xf9019180a0aafd5b14a6edacd149e110ba6776a654f2dbffca340902be933d011113f2750380a0a502c93b1918c4c6534d4593ae03a5a23fa10ebc30ffb7080b297bff2446e42da02eb2bf45fd443bd1df8b6f9c09726a4c6252a0f7896a131a081e39a7f644b38980a0a9cf7f673a0bce76fd40332afe8601542910b48dea44e93933a3e5e930da5d19a0ddf79db0a36d0c8134ba143bcb541cd4795a9a2bae8aca0ba24b8d8963c2a77da0b973ec0f48f710bf79f63688485755cbe87f9d4c68326bb83c26af620802a80ea0f0855349af6bf84afc8bca2eda31c8ef8c5139be1929eeb3da4ba6b68a818cb0a0c271e189aeeb1db5d59d7fe87d7d6327bbe7cfa389619016459196497de3ccdea0e7503ba5799e77aa31bbe1310c312ca17b2c5bcc8fa38f266675e8f154c2516ba09278b846696d37213ab9d20a5eb42b03db3173ce490a2ef3b2f3b3600579fc63a0e9041059114f9c910adeca12dbba1fef79b2e2c8899f2d7213cd22dfe4310561a047c59da56bb2bf348c9dd2a2e8f5538a92b904b661cfe54a4298b85868bbe4858080", "0xf85180a0776aa456ba9c5008e03b82b841a9cf2fc1e8578cfacd5c9015804eae315f17fb80808080808080808080808080a072e3e284d47badbb0a5ca1421e1179d3ea90cc10785b26b74fb8a81f0f9e841880", @@ -227,6 +234,7 @@ value: U256::from_str( "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", ) .unwrap(), + is_private, proof: convert_to_proof([ "0xf9019180a0aafd5b14a6edacd149e110ba6776a654f2dbffca340902be933d011113f2750380a0a502c93b1918c4c6534d4593ae03a5a23fa10ebc30ffb7080b297bff2446e42da02eb2bf45fd443bd1df8b6f9c09726a4c6252a0f7896a131a081e39a7f644b38980a0a9cf7f673a0bce76fd40332afe8601542910b48dea44e93933a3e5e930da5d19a0ddf79db0a36d0c8134ba143bcb541cd4795a9a2bae8aca0ba24b8d8963c2a77da0b973ec0f48f710bf79f63688485755cbe87f9d4c68326bb83c26af620802a80ea0f0855349af6bf84afc8bca2eda31c8ef8c5139be1929eeb3da4ba6b68a818cb0a0c271e189aeeb1db5d59d7fe87d7d6327bbe7cfa389619016459196497de3ccdea0e7503ba5799e77aa31bbe1310c312ca17b2c5bcc8fa38f266675e8f154c2516ba09278b846696d37213ab9d20a5eb42b03db3173ce490a2ef3b2f3b3600579fc63a0e9041059114f9c910adeca12dbba1fef79b2e2c8899f2d7213cd22dfe4310561a047c59da56bb2bf348c9dd2a2e8f5538a92b904b661cfe54a4298b85868bbe4858080", "0xf8518080808080a0d546c4ca227a267d29796643032422374624ed109b3d94848c5dc06baceaee76808080808080a027c48e210ccc6e01686be2d4a199d35f0e1e8df624a8d3a17c163be8861acd6680808080", @@ -240,6 +248,7 @@ value: U256::from_str( "0xc78009fdf07fc56a11f122370658a353aaa542ed63e44c4bc15ff4cd105ab33c", ) .unwrap(), + is_private, proof: convert_to_proof([ "0xf9019180a0aafd5b14a6edacd149e110ba6776a654f2dbffca340902be933d011113f2750380a0a502c93b1918c4c6534d4593ae03a5a23fa10ebc30ffb7080b297bff2446e42da02eb2bf45fd443bd1df8b6f9c09726a4c6252a0f7896a131a081e39a7f644b38980a0a9cf7f673a0bce76fd40332afe8601542910b48dea44e93933a3e5e930da5d19a0ddf79db0a36d0c8134ba143bcb541cd4795a9a2bae8aca0ba24b8d8963c2a77da0b973ec0f48f710bf79f63688485755cbe87f9d4c68326bb83c26af620802a80ea0f0855349af6bf84afc8bca2eda31c8ef8c5139be1929eeb3da4ba6b68a818cb0a0c271e189aeeb1db5d59d7fe87d7d6327bbe7cfa389619016459196497de3ccdea0e7503ba5799e77aa31bbe1310c312ca17b2c5bcc8fa38f266675e8f154c2516ba09278b846696d37213ab9d20a5eb42b03db3173ce490a2ef3b2f3b3600579fc63a0e9041059114f9c910adeca12dbba1fef79b2e2c8899f2d7213cd22dfe4310561a047c59da56bb2bf348c9dd2a2e8f5538a92b904b661cfe54a4298b85868bbe4858080", "0xf85180808080a030263404acfee103d0b1019053ff3240fce433c69b709831673285fa5887ce4c80808080808080a0f8f1fbb1f7b482d9860480feebb83ff54a8b6ec1ead61cc7d2f25d7c01659f9c80808080", @@ -250,6 +259,7 @@ StorageProof { key: slot_100, nibbles: Nibbles::unpack(keccak256(slot_100)), value: U256::ZERO, + is_private, proof: convert_to_proof([ "0xf9019180a0aafd5b14a6edacd149e110ba6776a654f2dbffca340902be933d011113f2750380a0a502c93b1918c4c6534d4593ae03a5a23fa10ebc30ffb7080b297bff2446e42da02eb2bf45fd443bd1df8b6f9c09726a4c6252a0f7896a131a081e39a7f644b38980a0a9cf7f673a0bce76fd40332afe8601542910b48dea44e93933a3e5e930da5d19a0ddf79db0a36d0c8134ba143bcb541cd4795a9a2bae8aca0ba24b8d8963c2a77da0b973ec0f48f710bf79f63688485755cbe87f9d4c68326bb83c26af620802a80ea0f0855349af6bf84afc8bca2eda31c8ef8c5139be1929eeb3da4ba6b68a818cb0a0c271e189aeeb1db5d59d7fe87d7d6327bbe7cfa389619016459196497de3ccdea0e7503ba5799e77aa31bbe1310c312ca17b2c5bcc8fa38f266675e8f154c2516ba09278b846696d37213ab9d20a5eb42b03db3173ce490a2ef3b2f3b3600579fc63a0e9041059114f9c910adeca12dbba1fef79b2e2c8899f2d7213cd22dfe4310561a047c59da56bb2bf348c9dd2a2e8f5538a92b904b661cfe54a4298b85868bbe4858080", "0xf891a090bacef44b189ddffdc5f22edc70fe298c58e5e523e6e1dfdf7dbc6d657f7d1b80a026eed68746028bc369eb456b7d3ee475aa16f34e5eaa0c98fdedb9c59ebc53b0808080a09ce86197173e14e0633db84ce8eea32c5454eebe954779255644b45b717e8841808080a0328c7afb2c58ef3f8c4117a8ebd336f1a61d24591067ed9c5aae94796cac987d808080808080", @@ -263,3 +273,167 @@ let account_proof = Proof::from_tx(provider.tx_ref()).account_proof(target, &slots).unwrap(); similar_asserts::assert_eq!(account_proof, expected); assert_eq!(account_proof.verify(root), Ok(())); } + +/// Helper to insert an account with flagged storage entries into the hashed tables. +fn insert_account_with_storage( + tx: &impl DbTxMut, + address: Address, + account: Account, + storage: &[(B256, alloy_primitives::FlaggedStorage)], +) { + let hashed_address = keccak256(address); + tx.put::<tables::HashedAccounts>(hashed_address, account).unwrap(); + for (key, value) in storage { + tx.put::<tables::HashedStorages>( + hashed_address, + StorageEntry { key: keccak256(key), value: *value }, + ) + .unwrap(); + } +} + +#[test] +fn test_flagged_storage_proof() { + // This test verifies that Merkle proofs work correctly with Seismic's flagged storage, + // where storage slots carry a privacy flag (is_private) that affects trie hashing. + + let factory = create_test_provider_factory(); + let tx = factory.provider_rw().unwrap(); + + // Account 1: has both public and private storage slots + let address1 = address!("0x1000000000000000000000000000000000000001"); + let account1 = Account { nonce: 1, balance: U256::from(1000), bytecode_hash: None }; + let slot_a = B256::with_last_byte(0x01); // public slot + let slot_b = B256::with_last_byte(0x02); // private slot + let slot_c = B256::with_last_byte(0x03); // public slot + let storage1 = vec![ + (slot_a, alloy_primitives::FlaggedStorage::new(U256::from(100), false)), + (slot_b, alloy_primitives::FlaggedStorage::new(U256::from(200), true)), + (slot_c, alloy_primitives::FlaggedStorage::new(U256::from(300), false)), + ]; + insert_account_with_storage(tx.tx_ref(), address1, account1, &storage1); + + // Account 2: has only private storage slots + let address2 = address!("0x2000000000000000000000000000000000000002"); + let account2 = + Account { nonce: 5, balance: U256::from(2000), bytecode_hash: Some(keccak256("code2")) }; + let slot_d = B256::with_last_byte(0x10); // private slot + let slot_e = B256::with_last_byte(0x20); // private slot + let storage2 = vec![ + (slot_d, alloy_primitives::FlaggedStorage::new(U256::from(400), true)), + (slot_e, alloy_primitives::FlaggedStorage::new(U256::from(500), true)), + ]; + insert_account_with_storage(tx.tx_ref(), address2, account2, &storage2); + + // Account 3: has only public storage slots (standard behavior) + let address3 = address!("0x3000000000000000000000000000000000000003"); + let account3 = Account { nonce: 10, balance: U256::from(3000), bytecode_hash: None }; + let slot_f = B256::with_last_byte(0x30); // public slot + let storage3 = vec![(slot_f, alloy_primitives::FlaggedStorage::new(U256::from(600), false))]; + insert_account_with_storage(tx.tx_ref(), address3, account3, &storage3); + + // Account 4: no storage at all + let address4 = address!("0x4000000000000000000000000000000000000004"); + let account4 = Account { nonce: 0, balance: U256::from(4000), bytecode_hash: None }; + tx.tx_ref().put::<tables::HashedAccounts>(keccak256(address4), account4).unwrap(); + + tx.commit().unwrap(); + + // Compute state root + let tx = factory.provider_rw().unwrap(); + let root = StateRoot::from_tx(tx.tx_ref()).root().unwrap(); + assert_ne!(root, EMPTY_ROOT_HASH, "state root should not be empty"); + + // --- Verify account proofs --- + + // 1. Account with mixed public/private storage: proof for all slots + let slots = vec![slot_a, slot_b, slot_c]; + let account_proof = Proof::from_tx(tx.tx_ref()).account_proof(address1, &slots).unwrap(); + assert!(account_proof.info.is_some(), "account1 should exist"); + assert_eq!(account_proof.info.unwrap().nonce, 1); + assert_ne!( + account_proof.storage_root, EMPTY_ROOT_HASH, + "account1 should have non-empty storage" + ); + assert_eq!(account_proof.verify(root), Ok(()), "account1 proof should verify"); + + // Check storage proofs individually + assert_eq!(account_proof.storage_proofs.len(), 3); + for storage_proof in &account_proof.storage_proofs { + assert_eq!( + storage_proof.verify(account_proof.storage_root), + Ok(()), + "storage proof for slot {:?} should verify against storage root", + storage_proof.key + ); + } + + // Verify privacy flags are correctly reflected in storage proofs + let proof_a = account_proof.storage_proofs.iter().find(|p| p.key == slot_a).unwrap(); + assert!(!proof_a.is_private, "slot_a should be public"); + assert_eq!(proof_a.value, U256::from(100)); + + let proof_b = account_proof.storage_proofs.iter().find(|p| p.key == slot_b).unwrap(); + assert!(proof_b.is_private, "slot_b should be private"); + assert_eq!(proof_b.value, U256::from(200)); + + let proof_c = account_proof.storage_proofs.iter().find(|p| p.key == slot_c).unwrap(); + assert!(!proof_c.is_private, "slot_c should be public"); + assert_eq!(proof_c.value, U256::from(300)); + + // 2. Account with only private storage + let slots2 = vec![slot_d, slot_e]; + let account_proof2 = Proof::from_tx(tx.tx_ref()).account_proof(address2, &slots2).unwrap(); + assert!(account_proof2.info.is_some(), "account2 should exist"); + assert_eq!(account_proof2.verify(root), Ok(()), "account2 proof should verify"); + + for storage_proof in &account_proof2.storage_proofs { + assert!(storage_proof.is_private, "all account2 storage slots should be private"); + assert_eq!( + storage_proof.verify(account_proof2.storage_root), + Ok(()), + "private storage proof should verify" + ); + } + + // 3. Account with only public storage + let slots3 = vec![slot_f]; + let account_proof3 = Proof::from_tx(tx.tx_ref()).account_proof(address3, &slots3).unwrap(); + assert!(account_proof3.info.is_some(), "account3 should exist"); + assert_eq!(account_proof3.verify(root), Ok(()), "account3 proof should verify"); + + let proof_f = &account_proof3.storage_proofs[0]; + assert!(!proof_f.is_private, "slot_f should be public"); + assert_eq!(proof_f.value, U256::from(600)); + assert_eq!( + proof_f.verify(account_proof3.storage_root), + Ok(()), + "public storage proof should verify" + ); + + // 4. Account with no storage: empty storage proof + let nonexistent_slot = B256::with_last_byte(0xFF); + let account_proof4 = + Proof::from_tx(tx.tx_ref()).account_proof(address4, &[nonexistent_slot]).unwrap(); + assert!(account_proof4.info.is_some(), "account4 should exist"); + assert_eq!(account_proof4.storage_root, EMPTY_ROOT_HASH, "account4 has no storage"); + assert_eq!(account_proof4.verify(root), Ok(()), "account4 proof should verify"); + + let empty_proof = &account_proof4.storage_proofs[0]; + assert_eq!(empty_proof.value, U256::ZERO, "nonexistent slot should have zero value"); + + // 5. Query a nonexistent slot on an account that has storage + let nonexistent_slot2 = B256::with_last_byte(0xAA); + let account_proof5 = + Proof::from_tx(tx.tx_ref()).account_proof(address1, &[nonexistent_slot2]).unwrap(); + assert_eq!(account_proof5.verify(root), Ok(()), "proof for nonexistent slot should verify"); + let missing_proof = &account_proof5.storage_proofs[0]; + assert_eq!(missing_proof.value, U256::ZERO, "nonexistent slot should have zero value"); + + // 6. Proof for a completely nonexistent account + let nonexistent_address = address!("0xdead000000000000000000000000000000000000"); + let account_proof6 = + Proof::from_tx(tx.tx_ref()).account_proof(nonexistent_address, &[]).unwrap(); + assert!(account_proof6.info.is_none(), "nonexistent account should have no info"); + assert_eq!(account_proof6.verify(root), Ok(()), "proof for nonexistent account should verify"); +}
diff --git reth/crates/trie/db/tests/trie.proptest-regressions seismic-reth/crates/trie/db/tests/trie.proptest-regressions new file mode 100644 index 0000000000000000000000000000000000000000..985501c0e5b7d61748565844a97db4a4dd224f6a --- /dev/null +++ seismic-reth/crates/trie/db/tests/trie.proptest-regressions @@ -0,0 +1,8 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 674b48dcd9b6a14db97f39bca073ec06adb02747031eaf1c3e45facc34ba9e3d # shrinks to state = {0x7ed5a0c0a0446aef3e8a37deb577e3e9c4d78c99: (Account { nonce: 11030852537627372716, balance: 101092925486967073639829781883998712174699118353393240094905867310731299056377, bytecode_hash: Some(0xebed5fe0368f02ef5a83086ffab16fca7db08c2d1a5f9e4850befe81abe8675d) }, {0x591bbd4d0490755e86e9109bbe9efcb4e8b9dcc5c111ad5aa4e957e31f2ceab7: FlaggedStorage { value: 101589334507263622185626339124864292125625202242444003044283033711717448354652, is_private: false }, 0xa90d4b992504eab926835443de6421b4c20dc64510688b4d46be740958c229c8: FlaggedStorage { value: 12954600061749020995018837836416948077480643696636806618, is_private: false }})} +cc ab538deea3fdaa942b15f8e7bcd6cddffbc23c4aac03a951ee191bd92b29fc42 # shrinks to item = (0x341a004b8efb93697862e0666e00067645eb99a0, {0x55234e9e6943f1e3c7133d194edb123c8e7380334c968500db0b00f55e041aae: FlaggedStorage { value: 112059458919946063391099606430831296486970527425673685477513114556136590082186, is_private: true }, 0x921f141717a65e96086d07a454d1d452820399464275704a84655e97005ba6e4: FlaggedStorage { value: 319982340417456178828386804444969996492308166526454630153767435928388902965, is_private: false }, 0xcc5c5b2c8ff408c0261e3ea71e5f843617d6c75948d7caa60ab1d7fe6422a4cf: FlaggedStorage { value: 80595192184022019462367709016797387522027913753499355039252894625729195902063, is_private: false }})
diff --git reth/crates/trie/db/tests/trie.rs seismic-reth/crates/trie/db/tests/trie.rs index 6f2588f39e9666d05923b2bfe910978f0968191b..5202f73605e0fde1797cab066d5b0da8395e5707 100644 --- reth/crates/trie/db/tests/trie.rs +++ seismic-reth/crates/trie/db/tests/trie.rs @@ -19,7 +19,10 @@ StorageTrieWriter, TrieWriter, }; use reth_trie::{ prefix_set::{PrefixSetMut, TriePrefixSets}, - test_utils::{state_root, state_root_prehashed, storage_root, storage_root_prehashed}, + test_utils::{ + state_root_prehashed, state_root_privacy_aware, storage_root, storage_root_prehashed, + storage_root_privacy_aware, + }, triehash::KeccakHasher, updates::StorageTrieUpdates, BranchNodeCompact, HashBuilder, IntermediateStateRootState, Nibbles, StateRoot, @@ -32,14 +35,18 @@ fn insert_account( tx: &impl DbTxMut, address: Address, account: Account, - storage: &BTreeMap<B256, U256>, + storage: &BTreeMap<B256, alloy_primitives::FlaggedStorage>, ) { let hashed_address = keccak256(address); tx.put::<tables::HashedAccounts>(hashed_address, account).unwrap(); insert_storage(tx, hashed_address, storage); }   -fn insert_storage(tx: &impl DbTxMut, hashed_address: B256, storage: &BTreeMap<B256, U256>) { +fn insert_storage( + tx: &impl DbTxMut, + hashed_address: B256, + storage: &BTreeMap<B256, alloy_primitives::FlaggedStorage>, +) { for (k, v) in storage { tx.put::<tables::HashedStorages>( hashed_address, @@ -59,7 +66,12 @@ tx.tx_ref().cursor_dup_write::<tables::HashedStorages>().unwrap(); let data = inputs.iter().map(|x| B256::from_str(x).unwrap()); let value = U256::from(0); for key in data { - hashed_storage_cursor.upsert(hashed_address, &StorageEntry { key, value }).unwrap(); + hashed_storage_cursor + .upsert( + hashed_address, + &StorageEntry { key, value: alloy_primitives::FlaggedStorage::public(value) }, + ) + .unwrap(); }   // Generate the intermediate nodes on the receiving end of the channel @@ -73,7 +85,13 @@ if hashed_storage_cursor.seek_by_key_subkey(hashed_address, modified_key).unwrap().is_some() { hashed_storage_cursor.delete_current().unwrap(); } hashed_storage_cursor - .upsert(hashed_address, &StorageEntry { key: modified_key, value }) + .upsert( + hashed_address, + &StorageEntry { + key: modified_key, + value: alloy_primitives::FlaggedStorage::public(value), + }, + ) .unwrap();   // 2. Calculate full merkle root @@ -110,8 +128,7 @@ }   #[test] fn arbitrary_storage_root() { - proptest!(ProptestConfig::with_cases(10), |(item in arb::<(Address, std::collections::BTreeMap<B256, U256>)>())| { - let (address, storage) = item; + proptest!(ProptestConfig::with_cases(10), |(item in arb::<(Address, std::collections::BTreeMap<B256, alloy_primitives::FlaggedStorage>)>())| { let (address, storage) = item;   let hashed_address = keccak256(address); let factory = create_test_provider_factory(); @@ -127,7 +144,7 @@ tx.commit().unwrap();   let tx = factory.provider_rw().unwrap(); let got = StorageRoot::from_tx(tx.tx_ref(), address).root().unwrap(); - let expected = storage_root(storage.into_iter()); + let expected = storage_root_privacy_aware(storage.into_iter()); assert_eq!(expected, got); }); } @@ -140,7 +157,7 @@ ( Address::random(), ( Account { nonce: 0, balance: U256::from(0), bytecode_hash: None }, - BTreeMap::from([(B256::with_last_byte(0x4), U256::from(12))]), + BTreeMap::from([(B256::with_last_byte(0x4), U256::from(12).into())]), ), ), ( @@ -159,8 +176,8 @@ balance: U256::from(414241124u32), bytecode_hash: Some(keccak256("test")), }, BTreeMap::from([ - (B256::ZERO, U256::from(3)), - (B256::with_last_byte(2), U256::from(1)), + (B256::ZERO, U256::from(3).into()), + (B256::with_last_byte(2), U256::from(1).into()), ]), ), ), @@ -196,8 +213,10 @@ let factory = create_test_provider_factory(); let tx = factory.provider_rw().unwrap();   let address = Address::random(); - let storage = - BTreeMap::from([(B256::ZERO, U256::from(3)), (B256::with_last_byte(2), U256::from(1))]); + let storage = BTreeMap::from([ + (B256::ZERO, alloy_primitives::FlaggedStorage::public(U256::from(3))), + (B256::with_last_byte(2), alloy_primitives::FlaggedStorage::public(U256::from(1))), + ]);   let code = "el buen fla"; let account = Account { @@ -215,7 +234,7 @@ assert_eq!(storage_root(storage.into_iter()), got); }   -type State = BTreeMap<Address, (Account, BTreeMap<B256, U256>)>; +type State = BTreeMap<Address, (Account, BTreeMap<B256, alloy_primitives::FlaggedStorage>)>;   #[test] fn arbitrary_state_root() { @@ -242,7 +261,7 @@ } tx.commit().unwrap(); let tx = factory.provider_rw().unwrap();   - let expected = state_root(state); + let expected = state_root_privacy_aware(state);   let threshold = 10; let mut got = None; @@ -278,7 +297,7 @@ for (address, (account, storage)) in &state { insert_account(tx.tx_ref(), *address, *account, storage) } tx.commit().unwrap(); - let expected = state_root(state); + let expected = state_root_privacy_aware(state);   let tx = factory.provider_rw().unwrap(); let got = StateRoot::from_tx(tx.tx_ref()).root().unwrap(); @@ -309,7 +328,9 @@ ("1400000000000000000000000000000000000000000000000000000000000000", 0x01), ("3000000000000000000000000000000000000000000000000000000000E00000", 0x127a89), ("3000000000000000000000000000000000000000000000000000000000E00001", 0x05), ] - .map(|(slot, val)| (B256::from_str(slot).unwrap(), U256::from(val))), + .map(|(slot, val)| { + (B256::from_str(slot).unwrap(), revm_primitives::FlaggedStorage::public(val)) + }), );   let mut hashed_storage_cursor = @@ -327,6 +348,7 @@ }   #[test] fn account_and_storage_trie() { + let account_is_private = false; // accounts are always public let ether = U256::from(1e18); let storage = BTreeMap::from( [ @@ -351,7 +373,11 @@ // Insert first account let key1 = b256!("0xb000000000000000000000000000000000000000000000000000000000000000"); let account1 = Account { nonce: 0, balance: U256::from(3).mul(ether), bytecode_hash: None }; hashed_account_cursor.upsert(key1, &account1).unwrap(); - hash_builder.add_leaf(Nibbles::unpack(key1), &encode_account(account1, None)); + hash_builder.add_leaf( + Nibbles::unpack(key1), + &encode_account(account1, None), + account_is_private, + );   // Some address whose hash starts with 0xB040 let address2 = address!("0x7db3e81b72d2695e19764583f6d219dbee0f35ca"); @@ -360,7 +386,11 @@ assert_eq!(key2[0], 0xB0); assert_eq!(key2[1], 0x40); let account2 = Account { nonce: 0, balance: ether, ..Default::default() }; hashed_account_cursor.upsert(key2, &account2).unwrap(); - hash_builder.add_leaf(Nibbles::unpack(key2), &encode_account(account2, None)); + hash_builder.add_leaf( + Nibbles::unpack(key2), + &encode_account(account2, None), + account_is_private, + );   // Some address whose hash starts with 0xB041 let address3 = address!("0x16b07afd1c635f77172e842a000ead9a2a222459"); @@ -380,29 +410,55 @@ .is_some() { hashed_storage_cursor.delete_current().unwrap(); } - hashed_storage_cursor.upsert(key3, &StorageEntry { key: hashed_slot, value }).unwrap(); + hashed_storage_cursor + .upsert( + key3, + &StorageEntry { + key: hashed_slot, + value: alloy_primitives::FlaggedStorage::public(value), + }, + ) + .unwrap(); } let account3_storage_root = StorageRoot::from_tx(tx.tx_ref(), address3).root().unwrap(); - hash_builder - .add_leaf(Nibbles::unpack(key3), &encode_account(account3, Some(account3_storage_root))); + hash_builder.add_leaf( + Nibbles::unpack(key3), + &encode_account(account3, Some(account3_storage_root)), + account_is_private, + );   let key4a = b256!("0xB1A0000000000000000000000000000000000000000000000000000000000000"); let account4a = Account { nonce: 0, balance: U256::from(4).mul(ether), ..Default::default() }; hashed_account_cursor.upsert(key4a, &account4a).unwrap(); - hash_builder.add_leaf(Nibbles::unpack(key4a), &encode_account(account4a, None)); + hash_builder.add_leaf( + Nibbles::unpack(key4a), + &encode_account(account4a, None), + account_is_private, + );   let key5 = b256!("0xB310000000000000000000000000000000000000000000000000000000000000"); let account5 = Account { nonce: 0, balance: U256::from(8).mul(ether), ..Default::default() }; hashed_account_cursor.upsert(key5, &account5).unwrap(); - hash_builder.add_leaf(Nibbles::unpack(key5), &encode_account(account5, None)); + hash_builder.add_leaf( + Nibbles::unpack(key5), + &encode_account(account5, None), + account_is_private, + );   let key6 = b256!("0xB340000000000000000000000000000000000000000000000000000000000000"); let account6 = Account { nonce: 0, balance: U256::from(1).mul(ether), ..Default::default() }; hashed_account_cursor.upsert(key6, &account6).unwrap(); - hash_builder.add_leaf(Nibbles::unpack(key6), &encode_account(account6, None)); + hash_builder.add_leaf( + Nibbles::unpack(key6), + &encode_account(account6, None), + account_is_private, + );   // Populate account & storage trie DB tables + /* let expected_root = b256!("0x72861041bc90cd2f93777956f058a545412b56de79af5eb6b8075fe2eabbe015"); + */ + let expected_root = b256!("0xf7eac2e1715b2cf20e7d731df7a6cadf6602bac6f66de747c7eb929930c3e976"); let computed_expected_root: B256 = triehash::trie_root::<KeccakHasher, _, _, _>([ (key1, encode_account(account1, None)), (key2, encode_account(account2, None)), @@ -453,9 +509,12 @@ let mut prefix_set = PrefixSetMut::default(); prefix_set.insert(Nibbles::unpack(key4b));   + /* let expected_state_root = b256!("0x8e263cd4eefb0c3cbbb14e5541a66a755cad25bcfab1e10dd9d706263e811b28"); - + */ + let expected_state_root = + b256!("0x96372312afd49741fe2e31097b80e1f5f7f9dbb23ad662099c797cb44bf88a12"); let (root, trie_updates) = StateRoot::from_tx(tx.tx_ref()) .with_prefix_sets(TriePrefixSets { account_prefix_set: prefix_set.freeze(), @@ -685,7 +744,7 @@ fn extension_node_storage_trie<N: ProviderNodeTypes>( tx: &DatabaseProviderRW<Arc<TempDatabase<DatabaseEnv>>, N>, hashed_address: B256, ) -> (B256, StorageTrieUpdates) { - let value = U256::from(1); + let value = U256::from(1).into();   let mut hashed_storage = tx.tx_ref().cursor_write::<tables::HashedStorages>().unwrap();   @@ -702,7 +761,7 @@ ] { hashed_storage .upsert(hashed_address, &StorageEntry { key: B256::new(key), value }) .unwrap(); - hb.add_leaf(Nibbles::unpack(key), &alloy_rlp::encode_fixed_size(&value)); + hb.add_leaf(Nibbles::unpack(key), &alloy_rlp::encode_fixed_size(&value), value.is_private); }   let root = hb.root(); @@ -729,7 +788,7 @@ hex!("30af8f0000000000000000000000000000000000000000000000000000000000"), hex!("3100000000000000000000000000000000000000000000000000000000000000"), ] { hashed_accounts.upsert(B256::new(key), &a).unwrap(); - hb.add_leaf(Nibbles::unpack(key), &val); + hb.add_leaf(Nibbles::unpack(key), &val, false); // account leaves are always public }   hb.root()
diff --git reth/crates/trie/db/tests/witness.rs seismic-reth/crates/trie/db/tests/witness.rs index 5dfa1c3e4aeb394fcc3fa7c482d66b63fb348aba..df2c9a0a779358d058e74a14bb7f59c2e262db25 100644 --- reth/crates/trie/db/tests/witness.rs +++ seismic-reth/crates/trie/db/tests/witness.rs @@ -4,7 +4,7 @@ use alloy_consensus::EMPTY_ROOT_HASH; use alloy_primitives::{ keccak256, map::{HashMap, HashSet}, - Address, Bytes, B256, U256, + Address, Bytes, B256, }; use alloy_rlp::EMPTY_STRING_CODE; use reth_db::{cursor::DbCursorRW, tables}; @@ -16,6 +16,7 @@ proof::Proof, witness::TrieWitness, HashedPostState, HashedStorage, MultiProofTargets, StateRoot, }; use reth_trie_db::{DatabaseProof, DatabaseStateRoot, DatabaseTrieWitness}; +use revm_state::FlaggedStorage;   #[test] fn includes_empty_node_preimage() { @@ -53,7 +54,7 @@ .compute(HashedPostState { accounts: HashMap::from_iter([(hashed_address, Some(Account::default()))]), storages: HashMap::from_iter([( hashed_address, - HashedStorage::from_iter(false, [(hashed_slot, U256::from(1))]), + HashedStorage::from_iter(false, [(hashed_slot, FlaggedStorage::public(1))]), )]), }) .unwrap(); @@ -78,7 +79,10 @@ // Insert account and slot into database provider.insert_account_for_hashing([(address, Some(Account::default()))]).unwrap(); provider - .insert_storage_for_hashing([(address, [StorageEntry { key: slot, value: U256::from(1) }])]) + .insert_storage_for_hashing([( + address, + [StorageEntry { key: slot, value: alloy_primitives::FlaggedStorage::public(1) }], + )]) .unwrap();   let state_root = StateRoot::from_tx(provider.tx_ref()).root().unwrap(); @@ -123,10 +127,16 @@ provider.insert_account_for_hashing([(address, Some(Account::default()))]).unwrap(); let mut hashed_storage_cursor = provider.tx_ref().cursor_dup_write::<tables::HashedStorages>().unwrap(); hashed_storage_cursor - .upsert(hashed_address, &StorageEntry { key: hashed_slot1, value: U256::from(1) }) + .upsert( + hashed_address, + &StorageEntry { key: hashed_slot1, value: alloy_primitives::FlaggedStorage::public(1) }, + ) .unwrap(); hashed_storage_cursor - .upsert(hashed_address, &StorageEntry { key: hashed_slot2, value: U256::from(1) }) + .upsert( + hashed_address, + &StorageEntry { key: hashed_slot2, value: alloy_primitives::FlaggedStorage::public(1) }, + ) .unwrap();   let state_root = StateRoot::from_tx(provider.tx_ref()).root().unwrap(); @@ -144,7 +154,8 @@ storages: HashMap::from_iter([( hashed_address, HashedStorage::from_iter( false, - [hashed_slot1, hashed_slot2].map(|hashed_slot| (hashed_slot, U256::from(2))), + [hashed_slot1, hashed_slot2] + .map(|hashed_slot| (hashed_slot, FlaggedStorage::public(2))), ), )]), })
diff --git reth/crates/trie/parallel/Cargo.toml seismic-reth/crates/trie/parallel/Cargo.toml index 5106142ef386583f9aafbcc01c38368ec95255ee..69c84694473a978e9f89d7f7a8773062b77bb236 100644 --- reth/crates/trie/parallel/Cargo.toml +++ seismic-reth/crates/trie/parallel/Cargo.toml @@ -45,6 +45,8 @@ # reth reth-primitives-traits.workspace = true reth-provider = { workspace = true, features = ["test-utils"] } reth-trie = { workspace = true, features = ["test-utils"] } +revm-primitives.workspace = true +revm-state.workspace = true   # misc rand.workspace = true
diff --git reth/crates/trie/parallel/benches/root.rs seismic-reth/crates/trie/parallel/benches/root.rs index fe1953b90554955c0b5ddca231d223d531538fdc..517e18c0bfd412d616256f5ff5c9aa8f35e9f9c0 100644 --- reth/crates/trie/parallel/benches/root.rs +++ seismic-reth/crates/trie/parallel/benches/root.rs @@ -1,5 +1,5 @@ #![allow(missing_docs, unreachable_pub)] -use alloy_primitives::{B256, U256}; +use alloy_primitives::B256; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner}; use proptest_arbitrary_interop::arb; @@ -13,6 +13,7 @@ TrieInput, }; use reth_trie_db::{DatabaseHashedCursorFactory, DatabaseStateRoot}; use reth_trie_parallel::root::ParallelStateRoot; +use revm_state::FlaggedStorage; use std::collections::HashMap;   pub fn calculate_state_root(c: &mut Criterion) { @@ -87,7 +88,7 @@ ( arb::<Account>().prop_filter("non empty account", |a| !a.is_empty()), hash_map( any::<B256>(), - any::<U256>().prop_filter("non zero value", |v| !v.is_zero()), + any::<FlaggedStorage>().prop_filter("non zero value", |v| !v.is_zero()), storage_size, ), ), @@ -111,7 +112,9 @@ ( address, slots_to_update .into_iter() - .map(|slot| (slot, any::<U256>().new_tree(&mut runner).unwrap().current())) + .map(|slot| { + (slot, any::<FlaggedStorage>().new_tree(&mut runner).unwrap().current()) + }) .collect::<HashMap<_, _>>(), ) })
diff --git reth/crates/trie/parallel/src/lib.rs seismic-reth/crates/trie/parallel/src/lib.rs index c04af264d18d0c49b2a23ab7a088eeabc8924ec9..0b1d84233fa968834eb2c55773b24617f93581af 100644 --- reth/crates/trie/parallel/src/lib.rs +++ seismic-reth/crates/trie/parallel/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/trie/parallel/src/proof.rs seismic-reth/crates/trie/parallel/src/proof.rs index 63ef762000a87948895e87c2102ac341bb324e49..321341c90ab173f41ccd5d52c9aecf74c342b412 100644 --- reth/crates/trie/parallel/src/proof.rs +++ seismic-reth/crates/trie/parallel/src/proof.rs @@ -310,8 +310,12 @@ // Encode account account_rlp.clear(); let account = account.into_trie_account(decoded_storage_multiproof.root); account.encode(&mut account_rlp as &mut dyn BufMut); - - hash_builder.add_leaf(Nibbles::unpack(hashed_address), &account_rlp); + let is_private = false; // account leaves are always public. Their storage leaves can be private. + hash_builder.add_leaf( + Nibbles::unpack(hashed_address), + &account_rlp, + is_private, + );   // We might be adding leaves that are not necessarily our proof targets. if targets.contains_key(&hashed_address) { @@ -414,9 +418,10 @@ provider_rw .insert_storage_for_hashing(state.iter().map(|(address, (_, storage))| { ( *address, - storage - .iter() - .map(|(slot, value)| StorageEntry { key: *slot, value: *value }), + storage.iter().map(|(slot, value)| StorageEntry { + key: *slot, + value: alloy_primitives::FlaggedStorage::public(*value), + }), ) })) .unwrap();
diff --git reth/crates/trie/parallel/src/root.rs seismic-reth/crates/trie/parallel/src/root.rs index 61d8f69a1d239d6bd1124cdcf00e4829a42ac1b2..078b1708f2486e903c97f8a3a10e1d724e88026a 100644 --- reth/crates/trie/parallel/src/root.rs +++ seismic-reth/crates/trie/parallel/src/root.rs @@ -215,7 +215,12 @@ account_rlp.clear(); let account = account.into_trie_account(storage_root); account.encode(&mut account_rlp as &mut dyn BufMut); - hash_builder.add_leaf(Nibbles::unpack(hashed_address), &account_rlp); + let is_private = false; // account leaves are always public. Their storage leaves can be private. + hash_builder.add_leaf( + Nibbles::unpack(hashed_address), + &account_rlp, + is_private, + ); } } } @@ -306,6 +311,7 @@ use rand::Rng; use reth_primitives_traits::{Account, StorageEntry}; use reth_provider::{test_utils::create_test_provider_factory, HashingWriter}; use reth_trie::{test_utils, HashedPostState, HashedStorage}; + use revm_state::FlaggedStorage;   #[tokio::test] async fn random_parallel_root() { @@ -318,13 +324,13 @@ .map(|_| { let address = Address::random(); let account = Account { balance: U256::from(rng.random::<u64>()), ..Default::default() }; - let mut storage = HashMap::<B256, U256>::default(); + let mut storage = HashMap::<B256, alloy_primitives::FlaggedStorage>::default(); let has_storage = rng.random_bool(0.7); if has_storage { for _ in 0..100 { storage.insert( B256::from(U256::from(rng.random::<u64>())), - U256::from(rng.random::<u64>()), + U256::from(rng.random::<u64>()).into(), ); } } @@ -373,13 +379,13 @@ let should_update_storage = rng.random_bool(0.3); if should_update_storage { for (slot, value) in storage.iter_mut() { let hashed_slot = keccak256(slot); - *value = U256::from(rng.random::<u64>()); + *value = U256::from(rng.random::<u64>()).into(); hashed_state .storages .entry(hashed_address) .or_insert_with(HashedStorage::default) .storage - .insert(hashed_slot, *value); + .insert(hashed_slot, FlaggedStorage::from(*value)); } } }
diff --git reth/crates/trie/sparse-parallel/src/trie.rs seismic-reth/crates/trie/sparse-parallel/src/trie.rs index 7523baf9a4b247735d1fb386741fef64790615c3..c1bcabe5e1488e9186f1e488ef6019d96515a6ed 100644 --- reth/crates/trie/sparse-parallel/src/trie.rs +++ seismic-reth/crates/trie/sparse-parallel/src/trie.rs @@ -293,6 +293,7 @@ fn update_leaf<P: TrieNodeProvider>( &mut self, full_path: Nibbles, value: Vec<u8>, + is_private: bool, provider: P, ) -> SparseTrieResult<()> { self.prefix_set.insert(full_path); @@ -324,7 +325,12 @@ next.filter(|next| SparseSubtrieType::path_len_is_upper(next.len())) { // Traverse the next node, keeping track of any changed nodes and the next step in the // trie - match self.upper_subtrie.update_next_node(current, &full_path, retain_updates)? { + match self.upper_subtrie.update_next_node( + current, + &full_path, + is_private, + retain_updates, + )? { LeafUpdateStep::Continue { next_node } => { next = Some(next_node); } @@ -433,7 +439,7 @@ }   // If we didn't update the target leaf, we need to call update_leaf on the subtrie // to ensure that the leaf is updated correctly. - subtrie.update_leaf(full_path, value, provider, retain_updates)?; + subtrie.update_leaf(full_path, value, provider, retain_updates, is_private)?; }   Ok(()) @@ -1136,10 +1142,10 @@ } // If the only child is a leaf node, we downgrade the branch node into a // leaf node, prepending the nibble to the key, and delete the old // child. - SparseNode::Leaf { key, .. } => { + SparseNode::Leaf { key, is_private, .. } => { let mut new_key = Nibbles::from_nibbles_unchecked([remaining_child_nibble]); new_key.extend(key); - (SparseNode::new_leaf(new_key), true) + (SparseNode::new_leaf(new_key, *is_private), true) } // If the only child node is an extension node, we downgrade the branch // node into an even longer extension node, prepending the nibble to the @@ -1186,10 +1192,10 @@ // extending the key. While it's impossible to encounter an extension node // followed by a leaf node in a complete trie, it's possible here because we // could have downgraded the extension node's child into a leaf node from a // branch in a previous call to `branch_changes_on_leaf_removal`. - SparseNode::Leaf { key, .. } => { + SparseNode::Leaf { key, is_private, .. } => { let mut new_key = *parent_key; new_key.extend(key); - Some(SparseNode::new_leaf(new_key)) + Some(SparseNode::new_leaf(new_key, *is_private)) } // Similar to the leaf node, for an extension node, we collapse them into one // extension node, extending the key. @@ -1524,6 +1530,7 @@ full_path: Nibbles, value: Vec<u8>, provider: impl TrieNodeProvider, retain_updates: bool, + is_private: bool, ) -> SparseTrieResult<()> { debug_assert!(full_path.starts_with(&self.path)); let existing = self.inner.values.insert(full_path, value); @@ -1535,7 +1542,7 @@ // Here we are starting at the root of the subtrie, and traversing from there. let mut current = Some(self.path); while let Some(current_path) = current { - match self.update_next_node(current_path, &full_path, retain_updates)? { + match self.update_next_node(current_path, &full_path, is_private, retain_updates)? { LeafUpdateStep::Continue { next_node } => { current = Some(next_node); } @@ -1595,6 +1602,7 @@ fn update_next_node( &mut self, mut current: Nibbles, path: &Nibbles, + is_private: bool, retain_updates: bool, ) -> SparseTrieResult<LeafUpdateStep> { debug_assert!(path.starts_with(&self.path)); @@ -1608,7 +1616,7 @@ SparseNode::Empty => { // We need to insert the node with a different path and key depending on the path of // the subtrie. let path = path.slice(self.path.len()..); - *node = SparseNode::new_leaf(path); + *node = SparseNode::new_leaf(path, is_private); Ok(LeafUpdateStep::complete_with_insertions(vec![current], None)) } SparseNode::Hash(hash) => { @@ -1643,9 +1651,14 @@ current.get_unchecked(common), path.get_unchecked(common), ), ); - self.nodes.insert(new_leaf_path, SparseNode::new_leaf(path.slice(common + 1..))); - self.nodes - .insert(existing_leaf_path, SparseNode::new_leaf(current.slice(common + 1..))); + self.nodes.insert( + new_leaf_path, + SparseNode::new_leaf(path.slice(common + 1..), is_private), + ); + self.nodes.insert( + existing_leaf_path, + SparseNode::new_leaf(current.slice(common + 1..), is_private), + );   Ok(LeafUpdateStep::complete_with_insertions( vec![branch_path, new_leaf_path, existing_leaf_path], @@ -1678,7 +1691,7 @@ self.nodes.insert(branch_path, branch);   // create new leaf - let new_leaf = SparseNode::new_leaf(path.slice(common + 1..)); + let new_leaf = SparseNode::new_leaf(path.slice(common + 1..), is_private); self.nodes.insert(new_leaf_path, new_leaf);   let mut inserted_nodes = vec![branch_path, new_leaf_path]; @@ -1701,7 +1714,7 @@ let nibble = path.get_unchecked(current.len()); current.push_unchecked(nibble); if !state_mask.is_bit_set(nibble) { state_mask.set_bit(nibble); - let new_leaf = SparseNode::new_leaf(path.slice(current.len()..)); + let new_leaf = SparseNode::new_leaf(path.slice(current.len()..), is_private); self.nodes.insert(current, new_leaf); return Ok(LeafUpdateStep::complete_with_insertions(vec![current], None)) } @@ -1832,6 +1845,7 @@ key: leaf.key, // Memoize the hash of a previously blinded node in a new leaf // node. hash: Some(*hash), + is_private: leaf.is_private, }); } // Leaf node already exists. @@ -1850,7 +1864,7 @@ }, Entry::Vacant(entry) => { let mut full = *entry.key(); full.extend(&leaf.key); - entry.insert(SparseNode::new_leaf(leaf.key)); + entry.insert(SparseNode::new_leaf(leaf.key, leaf.is_private)); self.inner.values.insert(full, leaf.value.clone()); } }, @@ -2049,7 +2063,7 @@ SparseNode::Hash(hash) => { // Return pre-computed hash of a blinded node immediately (RlpNode::word_rlp(hash), SparseNodeType::Hash) } - SparseNode::Leaf { key, hash } => { + SparseNode::Leaf { key, hash, is_private } => { let mut path = path; path.extend(key); let value = self.values.get(&path); @@ -2063,7 +2077,8 @@ } else { // Encode the leaf node and update its hash let value = self.values.get(&path).unwrap(); self.buffers.rlp_buf.clear(); - let rlp_node = LeafNodeRef { key, value }.rlp(&mut self.buffers.rlp_buf); + let rlp_node = + LeafNodeRef { key, value, is_private }.rlp(&mut self.buffers.rlp_buf); *hash = rlp_node.as_hash(); (rlp_node, SparseNodeType::Leaf) } @@ -2644,7 +2659,7 @@ trie: &mut ParallelSparseTrie, leaves: impl IntoIterator<Item = (Nibbles, Vec<u8>)>, ) { for (path, value) in leaves { - trie.update_leaf(path, value, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(path, value, false, DefaultTrieNodeProvider).unwrap(); } }   @@ -2763,7 +2778,11 @@ } }   fn create_leaf_node(key: impl AsRef<[u8]>, value_nonce: u64) -> TrieNode { - TrieNode::Leaf(LeafNode::new(Nibbles::from_nibbles(key), encode_account_value(value_nonce))) + TrieNode::Leaf(LeafNode::new( + Nibbles::from_nibbles(key), + encode_account_value(value_nonce), + false, + )) }   fn create_extension_node(key: impl AsRef<[u8]>, child_hash: B256) -> TrieNode { @@ -2832,7 +2851,7 @@ TrieElement::Leaf(key, account) => { let account = account.into_trie_account(EMPTY_ROOT_HASH); account.encode(&mut account_rlp);   - hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp); + hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp, false); account_rlp.clear(); } } @@ -3108,7 +3127,7 @@ trie.reveal_nodes(vec![RevealedSparseNode { path, node, masks }]).unwrap();   assert_matches!( trie.upper_subtrie.nodes.get(&path), - Some(SparseNode::Leaf { key, hash: None }) + Some(SparseNode::Leaf { key, hash: None, is_private: false }) if key == &Nibbles::from_nibbles([0x2, 0x3]) );   @@ -3137,7 +3156,7 @@ assert_eq!(lower_subtrie.path, path);   assert_matches!( lower_subtrie.nodes.get(&path), - Some(SparseNode::Leaf { key, hash: None }) + Some(SparseNode::Leaf { key, hash: None, is_private: false }) if key == &Nibbles::from_nibbles([0x3, 0x4]) ); } @@ -3521,15 +3540,15 @@ SparseNode::new_branch(TrieMask::new(0b0101)), ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::new()), + SparseNode::new_leaf(Nibbles::new(), false), ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), - SparseNode::new_leaf(Nibbles::new()), + SparseNode::new_leaf(Nibbles::new(), false), ), ( Nibbles::from_nibbles([0x5, 0x3]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x7])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x7]), false), ), ] .into_iter(), @@ -3578,11 +3597,11 @@ [ (Nibbles::default(), SparseNode::new_branch(TrieMask::new(0b0011))), ( Nibbles::from_nibbles([0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2]), false), ), ( Nibbles::from_nibbles([0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x4])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x4]), false), ), ] .into_iter(), @@ -3644,11 +3663,11 @@ (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))), (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(TrieMask::new(0b0011))), ( Nibbles::from_nibbles([0x5, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2]), false), ), ( Nibbles::from_nibbles([0x5, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x4])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x4]), false), ), ] .into_iter(), @@ -3699,16 +3718,16 @@ [ (Nibbles::default(), SparseNode::new_branch(TrieMask::new(0b0101))), ( Nibbles::from_nibbles([0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2]), false), ), (Nibbles::from_nibbles([0x2]), SparseNode::new_branch(TrieMask::new(0b0011))), ( Nibbles::from_nibbles([0x2, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x4])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x4]), false), ), ( Nibbles::from_nibbles([0x2, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x6])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x6]), false), ), ] .into_iter(), @@ -3771,7 +3790,7 @@ SparseNode::new_branch(TrieMask::new(0b0011000)), ), ( Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x3]), - SparseNode::new_leaf(Nibbles::default()), + SparseNode::new_leaf(Nibbles::default(), false), ), ( Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4]), @@ -3783,11 +3802,11 @@ SparseNode::new_branch(TrieMask::new(0b0011)), ), ( Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x5, 0x0]), - SparseNode::new_leaf(Nibbles::default()), + SparseNode::new_leaf(Nibbles::default(), false), ), ( Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4, 0x5, 0x1]), - SparseNode::new_leaf(Nibbles::default()), + SparseNode::new_leaf(Nibbles::default(), false), ), ] .into_iter(), @@ -3843,7 +3862,7 @@ [ (Nibbles::default(), SparseNode::new_branch(TrieMask::new(0b0011))), ( Nibbles::from_nibbles([0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2]), false), ), (Nibbles::from_nibbles([0x1]), SparseNode::Hash(B256::repeat_byte(0xab))), ] @@ -3889,7 +3908,7 @@ // After removing 0x123, the trie becomes empty // let mut trie = new_test_trie(std::iter::once(( Nibbles::default(), - SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2, 0x3])), + SparseNode::new_leaf(Nibbles::from_nibbles([0x1, 0x2, 0x3]), false), )));   let provider = MockTrieNodeProvider::new(); @@ -3954,6 +3973,7 @@ Nibbles::from_nibbles([0x0, 0x1, 0x2]), SparseNode::Leaf { key: Nibbles::from_nibbles([0x3, 0x4]), hash: Some(B256::repeat_byte(0x40)), + is_private: false, }, ), ( @@ -3961,6 +3981,7 @@ Nibbles::from_nibbles([0x0, 0x1, 0x3]), SparseNode::Leaf { key: Nibbles::from_nibbles([0x5, 0x6]), hash: Some(B256::repeat_byte(0x50)), + is_private: false, }, ), ( @@ -3968,6 +3989,7 @@ Nibbles::from_nibbles([0x0, 0x1, 0x4]), SparseNode::Leaf { key: Nibbles::from_nibbles([0x6, 0x7]), hash: Some(B256::repeat_byte(0x60)), + is_private: false, }, ), ( @@ -3975,6 +3997,7 @@ Nibbles::from_nibbles([0x1]), SparseNode::Leaf { key: Nibbles::from_nibbles([0x7, 0x8]), hash: Some(B256::repeat_byte(0x70)), + is_private: false, }, ), ] @@ -4213,7 +4236,7 @@ let provider = DefaultTrieNodeProvider; let mut sparse = ParallelSparseTrie::default().with_updates(true); for path in &paths { - sparse.update_leaf(*path, value_encoded(), &provider).unwrap(); + sparse.update_leaf(*path, value_encoded(), false, &provider).unwrap(); } let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); @@ -4372,29 +4395,29 @@ SparseNode::new_branch(0b1010.into()) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), false) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), false) ), ( Nibbles::from_nibbles([0x5, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3]), false) ), (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]), false) ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), false) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), false) ) ]) ); @@ -4430,25 +4453,25 @@ SparseNode::new_branch(0b1010.into()) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), false) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), false) ), (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]), false) ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), false) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), false) ) ]) ); @@ -4473,21 +4496,21 @@ (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))), (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())), ( Nibbles::from_nibbles([0x5, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]), false) ), (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]), false) ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), false) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), false) ) ]) ); @@ -4510,7 +4533,7 @@ (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))), (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())), ( Nibbles::from_nibbles([0x5, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]), false) ), ( Nibbles::from_nibbles([0x5, 0x3]), @@ -4519,11 +4542,11 @@ ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), false) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), false) ) ]) ); @@ -4544,11 +4567,11 @@ (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))), (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())), ( Nibbles::from_nibbles([0x5, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]), false) ), ( Nibbles::from_nibbles([0x5, 0x3]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2]), false) ), ]) ); @@ -4563,7 +4586,7 @@ .map(|(k, v)| (*k, v.clone())) .collect::<BTreeMap<_, _>>(), BTreeMap::from_iter([( Nibbles::default(), - SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), false) ),]) );   @@ -4584,6 +4607,7 @@ fn sparse_trie_remove_leaf_blinded() { let leaf = LeafNode::new( Nibbles::default(), alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(), + false, ); let branch = TrieNode::Branch(BranchNode::new( vec![ @@ -4633,6 +4657,7 @@ fn sparse_trie_remove_leaf_non_existent() { let leaf = LeafNode::new( Nibbles::default(), alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(), + false, ); let branch = TrieNode::Branch(BranchNode::new( vec![ @@ -4696,7 +4721,7 @@ for (key, account) in update.clone() { let account = account.into_trie_account(EMPTY_ROOT_HASH); let mut account_rlp = Vec::new(); account.encode(&mut account_rlp); - sparse.update_leaf(key, account_rlp, &default_provider).unwrap(); + sparse.update_leaf(key, account_rlp, false, &default_provider).unwrap(); } // We need to clone the sparse trie, so that all updated branch nodes are // preserved, and not only those that were changed after the last call to @@ -4839,8 +4864,8 @@ for (key, account) in update.clone() { let account = account.into_trie_account(EMPTY_ROOT_HASH); let mut account_rlp = Vec::new(); account.encode(&mut account_rlp); - serial.update_leaf(key, account_rlp.clone(), &default_provider).unwrap(); - parallel.update_leaf(key, account_rlp, &default_provider).unwrap(); + serial.update_leaf(key, account_rlp.clone(), false, &default_provider).unwrap(); + parallel.update_leaf(key, account_rlp, false, &default_provider).unwrap(); }   // Calculate roots and assert their equality @@ -4939,11 +4964,11 @@ let mut account_rlp = Vec::new(); account.encode(&mut account_rlp);   // Add a leaf and calculate the root. - trie.update_leaf(key_50, account_rlp.clone(), &provider).unwrap(); + trie.update_leaf(key_50, account_rlp.clone(), false, &provider).unwrap(); trie.root();   // Add a second leaf and assert that the root is the expected value. - trie.update_leaf(key_51, account_rlp.clone(), &provider).unwrap(); + trie.update_leaf(key_51, account_rlp.clone(), false, &provider).unwrap();   let expected_root = hex!("0xdaf0ef9f91a2f179bb74501209effdb5301db1697bcab041eca2234b126e25de"); @@ -5025,7 +5050,7 @@ Some(&SparseNode::new_branch(0b101.into())) );   // Insert the leaf for the second key - sparse.update_leaf(key2(), value_encoded(), &provider).unwrap(); + sparse.update_leaf(key2(), value_encoded(), false, &provider).unwrap();   // Check that the branch node was updated and another nibble was set assert_eq!( @@ -5227,7 +5252,7 @@ Some(SparseNode::Extension { key, hash: None, store_in_db_trie: None }) if *key == Nibbles::from_nibbles([0x00]) );   // Insert the leaf with a different prefix - sparse.update_leaf(key3(), value_encoded(), &provider).unwrap(); + sparse.update_leaf(key3(), value_encoded(), false, &provider).unwrap();   // Check that the extension node was turned into a branch node assert_matches!( @@ -5293,7 +5318,7 @@ // └── 0x134: Leaf { key: 0x5 }   // First add leaf 0x1345 - this should create a leaf in upper trie at 0x let (leaf1_path, value1) = ctx.create_test_leaf([0x1, 0x3, 0x4, 0x5], 1); - trie.update_leaf(leaf1_path, value1.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf1_path, value1.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify upper trie has a leaf at the root with key 1345 ctx.assert_upper_subtrie(&trie) @@ -5302,7 +5327,7 @@ .has_value(&leaf1_path, &value1);   // Add leaf 0x1234 - this should go first in the upper subtrie let (leaf2_path, value2) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x4], 2); - trie.update_leaf(leaf2_path, value2.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf2_path, value2.clone(), false, DefaultTrieNodeProvider).unwrap();   // Upper trie should now have a branch at 0x1 ctx.assert_upper_subtrie(&trie) @@ -5312,7 +5337,7 @@ .has_no_value(&leaf2_path);   // Add leaf 0x1245 - this should cause a branch and create the 0x12 subtrie let (leaf3_path, value3) = ctx.create_test_leaf([0x1, 0x2, 0x4, 0x5], 3); - trie.update_leaf(leaf3_path, value3.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf3_path, value3.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify lower subtrie at 0x12 exists with correct structure ctx.assert_subtrie(&trie, Nibbles::from_nibbles([0x1, 0x2])) @@ -5324,7 +5349,7 @@ .has_value(&leaf3_path, &value3);   // Add leaf 0x1334 - this should create another lower subtrie let (leaf4_path, value4) = ctx.create_test_leaf([0x1, 0x3, 0x3, 0x4], 4); - trie.update_leaf(leaf4_path, value4.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf4_path, value4.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify lower subtrie at 0x13 exists with correct values ctx.assert_subtrie(&trie, Nibbles::from_nibbles([0x1, 0x3])) @@ -5368,7 +5393,8 @@ // First insert a leaf that ends exactly at the boundary (2 nibbles) let (first_leaf_path, first_value) = ctx.create_test_leaf([0x1, 0x2, 0x2, 0x4], 1);   - trie.update_leaf(first_leaf_path, first_value.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(first_leaf_path, first_value.clone(), false, DefaultTrieNodeProvider) + .unwrap();   // In an empty trie, the first leaf becomes the root, regardless of path length ctx.assert_upper_subtrie(&trie) @@ -5378,7 +5404,8 @@ // Now insert another leaf that shares the same 2-nibble prefix let (second_leaf_path, second_value) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x4], 2);   - trie.update_leaf(second_leaf_path, second_value.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(second_leaf_path, second_value.clone(), false, DefaultTrieNodeProvider) + .unwrap();   // Now both leaves should be in a lower subtrie at index [0x1, 0x2] ctx.assert_subtrie(&trie, Nibbles::from_nibbles([0x1, 0x2])) @@ -5441,7 +5468,8 @@ // Now update one of the leaves with a new value let updated_path = Nibbles::from_nibbles([0x1, 0x2, 0x3, 0x4]); let (_, updated_value) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x4], 100);   - trie.update_leaf(updated_path, updated_value.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(updated_path, updated_value.clone(), false, DefaultTrieNodeProvider) + .unwrap();   // Verify the subtrie structure is maintained and value is updated // The branch structure should remain the same and all values should be present @@ -5455,7 +5483,8 @@ // Add a new leaf that extends an existing branch let (new_leaf_path, new_leaf_value) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x6], 200);   - trie.update_leaf(new_leaf_path, new_leaf_value.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(new_leaf_path, new_leaf_value.clone(), false, DefaultTrieNodeProvider) + .unwrap();   // Verify the branch at [0x1, 0x2, 0x3] now has an additional child ctx.assert_subtrie(&trie, Nibbles::from_nibbles([0x1, 0x2])) @@ -5823,7 +5852,7 @@ );   // Now add a leaf that will force the hash node to become a branch let (leaf_path, value) = ctx.create_test_leaf([0xA, 0x0], 1); - trie.update_leaf(leaf_path, value, provider).unwrap(); + trie.update_leaf(leaf_path, value, false, provider).unwrap();   // Verify the structure: extension should now terminate in a branch on the upper trie ctx.assert_upper_subtrie(&trie) @@ -5859,8 +5888,8 @@ // Create leaves that share exactly 2 nibbles let (leaf1_path, value1) = ctx.create_test_leaf([0xA, 0xB, 0xC, 0xD, 0xE, 0xF], 1); let (leaf2_path, value2) = ctx.create_test_leaf([0xA, 0xB, 0xD, 0xE, 0xF, 0x0], 2);   - trie.update_leaf(leaf1_path, value1.clone(), DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(leaf2_path, value2.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf1_path, value1.clone(), false, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf2_path, value2.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify upper trie structure ctx.assert_upper_subtrie(&trie) @@ -5916,9 +5945,9 @@ let (leaf1_path, value1) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x4], 1); let (leaf2_path, value2) = ctx.create_test_leaf([0x2, 0x3, 0x4, 0x5], 2); let (leaf3_path, value3) = ctx.create_test_leaf([0x2, 0x3, 0x5, 0x6], 3);   - trie.update_leaf(leaf1_path, value1, DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(leaf2_path, value2, DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(leaf3_path, value3, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf1_path, value1, false, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf2_path, value2, false, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf3_path, value3, false, DefaultTrieNodeProvider).unwrap();   // Verify initial structure has branch at root ctx.assert_upper_subtrie(&trie).has_branch(&Nibbles::default(), &[0x1, 0x2]); @@ -5932,9 +5961,12 @@ // Clear and add new leaves let mut trie = ParallelSparseTrie::from_root(TrieNode::EmptyRoot, TrieMasks::none(), true).unwrap(); - trie.update_leaf(new_leaf1_path, new_value1.clone(), DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(new_leaf2_path, new_value2.clone(), DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(new_leaf3_path, new_value3.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(new_leaf1_path, new_value1.clone(), false, DefaultTrieNodeProvider) + .unwrap(); + trie.update_leaf(new_leaf2_path, new_value2.clone(), false, DefaultTrieNodeProvider) + .unwrap(); + trie.update_leaf(new_leaf3_path, new_value3.clone(), false, DefaultTrieNodeProvider) + .unwrap();   // Verify new structure has extension ctx.assert_upper_subtrie(&trie) @@ -5979,9 +6011,9 @@ let (leaf1_path, value1) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x4], 1); let (leaf2_path, value2) = ctx.create_test_leaf([0x2, 0x3, 0x4, 0x5], 2); let (leaf3_path, value3) = ctx.create_test_leaf([0x2, 0x3, 0x5, 0x6], 3);   - trie.update_leaf(leaf1_path, value1, DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(leaf2_path, value2.clone(), DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(leaf3_path, value3.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf1_path, value1, false, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf2_path, value2.clone(), false, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf3_path, value3.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify upper trie structure ctx.assert_upper_subtrie(&trie) @@ -6040,7 +6072,7 @@ // └── 0x124: Leaf { key: 0x }   // Step 1: Add first leaf - initially stored as leaf in upper trie let (leaf1_path, value1) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x4, 0x5], 1); - trie.update_leaf(leaf1_path, value1.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf1_path, value1.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify leaf node in upper trie (optimized single-leaf case) ctx.assert_upper_subtrie(&trie) @@ -6049,7 +6081,7 @@ .has_value(&leaf1_path, &value1);   // Step 2: Add leaf at 0x12346 - creates branch at 0x1234 let (leaf2_path, value2) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x4, 0x6], 2); - trie.update_leaf(leaf2_path, value2.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf2_path, value2.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify extension now goes to 0x1234 ctx.assert_upper_subtrie(&trie) @@ -6067,7 +6099,7 @@ .has_value(&leaf2_path, &value2);   // Step 3: Add leaf at 0x1235 - creates branch at 0x123 let (leaf3_path, value3) = ctx.create_test_leaf([0x1, 0x2, 0x3, 0x5], 3); - trie.update_leaf(leaf3_path, value3.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf3_path, value3.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify extension now goes to 0x123 ctx.assert_upper_subtrie(&trie) @@ -6086,7 +6118,7 @@ .has_value(&leaf3_path, &value3);   // Step 4: Add leaf at 0x124 - creates branch at 0x12 (subtrie root) let (leaf4_path, value4) = ctx.create_test_leaf([0x1, 0x2, 0x4], 4); - trie.update_leaf(leaf4_path, value4.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf4_path, value4.clone(), false, DefaultTrieNodeProvider).unwrap();   // Verify extension now goes to 0x12 ctx.assert_upper_subtrie(&trie) @@ -6132,8 +6164,8 @@ let (leaf1_path, value1) = ctx.create_test_leaf(&path1_nibbles, 1); let (leaf2_path, value2) = ctx.create_test_leaf(&path2_nibbles, 2);   - trie.update_leaf(leaf1_path, value1.clone(), DefaultTrieNodeProvider).unwrap(); - trie.update_leaf(leaf2_path, value2.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf1_path, value1.clone(), false, DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf2_path, value2.clone(), false, DefaultTrieNodeProvider).unwrap();   // The common prefix of 63 F's will create a very long extension let extension_key = vec![0xF; 63]; @@ -6233,7 +6265,7 @@ &hex!("d65eaa92c6bc4c13a5ec45527f0c18ea8932588728769ec7aecfe6d9f32e42")[..], ); let leaf_value = hex!("f8440180a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0f57acd40259872606d76197ef052f3d35588dadf919ee1f0e3cb9b62d3f4b02c").to_vec();   - let leaf_node = LeafNode::new(leaf_key, leaf_value); + let leaf_node = LeafNode::new(leaf_key, leaf_value, false); let leaf_masks = TrieMasks::none();   trie.reveal_nodes(vec![ @@ -6261,7 +6293,8 @@ 245, 122, 205, 64, 37, 152, 114, 96, 109, 118, 25, 126, 240, 82, 243, 211, 85, 136, 218, 223, 145, 158, 225, 240, 227, 203, 155, 98, 211, 244, 176, 44, ];   - trie.update_leaf(leaf_full_path, leaf_new_value.clone(), DefaultTrieNodeProvider).unwrap(); + trie.update_leaf(leaf_full_path, leaf_new_value.clone(), false, DefaultTrieNodeProvider) + .unwrap();   // Sanity checks before calculating the root assert_eq!( @@ -6284,7 +6317,7 @@ let mut sparse = ParallelSparseTrie::default(); let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]); let value = b"test_value".to_vec();   - sparse.update_leaf(path, value.clone(), &provider).unwrap(); + sparse.update_leaf(path, value.clone(), false, &provider).unwrap();   // Check that the leaf exists let result = sparse.find_leaf(&path, None); @@ -6304,7 +6337,7 @@ let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]); let value = b"test_value".to_vec(); let wrong_value = b"wrong_value".to_vec();   - sparse.update_leaf(path, value, &provider).unwrap(); + sparse.update_leaf(path, value, false, &provider).unwrap();   // Check with wrong expected value let result = sparse.find_leaf(&path, Some(&wrong_value)); @@ -6339,7 +6372,7 @@ fn find_leaf_exists_no_value_check() { let provider = DefaultTrieNodeProvider; let mut sparse = ParallelSparseTrie::default(); let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); - sparse.update_leaf(path, encode_account_value(0), &provider).unwrap(); + sparse.update_leaf(path, encode_account_value(0), false, &provider).unwrap();   let result = sparse.find_leaf(&path, None); assert_matches!(result, Ok(LeafLookup::Exists)); @@ -6351,7 +6384,7 @@ let provider = DefaultTrieNodeProvider; let mut sparse = ParallelSparseTrie::default(); let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let value = encode_account_value(0); - sparse.update_leaf(path, value.clone(), &provider).unwrap(); + sparse.update_leaf(path, value.clone(), false, &provider).unwrap();   let result = sparse.find_leaf(&path, Some(&value)); assert_matches!(result, Ok(LeafLookup::Exists)); @@ -6365,8 +6398,8 @@ let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); // Creates branch at 0x12 let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]); // Belongs to same branch let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]); // Diverges at nibble 7   - sparse.update_leaf(path1, encode_account_value(0), &provider).unwrap(); - sparse.update_leaf(path2, encode_account_value(1), &provider).unwrap(); + sparse.update_leaf(path1, encode_account_value(0), false, &provider).unwrap(); + sparse.update_leaf(path2, encode_account_value(1), false, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)) @@ -6381,7 +6414,7 @@ let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]); // This path diverges from the extension key let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]);   - sparse.update_leaf(path1, encode_account_value(0), &provider).unwrap(); + sparse.update_leaf(path1, encode_account_value(0), false, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)) @@ -6394,7 +6427,7 @@ let mut sparse = ParallelSparseTrie::default(); let existing_leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]);   - sparse.update_leaf(existing_leaf_path, encode_account_value(0), &provider).unwrap(); + sparse.update_leaf(existing_leaf_path, encode_account_value(0), false, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)) @@ -6408,8 +6441,8 @@ let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); // Creates branch at 0x12 let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]); let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2]); // Path of the branch itself   - sparse.update_leaf(path1, encode_account_value(0), &provider).unwrap(); - sparse.update_leaf(path2, encode_account_value(1), &provider).unwrap(); + sparse.update_leaf(path1, encode_account_value(0), false, &provider).unwrap(); + sparse.update_leaf(path2, encode_account_value(1), false, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)); @@ -6469,7 +6502,7 @@ (Nibbles::default(), SparseNode::new_branch(TrieMask::new(0b100010))), (path_to_blind, SparseNode::Hash(blinded_hash)), ( Nibbles::from_nibbles_unchecked([0x5]), - SparseNode::new_leaf(Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8])), + SparseNode::new_leaf(Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8]), false), ), ] .into_iter(),
diff --git reth/crates/trie/sparse/benches/rlp_node.rs seismic-reth/crates/trie/sparse/benches/rlp_node.rs index 9f2337f31b8a8b1089039e1513f5e258aadff3fa..a228c9bb4ad35f8440f02dfc5ab6f9406576380a 100644 --- reth/crates/trie/sparse/benches/rlp_node.rs +++ seismic-reth/crates/trie/sparse/benches/rlp_node.rs @@ -21,7 +21,9 @@ .new_tree(&mut runner) .unwrap() .current();   - // Create a sparse trie with `size` leaves + let is_private = false; // hardcoded to false for legacy benchmark + // Create a sparse trie with `size` leaves + let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default(); for (key, value) in &state { @@ -29,6 +31,7 @@ sparse .update_leaf( Nibbles::unpack(key), alloy_rlp::encode_fixed_size(value).to_vec(), + false, &provider, ) .unwrap(); @@ -44,6 +47,7 @@ sparse .update_leaf( Nibbles::unpack(key), alloy_rlp::encode_fixed_size(&rng.random::<U256>()).to_vec(), + is_private, &provider, ) .unwrap();
diff --git reth/crates/trie/sparse/benches/root.rs seismic-reth/crates/trie/sparse/benches/root.rs index 396776ecf5ed5d8f1be747ca2a7bb237378f3d30..bf36f45334f234a2799ba0acb5dfe95c8a8dec57 100644 --- reth/crates/trie/sparse/benches/root.rs +++ seismic-reth/crates/trie/sparse/benches/root.rs @@ -15,7 +15,11 @@ }; use reth_trie_common::{HashBuilder, Nibbles}; use reth_trie_sparse::{provider::DefaultTrieNodeProvider, SerialSparseTrie, SparseTrie};   +// seismic-only dependencies +use alloy_primitives::FlaggedStorage; + fn calculate_root_from_leaves(c: &mut Criterion) { + let is_private = false; // hardcode to false for legacy test let mut group = c.benchmark_group("calculate root from leaves"); group.sample_size(20);   @@ -32,7 +36,11 @@ // hash builder group.bench_function(BenchmarkId::new("hash builder", size), |b| { b.iter_with_setup(HashBuilder::default, |mut hb| { for (key, value) in state.iter().sorted_by_key(|(key, _)| *key) { - hb.add_leaf(Nibbles::unpack(key), &alloy_rlp::encode_fixed_size(value)); + hb.add_leaf( + Nibbles::unpack(key), + &alloy_rlp::encode_fixed_size(value), + is_private, + ); } hb.root(); hb @@ -48,6 +56,7 @@ sparse .update_leaf( Nibbles::unpack(key), alloy_rlp::encode_fixed_size(value).to_vec(), + is_private, &provider, ) .unwrap(); @@ -60,10 +69,12 @@ } }   fn calculate_root_from_leaves_repeated(c: &mut Criterion) { + let is_private = false; // hardcode to false for legacy test + let mut group = c.benchmark_group("calculate root from leaves repeated"); group.sample_size(20);   - for init_size in [1_000, 10_000, 100_000] { + for init_size in [1_000, 10_000, 100_000, 1_000_00] { // Too slow. #[expect(unexpected_cfgs)] if cfg!(codspeed) && init_size > 10_000 { @@ -105,6 +116,7 @@ for (key, value) in init_state.iter().sorted_by_key(|(key, _)| *key) { hb.add_leaf( Nibbles::unpack(key), &alloy_rlp::encode_fixed_size(value), + is_private, ); } hb.root(); @@ -163,6 +175,7 @@ TrieElement::Leaf(hashed_slot, value) => { hb.add_leaf( Nibbles::unpack(hashed_slot), alloy_rlp::encode_fixed_size(&value).as_ref(), + is_private, ); } } @@ -195,6 +208,7 @@ sparse .update_leaf( Nibbles::unpack(key), alloy_rlp::encode_fixed_size(value).to_vec(), + is_private, &provider, ) .unwrap(); @@ -209,6 +223,7 @@ sparse .update_leaf( Nibbles::unpack(key), alloy_rlp::encode_fixed_size(value).to_vec(), + is_private, &provider, ) .unwrap(); @@ -224,13 +239,14 @@ } } }   -fn generate_test_data(size: usize) -> B256Map<U256> { +fn generate_test_data(size: usize) -> B256Map<FlaggedStorage> { let mut runner = TestRunner::deterministic(); proptest::collection::hash_map(any::<B256>(), any::<U256>(), size) .new_tree(&mut runner) .unwrap() .current() .into_iter() + .map(|(key, value)| (key, FlaggedStorage::new(value, false))) .collect() }
diff --git reth/crates/trie/sparse/benches/update.rs seismic-reth/crates/trie/sparse/benches/update.rs index dff0260a9a43f7d99b69219c4ed0c516c74167c1..d7cea09664e26b8c45316561c267124cc390ac1f 100644 --- reth/crates/trie/sparse/benches/update.rs +++ seismic-reth/crates/trie/sparse/benches/update.rs @@ -23,7 +23,7 @@ || { let mut trie = SparseTrie::<SerialSparseTrie>::revealed_empty(); // Pre-populate with data for (path, value) in leaves.iter().cloned() { - trie.update_leaf(path, value, &provider).unwrap(); + trie.update_leaf(path, value, false, &provider).unwrap(); }   let new_leaves = leaves @@ -43,7 +43,7 @@ (trie, new_leaves) }, |(mut trie, new_leaves)| { for (path, new_value) in new_leaves { - trie.update_leaf(*path, new_value, &provider).unwrap(); + trie.update_leaf(*path, new_value, false, &provider).unwrap(); } trie }, @@ -67,7 +67,7 @@ || { let mut trie = SparseTrie::<SerialSparseTrie>::revealed_empty(); // Pre-populate with data for (path, value) in leaves.iter().cloned() { - trie.update_leaf(path, value, &provider).unwrap(); + trie.update_leaf(path, value, false, &provider).unwrap(); }   let delete_leaves = leaves
diff --git reth/crates/trie/sparse/src/state.rs seismic-reth/crates/trie/sparse/src/state.rs index 0071811f9bc66bf5e2ff2d1f8ab05475b63f4df3..3ebec2ae8301c5e32c449ecb70e4583a876fba2d 100644 --- reth/crates/trie/sparse/src/state.rs +++ seismic-reth/crates/trie/sparse/src/state.rs @@ -644,9 +644,10 @@ ) -> SparseStateTrieResult<()> { if !self.revealed_account_paths.contains(&path) { self.revealed_account_paths.insert(path); } + let is_private = false; // account leaves are always public. Their storage leaves can be private.   let provider = provider_factory.account_node_provider(); - self.state.update_leaf(path, value, provider)?; + self.state.update_leaf(path, value, is_private, provider)?; Ok(()) }   @@ -656,6 +657,7 @@ &mut self, address: B256, slot: Nibbles, value: Vec<u8>, + is_private: bool, provider_factory: impl TrieNodeProviderFactory, ) -> SparseStateTrieResult<()> { let provider = provider_factory.storage_node_provider(address); @@ -663,7 +665,7 @@ self.storage .tries .get_mut(&address) .ok_or(SparseTrieErrorKind::Blind)? - .update_leaf(slot, value, provider)?; + .update_leaf(slot, value, is_private, provider)?; self.storage.get_revealed_paths_mut(address).insert(slot); Ok(()) } @@ -693,7 +695,7 @@ // ...the account is newly created and the storage trie is empty. EMPTY_ROOT_HASH } } else { - return Err(SparseTrieErrorKind::Blind.into()) + return Err(SparseTrieErrorKind::Blind.into()); };   if account.is_empty() && storage_root == EMPTY_ROOT_HASH { @@ -721,7 +723,7 @@ address: B256, provider_factory: impl TrieNodeProviderFactory, ) -> SparseStateTrieResult<bool> { if !self.is_account_revealed(address) { - return Err(SparseTrieErrorKind::Blind.into()) + return Err(SparseTrieErrorKind::Blind.into()); }   // Nothing to update if the account doesn't exist in the trie. @@ -974,6 +976,7 @@ };   #[test] fn reveal_account_path_twice() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent let provider_factory = DefaultTrieNodeProviderFactory; let mut sparse = SparseStateTrie::<SerialSparseTrie>::default();   @@ -981,10 +984,12 @@ let leaf_value = alloy_rlp::encode(TrieAccount::default()); let leaf_1 = alloy_rlp::encode(TrieNode::Leaf(LeafNode::new( Nibbles::default(), leaf_value.clone(), + is_private, ))); let leaf_2 = alloy_rlp::encode(TrieNode::Leaf(LeafNode::new( Nibbles::default(), leaf_value.clone(), + is_private, )));   let multiproof = MultiProof { @@ -1046,6 +1051,7 @@ }   #[test] fn reveal_storage_path_twice() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent let provider_factory = DefaultTrieNodeProviderFactory; let mut sparse = SparseStateTrie::<SerialSparseTrie>::default();   @@ -1053,10 +1059,12 @@ let leaf_value = alloy_rlp::encode(TrieAccount::default()); let leaf_1 = alloy_rlp::encode(TrieNode::Leaf(LeafNode::new( Nibbles::default(), leaf_value.clone(), + is_private, ))); let leaf_2 = alloy_rlp::encode(TrieNode::Leaf(LeafNode::new( Nibbles::default(), leaf_value.clone(), + is_private, )));   let multiproof = MultiProof { @@ -1149,10 +1157,20 @@ let slot_3 = b256!("0x2000000000000000000000000000000000000000000000000000000000000000"); let slot_path_3 = Nibbles::unpack(slot_3); let value_3 = U256::from(rng.random::<u64>());   + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent + let mut storage_hash_builder = HashBuilder::default() .with_proof_retainer(ProofRetainer::from_iter([slot_path_1, slot_path_2])); - storage_hash_builder.add_leaf(slot_path_1, &alloy_rlp::encode_fixed_size(&value_1)); - storage_hash_builder.add_leaf(slot_path_2, &alloy_rlp::encode_fixed_size(&value_2)); + storage_hash_builder.add_leaf( + slot_path_1, + &alloy_rlp::encode_fixed_size(&value_1), + is_private, + ); + storage_hash_builder.add_leaf( + slot_path_2, + &alloy_rlp::encode_fixed_size(&value_2), + is_private, + );   let storage_root = storage_hash_builder.root(); let storage_proof_nodes = storage_hash_builder.take_proof_nodes(); @@ -1170,10 +1188,11 @@ let address_path_2 = Nibbles::unpack(address_2); let account_2 = Account::arbitrary(&mut arbitrary::Unstructured::new(&bytes)).unwrap(); let mut trie_account_2 = account_2.into_trie_account(EMPTY_ROOT_HASH);   + let is_private = false; // account leaves are always public. Their storage leaves can be private. let mut hash_builder = HashBuilder::default() .with_proof_retainer(ProofRetainer::from_iter([address_path_1, address_path_2])); - hash_builder.add_leaf(address_path_1, &alloy_rlp::encode(trie_account_1)); - hash_builder.add_leaf(address_path_2, &alloy_rlp::encode(trie_account_2)); + hash_builder.add_leaf(address_path_1, &alloy_rlp::encode(trie_account_1), is_private); + hash_builder.add_leaf(address_path_2, &alloy_rlp::encode(trie_account_2), is_private);   let root = hash_builder.root(); let proof_nodes = hash_builder.take_proof_nodes(); @@ -1230,11 +1249,13 @@ &provider_factory, ) .unwrap();   + let is_private = false; // legacy test does not use private storage sparse .update_storage_leaf( address_1, slot_path_3, alloy_rlp::encode(value_3), + is_private, &provider_factory, ) .unwrap(); @@ -1280,8 +1301,10 @@ }   #[test] fn test_filter_map_revealed_nodes() { + let is_private = false; // hardcode to false for legacy test let mut revealed_nodes = HashSet::from_iter([Nibbles::from_nibbles([0x0])]); - let leaf = TrieNode::Leaf(LeafNode::new(Nibbles::default(), alloy_rlp::encode([]))); + let leaf = + TrieNode::Leaf(LeafNode::new(Nibbles::default(), alloy_rlp::encode([]), is_private)); let leaf_encoded = alloy_rlp::encode(&leaf); let branch = TrieNode::Branch(BranchNode::new( vec![RlpNode::from_rlp(&leaf_encoded), RlpNode::from_rlp(&leaf_encoded)],
diff --git reth/crates/trie/sparse/src/traits.rs seismic-reth/crates/trie/sparse/src/traits.rs index 300ac39c1b6586e534d1604d9f6840e72628c33c..9a6adb215470d92a663a31d357a6f844171226b2 100644 --- reth/crates/trie/sparse/src/traits.rs +++ seismic-reth/crates/trie/sparse/src/traits.rs @@ -111,6 +111,7 @@ fn update_leaf<P: TrieNodeProvider>( &mut self, full_path: Nibbles, value: Vec<u8>, + is_private: bool, provider: P, ) -> SparseTrieResult<()>;
diff --git reth/crates/trie/sparse/src/trie.rs seismic-reth/crates/trie/sparse/src/trie.rs index ca356e060e214e8fd3dab2681658ece7db9b8965..46e6faa90b64141403b693da2bfc227810940d38 100644 --- reth/crates/trie/sparse/src/trie.rs +++ seismic-reth/crates/trie/sparse/src/trie.rs @@ -227,10 +227,11 @@ pub fn update_leaf( &mut self, path: Nibbles, value: Vec<u8>, + is_private: bool, provider: impl TrieNodeProvider, ) -> SparseTrieResult<()> { let revealed = self.as_revealed_mut().ok_or(SparseTrieErrorKind::Blind)?; - revealed.update_leaf(path, value, provider)?; + revealed.update_leaf(path, value, is_private, provider)?; Ok(()) }   @@ -423,7 +424,7 @@ trace!(target: "trie::sparse", ?path, ?node, ?masks, "reveal_node called");   // If the node is already revealed and it's not a hash node, do nothing. if self.nodes.get(&path).is_some_and(|node| !node.is_hash()) { - return Ok(()) + return Ok(()); }   if let Some(tree_mask) = masks.tree_mask { @@ -531,6 +532,7 @@ key: leaf.key, // Memoize the hash of a previously blinded node in a new leaf // node. hash: Some(*hash), + is_private: leaf.is_private, }); } // Left node already exists. @@ -549,8 +551,8 @@ }, Entry::Vacant(entry) => { let mut full = *entry.key(); full.extend(&leaf.key); - entry.insert(SparseNode::new_leaf(leaf.key)); - self.values.insert(full, leaf.value.clone()); + entry.insert(SparseNode::new_leaf(leaf.key, leaf.is_private)); + self.values.insert(full, leaf.value); } }, } @@ -570,6 +572,7 @@ fn update_leaf<P: TrieNodeProvider>( &mut self, full_path: Nibbles, value: Vec<u8>, + is_private: bool, provider: P, ) -> SparseTrieResult<()> { trace!(target: "trie::sparse", ?full_path, ?value, "update_leaf called"); @@ -585,13 +588,15 @@ let mut current = Nibbles::default(); while let Some(node) = self.nodes.get_mut(&current) { match node { SparseNode::Empty => { - *node = SparseNode::new_leaf(full_path); + *node = SparseNode::new_leaf(full_path, is_private); break } &mut SparseNode::Hash(hash) => { return Err(SparseTrieErrorKind::BlindedNode { path: current, hash }.into()) } - SparseNode::Leaf { key: current_key, .. } => { + SparseNode::Leaf { key: current_key, is_private: existing_is_private, .. } => { + // Store the existing is_private value before modifying the node + let existing_is_private = *existing_is_private; current.extend(current_key);   // this leaf is being updated @@ -617,11 +622,11 @@ ), ); self.nodes.insert( full_path.slice(..=common), - SparseNode::new_leaf(full_path.slice(common + 1..)), + SparseNode::new_leaf(full_path.slice(common + 1..), is_private), ); self.nodes.insert( current.slice(..=common), - SparseNode::new_leaf(current.slice(common + 1..)), + SparseNode::new_leaf(current.slice(common + 1..), existing_is_private), );   break; @@ -677,7 +682,8 @@ ); self.nodes.insert(current.slice(..common), branch);   // create new leaf - let new_leaf = SparseNode::new_leaf(full_path.slice(common + 1..)); + let new_leaf = + SparseNode::new_leaf(full_path.slice(common + 1..), is_private); self.nodes.insert(full_path.slice(..=common), new_leaf);   // recreate extension to previous child if needed @@ -694,7 +700,8 @@ let nibble = full_path.get_unchecked(current.len()); current.push_unchecked(nibble); if !state_mask.is_bit_set(nibble) { state_mask.set_bit(nibble); - let new_leaf = SparseNode::new_leaf(full_path.slice(current.len()..)); + let new_leaf = + SparseNode::new_leaf(full_path.slice(current.len()..), is_private); self.nodes.insert(current, new_leaf); break; } @@ -775,12 +782,12 @@ // extending the key. While it's impossible to encounter an extension node // followed by a leaf node in a complete trie, it's possible here because we // could have downgraded the extension node's child into a leaf node from // another node type. - SparseNode::Leaf { key: leaf_key, .. } => { + SparseNode::Leaf { key: leaf_key, is_private, .. } => { self.nodes.remove(&child.path);   let mut new_key = *key; new_key.extend(leaf_key); - SparseNode::new_leaf(new_key) + SparseNode::new_leaf(new_key, *is_private) } // For an extension node, we collapse them into one extension node, // extending the key @@ -857,12 +864,12 @@ } // If the only child is a leaf node, we downgrade the branch node into a // leaf node, prepending the nibble to the key, and delete the old // child. - SparseNode::Leaf { key, .. } => { + SparseNode::Leaf { key, is_private, .. } => { delete_child = true;   let mut new_key = Nibbles::from_nibbles_unchecked([child_nibble]); new_key.extend(key); - SparseNode::new_leaf(new_key) + SparseNode::new_leaf(new_key, *is_private) } // If the only child node is an extension node, we downgrade the branch // node into an even longer extension node, prepending the nibble to the @@ -1147,7 +1154,7 @@ Entry::Vacant(entry) => { entry.insert(SparseNode::Hash(hash)); } } - return Ok(()) + return Ok(()); }   self.reveal_node(path, TrieNode::decode(&mut &child[..])?, TrieMasks::none()) @@ -1195,7 +1202,7 @@ path: current, node, unset_branch_nibble: None, }); - break + break; } SparseNode::Extension { key, .. } => { #[cfg(debug_assertions)] @@ -1314,16 +1321,16 @@ while let Some((mut path, level)) = paths.pop() { match self.nodes.get(&path).unwrap() { SparseNode::Empty | SparseNode::Hash(_) => {} - SparseNode::Leaf { key: _, hash } => { + SparseNode::Leaf { key: _, hash, is_private: _ } => { if hash.is_some() && !prefix_set.contains(&path) { - continue + continue; }   targets.push((level, path)); } SparseNode::Extension { key, hash, store_in_db_trie: _ } => { if hash.is_some() && !prefix_set.contains(&path) { - continue + continue; }   if level >= depth { @@ -1337,7 +1344,7 @@ } } SparseNode::Branch { state_mask, hash, store_in_db_trie: _ } => { if hash.is_some() && !prefix_set.contains(&path) { - continue + continue; }   if level >= depth { @@ -1419,7 +1426,7 @@ let (rlp_node, node_type) = match node { SparseNode::Empty => (RlpNode::word_rlp(&EMPTY_ROOT_HASH), SparseNodeType::Empty), SparseNode::Hash(hash) => (RlpNode::word_rlp(hash), SparseNodeType::Hash), - SparseNode::Leaf { key, hash } => { + SparseNode::Leaf { key, hash, is_private } => { let mut path = path; path.extend(key); if let Some(hash) = hash.filter(|_| !prefix_set_contains(&path)) { @@ -1427,7 +1434,7 @@ (RlpNode::word_rlp(&hash), SparseNodeType::Leaf) } else { let value = self.values.get(&path).unwrap(); rlp_buf.clear(); - let rlp_node = LeafNodeRef { key, value }.rlp(rlp_buf); + let rlp_node = LeafNodeRef { key, value, is_private }.rlp(rlp_buf); *hash = rlp_node.as_hash(); (rlp_node, SparseNodeType::Leaf) } @@ -1482,7 +1489,7 @@ path: child_path, is_in_prefix_set: None, }, ]); - continue + continue; } } SparseNode::Branch { state_mask, hash, store_in_db_trie } => { @@ -1496,7 +1503,7 @@ node_type: SparseNodeType::Branch { store_in_db_trie: Some(store_in_db_trie), }, }); - continue + continue; } let retain_updates = self.updates.is_some() && prefix_set_contains(&path);   @@ -1588,7 +1595,7 @@ path, is_in_prefix_set: None, }, )); - continue 'main + continue 'main; } }   @@ -1739,6 +1746,8 @@ key: Nibbles, /// Pre-computed hash of the sparse node. /// Can be reused unless this trie path has been updated. hash: Option<B256>, + /// whether the leaf node is private + is_private: bool, }, /// Sparse extension node with key. Extension { @@ -1777,7 +1786,7 @@ /// Create new sparse node from [`TrieNode`]. pub fn from_node(node: TrieNode) -> Self { match node { TrieNode::EmptyRoot => Self::Empty, - TrieNode::Leaf(leaf) => Self::new_leaf(leaf.key), + TrieNode::Leaf(leaf) => Self::new_leaf(leaf.key, leaf.is_private), TrieNode::Extension(ext) => Self::new_ext(ext.key), TrieNode::Branch(branch) => Self::new_branch(branch.state_mask), } @@ -1803,8 +1812,17 @@ Self::Extension { key, hash: None, store_in_db_trie: None } }   /// Create new [`SparseNode::Leaf`] from leaf key and value. - pub const fn new_leaf(key: Nibbles) -> Self { - Self::Leaf { key, hash: None } + pub const fn new_leaf(key: Nibbles, is_private: bool) -> Self { + Self::Leaf { key, hash: None, is_private } + } + + /// returns if the node holds private state + /// node is always public unless it is a leaf + pub fn is_private(&self) -> bool { + match self { + Self::Leaf { is_private, .. } => *is_private, + _ => false, + } }   /// Returns `true` if the node is a hash node. @@ -1963,7 +1981,8 @@ let mut sparse = SerialSparseTrie::default(); let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]); let value = b"test_value".to_vec();   - sparse.update_leaf(path, value.clone(), &provider).unwrap(); + let is_private = false; // hardcode to false for legacy test + sparse.update_leaf(path, value.clone(), is_private, &provider).unwrap();   // Check that the leaf exists let result = sparse.find_leaf(&path, None); @@ -1983,7 +2002,8 @@ let path = Nibbles::from_nibbles([0x1, 0x2, 0x3]); let value = b"test_value".to_vec(); let wrong_value = b"wrong_value".to_vec();   - sparse.update_leaf(path, value, &provider).unwrap(); + let is_private = false; // hardcode to false for legacy test + sparse.update_leaf(path, value, is_private, &provider).unwrap();   // Check with wrong expected value let result = sparse.find_leaf(&path, Some(&wrong_value)); @@ -2018,7 +2038,8 @@ fn find_leaf_exists_no_value_check() { let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default(); let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); - sparse.update_leaf(path, VALUE_A(), &provider).unwrap(); + let is_private = false; // hardcode to false for legacy test + sparse.update_leaf(path, VALUE_A(), is_private, &provider).unwrap();   let result = sparse.find_leaf(&path, None); assert_matches!(result, Ok(LeafLookup::Exists)); @@ -2030,7 +2051,8 @@ let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default(); let path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let value = VALUE_A(); - sparse.update_leaf(path, value.clone(), &provider).unwrap(); + let is_private = false; // hardcode to false for legacy test + sparse.update_leaf(path, value.clone(), is_private, &provider).unwrap();   let result = sparse.find_leaf(&path, Some(&value)); assert_matches!(result, Ok(LeafLookup::Exists)); @@ -2044,8 +2066,9 @@ let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); // Creates branch at 0x12 let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]); // Belongs to same branch let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]); // Diverges at nibble 7   - sparse.update_leaf(path1, VALUE_A(), &provider).unwrap(); - sparse.update_leaf(path2, VALUE_B(), &provider).unwrap(); + let is_private = false; // hardcode to false for legacy test + sparse.update_leaf(path1, VALUE_A(), is_private, &provider).unwrap(); + sparse.update_leaf(path2, VALUE_B(), is_private, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)); @@ -2060,7 +2083,8 @@ let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]); // This path diverges from the extension key let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x7, 0x8]);   - sparse.update_leaf(path1, VALUE_A(), &provider).unwrap(); + let is_private = false; // hardcode to false for legacy test + sparse.update_leaf(path1, VALUE_A(), is_private, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)); @@ -2072,8 +2096,9 @@ let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default(); let existing_leaf_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4, 0x5, 0x6]); + let is_private = false; // hardcode to false for legacy test   - sparse.update_leaf(existing_leaf_path, VALUE_A(), &provider).unwrap(); + sparse.update_leaf(existing_leaf_path, VALUE_A(), is_private, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)); @@ -2086,9 +2111,10 @@ let mut sparse = SerialSparseTrie::default(); let path1 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); // Creates branch at 0x12 let path2 = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x5, 0x6]); let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2]); // Path of the branch itself + let is_private = false; // hardcode to false for legacy test   - sparse.update_leaf(path1, VALUE_A(), &provider).unwrap(); - sparse.update_leaf(path2, VALUE_B(), &provider).unwrap(); + sparse.update_leaf(path1, VALUE_A(), is_private, &provider).unwrap(); + sparse.update_leaf(path2, VALUE_B(), is_private, &provider).unwrap();   let result = sparse.find_leaf(&search_path, None); assert_matches!(result, Ok(LeafLookup::NonExistent)); @@ -2140,6 +2166,7 @@ fn find_leaf_error_trie_node() { let blinded_hash = B256::repeat_byte(0xAA); let path_to_blind = Nibbles::from_nibbles_unchecked([0x1]); let search_path = Nibbles::from_nibbles_unchecked([0x1, 0x2, 0x3, 0x4]); + let is_private = false; // legacy test does not use private storage   let mut nodes = HashMap::default();   @@ -2153,7 +2180,7 @@ let path_revealed = Nibbles::from_nibbles_unchecked([0x5]); let path_revealed_leaf = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]); nodes.insert( path_revealed, - SparseNode::new_leaf(Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8])), + SparseNode::new_leaf(Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8]), is_private), );   let mut values = HashMap::default(); @@ -2187,11 +2214,13 @@ let revealed_leaf_prefix = Nibbles::from_nibbles_unchecked([0x5]); let revealed_leaf_suffix = Nibbles::from_nibbles_unchecked([0x6, 0x7, 0x8]); let revealed_leaf_full_path = Nibbles::from_nibbles_unchecked([0x5, 0x6, 0x7, 0x8]); let revealed_value = VALUE_A(); + let is_private = false; // legacy test does not use private storage   // 1. Construct the RLP representation of the children for the root branch let rlp_node_child1 = RlpNode::word_rlp(&blinded_hash); // Blinded node   - let leaf_node_child5 = LeafNode::new(revealed_leaf_suffix, revealed_value.clone()); + let leaf_node_child5 = + LeafNode::new(revealed_leaf_suffix, revealed_value.clone(), is_private); let leaf_node_child5_rlp_buf = alloy_rlp::encode(&leaf_node_child5); let hash_of_child5 = keccak256(&leaf_node_child5_rlp_buf); let rlp_node_child5 = RlpNode::word_rlp(&hash_of_child5); @@ -2292,6 +2321,7 @@ destroyed_accounts: B256Set, proof_targets: impl IntoIterator<Item = Nibbles>, ) -> (B256, TrieUpdates, ProofNodes, HashMap<Nibbles, TrieMask>, HashMap<Nibbles, TrieMask>) { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent let mut account_rlp = Vec::new();   let mut hash_builder = HashBuilder::default() @@ -2325,7 +2355,7 @@ TrieElement::Leaf(key, account) => { let account = account.into_trie_account(EMPTY_ROOT_HASH); account.encode(&mut account_rlp);   - hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp); + hash_builder.add_leaf(Nibbles::unpack(key), &account_rlp, is_private); account_rlp.clear(); } } @@ -2380,12 +2410,14 @@ // Both nodes are extensions and have the same key ( TrieNode::Extension(ExtensionNode { key: proof_key, .. }), SparseNode::Extension { key: sparse_key, .. }, - ) | + ) => proof_key == sparse_key, // Both nodes are leaves and have the same key ( - TrieNode::Leaf(LeafNode { key: proof_key, .. }), - SparseNode::Leaf { key: sparse_key, .. }, - ) => proof_key == sparse_key, + TrieNode::Leaf(LeafNode { + key: proof_key, is_private: proof_is_private, .. + }), + SparseNode::Leaf { key: sparse_key, is_private: sparse_is_private, .. }, + ) => proof_key == sparse_key && proof_is_private == sparse_is_private, // Empty and hash nodes are specific to the sparse trie, skip them (_, SparseNode::Empty | SparseNode::Hash(_)) => continue, _ => false, @@ -2405,6 +2437,7 @@ }   #[test] fn sparse_trie_empty_update_one() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent let key = Nibbles::unpack(B256::with_last_byte(42)); let value = || Account::default(); let value_encoded = || { @@ -2423,7 +2456,7 @@ );   let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default().with_updates(true); - sparse.update_leaf(key, value_encoded(), &provider).unwrap(); + sparse.update_leaf(key, value_encoded(), is_private, &provider).unwrap(); let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates();   @@ -2434,6 +2467,7 @@ }   #[test] fn sparse_trie_empty_update_multiple_lower_nibbles() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent reth_tracing::init_test_tracing();   let paths = (0..=16).map(|b| Nibbles::unpack(B256::with_last_byte(b))).collect::<Vec<_>>(); @@ -2455,7 +2489,7 @@ let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default().with_updates(true); for path in &paths { - sparse.update_leaf(*path, value_encoded(), &provider).unwrap(); + sparse.update_leaf(*path, value_encoded(), is_private, &provider).unwrap(); } let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); @@ -2467,6 +2501,7 @@ }   #[test] fn sparse_trie_empty_update_multiple_upper_nibbles() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent let paths = (239..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>(); let value = || Account::default(); let value_encoded = || { @@ -2486,7 +2521,7 @@ let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default().with_updates(true); for path in &paths { - sparse.update_leaf(*path, value_encoded(), &provider).unwrap(); + sparse.update_leaf(*path, value_encoded(), is_private, &provider).unwrap(); } let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); @@ -2498,6 +2533,7 @@ }   #[test] fn sparse_trie_empty_update_multiple() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent let paths = (0..=255) .map(|b| { Nibbles::unpack(if b % 2 == 0 { @@ -2525,7 +2561,7 @@ let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default().with_updates(true); for path in &paths { - sparse.update_leaf(*path, value_encoded(), &provider).unwrap(); + sparse.update_leaf(*path, value_encoded(), is_private, &provider).unwrap(); } let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); @@ -2540,6 +2576,7 @@ }   #[test] fn sparse_trie_empty_update_repeated() { + let is_private = false; // legacy test does not use private storage let paths = (0..=255).map(|b| Nibbles::unpack(B256::repeat_byte(b))).collect::<Vec<_>>(); let old_value = Account { nonce: 1, ..Default::default() }; let old_value_encoded = { @@ -2565,7 +2602,7 @@ let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default().with_updates(true); for path in &paths { - sparse.update_leaf(*path, old_value_encoded.clone(), &provider).unwrap(); + sparse.update_leaf(*path, old_value_encoded.clone(), is_private, &provider).unwrap(); } let sparse_root = sparse.root(); let sparse_updates = sparse.updates_ref(); @@ -2583,7 +2620,7 @@ paths.clone(), );   for path in &paths { - sparse.update_leaf(*path, new_value_encoded.clone(), &provider).unwrap(); + sparse.update_leaf(*path, new_value_encoded.clone(), is_private, &provider).unwrap(); } let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates(); @@ -2595,6 +2632,8 @@ }   #[test] fn sparse_trie_remove_leaf() { + let is_private = false; // hardcoded to false all nodes except first + reth_tracing::init_test_tracing();   let provider = DefaultTrieNodeProvider; @@ -2603,22 +2642,52 @@ let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec();   sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), + value.clone(), + true, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), + value, + is_private, + &provider, + ) .unwrap();   // Extension (Key = 5) @@ -2648,29 +2717,29 @@ SparseNode::new_branch(0b1010.into()) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), true) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), is_private) ), ( Nibbles::from_nibbles([0x5, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x1, 0x3]), is_private), ), (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]), is_private) ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), is_private) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), is_private) ) ]) ); @@ -2703,25 +2772,25 @@ SparseNode::new_branch(0b1010.into()) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), true) ), ( Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), - SparseNode::new_leaf(Nibbles::default()) + SparseNode::new_leaf(Nibbles::default(), is_private) ), (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]), is_private) ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), is_private) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), is_private) ) ]) ); @@ -2743,21 +2812,21 @@ (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))), (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())), ( Nibbles::from_nibbles([0x5, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]), is_private) ), (Nibbles::from_nibbles([0x5, 0x3]), SparseNode::new_branch(0b1010.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x1]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0, 0x2]), is_private) ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), is_private) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), is_private) ) ]) ); @@ -2777,7 +2846,7 @@ (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))), (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())), ( Nibbles::from_nibbles([0x5, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]), is_private) ), ( Nibbles::from_nibbles([0x5, 0x3]), @@ -2786,11 +2855,11 @@ ), (Nibbles::from_nibbles([0x5, 0x3, 0x3]), SparseNode::new_branch(0b0101.into())), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2]), is_private) ), ( Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x0])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x0]), is_private) ) ]) ); @@ -2808,11 +2877,11 @@ (Nibbles::default(), SparseNode::new_ext(Nibbles::from_nibbles([0x5]))), (Nibbles::from_nibbles([0x5]), SparseNode::new_branch(0b1001.into())), ( Nibbles::from_nibbles([0x5, 0x0]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x2, 0x3, 0x3]), is_private) ), ( Nibbles::from_nibbles([0x5, 0x3]), - SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x3, 0x0, 0x2]), is_private) ), ]) ); @@ -2824,7 +2893,7 @@ pretty_assertions::assert_eq!( sparse.nodes.clone().into_iter().collect::<BTreeMap<_, _>>(), BTreeMap::from_iter([( Nibbles::default(), - SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2])) + SparseNode::new_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), is_private) ),]) );   @@ -2839,9 +2908,14 @@ }   #[test] fn sparse_trie_remove_leaf_blinded() { + // legacy test does not use private storage + // not relevant to removing a blinded leaf + let is_private = false; + let leaf = LeafNode::new( Nibbles::default(), alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(), + is_private, ); let branch = TrieNode::Branch(BranchNode::new( vec![ @@ -2884,9 +2958,14 @@ }   #[test] fn sparse_trie_remove_leaf_non_existent() { + // legacy test does not use private storage + // not relevant to removing a non-existent leaf + let is_private = false; + let leaf = LeafNode::new( Nibbles::default(), alloy_rlp::encode_fixed_size(&U256::from(1)).to_vec(), + is_private, ); let branch = TrieNode::Branch(BranchNode::new( vec![ @@ -2939,6 +3018,7 @@ let mut state = BTreeMap::default(); let default_provider = DefaultTrieNodeProvider; let provider_factory = create_test_provider_factory(); let mut sparse = SerialSparseTrie::default().with_updates(true); + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent   for (update, keys_to_delete) in updates { // Insert state updates into the sparse trie and calculate the root @@ -2946,7 +3026,9 @@ for (key, account) in update.clone() { let account = account.into_trie_account(EMPTY_ROOT_HASH); let mut account_rlp = Vec::new(); account.encode(&mut account_rlp); - sparse.update_leaf(key, account_rlp, &default_provider).unwrap(); + sparse + .update_leaf(key, account_rlp, is_private, &default_provider) + .unwrap(); } // We need to clone the sparse trie, so that all updated branch nodes are // preserved, and not only those that were changed after the last call to @@ -3078,6 +3160,8 @@ /// nibble of the branch node, so we need to adjust the branch node instead of fully /// replacing it. #[test] fn sparse_trie_reveal_node_1() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent + let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00])); let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01])); let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x02])); @@ -3135,7 +3219,7 @@ Some(&SparseNode::new_branch(0b101.into())) );   // Insert the leaf for the second key - sparse.update_leaf(key2(), value_encoded(), &provider).unwrap(); + sparse.update_leaf(key2(), value_encoded(), is_private, &provider).unwrap();   // Check that the branch node was updated and another nibble was set assert_eq!( @@ -3291,6 +3375,7 @@ /// 2. Reveal the leaf 0x0001 in the sparse trie, and check that the root branch node wasn't /// overwritten with the extension node from the proof. #[test] fn sparse_trie_reveal_node_3() { + let is_private = false; // hardcode to false for legacy test, TODO: make a private equivalent let key1 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x01])); let key2 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x00, 0x02])); let key3 = || pad_nibbles_right(Nibbles::from_nibbles_unchecked([0x01, 0x00])); @@ -3328,7 +3413,7 @@ Some(SparseNode::Extension { key, hash: None, store_in_db_trie: None }) if *key == Nibbles::from_nibbles([0x00]) );   // Insert the leaf with a different prefix - sparse.update_leaf(key3(), value_encoded(), &provider).unwrap(); + sparse.update_leaf(key3(), value_encoded(), is_private, &provider).unwrap();   // Check that the extension node was turned into a branch node assert_matches!( @@ -3365,6 +3450,7 @@ }   #[test] fn sparse_trie_get_changed_nodes_at_depth() { + let is_private = false; // hardcoded to false all nodes except first let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default();   @@ -3383,22 +3469,52 @@ // └── 3 -> Branch (Mask = 1010) – Level 3 // ├── 0 -> Leaf (Key = 3302, Path = 53302) – Level 4 // └── 2 -> Leaf (Key = 3320, Path = 53320) – Level 4 sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), + value, + is_private, + &provider, + ) .unwrap();   assert_eq!( @@ -3464,6 +3580,7 @@ }   #[test] fn hash_builder_branch_hash_mask() { + let is_private = false; // legacy test does not use private storage let key1 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x00])); let key2 = || pad_nibbles_left(Nibbles::from_nibbles_unchecked([0x01])); let value = || Account { bytecode_hash: Some(B256::repeat_byte(1)), ..Default::default() }; @@ -3482,8 +3599,8 @@ );   let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default(); - sparse.update_leaf(key1(), value_encoded(), &provider).unwrap(); - sparse.update_leaf(key2(), value_encoded(), &provider).unwrap(); + sparse.update_leaf(key1(), value_encoded(), is_private, &provider).unwrap(); + sparse.update_leaf(key2(), value_encoded(), is_private, &provider).unwrap(); let sparse_root = sparse.root(); let sparse_updates = sparse.take_updates();   @@ -3493,6 +3610,7 @@ }   #[test] fn sparse_trie_wipe() { + let is_private = false; // hardcoded to false all nodes except first let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default().with_updates(true);   @@ -3511,22 +3629,52 @@ // └── 3 -> Branch (Mask = 1010) – Level 3 // ├── 0 -> Leaf (Key = 3302, Path = 53302) – Level 4 // └── 2 -> Leaf (Key = 3320, Path = 53320) – Level 4 sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), + value, + is_private, + &provider, + ) .unwrap();   sparse.wipe(); @@ -3541,22 +3689,44 @@ }   #[test] fn sparse_trie_clear() { + let is_private = false; // hardcoded to false for legacy test + // tests that if we fill a sparse trie with some nodes and then clear it, it has the same // contents as an empty sparse trie let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default(); let value = alloy_rlp::encode_fixed_size(&U256::ZERO).to_vec(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value, &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), + value, + is_private, + &provider, + ) .unwrap();   sparse.clear(); @@ -3567,6 +3737,8 @@ }   #[test] fn sparse_trie_display() { + let is_private = false; // hardcoded to false all nodes except first + let provider = DefaultTrieNodeProvider; let mut sparse = SerialSparseTrie::default();   @@ -3585,22 +3757,52 @@ // └── 3 -> Branch (Mask = 1010) – Level 3 // ├── 0 -> Leaf (Key = 3302, Path = 53302) – Level 4 // └── 2 -> Leaf (Key = 3320, Path = 53320) – Level 4 sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x1]), + value.clone(), + true, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x0, 0x2, 0x3, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x2, 0x0, 0x1, 0x3]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x1, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), value.clone(), &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x0, 0x2]), + value.clone(), + is_private, + &provider, + ) .unwrap(); sparse - .update_leaf(Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), value, &provider) + .update_leaf( + Nibbles::from_nibbles([0x5, 0x3, 0x3, 0x2, 0x0]), + value, + is_private, + &provider, + ) .unwrap();   let normal_printed = format!("{sparse}"); @@ -3609,14 +3811,14 @@ Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None } 5 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None } 50 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None } 5023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None } -50231 -> Leaf { key: Nibbles(0x), hash: None } -50233 -> Leaf { key: Nibbles(0x), hash: None } -52013 -> Leaf { key: Nibbles(0x013), hash: None } +50231 -> Leaf { key: Nibbles(0x), hash: None, is_private: true } +50233 -> Leaf { key: Nibbles(0x), hash: None, is_private: false } +52013 -> Leaf { key: Nibbles(0x013), hash: None, is_private: false } 53 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None } -53102 -> Leaf { key: Nibbles(0x02), hash: None } +53102 -> Leaf { key: Nibbles(0x02), hash: None, is_private: false } 533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None } -53302 -> Leaf { key: Nibbles(0x2), hash: None } -53320 -> Leaf { key: Nibbles(0x0), hash: None } +53302 -> Leaf { key: Nibbles(0x2), hash: None, is_private: false } +53320 -> Leaf { key: Nibbles(0x0), hash: None, is_private: false } "; assert_eq!(normal_printed, expected);   @@ -3626,14 +3828,14 @@ Root -> Extension { key: Nibbles(0x5), hash: None, store_in_db_trie: None } 5 -> Branch { state_mask: TrieMask(0000000000001101), hash: None, store_in_db_trie: None } 50 -> Extension { key: Nibbles(0x23), hash: None, store_in_db_trie: None } 5023 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None } - 50231 -> Leaf { key: Nibbles(0x), hash: None } - 50233 -> Leaf { key: Nibbles(0x), hash: None } - 52013 -> Leaf { key: Nibbles(0x013), hash: None } + 50231 -> Leaf { key: Nibbles(0x), hash: None, is_private: true } + 50233 -> Leaf { key: Nibbles(0x), hash: None, is_private: false } + 52013 -> Leaf { key: Nibbles(0x013), hash: None, is_private: false } 53 -> Branch { state_mask: TrieMask(0000000000001010), hash: None, store_in_db_trie: None } - 53102 -> Leaf { key: Nibbles(0x02), hash: None } + 53102 -> Leaf { key: Nibbles(0x02), hash: None, is_private: false } 533 -> Branch { state_mask: TrieMask(0000000000000101), hash: None, store_in_db_trie: None } - 53302 -> Leaf { key: Nibbles(0x2), hash: None } - 53320 -> Leaf { key: Nibbles(0x0), hash: None } + 53302 -> Leaf { key: Nibbles(0x2), hash: None, is_private: false } + 53320 -> Leaf { key: Nibbles(0x0), hash: None, is_private: false } ";   assert_eq!(alternate_printed, expected);
diff --git reth/crates/trie/trie/Cargo.toml seismic-reth/crates/trie/trie/Cargo.toml index 403d187e46a9571cc95e2ab854637b5ecca2f7dc..5eb5810ce311a43070e7488dc2176e48c5d19401 100644 --- reth/crates/trie/trie/Cargo.toml +++ seismic-reth/crates/trie/trie/Cargo.toml @@ -21,6 +21,7 @@ reth-trie-sparse.workspace = true reth-trie-common = { workspace = true, features = ["rayon"] }   revm-database.workspace = true +revm-state.workspace = true   # alloy alloy-eips.workspace = true
diff --git reth/crates/trie/trie/benches/hash_post_state.rs seismic-reth/crates/trie/trie/benches/hash_post_state.rs index 15b567b7c83f87119b0878393db0b10746966cbb..819ba44f1198a60a3ceb555e6baa2dc285d21bde 100644 --- reth/crates/trie/trie/benches/hash_post_state.rs +++ seismic-reth/crates/trie/trie/benches/hash_post_state.rs @@ -4,6 +4,7 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use proptest::{prelude::*, strategy::ValueTree, test_runner::TestRunner}; use reth_trie::{HashedPostState, HashedStorage, KeccakKeyHasher}; use revm_database::{states::BundleBuilder, BundleAccount}; +use revm_state::FlaggedStorage;   pub fn hash_post_state(c: &mut Criterion) { let mut group = c.benchmark_group("Hash Post State"); @@ -59,8 +60,8 @@ any::<Address>(), hash_map( any::<U256>(), // slot ( - any::<U256>(), // old value - any::<U256>(), // new value + any::<FlaggedStorage>(), // old value + any::<FlaggedStorage>(), // new value ), storage_size, ),
diff --git reth/crates/trie/trie/benches/trie_root.rs seismic-reth/crates/trie/trie/benches/trie_root.rs index 625f66fd4432aa29646834408fb698522d694617..243f17d45f1ebe09191130aceb50f2fe1faafe0c 100644 --- reth/crates/trie/trie/benches/trie_root.rs +++ seismic-reth/crates/trie/trie/benches/trie_root.rs @@ -71,7 +71,8 @@ value_buffer.clear(); receipts[index].encode_2718(&mut value_buffer);   - hb.add_leaf(Nibbles::unpack(&index_buffer), &value_buffer); + let is_private = false; // hardcode to false for legacy bench + hb.add_leaf(Nibbles::unpack(&index_buffer), &value_buffer, is_private); }   hb.root()
diff --git reth/crates/trie/trie/src/hashed_cursor/mock.rs seismic-reth/crates/trie/trie/src/hashed_cursor/mock.rs index 895bf852a223cede53061dfad9dd57a210ac3c2f..01d80ca8c11153347efcafae1c3a55080d039e11 100644 --- reth/crates/trie/trie/src/hashed_cursor/mock.rs +++ seismic-reth/crates/trie/trie/src/hashed_cursor/mock.rs @@ -3,17 +3,18 @@ use crate::mock::{KeyVisit, KeyVisitType};   use super::{HashedCursor, HashedCursorFactory, HashedStorageCursor}; -use alloy_primitives::{map::B256Map, B256, U256}; +use alloy_primitives::{map::B256Map, B256}; use parking_lot::{Mutex, MutexGuard}; use reth_primitives_traits::Account; use reth_storage_errors::db::DatabaseError; +use revm_state::FlaggedStorage; use tracing::instrument;   /// Mock hashed cursor factory. #[derive(Clone, Default, Debug)] pub struct MockHashedCursorFactory { hashed_accounts: Arc<BTreeMap<B256, Account>>, - hashed_storage_tries: B256Map<Arc<BTreeMap<B256, U256>>>, + hashed_storage_tries: B256Map<Arc<BTreeMap<B256, FlaggedStorage>>>,   /// List of keys that the hashed accounts cursor has visited. visited_account_keys: Arc<Mutex<Vec<KeyVisit<B256>>>>, @@ -25,7 +26,7 @@ impl MockHashedCursorFactory { /// Creates a new mock hashed cursor factory. pub fn new( hashed_accounts: BTreeMap<B256, Account>, - hashed_storage_tries: B256Map<BTreeMap<B256, U256>>, + hashed_storage_tries: B256Map<BTreeMap<B256, FlaggedStorage>>, ) -> Self { let visited_storage_keys = hashed_storage_tries.keys().map(|k| (*k, Default::default())).collect(); @@ -56,7 +57,7 @@ }   impl HashedCursorFactory for MockHashedCursorFactory { type AccountCursor = MockHashedCursor<Account>; - type StorageCursor = MockHashedCursor<U256>; + type StorageCursor = MockHashedCursor<FlaggedStorage>;   fn hashed_account_cursor(&self) -> Result<Self::AccountCursor, DatabaseError> { Ok(MockHashedCursor::new(self.hashed_accounts.clone(), self.visited_account_keys.clone()))
diff --git reth/crates/trie/trie/src/hashed_cursor/mod.rs seismic-reth/crates/trie/trie/src/hashed_cursor/mod.rs index bc4bbd88c5610ea0cfd09682f7adfd56358da578..2b2e215ab08c529d545e21a97649df751fc3ad01 100644 --- reth/crates/trie/trie/src/hashed_cursor/mod.rs +++ seismic-reth/crates/trie/trie/src/hashed_cursor/mod.rs @@ -1,6 +1,7 @@ -use alloy_primitives::{B256, U256}; +use alloy_primitives::B256; use reth_primitives_traits::Account; use reth_storage_errors::db::DatabaseError; +use revm_state::FlaggedStorage;   /// Implementation of hashed state cursor traits for the post state. mod post_state; @@ -18,7 +19,7 @@ pub trait HashedCursorFactory { /// The hashed account cursor type. type AccountCursor: HashedCursor<Value = Account>; /// The hashed storage cursor type. - type StorageCursor: HashedStorageCursor<Value = U256>; + type StorageCursor: HashedStorageCursor<Value = FlaggedStorage>;   /// Returns a cursor for iterating over all hashed accounts in the state. fn hashed_account_cursor(&self) -> Result<Self::AccountCursor, DatabaseError>;
diff --git reth/crates/trie/trie/src/hashed_cursor/noop.rs seismic-reth/crates/trie/trie/src/hashed_cursor/noop.rs index 58b78dc245f142fea22755a8592b4a8859955ad2..448ed2baf81a20640e4dee364833069718df6a81 100644 --- reth/crates/trie/trie/src/hashed_cursor/noop.rs +++ seismic-reth/crates/trie/trie/src/hashed_cursor/noop.rs @@ -1,7 +1,8 @@ use super::{HashedCursor, HashedCursorFactory, HashedStorageCursor}; -use alloy_primitives::{B256, U256}; +use alloy_primitives::B256; use reth_primitives_traits::Account; use reth_storage_errors::db::DatabaseError; +use revm_state::FlaggedStorage;   /// Noop hashed cursor factory. #[derive(Clone, Default, Debug)] @@ -47,7 +48,7 @@ #[non_exhaustive] pub struct NoopHashedStorageCursor;   impl HashedCursor for NoopHashedStorageCursor { - type Value = U256; + type Value = FlaggedStorage;   fn seek(&mut self, _key: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> { Ok(None)
diff --git reth/crates/trie/trie/src/hashed_cursor/post_state.rs seismic-reth/crates/trie/trie/src/hashed_cursor/post_state.rs index b6c8994e137725b508df4e21781bedd147b18f82..6f6eb15abc209c1e89b1f293f0d6bcf7b77c7b5b 100644 --- reth/crates/trie/trie/src/hashed_cursor/post_state.rs +++ seismic-reth/crates/trie/trie/src/hashed_cursor/post_state.rs @@ -1,9 +1,10 @@ use super::{HashedCursor, HashedCursorFactory, HashedStorageCursor}; use crate::forward_cursor::ForwardInMemoryCursor; -use alloy_primitives::{map::B256Set, B256, U256}; +use alloy_primitives::{map::B256Set, B256}; use reth_primitives_traits::Account; use reth_storage_errors::db::DatabaseError; use reth_trie_common::{HashedAccountsSorted, HashedPostStateSorted, HashedStorageSorted}; +use revm_state::FlaggedStorage;   /// The hashed cursor factory for the post state. #[derive(Clone, Debug)] @@ -80,7 +81,7 @@ // It's an exact match, return the account from post state without looking up in the // database. if post_state_entry.is_some_and(|entry| entry.0 == key) { - return Ok(post_state_entry) + return Ok(post_state_entry); }   // It's not an exact match, reposition to the first greater or equal account that wasn't @@ -178,7 +179,7 @@ pub struct HashedPostStateStorageCursor<'a, C> { /// The database cursor. cursor: C, /// Forward-only in-memory cursor over non zero-valued account storage slots. - post_state_cursor: Option<ForwardInMemoryCursor<'a, B256, U256>>, + post_state_cursor: Option<ForwardInMemoryCursor<'a, B256, FlaggedStorage>>, /// Reference to the collection of storage slot keys that were cleared. cleared_slots: Option<&'a B256Set>, /// Flag indicating whether database storage was wiped. @@ -190,7 +191,7 @@ }   impl<'a, C> HashedPostStateStorageCursor<'a, C> where - C: HashedStorageCursor<Value = U256>, + C: HashedStorageCursor<Value = FlaggedStorage>, { /// Create new instance of [`HashedPostStateStorageCursor`] for the given hashed address. pub fn new(cursor: C, post_state_storage: Option<&'a HashedStorageSorted>) -> Self { @@ -208,14 +209,17 @@ self.cleared_slots.is_some_and(|s| s.contains(slot)) }   /// Find the storage entry in post state or database that's greater or equal to provided subkey. - fn seek_inner(&mut self, subkey: B256) -> Result<Option<(B256, U256)>, DatabaseError> { + fn seek_inner( + &mut self, + subkey: B256, + ) -> Result<Option<(B256, FlaggedStorage)>, DatabaseError> { // Attempt to find the account's storage in post state. let post_state_entry = self.post_state_cursor.as_mut().and_then(|c| c.seek(&subkey));   // If database storage was wiped or it's an exact match, // return the storage slot from post state without looking up in the database. if self.storage_wiped || post_state_entry.is_some_and(|entry| entry.0 == subkey) { - return Ok(post_state_entry) + return Ok(post_state_entry); }   // It's not an exact match and storage was not wiped, @@ -230,14 +234,17 @@ Ok(Self::compare_entries(post_state_entry, db_entry)) }   /// Find the storage entry that is right after current cursor position. - fn next_inner(&mut self, last_slot: B256) -> Result<Option<(B256, U256)>, DatabaseError> { + fn next_inner( + &mut self, + last_slot: B256, + ) -> Result<Option<(B256, FlaggedStorage)>, DatabaseError> { // Attempt to find the account's storage in post state. let post_state_entry = self.post_state_cursor.as_mut().and_then(|c| c.first_after(&last_slot));   // Return post state entry immediately if database was wiped. if self.storage_wiped { - return Ok(post_state_entry) + return Ok(post_state_entry); }   // If post state was given precedence, move the cursor forward. @@ -259,9 +266,9 @@ /// /// Given the next post state and database entries, return the smallest of the two. /// If the storage keys are the same, the post state entry is given precedence. fn compare_entries( - post_state_item: Option<(B256, U256)>, - db_item: Option<(B256, U256)>, - ) -> Option<(B256, U256)> { + post_state_item: Option<(B256, FlaggedStorage)>, + db_item: Option<(B256, FlaggedStorage)>, + ) -> Option<(B256, FlaggedStorage)> { if let Some((post_state_entry, db_entry)) = post_state_item.zip(db_item) { // If both are not empty, return the smallest of the two // Post state is given precedence if keys are equal @@ -275,9 +282,9 @@ }   impl<C> HashedCursor for HashedPostStateStorageCursor<'_, C> where - C: HashedStorageCursor<Value = U256>, + C: HashedStorageCursor<Value = FlaggedStorage>, { - type Value = U256; + type Value = FlaggedStorage;   /// Seek the next account storage entry for a given hashed key pair. fn seek(&mut self, subkey: B256) -> Result<Option<(B256, Self::Value)>, DatabaseError> { @@ -303,7 +310,7 @@ }   impl<C> HashedStorageCursor for HashedPostStateStorageCursor<'_, C> where - C: HashedStorageCursor<Value = U256>, + C: HashedStorageCursor<Value = FlaggedStorage>, { /// Returns `true` if the account has no storage entries. ///
diff --git reth/crates/trie/trie/src/lib.rs seismic-reth/crates/trie/trie/src/lib.rs index 7efa00631d20e32983236e714716ecd04dc1bc11..ea15d1d1bd5aea11dca4bafdd938932959b53c99 100644 --- reth/crates/trie/trie/src/lib.rs +++ seismic-reth/crates/trie/trie/src/lib.rs @@ -10,7 +10,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/trie/trie/src/node_iter.rs seismic-reth/crates/trie/trie/src/node_iter.rs index c2ae162ccd0be59aeac8120fda7fe22bf6c89acf..41fa380fac251f30852a07ca07065b0a6f449040 100644 --- reth/crates/trie/trie/src/node_iter.rs +++ seismic-reth/crates/trie/trie/src/node_iter.rs @@ -217,7 +217,7 @@ return Ok(Some(TrieElement::Branch(TrieBranchNode::new( *key, self.walker.hash().unwrap(), self.walker.children_are_in_trie(), - )))) + )))); } } } @@ -368,6 +368,7 @@ TrieElement::Leaf(key, account) => { hash_builder.add_leaf( Nibbles::unpack(key), &alloy_rlp::encode(account.into_trie_account(EMPTY_ROOT_HASH)), + false, // account nodes are always public ); } } @@ -386,6 +387,7 @@ fn empty_leaf_rlp_for_key(key: Nibbles) -> RlpNode { RlpNode::from_rlp(&alloy_rlp::encode(LeafNode::new( key, alloy_rlp::encode(TrieAccount::default()), + false, // account nodes are always public ))) }
diff --git reth/crates/trie/trie/src/proof/mod.rs seismic-reth/crates/trie/trie/src/proof/mod.rs index dc18a24988d1154f9d7ec2ffd2ab18f0838f2700..867db6502a5f850f895032d0f3435469639cd6b9 100644 --- reth/crates/trie/trie/src/proof/mod.rs +++ seismic-reth/crates/trie/trie/src/proof/mod.rs @@ -153,7 +153,12 @@ account_rlp.clear(); let account = account.into_trie_account(storage_multiproof.root); account.encode(&mut account_rlp as &mut dyn BufMut);   - hash_builder.add_leaf(Nibbles::unpack(hashed_address), &account_rlp); + let is_private = false; // account leaves are always public. Their storage leaves can be private. + hash_builder.add_leaf( + Nibbles::unpack(hashed_address), + &account_rlp, + is_private, + );   // We might be adding leaves that are not necessarily our proof targets. if leaf_is_proof_target { @@ -303,7 +308,7 @@ self.hashed_cursor_factory.hashed_storage_cursor(self.hashed_address)?;   // short circuit on empty storage if hashed_storage_cursor.is_storage_empty()? { - return Ok(StorageMultiProof::empty()) + return Ok(StorageMultiProof::empty()); }   let target_nibbles = targets.into_iter().map(Nibbles::unpack).collect::<Vec<_>>(); @@ -328,6 +333,7 @@ TrieElement::Leaf(hashed_slot, value) => { hash_builder.add_leaf( Nibbles::unpack(hashed_slot), alloy_rlp::encode_fixed_size(&value).as_ref(), + value.is_private, ); } }
diff --git reth/crates/trie/trie/src/test_utils.rs seismic-reth/crates/trie/trie/src/test_utils.rs index ebd976b182cab2108b953b48283743ea2853f5af..22eaa0872dcca87bd605b2e1831da8a239ebfbf5 100644 --- reth/crates/trie/trie/src/test_utils.rs +++ seismic-reth/crates/trie/trie/src/test_utils.rs @@ -1,4 +1,5 @@ -use alloy_primitives::{Address, B256, U256}; +use crate::{HashBuilder, Nibbles}; +use alloy_primitives::{Address, B256}; use alloy_rlp::encode_fixed_size; use reth_primitives_traits::Account; use reth_trie_common::triehash::KeccakHasher; @@ -10,7 +11,7 @@ /// Compute the state root of a given set of accounts using [`triehash::sec_trie_root`]. pub fn state_root<I, S>(accounts: I) -> B256 where I: IntoIterator<Item = (Address, (Account, S))>, - S: IntoIterator<Item = (B256, U256)>, + S: IntoIterator<Item = (B256, alloy_primitives::FlaggedStorage)>, { let encoded_accounts = accounts.into_iter().map(|(address, (account, storage))| { let storage_root = storage_root(storage); @@ -21,7 +22,9 @@ triehash::sec_trie_root::<KeccakHasher, _, _, _>(encoded_accounts) }   /// Compute the storage root for a given account using [`triehash::sec_trie_root`]. -pub fn storage_root<I: IntoIterator<Item = (B256, U256)>>(storage: I) -> B256 { +pub fn storage_root<I: IntoIterator<Item = (B256, alloy_primitives::FlaggedStorage)>>( + storage: I, +) -> B256 { let encoded_storage = storage.into_iter().map(|(k, v)| (k, encode_fixed_size(&v))); triehash::sec_trie_root::<KeccakHasher, _, _, _>(encoded_storage) } @@ -31,7 +34,7 @@ /// [`triehash::trie_root`]. pub fn state_root_prehashed<I, S>(accounts: I) -> B256 where I: IntoIterator<Item = (B256, (Account, S))>, - S: IntoIterator<Item = (B256, U256)>, + S: IntoIterator<Item = (B256, alloy_primitives::FlaggedStorage)>, { let encoded_accounts = accounts.into_iter().map(|(address, (account, storage))| { let storage_root = storage_root_prehashed(storage); @@ -43,7 +46,88 @@ triehash::trie_root::<KeccakHasher, _, _, _>(encoded_accounts) }   /// Compute the storage root for a given account with prehashed slots using [`triehash::trie_root`]. -pub fn storage_root_prehashed<I: IntoIterator<Item = (B256, U256)>>(storage: I) -> B256 { +pub fn storage_root_prehashed<I: IntoIterator<Item = (B256, alloy_primitives::FlaggedStorage)>>( + storage: I, +) -> B256 { let encoded_storage = storage.into_iter().map(|(k, v)| (k, encode_fixed_size(&v))); triehash::trie_root::<KeccakHasher, _, _, _>(encoded_storage) } + +/// Compute the state root of a given set of accounts using privacy-aware HashBuilder. +/// This function respects the privacy flags in FlaggedStorage values and hashes the keys. +pub fn state_root_privacy_aware<I, S>(accounts: I) -> B256 +where + I: IntoIterator<Item = (Address, (Account, S))>, + S: IntoIterator<Item = (B256, alloy_primitives::FlaggedStorage)>, +{ + let mut hash_builder = HashBuilder::default(); + + // Collect and sort account entries by hashed address for consistent ordering + let mut account_entries: Vec<_> = accounts + .into_iter() + .map(|(address, (account, storage))| { + let storage_root = storage_root_privacy_aware(storage); + let account = account.into_trie_account(storage_root); + (alloy_primitives::keccak256(address), account) + }) + .collect(); + account_entries.sort_by(|a, b| a.0.cmp(&b.0)); + + // Add each account entry to the hash builder + // Note: Account privacy is determined by whether it has private storage + for (hashed_address, account) in account_entries { + let nibbles = Nibbles::unpack(hashed_address); + let encoded_account = alloy_rlp::encode(account); + hash_builder.add_leaf(nibbles, &encoded_account, false); + } + + hash_builder.root() +} + +/// Compute the storage root for a given account using privacy-aware HashBuilder. +/// This function respects the privacy flags in FlaggedStorage values and hashes the keys. +pub fn storage_root_privacy_aware< + I: IntoIterator<Item = (B256, alloy_primitives::FlaggedStorage)>, +>( + storage: I, +) -> B256 { + let mut hash_builder = HashBuilder::default(); + + // Collect and sort storage entries by hashed key for consistent ordering + let mut storage_entries: Vec<_> = + storage.into_iter().map(|(k, v)| (alloy_primitives::keccak256(k), v)).collect(); + storage_entries.sort_by(|a, b| a.0.cmp(&b.0)); + + // Add each storage entry to the hash builder with privacy awareness + for (hashed_key, flagged_storage) in storage_entries { + let nibbles = Nibbles::unpack(hashed_key); + let encoded_value = encode_fixed_size(&flagged_storage); + hash_builder.add_leaf(nibbles, &encoded_value, flagged_storage.is_private()); + } + + hash_builder.root() +} + +/// Compute the storage root for a given account with prehashed slots using privacy-aware +/// HashBuilder. This function respects the privacy flags in FlaggedStorage values, unlike the +/// standard version above. +pub fn storage_root_prehashed_privacy_aware< + I: IntoIterator<Item = (B256, alloy_primitives::FlaggedStorage)>, +>( + storage: I, +) -> B256 { + let mut hash_builder = HashBuilder::default(); + + // Collect and sort storage entries by key for consistent ordering + let mut storage_entries: Vec<_> = storage.into_iter().collect(); + storage_entries.sort_by(|a, b| a.0.cmp(&b.0)); + + // Add each storage entry to the hash builder with privacy awareness + for (key, flagged_storage) in storage_entries { + let nibbles = Nibbles::unpack(key); + let encoded_value = encode_fixed_size(&flagged_storage); + hash_builder.add_leaf(nibbles, &encoded_value, flagged_storage.is_private()); + } + + hash_builder.root() +}
diff --git reth/crates/trie/trie/src/trie.rs seismic-reth/crates/trie/trie/src/trie.rs index 17cdd1f96c57778e88d19c5639f653b7124974ea..0541e38b163997efde08c5fb9a8fdc0be979f1db 100644 --- reth/crates/trie/trie/src/trie.rs +++ seismic-reth/crates/trie/trie/src/trie.rs @@ -221,6 +221,8 @@ storage_result, hashed_address, account, &mut hash_builder, + // TODO(audit) + false, retain_updates, )? { // still in progress, need to pause again @@ -252,6 +254,7 @@ hash_builder.add_branch(node.key, node.value, node.children_are_in_trie); } TrieElement::Leaf(hashed_address, account) => { tracker.inc_leaf(); + let is_private = false; // account leaves are always public. Their storage leaves can be private. storage_ctx.hashed_entries_walked += 1;   // calculate storage root, calculating the remaining threshold so we have @@ -280,6 +283,7 @@ storage_result, hashed_address, account, &mut hash_builder, + is_private, retain_updates, )? { // storage root hit threshold, need to pause @@ -414,6 +418,7 @@ storage_result: StorageRootProgress, hashed_address: B256, account: Account, hash_builder: &mut HashBuilder, + is_private: bool, retain_updates: bool, ) -> Result<Option<IntermediateStorageRootState>, StateRootError> { match storage_result { @@ -429,7 +434,11 @@ // Encode the account with the computed storage root self.account_rlp.clear(); let trie_account = account.into_trie_account(storage_root); trie_account.encode(&mut self.account_rlp as &mut dyn BufMut); - hash_builder.add_leaf(Nibbles::unpack(hashed_address), &self.account_rlp); + hash_builder.add_leaf( + Nibbles::unpack(hashed_address), + &self.account_rlp, + is_private, + ); Ok(None) } StorageRootProgress::Progress(state, storage_slots_walked, updates) => { @@ -667,6 +676,7 @@ hashed_entries_walked += 1; hash_builder.add_leaf( Nibbles::unpack(hashed_slot), alloy_rlp::encode_fixed_size(&value).as_ref(), + value.is_private, );   // Check if we need to return intermediate progress
diff --git reth/crates/trie/trie/src/verify.rs seismic-reth/crates/trie/trie/src/verify.rs index 21a27655fa98abb1a4b22a6edef039f1367fe0dc..95b746f0a50de7940fe3fecda4b3f8746cf940d5 100644 --- reth/crates/trie/trie/src/verify.rs +++ seismic-reth/crates/trie/trie/src/verify.rs @@ -547,8 +547,8 @@ );   // Add storage for the account let mut storage1 = BTreeMap::new(); - storage1.insert(keccak256(B256::from(U256::from(1))), U256::from(100)); - storage1.insert(keccak256(B256::from(U256::from(2))), U256::from(200)); + storage1.insert(keccak256(B256::from(U256::from(1))), U256::from(100).into()); + storage1.insert(keccak256(B256::from(U256::from(2))), U256::from(200).into()); storage_tries.insert(addr1, storage1);   let factory = MockHashedCursorFactory::new(accounts, storage_tries); @@ -617,7 +617,8 @@ // Add some storage for each account let mut storage = BTreeMap::new(); for j in 0..i { - storage.insert(keccak256(B256::from(U256::from(j))), U256::from(j as u64 * 10)); + storage + .insert(keccak256(B256::from(U256::from(j))), U256::from(j as u64 * 10).into()); } if !storage.is_empty() { storage_tries.insert(addr, storage);
diff --git reth/crates/trie/trie/src/witness.rs seismic-reth/crates/trie/trie/src/witness.rs index 02ae6aa09c5f09175d67e25f2264182a38ef36e5..efbf27078175aac3d074abecf995d92c38f36b0c 100644 --- reth/crates/trie/trie/src/witness.rs +++ seismic-reth/crates/trie/trie/src/witness.rs @@ -172,15 +172,19 @@ ), )?; for hashed_slot in hashed_slots.into_iter().sorted_unstable() { let storage_nibbles = Nibbles::unpack(hashed_slot); - let maybe_leaf_value = storage - .and_then(|s| s.storage.get(&hashed_slot)) - .filter(|v| !v.is_zero()) - .map(|v| alloy_rlp::encode_fixed_size(v).to_vec()); - + let maybe_leaf_value = + storage.and_then(|s| s.storage.get(&hashed_slot)).filter(|v| !v.is_zero()); if let Some(value) = maybe_leaf_value { - storage_trie.update_leaf(storage_nibbles, value, &provider).map_err(|err| { - SparseStateTrieErrorKind::SparseStorageTrie(hashed_address, err.into_kind()) - })?; + let is_private = value.is_private; + let value = alloy_rlp::encode_fixed_size(value).to_vec(); + storage_trie + .update_leaf(storage_nibbles, value, is_private, &provider) + .map_err(|err| { + SparseStateTrieErrorKind::SparseStorageTrie( + hashed_address, + err.into_kind(), + ) + })?; } else { storage_trie.remove_leaf(&storage_nibbles, &provider).map_err(|err| { SparseStateTrieErrorKind::SparseStorageTrie(hashed_address, err.into_kind())
diff --git reth/crates/storage/codecs/Cargo.toml seismic-reth/crates/storage/codecs/Cargo.toml index 98bc23c353234df80c82900f1ad1dedf684dd9a8..75e113497dabe77156913eeb7a0d9bc1706d26fc 100644 --- reth/crates/storage/codecs/Cargo.toml +++ seismic-reth/crates/storage/codecs/Cargo.toml @@ -11,6 +11,11 @@ [lints] workspace = true   [dependencies] +# enclave +seismic-enclave.workspace = true +seismic-alloy-consensus = { workspace = true, default-features = false, features = ["arbitrary", "serde"] } +seismic-alloy-genesis.workspace = true + # reth reth-codecs-derive.workspace = true reth-zstd-compressors = { workspace = true, optional = true, default-features = false } @@ -18,7 +23,6 @@ # eth alloy-consensus = { workspace = true, optional = true } alloy-eips = { workspace = true, optional = true, features = ["serde"] } -alloy-genesis = { workspace = true, optional = true } alloy-primitives.workspace = true alloy-trie = { workspace = true, optional = true }   @@ -33,6 +37,9 @@ serde.workspace = true arbitrary = { workspace = true, features = ["derive"], optional = true }   [dev-dependencies] +seismic-alloy-consensus = { workspace = true, default-features = false, features = ["arbitrary", "serde"] } + +alloy-genesis = { workspace = true } alloy-eips = { workspace = true, default-features = false, features = ["arbitrary", "serde"] } alloy-primitives = { workspace = true, features = ["arbitrary", "serde", "rand"] } alloy-consensus = { workspace = true, features = ["arbitrary"] } @@ -51,7 +58,6 @@ "alloy-primitives/std", "bytes/std", "alloy-consensus?/std", "alloy-eips?/std", - "alloy-genesis?/std", "alloy-trie?/std", "serde/std", "op-alloy-consensus?/std", @@ -61,7 +67,6 @@ ] alloy = [ "dep:alloy-consensus", "dep:alloy-eips", - "dep:alloy-genesis", "dep:alloy-trie", "dep:reth-zstd-compressors", ]
diff --git reth/crates/storage/codecs/derive/src/arbitrary.rs seismic-reth/crates/storage/codecs/derive/src/arbitrary.rs index 5713bb9b0ffd4286ea101250d3a823f9144d988f..ecaed9e60e9f6a36443f2baeb755f110751564dc 100644 --- reth/crates/storage/codecs/derive/src/arbitrary.rs +++ seismic-reth/crates/storage/codecs/derive/src/arbitrary.rs @@ -13,7 +13,7 @@ type_ident: &impl ToTokens, mod_tests: &Ident, ) -> TokenStream2 { // Same as proptest - let mut default_cases = 256; + let mut default_cases = 1;   let mut traits = vec![]; let mut roundtrips = vec![];
diff --git reth/crates/storage/codecs/derive/src/compact/generator.rs seismic-reth/crates/storage/codecs/derive/src/compact/generator.rs index e6c06f44ad81af16ab0948f4f0dfdfe3afed0e2f..139e72673190380472e69c965db92ce30c36dbc9 100644 --- reth/crates/storage/codecs/derive/src/compact/generator.rs +++ seismic-reth/crates/storage/codecs/derive/src/compact/generator.rs @@ -107,8 +107,17 @@ ident: &Ident, zstd: Option<ZstdConfig>, ) -> TokenStream2 { let mut lines = vec![]; - let mut known_types = - vec!["B256", "Address", "Bloom", "Vec", "TxHash", "BlockHash", "FixedBytes", "Cow"]; + let mut known_types = vec![ + "B256", + "Address", + "Bloom", + "Vec", + "TxHash", + "BlockHash", + "FixedBytes", + "Cow", + "TxSeismicElements", + ];   // Only types without `Bytes` should be added here. It's currently manually added, since // it's hard to figure out with derive_macro which types have Bytes fields.
diff --git reth/crates/storage/codecs/derive/src/compact/mod.rs seismic-reth/crates/storage/codecs/derive/src/compact/mod.rs index ae349cd06e590f9a630a8005000111fe3a5506a0..5b4801b4dbd9048fb54b9cc089edb173e6957115 100644 --- reth/crates/storage/codecs/derive/src/compact/mod.rs +++ seismic-reth/crates/storage/codecs/derive/src/compact/mod.rs @@ -202,10 +202,11 @@ /// length. pub fn get_bit_size(ftype: &str) -> u8 { match ftype { "TransactionKind" | "TxKind" | "bool" | "Option" | "Signature" => 1, - "TxType" | "OpTxType" => 2, + "TxType" | "OpTxType" | "SeismicTxType" => 2, "u64" | "BlockNumber" | "TxNumber" | "ChainId" | "NumTransactions" => 4, "u128" => 5, "U256" => 6, + "u8" => 1, _ => 0, } }
diff --git reth/crates/storage/codecs/derive/src/lib.rs seismic-reth/crates/storage/codecs/derive/src/lib.rs index a835e8fab3c22bc5268a7dcee2e95e51a059de5b..b4c7998ef81e6400fcb45177789fb7d56f932be3 100644 --- reth/crates/storage/codecs/derive/src/lib.rs +++ seismic-reth/crates/storage/codecs/derive/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![allow(unreachable_pub, missing_docs)]
diff --git reth/crates/storage/codecs/src/alloy/genesis_account.rs seismic-reth/crates/storage/codecs/src/alloy/genesis_account.rs index a35d4947db79e903947ccb94ffbd945601038bb8..5ccb9aa963e9a7c8569c6c20cb286cd422fba356 100644 --- reth/crates/storage/codecs/src/alloy/genesis_account.rs +++ seismic-reth/crates/storage/codecs/src/alloy/genesis_account.rs @@ -2,9 +2,10 @@ //! Compact implementation for [`AlloyGenesisAccount`]   use crate::Compact; use alloc::vec::Vec; -use alloy_genesis::GenesisAccount as AlloyGenesisAccount; +use seismic_alloy_genesis::GenesisAccount as AlloyGenesisAccount; use alloy_primitives::{Bytes, B256, U256}; use reth_codecs_derive::add_arbitrary_tests; +use alloy_primitives::FlaggedStorage;   /// `GenesisAccount` acts as bridge which simplifies Compact implementation for /// `AlloyGenesisAccount`. @@ -69,6 +70,7 @@ #[add_arbitrary_tests(crate, compact)] pub(crate) struct StorageEntry { key: B256, value: B256, + is_private: bool, }   impl Compact for AlloyGenesisAccount { @@ -83,7 +85,11 @@ code: self.code.as_ref(), storage: self.storage.as_ref().map(|s| StorageEntries { entries: s .iter() - .map(|(key, value)| StorageEntry { key: *key, value: *value }) + .map(|(key, value)| StorageEntry { + key: *key, + value: value.value.into(), + is_private: value.is_private, + }) .collect(), }), private_key: self.private_key.as_ref(), @@ -99,7 +105,7 @@ balance: account.balance, code: account.code, storage: account .storage - .map(|s| s.entries.into_iter().map(|entry| (entry.key, entry.value)).collect()), + .map(|s| s.entries.into_iter().map(|entry| (entry.key, FlaggedStorage::new(U256::from_be_bytes(entry.value.0), entry.is_private))).collect()), private_key: account.private_key, }; (alloy_account, buf)
diff --git reth/crates/storage/codecs/src/alloy/mod.rs seismic-reth/crates/storage/codecs/src/alloy/mod.rs index 34fcd6fdc2b0bd392cf0ab23a003b006f292c017..9d96d2bb0dea5f854a5ac44319ac56abd9ed9b44 100644 --- reth/crates/storage/codecs/src/alloy/mod.rs +++ seismic-reth/crates/storage/codecs/src/alloy/mod.rs @@ -51,7 +51,7 @@ validate_bitflag_backwards_compat!(Header, UnusedBits::Zero); validate_bitflag_backwards_compat!(HeaderExt, UnusedBits::NotZero); validate_bitflag_backwards_compat!(TxEip2930, UnusedBits::Zero); validate_bitflag_backwards_compat!(StorageEntries, UnusedBits::Zero); - validate_bitflag_backwards_compat!(StorageEntry, UnusedBits::Zero); + validate_bitflag_backwards_compat!(StorageEntry, UnusedBits::NotZero); // Seismic broke backwards compatibility here for the is_private flag   validate_bitflag_backwards_compat!(GenesisAccountRef<'_>, UnusedBits::NotZero); validate_bitflag_backwards_compat!(GenesisAccount, UnusedBits::NotZero);
diff --git reth/crates/storage/codecs/src/alloy/transaction/mod.rs seismic-reth/crates/storage/codecs/src/alloy/transaction/mod.rs index f841ff24f1734f71171d845ecf3954d069ccbeb3..8a0ad7dc8c5e40f80a24f6d376fb7cfcabce1194 100644 --- reth/crates/storage/codecs/src/alloy/transaction/mod.rs +++ seismic-reth/crates/storage/codecs/src/alloy/transaction/mod.rs @@ -53,7 +53,7 @@ } } }   -cond_mod!(eip1559, eip2930, eip4844, eip7702, legacy, txtype); +cond_mod!(eip1559, eip2930, eip4844, eip7702, legacy, seismic, txtype);   mod ethereum; pub use ethereum::{CompactEnvelope, Envelope, FromTxCompact, ToTxCompact};
diff --git reth/crates/storage/codecs/src/alloy/transaction/seismic.rs seismic-reth/crates/storage/codecs/src/alloy/transaction/seismic.rs new file mode 100644 index 0000000000000000000000000000000000000000..c348043693b43c97c5e800276cf8e65682973489 --- /dev/null +++ seismic-reth/crates/storage/codecs/src/alloy/transaction/seismic.rs @@ -0,0 +1,494 @@ +//! Compact implementation for [`AlloyTxSeismic`] + +use crate::{ + txtype::{ + COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, + COMPACT_IDENTIFIER_LEGACY, + }, + Compact, +}; +use alloy_consensus::{ + transaction::{TxEip1559, TxEip2930, TxEip7702, TxLegacy}, + Signed, TxEip4844, +}; +use alloy_eips::eip2718::{EIP7702_TX_TYPE_ID, EIP4844_TX_TYPE_ID}; +use alloy_primitives::{aliases::U96, Bytes, ChainId, Signature, TxKind, U256}; +use bytes::{Buf, BufMut, BytesMut}; +use alloy_eips::eip7702::SignedAuthorization; +use seismic_alloy_consensus::{ + transaction::TxSeismicElements, SeismicTxEnvelope, SeismicTxType, SeismicTypedTransaction, + TxSeismic as AlloyTxSeismic, SEISMIC_TX_TYPE_ID, +}; + +use super::ethereum::{CompactEnvelope, Envelope, FromTxCompact, ToTxCompact}; + +/// Seismic transaction. +#[derive(Debug, Clone, PartialEq, Eq, Default, Compact)] +#[reth_codecs(crate = "crate")] +#[cfg_attr( + any(test, feature = "test-utils"), + derive(arbitrary::Arbitrary, serde::Serialize, serde::Deserialize), + crate::add_arbitrary_tests(crate, compact) +)] +#[cfg_attr(feature = "test-utils", allow(unreachable_pub), visibility::make(pub))] +pub(crate) struct TxSeismic { + /// Added as EIP-155: Simple replay attack protection + chain_id: ChainId, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + nonce: u64, + /// A scalar value equal to the number of + /// Wei to be paid per unit of gas for all computation + /// costs incurred as a result of the execution of this transaction; formally Tp. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + gas_price: u128, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + gas_limit: u64, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. + to: TxKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; formally Tv. + value: U256, + /// seismic elements + seismic_elements: TxSeismicElements, + /// Optional list of EIP-7702 authorization tuples + authorization_list: Vec<SignedAuthorization>, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call, formally Td. + input: Bytes, +} + +impl Compact for TxSeismicElements { + fn to_compact<B>(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let mut len = 0; + + // 1. encryption_pubkey (fixed size: 33 bytes) + len += self.encryption_pubkey.serialize().to_compact(buf); + + // 2. encryption_nonce (variable size: store length + data) + let mut cache = BytesMut::new(); + let nonce_len = self.encryption_nonce.to_compact(&mut cache); + buf.put_u8(nonce_len as u8); + buf.put_slice(&cache); + len += nonce_len + 1; + + // 3. message_version (fixed size: 1 byte) + buf.put_u8(self.message_version); + len += 1; + + // 4. recent_block_hash (fixed size: 32 bytes) + len += self.recent_block_hash.to_compact(buf); + + // 5. expires_at_block (variable size: store length + data) + let mut cache = BytesMut::new(); + let expires_len = self.expires_at_block.to_compact(&mut cache); + buf.put_u8(expires_len as u8); + buf.put_slice(&cache); + len += expires_len + 1; + + // 6. signed_read (fixed size: 1 byte) + buf.put_u8(self.signed_read as u8); + len += 1; + + len + } + + #[allow(clippy::indexing_slicing, clippy::unwrap_used)] + fn from_compact(mut buf: &[u8], _len: usize) -> (Self, &[u8]) { + // Codec format is fixed by to_compact; malformed data indicates corruption and should panic + // 1. encryption_pubkey (fixed size: 33 bytes) + let encryption_pubkey_compressed_bytes = + &buf[..seismic_enclave::secp256k1::constants::PUBLIC_KEY_SIZE]; + let encryption_pubkey = + seismic_enclave::secp256k1::PublicKey::from_slice(encryption_pubkey_compressed_bytes) + .unwrap(); + buf.advance(seismic_enclave::secp256k1::constants::PUBLIC_KEY_SIZE); + + // 2. encryption_nonce (variable size: read length then data) + let (nonce_len, buf) = (buf[0], &buf[1..]); + let (encryption_nonce, buf) = U96::from_compact(buf, nonce_len as usize); + + // 3. message_version (fixed size: 1 byte) + let (message_version, buf) = (buf[0], &buf[1..]); + + // 4. recent_block_hash (fixed size: 32 bytes) + let (recent_block_hash, buf) = alloy_primitives::B256::from_compact(buf, 32); + + // 5. expires_at_block (variable size: read length then data) + let (expires_len, buf) = (buf[0], &buf[1..]); + let (expires_at_block, buf) = u64::from_compact(buf, expires_len as usize); + + // 6. signed_read (fixed size: 1 byte) + let (signed_read, buf) = (buf[0] != 0, &buf[1..]); + + ( + Self { + encryption_pubkey, + encryption_nonce, + message_version, + recent_block_hash, + expires_at_block, + signed_read, + }, + buf, + ) + } +} + +impl Compact for AlloyTxSeismic { + fn to_compact<B>(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let tx = TxSeismic { + chain_id: self.chain_id, + nonce: self.nonce, + gas_price: self.gas_price, + gas_limit: self.gas_limit, + to: self.to, + value: self.value, + seismic_elements: self.seismic_elements, + input: self.input.clone(), + authorization_list: self.authorization_list.clone(), + }; + + tx.to_compact(buf) + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { + let (tx, _) = TxSeismic::from_compact(buf, len); + + let alloy_tx = Self { + chain_id: tx.chain_id, + nonce: tx.nonce, + gas_price: tx.gas_price, + gas_limit: tx.gas_limit, + to: tx.to, + value: tx.value, + seismic_elements: tx.seismic_elements, + input: tx.input, + authorization_list: tx.authorization_list, + }; + + (alloy_tx, buf) + } +} + +impl Compact for SeismicTxType { + fn to_compact<B>(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + match self { + Self::Legacy => COMPACT_IDENTIFIER_LEGACY, + Self::Eip2930 => COMPACT_IDENTIFIER_EIP2930, + Self::Eip1559 => COMPACT_IDENTIFIER_EIP1559, + Self::Eip4844 => { + buf.put_u8(EIP4844_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } + Self::Eip7702 => { + buf.put_u8(EIP7702_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } + Self::Seismic => { + buf.put_u8(SEISMIC_TX_TYPE_ID); + COMPACT_EXTENDED_IDENTIFIER_FLAG + } + } + } + + fn from_compact(mut buf: &[u8], identifier: usize) -> (Self, &[u8]) { + use bytes::Buf; + ( + match identifier { + COMPACT_IDENTIFIER_LEGACY => Self::Legacy, + COMPACT_IDENTIFIER_EIP2930 => Self::Eip2930, + COMPACT_IDENTIFIER_EIP1559 => Self::Eip1559, + COMPACT_EXTENDED_IDENTIFIER_FLAG => { + let extended_identifier = buf.get_u8(); + match extended_identifier { + EIP4844_TX_TYPE_ID => Self::Eip4844, + EIP7702_TX_TYPE_ID => Self::Eip7702, + SEISMIC_TX_TYPE_ID => Self::Seismic, + _ => panic!("Unsupported TxType identifier: {extended_identifier}"), + } + } + _ => panic!("Unknown identifier for TxType: {identifier}"), + }, + buf, + ) + } +} + +impl Compact for SeismicTypedTransaction { + fn to_compact<B>(&self, out: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let identifier = self.tx_type().to_compact(out); + match self { + Self::Legacy(tx) => tx.to_compact(out), + Self::Eip2930(tx) => tx.to_compact(out), + Self::Eip1559(tx) => tx.to_compact(out), + Self::Eip4844(tx) => tx.to_compact(out), + Self::Eip7702(tx) => tx.to_compact(out), + Self::Seismic(tx) => tx.to_compact(out), + }; + identifier + } + + fn from_compact(buf: &[u8], identifier: usize) -> (Self, &[u8]) { + let (tx_type, buf) = SeismicTxType::from_compact(buf, identifier); + match tx_type { + SeismicTxType::Legacy => { + let (tx, buf) = Compact::from_compact(buf, buf.len()); + (Self::Legacy(tx), buf) + } + SeismicTxType::Eip2930 => { + let (tx, buf) = Compact::from_compact(buf, buf.len()); + (Self::Eip2930(tx), buf) + } + SeismicTxType::Eip1559 => { + let (tx, buf) = Compact::from_compact(buf, buf.len()); + (Self::Eip1559(tx), buf) + } + SeismicTxType::Eip4844 => { + let (tx, buf): (TxEip4844, _) = Compact::from_compact(buf, buf.len()); + (Self::Eip4844(tx), buf) + } + SeismicTxType::Eip7702 => { + let (tx, buf) = Compact::from_compact(buf, buf.len()); + (Self::Eip7702(tx), buf) + } + SeismicTxType::Seismic => { + let (tx, buf) = Compact::from_compact(buf, buf.len()); + (Self::Seismic(tx), buf) + } + } + } +} + +impl ToTxCompact for SeismicTxEnvelope { + fn to_tx_compact(&self, buf: &mut (impl BufMut + AsMut<[u8]>)) { + match self { + Self::Legacy(tx) => tx.tx().to_compact(buf), + Self::Eip2930(tx) => tx.tx().to_compact(buf), + Self::Eip1559(tx) => tx.tx().to_compact(buf), + Self::Eip4844(tx) => tx.tx().to_compact(buf), + Self::Eip7702(tx) => tx.tx().to_compact(buf), + Self::Seismic(tx) => tx.tx().to_compact(buf), + }; + } +} + +impl FromTxCompact for SeismicTxEnvelope { + type TxType = SeismicTxType; + + fn from_tx_compact(buf: &[u8], tx_type: SeismicTxType, signature: Signature) -> (Self, &[u8]) { + match tx_type { + SeismicTxType::Legacy => { + let (tx, buf) = TxLegacy::from_compact(buf, buf.len()); + let tx = Signed::new_unhashed(tx, signature); + (Self::Legacy(tx), buf) + } + SeismicTxType::Eip2930 => { + let (tx, buf) = TxEip2930::from_compact(buf, buf.len()); + let tx = Signed::new_unhashed(tx, signature); + (Self::Eip2930(tx), buf) + } + SeismicTxType::Eip1559 => { + let (tx, buf) = TxEip1559::from_compact(buf, buf.len()); + let tx = Signed::new_unhashed(tx, signature); + (Self::Eip1559(tx), buf) + } + SeismicTxType::Eip4844 => { + let (tx, buf) = TxEip4844::from_compact(buf, buf.len()); + let tx = Signed::new_unhashed(tx, signature); + (Self::Eip4844(tx), buf) + } + SeismicTxType::Eip7702 => { + let (tx, buf) = TxEip7702::from_compact(buf, buf.len()); + let tx = Signed::new_unhashed(tx, signature); + (Self::Eip7702(tx), buf) + } + SeismicTxType::Seismic => { + let (tx, buf) = AlloyTxSeismic::from_compact(buf, buf.len()); + let tx = Signed::new_unhashed(tx, signature); + (Self::Seismic(tx), buf) + } + } + } +} + +impl Envelope for SeismicTxEnvelope { + fn signature(&self) -> &Signature { + match self { + Self::Legacy(tx) => tx.signature(), + Self::Eip2930(tx) => tx.signature(), + Self::Eip1559(tx) => tx.signature(), + Self::Eip4844(tx) => tx.signature(), + Self::Eip7702(tx) => tx.signature(), + Self::Seismic(tx) => tx.signature(), + } + } + + fn tx_type(&self) -> Self::TxType { + Self::tx_type(self) + } +} + +impl Compact for SeismicTxEnvelope { + fn to_compact<B>(&self, buf: &mut B) -> usize + where + B: BufMut + AsMut<[u8]>, + { + CompactEnvelope::to_compact(self, buf) + } + + fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { + CompactEnvelope::from_compact(buf, len) + } +} + +// Custom test module that excludes EIP4844 cases to avoid proptest failures +#[cfg(test)] +mod seismic_typed_transaction_tests { + use super::*; + use crate::Compact; + use proptest::prelude::*; + use proptest_arbitrary_interop::arb; + + #[test] + fn proptest() { + let config = ProptestConfig::with_cases(100); + + proptest::proptest!(config, |(field in arb::<SeismicTypedTransaction>())| { + // Skip EIP4844 cases as they have incomplete serialization support + match &field { + SeismicTypedTransaction::Eip4844(_) => return Ok(()), + _ => {} + } + + let mut buf = vec![]; + let len = field.clone().to_compact(&mut buf); + let (decoded, _): (SeismicTypedTransaction, _) = Compact::from_compact(&buf, len); + assert_eq!(field, decoded, "maybe_generate_tests::compact"); + }); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy_primitives::{hex, Bytes, TxKind}; + use bytes::BytesMut; + use seismic_enclave::secp256k1::PublicKey; + + #[test] + fn test_seismic_tx_compact_roundtrip() { + // Create a test transaction based on the example in file_context_0 + let tx = AlloyTxSeismic { + chain_id: 1166721750861005481, + nonce: 13985005159674441909, + gas_price: 296133358425745351516777806240018869443, + gas_limit: 6091425913586946366, + to: TxKind::Create, + value: U256::from_str_radix( + "30997721070913355446596643088712595347117842472993214294164452566768407578853", + 10, + ) + .unwrap(), + seismic_elements: TxSeismicElements { + encryption_pubkey: PublicKey::from_slice( + &hex::decode( + "02d211b6b0a191b9469bb3674e9c609f453d3801c3e3fd7e0bb00c6cc1e1d941df", + ) + .unwrap(), + ) + .unwrap(), + encryption_nonce: U96::from_str_radix("11856476099097235301", 10).unwrap(), + message_version: 85, + recent_block_hash: alloy_primitives::B256::from_slice( + &hex::decode( + "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", + ) + .unwrap(), + ), + expires_at_block: 1000000, + signed_read: false, + }, + input: Bytes::from_static(&[0x24]), + authorization_list: vec![ + alloy_eips::eip7702::Authorization { + chain_id: U256::from(1), + address: alloy_primitives::address!("0xdac17f958d2ee523a2206206994597c13d831ec7"), + nonce: 1, + } + .into_signed(Signature::new( + alloy_primitives::b256!("0x1fd474b1f9404c0c5df43b7620119ffbc3a1c3f942c73b6e14e9f55255ed9b1d").into(), + alloy_primitives::b256!("0x29aca24813279a901ec13b5f7bb53385fa1fc627b946592221417ff74a49600d").into(), + false, + )), + ], + }; + + // Encode to compact format + let mut buf = BytesMut::new(); + let encoded_size = tx.to_compact(&mut buf); + + // Decode from compact format + let (decoded_tx, _) = AlloyTxSeismic::from_compact(&buf, encoded_size); + + // Verify the roundtrip + assert_eq!(tx.chain_id, decoded_tx.chain_id); + assert_eq!(tx.nonce, decoded_tx.nonce); + assert_eq!(tx.gas_price, decoded_tx.gas_price); + assert_eq!(tx.gas_limit, decoded_tx.gas_limit); + assert_eq!(tx.to, decoded_tx.to); + assert_eq!(tx.value, decoded_tx.value); + assert_eq!(tx.input, decoded_tx.input); + assert_eq!(tx.authorization_list, decoded_tx.authorization_list); + + // Check seismic elements + assert_eq!( + tx.seismic_elements.encryption_pubkey.serialize(), + decoded_tx.seismic_elements.encryption_pubkey.serialize() + ); + assert_eq!( + tx.seismic_elements.encryption_nonce, + decoded_tx.seismic_elements.encryption_nonce + ); + assert_eq!( + tx.seismic_elements.message_version, + decoded_tx.seismic_elements.message_version + ); + assert_eq!( + tx.seismic_elements.recent_block_hash, + decoded_tx.seismic_elements.recent_block_hash + ); + assert_eq!( + tx.seismic_elements.expires_at_block, + decoded_tx.seismic_elements.expires_at_block + ); + assert_eq!( + tx.seismic_elements.signed_read, + decoded_tx.seismic_elements.signed_read + ); + } +}
diff --git reth/crates/storage/codecs/src/alloy/transaction/txtype.rs seismic-reth/crates/storage/codecs/src/alloy/transaction/txtype.rs index 63f80bfaf20170496700437198d2cd75397f7fed..39e941717c344e800cd6732fe0d457515f6b05c7 100644 --- reth/crates/storage/codecs/src/alloy/transaction/txtype.rs +++ seismic-reth/crates/storage/codecs/src/alloy/transaction/txtype.rs @@ -1,8 +1,10 @@ //! Compact implementation for [`TxType`]   -use crate::txtype::{COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, COMPACT_IDENTIFIER_LEGACY}; -use alloy_consensus::constants::{EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}; -use alloy_consensus::TxType; +use crate::txtype::{ + COMPACT_EXTENDED_IDENTIFIER_FLAG, COMPACT_IDENTIFIER_EIP1559, COMPACT_IDENTIFIER_EIP2930, + COMPACT_IDENTIFIER_LEGACY, +}; +use alloy_consensus::{constants::*, TxType};   impl crate::Compact for TxType { fn to_compact<B>(&self, buf: &mut B) -> usize @@ -55,10 +57,9 @@ #[cfg(test)] mod tests { use super::*; use rstest::rstest; - + + use crate::Compact; use alloy_consensus::constants::{EIP4844_TX_TYPE_ID, EIP7702_TX_TYPE_ID}; - use crate::Compact; -   #[rstest] #[case(TxType::Legacy, COMPACT_IDENTIFIER_LEGACY, vec![])] @@ -94,4 +95,4 @@ assert_eq!(actual_type, expected_type, "Unexpected TxType for identifier {identifier}"); assert!(remaining_buf.is_empty(), "Buffer not fully consumed for identifier {identifier}"); } -} \ No newline at end of file +}
diff --git reth/crates/storage/codecs/src/lib.rs seismic-reth/crates/storage/codecs/src/lib.rs index a9cb7f2fcd12342b89da6d4723e7cf6d30badf7a..20947aee1be5fbe5a99f8737249db872dcc2537e 100644 --- reth/crates/storage/codecs/src/lib.rs +++ seismic-reth/crates/storage/codecs/src/lib.rs @@ -11,7 +11,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -22,7 +22,7 @@ pub use reth_codecs_derive::*; use serde as _;   -use alloy_primitives::{Address, Bloom, Bytes, FixedBytes, U256}; +use alloy_primitives::{aliases::U96, Address, Bloom, Bytes, FixedBytes, U256}; use bytes::{Buf, BufMut};   use alloc::{ @@ -392,6 +392,31 @@ }   let mut arr = [0; 32]; arr[(32 - len)..].copy_from_slice(&buf[..len]); + buf.advance(len); + (Self::from_be_bytes(arr), buf) + } +} + +impl Compact for U96 { + #[inline] + fn to_compact<B>(&self, buf: &mut B) -> usize + where + B: bytes::BufMut + AsMut<[u8]>, + { + let inner = self.to_be_bytes::<12>(); + let size = 12 - (self.leading_zeros() / 8); + buf.put_slice(&inner[12 - size..]); + size + } + + #[inline] + fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) { + if len == 0 { + return (Self::ZERO, buf) + } + + let mut arr = [0; 12]; + arr[(12 - len)..].copy_from_slice(&buf[..len]); buf.advance(len); (Self::from_be_bytes(arr), buf) }
diff --git reth/crates/storage/db-api/Cargo.toml seismic-reth/crates/storage/db-api/Cargo.toml index 3f7e5c7b1a7ea6ceffb789723529b8b11ad374c9..ee2e0e84549ea87703a44b196a2753f18f94c91d 100644 --- reth/crates/storage/db-api/Cargo.toml +++ seismic-reth/crates/storage/db-api/Cargo.toml @@ -12,6 +12,10 @@ [lints] workspace = true   [dependencies] +# seismic +reth-seismic-primitives = { workspace = true, features = ["serde", "reth-codec"] } +seismic-alloy-genesis.workspace = true + # reth reth-codecs.workspace = true reth-db-models = { workspace = true, features = ["serde", "reth-codec"] } @@ -24,11 +28,12 @@ reth-trie-common.workspace = true   # ethereum alloy-primitives.workspace = true -alloy-genesis.workspace = true alloy-consensus.workspace = true   # optimism -reth-optimism-primitives = { workspace = true, optional = true } +# seismic: remove this dep to avoid pulling them optimism crates that don't compile implicitly by cargo/lsp/etc. +# The optimism crates don't compile because of type changes we made that affects them, such as FlaggedStorage. +# reth-optimism-primitives = { workspace = true, optional = true }   # codecs modular-bitfield.workspace = true @@ -60,6 +65,7 @@ proptest.workspace = true proptest-arbitrary-interop.workspace = true   [features] +timestamp-in-seconds = ["reth-seismic-primitives/timestamp-in-seconds"] test-utils = [ "arbitrary", "reth-primitives-traits/test-utils", @@ -82,11 +88,13 @@ "reth-codecs/arbitrary", "reth-prune-types/arbitrary", "reth-stages-types/arbitrary", "alloy-consensus/arbitrary", - "reth-optimism-primitives?/arbitrary", + # seismic: remove this dep to avoid pulling them optimism crates that don't compile implicitly by cargo/lsp/etc. + # The optimism crates don't compile because of type changes we made that affects them, such as FlaggedStorage. + # "reth-optimism-primitives?/arbitrary", "reth-ethereum-primitives/arbitrary", ] op = [ - "dep:reth-optimism-primitives", + # "dep:reth-optimism-primitives", "reth-codecs/op", "reth-primitives-traits/op", ]
diff --git reth/crates/storage/db-api/src/lib.rs seismic-reth/crates/storage/db-api/src/lib.rs index 96a3253a32f7bbcc8485f5220411382ea09f0553..19d1c0b6e963598873a8a19b0575c9bc434b4c64 100644 --- reth/crates/storage/db-api/src/lib.rs +++ seismic-reth/crates/storage/db-api/src/lib.rs @@ -54,7 +54,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/storage/db-api/src/models/mod.rs seismic-reth/crates/storage/db-api/src/models/mod.rs index cffa9d910f85e722327dba610d51c715bc88ce7c..dd91313fee615eceefca74f55a541baf9a8f6849 100644 --- reth/crates/storage/db-api/src/models/mod.rs +++ seismic-reth/crates/storage/db-api/src/models/mod.rs @@ -5,7 +5,6 @@ table::{Compress, Decode, Decompress, Encode}, DatabaseError, }; use alloy_consensus::Header; -use alloy_genesis::GenesisAccount; use alloy_primitives::{Address, Bytes, Log, B256, U256}; use reth_codecs::{add_arbitrary_tests, Compact}; use reth_ethereum_primitives::{Receipt, TransactionSigned, TxType}; @@ -13,6 +12,7 @@ use reth_primitives_traits::{Account, Bytecode, StorageEntry}; use reth_prune_types::{PruneCheckpoint, PruneSegment}; use reth_stages_types::StageCheckpoint; use reth_trie_common::{StoredNibbles, StoredNibblesSubKey, *}; +use seismic_alloy_genesis::GenesisAccount; use serde::{Deserialize, Serialize};   pub mod accounts; @@ -202,8 +202,13 @@ }   impl$(<$($generic: core::fmt::Debug + Send + Sync + Compact),*>)? Decompress for $name$(<$($generic),*>)? { fn decompress(value: &[u8]) -> Result<$name$(<$($generic),*>)?, $crate::DatabaseError> { - let (obj, _) = Compact::from_compact(value, value.len()); - Ok(obj) + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + Compact::from_compact(value, value.len()) + })); + match result { + Ok((obj, _)) => Ok(obj), + Err(_) => Err($crate::DatabaseError::Decode), + } } } )+ @@ -245,6 +250,13 @@ impl_compression_for_compact!(OpTransactionSigned, OpReceipt); }   +mod seismic { + use super::*; + use reth_seismic_primitives::{SeismicReceipt, SeismicTransactionSigned}; + + impl_compression_for_compact!(SeismicTransactionSigned, SeismicReceipt); +} + macro_rules! impl_compression_fixed_compact { ($($name:tt),+) => { $( @@ -262,8 +274,14 @@ }   impl Decompress for $name { fn decompress(value: &[u8]) -> Result<$name, $crate::DatabaseError> { - let (obj, _) = Compact::from_compact(&value, value.len()); - Ok(obj) + let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + let (obj, _) = Compact::from_compact(&value, value.len()); + obj + })); + match result { + Ok(obj) => Ok(obj), + Err(_) => Err($crate::DatabaseError::Decode), + } } }
diff --git reth/crates/storage/db-common/Cargo.toml seismic-reth/crates/storage/db-common/Cargo.toml index a4122ebf5c081e299592c3f5cca92839e8b9c830..54230f1daa9ade5ea23bc47b0bbad7478504382b 100644 --- reth/crates/storage/db-common/Cargo.toml +++ seismic-reth/crates/storage/db-common/Cargo.toml @@ -8,6 +8,9 @@ homepage.workspace = true repository.workspace = true   [dependencies] +# seismic +seismic-alloy-genesis.workspace = true + # reth reth-chainspec.workspace = true reth-db-api.workspace = true @@ -26,7 +29,6 @@ reth-execution-errors.workspace = true   # eth alloy-consensus.workspace = true -alloy-genesis.workspace = true alloy-primitives.workspace = true   # misc @@ -42,6 +44,7 @@ # tracing tracing.workspace = true   [dev-dependencies] +alloy-genesis.workspace = true reth-db = { workspace = true, features = ["mdbx"] } reth-provider = { workspace = true, features = ["test-utils"] }
diff --git reth/crates/storage/db-common/src/init.rs seismic-reth/crates/storage/db-common/src/init.rs index 87bb2ce98a039d8a805e209a82a77f5bebeb2c94..4e43a3b1f66a262d55174ba80ba4d6eacc8c66ed 100644 --- reth/crates/storage/db-common/src/init.rs +++ seismic-reth/crates/storage/db-common/src/init.rs @@ -1,7 +1,6 @@ //! Reth genesis initialization utility functions.   use alloy_consensus::BlockHeader; -use alloy_genesis::GenesisAccount; use alloy_primitives::{keccak256, map::HashMap, Address, B256, U256}; use reth_chainspec::EthChainSpec; use reth_codecs::Compact; @@ -27,6 +26,8 @@ use reth_trie_db::DatabaseStateRoot; use serde::{Deserialize, Serialize}; use std::io::BufRead; use tracing::{debug, error, info, trace}; + +use seismic_alloy_genesis::GenesisAccount;   /// Default soft limit for number of bytes to read from state dump file, before inserting into /// database. @@ -134,7 +135,10 @@ }   debug!("Writing genesis block.");   - let alloc = &genesis.alloc; + // Convert alloy_genesis accounts to seismic accounts for DB storage (adds FlaggedStorage). + // This is lossless: all genesis storage is marked as public. + let alloc: std::collections::BTreeMap<Address, GenesisAccount> = + genesis.alloc.iter().map(|(addr, account)| (*addr, account.clone().into())).collect();   // use transaction to insert genesis header let provider_rw = factory.database_provider_rw()?; @@ -227,9 +231,11 @@ .storage .as_ref() .map(|m| { m.iter() - .map(|(key, value)| { - let value = U256::from_be_bytes(value.0); - (*key, (U256::ZERO, value)) + .map(|(key, &flagged_value)| { + ( + *key, + (alloy_primitives::FlaggedStorage::public(U256::ZERO), flagged_value), + ) }) .collect::<HashMap<_, _>>() }) @@ -237,7 +243,10 @@ .unwrap_or_default();   reverts_init.insert( *address, - (Some(None), storage.keys().map(|k| StorageEntry::new(*k, U256::ZERO)).collect()), + ( + Some(None), + storage.keys().map(|k| StorageEntry { key: *k, ..Default::default() }).collect(), + ), );   state_init.insert( @@ -292,7 +301,7 @@ let alloc_storage = alloc.filter_map(|(addr, account)| { // only return Some if there is storage account.storage.as_ref().map(|storage| { - (*addr, storage.iter().map(|(&key, &value)| StorageEntry { key, value: value.into() })) + (*addr, storage.clone().into_iter().map(|(key, value)| StorageEntry { key, value })) }) }); provider.insert_storage_for_hashing(alloc_storage)?; @@ -668,7 +677,7 @@ use super::*; use alloy_consensus::constants::{ HOLESKY_GENESIS_HASH, MAINNET_GENESIS_HASH, SEPOLIA_GENESIS_HASH, }; - use alloy_genesis::Genesis; + use alloy_genesis::{Genesis, GenesisAccount}; use reth_chainspec::{Chain, ChainSpec, HOLESKY, MAINNET, SEPOLIA}; use reth_db::DatabaseEnv; use reth_db_api::{
diff --git reth/crates/storage/db-common/src/lib.rs seismic-reth/crates/storage/db-common/src/lib.rs index 173e53143408e90ee872d5d81dea35641517f862..ec01e12afe51fca61ac2bf32cd341a8c10cf52de 100644 --- reth/crates/storage/db-common/src/lib.rs +++ seismic-reth/crates/storage/db-common/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/storage/db/src/implementation/mdbx/mod.rs seismic-reth/crates/storage/db/src/implementation/mdbx/mod.rs index faa784de698fd95ea09025004c36c65e7f420ef1..f9151b547df5203e5a1d042acc54aadf85025a1e 100644 --- reth/crates/storage/db/src/implementation/mdbx/mod.rs +++ seismic-reth/crates/storage/db/src/implementation/mdbx/mod.rs @@ -591,8 +591,8 @@ let tx = db.tx_mut().expect(ERROR_INIT_TX);   let mut dup_cursor = tx.cursor_dup_write::<PlainStorageState>().unwrap();   - let entry_0 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(0) }; - let entry_1 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1) }; + let entry_0 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(0).into() }; + let entry_1 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1).into() };   dup_cursor.upsert(Address::with_last_byte(1), &entry_0).expect(ERROR_UPSERT); dup_cursor.upsert(Address::with_last_byte(1), &entry_1).expect(ERROR_UPSERT); @@ -958,11 +958,11 @@ let key = Address::random(); let subkey1 = B256::random(); let subkey2 = B256::random();   - let entry1 = StorageEntry { key: subkey1, value: U256::ZERO }; + let entry1 = StorageEntry { key: subkey1, value: U256::ZERO.into() }; assert!(dup_cursor.insert(key, &entry1).is_ok());   // Can't insert - let entry2 = StorageEntry { key: subkey2, value: U256::ZERO }; + let entry2 = StorageEntry { key: subkey2, value: U256::ZERO.into() }; assert!(dup_cursor.insert(key, &entry2).is_err()); }   @@ -1118,12 +1118,12 @@ let mut dup_cursor = tx.cursor_dup_write::<PlainStorageState>().unwrap(); let subkey = B256::random();   let value = U256::from(1); - let entry1 = StorageEntry { key: subkey, value }; + let entry1 = StorageEntry { key: subkey, value: value.into() }; dup_cursor.upsert(key, &entry1).expect(ERROR_UPSERT); assert_eq!(dup_cursor.seek_by_key_subkey(key, subkey), Ok(Some(entry1)));   let value = U256::from(2); - let entry2 = StorageEntry { key: subkey, value }; + let entry2 = StorageEntry { key: subkey, value: value.into() }; dup_cursor.upsert(key, &entry2).expect(ERROR_UPSERT); assert_eq!(dup_cursor.seek_by_key_subkey(key, subkey), Ok(Some(entry1))); assert_eq!(dup_cursor.next_dup_val(), Ok(Some(entry2))); @@ -1235,11 +1235,11 @@ let value00 = StorageEntry::default(); env.update(|tx| tx.put::<PlainStorageState>(key, value00).expect(ERROR_PUT)).unwrap();   // PUT (2,2) - let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2) }; + let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2).into() }; env.update(|tx| tx.put::<PlainStorageState>(key, value22).expect(ERROR_PUT)).unwrap();   // PUT (1,1) - let value11 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1) }; + let value11 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1).into() }; env.update(|tx| tx.put::<PlainStorageState>(key, value11).expect(ERROR_PUT)).unwrap();   // Iterate with cursor @@ -1279,11 +1279,11 @@ let value00 = StorageEntry::default(); env.update(|tx| tx.put::<PlainStorageState>(key, value00).expect(ERROR_PUT)).unwrap();   // PUT (2,2) - let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2) }; + let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2).into() }; env.update(|tx| tx.put::<PlainStorageState>(key, value22).expect(ERROR_PUT)).unwrap();   // PUT (1,1) - let value11 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1) }; + let value11 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1).into() }; env.update(|tx| tx.put::<PlainStorageState>(key, value11).expect(ERROR_PUT)).unwrap();   // Try to walk_dup with not existing key should immediately return None @@ -1309,11 +1309,11 @@ let value00 = StorageEntry::default(); env.update(|tx| tx.put::<PlainStorageState>(key1, value00).expect(ERROR_PUT)).unwrap();   // PUT key1 (1,1) - let value11 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1) }; + let value11 = StorageEntry { key: B256::with_last_byte(1), value: U256::from(1).into() }; env.update(|tx| tx.put::<PlainStorageState>(key1, value11).expect(ERROR_PUT)).unwrap();   // PUT key2 (2,2) - let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2) }; + let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2).into() }; env.update(|tx| tx.put::<PlainStorageState>(key2, value22).expect(ERROR_PUT)).unwrap();   // Iterate with walk_dup @@ -1349,7 +1349,7 @@ let key1 = Address::new([0x11; 20]); let key2 = Address::new([0x22; 20]);   // PUT key1 (0,1) - let value01 = StorageEntry { key: B256::with_last_byte(0), value: U256::from(1) }; + let value01 = StorageEntry { key: B256::with_last_byte(0), value: U256::from(1).into() }; env.update(|tx| tx.put::<PlainStorageState>(key1, value01).expect(ERROR_PUT)).unwrap();   // PUT key1 (0,0) @@ -1357,7 +1357,7 @@ let value00 = StorageEntry::default(); env.update(|tx| tx.put::<PlainStorageState>(key1, value00).expect(ERROR_PUT)).unwrap();   // PUT key2 (2,2) - let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2) }; + let value22 = StorageEntry { key: B256::with_last_byte(2), value: U256::from(2).into() }; env.update(|tx| tx.put::<PlainStorageState>(key2, value22).expect(ERROR_PUT)).unwrap();   // Iterate with walk
diff --git reth/crates/storage/db/src/lib.rs seismic-reth/crates/storage/db/src/lib.rs index 278986f9f9835d9466062e7109187221cd61dea8..d852c0f33d1854743de6e15fe07bb591f1661f5e 100644 --- reth/crates/storage/db/src/lib.rs +++ seismic-reth/crates/storage/db/src/lib.rs @@ -10,7 +10,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/storage/errors/src/lib.rs seismic-reth/crates/storage/errors/src/lib.rs index aa8254ee17444a62c4bde948023e8628ab17a4b9..ec97df91d1fca03c989a9efb5fcc856867815df5 100644 --- reth/crates/storage/errors/src/lib.rs +++ seismic-reth/crates/storage/errors/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/storage/errors/src/provider.rs seismic-reth/crates/storage/errors/src/provider.rs index c27587690ba6c631f578908ddc0c8a1a2c7e0b81..eaf3dcd7215de7c96ec8948da0c242ff6c96ca42 100644 --- reth/crates/storage/errors/src/provider.rs +++ seismic-reth/crates/storage/errors/src/provider.rs @@ -134,12 +134,34 @@ UnifiedStorageWriterError(#[from] UnifiedStorageWriterError), /// Received invalid output from configured storage implementation. #[error("received invalid output from storage")] InvalidStorageOutput, + /// Enclave encryptography error. + #[error("enclave error: {_0}")] + EnclaveError(EnclaveError), /// Missing trie updates. #[error("missing trie updates for block {0}")] MissingTrieUpdates(B256), /// Any other error type wrapped into a cloneable [`AnyError`]. #[error(transparent)] Other(#[from] AnyError), +} + +/// Custom error type for reth error handling. +#[derive(Clone, Debug, Eq, PartialEq, Display)] +pub enum EnclaveError { + /// enclave encryption fails + EncryptionError, + /// enclave decryption fails + DecryptionError, + /// Ephemeral keypair generation fails + EphRngKeypairGenerationError(String), + /// Custom error. + Custom(&'static str), +} + +impl From<EnclaveError> for ProviderError { + fn from(err: EnclaveError) -> Self { + Self::EnclaveError(err) + } }   impl ProviderError {
diff --git reth/crates/storage/libmdbx-rs/mdbx-sys/src/lib.rs seismic-reth/crates/storage/libmdbx-rs/mdbx-sys/src/lib.rs index 6f86951ca5e2f531a3a5e6b8233eed9ce284bd98..84823eb615c486e032eae062a8ed5c7dfd2e9d90 100644 --- reth/crates/storage/libmdbx-rs/mdbx-sys/src/lib.rs +++ seismic-reth/crates/storage/libmdbx-rs/mdbx-sys/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, clippy::all)]
diff --git reth/crates/storage/libmdbx-rs/src/lib.rs seismic-reth/crates/storage/libmdbx-rs/src/lib.rs index 300dfa60c70f1279febe059d06a2bf84ead625dd..c09b0c7de2a19c06d2dd52c2f7ade6457bb6ccc9 100644 --- reth/crates/storage/libmdbx-rs/src/lib.rs +++ seismic-reth/crates/storage/libmdbx-rs/src/lib.rs @@ -2,7 +2,7 @@ #![doc = include_str!("../README.md")] #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![allow(missing_docs, clippy::needless_pass_by_ref_mut)]
diff --git reth/crates/storage/nippy-jar/src/lib.rs seismic-reth/crates/storage/nippy-jar/src/lib.rs index f3d1944d3b49123a571693bb00f77261ad700c3b..f8085f27b6072f6e3bbc0b0f8413dd94532d7996 100644 --- reth/crates/storage/nippy-jar/src/lib.rs +++ seismic-reth/crates/storage/nippy-jar/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/storage/provider/Cargo.toml seismic-reth/crates/storage/provider/Cargo.toml index 82a3726c43ea313805f6b8ed33cf6ddb0eecb601..2fd3045d235c6f6ecae343604542e6bdb7832a79 100644 --- reth/crates/storage/provider/Cargo.toml +++ seismic-reth/crates/storage/provider/Cargo.toml @@ -39,7 +39,7 @@ alloy-primitives.workspace = true alloy-rpc-types-engine.workspace = true alloy-consensus.workspace = true revm-database.workspace = true -revm-state = { workspace = true, optional = true } +revm-state.workspace = true   # tracing tracing.workspace = true @@ -70,7 +70,7 @@ reth-chain-state = { workspace = true, features = ["test-utils"] } reth-trie = { workspace = true, features = ["test-utils"] } reth-testing-utils.workspace = true reth-ethereum-engine-primitives.workspace = true -reth-ethereum-primitives.workspace = true +reth-ethereum-primitives = { workspace = true, features = ["reth-codec", "serde", "serde-bincode-compat"] }   revm-database-interface.workspace = true revm-state.workspace = true @@ -97,6 +97,6 @@ "reth-db-api/test-utils", "reth-trie-db/test-utils", "reth-prune-types/test-utils", "reth-stages-types/test-utils", - "revm-state", + # "revm-state", // seismic requires revm-state as a non-optional dependency "tokio", ]
diff --git reth/crates/storage/provider/src/bundle_state/state_reverts.rs seismic-reth/crates/storage/provider/src/bundle_state/state_reverts.rs index 7ffdc153b22626771a0d2336ac431cd75eae7174..717ee2e98d51c57d5dee565ec69565375a97ea73 100644 --- reth/crates/storage/provider/src/bundle_state/state_reverts.rs +++ seismic-reth/crates/storage/provider/src/bundle_state/state_reverts.rs @@ -1,5 +1,6 @@ -use alloy_primitives::{B256, U256}; +use alloy_primitives::B256; use revm_database::states::RevertToSlot; +use revm_state::FlaggedStorage; use std::iter::Peekable;   /// Iterator over storage reverts. @@ -13,7 +14,7 @@ impl<R, W> StorageRevertsIter<R, W> where R: Iterator<Item = (B256, RevertToSlot)>, - W: Iterator<Item = (B256, U256)>, + W: Iterator<Item = (B256, FlaggedStorage)>, { /// Create a new iterator over storage reverts. pub fn new( @@ -24,12 +25,12 @@ Self { reverts: reverts.into_iter().peekable(), wiped: wiped.into_iter().peekable() } }   /// Consume next revert and return it. - fn next_revert(&mut self) -> Option<(B256, U256)> { + fn next_revert(&mut self) -> Option<(B256, FlaggedStorage)> { self.reverts.next().map(|(key, revert)| (key, revert.to_previous_value())) }   /// Consume next wiped storage and return it. - fn next_wiped(&mut self) -> Option<(B256, U256)> { + fn next_wiped(&mut self) -> Option<(B256, FlaggedStorage)> { self.wiped.next() } } @@ -37,9 +38,9 @@ impl<R, W> Iterator for StorageRevertsIter<R, W> where R: Iterator<Item = (B256, RevertToSlot)>, - W: Iterator<Item = (B256, U256)>, + W: Iterator<Item = (B256, FlaggedStorage)>, { - type Item = (B256, U256); + type Item = (B256, FlaggedStorage);   /// Iterate over storage reverts and wiped entries and return items in the sorted order. /// NOTE: The implementation assumes that inner iterators are already sorted. @@ -85,7 +86,7 @@ #[test] fn test_storage_reverts_iter_empty() { // Create empty sample data for reverts and wiped entries. let reverts: Vec<(B256, RevertToSlot)> = vec![]; - let wiped: Vec<(B256, U256)> = vec![]; + let wiped: Vec<(B256, FlaggedStorage)> = vec![];   // Create the iterator with the empty data. let iter = StorageRevertsIter::new(reverts, wiped); @@ -102,7 +103,7 @@ fn test_storage_reverts_iter_reverts_only() { // Create sample data for only reverts. let reverts = vec![ (B256::from_slice(&[4; 32]), RevertToSlot::Destroyed), - (B256::from_slice(&[5; 32]), RevertToSlot::Some(U256::from(40))), + (B256::from_slice(&[5; 32]), RevertToSlot::Some(FlaggedStorage::public(40))), ];   // Create the iterator with only reverts and no wiped entries. @@ -115,8 +116,9 @@ // Verify the output order and values. assert_eq!( results, vec![ - (B256::from_slice(&[4; 32]), U256::ZERO), // Revert slot previous value - (B256::from_slice(&[5; 32]), U256::from(40)), // Only revert present. + (B256::from_slice(&[4; 32]), FlaggedStorage::ZERO), // Revert slot previous value + (B256::from_slice(&[5; 32]), FlaggedStorage::public(40)), /* Only revert + * present. */ ] ); } @@ -125,8 +127,8 @@ #[test] fn test_storage_reverts_iter_wiped_only() { // Create sample data for only wiped entries. let wiped = vec![ - (B256::from_slice(&[6; 32]), U256::from(50)), - (B256::from_slice(&[7; 32]), U256::from(60)), + (B256::from_slice(&[6; 32]), FlaggedStorage::public(50)), + (B256::from_slice(&[7; 32]), FlaggedStorage::public(60)), ];   // Create the iterator with only wiped entries and no reverts. @@ -139,8 +141,10 @@ // Verify the output order and values. assert_eq!( results, vec![ - (B256::from_slice(&[6; 32]), U256::from(50)), // Only wiped present. - (B256::from_slice(&[7; 32]), U256::from(60)), // Only wiped present. + (B256::from_slice(&[6; 32]), FlaggedStorage::public(50)), /* Only wiped + * present. */ + (B256::from_slice(&[7; 32]), FlaggedStorage::public(60)), /* Only wiped + * present. */ ] ); } @@ -149,15 +153,15 @@ #[test] fn test_storage_reverts_iter_interleaved() { // Create sample data for interleaved reverts and wiped entries. let reverts = vec![ - (B256::from_slice(&[8; 32]), RevertToSlot::Some(U256::from(70))), - (B256::from_slice(&[9; 32]), RevertToSlot::Some(U256::from(80))), + (B256::from_slice(&[8; 32]), RevertToSlot::Some(FlaggedStorage::public(70))), + (B256::from_slice(&[9; 32]), RevertToSlot::Some(FlaggedStorage::public(80))), // Some higher key than wiped - (B256::from_slice(&[15; 32]), RevertToSlot::Some(U256::from(90))), + (B256::from_slice(&[15; 32]), RevertToSlot::Some(FlaggedStorage::public(90))), ];   let wiped = vec![ - (B256::from_slice(&[8; 32]), U256::from(75)), // Same key as revert - (B256::from_slice(&[10; 32]), U256::from(85)), // Wiped with new key + (B256::from_slice(&[8; 32]), FlaggedStorage::public(75)), // Same key as revert + (B256::from_slice(&[10; 32]), FlaggedStorage::public(85)), // Wiped with new key ];   // Create the iterator with the sample data. @@ -170,10 +174,13 @@ // Verify the output order and values. assert_eq!( results, vec![ - (B256::from_slice(&[8; 32]), U256::from(70)), // Revert takes priority. - (B256::from_slice(&[9; 32]), U256::from(80)), // Only revert present. - (B256::from_slice(&[10; 32]), U256::from(85)), // Wiped entry. - (B256::from_slice(&[15; 32]), U256::from(90)), // Greater revert entry + (B256::from_slice(&[8; 32]), FlaggedStorage::public(70)), /* Revert takes + * priority. */ + (B256::from_slice(&[9; 32]), FlaggedStorage::public(80)), /* Only revert + * present. */ + (B256::from_slice(&[10; 32]), FlaggedStorage::public(85)), // Wiped entry. + (B256::from_slice(&[15; 32]), FlaggedStorage::public(90)), /* Greater revert + * entry */ ] ); }
diff --git reth/crates/storage/provider/src/lib.rs seismic-reth/crates/storage/provider/src/lib.rs index 6c7826c82d723de0504a34c91e6f4571886237ce..414c2aa26d089f6885605de985bba8a92112f774 100644 --- reth/crates/storage/provider/src/lib.rs +++ seismic-reth/crates/storage/provider/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/storage/provider/src/providers/database/provider.rs seismic-reth/crates/storage/provider/src/providers/database/provider.rs index 160ed34a17643704133c892c39196747a08ef1fb..85da7a8daffb2db07eaca05bc39caaef28a437b7 100644 --- reth/crates/storage/provider/src/providers/database/provider.rs +++ seismic-reth/crates/storage/provider/src/providers/database/provider.rs @@ -1720,7 +1720,7 @@ .map(|key| -> ProviderResult<_> { Ok(plain_storage .seek_by_key_subkey(address, key)? .filter(|v| v.key == key) - .unwrap_or_else(|| StorageEntry { key, value: Default::default() })) + .unwrap_or_else(|| StorageEntry { key, ..Default::default() })) }) .collect::<ProviderResult<Vec<_>>>() .map(|storage| (address, storage)) @@ -1919,9 +1919,9 @@ let mut wiped_storage = Vec::new(); if wiped { tracing::trace!(?address, "Wiping storage"); if let Some((_, entry)) = storages_cursor.seek_exact(address)? { - wiped_storage.push((entry.key, entry.value)); + wiped_storage.push((entry.key, entry.into())); while let Some(entry) = storages_cursor.next_dup_val()? { - wiped_storage.push((entry.key, entry.value)) + wiped_storage.push((entry.key, entry.into())) } } } @@ -2006,7 +2006,7 @@ storages_cursor.delete_current()?; } }   - if !entry.value.is_zero() { + if !entry.to_flagged_storage().is_zero() { storages_cursor.upsert(address, &entry)?; } } @@ -2499,10 +2499,10 @@ map.insert(keccak256(address), storage); map });   - let hashed_storage_keys = hashed_storages - .iter() - .map(|(hashed_address, entries)| (*hashed_address, entries.keys().copied().collect())) - .collect(); + let hashed_storage_keys = + HashMap::from_iter(hashed_storages.iter().map(|(hashed_address, entries)| { + (*hashed_address, BTreeSet::from_iter(entries.keys().copied())) + }));   let mut hashed_storage_cursor = self.tx.cursor_dup_write::<tables::HashedStorages>()?; // Hash the address and key and apply them to HashedStorage (if Storage is None @@ -2518,7 +2518,10 @@ hashed_storage_cursor.delete_current()?; }   if !value.is_zero() { - hashed_storage_cursor.upsert(hashed_address, &StorageEntry { key, value })?; + hashed_storage_cursor.upsert( + hashed_address, + &StorageEntry { key, value, ..Default::default() }, + )?; } Ok(()) })
diff --git reth/crates/storage/provider/src/providers/state/historical.rs seismic-reth/crates/storage/provider/src/providers/state/historical.rs index d3d94224d12148ca67e2f08094713aad59c96099..96cc17b7a922fe01ba56ab70107a2b67a1d88291 100644 --- reth/crates/storage/provider/src/providers/state/historical.rs +++ seismic-reth/crates/storage/provider/src/providers/state/historical.rs @@ -3,7 +3,7 @@ providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader, HashedPostStateProvider, ProviderError, StateProvider, StateRootProvider, }; use alloy_eips::merge::EPOCH_SLOTS; -use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, StorageValue, B256}; +use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, B256}; use reth_db_api::{ cursor::{DbCursorRO, DbDupCursorRO}, models::{storage_sharded_key::StorageShardedKey, ShardedKey}, @@ -28,8 +28,9 @@ use reth_trie_db::{ DatabaseHashedPostState, DatabaseHashedStorage, DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, }; +use std::fmt::Debug;   -use std::fmt::Debug; +use revm_state::FlaggedStorage;   /// State provider for a given block number which takes a tx reference. /// @@ -402,7 +403,7 @@ fn storage( &self, address: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>> { + ) -> ProviderResult<Option<FlaggedStorage>> { match self.storage_history_lookup(address, storage_key)? { HistoryInfo::NotYetWritten => Ok(None), HistoryInfo::InChangeset(changeset_block_number) => Ok(Some( @@ -415,15 +416,15 @@ block_number: changeset_block_number, address, storage_key: Box::new(storage_key), })? - .value, + .into(), )), HistoryInfo::InPlainState | HistoryInfo::MaybeInPlainState => Ok(self .tx() .cursor_dup_read::<tables::PlainStorageState>()? .seek_by_key_subkey(address, storage_key)? .filter(|entry| entry.key == storage_key) - .map(|entry| entry.value) - .or(Some(StorageValue::ZERO))), + .map(|entry| entry.into()) + .or(Some(FlaggedStorage::ZERO))), } } } @@ -532,6 +533,7 @@ }; use reth_primitives_traits::{Account, StorageEntry}; use reth_storage_api::{BlockHashReader, BlockNumReader, DBProvider, DatabaseProviderFactory}; use reth_storage_errors::provider::ProviderError; + use revm_state::FlaggedStorage;   const ADDRESS: Address = address!("0x0000000000000000000000000000000000000001"); const HIGHER_ADDRESS: Address = address!("0x0000000000000000000000000000000000000005"); @@ -687,13 +689,13 @@ BlockNumberList::new([4]).unwrap(), ) .unwrap();   - let higher_entry_plain = StorageEntry { key: STORAGE, value: U256::from(1000) }; - let higher_entry_at4 = StorageEntry { key: STORAGE, value: U256::from(0) }; - let entry_plain = StorageEntry { key: STORAGE, value: U256::from(100) }; - let entry_at15 = StorageEntry { key: STORAGE, value: U256::from(15) }; - let entry_at10 = StorageEntry { key: STORAGE, value: U256::from(10) }; - let entry_at7 = StorageEntry { key: STORAGE, value: U256::from(7) }; - let entry_at3 = StorageEntry { key: STORAGE, value: U256::from(0) }; + let higher_entry_plain = StorageEntry { key: STORAGE, value: FlaggedStorage::public(1000) }; + let higher_entry_at4 = StorageEntry { key: STORAGE, value: FlaggedStorage::public(0) }; + let entry_plain = StorageEntry { key: STORAGE, value: FlaggedStorage::public(100) }; + let entry_at15 = StorageEntry { key: STORAGE, value: FlaggedStorage::public(15) }; + let entry_at10 = StorageEntry { key: STORAGE, value: FlaggedStorage::public(10) }; + let entry_at7 = StorageEntry { key: STORAGE, value: FlaggedStorage::public(7) }; + let entry_at3 = StorageEntry { key: STORAGE, value: FlaggedStorage::public(0) };   // setup tx.put::<tables::StorageChangeSets>((3, ADDRESS).into(), entry_at3).unwrap(); @@ -716,31 +718,31 @@ Ok(None) )); assert!(matches!( HistoricalStateProviderRef::new(&db, 3).storage(ADDRESS, STORAGE), - Ok(Some(U256::ZERO)) + Ok(Some(FlaggedStorage::ZERO)) )); assert!(matches!( HistoricalStateProviderRef::new(&db, 4).storage(ADDRESS, STORAGE), - Ok(Some(expected_value)) if expected_value == entry_at7.value + Ok(Some(expected_value)) if expected_value == entry_at7.value.into() )); assert!(matches!( HistoricalStateProviderRef::new(&db, 7).storage(ADDRESS, STORAGE), - Ok(Some(expected_value)) if expected_value == entry_at7.value + Ok(Some(expected_value)) if expected_value == entry_at7.value.into() )); assert!(matches!( HistoricalStateProviderRef::new(&db, 9).storage(ADDRESS, STORAGE), - Ok(Some(expected_value)) if expected_value == entry_at10.value + Ok(Some(expected_value)) if expected_value == entry_at10.value.into() )); assert!(matches!( HistoricalStateProviderRef::new(&db, 10).storage(ADDRESS, STORAGE), - Ok(Some(expected_value)) if expected_value == entry_at10.value + Ok(Some(expected_value)) if expected_value == entry_at10.value.into() )); assert!(matches!( HistoricalStateProviderRef::new(&db, 11).storage(ADDRESS, STORAGE), - Ok(Some(expected_value)) if expected_value == entry_at15.value + Ok(Some(expected_value)) if expected_value == entry_at15.value.into() )); assert!(matches!( HistoricalStateProviderRef::new(&db, 16).storage(ADDRESS, STORAGE), - Ok(Some(expected_value)) if expected_value == entry_plain.value + Ok(Some(expected_value)) if expected_value == entry_plain.value.into() )); assert!(matches!( HistoricalStateProviderRef::new(&db, 1).storage(HIGHER_ADDRESS, STORAGE), @@ -748,7 +750,7 @@ Ok(None) )); assert!(matches!( HistoricalStateProviderRef::new(&db, 1000).storage(HIGHER_ADDRESS, STORAGE), - Ok(Some(expected_value)) if expected_value == higher_entry_plain.value + Ok(Some(expected_value)) if expected_value == higher_entry_plain.value.into() )); }
diff --git reth/crates/storage/provider/src/providers/state/latest.rs seismic-reth/crates/storage/provider/src/providers/state/latest.rs index 5c838b0da3e4c3b4517ac3494c296888f97f4b0f..90f240ae6635f259b4fd1e308a3c228808770093 100644 --- reth/crates/storage/provider/src/providers/state/latest.rs +++ seismic-reth/crates/storage/provider/src/providers/state/latest.rs @@ -2,7 +2,7 @@ use crate::{ providers::state::macros::delegate_provider_impls, AccountReader, BlockHashReader, HashedPostStateProvider, StateProvider, StateRootProvider, }; -use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, StorageValue, B256}; +use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, B256}; use reth_db_api::{cursor::DbDupCursorRO, tables, transaction::DbTx}; use reth_primitives_traits::{Account, Bytecode}; use reth_storage_api::{BytecodeReader, DBProvider, StateProofProvider, StorageRootProvider}; @@ -18,6 +18,7 @@ use reth_trie_db::{ DatabaseProof, DatabaseStateRoot, DatabaseStorageProof, DatabaseStorageRoot, DatabaseTrieWitness, }; +use revm_state::FlaggedStorage;   /// State provider over latest state that takes tx reference. /// @@ -156,11 +157,11 @@ fn storage( &self, account: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>> { + ) -> ProviderResult<Option<FlaggedStorage>> { let mut cursor = self.tx().cursor_dup_read::<tables::PlainStorageState>()?; if let Some(entry) = cursor.seek_by_key_subkey(account, storage_key)? { if entry.key == storage_key { - return Ok(Some(entry.value)) + return Ok(Some(entry.into())) } } Ok(None)
diff --git reth/crates/storage/provider/src/providers/state/macros.rs seismic-reth/crates/storage/provider/src/providers/state/macros.rs index 74bb371819f937251606ad5a4e426aae1b53ac3b..2d9fe4742da59872a4bd9ac919033a8946a7f231 100644 --- reth/crates/storage/provider/src/providers/state/macros.rs +++ seismic-reth/crates/storage/provider/src/providers/state/macros.rs @@ -38,7 +38,7 @@ fn block_hash(&self, number: u64) -> reth_storage_errors::provider::ProviderResult<Option<alloy_primitives::B256>>; fn canonical_hashes_range(&self, start: alloy_primitives::BlockNumber, end: alloy_primitives::BlockNumber) -> reth_storage_errors::provider::ProviderResult<Vec<alloy_primitives::B256>>; } StateProvider $(where [$($generics)*])? { - fn storage(&self, account: alloy_primitives::Address, storage_key: alloy_primitives::StorageKey) -> reth_storage_errors::provider::ProviderResult<Option<alloy_primitives::StorageValue>>; + fn storage(&self, account: alloy_primitives::Address, storage_key: alloy_primitives::StorageKey) -> reth_storage_errors::provider::ProviderResult<Option<revm_state::FlaggedStorage>>; } BytecodeReader $(where [$($generics)*])? { fn bytecode_by_hash(&self, code_hash: &alloy_primitives::B256) -> reth_storage_errors::provider::ProviderResult<Option<reth_primitives_traits::Bytecode>>;
diff --git reth/crates/storage/provider/src/test_utils/blocks.rs seismic-reth/crates/storage/provider/src/test_utils/blocks.rs index 13a05e7921f29f7ee2770d7d9cbd22a2663430ab..e9b239821fc10564e47bfbb30ede8736faf00a0b 100644 --- reth/crates/storage/provider/src/test_utils/blocks.rs +++ seismic-reth/crates/storage/provider/src/test_utils/blocks.rs @@ -14,7 +14,7 @@ use reth_node_types::NodeTypes; use reth_primitives_traits::{Account, RecoveredBlock, SealedBlock, SealedHeader}; use reth_trie::root::{state_root_unhashed, storage_root_unhashed}; use revm_database::BundleState; -use revm_state::AccountInfo; +use revm_state::{AccountInfo, FlaggedStorage}; use std::{str::FromStr, sync::LazyLock};   /// Assert genesis block @@ -205,7 +205,10 @@ .state_present_account_info(account1, info.clone()) .revert_account_info(number, account1, Some(None)) .state_present_account_info(account2, info) .revert_account_info(number, account2, Some(None)) - .state_storage(account1, HashMap::from_iter([(slot, (U256::ZERO, U256::from(10)))])) + .state_storage( + account1, + HashMap::from_iter([(slot, (FlaggedStorage::ZERO, FlaggedStorage::public(10)))]), + ) .build(), vec![vec![Receipt { tx_type: TxType::Eip2930, @@ -253,13 +256,16 @@ .state_present_account_info( account, AccountInfo { nonce: 3, balance: U256::from(20), ..Default::default() }, ) - .state_storage(account, HashMap::from_iter([(slot, (U256::ZERO, U256::from(15)))])) + .state_storage( + account, + HashMap::from_iter([(slot, (FlaggedStorage::ZERO, FlaggedStorage::public(15)))]), + ) .revert_account_info( number, account, Some(Some(AccountInfo { nonce: 1, balance: U256::from(10), ..Default::default() })), ) - .revert_storage(number, account, Vec::from([(slot, U256::from(10))])) + .revert_storage(number, account, Vec::from([(slot, FlaggedStorage::public(10))])) .build(), vec![vec![Receipt { tx_type: TxType::Eip1559, @@ -314,10 +320,9 @@ AccountInfo { nonce: 1, balance: U256::from(idx), ..Default::default() }, ) .state_storage( address, - slot_range - .clone() - .map(|slot| (U256::from(slot), (U256::ZERO, U256::from(slot)))) - .collect(), + HashMap::from_iter(slot_range.clone().map(|slot| { + (U256::from(slot), (FlaggedStorage::ZERO, FlaggedStorage::public(slot))) + })), ) .revert_account_info(number, address, Some(None)) .revert_storage(number, address, Vec::new()); @@ -374,18 +379,19 @@ AccountInfo { nonce: 1, balance: U256::from(idx * 2), ..Default::default() }, ) .state_storage( address, - slot_range - .clone() - .map(|slot| (U256::from(slot), (U256::from(slot), U256::from(slot * 2)))) - .collect(), + HashMap::from_iter(slot_range.clone().map(|slot| { + ( + U256::from(slot), + (FlaggedStorage::public(slot), FlaggedStorage::public(slot * 2)), + ) + })), ) } else { bundle_state_builder.state_address(address).state_storage( address, - slot_range - .clone() - .map(|slot| (U256::from(slot), (U256::from(slot), U256::ZERO))) - .collect(), + HashMap::from_iter(slot_range.clone().map(|slot| { + (U256::from(slot), (FlaggedStorage::public(slot), FlaggedStorage::ZERO)) + })), ) }; // record previous account info @@ -402,7 +408,9 @@ ) .revert_storage( number, address, - slot_range.clone().map(|slot| (U256::from(slot), U256::from(slot))).collect(), + Vec::from_iter( + slot_range.clone().map(|slot| (U256::from(slot), FlaggedStorage::public(slot))), + ), ); } let execution_outcome = ExecutionOutcome::new( @@ -456,11 +464,12 @@ AccountInfo { nonce: 1, balance: U256::from(idx * 2), ..Default::default() }, ) .state_storage( address, - slot_range - .clone() - .take(50) - .map(|slot| (U256::from(slot), (U256::from(slot), U256::from(slot * 4)))) - .collect(), + HashMap::from_iter(slot_range.clone().take(50).map(|slot| { + ( + U256::from(slot), + (FlaggedStorage::public(slot), FlaggedStorage::public(slot * 4)), + ) + })), ); bundle_state_builder = if idx.is_multiple_of(2) { bundle_state_builder @@ -478,7 +487,7 @@ number, address, slot_range .clone() - .map(|slot| (U256::from(slot), U256::from(slot * 2))) + .map(|slot| (U256::from(slot), FlaggedStorage::public(slot * 2))) .collect(), ) } else {
diff --git reth/crates/storage/provider/src/test_utils/mock.rs seismic-reth/crates/storage/provider/src/test_utils/mock.rs index 9e47f8b6f1fac5c2885c235538e4b579fe551b4d..5d1ea5515c73b79fa9d2fc01f9dbfbee5668d83e 100644 --- reth/crates/storage/provider/src/test_utils/mock.rs +++ seismic-reth/crates/storage/provider/src/test_utils/mock.rs @@ -8,8 +8,8 @@ }; use alloy_consensus::{constants::EMPTY_ROOT_HASH, transaction::TransactionMeta, BlockHeader}; use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{ - keccak256, map::HashMap, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, - TxHash, TxNumber, B256, U256, + keccak256, map::HashMap, Address, BlockHash, BlockNumber, Bytes, StorageKey, TxHash, TxNumber, + B256, U256, }; use parking_lot::Mutex; use reth_chain_state::{CanonStateNotifications, CanonStateSubscriptions}; @@ -43,6 +43,8 @@ ops::{RangeBounds, RangeInclusive}, sync::Arc, }; use tokio::sync::broadcast; + +use revm_state::FlaggedStorage;   /// A mock implementation for Provider interfaces. #[derive(Debug)] @@ -197,7 +199,7 @@ #[derive(Debug, Clone)] pub struct ExtendedAccount { account: Account, bytecode: Option<Bytecode>, - storage: HashMap<StorageKey, StorageValue>, + storage: HashMap<StorageKey, FlaggedStorage>, }   impl ExtendedAccount { @@ -222,7 +224,7 @@ /// Add storage to the extended account. If the storage key is already present, /// the value is updated. pub fn extend_storage( mut self, - storage: impl IntoIterator<Item = (StorageKey, StorageValue)>, + storage: impl IntoIterator<Item = (StorageKey, FlaggedStorage)>, ) -> Self { self.storage.extend(storage); self @@ -866,7 +868,7 @@ fn storage( &self, account: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>> { + ) -> ProviderResult<Option<FlaggedStorage>> { let lock = self.accounts.lock(); Ok(lock.get(&account).and_then(|account| account.storage.get(&storage_key)).copied()) }
diff --git reth/crates/storage/provider/src/test_utils/mod.rs seismic-reth/crates/storage/provider/src/test_utils/mod.rs index d65655de8bfa09f0cb1dc52807a0262d216be037..1dbc87097d5db9d0be8be0175ff658158ea55684 100644 --- reth/crates/storage/provider/src/test_utils/mod.rs +++ seismic-reth/crates/storage/provider/src/test_utils/mod.rs @@ -2,7 +2,7 @@ use crate::{ providers::{ProviderNodeTypes, StaticFileProvider}, HashingWriter, ProviderFactory, TrieWriter, }; -use alloy_primitives::B256; +use alloy_primitives::{FlaggedStorage, B256, U256}; use reth_chainspec::{ChainSpec, MAINNET}; use reth_db::{ test_utils::{create_test_rw_db, create_test_static_files_dir, TempDatabase}, @@ -80,7 +80,11 @@ // Only return `Some` if there is storage. account.storage.map(|storage| { ( addr, - storage.into_iter().map(|(key, value)| StorageEntry { key, value: value.into() }), + storage.into_iter().map(|(key, value)| StorageEntry { + key, + value: FlaggedStorage::public(U256::from_be_bytes(value.0)), + ..Default::default() + }), ) }) });
diff --git reth/crates/storage/provider/src/writer/mod.rs seismic-reth/crates/storage/provider/src/writer/mod.rs index bca2a4cdb4c2d6ce2ddbb8d47e5d64506fc9412a..1d67cab7882cd996adc34e42d25536942ff72ec3 100644 --- reth/crates/storage/provider/src/writer/mod.rs +++ seismic-reth/crates/storage/provider/src/writer/mod.rs @@ -255,6 +255,7 @@ }; use revm_database_interface::{DatabaseCommit, EmptyDB}; use revm_state::{ Account as RevmAccount, AccountInfo as RevmAccountInfo, AccountStatus, EvmStorageSlot, + FlaggedStorage, }; use std::{collections::BTreeMap, str::FromStr};   @@ -282,7 +283,7 @@ .unwrap(); storage_cursor .insert( hashed_address, - &StorageEntry { key: hashed_slot, value: U256::from(1) }, + &StorageEntry { key: hashed_slot, value: FlaggedStorage::public(1) }, ) .unwrap(); } @@ -452,15 +453,22 @@ let provider = factory.database_provider_rw().unwrap();   let address_a = Address::ZERO; let address_b = Address::repeat_byte(0xff); + let address_c = Address::random();   let account_b = RevmAccountInfo { balance: U256::from(2), nonce: 2, ..Default::default() }; + let account_c = RevmAccountInfo { balance: U256::from(1), nonce: 3, ..Default::default() };   let mut state = State::builder().with_bundle_update().build(); state.insert_not_existing(address_a); state.insert_account_with_storage( address_b, account_b.clone(), - HashMap::from_iter([(U256::from(1), U256::from(1))]), + HashMap::from_iter([(U256::from(1), FlaggedStorage::new(1, false))]), + ); + state.insert_account_with_storage( + address_c, + account_c.clone(), + HashMap::from_iter([(U256::from(3), FlaggedStorage::new(1, false))]), );   state.commit(HashMap::from_iter([ @@ -474,11 +482,17 @@ // 0x01 => 0 => 2 storage: HashMap::from_iter([ ( U256::from(0), - EvmStorageSlot { present_value: U256::from(1), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::new(1, true), + ..Default::default() + }, ), ( U256::from(1), - EvmStorageSlot { present_value: U256::from(2), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::new(2, true), + ..Default::default() + }, ), ]), transaction_id: 0, @@ -493,8 +507,25 @@ // 0x01 => 1 => 2 storage: HashMap::from_iter([( U256::from(1), EvmStorageSlot { - present_value: U256::from(2), - original_value: U256::from(1), + present_value: FlaggedStorage::new(2, false), + original_value: FlaggedStorage::new(1, false), + ..Default::default() + }, + )]), + transaction_id: 0, + }, + ), + ( + address_c, + RevmAccount { + status: AccountStatus::Touched, + info: account_c, + // 0x03 => {private: false, value: 1} => {private: true, value: 2} + storage: HashMap::from_iter([( + U256::from(3), + EvmStorageSlot { + present_value: FlaggedStorage::new(2, true), + original_value: FlaggedStorage::new(1, false), ..Default::default() }, )]), @@ -518,16 +549,19 @@ .expect("Could not open plain storage state cursor");   assert_eq!( storage_cursor.seek_exact(address_a).unwrap(), - Some((address_a, StorageEntry { key: B256::ZERO, value: U256::from(1) })), - "Slot 0 for account A should be 1" + Some((address_a, StorageEntry { key: B256::ZERO, value: FlaggedStorage::private(1) })), + "Slot 0 for account A should be a private 1" ); assert_eq!( storage_cursor.next_dup().unwrap(), Some(( address_a, - StorageEntry { key: B256::from(U256::from(1).to_be_bytes()), value: U256::from(2) } + StorageEntry { + key: B256::from(U256::from(1).to_be_bytes()), + value: FlaggedStorage::private(2), + } )), - "Slot 1 for account A should be 2" + "Slot 1 for account A should be a private 2" ); assert_eq!( storage_cursor.next_dup().unwrap(), @@ -539,15 +573,34 @@ assert_eq!( storage_cursor.seek_exact(address_b).unwrap(), Some(( address_b, - StorageEntry { key: B256::from(U256::from(1).to_be_bytes()), value: U256::from(2) } + StorageEntry { + key: B256::from(U256::from(1).to_be_bytes()), + value: FlaggedStorage::public(2), + } )), - "Slot 1 for account B should be 2" + "Slot 1 for account B should be a public 2" ); assert_eq!( storage_cursor.next_dup().unwrap(), None, "Account B should only have 1 storage slot" ); + assert_eq!( + storage_cursor.seek_exact(address_c).unwrap(), + Some(( + address_c, + StorageEntry { + key: B256::from(U256::from(3).to_be_bytes()), + value: FlaggedStorage::private(2), + } + )), + "Slot 3 for account C should be a private 2" + ); + assert_eq!( + storage_cursor.next_dup().unwrap(), + None, + "Account C should only have 1 storage slot" + );   // Check change set let mut changeset_cursor = provider @@ -558,17 +611,20 @@ assert_eq!( changeset_cursor.seek_exact(BlockNumberAddress((1, address_a))).unwrap(), Some(( BlockNumberAddress((1, address_a)), - StorageEntry { key: B256::ZERO, value: U256::from(0) } + StorageEntry { key: B256::ZERO, value: FlaggedStorage::ZERO } )), - "Slot 0 for account A should have changed from 0" + "Slot 0 for account A should have changed from a public 0" ); assert_eq!( changeset_cursor.next_dup().unwrap(), Some(( BlockNumberAddress((1, address_a)), - StorageEntry { key: B256::from(U256::from(1).to_be_bytes()), value: U256::from(0) } + StorageEntry { + key: B256::from(U256::from(1).to_be_bytes()), + value: FlaggedStorage::ZERO, + } )), - "Slot 1 for account A should have changed from 0" + "Slot 1 for account A should have changed from a public 0" ); assert_eq!( changeset_cursor.next_dup().unwrap(), @@ -580,9 +636,12 @@ assert_eq!( changeset_cursor.seek_exact(BlockNumberAddress((1, address_b))).unwrap(), Some(( BlockNumberAddress((1, address_b)), - StorageEntry { key: B256::from(U256::from(1).to_be_bytes()), value: U256::from(1) } + StorageEntry { + key: B256::from(U256::from(1).to_be_bytes()), + value: FlaggedStorage::public(1), + } )), - "Slot 1 for account B should have changed from 1" + "Slot 1 for account B should have changed from a public 1" ); assert_eq!( changeset_cursor.next_dup().unwrap(), @@ -590,6 +649,23 @@ None, "Account B should only be in the changeset 1 time" );   + assert_eq!( + changeset_cursor.seek_exact(BlockNumberAddress((1, address_c))).unwrap(), + Some(( + BlockNumberAddress((1, address_c)), + StorageEntry { + key: B256::from(U256::from(3).to_be_bytes()), + value: FlaggedStorage::public(1), + } + )), + "Slot 1 for account C should have changed from a public 1" + ); + assert_eq!( + changeset_cursor.next_dup().unwrap(), + None, + "Account C should only be in the changeset 1 time" + ); + // Delete account A let mut state = State::builder().with_bundle_update().build(); state.insert_account(address_a, RevmAccountInfo::default()); @@ -620,17 +696,20 @@ assert_eq!( changeset_cursor.seek_exact(BlockNumberAddress((2, address_a))).unwrap(), Some(( BlockNumberAddress((2, address_a)), - StorageEntry { key: B256::ZERO, value: U256::from(1) } + StorageEntry { key: B256::ZERO, value: FlaggedStorage::private(1) } )), - "Slot 0 for account A should have changed from 1 on deletion" + "Slot 0 for account A should have changed from a private 1 on deletion" ); assert_eq!( changeset_cursor.next_dup().unwrap(), Some(( BlockNumberAddress((2, address_a)), - StorageEntry { key: B256::from(U256::from(1).to_be_bytes()), value: U256::from(2) } + StorageEntry { + key: B256::from(U256::from(1).to_be_bytes()), + value: FlaggedStorage::private(2), + } )), - "Slot 1 for account A should have changed from 2 on deletion" + "Slot 1 for account A should have changed from a private 2 on deletion" ); assert_eq!( changeset_cursor.next_dup().unwrap(), @@ -660,11 +739,17 @@ // 0x01 => 0 => 2 storage: HashMap::from_iter([ ( U256::ZERO, - EvmStorageSlot { present_value: U256::from(1), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(1), + ..Default::default() + }, ), ( U256::from(1), - EvmStorageSlot { present_value: U256::from(2), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(2), + ..Default::default() + }, ), ]), transaction_id: 0, @@ -682,7 +767,10 @@ let mut state = State::builder().with_bundle_update().build(); state.insert_account_with_storage( address1, account_info.clone(), - HashMap::from_iter([(U256::ZERO, U256::from(1)), (U256::from(1), U256::from(2))]), + HashMap::from_iter([ + (U256::ZERO, FlaggedStorage::public(1)), + (U256::from(1), FlaggedStorage::public(2)), + ]), );   // Block #1: change storage. @@ -695,8 +783,8 @@ // 0x00 => 1 => 2 storage: HashMap::from_iter([( U256::ZERO, EvmStorageSlot { - original_value: U256::from(1), - present_value: U256::from(2), + original_value: FlaggedStorage::public(1), + present_value: FlaggedStorage::public(2), ..Default::default() }, )]), @@ -741,15 +829,24 @@ // 0x06 => 0 => 6 storage: HashMap::from_iter([ ( U256::ZERO, - EvmStorageSlot { present_value: U256::from(2), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(2), + ..Default::default() + }, ), ( U256::from(2), - EvmStorageSlot { present_value: U256::from(4), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(4), + ..Default::default() + }, ), ( U256::from(6), - EvmStorageSlot { present_value: U256::from(6), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(6), + ..Default::default() + }, ), ]), transaction_id: 0, @@ -787,7 +884,10 @@ info: account_info.clone(), // 0x00 => 0 => 2 storage: HashMap::from_iter([( U256::ZERO, - EvmStorageSlot { present_value: U256::from(2), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(2), + ..Default::default() + }, )]), transaction_id: 0, }, @@ -821,7 +921,10 @@ info: account_info, // 0x00 => 0 => 9 storage: HashMap::from_iter([( U256::ZERO, - EvmStorageSlot { present_value: U256::from(9), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(9), + ..Default::default() + }, )]), transaction_id: 0, }, @@ -856,14 +959,14 @@ assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((0, address1)), - StorageEntry { key: B256::with_last_byte(0), value: U256::ZERO } + StorageEntry { key: B256::with_last_byte(0), value: FlaggedStorage::ZERO } ))) ); assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((0, address1)), - StorageEntry { key: B256::with_last_byte(1), value: U256::ZERO } + StorageEntry { key: B256::with_last_byte(1), value: FlaggedStorage::ZERO } ))) );   @@ -873,7 +976,7 @@ assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((1, address1)), - StorageEntry { key: B256::with_last_byte(0), value: U256::from(1) } + StorageEntry { key: B256::with_last_byte(0), value: FlaggedStorage::public(1) } ))) );   @@ -884,14 +987,14 @@ assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((2, address1)), - StorageEntry { key: B256::with_last_byte(0), value: U256::from(2) } + StorageEntry { key: B256::with_last_byte(0), value: FlaggedStorage::public(2) } ))) ); assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((2, address1)), - StorageEntry { key: B256::with_last_byte(1), value: U256::from(2) } + StorageEntry { key: B256::with_last_byte(1), value: FlaggedStorage::public(2) } ))) );   @@ -906,21 +1009,21 @@ assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((4, address1)), - StorageEntry { key: B256::with_last_byte(0), value: U256::ZERO } + StorageEntry { key: B256::with_last_byte(0), value: FlaggedStorage::ZERO } ))) ); assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((4, address1)), - StorageEntry { key: B256::with_last_byte(2), value: U256::ZERO } + StorageEntry { key: B256::with_last_byte(2), value: FlaggedStorage::ZERO } ))) ); assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((4, address1)), - StorageEntry { key: B256::with_last_byte(6), value: U256::ZERO } + StorageEntry { key: B256::with_last_byte(6), value: FlaggedStorage::ZERO } ))) );   @@ -932,21 +1035,21 @@ assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((5, address1)), - StorageEntry { key: B256::with_last_byte(0), value: U256::from(2) } + StorageEntry { key: B256::with_last_byte(0), value: FlaggedStorage::public(2) } ))) ); assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((5, address1)), - StorageEntry { key: B256::with_last_byte(2), value: U256::from(4) } + StorageEntry { key: B256::with_last_byte(2), value: FlaggedStorage::public(4) } ))) ); assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((5, address1)), - StorageEntry { key: B256::with_last_byte(6), value: U256::from(6) } + StorageEntry { key: B256::with_last_byte(6), value: FlaggedStorage::public(6) } ))) );   @@ -959,7 +1062,7 @@ assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((7, address1)), - StorageEntry { key: B256::with_last_byte(0), value: U256::ZERO } + StorageEntry { key: B256::with_last_byte(0), value: FlaggedStorage::ZERO } ))) ); assert_eq!(storage_changes.next(), None); @@ -986,11 +1089,17 @@ // 0x01 => 0 => 2 storage: HashMap::from_iter([ ( U256::ZERO, - EvmStorageSlot { present_value: U256::from(1), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(1), + ..Default::default() + }, ), ( U256::from(1), - EvmStorageSlot { present_value: U256::from(2), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(2), + ..Default::default() + }, ), ]), transaction_id: 0, @@ -1007,7 +1116,10 @@ let mut state = State::builder().with_bundle_update().build(); state.insert_account_with_storage( address1, account1.clone(), - HashMap::from_iter([(U256::ZERO, U256::from(1)), (U256::from(1), U256::from(2))]), + HashMap::from_iter([ + (U256::ZERO, FlaggedStorage::public(1)), + (U256::from(1), FlaggedStorage::public(2)), + ]), );   // Block #1: Destroy, re-create, change storage. @@ -1039,7 +1151,10 @@ info: account1, // 0x01 => 0 => 5 storage: HashMap::from_iter([( U256::from(1), - EvmStorageSlot { present_value: U256::from(5), ..Default::default() }, + EvmStorageSlot { + present_value: FlaggedStorage::public(5), + ..Default::default() + }, )]), transaction_id: 0, }, @@ -1063,14 +1178,14 @@ assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((1, address1)), - StorageEntry { key: B256::with_last_byte(0), value: U256::from(1) } + StorageEntry { key: B256::with_last_byte(0), value: FlaggedStorage::public(1) } ))) ); assert_eq!( storage_changes.next(), Some(Ok(( BlockNumberAddress((1, address1)), - StorageEntry { key: B256::with_last_byte(1), value: U256::from(2) } + StorageEntry { key: B256::with_last_byte(1), value: FlaggedStorage::public(2) } ))) ); assert_eq!(storage_changes.next(), None); @@ -1108,12 +1223,14 @@ }   #[test] fn bundle_state_state_root() { - type PreState = BTreeMap<Address, (Account, BTreeMap<B256, U256>)>; + type PreState = + BTreeMap<Address, (Account, BTreeMap<B256, alloy_primitives::FlaggedStorage>)>; let mut prestate: PreState = (0..10) .map(|key| { let account = Account { nonce: 1, balance: U256::from(key), bytecode_hash: None }; - let storage = - (1..11).map(|key| (B256::with_last_byte(key), U256::from(key))).collect(); + let storage = (1..11) + .map(|key| (B256::with_last_byte(key), U256::from(key).into())) + .collect(); (Address::with_last_byte(key), (account, storage)) }) .collect(); @@ -1186,7 +1303,7 @@ account2.0.into(), HashMap::from_iter([(slot2, account2_slot2_old_value)]), );   - let account2_slot2_new_value = U256::from(100); + let account2_slot2_new_value = U256::from(100).into(); account2.1.insert(slot2_key, account2_slot2_new_value); state.commit(HashMap::from_iter([( address2, @@ -1262,7 +1379,7 @@ // update storage for account 1 let slot20 = U256::from(20); let slot20_key = B256::from(slot20); - let account1_slot20_value = U256::from(12345); + let account1_slot20_value = U256::from(12345).into(); prestate.get_mut(&address1).unwrap().1.insert(slot20_key, account1_slot20_value); state.commit(HashMap::from_iter([( address1, @@ -1271,7 +1388,7 @@ status: AccountStatus::Touched | AccountStatus::Created, info: account1_new.into(), storage: HashMap::from_iter([( slot20, - EvmStorageSlot::new_changed(U256::ZERO, account1_slot20_value, 0), + EvmStorageSlot::new_changed(FlaggedStorage::ZERO, account1_slot20_value, 0), )]), transaction_id: 0, }, @@ -1336,7 +1453,7 @@ "512428ed685fff57294d1a9cbb147b18ae5db9cf6ae4b312fa1946ba0561882e", "51e6784c736ef8548f856909870b38e49ef7a4e3e77e5e945e0d5e6fcaa3037f", ] .into_iter() - .map(|str| (B256::from_str(str).unwrap(), U256::from(1))), + .map(|str| (B256::from_str(str).unwrap(), FlaggedStorage::public(1))), ); let mut state = HashedPostState::default(); state.storages.insert(hashed_address, init_storage.clone()); @@ -1365,7 +1482,7 @@ "00deb8486ad8edccfdedfc07109b3667b38a03a8009271aac250cce062d90917", "88d233b7380bb1bcdc866f6871c94685848f54cf0ee033b1480310b4ddb75fc9", ] .into_iter() - .map(|str| (B256::from_str(str).unwrap(), U256::from(1))), + .map(|str| (B256::from_str(str).unwrap(), FlaggedStorage::public(1))), ); let mut state = HashedPostState::default(); state.storages.insert(hashed_address, updated_storage.clone());
diff --git reth/crates/storage/rpc-provider/src/lib.rs seismic-reth/crates/storage/rpc-provider/src/lib.rs index 869089320961cb34120e398a44348a6ecbbb0fe1..5af6c4dd1d8e25d6443664d95c70e915f63f6d14 100644 --- reth/crates/storage/rpc-provider/src/lib.rs +++ seismic-reth/crates/storage/rpc-provider/src/lib.rs @@ -28,7 +28,8 @@ use alloy_consensus::{constants::KECCAK_EMPTY, BlockHeader}; use alloy_eips::{BlockHashOrNumber, BlockNumberOrTag}; use alloy_network::{primitives::HeaderResponse, BlockResponse}; use alloy_primitives::{ - map::HashMap, Address, BlockHash, BlockNumber, StorageKey, TxHash, TxNumber, B256, U256, + map::HashMap, Address, BlockHash, BlockNumber, FlaggedStorage, StorageKey, TxHash, TxNumber, + B256, U256, }; use alloy_provider::{ext::DebugApi, network::Network, Provider}; use alloy_rpc_types::{AccountInfo, BlockId}; @@ -1088,13 +1089,15 @@ fn storage( &self, address: Address, storage_key: StorageKey, - ) -> Result<Option<U256>, ProviderError> { + ) -> Result<Option<FlaggedStorage>, ProviderError> { self.block_on_async(async { Ok(Some( self.provider .get_storage_at(address, storage_key.into()) .block_id(self.block_id) .await + // TODO(audit): this might leak + .map(FlaggedStorage::public) .map_err(ProviderError::other)?, )) }) @@ -1226,7 +1229,7 @@ for (address, keys) in addresses_with_keys { let mut values = Vec::new(); for key in keys { let value = self.storage(address, key)?.unwrap_or_default(); - values.push(reth_primitives::StorageEntry::new(key, value)); + values.push(reth_primitives::StorageEntry::new(key, value.value, value.is_private)); } results.push((address, values)); }
diff --git reth/crates/storage/storage-api/Cargo.toml seismic-reth/crates/storage/storage-api/Cargo.toml index e8601e9667d606d89c359d9a5563ff182cee9266..f33a6c7ab57043bce14b34b484b378e3f91454aa 100644 --- reth/crates/storage/storage-api/Cargo.toml +++ seismic-reth/crates/storage/storage-api/Cargo.toml @@ -23,6 +23,7 @@ reth-stages-types.workspace = true reth-storage-errors.workspace = true reth-trie-common.workspace = true revm-database.workspace = true +revm-state.workspace = true reth-ethereum-primitives.workspace = true   # ethereum
diff --git reth/crates/storage/storage-api/src/chain.rs seismic-reth/crates/storage/storage-api/src/chain.rs index 5c66d055e1808ccca8e9534eb6316a4803f396d5..bf761349f3b181fc81f5a637290a1c16e1998cfe 100644 --- reth/crates/storage/storage-api/src/chain.rs +++ seismic-reth/crates/storage/storage-api/src/chain.rs @@ -167,15 +167,16 @@ for (header, transactions) in inputs { // If we are past shanghai, then all blocks should have a withdrawal list, // even if empty - let withdrawals = if chain_spec.is_shanghai_active_at_timestamp(header.timestamp()) { - withdrawals_cursor - .seek_exact(header.number())? - .map(|(_, w)| w.withdrawals) - .unwrap_or_default() - .into() - } else { - None - }; + let withdrawals = + if chain_spec.is_shanghai_active_at_timestamp(header.timestamp_seconds()) { + withdrawals_cursor + .seek_exact(header.number())? + .map(|(_, w)| w.withdrawals) + .unwrap_or_default() + .into() + } else { + None + }; let ommers = if chain_spec.is_paris_active_at_block(header.number()) { Vec::new() } else {
diff --git reth/crates/storage/storage-api/src/lib.rs seismic-reth/crates/storage/storage-api/src/lib.rs index 7b326c6c82e910453e63420e52d4f7fd28807fa6..6bb6439f61f11e9cd509460f316664d63c3881e5 100644 --- reth/crates/storage/storage-api/src/lib.rs +++ seismic-reth/crates/storage/storage-api/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/storage/storage-api/src/noop.rs seismic-reth/crates/storage/storage-api/src/noop.rs index ca66ac6931c6795f66aa4aedd01594d144230fb7..41e71e5fcda63136b2b1fb9ee88350291a8ec32f 100644 --- reth/crates/storage/storage-api/src/noop.rs +++ seismic-reth/crates/storage/storage-api/src/noop.rs @@ -15,7 +15,7 @@ use alloc::{boxed::Box, string::String, sync::Arc, vec::Vec}; use alloy_consensus::transaction::TransactionMeta; use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumberOrTag}; use alloy_primitives::{ - Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, TxNumber, B256, U256, + Address, BlockHash, BlockNumber, Bytes, StorageKey, TxHash, TxNumber, B256, U256, }; use core::{ fmt::Debug, @@ -38,6 +38,7 @@ use reth_trie_common::{ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, MultiProofTargets, StorageMultiProof, StorageProof, TrieInput, }; +use revm_state::FlaggedStorage;   /// Supports various api interfaces for testing purposes. #[derive(Debug)] @@ -494,7 +495,7 @@ fn storage( &self, _account: Address, _storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>> { + ) -> ProviderResult<Option<FlaggedStorage>> { Ok(None) } }
diff --git reth/crates/storage/storage-api/src/state.rs seismic-reth/crates/storage/storage-api/src/state.rs index dc8241fb95f47d4718aed017922df4c6eb3e2215..c8362a08216e4b802781e7061d08ea9f608d9e24 100644 --- reth/crates/storage/storage-api/src/state.rs +++ seismic-reth/crates/storage/storage-api/src/state.rs @@ -5,13 +5,14 @@ }; use alloc::boxed::Box; use alloy_consensus::constants::KECCAK_EMPTY; use alloy_eips::{BlockId, BlockNumberOrTag}; -use alloy_primitives::{Address, BlockHash, BlockNumber, StorageKey, StorageValue, B256, U256}; +use alloy_primitives::{Address, BlockHash, BlockNumber, StorageKey, B256, U256}; use auto_impl::auto_impl; use reth_execution_types::ExecutionOutcome; use reth_primitives_traits::Bytecode; use reth_storage_errors::provider::ProviderResult; use reth_trie_common::HashedPostState; use revm_database::BundleState; +use revm_state::FlaggedStorage;   /// This just receives state, or [`ExecutionOutcome`], from the provider #[auto_impl::auto_impl(&, Arc, Box)] @@ -47,7 +48,7 @@ fn storage( &self, account: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>>; + ) -> ProviderResult<Option<FlaggedStorage>>;   /// Get account code by its address. ///
diff --git reth/crates/storage/zstd-compressors/src/lib.rs seismic-reth/crates/storage/zstd-compressors/src/lib.rs index d7f2b65904d83871e0d74468f06ea0a10ac87103..9c58b21ef9fb6182889555656ca15a2e401e0c40 100644 --- reth/crates/storage/zstd-compressors/src/lib.rs +++ seismic-reth/crates/storage/zstd-compressors/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -106,6 +106,11 @@ // by getting the upper bound and retry the decompression. let mut reserved_upper_bound = false; while let Err(err) = self.decompressor.decompress_to_buffer(src, &mut self.buf) { let err = err.to_string(); + // This panics on malformed/corrupt data (e.g. "Unknown frame descriptor", + // "Dictionary mismatch"). In production this is fine — every DB read goes through + // `Decompress::decompress` (`db-api/src/models/mod.rs`) which wraps `from_compact` in + // `catch_unwind` and converts the panic to `DatabaseError::Decode`. + // See: `db_corruption` fuzz test for validation of this path. assert!( err.contains("Destination buffer is too small"), "Failed to decompress {} bytes: {err}",

Changes to documentation files.

diff --git reth/.claude/prompts/claude-pr-review.md seismic-reth/.claude/prompts/claude-pr-review.md new file mode 100644 index 0000000000000000000000000000000000000000..6ba325a79024c21f0999229a3788e201641382f6 --- /dev/null +++ seismic-reth/.claude/prompts/claude-pr-review.md @@ -0,0 +1,265 @@ +# Claude PR Review Guidelines + +You're a code reviewer helping engineers ship better code on seismic-reth, a privacy-enabled fork of reth. Your feedback should be high-signal: every comment should prevent a bug, improve safety, or teach something valuable. + +Output your review as plain text. Do NOT use `gh pr comment` or any other tool to post comments — the action handles posting. + +**Important:** Your ENTIRE text output becomes the PR comment body. Do not include conversational preamble like "I'll review this PR" or "Let me get the diff." Start directly with your one-line summary of what the PR does. + +## Review Philosophy + +**When in doubt, approve.** Your default is to approve. Only request changes when you are certain something will break. + +**Review the code, not the coder.** Focus on patterns and behavior, not style. + +**Teach through specifics.** Concrete examples beat abstract advice. But only teach when there's a genuine gap — don't explain things the author already knows. + +**Balance teaching with shipping.** Idealism is nice; working software ships. + +## Seismic-Reth Domain Context + +This is a privacy-focused Ethereum execution client forked from reth. The codebase adds confidential transactions, encrypted storage, TEE integration, and custom precompiles. Seismic-specific code lives primarily in `crates/seismic/` with subcrates: `evm`, `primitives`, `rpc`, `txpool`, `payload`, `node`, `cli`, `chainspec`, `hardforks`, `fuzz`. + +### Confidential Transactions (type 0x4a) + +`TxSeismic` is defined in `crates/seismic/primitives/src/transaction/signed.rs`. Each transaction carries `seismic_elements`: +- `encryption_pubkey` (33-byte compressed secp256k1 public key) +- `encryption_nonce` (U96) +- `message_version` (0 or 2) +- `recent_block_hash` (freshness check against `RecentBlockCache`) +- `expires_at_block` (block expiration) +- `signed_read` (bool — whether this is a read authorization) + +Compact codec lives in `crates/storage/codecs/src/alloy/transaction/seismic.rs`. The `to_compact()`/`from_compact()` methods serialize these fields with defensive indexing — codec changes can break backward compatibility with existing stored data. + +RPC conversion from JSON to `TxSeismic` is in `crates/seismic/primitives/src/alloy_compat.rs`. + +### Enclave/TEE & Purpose Keys + +Purpose keys are fetched once at boot from the TEE enclave (`crates/seismic/node/src/enclave.rs`). The `boot_enclave_and_fetch_keys()` function has two modes: +- **Real enclave:** HTTP client connects to the configured endpoint (default `127.0.0.1:7878`) +- **Mock server:** Started via `seismic_enclave::start_mock_server()`, gated behind `--enclave.mock-server` CLI flag (`crates/node/core/src/args/enclave.rs:29`) + +Keys are stored in a global `OnceLock` in `crates/seismic/node/src/purpose_keys.rs` and accessed via `get_purpose_keys()`. The `GetPurposeKeysResponse` contains: +- `tx_io_sk` — **SECRET KEY**, must never be logged or serialized +- `tx_io_pk` — public key, exposed via `seismic_getTeePublicKey` RPC endpoint +- `snapshot_key_bytes` — 32-byte key +- `rng_keypair` — Schnorrkel keypair for RNG precompile + +**Known leak risk:** `SeismicApi` and `EthApiExt` structs (`crates/seismic/rpc/src/eth/ext.rs:53-56, 133-137`) both `#[derive(Debug)]` and hold `GetPurposeKeysResponse` with the secret key. Any `debug!()` or `{:?}` formatting of these structs would leak `tx_io_sk`. Watch for new Debug logging added to these types. + +### Flagged Storage (CLOAD/CSTORE) + +Custom opcodes enforce privacy boundaries: +- `CLOAD` (0xB0): Load from **private** storage only +- `CSTORE` (0xB1): Store to **private** storage only +- Standard `SLOAD`/`SSTORE`: **Public** storage only + +Cross-boundary access fails: SLOAD on a private slot or CLOAD on a public slot returns an error ("invalid private storage access"). This is enforced in seismic-revm (external dep) and tested end-to-end in `crates/seismic/node/tests/e2e/integration.rs:858-1184` with a dedicated test contract. + +### Seismic Precompiles (addresses 100–105) + +All precompiles have signature `fn(&[u8], u64) -> PrecompileResult` and are registered via `SeismicEvmFactory::new_with_purpose_keys()` in `crates/seismic/evm/src/lib.rs:63`. + +| Address | Function | Min Input | Key Edge Case | +|---------|----------|-----------|---------------| +| 100 | RNG | — | Stateful (uses rng_keypair), unlike others | +| 101 | ECDH (`derive_symmetric_key`) | 65 bytes (32B sk + 33B pk) | `.expect("must be 32 bytes")` guarded by length check | +| 102 | AES-GCM encrypt | 44 bytes | `.expect("must be 12 bytes")` guarded by `validate_nonce_length` | +| 103 | AES-GCM decrypt | 60 bytes | Same nonce validation | +| 104 | HKDF | 0 bytes | No minimum; variable length | +| 105 | secp256k1 sign | 64 bytes (32B sk + 32B msg) | `.try_into().unwrap()` guarded by length check | + +Boundary input validation is fuzzed in `crates/seismic/fuzz/tests/precompiles.rs`. + +### Hardforks + +Defined in `crates/seismic/hardforks/src/lib.rs`. All standard Ethereum forks (Frontier through Prague) activate at **Block 0** or **Timestamp 0**. Seismic's `Mercury` hardfork activates at **Timestamp 0**. Chain IDs: mainnet=5123, dev=5124 (see `crates/seismic/chainspec/src/lib.rs`). + +### TxPool Validation + +`RecentBlockCache` (`crates/seismic/txpool/src/recent_block_cache.rs`) stores recent block hashes in a `HashSet` + `VecDeque` with FIFO eviction. The cache is wrapped in `RwLock` in `crates/seismic/txpool/src/validator.rs:28`. + +Lock recovery pattern: `self.recent_blocks.write().unwrap_or_else(|e| e.into_inner())` — handles poisoned locks from prior panics. `on_new_head_block()` writes; `validate_recent_block_hash()` reads. + +### RPC + +Key seismic-specific endpoints in `crates/seismic/rpc/src/eth/ext.rs`: +- `seismic_getTeePublicKey` (line 41-50) — returns `tx_io_pk` +- `eth_call` override (line 108) — decrypts signed reads via `signed_read_to_plaintext_tx()`, executes, re-encrypts +- `eth_sendRawTransaction` override (line 118) — accepts `SeismicRawTxRequest` (encrypted bytes or typed data), kept encrypted in pool +- `eth_estimateGas` override (line 123) — decrypts if seismic, estimates +- `eth_simulateV1` override (line 100) — decrypt/simulate/re-encrypt + +`signed_read_to_plaintext_tx()` lives in `crates/seismic/rpc/src/eth/utils.rs:86-105` — conditionally decrypts using `tx_io_sk`. Errors propagate through `EthApiError`. + +### Clippy Strictness + +Seismic CI enforces `clippy::unwrap_used`, `clippy::expect_used`, `clippy::panic`, `clippy::unreachable`, `clippy::todo` as **errors** in non-test code. Existing `expect()`/`panic!()` calls in production code use explicit `#[allow(...)]` with documented justifications (startup panics in enclave.rs, genesis deserialization in chainspec). New code must follow this pattern. + +## Known Antipatterns + +These patterns are always bugs in Seismic code. Flag them immediately: + +- `ChainSpecBuilder::default()...cancun_activated()` used with `SeismicNode` — must use `SEISMIC_DEV` or `SEISMIC_MAINNET` +- `MAINNET` chain ID in Seismic test code — Seismic has its own chain IDs (mainnet=5123, dev=5124) +- Raw `timestamp` in payload attributes without multiplying by `SEISMIC_TIMESTAMP_MULTIPLIER` (1000) — Seismic uses millisecond timestamps +- Duplicated `ensure_mock_purpose_keys()` — should use the shared helper from `utils.rs` +- `EthereumNode` used where `SeismicNode` is expected in Seismic E2E tests + +## Review Priorities + +### Phase 1: Critical Issues + +Problems that would cause immediate harm: + +- Bugs or logic errors that will hit production +- Security vulnerabilities (injection, auth bypass, secret leakage) +- **Plaintext leaks of shielded values** in logs, errors, Display impls, or RPC responses — especially `debug!()` calls on types containing `seismic_elements` or `purpose_keys` +- **Purpose key exposure** — `tx_io_sk` logged, serialized, or returned via RPC +- **Confidential tx field mishandling** — wrong encryption_nonce, missing pubkey validation, message_version mismatch +- **Flagged storage boundary violations** — SLOAD/SSTORE used where CLOAD/CSTORE is required, or vice versa +- Data corruption or loss risks (especially codec backward compatibility) +- Race conditions in `RwLock<RecentBlockCache>` or other shared state +- Breaking API changes not flagged in the PR description +- **Mock enclave accessible in production** — `--enclave.mock-server` path reachable without the flag +- **Wrong chain spec for node type** — `ChainSpecBuilder::default()...cancun_activated()` or `MAINNET` used with `SeismicNode`. Seismic nodes must use `SEISMIC_DEV` or `SEISMIC_MAINNET` chain specs. +- **Missing timestamp multiplier** — Seismic uses millisecond timestamps. Payload attributes must multiply timestamps by 1000 (use `SEISMIC_TIMESTAMP_MULTIPLIER`). +- **Semantic mismatch** — code that claims to test or set up Seismic functionality but actually uses vanilla Ethereum configuration (wrong chain spec, wrong node type, missing Seismic-specific parameters) + +### Phase 2: Patterns & Principles + +Improvements to maintainability (flag these, but they're rarely blockers): + +- Error handling gaps at system boundaries +- Performance problems with measurable impact +- Hidden dependencies or surprising behaviors +- Missing validation of external input +- Upstream merge friction (unnecessary renames, deleted code that creates conflicts when merging from upstream reth) +- `unwrap()`/`expect()`/`panic!()` in non-test code without `#[allow(...)]` and justification (CI will reject) +- Precompile input validation gaps (missing length checks before `.expect()` or `.unwrap()`) + +### Phase 3: Polish + +Nice-to-haves — mention only if the win is obvious: + +- Dead code, unused imports +- Naming that actively misleads +- A simpler way to express the same logic + +**Ignore:** style preferences covered by formatters/linters (`rustfmt`, `clippy`), missing docs on internal code, test coverage opinions, "consider using X library" suggestions. + +## Decision Framework + +**Request Changes** — Only when you're certain something will break: + +- Bugs that will hit production +- Security vulnerabilities with clear exploit paths +- Data loss or corruption risks +- Plaintext leakage of confidential transaction data or purpose keys + +If you're not 100% certain, don't request changes. + +**Approve** — Your default. Use it when: + +- The code works +- You have suggestions but they're improvements, not blockers +- You're uncertain whether something is actually a problem + +Approve with comments beats comment-only reviews. If it's not worth blocking, it's worth approving. + +## Weighing Existing Context + +Before commenting, check the PR description and existing discussion: + +- **Resolved threads**: Don't re-raise them. +- **Engineer responses**: If they explained why something is intentional, accept it. They have context you don't. +- **Prior approvals**: Your bar for requesting changes should be even higher. + +When engineers push back on feedback, assume they have context you're missing. Don't repeat the same point. + +## Writing Comments + +Be direct and brief. One issue, one to two lines. Include file path and line number. + +**Good:** + +> `crates/seismic/rpc/src/eth/ext.rs:203` — `signed_read_to_plaintext_tx` passes `self.purpose_keys.tx_io_sk` directly. If `plaintext_copy()` errors, the error chain should not include the secret key bytes in its Display impl. + +**Good:** + +> `crates/seismic/rpc/src/eth/transaction.rs:37` — `?recovered` in `debug!()` logs the full `Recovered<SeismicTransactionSigned>`, which includes `seismic_elements` (encryption_pubkey, nonce). Use a custom formatter or log only the tx hash. + +**Good:** + +> `crates/seismic/txpool/src/validator.rs:166` — `on_new_head_block()` takes a write lock on `RecentBlockCache` and calls `self.inner.client().header_by_number()` inside the lock. If that client call blocks, readers in `validate_recent_block_hash()` will starve. + +**Good:** + +> `crates/storage/codecs/src/alloy/transaction/seismic.rs:110` — `from_compact()` changed the field order. Existing encoded data in MDBX uses the old order — this will silently deserialize with swapped fields. + +**Good:** + +> `crates/seismic/payload/src/builder.rs:244` — `.expect("fee is always valid; execution succeeded")` is fine here — matches the existing pattern with `#[allow(clippy::expect_used)]` and documented justification. + +**Too much:** + +> Issue 1: Database Error Handling (Blocking) +> The writer module is using unwrap() on database operations which could... Why this matters: In production, database operations can fail due to... + +Skip headers, emojis, and "Why this matters" sections unless it's genuinely non-obvious. + +## Avoid + +- Filler words: "robust," "comprehensive," "excellent," "well-structured," "solid" +- Summarizing what the PR description already says +- Hedging: "Maybe you could...", "Consider perhaps..." +- Starting with generic praise: "Great job!", "Nice work!" +- Long reviews — if it's more than a few focused paragraphs, you're not sure what actually matters + +## Output Format + +Start with a one-line summary of what the PR does (your own words). + +Then list issues by priority phase. Only include phases that have items: + +``` +Adds encrypted calldata relay for confidential transactions in the payload builder. + +**Phase 1** +- `crates/seismic/payload/src/builder.rs:202` — `debug!("default_seismic_payload: tx: {:?}", tx)` logs the full SeismicTransactionSigned with Debug derive, exposing seismic_elements (encryption_pubkey, nonce) in plaintext. +- `crates/seismic/rpc/src/eth/ext.rs:70` — `seismic_getTeePublicKey` returns `tx_io_pk` unconditionally. If seismic mode is disabled, this should return an error instead of a valid-looking key. + +**Phase 2** +- `crates/storage/codecs/src/alloy/transaction/seismic.rs:85` — New field added to TxSeismicElements compact encoding but `from_compact()` doesn't handle the old format without it. Existing MDBX data will fail to decode. +- `crates/seismic/evm/src/lib.rs:140` — `header.base_fee_per_gas().unwrap_or_default()` is fine (safe fallback), but the new `gas_limit` field uses bare `.unwrap()` without clippy allow. + +**Phase 3** +- `crates/seismic/evm/src/lib.rs:30` — unused import `secp256k1::SecretKey` after refactor. +``` + +If there are no issues worth mentioning, just say "LGTM" and stop. + +## Key Files Reference + +When reviewing changes to these files, pay extra attention: + +| File | Why it's sensitive | +|------|-------------------| +| `crates/seismic/rpc/src/eth/ext.rs` | Holds `tx_io_sk`, derives Debug, all custom RPC endpoints | +| `crates/seismic/rpc/src/eth/utils.rs` | `signed_read_to_plaintext_tx` decryption path | +| `crates/seismic/node/src/enclave.rs` | Mock server gating, purpose key fetch | +| `crates/seismic/node/src/purpose_keys.rs` | Global secret key storage | +| `crates/seismic/payload/src/builder.rs` | Tx logging, fee handling with expect | +| `crates/seismic/primitives/src/transaction/signed.rs` | TxSeismic structure, encoding | +| `crates/storage/codecs/src/alloy/transaction/seismic.rs` | Compact codec, backward compat | +| `crates/seismic/txpool/src/validator.rs` | RwLock on RecentBlockCache | +| `crates/seismic/hardforks/src/lib.rs` | Fork activation, Mercury | +| `crates/seismic/evm/src/lib.rs` | EVM config, precompile registration, purpose keys | +| `crates/storage/libmdbx-rs/mdbx-sys/libmdbx/` | **NEVER modify** — vendored third-party code | + +## Remember + +Your job is to catch real problems and help engineers ship safely. A short review that approves working code is better than a thorough essay that blocks it for theoretical improvements. + +When in doubt, approve.
diff --git reth/README.md seismic-reth/README.md index 869d1e6406c40d6d1e7e5a746152364855da6e03..e301e492a1006f6adbc8da25da5cdb76687061d5 100644 --- reth/README.md +++ seismic-reth/README.md @@ -1,85 +1,36 @@ -# reth +# Seismic Reth   -[![bench status](https://github.com/paradigmxyz/reth/actions/workflows/bench.yml/badge.svg)](https://github.com/paradigmxyz/reth/actions/workflows/bench.yml) -[![CI status](https://github.com/paradigmxyz/reth/workflows/unit/badge.svg)][gh-ci] -[![cargo-lint status](https://github.com/paradigmxyz/reth/actions/workflows/lint.yml/badge.svg)][gh-lint] -[![Telegram Chat][tg-badge]][tg-url] +[![forkdiff](https://github.com/SeismicSystems/seismic-reth/actions/workflows/gh-pages.yml/badge.svg?branch=seismic)](https://seismicsystems.github.io/seismic-reth/) +[![CI Status](https://github.com/SeismicSystems/seismic-reth/actions/workflows/seismic.yml/badge.svg?branch=seismic)](https://github.com/SeismicSystems/seismic-reth/actions/workflows/seismic.yml) +[![Chat on Telegram](https://img.shields.io/badge/chat-Join%20Us-blue?logo=telegram)](https://t.me/+xpzfNO4pmRoyM2Ux)   -**Modular, contributor-friendly and blazing-fast implementation of the Ethereum protocol** +**Encrypted Blockchain Client**   -![](./assets/reth-prod.png) +![](./assets/seismic-reth-beta.png)   -**[Install](https://paradigmxyz.github.io/reth/installation/installation.html)** -| [User Docs](https://reth.rs) +**[Install](https://seismicsystems.github.io/seismic-reth/installation/installation.html)** +| [User Book](https://seismicsystems.github.io/seismic-reth/) | [Developer Docs](./docs) -| [Crate Docs](https://reth.rs/docs) +| [Crate Docs](https://seismicsystems.github.io/seismic-reth/docs/)   -[gh-ci]: https://github.com/paradigmxyz/reth/actions/workflows/unit.yml -[gh-lint]: https://github.com/paradigmxyz/reth/actions/workflows/lint.yml -[tg-badge]: https://img.shields.io/endpoint?color=neon&logo=telegram&label=chat&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fparadigm%5Freth +<!-- [tg-badge]: https://img.shields.io/endpoint?color=neon&logo=telegram&label=chat&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fparadigm%5Freth -->   -## What is Reth? - -Reth (short for Rust Ethereum, [pronunciation](https://twitter.com/kelvinfichter/status/1597653609411268608)) is a new Ethereum full node implementation that is focused on being user-friendly, highly modular, as well as being fast and efficient. Reth is an Execution Layer (EL) and is compatible with all Ethereum Consensus Layer (CL) implementations that support the [Engine API](https://github.com/ethereum/execution-apis/tree/a0d03086564ab1838b462befbc083f873dcf0c0f/src/engine). It is originally built and driven forward by [Paradigm](https://paradigm.xyz/), and is licensed under the Apache and MIT licenses. +## What is Seismic Reth?   ## Goals   -As a full Ethereum node, Reth allows users to connect to the Ethereum network and interact with the Ethereum blockchain. This includes sending and receiving transactions/logs/traces, as well as accessing and interacting with smart contracts. Building a successful Ethereum node requires creating a high-quality implementation that is both secure and efficient, as well as being easy to use on consumer hardware. It also requires building a strong community of contributors who can help support and improve the software. +Seismic Reth extends [Reth](https://github.com/paradigmxyz/reth) with shielded transaction and storage capabilities, allowing users to confidentially interact with smart contracts and transactions on the Seismic network while maintaining compatibility with existing infrastructure. Seismic Reth runs in a Trusted Execution Environment (TEE) for secure communication between users and the Seismic network.   -More concretely, our goals are: +## Seismic features   -1. **Modularity**: Every component of Reth is built to be used as a library: well-tested, heavily documented and benchmarked. We envision that developers will import the node's crates, mix and match, and innovate on top of them. Examples of such usage include but are not limited to spinning up standalone P2P networks, talking directly to a node's database, or "unbundling" the node into the components you need. To achieve that, we are licensing Reth under the Apache/MIT permissive license. You can learn more about the project's components [here](./docs/repo/layout.md). -2. **Performance**: Reth aims to be fast, so we use Rust and the [Erigon staged-sync](https://erigon.substack.com/p/erigon-stage-sync-and-control-flows) node architecture. We also use our Ethereum libraries (including [Alloy](https://github.com/alloy-rs/alloy/) and [revm](https://github.com/bluealloy/revm/)) which we've battle-tested and optimized via [Foundry](https://github.com/foundry-rs/foundry/). -3. **Free for anyone to use any way they want**: Reth is free open source software, built for the community, by the community. By licensing the software under the Apache/MIT license, we want developers to use it without being bound by business licenses, or having to think about the implications of GPL-like licenses. -4. **Client Diversity**: The Ethereum protocol becomes more antifragile when no node implementation dominates. This ensures that if there's a software bug, the network does not finalize a bad block. By building a new client, we hope to contribute to Ethereum's antifragility. -5. **Support as many EVM chains as possible**: We aspire that Reth can full-sync not only Ethereum, but also other chains like Optimism, Polygon, BNB Smart Chain, and more. If you're working on any of these projects, please reach out. -6. **Configurability**: We want to solve for node operators that care about fast historical queries, but also for hobbyists who cannot operate on large hardware. We also want to support teams and individuals who want both sync from genesis and via "fast sync". We envision that Reth will be configurable enough and provide configurable "profiles" for the tradeoffs that each team faces. - -## Status - -Reth is production ready, and suitable for usage in mission-critical environments such as staking or high-uptime services. We also actively recommend professional node operators to switch to Reth in production for performance and cost reasons in use cases where high performance with great margins is required such as RPC, MEV, Indexing, Simulations, and P2P activities. - -More historical context below: - -- We released 1.0 "production-ready" stable Reth in June 2024. - - Reth completed an audit with [Sigma Prime](https://sigmaprime.io/), the developers of [Lighthouse](https://github.com/sigp/lighthouse), the Rust Consensus Layer implementation. Find it [here](./audit/sigma_prime_audit_v2.pdf). - - Revm (the EVM used in Reth) underwent an audit with [Guido Vranken](https://twitter.com/guidovranken) (#1 [Ethereum Bug Bounty](https://ethereum.org/en/bug-bounty)). We will publish the results soon. -- We released multiple iterative beta versions, up to [beta.9](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.9) on Monday June 3, 2024,the last beta release. -- We released [beta](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.1) on Monday March 4, 2024, our first breaking change to the database model, providing faster query speed, smaller database footprint, and allowing "history" to be mounted on separate drives. -- We shipped iterative improvements until the last alpha release on February 28, 2024, [0.1.0-alpha.21](https://github.com/paradigmxyz/reth/releases/tag/v0.1.0-alpha.21). -- We [initially announced](https://www.paradigm.xyz/2023/06/reth-alpha) [0.1.0-alpha.1](https://github.com/paradigmxyz/reth/releases/tag/v0.1.0-alpha.1) on June 20, 2023. - -### Database compatibility - -We do not have any breaking database changes since beta.1, and we do not plan any in the near future. - -Reth [v0.2.0-beta.1](https://github.com/paradigmxyz/reth/releases/tag/v0.2.0-beta.1) includes -a [set of breaking database changes](https://github.com/paradigmxyz/reth/pull/5191) that makes it impossible to use database files produced by earlier versions. - -If you had a database produced by alpha versions of Reth, you need to drop it with `reth db drop` -(using the same arguments such as `--config` or `--datadir` that you passed to `reth node`), and resync using the same `reth node` command you've used before. +See [seismic-features](./docs/seismic/features.md) for a detailed overview of Seismic Reth's new features.   ## For Users   -See the [Reth documentation](https://paradigmxyz.github.io/reth) for instructions on how to install and run Reth. +See the [Seismic Reth Book](https://seismicsystems.github.io/seismic-reth) for instructions on how to install and run Seismic Reth.   ## For Developers   -### Using reth as a library - -You can use individual crates of reth in your project. - -The crate docs can be found [here](https://paradigmxyz.github.io/reth/docs). - -For a general overview of the crates, see [Project Layout](./docs/repo/layout.md). - -### Contributing - -If you want to contribute, or follow along with contributor discussion, you can use our [main telegram](https://t.me/paradigm_reth) to chat with us about the development of Reth! - -- Our contributor guidelines can be found in [`CONTRIBUTING.md`](./CONTRIBUTING.md). -- See our [contributor docs](./docs) for more information on the project. A good starting point is [Project Layout](./docs/repo/layout.md). - ### Building and testing   <!-- @@ -90,28 +41,33 @@ -->   The Minimum Supported Rust Version (MSRV) of this project is [1.88.0](https://blog.rust-lang.org/2025/06/26/Rust-1.88.0/).   -See the docs for detailed instructions on how to [build from source](https://paradigmxyz.github.io/reth/installation/source). +See the book for detailed instructions on how to [build from source](https://seismicsystems.github.io/seismic-reth/installation/source.html).   -To fully test Reth, you will need to have [Geth installed](https://geth.ethereum.org/docs/getting-started/installing-geth), but it is possible to run a subset of tests without Geth. +To fully test Seismic Reth, you will need to have [Geth installed](https://geth.ethereum.org/docs/getting-started/installing-geth), but it is possible to run a subset of tests without Geth.   First, clone the repository:   ```sh -git clone https://github.com/paradigmxyz/reth -cd reth +git clone https://github.com/SeismicSystems/seismic-reth +cd seismic-reth ```   Next, run the tests:   ```sh +# Without Geth cargo nextest run --workspace   -# Run the Ethereum Foundation tests -make ef-tests +# With Geth +cargo nextest run --workspace --features geth-tests + +# With Ethereum Foundation tests +# +# Note: Requires cloning https://github.com/ethereum/tests +# +# cd testing/ef-tests && git clone https://github.com/ethereum/tests ethereum-tests +cargo nextest run -p ef-tests --features ef-tests ``` - -We highly recommend using [`cargo nextest`](https://nexte.st/) to speed up testing. -Using `cargo test` to run tests may work fine, but this is not tested and does not support more advanced features like retries for spurious failures.   > **Note** > @@ -124,12 +80,14 @@ If the answer is not there:   - Join the [Telegram][tg-url] to get help, or -- Open a [discussion](https://github.com/paradigmxyz/reth/discussions/new) with your question, or -- Open an issue with [the bug](https://github.com/paradigmxyz/reth/issues/new?assignees=&labels=C-bug%2CS-needs-triage&projects=&template=bug.yml) +- Open a [discussion](https://github.com/SeismicSystems/seismic-reth/discussions/new) with your question, or +- Open an issue with [the bug](https://github.com/SeismicSystems/seismic-reth/issues/new?assignees=&labels=C-bug%2CS-needs-triage&projects=&template=bug.yml)   ## Security   -See [`SECURITY.md`](./SECURITY.md). +### Report a Vulnerability + +Contact [p@seismic.systems](mailto:p@seismic.systems), [l@seismic.systems](mailto:l@seismic.systems)   ## Acknowledgements   @@ -137,13 +95,7 @@ Reth is a new implementation of the Ethereum protocol. In the process of developing the node we investigated the design decisions other nodes have made to understand what is done well, what is not, and where we can improve the status quo.   None of this would have been possible without them, so big shoutout to the teams below:   -- [Geth](https://github.com/ethereum/go-ethereum/): We would like to express our heartfelt gratitude to the go-ethereum team for their outstanding contributions to Ethereum over the years. Their tireless efforts and dedication have helped to shape the Ethereum ecosystem and make it the vibrant and innovative community it is today. Thank you for your hard work and commitment to the project. -- [Erigon](https://github.com/ledgerwatch/erigon) (fka Turbo-Geth): Erigon pioneered the ["Staged Sync" architecture](https://erigon.substack.com/p/erigon-stage-sync-and-control-flows) that Reth is using, as well as [introduced MDBX](https://github.com/ledgerwatch/erigon/wiki/Choice-of-storage-engine) as the database of choice. We thank Erigon for pushing the state of the art research on the performance limits of Ethereum nodes. -- [Akula](https://github.com/akula-bft/akula/): Reth uses forks of the Apache versions of Akula's [MDBX Bindings](https://github.com/paradigmxyz/reth/pull/132), [FastRLP](https://github.com/paradigmxyz/reth/pull/63) and [ECIES](https://github.com/paradigmxyz/reth/pull/80). Given that these packages were already released under the Apache License, and they implement standardized solutions, we decided not to reimplement them to iterate faster. We thank the Akula team for their contributions to the Rust Ethereum ecosystem and for publishing these packages. +- [Reth](https://github.com/paradigmxyz/reth): We would like to thank the Rust Ethereum community for their pioneering work in building Ethereum clients in Rust. Their dedication to pushing forward Rust implementations has helped pave the way for projects like Reth.   -## Warning - -The `NippyJar` and `Compact` encoding formats and their implementations are designed for storing and retrieving data internally. They are not hardened to safely read potentially malicious data. - -[book]: https://paradigmxyz.github.io/reth/ -[tg-url]: https://t.me/paradigm_reth +[book]: https://seismicsystems.github.io/seismic-reth/ +[tg-url]: https://t.me/+xpzfNO4pmRoyM2Ux
diff --git reth/docs/design/database.md seismic-reth/docs/design/database.md index e0874c215519710b67cab6dbbec6deec972e5663..6fab87d461eaa556134185c57008104610760c8b 100644 --- reth/docs/design/database.md +++ seismic-reth/docs/design/database.md @@ -81,7 +81,7 @@ } PlainStorageState { Address Account "PK" B256 StorageKey "PK" - U256 StorageValue + U256 FlaggedStorage } AccountsHistory { B256 Account "PK"
diff --git reth/docs/repo/ci.md seismic-reth/docs/repo/ci.md index afc2d24a17bc6e3296043edd756016393402ad8a..6a9fed3024c3316603c7ff55c4e9ea6adae69977 100644 --- reth/docs/repo/ci.md +++ seismic-reth/docs/repo/ci.md @@ -4,47 +4,51 @@ The CI runs a couple of workflows:   ### Code   -- **[unit]**: Runs unit tests (tests in `src/`) and doc tests -- **[integration]**: Runs integration tests (tests in `tests/` and sync tests) -- **[bench]**: Runs benchmarks -- **[sync]**: Runs sync tests -- **[stage]**: Runs all `stage run` commands +- **[unit]**: Runs unit tests (tests in `src/`) and doc tests +- **[integration]**: Runs integration tests (tests in `tests/` and sync tests) +- **[bench]**: Runs benchmarks +- **[sync]**: Runs sync tests +- **[stage]**: Runs all `stage run` commands +- **[seismic]**: Runs all Seismic-specific CI   ### Docs   -- **[book]**: Builds, tests, and deploys the book. +- **[book]**: Builds, tests, and deploys the book.   ### Meta -- **[release]**: Runs the release workflow -- **[release-dist]**: Publishes Reth to external package managers -- **[dependencies]**: Runs `cargo update` periodically to keep dependencies current -- **[stale]**: Marks issues as stale if there has been no activity -- **[docker]**: Publishes the Docker image. + +- **[release]**: Runs the release workflow +- **[release-dist]**: Publishes Reth to external package managers +- **[dependencies]**: Runs `cargo update` periodically to keep dependencies current +- **[stale]**: Marks issues as stale if there has been no activity +- **[docker]**: Publishes the Docker image.   ### Integration Testing   -- **[kurtosis]**: Spins up a Kurtosis testnet and runs Assertoor tests on Reth pairs. -- **[hive]**: Runs `ethereum/hive` tests. +- **[kurtosis]**: Spins up a Kurtosis testnet and runs Assertoor tests on Reth pairs. +- **[hive]**: Runs `ethereum/hive` tests.   ### Linting and Checks   -- **[lint]**: Lints code using `cargo clippy` and other checks -- **[lint-actions]**: Lints GitHub Actions workflows -- **[label-pr]**: Automatically labels PRs +- **[lint]**: Lints code using `cargo clippy` and other checks +- **[lint-actions]**: Lints GitHub Actions workflows +- **[label-pr]**: Automatically labels PRs   -[unit]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/unit.yml -[integration]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/integration.yml -[bench]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/bench.yml -[sync]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/sync.yml -[stage]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/stage.yml -[book]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/book.yml -[release]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/release.yml -[release-dist]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/release-dist.yml -[dependencies]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/dependencies.yml -[stale]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/stale.yml -[docker]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/docker.yml -[kurtosis]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/kurtosis.yml -[hive]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/hive.yml -[lint]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/lint.yml -[lint-actions]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/lint-actions.yml -[label-pr]: https://github.com/paradigmxyz/reth/blob/main/.github/workflows/label-pr.yml +[unit]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/unit.yml +[integration]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/integration.yml +[bench]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/bench.yml +[sync]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/sync.yml +[stage]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/stage.yml +[book]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/book.yml +[deny]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/deny.yml +[release]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/release.yml +[release-dist]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/release-dist.yml +[dependencies]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/dependencies.yml +[stale]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/stale.yml +[docker]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/docker.yml +[kurtosis]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/kurtosis.yml +[hive]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/hive.yml +[lint]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/lint.yml +[lint-actions]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/lint-actions.yml +[label-pr]: https://github.com/SeismicSystems/seismic-reth/blob/main/.github/workflows/label-pr.yml +[seismic]: https://github.com/SeismicSystems/seismic-reth/blob/seismic/.github/workflows/seismic.yml
diff --git reth/docs/repo/layout.md seismic-reth/docs/repo/layout.md index 22aae4c3512551b7f8c718b8c051da7177c53484..81e19a9d1ae693a053ca0f0bdb4f42b79ac73236 100644 --- reth/docs/repo/layout.md +++ seismic-reth/docs/repo/layout.md @@ -4,26 +4,26 @@ This repository contains several Rust crates that implement the different building blocks of an Ethereum node. The high-level structure of the repository is as follows:   Generally, reth is composed of a few components, with supporting crates. The main components can be defined as:   -- [Project Layout](#project-layout) - - [Documentation](#documentation) - - [Binaries](#binaries) - - [Storage](#storage) - - [Networking](#networking) - - [Common](#common) - - [Discovery](#discovery) - - [Protocol](#protocol) - - [Downloaders](#downloaders) - - [Consensus](#consensus) - - [Execution](#execution) - - [Sync](#sync) - - [RPC](#rpc) - - [Transports](#transports) - - [Common](#common-1) - - [Utilities Crates](#utilities-crates) - - [Payloads](#payloads) - - [Primitives](#primitives) - - [Optimism](#optimism) - - [Misc](#misc) +- [Project Layout](#project-layout) + - [Documentation](#documentation) + - [Binaries](#binaries) + - [Storage](#storage) + - [Networking](#networking) + - [Common](#common) + - [Discovery](#discovery) + - [Protocol](#protocol) + - [Downloaders](#downloaders) + - [Consensus](#consensus) + - [Execution](#execution) + - [Sync](#sync) + - [RPC](#rpc) + - [Transports](#transports) + - [Common](#common-1) + - [Utilities Crates](#utilities-crates) + - [Payloads](#payloads) + - [Primitives](#primitives) + - [Optimism](#optimism) + - [Misc](#misc)   The supporting crates are split into two categories: [primitives](#primitives) and [miscellaneous](#misc).   @@ -39,12 +39,11 @@ ### Storage   These crates are related to the database.   -- [`storage/codecs`](../../crates/storage/codecs): Different storage codecs. -- [`storage/libmdbx-rs`](../../crates/storage/libmdbx-rs): Rust bindings for [libmdbx](https://libmdbx.dqdkfa.ru). A fork of an earlier Apache-licensed version of [libmdbx-rs][libmdbx-rs]. -- [`storage/db`](../../crates/storage/db): Strongly typed Database abstractions (transactions, cursors, tables) over lower level database backends. - - Implemented backends: mdbx -- [`storage/provider`](../../crates/storage/provider): Traits which provide a higher level api over the database to access the Ethereum state and historical data (transactions, blocks etc.) - +- [`storage/codecs`](../../crates/storage/codecs): Different storage codecs. +- [`storage/libmdbx-rs`](../../crates/storage/libmdbx-rs): Rust bindings for [libmdbx](https://libmdbx.dqdkfa.ru). A fork of an earlier Apache-licensed version of [libmdbx-rs][libmdbx-rs]. +- [`storage/db`](../../crates/storage/db): Strongly typed Database abstractions (transactions, cursors, tables) over lower level database backends. + - Implemented backends: mdbx +- [`storage/provider`](../../crates/storage/provider): Traits which provide a higher level api over the database to access the Ethereum state and historical data (transactions, blocks etc.)   ### Networking   @@ -52,36 +51,36 @@ These crates are related to networking (P2P).   The networking component mainly lives in [`net/network`](../../crates/net/network), which handles:   -- Message egress/ingress -- Peer management -- Session management +- Message egress/ingress +- Peer management +- Session management   #### Common   -- [`net/banlist`](../../crates/net/banlist): A simple peer banlist that can be used to ban peers or IP addresses. - - Contains: Peer banlist. -- [`net/network-api`](../../crates/net/network-api): Contains traits that define the networking component as a whole. Other components that interface with the network stack only need to depend on this crate for the relevant types. -- [`net/nat`](../../crates/net/nat): A small helper crate that resolves the external IP of the running node using various methods (such as a manually provided IP, using UPnP etc.) +- [`net/banlist`](../../crates/net/banlist): A simple peer banlist that can be used to ban peers or IP addresses. + - Contains: Peer banlist. +- [`net/network-api`](../../crates/net/network-api): Contains traits that define the networking component as a whole. Other components that interface with the network stack only need to depend on this crate for the relevant types. +- [`net/nat`](../../crates/net/nat): A small helper crate that resolves the external IP of the running node using various methods (such as a manually provided IP, using UPnP etc.)   #### Discovery   -- [`net/discv4`](../../crates/net/discv4): An implementation of the [discv4][discv4] protocol -- [`net/dns`](../../crates/net/dns): An implementation of node discovery via DNS ([EIP-1459][eip-1459]) +- [`net/discv4`](../../crates/net/discv4): An implementation of the [discv4][discv4] protocol +- [`net/dns`](../../crates/net/dns): An implementation of node discovery via DNS ([EIP-1459][eip-1459])   #### Protocol   -- [`net/eth-wire`](../../crates/net/eth-wire): Implements the `eth` wire protocol and the ``RLPx`` networking stack. -- [`net/ecies`](../../crates/net/ecies): Implementation of the Elliptic Curve Integrated Encryption Scheme used in the ``RLPx`` handshake. +- [`net/eth-wire`](../../crates/net/eth-wire): Implements the `eth` wire protocol and the `RLPx` networking stack. +- [`net/ecies`](../../crates/net/ecies): Implementation of the Elliptic Curve Integrated Encryption Scheme used in the `RLPx` handshake.   #### Downloaders   -- [`net/downloaders`](../../crates/net/downloaders): Traits defining block body and header downloaders, as well as P2P implementations of both. +- [`net/downloaders`](../../crates/net/downloaders): Traits defining block body and header downloaders, as well as P2P implementations of both.   ### Consensus   Different consensus mechanisms.   -- [`consensus/common`](../../crates/consensus/common): Common consensus functions and traits (e.g. fee calculation) +- [`consensus/common`](../../crates/consensus/common): Common consensus functions and traits (e.g. fee calculation)   ### Execution   @@ -96,7 +95,8 @@ ### Sync   These crates implement the main syncing drivers of reth.   -- [`stages`](../../crates/stages): A pipelined sync, including implementation of various stages. This is used during initial sync and is faster than the tree-like structure for longer sync ranges. +- [`blockchain-tree`](../../crates/blockchain-tree): A tree-like structure for handling multiple chains of unfinalized blocks. This is the main component during live sync (i.e. syncing at the tip) +- [`stages`](../../crates/stages): A pipelined sync, including implementation of various stages. This is used during initial sync and is faster than the tree-like structure for longer sync ranges.   ### RPC   @@ -104,17 +104,17 @@ Crates related to the RPC component (including IPC transport)   The RPC component mainly lives in [`rpc/rpc`](../../crates/rpc/rpc), which implements the following namespaces:   -- `admin_` -- `debug_` (includes Geth-style tracing APIs) -- `eth_` -- `net_` -- `trace_` (OpenEthereum-style tracing APIs) -- `txpool_` -- `web3_` +- `admin_` +- `debug_` (includes Geth-style tracing APIs) +- `eth_` +- `net_` +- `trace_` (OpenEthereum-style tracing APIs) +- `txpool_` +- `web3_`   These RPC interface is defined in [`rpc/rpc-api`](../../crates/rpc/rpc-api).   -The engine API ([`engine_`][engine-spec]) lives in [`rpc/rpc-engine-api`](../../crates/rpc/rpc-engine-api) (this is *not* an interface crate despite the confusing name). +The engine API ([`engine_`][engine-spec]) lives in [`rpc/rpc-engine-api`](../../crates/rpc/rpc-engine-api) (this is _not_ an interface crate despite the confusing name).   There is also a crate to easily configure an RPC server: [`rpc/rpc-builder`](../../crates/rpc/rpc-builder).   @@ -126,12 +126,12 @@ The IPC transport lives in [`rpc/ipc`](../../crates/rpc/ipc).   #### Common   -- [`rpc/rpc-api`](../../crates/rpc/rpc-api): RPC traits - - Supported transports: HTTP, WS, IPC - - Supported namespaces: `eth_`, `engine_`, `debug_` -- [`rpc/rpc-eth-api`](../../crates/rpc/rpc-eth-api/): Reth RPC 'eth' namespace API (including interface and implementation), this crate is re-exported by `rpc/rpc-api` -- [`rpc/rpc-eth-types`](../../crates/rpc/rpc-eth-types/): Types `supporting the implementation` of 'eth' namespace RPC server API -- [`rpc/rpc-server-types`](../../crates/rpc/rpc-server-types/): RPC server types and constants +- [`rpc/rpc-api`](../../crates/rpc/rpc-api): RPC traits + - Supported transports: HTTP, WS, IPC + - Supported namespaces: `eth_`, `engine_`, `debug_` +- [`rpc/rpc-eth-api`](../../crates/rpc/rpc-eth-api/): Reth RPC 'eth' namespace API (including interface and implementation), this crate is re-exported by `rpc/rpc-api` +- [`rpc/rpc-eth-types`](../../crates/rpc/rpc-eth-types/): Types `supporting the implementation` of 'eth' namespace RPC server API +- [`rpc/rpc-server-types`](../../crates/rpc/rpc-server-types/): RPC server types and constants   #### Utilities Crates   @@ -143,21 +143,25 @@ ### Payloads   Crates related to building and validating payloads (blocks).   -- [`transaction-pool`](../../crates/transaction-pool): An in-memory pending transactions pool. -- [`payload/builder`](../../crates/payload/builder): Abstractions for payload building and a payload builder service that works with multiple kinds of payload resolvers. -- [`payload/basic`](../../crates/payload/basic): A basic payload generator. +- [`transaction-pool`](../../crates/transaction-pool): An in-memory pending transactions pool. +- [`payload/builder`](../../crates/payload/builder): Abstractions for payload building and a payload builder service that works with multiple kinds of payload resolvers. +- [`payload/basic`](../../crates/payload/basic): A basic payload generator.   ### Primitives   These crates define primitive types or algorithms.   -- [`primitives`](../../crates/primitives): Commonly used types in Reth. -- [`primitives-traits`](../../crates/primitives-traits/): Common abstracted types in reth. -- [`trie`](../../crates/trie): An implementation of a Merkle Patricia Trie used for various roots (e.g. the state root) in Ethereum. +- [`primitives`](../../crates/primitives): Commonly used types in Reth. +- [`primitives-traits`](../../crates/primitives-traits/): Common abstracted types in reth. +- [`trie`](../../crates/trie): An implementation of a Merkle Patricia Trie used for various roots (e.g. the state root) in Ethereum.   ### Optimism   Crates related to the Optimism rollup live in [optimism](../../crates/optimism/). + +### Seismic + +-   ### Misc
diff --git reth/docs/seismic/features.md seismic-reth/docs/seismic/features.md new file mode 100644 index 0000000000000000000000000000000000000000..ae4b7ff36ca3a2744eaa3ad2e9f32d9a47a60a29 --- /dev/null +++ seismic-reth/docs/seismic/features.md @@ -0,0 +1,283 @@ +# Shielded Enhancements for Seismic Reth <!-- omit in toc --> + +### Introduction <!-- omit in toc --> + +Welcome to the documentation for the shielded enhancements added to **Seismic Reth**, the execution layer of the Seismic blockchain. These enhancements introduce shielded storage and transaction capabilities, enabling developers to handle sensitive data securely within smart contracts and transactions. By building upon the existing Reth infrastructure, we've implemented changes to ensure ease of adoption and maintain compatibility. + +This documentation highlights the differences and new features introduced, with a focus on the modifications that make Reth shielded. We recommend familiarizing yourself with the standard Reth documentation alongside this guide. + +--- + +### Table of Contents <!-- omit in toc --> + +- [1. Overall Changes](#1-overall-changes) +- [2. Shielded Storage](#2-shielded-storage) + - [2.1 Shielded Storage Flag](#21-shielded-storage-flag) + - [2.2 State Root Calculation](#22-state-root-calculation) + - [2.3 `eth_storageAt` RPC Modification](#23-eth_storageat-rpc-modification) + - [2.4 Storage Hashing Parallelization](#24-storage-hashing-parallelization) +- [3. Shielded Transactions](#3-shielded-transactions) + - [3.1 Transaction Flow Overview](#31-transaction-flow-overview) + - [_eth\_sendRawTransaction_ Flow](#eth_sendrawtransaction-flow) + - [_eth\_call_ Flow](#eth_call-flow) + - [3.2 Cryptography Client and Arguments](#32-cryptography-client-and-arguments) + - [3.3 `TxSeismic` Transaction Type](#33-txseismic-transaction-type) + - [3.4 `ConfigureEvmEnv` and `EthEvmConfig` Changes](#34-configureevmenv-and-ethevmconfig-changes) + - [3.5 RPC Method Changes](#35-rpc-method-changes) +- [4. Support for `seismic-revm`'s `Mercury` Specification](#4-support-for-seismic-revms-mercury-specification) + - [4.1 Seismic Chain Spec](#41-seismic-chain-spec) + - [4.2 `rng_mode` Initialization](#42-rng_mode-initialization) +- [5. RPC Modifications](#5-rpc-modifications) + - [5.1 Summary of Modified Endpoints](#51-summary-of-modified-endpoints) +- [6. Backup Mechanism](#6-backup-mechanism) +- [7. Performance Testing](#7-performance-testing) +- [8. Testing](#8-testing) + - [8.1 Running Tests](#81-running-tests) + - [8.2 Modifications of existing tests](#82-modifications-of-existing-tests) + - [8.3 Integration Testing](#83-integration-testing) + - [8.4 Ethereum Package Testing](#84-ethereum-package-testing) +- [9. Future Considerations](#9-future-considerations) +--- + +### 1. Overall Changes + +We have introduced several changes to make Reth encrypted, enabling shielded storage and transactions. The key modifications include: + +- **Shielded Storage**: Added an `is_private` flag to storage values, changing the storage value type from `U256` to `FlaggedStorage`. +- **Shielded Transaction**: Providing a new transaction type `TxSeismic` that extends the existing transaction and supports shielded input. + +--- + +### 2. Shielded Storage + +#### 2.1 Shielded Storage Flag + +Previously, storage values were of type `U256`. With the encryption enhancements, we've introduced a new type called `FlaggedStorage`, which includes an `is_private` flag to indicate whether a storage value is confidential. + +- **Implementation**: This change aligns with modifications in `seismic-revm` ([Pull Request #9](https://github.com/SeismicSystems/seismic-revm/pull/9)) and requires the use of REVM inspectors ([Pull Request #1](https://github.com/SeismicSystems/seismic-revm-inspectors/pull/1)). + +#### 2.2 State Root Calculation + +- **Modification**: The `is_private` flag is **not** encoded during the state root calculation. This decision is reflected in the code [here](https://github.com/SeismicSystems/seismic-reth/pull/4/commits/5a69f1ea359d4e95dd6a825e604548b0e11579#diff-a69280a7601140010b48c98e07c58431efd9e6f45180dcfcd2e0d423e4588a98R162). +- **Consideration**: We may want to include the `is_private` flag as part of the state since a storage slot can transition from public to private. This is an open point for future development. + +#### 2.3 `eth_storageAt` RPC Modification + +- **Behavior**: Modified the `eth_storageAt` RPC method to handle private storage. + - If `is_private` is `true`, the RPC call returns `0`. +- **Rationale**: + - **Prevent Information Leakage**: Since storage can transition from private to public, exposing the storage type could leak information through enumeration. + - **Potentially Misleading Data**: Returning `0` might be misleading if there is a value being stored. Developers should be aware of this behavior. +- **Code Reference**: [Commit](https://github.com/SeismicSystems/seismic-reth/pull/4/commits/f26de3b8ff74a4b23de0df548c8b629c2479d907) +- **Impact**: For a complete set of code paths affected, refer to all places where `encode_fixed_size()` is called. + +#### 2.4 Storage Hashing Parallelization + +- **Modification**: We include the `is_private` flag along with `addr_key` as the key instead of combining it with the value during parallelization of the `StorageHashingStage`. +- **Code Reference**: `seismic-reth/crates/stages/stages/src/stages/hashing_storage.rs:106` + +--- + +### 3. Shielded Transactions + +The inputs of a shielded transaction are encrypted and can only be decrypted with a secret key from a secure enclave. Encryption and decryption logic happens outside of Seismic Reth and inside the [cryptography server](https://github.com/SeismicSystems/teeservice). We added modifications to support the communications with the cryptography server and shielded transaction processing. + +#### 3.1 Transaction Flow Overview + +##### _eth_sendRawTransaction_ Flow + +1. **Client-side Encryption**: + + - Client generates an ephemeral key pair + - Uses ephemeral private key + network's public key to generate shared secret via ECDH + - Encrypts transaction calldata using shared secret + - Includes ephemeral public key in transaction as `encryption_pubkey` + - Can submit transaction in two ways: + - Raw transaction bytes (message_version = 0) + - EIP-712 typed data (message_version = 2) + +2. **Network Processing**: + - Seismic Reth receives encrypted transaction + - Uses network private key + transaction's `encryption_pubkey` to regenerate shared secret + - Decrypts calldata before EVM execution + - Processes transaction normally after decryption + +##### _eth_call_ Flow + +1. **Client-side Encryption**: + + - Client generates an ephemeral key pair + - Uses ephemeral private key + network's public key to generate shared secret via ECDH + - Encrypts transaction calldata using shared secret + - Includes ephemeral public key in transaction as `encryption_pubkey` + - Can submit transaction in two ways: + - Raw transaction bytes (message_version = 0) + - EIP-712 typed data (message_version = 2) + +2. **Network Processing**: + + - Seismic Reth receives encrypted transaction + - Uses network private key + transaction's `encryption_pubkey` to regenerate shared secret + - Decrypts calldata before EVM execution + - Simulates transaction normally after decryption + - Encrypts simulation output using the shared secret + +3. **Client-side Decryption**: + - Uses ephemeral private key + network's public key to generate shared secret via ECDH + - Decrypts simulation output using shared secret + +#### 3.2 Cryptography Client and Arguments + +- **Functionality**: Decryption occurs when the EVM initializes with the corresponding transaction, ensuring that the input data remains confidential until execution. Encryption and decryption logic lives in an external cryptography server so that sensitive information can be separated from Seismic Reth. +- **Addition**: Implemented a client for the cryptography server and arguments to interact with a server for decryption and encryption tasks. + +#### 3.3 `TxSeismic` Transaction Type + +- **Definition**: Introduced `TxSeismic`, which defines fields for seismic transactions. In this transaction type, only the `input` field is encrypted. + +The `TxSeismic` transaction type contains the following fields: + +- `chain_id`: Chain identifier for replay attack protection (EIP-155) +- `nonce`: Number of transactions sent by the sender (Tn) +- `gas_price`: Amount of Wei to be paid per unit of gas for computation costs (Tp). Uses u128 since max Ethereum circulation of ~120M ETH is well within bounds +- `gas_limit`: Maximum amount of gas allowed for transaction execution (Tg). Must be paid upfront and cannot be increased +- `to`: 160-bit recipient address for message calls, or empty (∅) for contract creation (Tt) +- `value`: Amount of Wei to transfer to recipient or endow to new contract (Tv) +- `encryption_pubkey`: 33-byte public key used to encrypt transaction output +- `message_version`: Version number of the message format to support EIP-712 `TypedData` +- `input`: Variable length byte array containing encrypted input + +#### 3.4 `ConfigureEvmEnv` and `EthEvmConfig` Changes + +Extended `ConfigureEvmEnv` trait and `EthEvmConfig` implementation to integrate encryption/decryption capabilities. The `fill_tx_env` method was modified to handle `TxSeismic` transactions by performing input decryption prior to EVM execution, enabling shielded transaction processing. + +#### 3.5 RPC Method Changes + +- **Modified Methods** + + - `eth_sendTransaction` + - `eth_sendRawTransaction` + - `eth_call` + - `eth_estimateGas` + + to support shielded transactions + +### 4. Support for `seismic-revm`'s `Mercury` Specification + +#### 4.1 Seismic Chain Spec + +If chain spec is `SEISMIC_MAINNET` (chain id is 5123) or `SEISMIC_DEV` (chain id is 5124), the `Mercury` spec of EVM is used. + +#### 4.2 `rng_mode` Initialization + +Depending + +### 5. RPC Modifications + +#### 5.1 Summary of Modified Endpoints + +We have modified several RPC endpoints to support shielded features: + +- **Modified _eth_ RPC Methods**: + + - **`eth_storageAt`**: + - Returns `0` for private storage slots. + - **Modification Location**: [Code Reference](https://github.com/SeismicSystems/seismic-reth/pull/4/commits/f26de3b8ff74a4b23de0df548c8b629c2479d907) + - **`eth_sendTransaction`**: + - Accepts `TxSeismic` transaction type and input encryption + - **`eth_sendRawTransaction`**: + - Accepts both raw seismic transactions (`Bytes`) and EIP-712 typed data with signatures (`TypedDataRequest`) + - **`eth_call`**: + - Accepts three types of shielded transaction format: + - `TransactionRequest`: Standard transaction call request with additional fields. Since this format of request is unsigned, `msg.sender` is overridden to `None` + - `TypedData`: EIP-712 signed typed message with signature + - `Bytes`: Raw signed seismic transaction bytes + - **`eth_estimateGas`**: + - Accepts three types of shielded transaction format: + - `TransactionRequest`: Standard transaction call request with additional fields. Since this format of request is unsigned, `msg.sender` is overridden to `None` + +- **SeismicAPI RPC Endpoints** + + - **`seismic_getTeePublicKey`**: + - Returns the network public key for client-side encryption when constructing shielded input + +--- + +### 6. Backup Mechanism + +- **Feature**: Seismic Reth saves the database state every time it reaches a certain canonical block production, controlled by the `DEFAULT_BACKUP_THRESHOLD` parameter. +- **Consideration**: This feature requires further specification depending on how the consensus layer interacts with Seismic Reth for accurate block counting. +- **Purpose**: Enables state snapshots at defined intervals, which can be crucial for recovery. + +--- + +### 7. Performance Testing + +We conducted end-to-end tests for the above changes. The performance metrics are as follows: + +| **Block Time with HTTP Request** | **0 Calls** | **1400 Calls** | **5200 Calls** | +| -------------------------------- | ------------- | -------------- | -------------- | +| **1400 Normal Transactions** | 2.018 seconds | 5.273 seconds | 10.257 seconds | +| **1400 Encrypted Transactions** | 6.601 seconds | 11.523 seconds | 21.790 seconds | + +- **Observation**: The HTTP call latency contributes approximately **40%** of the total latency. +- **Note**: These tests include end-to-end scenarios, demonstrating the overhead introduced by the encryption and decryption processes. + +--- + +### 8. Testing + +#### 8.1 Running Tests + +To ensure the integrity of the shielded enhancements, you can run end-to-end tests using the following command: + +```bash +cargo nextest run --workspace +``` + +For the backup-specific e2e test: + +```bash +RUST_BACKTRACE=1 RUST_LOG=trace cargo test --package reth-node-ethereum --test e2e -- backup::backup --exact --show-output --nocapture +``` + +#### 8.2 Modifications of existing tests + +**Note**: We ignore certain tests by default in `nextest.toml`: + +- `providers::static_file::tests::test_header_truncation` +- `providers::static_file::tests::test_tx_based_truncation` +- `eth::core::tests` + +For shielded transaction, + +For shielded storage, we've modified: + +- `reth-provider writer::tests::write_to_db_storage` to verify that the `is_private` flag is committed to the database from the EVM execution outcome. +- `reth-trie state::tests::hashed_state_wiped_extension` to ensure that the `is_private` flag is propagated from `hashedStorages` to `postHashedStorages`. + +Because we have a decryption call for `TxSeismic` call, `#[tokio::test(flavor = "multi_thread")]` replaces `#[tokio::test]` to provide runtime async support. + +#### 8.3 Integration Testing + +See the `crates/seismic/node/tests/integration.rs` examples of integration testing using seismic transactions. + +#### 8.4 Ethereum Package Testing + +We added a `TxSeismic` spammer for Ethereum Package testing. For specific instruction see this [PR](https://github.com/SeismicSystems/seismic-reth/pull/49) + +--- + +### 9. Future Considerations + +There are several areas that require attention and potential future development: + +1. **Witness Auditing**: + + - **Action**: The `witness()` function needs to be audited to ensure it correctly handles private data. + - **Importance**: To prevent potential leaks or mishandling of confidential information. + +2. **RPC Method Enhancements**: + - **Encrypted Events and Data**: Future improvements may include supporting encrypted events, enabling the emission of shielded data without compromising confidentiality. + - **_eth_simulate_v1_**: support endpoint for shielded transactions + - **_debug\_\*_ _trace\_\*_**: support endpoints for shielded data with redaction
diff --git reth/docs/vocs/docs/pages/cli/reth.mdx seismic-reth/docs/vocs/docs/pages/cli/reth.mdx index 88218426c7ad4e043f4fb45e453354fa959c4269..9cd2530e57122f2ac64f577cc7eb2afab34ad017 100644 --- reth/docs/vocs/docs/pages/cli/reth.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth.mdx @@ -1,12 +1,13 @@ # reth   -Reth +Seismic Reth   ```bash -$ reth --help +$ seismic-reth --help ``` + ```txt -Usage: reth [OPTIONS] <COMMAND> +Usage: seismic-reth [OPTIONS] <COMMAND>   Commands: node Start the node @@ -114,4 +115,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/config.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/config.mdx index b449f118168d3725a297ae8cdc3b7ca1e8776a66..836432bd7d7746c4cb114b7ef67b0dc053ce9a88 100644 --- reth/docs/vocs/docs/pages/cli/reth/config.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/config.mdx @@ -5,8 +5,9 @@ ```bash $ reth config --help ``` + ```txt -Usage: reth config [OPTIONS] +Usage: seismic-reth config [OPTIONS]   Options: --config <FILE> @@ -99,4 +100,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/checksum.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/checksum.mdx index ba12fd1b2f55fd86c3932fe85fc1f7864e021735..b8c4b2a0ecc2a150364a23484c238923245312ef 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/checksum.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/checksum.mdx @@ -5,8 +5,9 @@ ```bash $ reth db checksum --help ``` + ```txt -Usage: reth db checksum [OPTIONS] <TABLE> +Usage: seismic-reth db checksum [OPTIONS] <TABLE>   Arguments: <TABLE> @@ -116,4 +117,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/clear.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/clear.mdx index 79e324021bfcdf0c5b50e018a81a24dcf0a1deb4..61e3b1b53abc88fe700b35d3c4aa455257f7e0f5 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/clear.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/clear.mdx @@ -5,8 +5,9 @@ ```bash $ reth db clear --help ``` + ```txt -Usage: reth db clear [OPTIONS] <COMMAND> +Usage: seismic-reth db clear [OPTIONS] <COMMAND>   Commands: mdbx Deletes all database table entries @@ -108,4 +109,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/clear/mdbx.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/clear/mdbx.mdx index 843f5253c9a96633351c8d6215f0b5af8119c537..f26de206f96ebbb1f4ef4f07fdb644e2efc05d42 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/clear/mdbx.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/clear/mdbx.mdx @@ -5,8 +5,9 @@ ```bash $ reth db clear mdbx --help ``` + ```txt -Usage: reth db clear mdbx [OPTIONS] <TABLE> +Usage: seismic-reth db clear mdbx [OPTIONS] <TABLE>   Arguments: <TABLE> @@ -107,4 +108,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/clear/static-file.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/clear/static-file.mdx index 3af272ff36294756be163b25100396911b57757b..f2b4ff6638a1ddbfe96da01b9e28fa01c0a9efa3 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/clear/static-file.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/clear/static-file.mdx @@ -5,8 +5,9 @@ ```bash $ reth db clear static-file --help ``` + ```txt -Usage: reth db clear static-file [OPTIONS] <SEGMENT> +Usage: seismic-reth db clear static-file [OPTIONS] <SEGMENT>   Arguments: <SEGMENT> @@ -110,4 +111,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/diff.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/diff.mdx index f440545f1298612f0aae83bbc1f5dabc06cf1f0d..d7fef146bcb78ee8abe3cb6f463854e6a4c4c98d 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/diff.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/diff.mdx @@ -5,8 +5,9 @@ ```bash $ reth db diff --help ``` + ```txt -Usage: reth db diff [OPTIONS] --secondary-datadir <SECONDARY_DATADIR> --output <OUTPUT> +Usage: seismic-reth db diff [OPTIONS] --secondary-datadir <SECONDARY_DATADIR> --output <OUTPUT>   Options: --secondary-datadir <SECONDARY_DATADIR> @@ -143,4 +144,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/drop.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/drop.mdx index 64552318a21cd71147f743af402f94ae1bc555be..7eb62f4fcdf1d1610c542e6c49cdc09aa39060d2 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/drop.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/drop.mdx @@ -5,8 +5,9 @@ ```bash $ reth db drop --help ``` + ```txt -Usage: reth db drop [OPTIONS] +Usage: seismic-reth db drop [OPTIONS]   Options: -f, --force @@ -106,4 +107,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/get.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/get.mdx index c7fc831b764daf3666c79e96eaed18ff7448e62c..adc6d48f33148d10ee7f702f63ef7dcc0915945b 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/get.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/get.mdx @@ -5,8 +5,9 @@ ```bash $ reth db get --help ``` + ```txt -Usage: reth db get [OPTIONS] <COMMAND> +Usage: seismic-reth db get [OPTIONS] <COMMAND>   Commands: mdbx Gets the content of a database table for the given key @@ -108,4 +109,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/get/mdbx.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/get/mdbx.mdx index 48fd6c889c6e01dad7739e59142300a93239a20e..345a29021b65a67fcba4bcf3f1ede22d25a0673d 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/get/mdbx.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/get/mdbx.mdx @@ -5,8 +5,9 @@ ```bash $ reth db get mdbx --help ``` + ```txt -Usage: reth db get mdbx [OPTIONS] <TABLE> <KEY> [SUBKEY] +Usage: seismic-reth db get mdbx [OPTIONS] <TABLE> <KEY> [SUBKEY]   Arguments: <TABLE> @@ -116,4 +117,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/get/static-file.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/get/static-file.mdx index af21819a452c25c9a96b3f7b0ecaf2b16eadc55d..e405caa12124013584c76adb60e86a6552f47d1a 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/get/static-file.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/get/static-file.mdx @@ -5,8 +5,9 @@ ```bash $ reth db get static-file --help ``` + ```txt -Usage: reth db get static-file [OPTIONS] <SEGMENT> <KEY> +Usage: seismic-reth db get static-file [OPTIONS] <SEGMENT> <KEY>   Arguments: <SEGMENT> @@ -116,4 +117,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/list.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/list.mdx index cff6c7eed5e3883bd87d4fb9ceb7ea8083035e0d..86db3cc8522c0de113e867a48fa3ddd306d3903f 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/list.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/list.mdx @@ -5,8 +5,9 @@ ```bash $ reth db list --help ``` + ```txt -Usage: reth db list [OPTIONS] <TABLE> +Usage: seismic-reth db list [OPTIONS] <TABLE>   Arguments: <TABLE> @@ -149,4 +150,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/path.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/path.mdx index 1dd3279a79783c9dfa6410192234367fa906be7a..3e9d044c12b2900827cdb8d07767b3e48595c558 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/path.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/path.mdx @@ -5,8 +5,9 @@ ```bash $ reth db path --help ``` + ```txt -Usage: reth db path [OPTIONS] +Usage: seismic-reth db path [OPTIONS]   Options: -h, --help @@ -103,4 +104,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/stats.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/stats.mdx index 1f2c50908dccd2af0b20552d7d2cd609def77bf7..65d572a3b02b534c1f0a16cec4b761b273bc6e87 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/stats.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/stats.mdx @@ -5,8 +5,9 @@ ```bash $ reth db stats --help ``` + ```txt -Usage: reth db stats [OPTIONS] +Usage: seismic-reth db stats [OPTIONS]   Options: --detailed-sizes @@ -116,4 +117,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/db/version.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/db/version.mdx index a683749fcdf83b2eaaf585bd466f5b72bcd085b9..b64098def54a51c0bc777d01b276ec67927fc214 100644 --- reth/docs/vocs/docs/pages/cli/reth/db/version.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/db/version.mdx @@ -5,8 +5,9 @@ ```bash $ reth db version --help ``` + ```txt -Usage: reth db version [OPTIONS] +Usage: seismic-reth db version [OPTIONS]   Options: -h, --help @@ -103,4 +104,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/debug.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/debug.mdx index f56a60aa941d20605f526cc17d63ebe2dfe76784..ea27b5ce8ae00462f0ba2a5b970e43785854da5d 100644 --- reth/docs/vocs/docs/pages/cli/reth/debug.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/debug.mdx @@ -5,8 +5,9 @@ ```bash $ reth debug --help ``` + ```txt -Usage: reth debug [OPTIONS] <COMMAND> +Usage: seismic-reth debug [OPTIONS] <COMMAND>   Commands: merkle Debug the clean & incremental state root calculations @@ -93,4 +94,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/download.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/download.mdx index 973dce74a2284f1ff2881e8e8c9954fd37c10b94..9702bd76765f15bbcf78b14d1fd666b0079f01ce 100644 --- reth/docs/vocs/docs/pages/cli/reth/download.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/download.mdx @@ -5,8 +5,9 @@ ```bash $ reth download --help ``` + ```txt -Usage: reth download [OPTIONS] +Usage: seismic-reth download [OPTIONS]   Options: -h, --help @@ -161,4 +162,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/dump-genesis.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/dump-genesis.mdx index 6bc27381a24beb792a50cbe18ff5437bf461ad7a..01df327f8162bd4a460a1288f616373ffd4dc469 100644 --- reth/docs/vocs/docs/pages/cli/reth/dump-genesis.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/dump-genesis.mdx @@ -5,8 +5,9 @@ ```bash $ reth dump-genesis --help ``` + ```txt -Usage: reth dump-genesis [OPTIONS] +Usage: seismic-reth dump-genesis [OPTIONS]   Options: --chain <CHAIN_OR_PATH> @@ -102,4 +103,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/import-era.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/import-era.mdx index a783067d1936633e37307c9ac3427e8a8ac172ef..dfbaa21d07ebec2bc34dd27ca428fab6e51859db 100644 --- reth/docs/vocs/docs/pages/cli/reth/import-era.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/import-era.mdx @@ -5,8 +5,9 @@ ```bash $ reth import-era --help ``` + ```txt -Usage: reth import-era [OPTIONS] +Usage: seismic-reth import-era [OPTIONS]   Options: -h, --help @@ -162,4 +163,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/import.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/import.mdx index 0914444e1085e64591f47ac2733faa494eb9d740..c7f2a762721a885c90f8a3edcb5bd49c4212a722 100644 --- reth/docs/vocs/docs/pages/cli/reth/import.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/import.mdx @@ -5,8 +5,9 @@ ```bash $ reth import --help ``` + ```txt -Usage: reth import [OPTIONS] <IMPORT_PATH>... +Usage: seismic-reth import [OPTIONS] <IMPORT_PATH>...   Options: -h, --help @@ -163,4 +164,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/init-state.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/init-state.mdx index 8c0cfa6e4d3157e6dab21daa36b0a692e0dbd7d2..dcbb6aded2bd275cf5579ab4f0b244bcfb8ef4ec 100644 --- reth/docs/vocs/docs/pages/cli/reth/init-state.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/init-state.mdx @@ -5,8 +5,9 @@ ```bash $ reth init-state --help ``` + ```txt -Usage: reth init-state [OPTIONS] <STATE_DUMP_FILE> +Usage: seismic-reth init-state [OPTIONS] <STATE_DUMP_FILE>   Options: -h, --help @@ -186,4 +187,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/init.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/init.mdx index b1ac27e8ba713b095ca5ec144f0674a71a6c21e1..17a2b5ed3dd087533ecc481e84f141bdfec98f60 100644 --- reth/docs/vocs/docs/pages/cli/reth/init.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/init.mdx @@ -5,8 +5,9 @@ ```bash $ reth init --help ``` + ```txt -Usage: reth init [OPTIONS] +Usage: seismic-reth init [OPTIONS]   Options: -h, --help @@ -151,4 +152,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/node.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/node.mdx index cbfaa615bbb332cf0995626bd247338b9f933802..abfbbd69f0b723ca5ffbfc96c585625dd5315d53 100644 --- reth/docs/vocs/docs/pages/cli/reth/node.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/node.mdx @@ -1,12 +1,13 @@ -# reth node +# seismic-reth node   Start the node   ```bash -$ reth node --help +$ seismic-reth node --help ``` + ```txt -Usage: reth node [OPTIONS] +Usage: seismic-reth node [OPTIONS]   Options: --config <FILE> @@ -17,9 +18,9 @@ The chain this node is running. Possible values are either a built-in chain or the path to a chain specification file.   Built-in chains: - mainnet, sepolia, holesky, hoodi, dev + seismic, dev   - [default: mainnet] + [default: seismic]   --instance <INSTANCE> Add a new instance of a node. @@ -951,7 +952,22 @@ - always: Colors on - auto: Colors on - never: Colors off   - [default: always] +Trusted Execution Environment Server: + The TEE Server provides secure encryption/decryption services for TxSeismic transactions in an isolated environment. Required for processing encrypted TxSeismic transaction data. + + --enclave.endpoint-addr <ADDR> + TEE server address to listen on + + [default: 127.0.0.1] + + --enclave.endpoint-port <PORT> + TEE server port to listen on + + [default: 8545] + + --enclave.mock-server + Spin up mock TEE service for testing purpose at [--enclave.endpoint-addr]:[--enclave.endpoint-port] +   Display: -v, --verbosity... @@ -965,4 +981,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/p2p/body.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/body.mdx index b089ccc7e8e1680119a8c940b3286d8f9c11cd51..fbf76c40127efae370f47650b4c2cc3d1c65ee20 100644 --- reth/docs/vocs/docs/pages/cli/reth/p2p/body.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/body.mdx @@ -5,8 +5,9 @@ ```bash $ reth p2p body --help ``` + ```txt -Usage: reth p2p body [OPTIONS] <ID> +Usage: seismic-reth p2p body [OPTIONS] <ID>   Options: --retries <RETRIES> @@ -314,4 +315,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/p2p/header.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/header.mdx index d308589bb700ed334d654b5ef9f3570b887dae00..be8be12b19d5aed1ab14485ac6953573af53e013 100644 --- reth/docs/vocs/docs/pages/cli/reth/p2p/header.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/header.mdx @@ -5,8 +5,9 @@ ```bash $ reth p2p header --help ``` + ```txt -Usage: reth p2p header [OPTIONS] <ID> +Usage: seismic-reth p2p header [OPTIONS] <ID>   Options: --retries <RETRIES> @@ -314,4 +315,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx.mdx index dbd7ca91b341c5480b274d58745dcc992ea17f72..f48fb951caea65defdf4401c8d52dd63b04a7ded 100644 --- reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx.mdx @@ -5,8 +5,9 @@ ```bash $ reth p2p rlpx --help ``` + ```txt -Usage: reth p2p rlpx [OPTIONS] <COMMAND> +Usage: seismic-reth p2p rlpx [OPTIONS] <COMMAND>   Commands: ping ping node @@ -97,4 +98,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx/ping.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx/ping.mdx index ac123d472852d3ca0fbe36f83fec85cd43ed5da3..965197ca7b4b1019744b01c3a5ef3d046c2e3555 100644 --- reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx/ping.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/p2p/rlpx/ping.mdx @@ -5,8 +5,9 @@ ```bash $ reth p2p rlpx ping --help ``` + ```txt -Usage: reth p2p rlpx ping [OPTIONS] <NODE> +Usage: seismic-reth p2p rlpx ping [OPTIONS] <NODE>   Arguments: <NODE> @@ -97,4 +98,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/prune.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/prune.mdx index ce6bc399d8ee79e501d9ef753a45939345764a3b..74834bdfabed3bf764599a6f47eb88d6251c0f8c 100644 --- reth/docs/vocs/docs/pages/cli/reth/prune.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/prune.mdx @@ -5,8 +5,9 @@ ```bash $ reth prune --help ``` + ```txt -Usage: reth prune [OPTIONS] +Usage: seismic-reth prune [OPTIONS]   Options: -h, --help @@ -151,4 +152,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/recover.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/recover.mdx index 880b8482d01a3e8b41fe5a7b4bbc9998b0342bdb..5d228dd6394f06b2ac3740a18e3d04e646fdc9fb 100644 --- reth/docs/vocs/docs/pages/cli/reth/recover.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/recover.mdx @@ -5,8 +5,9 @@ ```bash $ reth recover --help ``` + ```txt -Usage: reth recover [OPTIONS] <COMMAND> +Usage: seismic-reth recover [OPTIONS] <COMMAND>   Commands: storage-tries Recover the node by deleting dangling storage tries @@ -97,4 +98,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/recover/storage-tries.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/recover/storage-tries.mdx index 701dd393686c43ef195c81dc8b84f4563dd92cfe..26a12895ae63dd0d50965eee10315bb882405dc2 100644 --- reth/docs/vocs/docs/pages/cli/reth/recover/storage-tries.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/recover/storage-tries.mdx @@ -5,8 +5,9 @@ ```bash $ reth recover storage-tries --help ``` + ```txt -Usage: reth recover storage-tries [OPTIONS] +Usage: seismic-reth recover storage-tries [OPTIONS]   Options: -h, --help @@ -151,4 +152,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage.mdx index bc693f7e463a6e5d52db7291b13d94282fa18458..49c617a7e59e75402ae788948044689ee8dbc3ba 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage --help ``` + ```txt -Usage: reth stage [OPTIONS] <COMMAND> +Usage: seismic-reth stage [OPTIONS] <COMMAND>   Commands: run Run a single stage @@ -100,4 +101,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/drop.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/drop.mdx index a36545638cec07cca1dc0237b66a3a8b42aef2ba..abb2be0e28a01d4f62540021ea70b8c64f7f3c70 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/drop.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/drop.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage drop --help ``` + ```txt -Usage: reth stage drop [OPTIONS] <STAGE> +Usage: seismic-reth stage drop [OPTIONS] <STAGE>   Options: -h, --help @@ -165,4 +166,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/dump.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump.mdx index 97211934295f71d905ac80ec7c2b994b3b2cf857..2fbf7ba376f2009d6b764837cc4b5e6d88b37047 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/dump.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage dump --help ``` + ```txt -Usage: reth stage dump [OPTIONS] <COMMAND> +Usage: seismic-reth stage dump [OPTIONS] <COMMAND>   Commands: execution Execution stage @@ -158,4 +159,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/dump/account-hashing.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/account-hashing.mdx index c1459ee5498c74bff0d5a1a1b6a9578a8bad50ed..bc99c174af38c6b803f5786404665d8b01ca5625 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/dump/account-hashing.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/account-hashing.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage dump account-hashing --help ``` + ```txt -Usage: reth stage dump account-hashing [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO> +Usage: seismic-reth stage dump account-hashing [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO>   Options: --output-datadir <OUTPUT_PATH> @@ -115,4 +116,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/dump/execution.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/execution.mdx index 4f39dccac120890c72177eb0ef8262262c8923da..92c0310d5bcdfab4816743628c3ad478a94fb7e0 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/dump/execution.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/execution.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage dump execution --help ``` + ```txt -Usage: reth stage dump execution [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO> +Usage: seismic-reth stage dump execution [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO>   Options: --output-datadir <OUTPUT_PATH> @@ -115,4 +116,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/dump/merkle.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/merkle.mdx index f5d6a07b09a4a21a1b9329c9e8785aa6252492d6..1464a7309cd1543bb8707bd3e1b84c7b65ccf496 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/dump/merkle.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/merkle.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage dump merkle --help ``` + ```txt -Usage: reth stage dump merkle [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO> +Usage: seismic-reth stage dump merkle [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO>   Options: --output-datadir <OUTPUT_PATH> @@ -115,4 +116,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/dump/storage-hashing.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/storage-hashing.mdx index fce03ffa753d3b3bea774e66f850a97e30734c3c..86b21b10c862886cbb3a58444f969c5d028cbe09 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/dump/storage-hashing.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/dump/storage-hashing.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage dump storage-hashing --help ``` + ```txt -Usage: reth stage dump storage-hashing [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO> +Usage: seismic-reth stage dump storage-hashing [OPTIONS] --output-datadir <OUTPUT_PATH> --from <FROM> --to <TO>   Options: --output-datadir <OUTPUT_PATH> @@ -115,4 +116,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/run.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/run.mdx index 8e0e6400ec2d7c1b950aac524ea5402ad691e16a..829ef5d5077a10fb0953d725b68690e4b07707b4 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/run.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/run.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage run --help ``` + ```txt -Usage: reth stage run [OPTIONS] --from <FROM> --to <TO> <STAGE> +Usage: seismic-reth stage run [OPTIONS] --from <FROM> --to <TO> <STAGE>   Options: -h, --help @@ -380,4 +381,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/unwind.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/unwind.mdx index 1a3fd02cae82b3daa201afcb7883db7a7852671f..285c41b82943564f8fdb833bb37ec2f5a6a8b30f 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/unwind.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/unwind.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage unwind --help ``` + ```txt -Usage: reth stage unwind [OPTIONS] <COMMAND> +Usage: seismic-reth stage unwind [OPTIONS] <COMMAND>   Commands: to-block Unwinds the database from the latest block, until the given block number or hash has been reached, that block is not included @@ -159,4 +160,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/unwind/num-blocks.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/unwind/num-blocks.mdx index bed98899e195a3fce1bef8b1d8ea9a175f07bfb9..724d1bbb30eac40a0d5c21d7e35ec9bb3ab7bc16 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/unwind/num-blocks.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/unwind/num-blocks.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage unwind num-blocks --help ``` + ```txt -Usage: reth stage unwind num-blocks [OPTIONS] <AMOUNT> +Usage: seismic-reth stage unwind num-blocks [OPTIONS] <AMOUNT>   Arguments: <AMOUNT> @@ -107,4 +108,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/stage/unwind/to-block.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/stage/unwind/to-block.mdx index bcfc87cf3e573d7baf9cdd6c10542d3517be124d..5d46f8257ae2bb1a1af0265d969e46fbb0ebef61 100644 --- reth/docs/vocs/docs/pages/cli/reth/stage/unwind/to-block.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/stage/unwind/to-block.mdx @@ -5,8 +5,9 @@ ```bash $ reth stage unwind to-block --help ``` + ```txt -Usage: reth stage unwind to-block [OPTIONS] <TARGET> +Usage: seismic-reth stage unwind to-block [OPTIONS] <TARGET>   Arguments: <TARGET> @@ -107,4 +108,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/cli/reth/test-vectors/tables.mdx seismic-reth/docs/vocs/docs/pages/cli/reth/test-vectors/tables.mdx index 2a3023817b3553635fc7bd58bae24e640290c63e..dacf0b385a42dc36ffce33ab24583d03545decca 100644 --- reth/docs/vocs/docs/pages/cli/reth/test-vectors/tables.mdx +++ seismic-reth/docs/vocs/docs/pages/cli/reth/test-vectors/tables.mdx @@ -4,7 +4,7 @@ Generates test vectors for specified tables. If no table is specified, generate for all   ```bash $ reth test-vectors tables --help -Usage: reth test-vectors tables [OPTIONS] [NAMES]... +Usage: seismic-reth test-vectors tables [OPTIONS] [NAMES]...   Arguments: [NAMES]... @@ -110,4 +110,4 @@ -vvvvv Traces (warning: very verbose!)   -q, --quiet Silence all log output -``` \ No newline at end of file +```
diff --git reth/docs/vocs/docs/pages/installation/docker.mdx seismic-reth/docs/vocs/docs/pages/installation/docker.mdx index ecf55f6b3daae1b3d32e75bc31a85d31b940d3d2..983da5f3e778d2a283b40bb62d709b4b17f55104 100644 --- reth/docs/vocs/docs/pages/installation/docker.mdx +++ seismic-reth/docs/vocs/docs/pages/installation/docker.mdx @@ -48,6 +48,11 @@ ```bash docker build . -t reth:local ```   +If your build requires ssh private key to clone private repo, +```bash +docker buildx build --secret id=ssh_key,src=$ABSOLUTE_PATH_TO_SSH_PK -t reth:local . +``` + The build will likely take several minutes. Once it's built, test it with:   ```bash
diff --git reth/docs/vocs/docs/pages/installation/source.mdx seismic-reth/docs/vocs/docs/pages/installation/source.mdx index a7e1a2c33cc8f0261929f213288ffff861f9e075..ccdc6efab73ed7cc47e6d46e5ef9d875bad55cb9 100644 --- reth/docs/vocs/docs/pages/installation/source.mdx +++ seismic-reth/docs/vocs/docs/pages/installation/source.mdx @@ -4,10 +4,10 @@ ---   # Build from Source   -You can build Reth on Linux, macOS, Windows, and Windows WSL2. +You can build Seismic Reth on Linux, macOS, Windows, and Windows WSL2.   :::note -Reth does **not** work on Windows WSL1. +Seismic Reth does **not** work on Windows WSL1. :::   ## Dependencies @@ -35,27 +35,27 @@ - **Ubuntu**: `apt-get install libclang-dev pkg-config build-essential` - **macOS**: `brew install llvm pkg-config` - **Windows**: `choco install llvm` or `winget install LLVM.LLVM`   -These are needed to build bindings for Reth's database. +These are needed to build bindings for Seismic Reth's database.   The Minimum Supported Rust Version (MSRV) of this project is 1.80.0. If you already have a version of Rust installed, you can check your version by running `rustc --version`. To update your version of Rust, run `rustup update`.   -## Build Reth +## Build Seismic Reth   With Rust and the dependencies installed, you're ready to build Reth. First, clone the repository:   ```bash -git clone https://github.com/paradigmxyz/reth -cd reth +git clone https://github.com/SeismicSystems/seismic-reth +cd seismic-reth ```   Then, install Reth into your `PATH` directly via:   ```bash -cargo install --locked --path bin/reth --bin reth +cargo install --locked --path seismic-reth --bin seismic-reth ```   -The binary will now be accessible as `reth` via the command line, and exist under your default `.cargo/bin` folder. +The binary will now be accessible as `seismic-reth` via the command line, and exist under your default `.cargo/bin` folder.   Alternatively, you can build yourself with:   @@ -63,9 +63,9 @@ ```bash cargo build --release ```   -This will place the reth binary under `./target/release/reth`, and you can copy it to your directory of preference after that. +This will place the seismic-reth binary under `./target/release/seismic-reth`, and you can copy it to your directory of preference after that.   -Compilation may take around 10 minutes. Installation was successful if `reth --help` displays the [command-line documentation](/cli/reth). +Compilation may take around 10 minutes. Installation was successful if `seismic-reth --help` displays the [command-line documentation](/cli/reth).   If you run into any issues, please check the [Troubleshooting](#troubleshooting) section, or reach out to us on [Telegram](https://t.me/paradigm_reth).   @@ -128,7 +128,7 @@ ## Troubleshooting   ### Command is not found   -Reth will be installed to `CARGO_HOME` or `$HOME/.cargo`. This directory needs to be on your `PATH` before you can run `$ reth`. +Seismic Reth will be installed to `CARGO_HOME` or `$HOME/.cargo`. This directory needs to be on your `PATH` before you can run `$ seismic-reth`.   See ["Configuring the `PATH` environment variable"](https://www.rust-lang.org/tools/install) for more information.   @@ -137,7 +137,7 @@ Make sure you are running the latest version of Rust. If you have installed Rust using rustup, simply run `rustup update`.   If you can't install the latest version of Rust you can instead compile using the Minimum Supported -Rust Version (MSRV) which is listed under the `rust-version` key in Reth's +Rust Version (MSRV) which is listed under the `rust-version` key in Seismic Reth's [Cargo.toml](https://github.com/paradigmxyz/reth/blob/main/Cargo.toml).   If compilation fails with `(signal: 9, SIGKILL: kill)`, this could mean your machine ran out of @@ -155,6 +155,6 @@ ### Bus error (WSL2)   In WSL 2 on Windows, the default virtual disk size is set to 1TB.   -You must increase the allocated disk size for your WSL2 instance before syncing reth. +You must increase the allocated disk size for your WSL2 instance before syncing seismic-reth.   You can follow the instructions here: [how to expand the size of your WSL2 virtual hard disk.](https://learn.microsoft.com/en-us/windows/wsl/disk-space#how-to-expand-the-size-of-your-wsl-2-virtual-hard-disk)
diff --git reth/docs/vocs/docs/pages/overview.mdx seismic-reth/docs/vocs/docs/pages/overview.mdx index 33bc607bd45b13e0fad7f746270ce67d6f750290..cc89b0e5fda079a59b80428462477cb4e193d1fd 100644 --- reth/docs/vocs/docs/pages/overview.mdx +++ seismic-reth/docs/vocs/docs/pages/overview.mdx @@ -1,64 +1,40 @@ +# Seismic Reth [Documentation for Seismic Reth users and developers] + --- -description: Reth - A secure, performant, and modular blockchain SDK and Ethereum node. +description: Seismic Reth is an **Seismic full node implementation that is focused on being user-friendly, highly modular, as well as being fast and efficient.** ---   -# Reth [Documentation for Reth users and developers] - -Reth (short for Rust Ethereum, [pronunciation](https://twitter.com/kelvinfichter/status/1597653609411268608)) is an **Ethereum full node implementation that is focused on being user-friendly, highly modular, as well as being fast and efficient.** +Seismic Reth is production ready, and suitable for usage in mission-critical environments such as staking or high-uptime services. We also actively recommend professional node operators to switch to Reth in production for performance and cost reasons in use cases where high performance with great margins is required such as RPC, MEV, Indexing, Simulations, and P2P activities.   -Reth is production ready, and suitable for usage in mission-critical environments such as staking or high-uptime services. We also actively recommend professional node operators to switch to Reth in production for performance and cost reasons in use cases where high performance with great margins is required such as RPC, MEV, Indexing, Simulations, and P2P activities. +<img src="https://raw.githubusercontent.com/SeismicSystems/seismic-reth/seismic/assets/seismic-reth-beta.png" style="border-radius: 20px">   -![Reth](https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-prod.png) +<!-- Add a quick description about Reth, what it is, the goals of the build, and any other quick overview information -->   ## What is this about?   -[Reth](https://github.com/paradigmxyz/reth/) is an execution layer (EL) implementation that is compatible with all Ethereum consensus layer (CL) implementations that support the [Engine API](https://github.com/ethereum/execution-apis/tree/59e3a719021f48c1ef5653840e3ea5750e6af693/src/engine). +[Seismic Reth](https://github.com/SeismicSystems/seismic-reth) is an execution layer (EL) implementation that is compatible with all Ethereum consensus layer (CL) implementations that support the [Engine API](https://github.com/ethereum/execution-apis/tree/59e3a719021f48c1ef5653840e3ea5750e6af693/src/engine).   -It is originally built and driven forward by [Paradigm](https://paradigm.xyz/), and is licensed under the Apache and MIT licenses. +It is originally built and driven forward by [Seismic Systems](https://www.seismic.systems/).   -As a full Ethereum node, Reth allows users to connect to the Ethereum network and interact with the Ethereum blockchain. +As a full Seismic node, Reth allows users to connect to the Seismic network and interact with the Seismic blockchain.   -This includes sending and receiving transactions, querying logs and traces, as well as accessing and interacting with smart contracts. +This includes sending and receiving encrypted transactions, querying logs, as well as accessing and interacting with smart contracts.   -Building a successful Ethereum node requires creating a high-quality implementation that is both secure and efficient, as well as being easy to use on consumer hardware. It also requires building a strong community of contributors who can help support and improve the software. +Building a successful Seismic node requires creating a high-quality implementation that is both secure and efficient, as well as being easy to use on consumer hardware. It also requires building a strong community of contributors who can help support and improve the software.   -## What are the goals of Reth? +## What are the goals of Seismic Reth?   **1. Modularity**   -Every component of Reth is built to be used as a library: well-tested, heavily documented and benchmarked. We envision that developers will import the node's crates, mix and match, and innovate on top of them. - -Examples of such usage include, but are not limited to, spinning up standalone P2P networks, talking directly to a node's database, or "unbundling" the node into the components you need. - -To achieve that, we are licensing Reth under the Apache/MIT permissive license. +Changes to the upstream Reth is minimized refactoring is continuously pushed to maintain the modularity of the upstream repository   **2. Performance**   -Reth aims to be fast, so we used Rust and the [Erigon staged-sync](https://erigon.substack.com/p/erigon-stage-sync-and-control-flows) node architecture. - -We also use our Ethereum libraries (including [Alloy](https://github.com/alloy-rs/alloy/) and [revm](https://github.com/bluealloy/revm/)) which we’ve battle-tested and optimized via [Foundry](https://github.com/foundry-rs/foundry/). - -**3. Free for anyone to use any way they want** - -Reth is free open-source software, built for the community, by the community. - -By licensing the software under the Apache/MIT license, we want developers to use it without being bound by business licenses, or having to think about the implications of GPL-like licenses. - -**4. Client Diversity** - -The Ethereum protocol becomes more antifragile when no node implementation dominates. This ensures that if there's a software bug, the network does not finalize a bad block. By building a new client, we hope to contribute to Ethereum's antifragility. - -**5. Used by a wide demographic** - -We want to solve for node operators that care about fast historical queries, but also for hobbyists who cannot operate on large hardware. - -We also want to support teams and individuals who want both sync from genesis and via "fast sync". - -We envision that Reth will be configurable enough for the tradeoffs that each team faces. +Seismic Reth aims to be fast, adding minimal overhead over Reth   ## Who is this for?   -Reth is a new Ethereum full node that allows users to sync and interact with the entire blockchain, including its historical state if in archive mode. +Seismic Reth is a new Seismic full node that allows users to sync and interact with the entire blockchain, including its historical state if in archive mode.   - Full node: It can be used as a full node, which stores and processes the entire blockchain, validates blocks and transactions, and participates in the consensus process. - Archive node: It can also be used as an archive node, which stores the entire history of the blockchain and is useful for applications that need access to historical data. @@ -98,17 +74,15 @@ ## Sections   Here are some useful sections to jump to:   -- Install Reth by following the [guide](/installation/overview). +- Install Seismic Reth by following the [guide](/installation/overview). - Sync your node on any [official network](/run/overview). - View [statistics and metrics](/run/monitoring) about your node. - Query the [JSON-RPC](/jsonrpc/intro) using Foundry's `cast` or `curl`. - Set up your [development environment and contribute](/introduction/contributing)!   :::note -The documentation is continuously rendered [here](https://reth.rs)! +The book is continuously rendered [here](https://seismicsystems.github.io/seismic-reth/)! You can contribute to the docs on [GitHub][gh-docs]. :::   -[tg-badge]: https://img.shields.io/endpoint?color=neon&logo=telegram&label=chat&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fparadigm%5Freth -[tg-url]: https://t.me/paradigm_reth -[gh-docs]: https://github.com/paradigmxyz/reth/tree/main/docs +[gh-docs]: https://github.com/SeismicSystems/seismic-reth/tree/main/docs
diff --git reth/docs/vocs/docs/pages/seismic-developers.md seismic-reth/docs/vocs/docs/pages/seismic-developers.md new file mode 100644 index 0000000000000000000000000000000000000000..07745bc5b2046effb3a1103ed3706ac10f0c89bb --- /dev/null +++ seismic-reth/docs/vocs/docs/pages/seismic-developers.md @@ -0,0 +1,52 @@ +# Seismic Developer + +#### Table of Contents + + - [Running a Local Full Node](#running-a-local-full-node) + - [Build a Reth Docker Image](#build-a-reth-docker-image) + - [Spin Up a Network of Nodes](#spin-up-a-network-of-nodes) + - [Debugging](#debugging) + +## Running a Local Full Node + +### Build a Reth Docker Image + +Add the ABSOLUTE file path to your SSH private key with GitHub as the value of the `src=` parameter when you run the following command. This is to build Reth's dependencies from Seismic's GitHub, if there are any. + +```bash +docker buildx build --secret id=ssh_key,src=[ABSOLUTE_PATH_TO_YOUR_SSH_PK] -t seismic-reth:local . +``` + +1. Because we use multistage builds during the creation of the final image, the SSH key is only copied to the intermediate image, which means that the final image will not contain your SSH keys. +2. In production environments, we can use `docker secret` to pass the same SSH keys. + +### Spin Up a Network of Nodes + +We use `kurtosis` and [ethereum-package](https://github.com/ethpandaops/ethereum-package) to spin up a network of nodes. + +``` +kurtosis run --enclave seismic-local github.com/ethpandaops/ethereum-package --args-file network_params.yaml +``` + +To verify that the nodes are brought up, you should be able to see the corresponding containers. + +* **vc-1**: Refers to Validator Client (VC). This is likely a Lighthouse validator client interacting with both the Reth execution client and Lighthouse beacon node for proposing and attesting blocks in Ethereum’s Proof of Stake consensus. +* **cl-1**: Refers to the Consensus Layer (CL). This is probably the Lighthouse beacon node responsible for maintaining consensus and communicating with the Reth execution client. +* **el-1**: Refers to the Execution Layer (EL). This is most likely the Reth execution client, which processes transactions, executes smart contracts, and maintains the Ethereum state. + +In particular, the above command does the following: + +1. Generates Execution Layer (EL) and Consensus Layer (CL) genesis information using [the Ethereum genesis generator](https://github.com/ethpandaops/ethereum-genesis-generator). +2. Configures and bootstraps a network of Ethereum nodes of *n* size using the genesis data generated above. +3. Spins up a [transaction spammer](https://github.com/MariusVanDerWijden/tx-fuzz) to send fake transactions to the network. +4. Spins up and connects a [testnet verifier](https://github.com/ethereum/merge-testnet-verifier). +5. Spins up a Grafana and Prometheus instance to observe the network. +6. Spins up a Blobscan instance to analyze blob transactions (EIP-4844). + +For more information, please see the [ethereum-package](https://github.com/ethpandaops/ethereum-package) documentation. We might want to fork this package for Seismic for more customizable testing, especially when enclaves start to get involved. + +### Debugging + +You can run `docker exec -it [CONTAINER_ID] bash` to debug a specific container. + +TODO: I don't think you can bring up more than one node using Kurtosis. There is currently a bug. \ No newline at end of file
diff --git reth/testing/viem-tests/README.md seismic-reth/testing/viem-tests/README.md new file mode 100644 index 0000000000000000000000000000000000000000..b6122d78bf2e59310dc1c8a8b72b28ebefb51375 --- /dev/null +++ seismic-reth/testing/viem-tests/README.md @@ -0,0 +1,19 @@ +# Seismic Viem tests + +To install dependencies: + +```bash +bun install +``` + +To run tests: + +```bash +bun test +``` + +Note: These tests assume the .env is set up. See `.env.example` for an example. +The tests do not actually check the .env rn. run the tests with something like: +```bash +SRETH_ROOT=$SRETH_ROOT RETH_DATA_DIR=$RETH_DATA_DIR RETH_STATIC_FILES=$RETH_STATIC_FILES bun viem:test +``` \ No newline at end of file

tests ^.^

diff --git reth/crates/e2e-test-utils/tests/e2e-testsuite/main.rs seismic-reth/crates/e2e-test-utils/tests/e2e-testsuite/main.rs index 96c976a44caa2fbd524b4fbba584f6b1296e595b..ea385a502fb6251831476f3e3cc8d805c9d7d33b 100644 --- reth/crates/e2e-test-utils/tests/e2e-testsuite/main.rs +++ seismic-reth/crates/e2e-test-utils/tests/e2e-testsuite/main.rs @@ -143,6 +143,10 @@ .build(), )) .with_network(NetworkSetup::single_node());   + let timestamp = + std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() + as u64; + let test = TestBuilder::new().with_setup(setup).with_action(AssertMineBlock::<EthEngineTypes>::new( 0, @@ -150,10 +154,7 @@ vec![], Some(B256::ZERO), // TODO: refactor once we have actions to generate payload attributes. PayloadAttributes { - timestamp: std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap() - .as_secs(), + timestamp, prev_randao: B256::random(), suggested_fee_recipient: Address::random(), withdrawals: None,
diff --git reth/crates/ethereum/evm/tests/execute.rs seismic-reth/crates/ethereum/evm/tests/execute.rs index 61e0c1c4b66e2d1e2aa07f230da540952bb101e1..0b6e1789c95cd4ef65e2e47677a50604b1b19fde 100644 --- reth/crates/ethereum/evm/tests/execute.rs +++ seismic-reth/crates/ethereum/evm/tests/execute.rs @@ -65,8 +65,10 @@ }   #[test] fn eip_4788_non_genesis_call() { - let mut header = - Header { timestamp: 1, number: 1, excess_blob_gas: Some(0), ..Header::default() }; + // When timestamp-in-seconds feature is disabled, timestamps are in milliseconds + // Use 1000ms (1 second) so TIMESTAMP opcode returns 1, matching the storage index + let timestamp = if cfg!(feature = "timestamp-in-seconds") { 1 } else { 1000 }; + let mut header = Header { timestamp, number: 1, excess_blob_gas: Some(0), ..Header::default() };   let db = create_database_with_beacon_root_contract();   @@ -117,14 +119,19 @@ // header.timestamp // * The storage value at header.timestamp % HISTORY_BUFFER_LENGTH + HISTORY_BUFFER_LENGTH // // should be parent_beacon_block_root let history_buffer_length = 8191u64; - let timestamp_index = header.timestamp % history_buffer_length; + let timestamp_for_opcode = if cfg!(feature = "timestamp-in-seconds") { + header.timestamp + } else { + header.timestamp / 1000 + }; + let timestamp_index = timestamp_for_opcode % history_buffer_length; let parent_beacon_block_root_index = timestamp_index % history_buffer_length + history_buffer_length;   let timestamp_storage = executor.with_state_mut(|state| { state.storage(BEACON_ROOTS_ADDRESS, U256::from(timestamp_index)).unwrap() }); - assert_eq!(timestamp_storage, U256::from(header.timestamp)); + assert_eq!(timestamp_storage.value, U256::from(timestamp_for_opcode));   // get parent beacon block root storage and compare let parent_beacon_block_root_storage = executor.with_state_mut(|state| { @@ -132,7 +139,7 @@ state .storage(BEACON_ROOTS_ADDRESS, U256::from(parent_beacon_block_root_index)) .expect("storage value should exist") }); - assert_eq!(parent_beacon_block_root_storage, U256::from(0x69)); + assert_eq!(parent_beacon_block_root_storage.value, U256::from(0x69)); }   #[test] @@ -273,8 +280,11 @@ #[test] fn eip_4788_high_base_fee() { // This test ensures that if we have a base fee, then we don't return an error when the // system contract is called, due to the gas price being less than the base fee. + // When timestamp-in-seconds feature is disabled, timestamps are in milliseconds + // Use 1000ms (1 second) so TIMESTAMP opcode returns 1, matching the storage index + let timestamp = if cfg!(feature = "timestamp-in-seconds") { 1 } else { 1000 }; let header = Header { - timestamp: 1, + timestamp, number: 1, parent_beacon_block_root: Some(B256::with_last_byte(0x69)), base_fee_per_gas: Some(u64::MAX), @@ -310,7 +320,12 @@ // header.timestamp // * The storage value at header.timestamp % HISTORY_BUFFER_LENGTH + HISTORY_BUFFER_LENGTH // // should be parent_beacon_block_root let history_buffer_length = 8191u64; - let timestamp_index = header.timestamp % history_buffer_length; + let timestamp_for_opcode = if cfg!(feature = "timestamp-in-seconds") { + header.timestamp + } else { + header.timestamp / 1000 + }; + let timestamp_index = timestamp_for_opcode % history_buffer_length; let parent_beacon_block_root_index = timestamp_index % history_buffer_length + history_buffer_length;   @@ -318,13 +333,13 @@ // get timestamp storage and compare let timestamp_storage = executor.with_state_mut(|state| { state.storage(BEACON_ROOTS_ADDRESS, U256::from(timestamp_index)).unwrap() }); - assert_eq!(timestamp_storage, U256::from(header.timestamp)); + assert_eq!(timestamp_storage.value, U256::from(timestamp_for_opcode));   // get parent beacon block root storage and compare let parent_beacon_block_root_storage = executor.with_state_mut(|state| { state.storage(BEACON_ROOTS_ADDRESS, U256::from(parent_beacon_block_root_index)).unwrap() }); - assert_eq!(parent_beacon_block_root_storage, U256::from(0x69)); + assert_eq!(parent_beacon_block_root_storage.value, U256::from(0x69)); }   /// Create a state provider with blockhashes and the EIP-2935 system contract. @@ -421,6 +436,7 @@ fn eip_2935_fork_activation_within_window_bounds() { let fork_activation_block = (HISTORY_SERVE_WINDOW - 10) as u64; let db = create_database_with_block_hashes(fork_activation_block);   + let timestamp = if cfg!(feature = "timestamp-in-seconds") { 1 } else { 1000 }; let chain_spec = Arc::new( ChainSpecBuilder::from(&*MAINNET) .shanghai_activated() @@ -431,7 +447,7 @@ );   let header = Header { parent_hash: B256::random(), - timestamp: 1, + timestamp, number: fork_activation_block, requests_hash: Some(EMPTY_REQUESTS_HASH), excess_blob_gas: Some(0), @@ -454,9 +470,11 @@ assert!( executor.with_state_mut(|state| state.basic(HISTORY_STORAGE_ADDRESS).unwrap().is_some()) ); assert_ne!( - executor.with_state_mut(|state| state - .storage(HISTORY_STORAGE_ADDRESS, U256::from(fork_activation_block - 1)) - .unwrap()), + executor + .with_state_mut(|state| state + .storage(HISTORY_STORAGE_ADDRESS, U256::from(fork_activation_block - 1)) + .unwrap()) + .value, U256::ZERO );   @@ -567,7 +585,8 @@ executor.with_state_mut(|state| state.basic(HISTORY_STORAGE_ADDRESS).unwrap().is_some()) ); assert_ne!( executor - .with_state_mut(|state| state.storage(HISTORY_STORAGE_ADDRESS, U256::ZERO).unwrap()), + .with_state_mut(|state| state.storage(HISTORY_STORAGE_ADDRESS, U256::ZERO).unwrap()) + .value, U256::ZERO ); assert!(executor.with_state_mut(|state| { @@ -598,12 +617,14 @@ executor.with_state_mut(|state| state.basic(HISTORY_STORAGE_ADDRESS).unwrap().is_some()) ); assert_ne!( executor - .with_state_mut(|state| state.storage(HISTORY_STORAGE_ADDRESS, U256::ZERO).unwrap()), + .with_state_mut(|state| state.storage(HISTORY_STORAGE_ADDRESS, U256::ZERO).unwrap()) + .value, U256::ZERO ); assert_ne!( executor - .with_state_mut(|state| state.storage(HISTORY_STORAGE_ADDRESS, U256::from(1)).unwrap()), + .with_state_mut(|state| state.storage(HISTORY_STORAGE_ADDRESS, U256::from(1)).unwrap()) + .value, U256::ZERO ); assert!(executor.with_state_mut(|state| {
diff --git reth/crates/ethereum/node/tests/e2e/blobs.rs seismic-reth/crates/ethereum/node/tests/e2e/blobs.rs index 8fd9d08d2dcc62f21c8fbe0819e3c4b252ac4d80..5233e45d1e0834475e4101b61fd147a35a03183e 100644 --- reth/crates/ethereum/node/tests/e2e/blobs.rs +++ seismic-reth/crates/ethereum/node/tests/e2e/blobs.rs @@ -11,7 +11,7 @@ use reth_tasks::TaskManager; use reth_transaction_pool::TransactionPool; use std::sync::Arc;   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn can_handle_blobs() -> eyre::Result<()> { reth_tracing::init_test_tracing(); let tasks = TaskManager::current(); @@ -21,7 +21,7 @@ let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); let chain_spec = Arc::new( ChainSpecBuilder::default() .chain(MAINNET.chain) - .genesis(genesis) + .genesis(genesis.into()) .cancun_activated() .build(), );
diff --git reth/crates/ethereum/node/tests/e2e/dev.rs seismic-reth/crates/ethereum/node/tests/e2e/dev.rs index ad214b04fe06434d0c84f3735442f283b3a94734..0d6ce9c19f42a994743712f7dddcb52ece0539ee 100644 --- reth/crates/ethereum/node/tests/e2e/dev.rs +++ seismic-reth/crates/ethereum/node/tests/e2e/dev.rs @@ -15,7 +15,7 @@ use reth_rpc_eth_api::helpers::EthTransactions; use reth_tasks::TaskManager; use std::sync::Arc;   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn can_run_dev_node() -> eyre::Result<()> { reth_tracing::init_test_tracing(); let tasks = TaskManager::current();
diff --git reth/crates/ethereum/node/tests/e2e/eth.rs seismic-reth/crates/ethereum/node/tests/e2e/eth.rs index c427f5f0b39768d68bb104099747d72b1f2f91c9..635e9e79db1c7fa55569327c5517c7f55f66e9c2 100644 --- reth/crates/ethereum/node/tests/e2e/eth.rs +++ seismic-reth/crates/ethereum/node/tests/e2e/eth.rs @@ -10,7 +10,7 @@ use reth_node_ethereum::EthereumNode; use reth_tasks::TaskManager; use std::sync::Arc;   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn can_run_eth_node() -> eyre::Result<()> { reth_tracing::init_test_tracing();   @@ -46,7 +46,7 @@ Ok(()) }   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] #[cfg(unix)] async fn can_run_eth_node_with_auth_engine_api_over_ipc() -> eyre::Result<()> { reth_tracing::init_test_tracing(); @@ -58,7 +58,7 @@ let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); let chain_spec = Arc::new( ChainSpecBuilder::default() .chain(MAINNET.chain) - .genesis(genesis) + .genesis(genesis.into()) .cancun_activated() .build(), ); @@ -94,7 +94,7 @@ Ok(()) }   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] #[cfg(unix)] async fn test_failed_run_eth_node_with_no_auth_engine_api_over_ipc_opts() -> eyre::Result<()> { reth_tracing::init_test_tracing(); @@ -106,7 +106,7 @@ let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); let chain_spec = Arc::new( ChainSpecBuilder::default() .chain(MAINNET.chain) - .genesis(genesis) + .genesis(genesis.into()) .cancun_activated() .build(), );
diff --git reth/crates/ethereum/node/tests/e2e/p2p.rs seismic-reth/crates/ethereum/node/tests/e2e/p2p.rs index 34a42105381018afb8cc45d605399094e5f68044..ff915e98917977dc7a56361ee63db60282b88755 100644 --- reth/crates/ethereum/node/tests/e2e/p2p.rs +++ seismic-reth/crates/ethereum/node/tests/e2e/p2p.rs @@ -6,7 +6,7 @@ use reth_e2e_test_utils::{setup, setup_engine, transaction::TransactionTestContext}; use reth_node_ethereum::EthereumNode; use std::sync::Arc;   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn can_sync() -> eyre::Result<()> { reth_tracing::init_test_tracing();   @@ -49,7 +49,7 @@ Ok(()) }   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn e2e_test_send_transactions() -> eyre::Result<()> { reth_tracing::init_test_tracing();   @@ -91,7 +91,8 @@ Ok(()) }   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] +#[ignore = "this takes a long time"] async fn test_long_reorg() -> eyre::Result<()> { reth_tracing::init_test_tracing();
diff --git reth/crates/ethereum/node/tests/e2e/pool.rs seismic-reth/crates/ethereum/node/tests/e2e/pool.rs index 9187cb61405bf4e5453ff99c13cb613c9ff36d6c..03c3739adf3658aaa9ef1d72f8c058a347a0e9e6 100644 --- reth/crates/ethereum/node/tests/e2e/pool.rs +++ seismic-reth/crates/ethereum/node/tests/e2e/pool.rs @@ -40,7 +40,7 @@ let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); let chain_spec = Arc::new( ChainSpecBuilder::default() .chain(MAINNET.chain) - .genesis(genesis) + .genesis(genesis.into()) .cancun_activated() .build(), ); @@ -114,7 +114,7 @@ let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); let chain_spec = Arc::new( ChainSpecBuilder::default() .chain(MAINNET.chain) - .genesis(genesis) + .genesis(genesis.into()) .cancun_activated() .build(), ); @@ -247,7 +247,7 @@ let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap(); let chain_spec = Arc::new( ChainSpecBuilder::default() .chain(MAINNET.chain) - .genesis(genesis) + .genesis(genesis.into()) .cancun_activated() .build(), );
diff --git reth/crates/ethereum/node/tests/e2e/rpc.rs seismic-reth/crates/ethereum/node/tests/e2e/rpc.rs index b1fd1fa7b733170e61ac7720c2cb2b62dec5c409..a19b3a44293a197c7bc479c98e112ac731ca51f3 100644 --- reth/crates/ethereum/node/tests/e2e/rpc.rs +++ seismic-reth/crates/ethereum/node/tests/e2e/rpc.rs @@ -32,7 +32,7 @@ } } }   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_fee_history() -> eyre::Result<()> { reth_tracing::init_test_tracing();   @@ -121,7 +121,7 @@ Ok(()) }   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_flashbots_validate_v3() -> eyre::Result<()> { reth_tracing::init_test_tracing();   @@ -203,7 +203,7 @@ .is_err()); Ok(()) }   -#[tokio::test] +#[tokio::test(flavor = "multi_thread")] async fn test_flashbots_validate_v4() -> eyre::Result<()> { reth_tracing::init_test_tracing();   @@ -287,6 +287,8 @@ Ok(()) }   #[tokio::test] +// TODO(usm) re-enable these +#[ignore = "We disabled fork activations"] async fn test_eth_config() -> eyre::Result<()> { reth_tracing::init_test_tracing();
diff --git reth/crates/net/eth-wire/tests/fuzz_roundtrip.rs seismic-reth/crates/net/eth-wire/tests/fuzz_roundtrip.rs index f09035f45ded8891666c7e33acfd7b0c05ece44f..2493d6b65e59aec8e06b863be5e5c2b9113ce61c 100644 --- reth/crates/net/eth-wire/tests/fuzz_roundtrip.rs +++ seismic-reth/crates/net/eth-wire/tests/fuzz_roundtrip.rs @@ -48,6 +48,7 @@ #[cfg(test)] #[expect(missing_docs)] pub mod fuzz_rlp { + #[allow(unused_imports)] use crate::roundtrip_encoding; use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use reth_codecs::add_arbitrary_tests; @@ -156,8 +157,9 @@ fuzz_type_and_name!(NewPooledTransactionHashes66, fuzz_NewPooledTransactionHashes66); fuzz_type_and_name!(NewPooledTransactionHashes68, fuzz_NewPooledTransactionHashes68); fuzz_type_and_name!(GetPooledTransactions, fuzz_GetPooledTransactions); fuzz_type_and_name!(PooledTransactions, fuzz_PooledTransactions); - fuzz_type_and_name!(GetNodeData, fuzz_GetNodeData); - fuzz_type_and_name!(NodeData, fuzz_NodeData); + // GetNodeData and NodeData are disabled for privacy - skip fuzz tests + // fuzz_type_and_name!(GetNodeData, fuzz_GetNodeData); + // fuzz_type_and_name!(NodeData, fuzz_NodeData); fuzz_type_and_name!(GetReceipts, fuzz_GetReceipts); fuzz_type_and_name!(Receipts, fuzz_Receipts); }
diff --git reth/crates/ress/protocol/tests/it/e2e.rs seismic-reth/crates/ress/protocol/tests/it/e2e.rs index 5259e763a54a195eae3b5dfb9d0233e8b63cbb5d..95c102ca85e70923b882439c58323450df8253b3 100644 --- reth/crates/ress/protocol/tests/it/e2e.rs +++ seismic-reth/crates/ress/protocol/tests/it/e2e.rs @@ -14,6 +14,7 @@ use std::time::{Duration, Instant}; use tokio::sync::{mpsc, oneshot};   #[tokio::test(flavor = "multi_thread")] +#[ignore] async fn disconnect_on_stateful_pair() { reth_tracing::init_test_tracing(); let mut net = Testnet::create_with(2, MockEthProvider::default()).await;
diff --git reth/crates/rpc/rpc-builder/tests/it/http.rs seismic-reth/crates/rpc/rpc-builder/tests/it/http.rs index a790253d26634a1244773dd575257c7d04482d13..f3bb3a73280a7ad1986850e487c4242b7f1d6ccc 100644 --- reth/crates/rpc/rpc-builder/tests/it/http.rs +++ seismic-reth/crates/rpc/rpc-builder/tests/it/http.rs @@ -1576,6 +1576,64 @@ .await; }   #[tokio::test(flavor = "multi_thread")] +async fn test_eth_get_flagged_storage_at_rpc_call() { + reth_tracing::init_test_tracing(); + + // Launch HTTP server with the specified RPC module + let handle = launch_http(vec![RethRpcModule::Eth]).await; + let client = handle.http_client().unwrap(); + + // Vec of block number items + let block_number = vec!["latest", "earliest", "pending", "0x2"]; + + // Iterate over test cases + for param in block_number { + // Requesting flagged storage at a given address with proper fields + test_rpc_call_ok::<alloy_primitives::FlaggedStorage>( + &client, + "eth_getFlaggedStorageAt", + rpc_params![ + "0x295a70b2de5e3953354a6a8344e616ed314d7251", // Address + "0x0", // Position in the storage + param // Block number or tag + ], + ) + .await; + } + + // Requesting flagged storage at a given address without block number which is optional + test_rpc_call_ok::<alloy_primitives::FlaggedStorage>( + &client, + "eth_getFlaggedStorageAt", + rpc_params![ + "0x295a70b2de5e3953354a6a8344e616ed314d7251", // Address + "0x0" // Position in the storage + ], + ) + .await; + + // Requesting flagged storage at a given address with no field + test_rpc_call_err::<alloy_primitives::FlaggedStorage>( + &client, + "eth_getFlaggedStorageAt", + rpc_params![], + ) + .await; + + // Requesting flagged storage at a given address with wrong fields + test_rpc_call_err::<alloy_primitives::FlaggedStorage>( + &client, + "eth_getFlaggedStorageAt", + rpc_params![ + "0x295a70b2de5e3953354a6a8344e616ed314d7251", // Address + "0x0", // Position in the storage + "not_valid_block_number" // Block number or tag + ], + ) + .await; +} + +#[tokio::test(flavor = "multi_thread")] async fn test_eth_get_transaction_count_rpc_call() { reth_tracing::init_test_tracing();
diff --git reth/crates/rpc/rpc-builder/tests/it/main.rs seismic-reth/crates/rpc/rpc-builder/tests/it/main.rs index f5dc3003e420905a8ab76b3ac8a061c31ca8764e..58cb4e555f7defb9cd97a91de6301ac6231298bd 100644 --- reth/crates/rpc/rpc-builder/tests/it/main.rs +++ seismic-reth/crates/rpc/rpc-builder/tests/it/main.rs @@ -3,6 +3,7 @@ mod auth; mod http; mod middleware; +mod ops; mod serde; mod startup; pub mod utils;
diff --git reth/crates/rpc/rpc-builder/tests/it/ops.rs seismic-reth/crates/rpc/rpc-builder/tests/it/ops.rs new file mode 100644 index 0000000000000000000000000000000000000000..570c9d92e102ebd99bac44644848a8042416cbba --- /dev/null +++ seismic-reth/crates/rpc/rpc-builder/tests/it/ops.rs @@ -0,0 +1,256 @@ +//! Ops signature-auth server tests + +use crate::utils::test_address; +use alloy_primitives::{Address, FlaggedStorage, B256, U256}; +use alloy_signer::Signer; +use alloy_signer_local::PrivateKeySigner; +use reth_provider::test_utils::{ExtendedAccount, MockEthProvider}; +use reth_rpc::OpsApi; +use reth_rpc_api::OpsApiServer; +use reth_rpc_builder::body_auth::{BodyAuthRpcModule, BodyAuthServerConfig, BodyAuthServerHandle}; +use reth_rpc_layer::{eip712_signing_hash, SignatureAuthConfig, Whitelist}; +use reth_tasks::TokioTaskExecutor; +use std::sync::Arc; + +/// Fixed contract address, slot, and chain ID for tests. +const CONTRACT_ADDRESS: Address = Address::ZERO; +const STORAGE_SLOT: B256 = B256::ZERO; +const TEST_CHAIN_ID: u64 = 1; + +/// Create a mock provider with a specific admin address stored at the contract slot. +fn mock_provider_with_admin(admin_address: Address) -> Arc<MockEthProvider> { + let provider = MockEthProvider::default(); + let mut value = [0u8; 32]; + value[12..].copy_from_slice(admin_address.as_slice()); + let storage_value = FlaggedStorage::public(U256::from_be_bytes(value)); + let account = + ExtendedAccount::new(0, U256::ZERO).extend_storage([(STORAGE_SLOT, storage_value)]); + provider.add_account(CONTRACT_ADDRESS, account); + Arc::new(provider) +} + +/// Launch an ops server with the given admin address. +async fn launch_ops_with_admin(admin_address: Address) -> (BodyAuthServerHandle, Whitelist) { + let provider = mock_provider_with_admin(admin_address); + let whitelist = Whitelist::new(); + let nonces = Arc::new(std::sync::RwLock::new(std::collections::HashMap::new())); + let mut auth_config = SignatureAuthConfig::new(whitelist.clone(), TEST_CHAIN_ID); + auth_config.nonces = nonces.clone(); + + let ops_api = OpsApi::new(provider, Box::new(TokioTaskExecutor::default()), nonces); + + let mut module = BodyAuthRpcModule::empty(); + module.merge_methods(ops_api.into_rpc()).unwrap(); + + let server_config = + BodyAuthServerConfig::builder(auth_config).socket_addr(test_address()).build(); + + let handle = server_config.start(module).await.unwrap(); + (handle, whitelist) +} + +fn get_storage_request(address: Address, index: B256, id: u64) -> String { + serde_json::json!({ + "jsonrpc": "2.0", + "method": "ops_getStorageAt", + "params": [format!("{address:?}"), format!("{index:?}"), "latest"], + "id": id + }) + .to_string() +} + +fn get_nonce_request(address: Address, id: u64) -> String { + serde_json::json!({ + "jsonrpc": "2.0", + "method": "ops_getNonce", + "params": [format!("{address:?}")], + "id": id + }) + .to_string() +} + +async fn send_signed_request( + url: &str, + body: &str, + signer: &PrivateKeySigner, + nonce: Option<&str>, +) -> reqwest::Response { + let signing_nonce = nonce.unwrap_or(""); + let hash = eip712_signing_hash(body.as_bytes(), signing_nonce, TEST_CHAIN_ID); + + let signature = signer.sign_hash(&hash).await.unwrap(); + let sig_hex = alloy_primitives::hex::encode(signature.as_bytes()); + + let mut req = reqwest::Client::new() + .post(url) + .header("Content-Type", "application/json") + .header("X-Signature", &sig_hex); + if let Some(nonce) = nonce { + req = req.header("X-Nonce", nonce); + } + req.body(body.to_string()).send().await.unwrap() +} + +fn current_unix_timestamp() -> u64 { + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .expect("system clock before unix epoch") + .as_secs() +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_request_without_signature_is_rejected() { + reth_tracing::init_test_tracing(); + let admin = PrivateKeySigner::random(); + let (handle, _) = launch_ops_with_admin(admin.address()).await; + + let body = get_storage_request(Address::ZERO, B256::ZERO, 1); + let resp = reqwest::Client::new() + .post(&handle.http_url()) + .header("Content-Type", "application/json") + .body(body) + .send() + .await + .unwrap(); + + assert_eq!(resp.status(), reqwest::StatusCode::BAD_REQUEST); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_get_storage_at_requires_whitelisted_key() { + reth_tracing::init_test_tracing(); + let admin = PrivateKeySigner::random(); + let (handle, _) = launch_ops_with_admin(admin.address()).await; + let url = handle.http_url(); + + // Admin key should NOT be able to call getStorageAt + let body = get_storage_request(Address::ZERO, B256::ZERO, 1); + let resp = send_signed_request(&url, &body, &admin, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::UNAUTHORIZED); + + // Random key should NOT be able to call getStorageAt + let random = PrivateKeySigner::random(); + let resp = send_signed_request(&url, &body, &random, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::UNAUTHORIZED); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_whitelisted_key_can_read_storage() { + reth_tracing::init_test_tracing(); + let admin = PrivateKeySigner::random(); + let reader = PrivateKeySigner::random(); + let (handle, whitelist) = launch_ops_with_admin(admin.address()).await; + let url = handle.http_url(); + + // Reader can't read yet + let read_body = get_storage_request(CONTRACT_ADDRESS, STORAGE_SLOT, 1); + let resp = send_signed_request(&url, &read_body, &reader, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::UNAUTHORIZED); + + // Whitelist the reader directly (1 hour TTL) + let expires_at = current_unix_timestamp() + 3600; + whitelist.add(reader.address(), expires_at); + + // Now reader can read + let resp = send_signed_request(&url, &read_body, &reader, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::OK); + let json: serde_json::Value = resp.json().await.unwrap(); + assert!(json["result"].is_string()); + + // Reusing the same nonce should fail + let resp = send_signed_request(&url, &read_body, &reader, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::UNAUTHORIZED); + + // The next nonce should succeed + let resp = send_signed_request(&url, &read_body, &reader, Some("1")).await; + assert_eq!(resp.status(), reqwest::StatusCode::OK); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_whitelist_expires() { + reth_tracing::init_test_tracing(); + let admin = PrivateKeySigner::random(); + let reader = PrivateKeySigner::random(); + let (handle, whitelist) = launch_ops_with_admin(admin.address()).await; + let url = handle.http_url(); + + // Whitelist reader with a short TTL (5 seconds is enough margin for CI). + let expires_at = current_unix_timestamp() + 5; + whitelist.add(reader.address(), expires_at); + + // Reader can read immediately + let read_body = get_storage_request(CONTRACT_ADDRESS, STORAGE_SLOT, 2); + let resp = send_signed_request(&url, &read_body, &reader, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::OK); + + // Wait for TTL to expire + tokio::time::sleep(std::time::Duration::from_secs(6)).await; + + // Reader can no longer read + let resp = send_signed_request(&url, &read_body, &reader, Some("1")).await; + assert_eq!(resp.status(), reqwest::StatusCode::UNAUTHORIZED); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_expired_whitelist_cannot_read_storage() { + reth_tracing::init_test_tracing(); + let admin = PrivateKeySigner::random(); + let reader = PrivateKeySigner::random(); + let (handle, whitelist) = launch_ops_with_admin(admin.address()).await; + let url = handle.http_url(); + + // Whitelist reader with a short TTL (5 seconds is enough margin for CI). + let expires_at = current_unix_timestamp() + 5; + whitelist.add(reader.address(), expires_at); + + // Wait for the whitelist entry to expire. + tokio::time::sleep(std::time::Duration::from_secs(6)).await; + + // Reader should be rejected — whitelist expired + let read_body = get_storage_request(CONTRACT_ADDRESS, STORAGE_SLOT, 2); + let resp = send_signed_request(&url, &read_body, &reader, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::UNAUTHORIZED); + + // Re-whitelist with a longer absolute expiry. + let expires_at = current_unix_timestamp() + 3600; + whitelist.add(reader.address(), expires_at); + + // Reader can read again + let resp = send_signed_request(&url, &read_body, &reader, Some("0")).await; + assert_eq!(resp.status(), reqwest::StatusCode::OK); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_get_nonce_for_whitelisted_key() { + reth_tracing::init_test_tracing(); + let admin = PrivateKeySigner::random(); + let reader = PrivateKeySigner::random(); + let (handle, whitelist) = launch_ops_with_admin(admin.address()).await; + let url = handle.http_url(); + + let expires_at = current_unix_timestamp() + 3600; + whitelist.add(reader.address(), expires_at); + + let nonce_body = get_nonce_request(reader.address(), 2); + let resp = send_signed_request(&url, &nonce_body, &reader, None).await; + assert_eq!(resp.status(), reqwest::StatusCode::OK); + let json: serde_json::Value = resp.json().await.unwrap(); + assert_eq!(json["result"], 0); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_ops_get_nonce_rejects_other_address() { + reth_tracing::init_test_tracing(); + let admin = PrivateKeySigner::random(); + let reader = PrivateKeySigner::random(); + let other = PrivateKeySigner::random(); + let (handle, whitelist) = launch_ops_with_admin(admin.address()).await; + let url = handle.http_url(); + + let expires_at = current_unix_timestamp() + 3600; + whitelist.add(reader.address(), expires_at); + + let nonce_body = get_nonce_request(other.address(), 2); + let resp = send_signed_request(&url, &nonce_body, &reader, None).await; + assert_eq!(resp.status(), reqwest::StatusCode::UNAUTHORIZED); +}
diff --git reth/crates/rpc/rpc-builder/tests/it/utils.rs seismic-reth/crates/rpc/rpc-builder/tests/it/utils.rs index 673a1f79fc203e67163736903ed5836675788850..3ccc885e2ade17aa94d386a94db077d9c6732757 100644 --- reth/crates/rpc/rpc-builder/tests/it/utils.rs +++ seismic-reth/crates/rpc/rpc-builder/tests/it/utils.rs @@ -61,7 +61,7 @@ /// Launches a new server with http only with the given modules pub async fn launch_http(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle { let builder = test_rpc_builder(); - let eth_api = builder.bootstrap_eth_api(); + let eth_api = builder.eth_api_builder().enable_storage_apis(true).build(); let server = builder.build(TransportRpcModuleConfig::set_http(modules), eth_api); RpcServerConfig::http(Default::default()) .with_http_address(test_address()) @@ -73,7 +73,7 @@ /// Launches a new server with ws only with the given modules pub async fn launch_ws(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle { let builder = test_rpc_builder(); - let eth_api = builder.bootstrap_eth_api(); + let eth_api = builder.eth_api_builder().enable_storage_apis(true).build(); let server = builder.build(TransportRpcModuleConfig::set_ws(modules), eth_api); RpcServerConfig::ws(Default::default()) .with_ws_address(test_address()) @@ -85,7 +85,7 @@ /// Launches a new server with http and ws and with the given modules pub async fn launch_http_ws(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle { let builder = test_rpc_builder(); - let eth_api = builder.bootstrap_eth_api(); + let eth_api = builder.eth_api_builder().enable_storage_apis(true).build(); let modules = modules.into(); let server = builder .build(TransportRpcModuleConfig::set_ws(modules.clone()).with_http(modules), eth_api); @@ -103,7 +103,7 @@ /// Launches a new server with http and ws and with the given modules on the same port. pub async fn launch_http_ws_same_port(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle { let builder = test_rpc_builder(); let modules = modules.into(); - let eth_api = builder.bootstrap_eth_api(); + let eth_api = builder.eth_api_builder().enable_storage_apis(true).build(); let server = builder .build(TransportRpcModuleConfig::set_ws(modules.clone()).with_http(modules), eth_api); let addr = test_address();
diff --git reth/crates/rpc/rpc-e2e-tests/tests/e2e-testsuite/main.rs seismic-reth/crates/rpc/rpc-e2e-tests/tests/e2e-testsuite/main.rs index e1a4a2497993bea455dbf58eb9a16656581932db..888a0da9ccece522e6c8c9bdad016cc5db564807 100644 --- reth/crates/rpc/rpc-e2e-tests/tests/e2e-testsuite/main.rs +++ seismic-reth/crates/rpc/rpc-e2e-tests/tests/e2e-testsuite/main.rs @@ -20,6 +20,7 @@ /// 1. Initializes a node with chain data from testdata (chain.rlp) /// 2. Applies the forkchoice state from headfcu.json /// 3. Runs tests cases in the local repository, some of which are execution-api tests #[tokio::test(flavor = "multi_thread")] +#[ignore = "Seismic FlaggedStorage incompatible — see crates/seismic/node/tests/e2e/rpc_compat.rs"] async fn test_local_rpc_tests_compat() -> Result<()> { reth_tracing::init_test_tracing();
diff --git reth/testing/ef-tests/Cargo.toml seismic-reth/testing/ef-tests/Cargo.toml index 6b11e29c7076d1910d1ed18fe635dc3f9d70bf3b..306f923554e2d3849837c0bd9ec5d35aeb835f2f 100644 --- reth/testing/ef-tests/Cargo.toml +++ seismic-reth/testing/ef-tests/Cargo.toml @@ -13,9 +13,12 @@ workspace = true   [features] ef-tests = [] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] asm-keccak = ["alloy-primitives/asm-keccak", "revm/asm-keccak"]   [dependencies] +seismic-alloy-genesis.workspace = true + reth-chainspec.workspace = true reth-ethereum-primitives.workspace = true reth-primitives-traits.workspace = true
diff --git reth/testing/ef-tests/src/lib.rs seismic-reth/testing/ef-tests/src/lib.rs index ca5e47d2d3bcf4278065c77e6100e936bfa30f47..0305f943c0841d3457f41f27e9e974d42d484f89 100644 --- reth/testing/ef-tests/src/lib.rs +++ seismic-reth/testing/ef-tests/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/testing/ef-tests/src/models.rs seismic-reth/testing/ef-tests/src/models.rs index 49c49bf1936a4004170f963e62404b991a4970d8..7220a9dd61535bf56543e4a27f06b953759212fc 100644 --- reth/testing/ef-tests/src/models.rs +++ seismic-reth/testing/ef-tests/src/models.rs @@ -3,13 +3,15 @@ use crate::{assert::assert_equal, Error}; use alloy_consensus::Header as RethHeader; use alloy_eips::eip4895::Withdrawals; -use alloy_genesis::GenesisAccount; use alloy_primitives::{keccak256, Address, Bloom, Bytes, B256, B64, U256}; use reth_chainspec::{ChainSpec, ChainSpecBuilder, EthereumHardfork, ForkCondition}; use reth_db_api::{cursor::DbDupCursorRO, tables, transaction::DbTx}; use reth_primitives_traits::SealedHeader; +use seismic_alloy_genesis::GenesisAccount; use serde::Deserialize; use std::{collections::BTreeMap, ops::Deref}; + +use alloy_primitives::FlaggedStorage;   /// The definition of a blockchain test. #[derive(Debug, PartialEq, Eq, Deserialize)] @@ -155,6 +157,7 @@ impl State { /// Return state as genesis state. pub fn into_genesis_state(self) -> BTreeMap<Address, GenesisAccount> { + let is_private = false; // testing helper assume no private state self.0 .into_iter() .map(|(address, account)| { @@ -165,7 +168,10 @@ .filter(|(_, v)| !v.is_zero()) .map(|(k, v)| { ( B256::from_slice(&k.to_be_bytes::<32>()), - B256::from_slice(&v.to_be_bytes::<32>()), + FlaggedStorage::new( + U256::from_be_bytes(v.to_be_bytes::<32>()), + is_private, + ), ) }) .collect(); @@ -237,7 +243,7 @@ { if U256::from_be_bytes(entry.key.0) == *slot { assert_equal( *value, - entry.value, + entry.value.value, &format!("Storage for slot {slot:?} does not match"), )?; } else {
diff --git reth/testing/testing-utils/Cargo.toml seismic-reth/testing/testing-utils/Cargo.toml index 06e73631ef88a8d6ecb765b40eef87ec469272a7..36a89d4072006867852ecefe6864b4d1415d3b3c 100644 --- reth/testing/testing-utils/Cargo.toml +++ seismic-reth/testing/testing-utils/Cargo.toml @@ -15,7 +15,7 @@ [dependencies] reth-ethereum-primitives = { workspace = true, features = ["arbitrary", "std"] } reth-primitives-traits = { workspace = true, features = ["secp256k1", "arbitrary"] }   -alloy-genesis.workspace = true +seismic-alloy-genesis.workspace = true alloy-primitives = { workspace = true, features = ["rand"] } alloy-consensus.workspace = true alloy-eips.workspace = true
diff --git reth/testing/testing-utils/src/generators.rs seismic-reth/testing/testing-utils/src/generators.rs index b35ae13a819500e019d6352ebca2984982145cdd..0373b38538eefa7fb0e9e3e8cdc45c1be698eb7d 100644 --- reth/testing/testing-utils/src/generators.rs +++ seismic-reth/testing/testing-utils/src/generators.rs @@ -8,7 +8,7 @@ eip1898::BlockWithParent, eip4895::{Withdrawal, Withdrawals}, NumHash, }; -use alloy_primitives::{Address, BlockNumber, Bytes, TxKind, B256, B64, U256}; +use alloy_primitives::{Address, BlockNumber, Bytes, FlaggedStorage, TxKind, B256, B64, U256}; pub use rand::Rng; use rand::{distr::uniform::SampleRange, rngs::StdRng, SeedableRng}; use reth_ethereum_primitives::{Block, BlockBody, Receipt, Transaction, TransactionSigned}; @@ -313,7 +313,9 @@ IAcc: IntoIterator<Item = (Address, (Account, Vec<StorageEntry>))>, { let mut state: BTreeMap<_, _> = accounts .into_iter() - .map(|(addr, (acc, st))| (addr, (acc, st.into_iter().map(|e| (e.key, e.value)).collect()))) + .map(|(addr, (acc, st))| { + (addr, (acc, st.into_iter().map(|e| (e.key, e.value)).collect::<BTreeMap<_, _>>())) + }) .collect();   let valid_addresses = state.keys().copied().collect::<Vec<_>>(); @@ -337,21 +339,31 @@ transfer = max(min(transfer, prev_from.balance), U256::from(1)); prev_from.balance = prev_from.balance.wrapping_sub(transfer);   // deposit in receiving account and update storage - let (prev_to, storage): &mut (Account, BTreeMap<B256, U256>) = state.get_mut(&to).unwrap(); + let (prev_to, storage): &mut (Account, BTreeMap<B256, FlaggedStorage>) = + state.get_mut(&to).unwrap();   let mut old_entries: Vec<_> = new_entries .into_iter() .filter_map(|entry| { let old = if entry.value.is_zero() { let old = storage.remove(&entry.key); - if matches!(old, Some(U256::ZERO)) { - return None + if let Some(old_stored) = old { + if old_stored.is_zero() { + return None; + } } old } else { storage.insert(entry.key, entry.value) }; - Some(StorageEntry { value: old.unwrap_or(U256::ZERO), ..entry }) + match old { + Some(old_value) => { + return Some(StorageEntry { value: old_value, ..entry }); + } + None => { + return Some(StorageEntry { key: entry.key, value: FlaggedStorage::ZERO }); + } + } }) .collect(); old_entries.sort_by_key(|entry| entry.key); @@ -412,7 +424,7 @@ m }); let value = U256::from(rng.random::<u64>());   - StorageEntry { key, value } + StorageEntry::new(key, value, false) }   /// Generate random Externally Owned Account (EOA account without contract).
diff --git reth/testing/testing-utils/src/genesis_allocator.rs seismic-reth/testing/testing-utils/src/genesis_allocator.rs index e486f884a89e19f689563ed06162c5c883e434f9..1764a0657f4b7b9927c872629cf7e2321596939a 100644 --- reth/testing/testing-utils/src/genesis_allocator.rs +++ seismic-reth/testing/testing-utils/src/genesis_allocator.rs @@ -1,13 +1,13 @@ //! Helps create a custom genesis alloc by making it easy to add funded accounts with known //! signers to the genesis block.   -use alloy_genesis::GenesisAccount; use alloy_primitives::{Address, Bytes, B256, U256}; use reth_primitives_traits::crypto::secp256k1::public_key_to_address; use secp256k1::{ rand::{thread_rng, RngCore}, Keypair, Secp256k1, }; +use seismic_alloy_genesis::GenesisAccount; use std::{ collections::{hash_map::Entry, BTreeMap, HashMap}, fmt, @@ -109,6 +109,8 @@ let secp = Secp256k1::new(); let pair = Keypair::new(&secp, &mut self.rng); let address = public_key_to_address(pair.public_key());   + let storage = seismic_alloy_genesis::convert_fixedbytes_map_to_flagged_storage(storage); + self.alloc.insert( address, GenesisAccount::default().with_balance(balance).with_storage(Some(storage)), @@ -128,6 +130,8 @@ ) -> (Keypair, Address) { let secp = Secp256k1::new(); let pair = Keypair::new(&secp, &mut self.rng); let address = public_key_to_address(pair.public_key()); + + let storage = seismic_alloy_genesis::convert_fixedbytes_map_to_flagged_storage(storage);   self.alloc.insert( address,
diff --git reth/testing/testing-utils/src/lib.rs seismic-reth/testing/testing-utils/src/lib.rs index c593d306468ffeec1309f55291f4e08832df1f48..8a574899c36d6f8228bf3a7b5526c7e735d98d76 100644 --- reth/testing/testing-utils/src/lib.rs +++ seismic-reth/testing/testing-utils/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/testing/viem-tests/.env.example seismic-reth/testing/viem-tests/.env.example new file mode 100644 index 0000000000000000000000000000000000000000..2d89e008c475b08c0e56ab58893312e488c260f2 --- /dev/null +++ seismic-reth/testing/viem-tests/.env.example @@ -0,0 +1,3 @@ +SRETH_ROOT=/home/runner/work/seismic-reth/seismic-reth # should point to the root of the local seismic-reth repo +RETH_DATA_DIR=~/.seismic-reth/data +RETH_STATIC_FILES=~/.seismic-reth/static_files \ No newline at end of file
diff --git reth/testing/viem-tests/.gitignore seismic-reth/testing/viem-tests/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a14702c409d3f34f9ab001e572dfeaf0da434bba --- /dev/null +++ seismic-reth/testing/viem-tests/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store
diff --git reth/testing/viem-tests/package.json seismic-reth/testing/viem-tests/package.json new file mode 100644 index 0000000000000000000000000000000000000000..1f03a5d1942e9ed7bdb1377d79b74f55c5c67f21 --- /dev/null +++ seismic-reth/testing/viem-tests/package.json @@ -0,0 +1,20 @@ +{ + "name": "client-tests", + "private": true, + "scripts": { + "test": "bun test" + }, + "module": "index.ts", + "type": "module", + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5.8.2" + }, + "dependencies": { + "seismic-viem": "^1.1.0", + "seismic-viem-tests": "^0.1.2", + "viem": "^2.44.1" + } +}
diff --git reth/testing/viem-tests/tsconfig.json seismic-reth/testing/viem-tests/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..238655f2ce24cd6f677057d7eaa8822e75aeb6b8 --- /dev/null +++ seismic-reth/testing/viem-tests/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +}
diff --git reth/testing/viem-tests/viem.test.ts seismic-reth/testing/viem-tests/viem.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..3ead3677c8dcd07eaf67bde1f84330f3b764e232 --- /dev/null +++ seismic-reth/testing/viem-tests/viem.test.ts @@ -0,0 +1,211 @@ +import { encodeFunctionData, http, parseEther, stringToBytes, stringToHex, type Chain } from "viem"; +import { + AesGcmCrypto, + createShieldedWalletClient, + localSeismicDevnet, + randomEncryptionNonce, + signSeismicTxTypedData, + stringifyBigInt, +} from "seismic-viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { beforeAll, afterAll, describe, test, expect } from "bun:test"; +import { + setupNode, + testAesKeygen, + testAesGcm, + testEcdh, + testHkdfHex, + testHkdfString, + testRng, + testRngWithPers, + testSecp256k1, + testSeismicCallTypedData, + testSeismicTx, + testSeismicTxEncoding, + testSeismicTxTypedData, + testSeismicTxTrace, + testWsConnection, + buildNode, + testLegacyTxTrace, + setupRethNode, +} from "seismic-viem-tests"; + +const TIMEOUT_MS = 20_000 +const LONG_TIMEOUT_MS = 60_000 +const chain = localSeismicDevnet +const port = 8545 + +const TEST_ACCOUNT_PRIVATE_KEY = + "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; +const account = privateKeyToAccount(TEST_ACCOUNT_PRIVATE_KEY); +const encryptionSk = + "0x311d54d3bf8359c70827122a44a7b4458733adce3c51c6b59d9acfce85e07505"; +const encryptionPubkey = + "0x028e76821eb4d77fd30223ca971c49738eb5b5b71eabe93f96b348fdce788ae5a0"; + +let url: string +let wsUrl: string +let exitProcess: () => Promise<void>; +let pcParams: { chain: Chain; url: string }; + +const HOST: string | null = null // "node-2.seismicdev.net"; + +beforeAll(async () => { + if (HOST !== null) { + url = `https://${HOST}/rpc`; + wsUrl = `wss://${HOST}/ws`; + exitProcess = async () => { + process.exit(0); + } + return + } + await buildNode(chain); + const debug = false; + const baseArgs = { port, ws: true, devBlockTimeSeconds: 1 } + const rethArgs = debug + ? { silent: false, verbosity: 4, ...baseArgs } + : baseArgs + + const node = await setupRethNode(rethArgs) + pcParams = { chain, url: node.url } + exitProcess = node.exitProcess; + url = node.url + wsUrl = `ws://localhost:${port}` +}); + +describe("Seismic Contract", async () => { + test( + "deploy & call contracts with seismic tx", + async () => { + await testSeismicTx({ chain, url, account }); + }, + { + timeout: LONG_TIMEOUT_MS, + } + ); +}); + +describe("Seismic Transaction Encoding", async () => { + test( + "node detects and parses seismic transaction", + async () => { + await testSeismicTxEncoding({ + chain, + account, + url, + encryptionSk, + encryptionPubkey, + }); + }, + { + timeout: TIMEOUT_MS, + } + ); +}); + +describe("Typed Data", async () => { + test( + "client can sign a seismic typed message", + async () => { + await testSeismicCallTypedData({ + chain, + account, + url, + encryptionSk, + encryptionPubkey, + }); + }, + { timeout: TIMEOUT_MS } + ); + + test( + "client can sign via eth_signTypedData", + async () => { + await testSeismicTxTypedData({ + account, + chain, + url, + encryptionSk, + encryptionPubkey, + }); + }, + { timeout: TIMEOUT_MS } + ); +}); + +describe("AES", async () => { + test("generates AES key correctly", testAesKeygen); +}); + +describe("Websocket Connection", () => { + test( + "should connect to the ws", + async () => { + await testWsConnection({ + chain, + wsUrl, + }); + }, + { timeout: TIMEOUT_MS } + ); +}); + +describe("Seismic Precompiles", async () => { + test("RNG(1)", async () => await testRng({ chain, url }, 1), { + timeout: TIMEOUT_MS, + }); + test("RNG(8)", async () => await testRng({ chain, url }, 8), { + timeout: TIMEOUT_MS, + }); + test("RNG(16)", async () => await testRng({ chain, url }, 16), { + timeout: TIMEOUT_MS, + }); + test("RNG(32)", async () => await testRng({ chain, url }, 32), { + timeout: TIMEOUT_MS, + }); + test( + "RNG(32, pers)", + async () => await testRngWithPers({ chain, url }, 32), + { + timeout: TIMEOUT_MS, + } + ); + test("ECDH", async () => await testEcdh({ chain, url }), { + timeout: TIMEOUT_MS, + }); + test("HKDF(string)", async () => await testHkdfString({ chain, url }), { + timeout: TIMEOUT_MS, + }); + test("HKDF(hex)", async () => await testHkdfHex({ chain, url }), { + timeout: TIMEOUT_MS, + }); + test("AES-GCM", async () => await testAesGcm({ chain, url }), { + timeout: TIMEOUT_MS, + }); + test("secp256k1", async () => await testSecp256k1({ chain, url }), { + timeout: TIMEOUT_MS, + }); +}); + +describe("Transaction Trace", async () => { + test( + "Seismic Tx removes input from trace", + async () => { + await testSeismicTxTrace({ chain, url, account }); + }, + { + timeout: TIMEOUT_MS, + } + ); + test( + "Legacy Tx keeps input in trace", + async () => { + await testLegacyTxTrace({ chain, url, account }); + }, + { timeout: TIMEOUT_MS } + ); +}); + +afterAll(async () => { + await exitProcess?.(); +});
diff --git reth/crates/e2e-test-utils/Cargo.toml seismic-reth/crates/e2e-test-utils/Cargo.toml index 015732bd05d7edb8123286ee1288d186089a1445..d2566ff63882bdb7fd6c7ebf3127b18479dee51b 100644 --- reth/crates/e2e-test-utils/Cargo.toml +++ seismic-reth/crates/e2e-test-utils/Cargo.toml @@ -11,6 +11,10 @@ [lints] workspace = true   [dependencies] +# Seismic pre-merge +op-alloy-rpc-types-engine = { workspace = true, optional = true } + +# upstream reth-chainspec.workspace = true reth-tracing.workspace = true reth-db = { workspace = true, features = ["test-utils"] } @@ -32,6 +36,7 @@ reth-stages-types.workspace = true reth-network-peers.workspace = true reth-engine-local.workspace = true reth-tasks.workspace = true +reth-evm.workspace = true reth-node-ethereum.workspace = true reth-ethereum-primitives.workspace = true reth-cli-commands.workspace = true @@ -67,6 +72,9 @@ tokio-stream.workspace = true serde_json.workspace = true tracing.workspace = true derive_more.workspace = true + +[features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"]   [[test]] name = "e2e_testsuite"
diff --git reth/crates/e2e-test-utils/src/lib.rs seismic-reth/crates/e2e-test-utils/src/lib.rs index 0037197f261654fa3ca18be536e78cbbbed0f7f6..2b6b7449630b226fe176bdaa503b06a5e7b6e34a 100644 --- reth/crates/e2e-test-utils/src/lib.rs +++ seismic-reth/crates/e2e-test-utils/src/lib.rs @@ -224,7 +224,9 @@ // Type aliases   /// Testing database pub type TmpDB = Arc<TempDatabase<DatabaseEnv>>; -type TmpNodeAdapter<N, Provider = BlockchainProvider<NodeTypesWithDBAdapter<N, TmpDB>>> = + +/// Type alias for a testing `FullNodeTypesAdapter` +pub type TmpNodeAdapter<N, Provider = BlockchainProvider<NodeTypesWithDBAdapter<N, TmpDB>>> = FullNodeTypesAdapter<N, TmpDB, Provider>;   /// Type alias for a `NodeAdapter`
diff --git reth/crates/e2e-test-utils/src/node.rs seismic-reth/crates/e2e-test-utils/src/node.rs index 72698134d75955675093e4c55acdc3de71255e25..0639f5f722399cb4876c9390d539e512d36d9f96 100644 --- reth/crates/e2e-test-utils/src/node.rs +++ seismic-reth/crates/e2e-test-utils/src/node.rs @@ -21,11 +21,14 @@ BlockReader, BlockReaderIdExt, CanonStateNotificationStream, CanonStateSubscriptions, HeaderProvider, StageCheckpointReader, }; use reth_rpc_builder::auth::AuthServerHandle; -use reth_rpc_eth_api::helpers::{EthApiSpec, EthTransactions, TraceExt}; +use reth_rpc_eth_api::helpers::{EthApiSpec, TraceExt}; // upstream needs EthTransactions, use reth_stages_types::StageId; use std::pin::Pin; use tokio_stream::StreamExt; use url::Url; + +// seismic imports that upstream doesn't use +use reth_rpc_eth_api::helpers::FullEthApi;   /// A helper struct to handle node actions #[expect(missing_debug_implementations)] @@ -88,9 +91,8 @@ length: u64, tx_generator: impl Fn(u64) -> Pin<Box<dyn Future<Output = Bytes>>>, ) -> eyre::Result<Vec<Payload::BuiltPayload>> where - AddOns::EthApi: EthApiSpec<Provider: BlockReader<Block = BlockTy<Node::Types>>> - + EthTransactions - + TraceExt, + AddOns::EthApi: + EthApiSpec<Provider: BlockReader<Block = BlockTy<Node::Types>>> + FullEthApi + TraceExt, { let mut chain = Vec::with_capacity(length as usize); for i in 0..length {
diff --git reth/crates/e2e-test-utils/src/payload.rs seismic-reth/crates/e2e-test-utils/src/payload.rs index b3f9b027fbadcb0cb437a5d27669d0d2373ab0f6..82285dbfb23927b7d97c20dbc657a2457fa7480a 100644 --- reth/crates/e2e-test-utils/src/payload.rs +++ seismic-reth/crates/e2e-test-utils/src/payload.rs @@ -54,15 +54,18 @@ } Ok(()) }   - /// Wait until the best built payload is ready + /// Wait until the best built payload is ready. + /// Accepts empty payloads after a timeout to avoid spinning forever when the pool is empty. pub async fn wait_for_built_payload(&self, payload_id: PayloadId) { + let deadline = tokio::time::Instant::now() + std::time::Duration::from_secs(10); loop { let payload = self.payload_builder.best_payload(payload_id).await.unwrap().unwrap(); - if payload.block().body().transactions().is_empty() { + let is_empty = payload.block().body().transactions().is_empty(); + if is_empty && tokio::time::Instant::now() < deadline { tokio::time::sleep(std::time::Duration::from_millis(20)).await; continue } - // Resolve payload once its built + // Resolve payload once it's built (or accept empty after timeout) self.payload_builder .resolve_kind(payload_id, PayloadKind::Earliest) .await
diff --git reth/crates/e2e-test-utils/src/rpc.rs seismic-reth/crates/e2e-test-utils/src/rpc.rs index 96dda81173524b886f5acfa015cb2f6a0638c9e7..a28016f41fc98a9dd4b4bc1f3648eec6eb96a95f 100644 --- reth/crates/e2e-test-utils/src/rpc.rs +++ seismic-reth/crates/e2e-test-utils/src/rpc.rs @@ -1,14 +1,16 @@ use alloy_consensus::TxEnvelope; +use alloy_eips::{BlockId, BlockNumberOrTag}; use alloy_network::eip2718::Decodable2718; -use alloy_primitives::{Bytes, B256}; +use alloy_primitives::{Address, Bytes, B256}; +use alloy_rpc_types_eth::Account; use reth_chainspec::EthereumHardforks; use reth_node_api::{BlockTy, FullNodeComponents}; use reth_node_builder::{rpc::RpcRegistry, NodeTypes}; use reth_provider::BlockReader; use reth_rpc_api::DebugApiServer; use reth_rpc_eth_api::{ - helpers::{EthApiSpec, EthTransactions, TraceExt}, - EthApiTypes, + helpers::{EthApiSpec, EthState, FullEthApi, TraceExt}, + EthApiTypes, RpcReceipt, };   #[expect(missing_debug_implementations)] @@ -19,9 +21,7 @@ impl<Node, EthApi> RpcTestContext<Node, EthApi> where Node: FullNodeComponents<Types: NodeTypes<ChainSpec: EthereumHardforks>>, - EthApi: EthApiSpec<Provider: BlockReader<Block = BlockTy<Node::Types>>> - + EthTransactions - + TraceExt, + EthApi: EthApiSpec<Provider: BlockReader<Block = BlockTy<Node::Types>>> + FullEthApi + TraceExt, { /// Injects a raw transaction into the node tx pool via RPC server pub async fn inject_tx(&self, raw_tx: Bytes) -> Result<B256, EthApi::Error> { @@ -34,5 +34,43 @@ pub async fn envelope_by_hash(&self, hash: B256) -> eyre::Result<TxEnvelope> { let tx = self.inner.debug_api().raw_transaction(hash).await?.unwrap(); let tx = tx.to_vec(); Ok(TxEnvelope::decode_2718(&mut tx.as_ref()).unwrap()) + } + + /// get transaction receipt + pub async fn transaction_receipt( + &self, + tx_hash: B256, + ) -> Result<Option<RpcReceipt<EthApi::NetworkTypes>>, EthApi::Error> { + let eth_api = self.inner.eth_api(); + eth_api.transaction_receipt(tx_hash).await + } + + /// get code + pub async fn get_code( + &self, + address: Address, + block_number: u64, + ) -> Result<Bytes, EthApi::Error> { + let eth_api = self.inner.eth_api(); + EthState::get_code( + eth_api, + address, + Some(BlockId::Number(BlockNumberOrTag::Number(block_number.into()))), + ) + .await + } + + pub async fn get_account( + &self, + address: Address, + block_number: u64, + ) -> Result<Option<Account>, EthApi::Error> { + let eth_api = self.inner.eth_api(); + EthState::get_account( + eth_api, + address, + BlockId::Number(BlockNumberOrTag::Number(block_number.into())), + ) + .await } }
diff --git reth/crates/e2e-test-utils/src/setup_import.rs seismic-reth/crates/e2e-test-utils/src/setup_import.rs index 81e5a386aac8bd25dd3530a2f9a40b033a7deb13..268a4e4574958346513e7a1195530f165d4a89f3 100644 --- reth/crates/e2e-test-utils/src/setup_import.rs +++ seismic-reth/crates/e2e-test-utils/src/setup_import.rs @@ -1,12 +1,17 @@ //! Setup utilities for importing RLP chain data before starting nodes.   -use crate::{node::NodeTestContext, NodeHelperType, Wallet}; +use crate::{ + node::NodeTestContext, NodeBuilderHelper, NodeHelperType, PayloadAttributesBuilder, TmpDB, + Wallet, +}; use reth_chainspec::ChainSpec; use reth_cli_commands::import_core::{import_blocks_from_file, ImportConfig}; use reth_config::Config; use reth_db::DatabaseEnv; -use reth_node_api::{NodeTypesWithDBAdapter, TreeConfig}; -use reth_node_builder::{EngineNodeLauncher, Node, NodeBuilder, NodeConfig, NodeHandle}; +use reth_engine_local::LocalPayloadAttributesBuilder; +use reth_evm::ConfigureEvm; +use reth_node_api::{NodeTypes, NodeTypesWithDBAdapter, PayloadTypes, TreeConfig}; +use reth_node_builder::{EngineNodeLauncher, NodeBuilder, NodeConfig, NodeHandle}; use reth_node_core::args::{DiscoveryArgs, NetworkArgs, RpcServerArgs}; use reth_node_ethereum::EthereumNode; use reth_provider::{ @@ -21,9 +26,13 @@ use tempfile::TempDir; use tracing::{debug, info, span, Level};   /// Setup result containing nodes and temporary directories that must be kept alive -pub struct ChainImportResult { +pub struct ChainImportResult<N: NodeBuilderHelper = EthereumNode> +where + LocalPayloadAttributesBuilder<N::ChainSpec>: + PayloadAttributesBuilder<<<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes>, +{ /// The nodes that were created - pub nodes: Vec<NodeHelperType<EthereumNode>>, + pub nodes: Vec<NodeHelperType<N, BlockchainProvider<NodeTypesWithDBAdapter<N, TmpDB>>>>, /// The task manager pub task_manager: TaskManager, /// The wallet for testing @@ -32,7 +41,11 @@ /// Temporary directories that must be kept alive for the duration of the test pub _temp_dirs: Vec<TempDir>, }   -impl std::fmt::Debug for ChainImportResult { +impl<N: NodeBuilderHelper> std::fmt::Debug for ChainImportResult<N> +where + LocalPayloadAttributesBuilder<N::ChainSpec>: + PayloadAttributesBuilder<<<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes>, +{ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ChainImportResult") .field("nodes", &self.nodes.len()) @@ -56,28 +69,36 @@ /// by abstracting the import process. /// It uses `NoopConsensus` during import to bypass validation checks like gas limit constraints, /// which allows importing test chains that may not strictly conform to mainnet consensus rules. The /// nodes themselves still run with proper consensus when started. -pub async fn setup_engine_with_chain_import( +pub async fn setup_engine_with_chain_import<N>( num_nodes: usize, chain_spec: Arc<ChainSpec>, is_dev: bool, tree_config: TreeConfig, rlp_path: &Path, - attributes_generator: impl Fn(u64) -> reth_payload_builder::EthPayloadBuilderAttributes + attributes_generator: impl Fn(u64) -> <<N as NodeTypes>::Payload as PayloadTypes>::PayloadBuilderAttributes + Send + Sync + Copy + 'static, -) -> eyre::Result<ChainImportResult> { + evm_config: impl ConfigureEvm<Primitives = N::Primitives> + Clone + 'static, +) -> eyre::Result<ChainImportResult<N>> +where + N: NodeBuilderHelper, + LocalPayloadAttributesBuilder<N::ChainSpec>: + PayloadAttributesBuilder<<<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes>, +{ let tasks = TaskManager::current(); let exec = tasks.executor();   + let n_chain_spec = Arc::new(N::ChainSpec::from((*chain_spec).clone())); + let network_config = NetworkArgs { discovery: DiscoveryArgs { disable_discovery: true, ..DiscoveryArgs::default() }, ..NetworkArgs::default() };   // Create nodes with imported data - let mut nodes: Vec<NodeHelperType<EthereumNode>> = Vec::with_capacity(num_nodes); + let mut nodes = Vec::with_capacity(num_nodes); let mut temp_dirs = Vec::with_capacity(num_nodes); // Keep temp dirs alive   for idx in 0..num_nodes { @@ -85,7 +106,7 @@ // Create a temporary datadir for this node let temp_dir = TempDir::new()?; let datadir = temp_dir.path().to_path_buf();   - let mut node_config = NodeConfig::new(chain_spec.clone()) + let mut node_config = NodeConfig::new(n_chain_spec.clone()) .with_network(network_config.clone()) .with_unused_ports() .with_rpc( @@ -119,11 +140,9 @@ let db = Arc::new(db_env);   // Create a provider factory with the initialized database (use regular DB, not // TempDatabase) We need to specify the node types properly for the adapter - let provider_factory = ProviderFactory::< - NodeTypesWithDBAdapter<EthereumNode, Arc<DatabaseEnv>>, - >::new( + let provider_factory = ProviderFactory::<NodeTypesWithDBAdapter<N, Arc<DatabaseEnv>>>::new( db.clone(), - chain_spec.clone(), + n_chain_spec.clone(), reth_provider::providers::StaticFileProvider::read_write(static_files_path.clone())?, );   @@ -135,8 +154,8 @@ // Use no_state to skip state validation for test chains let import_config = ImportConfig::default(); let config = Config::default();   - // Create EVM and consensus for Ethereum - let evm_config = reth_node_ethereum::EthEvmConfig::new(chain_spec.clone()); + // Create EVM and consensus + let evm_config = evm_config.clone(); // Use NoopConsensus to skip gas limit validation for test imports let consensus = reth_consensus::noop::NoopConsensus::arc();   @@ -214,11 +233,11 @@ debug!(target: "e2e::import", "Launching node with datadir: {:?}", datadir);   // Use the testing_node_with_datadir method which properly handles opening existing // databases - let node = EthereumNode::default(); + let node = N::default();   let NodeHandle { node, node_exit_future: _ } = NodeBuilder::new(node_config.clone()) .testing_node_with_datadir(exec.clone(), datadir.clone()) - .with_types_and_provider::<EthereumNode, BlockchainProvider<_>>() + .with_types_and_provider::<N, BlockchainProvider<_>>() .with_components(node.components_builder()) .with_add_ons(node.add_ons()) .launch_with_fn(|builder| { @@ -282,6 +301,7 @@ }; use std::path::PathBuf;   #[tokio::test] + #[ignore] async fn test_stage_checkpoints_persistence() { // This test specifically verifies that stage checkpoints are persisted correctly // when reopening the database @@ -451,6 +471,7 @@ (test_blocks, rlp_path) }   #[tokio::test] + #[ignore] async fn test_import_blocks_only() { // Tests just the block import functionality without full node setup reth_tracing::init_test_tracing(); @@ -519,6 +540,7 @@ assert_eq!(block_10_hash, test_blocks[9].hash(), "Block 10 hash should match"); }   #[tokio::test] + #[ignore] async fn test_import_with_node_integration() { // Tests the full integration with node setup, forkchoice updates, and syncing reth_tracing::init_test_tracing(); @@ -535,13 +557,14 @@ std::fs::write(&fcu_path, create_fcu_json(tip).to_string()) .expect("Failed to write FCU data");   // Setup nodes with imported chain - let result = setup_engine_with_chain_import( + let result = setup_engine_with_chain_import::<EthereumNode>( 1, - chain_spec, + chain_spec.clone(), false, TreeConfig::default(), &rlp_path, |_| EthPayloadBuilderAttributes::default(), + reth_node_ethereum::EthEvmConfig::new(chain_spec), ) .await .expect("Failed to setup nodes with chain import");
diff --git reth/crates/e2e-test-utils/src/testsuite/mod.rs seismic-reth/crates/e2e-test-utils/src/testsuite/mod.rs index b172a8d0e9fb575011ee8f3c7390855d78a6627e..d3f0ced2780ec113883193f5067ef0326fc2ffd0 100644 --- reth/crates/e2e-test-utils/src/testsuite/mod.rs +++ seismic-reth/crates/e2e-test-utils/src/testsuite/mod.rs @@ -320,13 +320,14 @@ self.actions.extend(actions.into_iter().map(ActionBox::new)); self }   - /// Run the test scenario + /// Run the test scenario using the default EthEvmConfig for chain imports. pub async fn run<N>(mut self) -> Result<()> where N: NodeBuilderHelper, LocalPayloadAttributesBuilder<N::ChainSpec>: PayloadAttributesBuilder< <<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes, >, + reth_node_ethereum::EthEvmConfig: reth_evm::ConfigureEvm<Primitives = N::Primitives>, { let mut setup = self.setup.take();   @@ -340,8 +341,41 @@ for action in actions { action.execute(&mut self.env).await?; }   - // explicitly drop the setup to shutdown the nodes - // after all actions have completed + drop(setup); + + Ok(()) + } + + /// Run the test scenario with a custom EVM config for chain imports. + /// Use this when the node type requires a non-Ethereum EVM config (e.g., SeismicNode). + pub async fn run_with_evm<N>( + mut self, + evm_config: impl reth_evm::ConfigureEvm<Primitives = N::Primitives> + Clone + 'static, + ) -> Result<()> + where + N: NodeBuilderHelper, + LocalPayloadAttributesBuilder<N::ChainSpec>: PayloadAttributesBuilder< + <<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes, + >, + { + let mut setup = self.setup.take(); + + if let Some(ref mut s) = setup { + if let Some(rlp_path) = s.import_rlp_path.take() { + s.apply_with_import_and_evm::<N>(&mut self.env, &rlp_path, evm_config).await?; + } else { + // No import path — this shouldn't need a custom EVM config, + // but we still need to set up the nodes + return Err(eyre::eyre!("run_with_evm requires with_setup_and_import to be called")); + } + } + + let actions = std::mem::take(&mut self.actions); + + for action in actions { + action.execute(&mut self.env).await?; + } + drop(setup);   Ok(())
diff --git reth/crates/e2e-test-utils/src/testsuite/setup.rs seismic-reth/crates/e2e-test-utils/src/testsuite/setup.rs index a13518149f62550d4c4363f2093491f416e54607..f1af4305f581672183601efe6a67ef8eba29030b 100644 --- reth/crates/e2e-test-utils/src/testsuite/setup.rs +++ seismic-reth/crates/e2e-test-utils/src/testsuite/setup.rs @@ -11,12 +11,13 @@ use eyre::{eyre, Result}; use reth_chainspec::ChainSpec; use reth_engine_local::LocalPayloadAttributesBuilder; use reth_ethereum_primitives::Block; +use reth_evm::ConfigureEvm; use reth_network_p2p::sync::{NetworkSyncUpdater, SyncState}; use reth_node_api::{EngineTypes, NodeTypes, PayloadTypes, TreeConfig}; use reth_node_core::primitives::RecoveredBlock; use reth_payload_builder::EthPayloadBuilderAttributes; use revm::state::EvmState; -use std::{marker::PhantomData, path::Path, sync::Arc}; +use std::{any::Any, marker::PhantomData, path::Path, sync::Arc}; use tokio::{ sync::mpsc, time::{sleep, Duration}, @@ -46,7 +47,7 @@ /// Tracks instance generic. _phantom: PhantomData<I>, /// Holds the import result to keep nodes alive when using imported chain /// This is stored as an option to avoid lifetime issues with `tokio::spawn` - import_result_holder: Option<crate::setup_import::ChainImportResult>, + import_result_holder: Option<Box<dyn Any + Send + Sync>>, /// Path to RLP file to import during setup pub import_rlp_path: Option<std::path::PathBuf>, } @@ -135,7 +136,23 @@ self.tree_config = tree_config; self }   - /// Apply setup using pre-imported chain data from RLP file + /// Apply setup using pre-imported chain data from RLP file with a custom EVM config. + pub async fn apply_with_import_and_evm<N>( + &mut self, + env: &mut Environment<I>, + rlp_path: &Path, + evm_config: impl ConfigureEvm<Primitives = N::Primitives> + Clone + 'static, + ) -> Result<()> + where + N: NodeBuilderHelper, + LocalPayloadAttributesBuilder<N::ChainSpec>: PayloadAttributesBuilder< + <<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes, + >, + { + Box::pin(self.apply_with_import_inner::<N>(env, rlp_path, evm_config)).await + } + + /// Apply setup using pre-imported chain data with the default EthEvmConfig. pub async fn apply_with_import<N>( &mut self, env: &mut Environment<I>, @@ -146,16 +163,20 @@ N: NodeBuilderHelper, LocalPayloadAttributesBuilder<N::ChainSpec>: PayloadAttributesBuilder< <<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes, >, + reth_node_ethereum::EthEvmConfig: ConfigureEvm<Primitives = N::Primitives>, { - // Note: this future is quite large so we box it - Box::pin(self.apply_with_import_::<N>(env, rlp_path)).await + let chain_spec = + self.chain_spec.clone().ok_or_else(|| eyre!("Chain specification is required"))?; + let evm_config = reth_node_ethereum::EthEvmConfig::new(chain_spec); + Box::pin(self.apply_with_import_inner::<N>(env, rlp_path, evm_config)).await }   - /// Apply setup using pre-imported chain data from RLP file - async fn apply_with_import_<N>( + /// Inner implementation for importing chain data with any EVM config. + async fn apply_with_import_inner<N>( &mut self, env: &mut Environment<I>, rlp_path: &Path, + evm_config: impl ConfigureEvm<Primitives = N::Primitives> + Clone + 'static, ) -> Result<()> where N: NodeBuilderHelper, @@ -164,7 +185,7 @@ <<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes, >, { // Create nodes with imported chain data - let import_result = self.create_nodes_with_import::<N>(rlp_path).await?; + let import_result = self.create_nodes_with_import::<N>(rlp_path, evm_config).await?;   // Extract node clients let mut node_clients = Vec::new(); @@ -178,23 +199,30 @@ let url = node.rpc_url(); node_clients.push(crate::testsuite::NodeClient::new(rpc, auth, url)); }   + // Set sync state to Idle for imported nodes before storing + for (idx, node_ctx) in import_result.nodes.iter().enumerate() { + debug!("Setting sync state to Idle for node {}", idx); + node_ctx.inner.network.update_sync_state(SyncState::Idle); + } + // Store the import result to keep nodes alive // They will be dropped when the Setup is dropped - self.import_result_holder = Some(import_result); + self.import_result_holder = Some(Box::new(import_result));   // Finalize setup - this will wait for nodes and initialize states self.finalize_setup(env, node_clients, true).await }   - /// Apply the setup to the environment + /// Apply the setup to the environment. + /// For chain imports with non-Ethereum nodes, use `apply_with_import_and_evm` instead. pub async fn apply<N>(&mut self, env: &mut Environment<I>) -> Result<()> where N: NodeBuilderHelper, LocalPayloadAttributesBuilder<N::ChainSpec>: PayloadAttributesBuilder< <<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes, >, + reth_node_ethereum::EthEvmConfig: ConfigureEvm<Primitives = N::Primitives>, { - // Note: this future is quite large so we box it Box::pin(self.apply_::<N>(env)).await }   @@ -205,6 +233,7 @@ N: NodeBuilderHelper, LocalPayloadAttributesBuilder<N::ChainSpec>: PayloadAttributesBuilder< <<N as NodeTypes>::Payload as PayloadTypes>::PayloadAttributes, >, + reth_node_ethereum::EthEvmConfig: ConfigureEvm<Primitives = N::Primitives>, { // If import_rlp_path is set, use apply_with_import instead if let Some(rlp_path) = self.import_rlp_path.take() { @@ -265,14 +294,11 @@ self.finalize_setup(env, node_clients, false).await }   /// Create nodes with imported chain data - /// - /// Note: Currently this only supports `EthereumNode` due to the import process - /// being Ethereum-specific. The generic parameter N is kept for consistency - /// with other methods but is not used. async fn create_nodes_with_import<N>( &self, rlp_path: &Path, - ) -> Result<crate::setup_import::ChainImportResult> + evm_config: impl ConfigureEvm<Primitives = N::Primitives> + Clone + 'static, + ) -> Result<crate::setup_import::ChainImportResult<N>> where N: NodeBuilderHelper, LocalPayloadAttributesBuilder<N::ChainSpec>: PayloadAttributesBuilder< @@ -290,16 +316,19 @@ suggested_fee_recipient: alloy_primitives::Address::ZERO, withdrawals: Some(vec![]), parent_beacon_block_root: Some(B256::ZERO), }; - EthPayloadBuilderAttributes::new(B256::ZERO, attributes) + <<N as NodeTypes>::Payload as PayloadTypes>::PayloadBuilderAttributes::from( + EthPayloadBuilderAttributes::new(B256::ZERO, attributes), + ) };   - crate::setup_import::setup_engine_with_chain_import( + crate::setup_import::setup_engine_with_chain_import::<N>( self.network.node_count, chain_spec, self.is_dev, self.tree_config.clone(), rlp_path, attributes_generator, + evm_config, ) .await } @@ -380,15 +409,6 @@ debug!( "Environment initialized with {} nodes, starting from block {} (hash: {})", self.network.node_count, initial_block_info.number, initial_block_info.hash ); - - // In test environments, explicitly set sync state to Idle after initialization - // This ensures that eth_syncing returns false as expected by tests - if let Some(import_result) = &self.import_result_holder { - for (idx, node_ctx) in import_result.nodes.iter().enumerate() { - debug!("Setting sync state to Idle for node {}", idx); - node_ctx.inner.network.update_sync_state(SyncState::Idle); - } - }   Ok(()) }

Changes to CICD workflows to support our custom testing and deployment.

diff --git reth/.github/CODEOWNERS seismic-reth/.github/CODEOWNERS index 01fe80522d5191f16d8665713f2ca30c8d9b09a9..69e65037b472b0dbdd027d50f922333d142c9cf6 100644 --- reth/.github/CODEOWNERS +++ seismic-reth/.github/CODEOWNERS @@ -1,45 +1 @@ -* @gakonst -crates/blockchain-tree-api/ @rakita @rkrasiuk @mattsse @Rjected -crates/blockchain-tree/ @rakita @rkrasiuk @mattsse @Rjected -crates/chain-state/ @fgimenez @mattsse @rkrasiuk -crates/chainspec/ @Rjected @joshieDo @mattsse -crates/cli/ @mattsse -crates/consensus/ @rkrasiuk @mattsse @Rjected -crates/e2e-test-utils/ @mattsse @Rjected -crates/engine @rkrasiuk @mattsse @Rjected -crates/engine/ @rkrasiuk @mattsse @Rjected @fgimenez -crates/era/ @mattsse @RomanHodulak -crates/errors/ @mattsse -crates/ethereum-forks/ @mattsse @Rjected -crates/ethereum/ @mattsse @Rjected -crates/etl/ @joshieDo @shekhirin -crates/evm/ @rakita @mattsse @Rjected -crates/exex/ @shekhirin -crates/net/ @mattsse @Rjected -crates/net/downloaders/ @rkrasiuk -crates/node/ @mattsse @Rjected @klkvr -crates/optimism/ @mattsse @Rjected @fgimenez -crates/payload/ @mattsse @Rjected -crates/primitives-traits/ @Rjected @RomanHodulak @mattsse @klkvr -crates/primitives/ @Rjected @mattsse @klkvr -crates/prune/ @shekhirin @joshieDo -crates/ress @rkrasiuk -crates/revm/ @mattsse @rakita -crates/rpc/ @mattsse @Rjected @RomanHodulak -crates/stages/ @rkrasiuk @shekhirin -crates/static-file/ @joshieDo @shekhirin -crates/storage/codecs/ @joshieDo -crates/storage/db-api/ @joshieDo @rakita -crates/storage/db-common/ @Rjected -crates/storage/db/ @joshieDo @rakita -crates/storage/errors/ @rakita -crates/storage/libmdbx-rs/ @rakita @shekhirin -crates/storage/nippy-jar/ @joshieDo @shekhirin -crates/storage/provider/ @rakita @joshieDo @shekhirin -crates/storage/storage-api/ @joshieDo @rkrasiuk -crates/tasks/ @mattsse -crates/tokio-util/ @fgimenez -crates/transaction-pool/ @mattsse -crates/trie/ @rkrasiuk @Rjected @shekhirin @mediocregopher -etc/ @Rjected @shekhirin -.github/ @gakonst @DaniPopes +* @cdrappi
diff --git reth/.github/ISSUE_TEMPLATE/bug.yml seismic-reth/.github/ISSUE_TEMPLATE/bug.yml index b01d4518f75d5cd25c2e93555448031fa6363627..a86f05c33469fa701ace3031a6743299839005d8 100644 --- reth/.github/ISSUE_TEMPLATE/bug.yml +++ seismic-reth/.github/ISSUE_TEMPLATE/bug.yml @@ -121,7 +121,7 @@ - type: checkboxes id: terms attributes: label: Code of Conduct - description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/paradigmxyz/reth/blob/main/CONTRIBUTING.md#code-of-conduct) + description: By submitting this issue, you agree to follow our [Code of Conduct](https://github.com/SeismicSystems/seismic-reth/blob/main/CONTRIBUTING.md#code-of-conduct) options: - label: I agree to follow the Code of Conduct required: true
diff --git reth/.github/ISSUE_TEMPLATE/config.yml seismic-reth/.github/ISSUE_TEMPLATE/config.yml index cfefdb13a6952d34de48f6214c4bebbd9a6d6132..0747827ec18aaeb040aff37d2db2eab518439b96 100644 --- reth/.github/ISSUE_TEMPLATE/config.yml +++ seismic-reth/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,5 @@ blank_issues_enabled: false contact_links: - name: GitHub Discussions - url: https://github.com/paradigmxyz/reth/discussions + url: https://github.com/SeismicSystems/seismic-reth/discussions about: Please ask and answer questions here to keep the issue tracker clean.
diff --git reth/.github/assets/kurtosis_network_params.yaml seismic-reth/.github/assets/kurtosis_network_params.yaml index e8cc1b51dc81c88a77d3b881c90e65f57d0adc04..9dfb5b4e635cc970f8a245625cab6ca87ebb4181 100644 --- reth/.github/assets/kurtosis_network_params.yaml +++ seismic-reth/.github/assets/kurtosis_network_params.yaml @@ -2,6 +2,7 @@ participants: - el_type: geth cl_type: lighthouse - el_type: reth + # TODO: add for seismic el_image: "ghcr.io/paradigmxyz/reth:kurtosis-ci" cl_type: teku additional_services:
diff --git reth/.github/workflows/book.yml seismic-reth/.github/workflows/book.yml index 389bd34c700c9338cab1faffc45ae285c768c6e4..0048a7459aad34839a7424ee0f8c8f0bb3441242 100644 --- reth/.github/workflows/book.yml +++ seismic-reth/.github/workflows/book.yml @@ -4,11 +4,15 @@ name: book   on: push: - branches: [main] + branches: [seismic] pull_request: - branches: [main] + branches: [seismic] types: [opened, reopened, synchronize, closed] merge_group: + +env: + CARGO_TERM_COLOR: always + CARGO_NET_GIT_FETCH_WITH_CLI: true   jobs: build: @@ -48,8 +52,8 @@ with: path: "./docs/vocs/docs/dist"   deploy: - # Only deploy if a push to main - if: github.ref_name == 'main' && github.event_name == 'push' + # Only deploy if a push to seismic + if: github.ref_name == 'seismic' && github.event_name == 'push' runs-on: ubuntu-latest needs: [build]
diff --git reth/.github/workflows/claude.yml seismic-reth/.github/workflows/claude.yml new file mode 100644 index 0000000000000000000000000000000000000000..2d66e57ac5bac1041ce6ddad13653e728608575b --- /dev/null +++ seismic-reth/.github/workflows/claude.yml @@ -0,0 +1,113 @@ +# Claude Code PR Review +# +# Runs Claude in agent mode to review PRs, then posts the review as a +# sticky comment (one comment, edited in-place on each push). +# +# Agent mode doesn't post comments itself, so a post-step extracts +# Claude's text output from the execution file and manages the comment. +# +# Requires: ANTHROPIC_API_KEY secret. + +name: Claude Code PR Review + +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + issue_comment: + types: [created] + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.issue.number }} + cancel-in-progress: true + +jobs: + claude: + if: > + (github.event_name == 'pull_request' && + github.event.pull_request.draft == false && + github.event.pull_request.user.login != 'dependabot[bot]' && + !contains(github.head_ref, 'gh-readonly-queue/')) || + (github.event_name == 'issue_comment' && + contains(github.event.comment.body, '@claude') && + github.event.issue.pull_request && + contains(fromJSON('["OWNER","MEMBER","COLLABORATOR"]'), github.event.comment.author_association)) + runs-on: ubuntu-latest + timeout-minutes: 20 + permissions: + contents: read + pull-requests: write + + env: + PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }} + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Read review prompt + id: prompt + run: | + { + echo 'REVIEW_PROMPT<<EOF' + cat .claude/prompts/claude-pr-review.md + echo 'EOF' + } >> "$GITHUB_ENV" + + - uses: anthropics/claude-code-action@v1 + id: claude + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + github_token: ${{ secrets.GITHUB_TOKEN }} + claude_args: | + --model claude-sonnet-4-20250514 + --allowedTools "Read,Grep,Bash(gh pr diff:*),Bash(gh pr view:*),Bash(git log:*),Bash(git diff:*),Bash(git show:*)" + prompt: | + Review PR #${{ env.PR_NUMBER }} in ${{ github.repository }}. + + 1. Run `gh pr diff ${{ env.PR_NUMBER }}` to get the diff. + 2. Review ONLY the changed files following the guidelines below. + 3. Output your review as plain text. Do NOT post comments yourself. + 4. If the diff touches files in `crates/seismic/`, use Read and Grep to follow key imports and verify semantic correctness (e.g., check that setup functions use Seismic chain specs, not vanilla Ethereum ones). + + ${{ env.REVIEW_PROMPT }} + + - name: Post review comment + if: always() && steps.claude.outputs.execution_file + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + EXECUTION_FILE: ${{ steps.claude.outputs.execution_file }} + run: | + set -euo pipefail + + # Extract the last assistant text block from the execution JSON. + # The file is an array of turns. We want only the final assistant + # message's text (the review), not earlier conversational turns. + REVIEW=$(jq -r ' + [.[] | select(.type == "assistant")] | last + | .message.content[]? | select(.type == "text") | .text + ' "$EXECUTION_FILE") + + if [ -z "$REVIEW" ] || [ "$REVIEW" = "null" ]; then + echo "No review text found in execution output" + exit 0 + fi + + # Sticky comment: find existing review comment and update it, + # or create a new one. We use a hidden marker to identify our comments. + MARKER="<!-- claude-pr-review -->" + BODY="$(printf '%s\n%s' "$MARKER" "$REVIEW")" + + # Search for existing comment with our marker + COMMENT_ID=$(gh api "repos/${{ github.repository }}/issues/${{ env.PR_NUMBER }}/comments" \ + --jq "[.[] | select(.user.login == \"github-actions[bot]\") | select(.body | contains(\"$MARKER\")) | .id] | first // empty") + + if [ -n "$COMMENT_ID" ]; then + echo "Updating existing review comment $COMMENT_ID" + gh api "repos/${{ github.repository }}/issues/comments/$COMMENT_ID" \ + -X PATCH -f body="$BODY" + else + echo "Creating new review comment" + gh api "repos/${{ github.repository }}/issues/${{ env.PR_NUMBER }}/comments" \ + -f body="$BODY" + fi
diff --git reth/.github/workflows/eth-sync.yml seismic-reth/.github/workflows/eth-sync.yml new file mode 100644 index 0000000000000000000000000000000000000000..db6acb63d8fc624d3b83557b9aed648f1a26a2d4 --- /dev/null +++ seismic-reth/.github/workflows/eth-sync.yml @@ -0,0 +1,54 @@ +# Runs an ethereum mainnet sync test. + +name: eth-sync-test + +on: + pull_request: + merge_group: + push: + branches: [ main ] + +env: + CARGO_TERM_COLOR: always + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + sync: + name: sync / 100k blocks + # Only run sync tests in merge groups + if: github.event_name == 'merge_group' + runs-on: + group: Reth + env: + RUST_LOG: info,sync=error + RUST_BACKTRACE: 1 + timeout-minutes: 60 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + - name: Build reth + run: | + cargo install --features asm-keccak,jemalloc --path bin/reth + - name: Run sync + run: | + reth node \ + --debug.tip 0x91c90676cab257a59cd956d7cb0bceb9b1a71d79755c23c7277a0697ccfaf8c4 \ + --debug.max-block 100000 \ + --debug.terminate + - name: Verify the target block hash + run: | + reth db get static-file headers 100000 \ + | grep 0x91c90676cab257a59cd956d7cb0bceb9b1a71d79755c23c7277a0697ccfaf8c4 + - name: Run stage unwind for 100 blocks + run: | + reth stage unwind num-blocks 100 + - name: Run stage unwind to block hash + run: | + reth stage unwind to-block 0x52e0509d33a988ef807058e2980099ee3070187f7333aae12b64d4d675f34c5a +
diff --git reth/.github/workflows/gh-pages.yml seismic-reth/.github/workflows/gh-pages.yml new file mode 100644 index 0000000000000000000000000000000000000000..bf188d8aa99ad41015c060992a2a60f24101bda9 --- /dev/null +++ seismic-reth/.github/workflows/gh-pages.yml @@ -0,0 +1,47 @@ +name: Forkdiff Github-Pages +permissions: + contents: read + pages: write + id-token: write +on: + workflow_dispatch: + push: + branches: + - seismic + +jobs: + build: + concurrency: ci-${{ github.ref }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Build forkdiff + uses: "docker://protolambda/forkdiff:0.1.0" + with: + args: -repo=/github/workspace -fork=/github/workspace/fork.yaml -out=/github/workspace/index.html + + # upload-pages-artifact action requires the files to be in a _site folder + - name: Prepare for deployment + run: | + mkdir -p _site + mv index.html _site/ + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + + # This needs to run in the github-pages environment to deploy successfully. For more info see: + # https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4
diff --git reth/.github/workflows/kurtosis.yml seismic-reth/.github/workflows/kurtosis.yml index f78fc81235aef4fcb8b0156739dacb2da30bcc78..9aa30ae1c1b6c60a6b8d6d53c86d2bb70b829725 100644 --- reth/.github/workflows/kurtosis.yml +++ seismic-reth/.github/workflows/kurtosis.yml @@ -66,5 +66,5 @@ - name: Slack Webhook Action uses: rtCamp/action-slack-notify@v2 env: SLACK_COLOR: ${{ job.status }} - SLACK_MESSAGE: "Failed run: https://github.com/paradigmxyz/reth/actions/runs/${{ github.run_id }}" + SLACK_MESSAGE: "Failed run: https://github.com/SeismicSystems/seismic-reth/actions/runs/${{ github.run_id }}" SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
diff --git reth/.github/workflows/prepare-reth.yml seismic-reth/.github/workflows/prepare-reth.yml index 37a9445af721dda343b98838e8e385f358697eae..2f7f2fa4c57543a334c8c69d4781fc83b60353ae 100644 --- reth/.github/workflows/prepare-reth.yml +++ seismic-reth/.github/workflows/prepare-reth.yml @@ -24,7 +24,7 @@ description: "Optional cargo package path"   jobs: prepare-reth: - if: github.repository == 'paradigmxyz/reth' + if: github.repository == 'SeismicSystems/seismic-reth' timeout-minutes: 45 runs-on: group: Reth
diff --git reth/.github/workflows/release-dist.yml seismic-reth/.github/workflows/release-dist.yml index 57a6f311d0bdb14eb2e1cd846fcfb8b85111432b..95098b990bb1a06ad9f2f6fa523a552f635a4394 100644 --- reth/.github/workflows/release-dist.yml +++ seismic-reth/.github/workflows/release-dist.yml @@ -16,5 +16,6 @@ uses: dawidd6/action-homebrew-bump-formula@v5 with: token: ${{ secrets.HOMEBREW }} no_fork: true + # TODO: seismic tap: paradigmxyz/brew formula: reth
diff --git reth/.github/workflows/release.yml seismic-reth/.github/workflows/release.yml index 7a647c2968734bbb8546a3f3273423aee2831428..9bd76a95c4baedb1b48318677b5a66f295996748 100644 --- reth/.github/workflows/release.yml +++ seismic-reth/.github/workflows/release.yml @@ -183,6 +183,7 @@ GITHUB_USER: ${{ github.repository_owner }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # The formatting here is borrowed from Lighthouse (which is borrowed from OpenEthereum): # https://github.com/openethereum/openethereum/blob/6c2d392d867b058ff867c4373e40850ca3f96969/.github/workflows/build.yml + # TODO: seismic run: | prerelease_flag="" if [[ "${GITHUB_REF}" == *-rc* ]]; then
diff --git reth/.github/workflows/seismic.yml seismic-reth/.github/workflows/seismic.yml new file mode 100644 index 0000000000000000000000000000000000000000..85372bb41e723ba24ce0bee023f56076bbf72992 --- /dev/null +++ seismic-reth/.github/workflows/seismic.yml @@ -0,0 +1,115 @@ +name: Seismic CI + +on: + push: + branches: [seismic] + pull_request: + branches: [seismic] + +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +env: + CARGO_TERM_COLOR: always + CARGO_NET_GIT_FETCH_WITH_CLI: true + +jobs: + rustfmt: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@nightly + with: + components: rustfmt + - run: cargo fmt --all --check + + build: + runs-on: large-github-runner + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + shared-key: "build-cache" + - name: cargo check (workspace) + run: cargo check --workspace + + warnings: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + shared-key: "warnings-cache" + - name: cargo check warnings + run: RUSTFLAGS="-D warnings" cargo check + + clippy: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + components: clippy + - uses: Swatinem/rust-cache@v2 + with: + shared-key: "clippy-cache" + - name: Clippy (seismic crates) + run: | + cargo clippy \ + -p reth-seismic-primitives \ + -p reth-seismic-chainspec \ + -p reth-seismic-evm \ + -p reth-seismic-payload-builder \ + -p reth-seismic-node \ + -p reth-seismic-rpc \ + -p reth-seismic-cli \ + -p reth-seismic-txpool \ + -p reth-seismic-forks \ + -p seismic-reth \ + --lib --tests --no-deps \ + -- -D warnings \ + -W clippy::unwrap_used \ + -W clippy::expect_used \ + -W clippy::indexing_slicing \ + -W clippy::panic \ + -W clippy::unreachable \ + -W clippy::todo + + unit-test: + runs-on: large-github-runner + timeout-minutes: 30 + env: + SEISMIC_CI: 1 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: taiki-e/install-action@nextest + - uses: Swatinem/rust-cache@v2 + with: + shared-key: "integration-test-cache" + - name: seismic-node test + # see profile.default in .config/nextest.toml for filtered tests + run: cargo nextest run --workspace -E '!kind(test)' --no-fail-fast + + integration-test: + runs-on: large-github-runner + timeout-minutes: 30 + env: + SEISMIC_CI: 1 + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: taiki-e/install-action@nextest + - uses: Swatinem/rust-cache@v2 + with: + shared-key: "integration-test-cache" + - name: seismic-node test + # see profile.default in .config/nextest.toml for filtered tests + run: cargo nextest run --workspace -E 'kind(test)' --no-fail-fast
diff --git reth/.config/nextest.toml seismic-reth/.config/nextest.toml index 26b4a000b931b1a5721f2a61f4b99fe25d3d1185..52b08edac8ce31babdfac0582bde81be5a31cdbd 100644 --- reth/.config/nextest.toml +++ seismic-reth/.config/nextest.toml @@ -1,10 +1,10 @@ [profile.default] -retries = { backoff = "exponential", count = 2, delay = "2s", jitter = true } -slow-timeout = { period = "30s", terminate-after = 4 } +retries = { backoff = "exponential", count = 3, delay = "5s", jitter = true, max-delay = "30s" } +slow-timeout = { period = "300s", terminate-after = 6 }   [[profile.default.overrides]] -filter = "test(general_state_tests)" -slow-timeout = { period = "1m", terminate-after = 10 } +filter = 'test(general_state_tests)' +slow-timeout = { period = "2m", terminate-after = 15 }   [[profile.default.overrides]] filter = "test(eest_fixtures)" @@ -15,3 +15,4 @@ # These tests are located in tests/e2e-testsuite/ directories across various crates [[profile.default.overrides]] filter = "binary(e2e_testsuite)" slow-timeout = { period = "2m", terminate-after = 3 } +
diff --git reth/.gitignore seismic-reth/.gitignore index a9b9f4768d53b8b82007f2ee9f87cfa8b87f8314..5ecca65e39bd5c8b95d48a9d289d6aec3c5be291 100644 --- reth/.gitignore +++ seismic-reth/.gitignore @@ -1,3 +1,9 @@ +# seismic-viem tests +node_modules +bun.lock* +.env +.cursor + # Generated by Cargo # will have compiled files and executables ./debug/ @@ -33,8 +39,9 @@ # Database debugging tools db-tools/   -# VSCode -.vscode +# VSCode (use .vscode/settings.local.json for local/private settings) +.vscode/* +!.vscode/settings.json   # Coverage report lcov.info @@ -72,3 +79,6 @@ # direnv .envrc .direnv/ + +# forkdiff output +index.html
diff --git reth/.vscode/settings.json seismic-reth/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..1113f2dc1d59e1b7fa0651fa933d24216dbeca60 --- /dev/null +++ seismic-reth/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "rust-analyzer.rustfmt.extraArgs": [ + "+nightly" + ] +}
diff --git reth/Cargo.toml seismic-reth/Cargo.toml index a4e39d05e98b0908fdf0b0a88fba65d608580b8f..c9b9684c2216de4662b2f8194a342de9a85d5bf2 100644 --- reth/Cargo.toml +++ seismic-reth/Cargo.toml @@ -3,14 +3,30 @@ version = "1.7.0" edition = "2021" rust-version = "1.88" license = "MIT OR Apache-2.0" -homepage = "https://paradigmxyz.github.io/reth" -repository = "https://github.com/paradigmxyz/reth" +homepage = "https://github.com/SeismicSystems/seismic-reth" +repository = "https://github.com/SeismicSystems/seismic-reth" exclude = [".github/"]   [workspace] members = [ - "bin/reth-bench/", - "bin/reth/", + # Seismic crates + "bin/seismic-reth/", + "bin/genesis-builder/", + "crates/seismic/chainspec", + "crates/seismic/cli", + "crates/seismic/evm/", + "crates/seismic/node/", + "crates/seismic/payload/", + "crates/seismic/primitives/", + "crates/seismic/reth/", + "crates/seismic/rpc/", + "crates/seismic/txpool/", + "crates/seismic/hardforks", + "crates/seismic/fuzz", + "crates/genesis-builder", + + # "bin/reth-bench/", + # "bin/reth/", "crates/storage/rpc-provider/", "crates/chain-state/", "crates/chainspec/", @@ -71,20 +87,21 @@ "crates/node/ethstats", "crates/node/events/", "crates/node/metrics", "crates/node/types", - "crates/optimism/bin", - "crates/optimism/chainspec", - "crates/optimism/cli", - "crates/optimism/consensus", - "crates/optimism/evm/", - "crates/optimism/flashblocks/", - "crates/optimism/hardforks/", - "crates/optimism/node/", - "crates/optimism/payload/", - "crates/optimism/primitives/", - "crates/optimism/reth/", - "crates/optimism/rpc/", - "crates/optimism/storage", - "crates/optimism/txpool/", + # seismic: these crates don't compile because of type changes we made that affects them, such as FlaggedStorage. + # "crates/optimism/bin", + # "crates/optimism/chainspec", + # "crates/optimism/cli", + # "crates/optimism/consensus", + # "crates/optimism/evm/", + # "crates/optimism/flashblocks/", + # "crates/optimism/hardforks/", + # "crates/optimism/node/", + # "crates/optimism/payload/", + # "crates/optimism/primitives/", + # "crates/optimism/reth/", + # "crates/optimism/rpc/", + # "crates/optimism/storage", + # "crates/optimism/txpool/", "crates/payload/basic/", "crates/payload/builder/", "crates/payload/builder-primitives/", @@ -139,43 +156,43 @@ "crates/trie/parallel/", "crates/trie/sparse", "crates/trie/sparse-parallel/", "crates/trie/trie", - "examples/beacon-api-sidecar-fetcher/", - "examples/beacon-api-sse/", - "examples/bsc-p2p", - "examples/custom-dev-node/", - "examples/custom-node/", - "examples/custom-engine-types/", - "examples/custom-evm/", - "examples/custom-inspector/", - "examples/custom-node-components/", - "examples/custom-payload-builder/", - "examples/custom-rlpx-subprotocol", - "examples/custom-node", - "examples/db-access", - "examples/engine-api-access", - "examples/exex-hello-world", - "examples/exex-subscription", - "examples/exex-test", - "examples/full-contract-state", - "examples/manual-p2p/", - "examples/network-txpool/", - "examples/network/", - "examples/network-proxy/", - "examples/node-builder-api/", - "examples/node-custom-rpc/", - "examples/node-event-hooks/", - "examples/op-db-access/", - "examples/polygon-p2p/", - "examples/rpc-db/", - "examples/precompile-cache/", - "examples/txpool-tracing/", - "examples/custom-beacon-withdrawals", + # "examples/beacon-api-sidecar-fetcher/", + # "examples/beacon-api-sse/", + # "examples/bsc-p2p", + # "examples/custom-dev-node/", + # "examples/custom-node/", + # "examples/custom-engine-types/", + # "examples/custom-evm/", + # "examples/custom-inspector/", + # "examples/custom-node-components/", + # "examples/custom-payload-builder/", + # "examples/custom-rlpx-subprotocol", + # "examples/custom-node", + # "examples/db-access", + # "examples/engine-api-access", + # "examples/exex-hello-world", + # "examples/exex-subscription", + # "examples/exex-test", + # "examples/full-contract-state", + # "examples/manual-p2p/", + # "examples/network-txpool/", + # "examples/network/", + # "examples/network-proxy/", + # "examples/node-builder-api/", + # "examples/node-custom-rpc/", + # "examples/node-event-hooks/", + # "examples/op-db-access/", + # "examples/polygon-p2p/", + # "examples/rpc-db/", + # "examples/precompile-cache/", + # "examples/txpool-tracing/", + # "examples/custom-beacon-withdrawals", "testing/ef-tests/", "testing/testing-utils", "testing/runner", "crates/tracing-otlp", ] -default-members = ["bin/reth"] +default-members = ["bin/seismic-reth", "bin/genesis-builder"] exclude = ["docs/cli"]   # Explicitly set the resolver to version 2, which is the default for packages with edition >= 2021 @@ -317,7 +334,11 @@ strip = "none"   # Include debug info in benchmarks too. [profile.bench] -inherits = "profiling" +opt-level = 3 +lto = "thin" +debug = "full" +strip = "none" +codegen-units = 16   [profile.maxperf] inherits = "release" @@ -325,8 +346,37 @@ lto = "fat" codegen-units = 1   [workspace.dependencies] + +# seismic dependencies +# reth-seismic-bin = { path = "crates/seismic/bin" } +reth-seismic-chainspec = { path = "crates/seismic/chainspec" } +reth-seismic-cli = { path = "crates/seismic/cli" } +reth-seismic-evm = { path = "crates/seismic/evm" } +reth-seismic-node = { path = "crates/seismic/node" } +reth-seismic-chain-registry = { path = "crates/seismic/chain-registry" } +reth-seismic-payload-builder = { path = "crates/seismic/payload" } +reth-seismic-primitives = { path = "crates/seismic/primitives" } +reth-seismic-reth = { path = "crates/seismic/reth" } +reth-seismic-rpc = { path = "crates/seismic/rpc" } +reth-seismic-txpool = { path = "crates/seismic/txpool" } +reth-seismic-forks = { path = "crates/seismic/hardforks", default-features = false } +reth-seismic-fuzz = { path = "crates/seismic/fuzz" } + +seismic-enclave = "0.1.0" +seismic-revm = "1.0.0" +alloy-seismic-evm = "0.20.1" + +seismic-alloy-rpc-types = { version = "0.0.1", default-features = false } +seismic-alloy-consensus = { version = "0.0.1", default-features = false } +seismic-alloy-provider = { version = "0.0.1", default-features = false } +seismic-alloy-genesis = { version = "0.0.1", default-features = false } +seismic-alloy-rpc-types-engine = { version = "0.0.1", default-features = false } +seismic-alloy-network = { version = "0.0.1", default-features = false } +seismic-alloy-flz = { version = "0.0.1", default-features = false } + +alloy-json-abi = { version = "1.1.2", default-features = false } # only used by seismic rn + # reth -op-reth = { path = "crates/optimism/bin" } reth = { path = "bin/reth" } reth-storage-rpc-provider = { path = "crates/storage/rpc-provider" } reth-basic-payload-builder = { path = "crates/payload/basic" } @@ -374,13 +424,13 @@ reth-ethereum = { path = "crates/ethereum/reth" } reth-etl = { path = "crates/etl" } reth-evm = { path = "crates/evm/evm", default-features = false } reth-evm-ethereum = { path = "crates/ethereum/evm", default-features = false } -reth-optimism-evm = { path = "crates/optimism/evm", default-features = false } reth-execution-errors = { path = "crates/evm/execution-errors", default-features = false } reth-execution-types = { path = "crates/evm/execution-types", default-features = false } reth-exex = { path = "crates/exex/exex" } reth-exex-test-utils = { path = "crates/exex/test-utils" } reth-exex-types = { path = "crates/exex/types" } reth-fs-util = { path = "crates/fs-util" } +reth-genesis-builder = { path = "crates/genesis-builder" } reth-invalid-block-hooks = { path = "crates/engine/invalid-block-hooks" } reth-ipc = { path = "crates/rpc/ipc" } reth-libmdbx = { path = "crates/storage/libmdbx-rs" } @@ -401,18 +451,7 @@ reth-node-ethereum = { path = "crates/ethereum/node" } reth-node-ethstats = { path = "crates/node/ethstats" } reth-node-events = { path = "crates/node/events" } reth-node-metrics = { path = "crates/node/metrics" } -reth-optimism-node = { path = "crates/optimism/node" } reth-node-types = { path = "crates/node/types" } -reth-op = { path = "crates/optimism/reth", default-features = false } -reth-optimism-chainspec = { path = "crates/optimism/chainspec", default-features = false } -reth-optimism-cli = { path = "crates/optimism/cli" } -reth-optimism-consensus = { path = "crates/optimism/consensus", default-features = false } -reth-optimism-forks = { path = "crates/optimism/hardforks", default-features = false } -reth-optimism-payload-builder = { path = "crates/optimism/payload" } -reth-optimism-primitives = { path = "crates/optimism/primitives", default-features = false } -reth-optimism-rpc = { path = "crates/optimism/rpc" } -reth-optimism-storage = { path = "crates/optimism/storage" } -reth-optimism-txpool = { path = "crates/optimism/txpool" } reth-payload-builder = { path = "crates/payload/builder" } reth-payload-builder-primitives = { path = "crates/payload/builder-primitives" } reth-payload-primitives = { path = "crates/payload/primitives" } @@ -433,7 +472,6 @@ reth-rpc-engine-api = { path = "crates/rpc/rpc-engine-api" } reth-rpc-eth-api = { path = "crates/rpc/rpc-eth-api" } reth-rpc-eth-types = { path = "crates/rpc/rpc-eth-types", default-features = false } reth-rpc-layer = { path = "crates/rpc/rpc-layer" } -reth-optimism-flashblocks = { path = "crates/optimism/flashblocks" } reth-rpc-server-types = { path = "crates/rpc/rpc-server-types" } reth-rpc-convert = { path = "crates/rpc/rpc-convert" } reth-stages = { path = "crates/stages/stages" } @@ -484,39 +522,39 @@ alloy-sol-macro = "1.3.1" alloy-sol-types = { version = "1.3.1", default-features = false } alloy-trie = { version = "0.9.1", default-features = false }   -alloy-hardforks = "0.3.1" +alloy-hardforks = "=0.3.1"   -alloy-consensus = { version = "1.0.30", default-features = false } -alloy-contract = { version = "1.0.30", default-features = false } -alloy-eips = { version = "1.0.30", default-features = false } -alloy-genesis = { version = "1.0.30", default-features = false } -alloy-json-rpc = { version = "1.0.30", default-features = false } -alloy-network = { version = "1.0.30", default-features = false } -alloy-network-primitives = { version = "1.0.30", default-features = false } -alloy-provider = { version = "1.0.30", features = ["reqwest"], default-features = false } -alloy-pubsub = { version = "1.0.30", default-features = false } -alloy-rpc-client = { version = "1.0.30", default-features = false } -alloy-rpc-types = { version = "1.0.30", features = ["eth"], default-features = false } -alloy-rpc-types-admin = { version = "1.0.30", default-features = false } -alloy-rpc-types-anvil = { version = "1.0.30", default-features = false } -alloy-rpc-types-beacon = { version = "1.0.30", default-features = false } -alloy-rpc-types-debug = { version = "1.0.30", default-features = false } -alloy-rpc-types-engine = { version = "1.0.30", default-features = false } -alloy-rpc-types-eth = { version = "1.0.30", default-features = false } -alloy-rpc-types-mev = { version = "1.0.30", default-features = false } -alloy-rpc-types-trace = { version = "1.0.30", default-features = false } -alloy-rpc-types-txpool = { version = "1.0.30", default-features = false } -alloy-serde = { version = "1.0.30", default-features = false } -alloy-signer = { version = "1.0.30", default-features = false } -alloy-signer-local = { version = "1.0.30", default-features = false } -alloy-transport = { version = "1.0.30" } -alloy-transport-http = { version = "1.0.30", features = ["reqwest-rustls-tls"], default-features = false } -alloy-transport-ipc = { version = "1.0.30", default-features = false } -alloy-transport-ws = { version = "1.0.30", default-features = false } +alloy-consensus = { version = "=1.1.0", default-features = false } +alloy-contract = { version = "=1.1.0", default-features = false } +alloy-eips = { version = "=1.1.0", default-features = false } +alloy-genesis = { version = "=1.1.0", default-features = false } +alloy-json-rpc = { version = "=1.1.0", default-features = false } +alloy-network = { version = "=1.1.0", default-features = false } +alloy-network-primitives = { version = "=1.1.0", default-features = false } +alloy-provider = { version = "=1.1.0", features = ["reqwest"], default-features = false } +alloy-pubsub = { version = "=1.1.0", default-features = false } +alloy-rpc-client = { version = "=1.1.0", default-features = false } +alloy-rpc-types = { version = "=1.1.0", features = ["eth"], default-features = false } +alloy-rpc-types-admin = { version = "=1.1.0", default-features = false } +alloy-rpc-types-anvil = { version = "=1.1.0", default-features = false } +alloy-rpc-types-beacon = { version = "=1.1.0", default-features = false } +alloy-rpc-types-debug = { version = "=1.1.0", default-features = false } +alloy-rpc-types-engine = { version = "=1.1.0", default-features = false } +alloy-rpc-types-eth = { version = "=1.1.0", default-features = false } +alloy-rpc-types-mev = { version = "=1.1.0", default-features = false } +alloy-rpc-types-trace = { version = "=1.1.0", default-features = false } +alloy-rpc-types-txpool = { version = "=1.1.0", default-features = false } +alloy-serde = { version = "=1.1.0", default-features = false } +alloy-signer = { version = "=1.1.0", default-features = false } +alloy-signer-local = { version = "=1.1.0", default-features = false } +alloy-transport = { version = "=1.1.0" } +alloy-transport-http = { version = "=1.1.0", features = ["reqwest-rustls-tls"], default-features = false } +alloy-transport-ipc = { version = "=1.1.0", default-features = false } +alloy-transport-ws = { version = "=1.1.0", default-features = false }   # op alloy-op-evm = { version = "0.20.1", default-features = false } -alloy-op-hardforks = "0.3.1" +alloy-op-hardforks = "=0.3.1" op-alloy-rpc-types = { version = "0.19.0", default-features = false } op-alloy-rpc-types-engine = { version = "0.19.0", default-features = false } op-alloy-network = { version = "0.19.0", default-features = false } @@ -542,7 +580,7 @@ dirs-next = "2.0.0" dyn-clone = "1.0.17" eyre = "0.6" fdlimit = "0.3.0" -generic-array = "0.14" +generic-array = "=0.14.7" humantime = "2.1" humantime-serde = "1.1" itertools = { version = "0.14", default-features = false } @@ -632,6 +670,7 @@ # crypto enr = { version = "0.13", default-features = false } k256 = { version = "0.13", default-features = false, features = ["ecdsa"] } secp256k1 = { version = "0.30", default-features = false, features = ["global-context", "recovery"] } +schnorrkel = { version = "0.11.2" } # rand 8 for secp256k1 rand_08 = { package = "rand", version = "0.8" }   @@ -713,45 +752,44 @@ visibility = "0.1.1" walkdir = "2.3.3" vergen-git2 = "1.0.5"   -# [patch.crates-io] -# alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-genesis = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-json-rpc = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-network = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-network-primitives = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-provider = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-pubsub = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-admin = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-anvil = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-beacon = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-debug = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-eth = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-mev = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-trace = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-rpc-types-txpool = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-serde = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-signer = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-signer-local = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-transport = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } -# alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "3049f232fbb44d1909883e154eb38ec5962f53a3" } +[patch.crates-io] +# Seismic enclave +seismic-enclave = { git = "https://github.com/SeismicSystems/enclave.git", rev = "f90b02f38a6190e8b2ff2d051d9043f3480cd3ac" } + +# seismic-alloy-core +alloy-primitives = { git = "https://github.com/SeismicSystems/seismic-alloy-core.git", rev = "994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" } +alloy-json-abi = { git = "https://github.com/SeismicSystems/seismic-alloy-core.git", rev = "994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" } +alloy-sol-macro-expander = { git = "https://github.com/SeismicSystems/seismic-alloy-core.git", rev = "994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" } +alloy-sol-macro-input = { git = "https://github.com/SeismicSystems/seismic-alloy-core.git", rev = "994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" } +alloy-sol-types = { git = "https://github.com/SeismicSystems/seismic-alloy-core.git", rev = "994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" } +alloy-sol-type-parser = { git = "https://github.com/SeismicSystems/seismic-alloy-core.git", rev = "994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" } +alloy-dyn-abi = { git = "https://github.com/SeismicSystems/seismic-alloy-core.git", rev = "994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" } + +alloy-trie = { git = "https://github.com/SeismicSystems/seismic-trie.git", rev = "2787e2265d492fa8eaee00424585b8f7e522178f" } + +# revm +revm = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-bytecode = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-database = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-state = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-primitives = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-interpreter = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-inspector = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-context = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-context-interface = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +revm-database-interface = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +op-revm = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } +seismic-revm = { git = "https://github.com/SeismicSystems/seismic-revm.git", rev = "2861f865d2b9249ebb0da4946be5052ec8ab41a0" } + +revm-inspectors = { git = "https://github.com/SeismicSystems/seismic-revm-inspectors.git", rev = "24652f3b9ef6a8057bc46203b26d1d9857f7ae30" } + +# Seismic alloy +seismic-alloy-consensus = { git = "https://github.com/SeismicSystems/seismic-alloy.git", rev = "c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" } +seismic-alloy-rpc-types = { git = "https://github.com/SeismicSystems/seismic-alloy.git", rev = "c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" } +seismic-alloy-network = { git = "https://github.com/SeismicSystems/seismic-alloy.git", rev = "c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" } +seismic-alloy-provider = { git = "https://github.com/SeismicSystems/seismic-alloy.git", rev = "c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" } +seismic-alloy-genesis = { git = "https://github.com/SeismicSystems/seismic-alloy.git", rev = "c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" }   -# op-alloy-consensus = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# op-alloy-network = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# op-alloy-rpc-types = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# op-alloy-rpc-types-engine = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# op-alloy-rpc-jsonrpsee = { git = "https://github.com/alloy-rs/op-alloy", rev = "a79d6fc" } -# -# revm-inspectors = { git = "https://github.com/paradigmxyz/revm-inspectors", rev = "1207e33" } -# -# jsonrpsee = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } -# jsonrpsee-core = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } -# jsonrpsee-server = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } -# jsonrpsee-http-client = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } -# jsonrpsee-types = { git = "https://github.com/paradigmxyz/jsonrpsee", branch = "matt/make-rpc-service-pub" } +# evm +alloy-evm = { git = "https://github.com/SeismicSystems/seismic-evm.git", rev = "c33f3076495d153eefbde07dd81c3a575f3d19b8" } +alloy-seismic-evm = { git = "https://github.com/SeismicSystems/seismic-evm.git", rev = "c33f3076495d153eefbde07dd81c3a575f3d19b8" }
diff --git reth/Dockerfile seismic-reth/Dockerfile index fc97c160bbc88793b95612c4459dc49feb73e479..7f193f31b73d126eb4c5f825a40013826f198c09 100644 --- reth/Dockerfile +++ seismic-reth/Dockerfile @@ -1,20 +1,27 @@ -# syntax=docker.io/docker/dockerfile:1.7-labs - +# Use cargo-chef for build caching FROM lukemathwalker/cargo-chef:latest-rust-1 AS chef WORKDIR /app   -LABEL org.opencontainers.image.source=https://github.com/paradigmxyz/reth +LABEL org.opencontainers.image.source=https://github.com/SeismicSystems/seismic-reth LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0"   # Install system dependencies RUN apt-get update && apt-get -y upgrade && apt-get install -y libclang-dev pkg-config   -# Builds a cargo-chef plan +# Build the cargo-chef plan FROM chef AS planner -COPY --exclude=.git --exclude=dist . . + +COPY ./bin/ ./bin/ +COPY ./crates/ ./crates/ +COPY ./testing/ ./testing/ +COPY ./examples/ ./examples/ +COPY Cargo.toml Cargo.lock deny.toml Makefile ./ RUN cargo chef prepare --recipe-path recipe.json   +# Build the application FROM chef AS builder +# Setting up SSH for GitHub access +RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts COPY --from=planner /app/recipe.json recipe.json   # Build profile, release by default @@ -29,26 +36,60 @@ # Extra Cargo features ARG FEATURES="" ENV FEATURES=$FEATURES   -# Builds dependencies -RUN cargo chef cook --profile $BUILD_PROFILE --features "$FEATURES" --recipe-path recipe.json +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true +# Build dependencies +RUN --mount=type=ssh cargo chef cook --profile $BUILD_PROFILE --features "$FEATURES" --recipe-path recipe.json   # Build application COPY --exclude=dist . . -RUN cargo build --profile $BUILD_PROFILE --features "$FEATURES" --locked --bin reth +RUN cargo build --profile $BUILD_PROFILE --features "$FEATURES" --locked --bin seismic-reth   -# ARG is not resolved in COPY so we have to hack around it by copying the -# binary to a temporary location -RUN cp /app/target/$BUILD_PROFILE/reth /app/reth +# Copy the binary to a temporary location +RUN cp /app/target/$BUILD_PROFILE/seismic-reth /app/seismic-reth   -# Use Ubuntu as the release image -FROM ubuntu AS runtime +# Use Ubuntu as the runtime image +FROM ubuntu:latest AS runtime WORKDIR /app   # Copy reth over from the build stage -COPY --from=builder /app/reth /usr/local/bin +COPY --from=builder /app/seismic-reth /usr/local/bin   -# Copy licenses +# Copy license files COPY LICENSE-* ./   -EXPOSE 30303 30303/udp 9001 8545 8546 -ENTRYPOINT ["/usr/local/bin/reth"] +# Define the ENTRYPOINT to run the reth node with the specified arguments +ENV HTTP_PORT=8545 +ENV WS_PORT=8546 +ENV AUTHRPC_PORT=8551 +ENV METRICS_PORT=9001 +ENV PEER_PORT=30303 +ENV DISCOVERY_PORT=30303 + +# Expose the necessary ports +EXPOSE \ + $HTTP_PORT \ + $WS_PORT \ + $AUTHRPC_PORT \ + $METRICS_PORT \ + $PEER_PORT \ + $DISCOVERY_PORT \ + 30303/udp + +# ENTRYPOINT /usr/local/bin/seismic-reth node \ +# --dev \ +# -vvvv \ +# --http \ +# --http.addr 0.0.0.0 \ +# --http.port $HTTP_PORT \ +# --http.api all \ +# --ws \ +# --ws.addr 0.0.0.0 \ +# --ws.port $WS_PORT \ +# --ws.api all \ +# --authrpc.addr 0.0.0.0 \ +# --authrpc.port $AUTHRPC_PORT \ +# --port $PEER_PORT \ +# --discovery.port $DISCOVERY_PORT \ +# --metrics $METRICS_PORT + +ENTRYPOINT ["/usr/local/bin/seismic-reth"]
diff --git reth/Dockerfile.cross seismic-reth/Dockerfile.cross index f477f1ed3e0b81b10b5167e5cc00704ad77abf74..e52412cdd5f87da2d0b55852a43baf9378f8a739 100644 --- reth/Dockerfile.cross +++ seismic-reth/Dockerfile.cross @@ -3,7 +3,7 @@ # It assumes the reth binary has already been compiled for `$TARGETPLATFORM` and is # locatable in `./dist/bin/$TARGETARCH` FROM --platform=$TARGETPLATFORM ubuntu:22.04   -LABEL org.opencontainers.image.source=https://github.com/paradigmxyz/reth +LABEL org.opencontainers.image.source=https://github.com/SeismicSystems/seismic-reth LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0"   # Filled by docker buildx
diff --git reth/DockerfileOp.cross seismic-reth/DockerfileOp.cross index 47606a828305d04c0d1723c2c47afe7bac925c2d..584e698542d8965c03076cabd25aff9b4ebbfaa9 100644 --- reth/DockerfileOp.cross +++ seismic-reth/DockerfileOp.cross @@ -3,7 +3,7 @@ # It assumes the reth binary has already been compiled for `$TARGETPLATFORM` and is # locatable in `./dist/bin/$TARGETARCH` FROM --platform=$TARGETPLATFORM ubuntu:22.04   -LABEL org.opencontainers.image.source=https://github.com/paradigmxyz/reth +LABEL org.opencontainers.image.source=https://github.com/SeismicSystems/seismic-reth LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0"   # Filled by docker buildx
diff --git reth/Makefile seismic-reth/Makefile index 30f6b0aa4783519e2a07cdfdcfa64bb2b7cb2568..cb4e3b807c1de7527649b65daa7d92b1a31c74c9 100644 --- reth/Makefile +++ seismic-reth/Makefile @@ -36,6 +36,7 @@ EEST_TESTS_URL := https://github.com/ethereum/execution-spec-tests/releases/download/$(EEST_TESTS_TAG)/fixtures_stable.tar.gz EEST_TESTS_DIR := ./testing/ef-tests/execution-spec-tests   # The docker image name +# TODO: publish one for seismic DOCKER_IMAGE_NAME ?= ghcr.io/paradigmxyz/reth   ##@ Help @@ -490,7 +491,20 @@ --enable-index-page -Zunstable-options -D warnings" \ cargo +nightly docs \ --document-private-items   -cargo-test: +test-seismic-reth :## see profile.default in .config/nextest.toml for filtered tests + cargo nextest run --workspace +test-reth: + cargo test \ + --workspace \ + --bin "reth" \ + --exclude optimism \ + --lib \ + --examples \ + --tests \ + --benches \ + --features "ethereum $(BIN_OTHER_FEATURES)" + +test-op-reth: cargo test \ --workspace \ --bin "op-reth" \ @@ -503,8 +517,10 @@ test-doc: cargo test --doc --workspace --all-features   test: - make cargo-test && \ - make test-doc + make test-reth && \ + make test-seismic-reth && \ + make test-doc && \ + make test-other-targets   pr: make lint && \
diff --git reth/assets/seismic-reth-beta.png seismic-reth/assets/seismic-reth-beta.png new file mode 100644 index 0000000000000000000000000000000000000000..c87ed634f985b299a1c9b9b0b72c28c2282c74ca Binary files /dev/null and seismic-reth/assets/seismic-reth-beta.png differ
diff --git reth/assets/seismic-reth-prod.png seismic-reth/assets/seismic-reth-prod.png new file mode 100644 index 0000000000000000000000000000000000000000..9121bd104fe59050fd9be27f6160d42fe8b7f0e5 Binary files /dev/null and seismic-reth/assets/seismic-reth-prod.png differ
diff --git reth/bin/genesis-builder/Cargo.toml seismic-reth/bin/genesis-builder/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7acbb208453851742f54b2168473e2e9f708f555 --- /dev/null +++ seismic-reth/bin/genesis-builder/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "genesis-builder" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +exclude.workspace = true + +[[bin]] +name = "genesis-builder" +path = "src/main.rs" + +[dependencies] +clap = { workspace = true, features = ["derive"] } +reth-genesis-builder = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] } + +[lints] +workspace = true
diff --git reth/bin/genesis-builder/src/main.rs seismic-reth/bin/genesis-builder/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..494b6abb0a82ee2ad08d364c5a4414f5a796bcf2 --- /dev/null +++ seismic-reth/bin/genesis-builder/src/main.rs @@ -0,0 +1,66 @@ +//! Genesis builder CLI tool for adding contracts to genesis files + +use clap::Parser; +use reth_genesis_builder::{builder::GenesisBuilder, error::BuilderError, genesis, manifest}; +use std::path::PathBuf; +use tracing::info; +use tracing_subscriber::{fmt, prelude::*, EnvFilter}; + +/// Command line arguments +#[derive(Parser)] +#[command(name = "genesis-builder")] +#[command(version)] +#[command(about = "Build genesis files with contracts from GitHub", long_about = None)] +struct Args { + /// Path to genesis manifest TOML file + #[arg( + long, + value_name = "FILE", + default_value = "crates/seismic/chainspec/res/genesis/manifest.toml" + )] + manifest: PathBuf, + + /// Path to genesis JSON file to modify + #[arg( + long, + value_name = "FILE", + default_value = "crates/seismic/chainspec/res/genesis/dev.json" + )] + genesis: PathBuf, + + /// Optional output path (defaults to modifying input genesis file in-place) + #[arg(long, value_name = "FILE")] + output: Option<PathBuf>, + + /// say "yes" to every overwrite question + #[arg(short = 'y', long)] + yes_overwrite: bool, +} + +/// Main function for building genesis files +fn main() -> Result<(), BuilderError> { + // Initialize tracing subscriber to read RUST_LOG env variable + tracing_subscriber::registry().with(fmt::layer()).with(EnvFilter::from_default_env()).init(); + + let args = Args::parse(); + + info!("Loading manifest: {}", args.manifest.display()); + let manifest_data = manifest::load_manifest(&args.manifest)?; + info!("Found {} contracts to deploy", manifest_data.contracts.len()); + + info!("Loading genesis: {}", args.genesis.display()); + let genesis_data = genesis::load_genesis(&args.genesis)?; + info!(" Current allocations: {}", genesis_data.alloc.len()); + + let builder = GenesisBuilder::new(manifest_data, genesis_data, args.yes_overwrite)?; + let updated_genesis = builder.build()?; + + let output_path = args.output.unwrap_or(args.genesis); + info!("Writing genesis: {}", output_path.display()); + genesis::write_genesis(&updated_genesis, &output_path)?; + + info!("Genesis build complete!"); + info!(" Total allocations: {}", updated_genesis.alloc.len()); + + Ok(()) +}
diff --git reth/bin/reth-bench/Cargo.toml seismic-reth/bin/reth-bench/Cargo.toml index 891fa4f9780b3fa24ddafd51201be86aa59daa52..59c754929c3c06a107b0a1c0887804438c12b50f 100644 --- reth/bin/reth-bench/Cargo.toml +++ seismic-reth/bin/reth-bench/Cargo.toml @@ -68,7 +68,10 @@ [dev-dependencies]   [features] default = ["jemalloc"] - +timestamp-in-seconds = [ + "reth-node-api/timestamp-in-seconds", + "reth-primitives-traits/timestamp-in-seconds", +] asm-keccak = [ "reth-node-core/asm-keccak", "alloy-primitives/asm-keccak",
diff --git reth/bin/reth-bench/src/main.rs seismic-reth/bin/reth-bench/src/main.rs index f146af0f70d5cbe54fb98ca15286e693e5873667..91925a58ccad4eb43ac76760def5a0323b3007bd 100644 --- reth/bin/reth-bench/src/main.rs +++ seismic-reth/bin/reth-bench/src/main.rs @@ -4,9 +4,10 @@ //! This is a tool that converts existing blocks into a stream of blocks for benchmarking purposes. //! These blocks are then fed into reth as a stream of execution payloads.   #![doc( + // TODO: seismic html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/bin/reth/Cargo.toml seismic-reth/bin/reth/Cargo.toml index a590f25810b70d2bc4143e2fc47c68530eb0376d..c6c42604d6a7b89e1fd4bb110762cecf7a6f5c3d 100644 --- reth/bin/reth/Cargo.toml +++ seismic-reth/bin/reth/Cargo.toml @@ -63,8 +63,13 @@ clap = { workspace = true, features = ["derive", "env"] } eyre.workspace = true   [dev-dependencies] +# seismic +reth-provider = { workspace = true, features = ["test-utils"] } + +# upstream backon.workspace = true tempfile.workspace = true +   [features] default = ["jemalloc", "reth-revm/portable"]
diff --git reth/bin/reth/src/lib.rs seismic-reth/bin/reth/src/lib.rs index ae07f9f35673a332f4615c476e63a0400ec76242..b7e98d3160db7bb41430965fe858010b0031c038 100644 --- reth/bin/reth/src/lib.rs +++ seismic-reth/bin/reth/src/lib.rs @@ -20,9 +20,10 @@ //! - `min-debug-logs`: Disables all logs below `debug` level. //! - `min-trace-logs`: Disables all logs below `trace` level.   #![doc( + // TODO: seismic html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/bin/seismic-reth/Cargo.toml seismic-reth/bin/seismic-reth/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9b8133fe5c3eecbfb16ac6425e7b843a5bc6b81b --- /dev/null +++ seismic-reth/bin/seismic-reth/Cargo.toml @@ -0,0 +1,58 @@ +[package] +name = "seismic-reth" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true +default-run = "seismic-reth" + +[dependencies] +alloy-signer-local.workspace = true +alloy-network.workspace = true +alloy-primitives.workspace = true + +# reth +reth-tracing.workspace = true +reth-cli-util.workspace = true +reth-cli-commands.workspace = true +reth-node-builder.workspace = true +reth-node-core.workspace = true +reth-node-ethereum.workspace = true +reth-node-metrics.workspace = true +reth-provider.workspace = true +reth-primitives.workspace = true + +# seismic +reth-seismic-node.workspace = true +reth-seismic-rpc.workspace = true +reth-seismic-cli.workspace = true + +seismic-alloy-rpc-types.workspace = true +seismic-alloy-consensus.workspace = true +seismic-enclave.workspace = true + +# misc +clap = { workspace = true, features = ["derive"] } +jsonrpsee-http-client.workspace = true +eyre.workspace = true +tracing.workspace = true +tokio.workspace = true + +[features] +default = ["jemalloc"] +timestamp-in-seconds = ["reth-seismic-node/timestamp-in-seconds"] +asm-keccak = ["reth-node-core/asm-keccak", "reth-primitives/asm-keccak"] + +jemalloc = ["reth-node-core/jemalloc", "reth-node-metrics/jemalloc"] +jemalloc-prof = ["jemalloc"] + +min-error-logs = ["tracing/release_max_level_error"] +min-warn-logs = ["tracing/release_max_level_warn"] +min-info-logs = ["tracing/release_max_level_info"] +min-debug-logs = ["tracing/release_max_level_debug"] +min-trace-logs = ["tracing/release_max_level_trace"] + +[[bin]] +name = "seismic-reth" +path = "src/main.rs"
diff --git reth/bin/seismic-reth/src/main.rs seismic-reth/bin/seismic-reth/src/main.rs new file mode 100644 index 0000000000000000000000000000000000000000..554d1e8d4c34395029af7cc9d71c15b8bc7b905b --- /dev/null +++ seismic-reth/bin/seismic-reth/src/main.rs @@ -0,0 +1,30 @@ +#![allow(missing_docs)] + +use clap::Parser; +use reth_seismic_cli::{chainspec::SeismicChainSpecParser, Cli}; +use reth_seismic_node::{enclave::boot_enclave_and_fetch_keys, node::SeismicNode}; + +fn main() { + // Enable backtraces unless we explicitly set RUST_BACKTRACE + if std::env::var_os("RUST_BACKTRACE").is_none() { + std::env::set_var("RUST_BACKTRACE", "1"); + } + + reth_cli_util::sigsegv_handler::install(); + + if let Err(err) = Cli::<SeismicChainSpecParser>::parse().run(|builder, encl| async move { + // Boot enclave and fetch purpose keys BEFORE building node components + let purpose_keys = boot_enclave_and_fetch_keys(&encl).await; + + // Store purpose keys in global static storage before building the node. + // Seismic RPC modules (seismic_ namespace + eth_ overrides) are registered + // in SeismicAddOns::launch_add_ons, which reads keys via get_purpose_keys(). + reth_seismic_node::purpose_keys::init_purpose_keys(purpose_keys); + + let node = builder.node(SeismicNode::default()).launch_with_debug_capabilities().await?; + node.node_exit_future.await + }) { + eprintln!("Error: {err:?}"); + std::process::exit(1); + } +}
diff --git reth/book.toml seismic-reth/book.toml index 00838b0010d05bc27a520ebf6ee77d105d8bb883..9fdd4b0d0704a1dc853f4a70c9aa2eceb4fbdfcc 100644 --- reth/book.toml +++ seismic-reth/book.toml @@ -1,14 +1,14 @@ [book] -authors = ["reth Core Contributors"] +authors = ["reth and seismic-reth Core Contributors"] language = "en" multilingual = false src = "book" -title = "reth Book" +title = "seismic-reth Book" description = "A book on all things Reth"   [output.html] theme = "book/theme" -git-repository-url = "https://github.com/paradigmxyz/reth" +git-repository-url = "https://github.com/SeismicSystems/seismic-reth/" default-theme = "ayu" no-section-label = true
diff --git reth/crates/chain-state/src/in_memory.rs seismic-reth/crates/chain-state/src/in_memory.rs index cd194db81e3d6976efb5f9961f9a6d84eb10d4a7..6e639461b65d3b5afcd42d5eabb3aea1fde0dd07 100644 --- reth/crates/chain-state/src/in_memory.rs +++ seismic-reth/crates/chain-state/src/in_memory.rs @@ -966,7 +966,7 @@ mod tests { use super::*; use crate::test_utils::TestBlockBuilder; use alloy_eips::eip7685::Requests; - use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey, StorageValue}; + use alloy_primitives::{Address, BlockNumber, Bytes, StorageKey}; use rand::Rng; use reth_errors::ProviderResult; use reth_ethereum_primitives::{EthPrimitives, Receipt}; @@ -979,6 +979,8 @@ use reth_trie::{ AccountProof, HashedStorage, MultiProof, MultiProofTargets, StorageMultiProof, StorageProof, TrieInput, }; + + use alloy_primitives::FlaggedStorage;   fn create_mock_state( test_block_builder: &mut TestBlockBuilder<EthPrimitives>, @@ -1018,7 +1020,7 @@ fn storage( &self, _address: Address, _storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>> { + ) -> ProviderResult<Option<FlaggedStorage>> { Ok(None) } }
diff --git reth/crates/chain-state/src/lib.rs seismic-reth/crates/chain-state/src/lib.rs index f2325c087db60e6d1a873ec42a0efa3a5a3de243..eae1dc164789188b40ac22609fb0bf03caf4cfc2 100644 --- reth/crates/chain-state/src/lib.rs +++ seismic-reth/crates/chain-state/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/chain-state/src/memory_overlay.rs seismic-reth/crates/chain-state/src/memory_overlay.rs index d9e80710e3dd09bfd6354d8d6a3c745e53536d50..8657be20a8ae215571417b74dc98d55cc513c05c 100644 --- reth/crates/chain-state/src/memory_overlay.rs +++ seismic-reth/crates/chain-state/src/memory_overlay.rs @@ -1,6 +1,6 @@ use super::ExecutedBlockWithTrieUpdates; use alloy_consensus::BlockHeader; -use alloy_primitives::{keccak256, Address, BlockNumber, Bytes, StorageKey, StorageValue, B256}; +use alloy_primitives::{keccak256, Address, BlockNumber, Bytes, StorageKey, B256}; use reth_errors::ProviderResult; use reth_primitives_traits::{Account, Bytecode, NodePrimitives}; use reth_storage_api::{ @@ -13,6 +13,8 @@ MultiProofTargets, StorageMultiProof, TrieInput, }; use revm_database::BundleState; use std::sync::OnceLock; + +use alloy_primitives::FlaggedStorage;   /// A state provider that stores references to in-memory blocks along with their state as well as a /// reference of the historical state provider for fallback lookups. @@ -219,7 +221,7 @@ fn storage( &self, address: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>> { + ) -> ProviderResult<Option<FlaggedStorage>> { for block in &self.in_memory { if let Some(value) = block.execution_output.storage(&address, storage_key.into()) { return Ok(Some(value));
diff --git reth/crates/chainspec/Cargo.toml seismic-reth/crates/chainspec/Cargo.toml index 4d3c23117b3b344ba85921dea8eb8963657a203e..89b4c1a44212e8177cbb4250207850a5fb5cb258 100644 --- reth/crates/chainspec/Cargo.toml +++ seismic-reth/crates/chainspec/Cargo.toml @@ -25,6 +25,9 @@ alloy-genesis.workspace = true alloy-primitives = { workspace = true, features = ["rlp"] } alloy-consensus.workspace = true   +# seismic +alloy-seismic-evm.workspace = true + # misc auto_impl.workspace = true serde_json.workspace = true @@ -38,6 +41,7 @@ alloy-rlp = { workspace = true, features = ["arrayvec"] }   [features] default = ["std"] +timestamp-in-seconds = ["reth-primitives-traits/timestamp-in-seconds"] std = [ "alloy-chains/std", "alloy-eips/std", @@ -62,6 +66,4 @@ "alloy-eips/arbitrary", "alloy-primitives/arbitrary", "alloy-trie/arbitrary", ] -test-utils = [ - "reth-primitives-traits/test-utils", -] +test-utils = ["reth-primitives-traits/test-utils"]
diff --git reth/crates/chainspec/res/genesis/dev.json seismic-reth/crates/chainspec/res/genesis/dev.json index ed0522167b0b277c3dda2ba762c6d2c0e8ee1c5a..f6e9b2c695fbef30d294b22794df80d2d72eb3ab 100644 --- reth/crates/chainspec/res/genesis/dev.json +++ seismic-reth/crates/chainspec/res/genesis/dev.json @@ -1 +1,75 @@ -{"nonce":"0x0","timestamp":"0x6490fdd2","extraData":"0x","gasLimit":"0x1c9c380","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","coinbase":"0x0000000000000000000000000000000000000000","stateRoot":"0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494","alloc":{"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266":{"balance":"0xD3C21BCECCEDA1000000"},"0x70997970C51812dc3A010C7d01b50e0d17dc79C8":{"balance":"0xD3C21BCECCEDA1000000"},"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC":{"balance":"0xD3C21BCECCEDA1000000"},"0x90F79bf6EB2c4f870365E785982E1f101E93b906":{"balance":"0xD3C21BCECCEDA1000000"},"0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65":{"balance":"0xD3C21BCECCEDA1000000"},"0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc":{"balance":"0xD3C21BCECCEDA1000000"},"0x976EA74026E726554dB657fA54763abd0C3a0aa9":{"balance":"0xD3C21BCECCEDA1000000"},"0x14dC79964da2C08b23698B3D3cc7Ca32193d9955":{"balance":"0xD3C21BCECCEDA1000000"},"0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f":{"balance":"0xD3C21BCECCEDA1000000"},"0xa0Ee7A142d267C1f36714E4a8F75612F20a79720":{"balance":"0xD3C21BCECCEDA1000000"},"0xBcd4042DE499D14e55001CcbB24a551F3b954096":{"balance":"0xD3C21BCECCEDA1000000"},"0x71bE63f3384f5fb98995898A86B02Fb2426c5788":{"balance":"0xD3C21BCECCEDA1000000"},"0xFABB0ac9d68B0B445fB7357272Ff202C5651694a":{"balance":"0xD3C21BCECCEDA1000000"},"0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec":{"balance":"0xD3C21BCECCEDA1000000"},"0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097":{"balance":"0xD3C21BCECCEDA1000000"},"0xcd3B766CCDd6AE721141F452C550Ca635964ce71":{"balance":"0xD3C21BCECCEDA1000000"},"0x2546BcD3c84621e976D8185a91A922aE77ECEc30":{"balance":"0xD3C21BCECCEDA1000000"},"0xbDA5747bFD65F08deb54cb465eB87D40e51B197E":{"balance":"0xD3C21BCECCEDA1000000"},"0xdD2FD4581271e230360230F9337D5c0430Bf44C0":{"balance":"0xD3C21BCECCEDA1000000"},"0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199":{"balance":"0xD3C21BCECCEDA1000000"}},"number":"0x0","gasUsed":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file +{ + "nonce": "0x0", + "timestamp": "0x6490fdd2", + "extraData": "0x", + "gasLimit": "0x1c9c380", + "difficulty": "0x0", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "coinbase": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x5eb6e371a698b8d68f665192350ffcecbbbf322916f4b51bd79bb6887da3f494", + "alloc": { + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x90F79bf6EB2c4f870365E785982E1f101E93b906": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x976EA74026E726554dB657fA54763abd0C3a0aa9": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x14dC79964da2C08b23698B3D3cc7Ca32193d9955": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xa0Ee7A142d267C1f36714E4a8F75612F20a79720": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xBcd4042DE499D14e55001CcbB24a551F3b954096": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x71bE63f3384f5fb98995898A86B02Fb2426c5788": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xFABB0ac9d68B0B445fB7357272Ff202C5651694a": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xcd3B766CCDd6AE721141F452C550Ca635964ce71": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x2546BcD3c84621e976D8185a91A922aE77ECEc30": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xbDA5747bFD65F08deb54cb465eB87D40e51B197E": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0xdD2FD4581271e230360230F9337D5c0430Bf44C0": { + "balance": "0xD3C21BCECCEDA1000000" + }, + "0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199": { + "balance": "0xD3C21BCECCEDA1000000" + } + }, + "number": "0x0", + "gasUsed": "0x0", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000" +} \ No newline at end of file
diff --git reth/crates/chainspec/src/api.rs seismic-reth/crates/chainspec/src/api.rs index 80327d38b6d713663053465c7e6ddf687f6e7160..ad2e460136d83be02a524ac5608d147f1aaaf490 100644 --- reth/crates/chainspec/src/api.rs +++ seismic-reth/crates/chainspec/src/api.rs @@ -61,6 +61,12 @@ fn is_ethereum(&self) -> bool { self.chain().is_ethereum() }   + /// Returns `true` if this chain is a Seismic chain. + fn is_seismic(&self) -> bool { + let id = self.chain().id(); + id == 5123 || id == 5124 + } + /// Returns the final total difficulty if the Paris hardfork is known. fn final_paris_total_difficulty(&self) -> Option<U256>;
diff --git reth/crates/chainspec/src/lib.rs seismic-reth/crates/chainspec/src/lib.rs index 5ba4252939925dfc2087812f5d8bca8ae5cbb4a0..0cd8881b8cb4abd85a03522e4be9445485276d92 100644 --- reth/crates/chainspec/src/lib.rs +++ seismic-reth/crates/chainspec/src/lib.rs @@ -3,11 +3,13 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] + +use alloy_genesis as _;   extern crate alloc;
diff --git reth/crates/chainspec/src/spec.rs seismic-reth/crates/chainspec/src/spec.rs index 206ac3339b94734140ddc75cf3b8a90dbe6c50e8..d0a82e86ee8497a4d48c1088c4e105fc123b01d9 100644 --- reth/crates/chainspec/src/spec.rs +++ seismic-reth/crates/chainspec/src/spec.rs @@ -19,6 +19,7 @@ eip1559::INITIAL_BASE_FEE, eip7685::EMPTY_REQUESTS_HASH, eip7892::BlobScheduleBlobParams, }; use alloy_genesis::Genesis; use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256}; +use alloy_seismic_evm::hardfork::{SeismicHardfork, SeismicHardforks}; use alloy_trie::root::state_root_ref_unhashed; use core::fmt::Debug; use derive_more::From; @@ -40,30 +41,37 @@ .fork(EthereumHardfork::London) .active_at_block(0) .then(|| genesis.base_fee_per_gas.map(|fee| fee as u64).unwrap_or(INITIAL_BASE_FEE));   + let genesis_timestamp_seconds = if cfg!(feature = "timestamp-in-seconds") { + genesis.timestamp + } else { + genesis.timestamp / 1000 + }; // If shanghai is activated, initialize the header with an empty withdrawals hash, and // empty withdrawals list. let withdrawals_root = hardforks .fork(EthereumHardfork::Shanghai) - .active_at_timestamp(genesis.timestamp) + .active_at_timestamp(genesis_timestamp_seconds) .then_some(EMPTY_WITHDRAWALS);   // If Cancun is activated at genesis, we set: // * parent beacon block root to 0x0 // * blob gas used to provided genesis or 0x0 // * excess blob gas to provided genesis or 0x0 - let (parent_beacon_block_root, blob_gas_used, excess_blob_gas) = - if hardforks.fork(EthereumHardfork::Cancun).active_at_timestamp(genesis.timestamp) { - let blob_gas_used = genesis.blob_gas_used.unwrap_or(0); - let excess_blob_gas = genesis.excess_blob_gas.unwrap_or(0); - (Some(B256::ZERO), Some(blob_gas_used), Some(excess_blob_gas)) - } else { - (None, None, None) - }; + let (parent_beacon_block_root, blob_gas_used, excess_blob_gas) = if hardforks + .fork(EthereumHardfork::Cancun) + .active_at_timestamp(genesis_timestamp_seconds) + { + let blob_gas_used = genesis.blob_gas_used.unwrap_or(0); + let excess_blob_gas = genesis.excess_blob_gas.unwrap_or(0); + (Some(B256::ZERO), Some(blob_gas_used), Some(excess_blob_gas)) + } else { + (None, None, None) + };   // If Prague is activated at genesis we set requests root to an empty trie root. let requests_hash = hardforks .fork(EthereumHardfork::Prague) - .active_at_timestamp(genesis.timestamp) + .active_at_timestamp(genesis_timestamp_seconds) .then_some(EMPTY_REQUESTS_HASH);   Header { @@ -395,6 +403,14 @@ pub fn genesis_hash(&self) -> B256 { self.genesis_header.hash() }   + /// Get the timestamp of the genesis block in seconds + pub(crate) fn genesis_timestamp_seconds(&self) -> u64 { + #[cfg(feature = "timestamp-in-seconds")] + return self.genesis.timestamp; + #[cfg(not(feature = "timestamp-in-seconds"))] + return self.genesis.timestamp / 1000; + } + /// Get the timestamp of the genesis block. pub const fn genesis_timestamp(&self) -> u64 { self.genesis.timestamp @@ -462,7 +478,7 @@ _ => return None, }) });   - ForkFilter::new(head, self.genesis_hash(), self.genesis_timestamp(), forks) + ForkFilter::new(head, self.genesis_hash(), self.genesis_timestamp_seconds(), forks) }   /// Compute the [`ForkId`] for the given [`Head`] following eip-6122 spec. @@ -505,9 +521,13 @@ // // this filter ensures that no block-based forks are returned for timestamp in self.hardforks.forks_iter().filter_map(|(_, cond)| { // ensure we only get timestamp forks activated __after__ the genesis block - cond.as_timestamp().filter(|time| time > &self.genesis.timestamp) + let genesis_timestamp_seconds = self.genesis_timestamp_seconds(); + cond.as_timestamp().filter(|time| time > &genesis_timestamp_seconds) }) { - if head.timestamp >= timestamp { + let timestamp_cmp = + if cfg!(feature = "timestamp-in-seconds") { timestamp } else { timestamp * 1000 }; + // MODIFIED:: timestamp is in seconds, not milliseconds + if head.timestamp >= timestamp_cmp { // skip duplicated hardfork activated at the same timestamp if timestamp != current_applied { forkhash += timestamp; @@ -528,9 +548,15 @@ /// An internal helper function that returns a head block that satisfies a given Fork condition. pub(crate) fn satisfy(&self, cond: ForkCondition) -> Head { match cond { ForkCondition::Block(number) => Head { number, ..Default::default() }, + // this timestamp is in seconds ForkCondition::Timestamp(timestamp) => { // to satisfy every timestamp ForkCondition, we find the last ForkCondition::Block // if one exists, and include its block_num in the returned Head + let timestamp = if cfg!(feature = "timestamp-in-seconds") { + timestamp + } else { + timestamp * 1000 + }; Head { timestamp, number: self.last_block_fork_before_merge_or_timestamp().unwrap_or_default(), @@ -747,6 +773,12 @@ }   impl EthereumHardforks for ChainSpec { fn ethereum_fork_activation(&self, fork: EthereumHardfork) -> ForkCondition { + self.fork(fork) + } +} + +impl SeismicHardforks for ChainSpec { + fn seismic_fork_activation(&self, fork: SeismicHardfork) -> ForkCondition { self.fork(fork) } } @@ -1043,6 +1075,14 @@ use core::ops::Deref; use reth_ethereum_forks::{ForkCondition, ForkHash, ForkId, Head}; use std::{collections::HashMap, str::FromStr};   + fn ts(timestamp_seconds: u64) -> u64 { + if cfg!(feature = "timestamp-in-seconds") { + timestamp_seconds + } else { + 1000 * timestamp_seconds + } + } + fn test_hardfork_fork_ids(spec: &ChainSpec, cases: &[(EthereumHardfork, ForkId)]) { for (hardfork, expected_id) in cases { if let Some(computed_id) = spec.hardfork_fork_id(*hardfork) { @@ -1172,7 +1212,8 @@ .with_fork(EthereumHardfork::Homestead, ForkCondition::Block(73)) .with_fork(EthereumHardfork::Shanghai, ForkCondition::Timestamp(11313123)) .build(); let happy_path_head = happy_path_case.satisfy(ForkCondition::Timestamp(11313123)); - let happy_path_expected = Head { number: 73, timestamp: 11313123, ..Default::default() }; + let happy_path_expected = + Head { number: 73, timestamp: ts(11313123), ..Default::default() }; assert_eq!( happy_path_head, happy_path_expected, "expected satisfy() to return {happy_path_expected:#?}, but got {happy_path_head:#?} " @@ -1189,7 +1230,7 @@ .build(); let multi_timestamp_head = multiple_timestamp_fork_case.satisfy(ForkCondition::Timestamp(11313398)); let mult_timestamp_expected = - Head { number: 73, timestamp: 11313398, ..Default::default() }; + Head { number: 73, timestamp: ts(11313398), ..Default::default() }; assert_eq!( multi_timestamp_head, mult_timestamp_expected, "expected satisfy() to return {mult_timestamp_expected:#?}, but got {multi_timestamp_head:#?} " @@ -1201,7 +1242,8 @@ .genesis(empty_genesis.clone()) .with_fork(EthereumHardfork::Shanghai, ForkCondition::Timestamp(11313123)) .build(); let no_block_fork_head = no_block_fork_case.satisfy(ForkCondition::Timestamp(11313123)); - let no_block_fork_expected = Head { number: 0, timestamp: 11313123, ..Default::default() }; + let no_block_fork_expected = + Head { number: 0, timestamp: ts(11313123), ..Default::default() }; assert_eq!( no_block_fork_head, no_block_fork_expected, "expected satisfy() to return {no_block_fork_expected:#?}, but got {no_block_fork_head:#?} ", @@ -1225,7 +1267,7 @@ .build(); let fork_cond_ttd_blocknum_head = fork_cond_ttd_blocknum_case.satisfy(ForkCondition::Timestamp(11313123)); let fork_cond_ttd_blocknum_expected = - Head { number: 101, timestamp: 11313123, ..Default::default() }; + Head { number: 101, timestamp: ts(11313123), ..Default::default() }; assert_eq!( fork_cond_ttd_blocknum_head, fork_cond_ttd_blocknum_expected, "expected satisfy() to return {fork_cond_ttd_blocknum_expected:#?}, but got {fork_cond_ttd_blocknum_expected:#?} ", @@ -1462,22 +1504,22 @@ ForkId { hash: ForkHash([0xf0, 0xaf, 0xd0, 0xe3]), next: 1681338455 }, ), // First Shanghai block ( - Head { number: 20000000, timestamp: 1681338455, ..Default::default() }, + Head { number: 20000000, timestamp: ts(1681338455), ..Default::default() }, ForkId { hash: ForkHash([0xdc, 0xe9, 0x6c, 0x2d]), next: 1710338135 }, ), // First Cancun block ( - Head { number: 20000001, timestamp: 1710338135, ..Default::default() }, + Head { number: 20000001, timestamp: ts(1710338135), ..Default::default() }, ForkId { hash: ForkHash([0x9f, 0x3d, 0x22, 0x54]), next: 1746612311 }, ), // First Prague block ( - Head { number: 20000002, timestamp: 1746612311, ..Default::default() }, + Head { number: 20000002, timestamp: ts(1746612311), ..Default::default() }, ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 }, ), // Future Prague block ( - Head { number: 20000002, timestamp: 2000000000, ..Default::default() }, + Head { number: 20000002, timestamp: ts(2000000000), ..Default::default() }, ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 }, ), ], @@ -1495,7 +1537,7 @@ ForkId { hash: ForkHash([0xbe, 0xf7, 0x1d, 0x30]), next: 1742999832 }, ), // First Prague block ( - Head { number: 0, timestamp: 1742999833, ..Default::default() }, + Head { number: 0, timestamp: ts(1742999833), ..Default::default() }, ForkId { hash: ForkHash([0x09, 0x29, 0xe2, 0x4e]), next: 0 }, ), ], @@ -1518,32 +1560,32 @@ ForkId { hash: ForkHash([0xc6, 0x1a, 0x60, 0x98]), next: 1696000704 }, ), // Last MergeNetsplit block ( - Head { number: 123, timestamp: 1696000703, ..Default::default() }, + Head { number: 123, timestamp: ts(1696000703), ..Default::default() }, ForkId { hash: ForkHash([0xc6, 0x1a, 0x60, 0x98]), next: 1696000704 }, ), // First Shanghai block ( - Head { number: 123, timestamp: 1696000704, ..Default::default() }, + Head { number: 123, timestamp: ts(1696000704), ..Default::default() }, ForkId { hash: ForkHash([0xfd, 0x4f, 0x01, 0x6b]), next: 1707305664 }, ), // Last Shanghai block ( - Head { number: 123, timestamp: 1707305663, ..Default::default() }, + Head { number: 123, timestamp: ts(1707305663), ..Default::default() }, ForkId { hash: ForkHash([0xfd, 0x4f, 0x01, 0x6b]), next: 1707305664 }, ), // First Cancun block ( - Head { number: 123, timestamp: 1707305664, ..Default::default() }, + Head { number: 123, timestamp: ts(1707305664), ..Default::default() }, ForkId { hash: ForkHash([0x9b, 0x19, 0x2a, 0xd0]), next: 1740434112 }, ), // Last Cancun block ( - Head { number: 123, timestamp: 1740434111, ..Default::default() }, + Head { number: 123, timestamp: ts(1740434111), ..Default::default() }, ForkId { hash: ForkHash([0x9b, 0x19, 0x2a, 0xd0]), next: 1740434112 }, ), // First Prague block ( - Head { number: 123, timestamp: 1740434112, ..Default::default() }, + Head { number: 123, timestamp: ts(1740434112), ..Default::default() }, ForkId { hash: ForkHash([0xdf, 0xbd, 0x9b, 0xed]), next: 0 }, ), ], @@ -1568,32 +1610,32 @@ Head { number: 1735371, ..Default::default() }, ForkId { hash: ForkHash([0xb9, 0x6c, 0xbd, 0x13]), next: 1677557088 }, ), ( - Head { number: 1735372, timestamp: 1677557087, ..Default::default() }, + Head { number: 1735372, timestamp: ts(1677557087), ..Default::default() }, ForkId { hash: ForkHash([0xb9, 0x6c, 0xbd, 0x13]), next: 1677557088 }, ), // First Shanghai block ( - Head { number: 1735373, timestamp: 1677557088, ..Default::default() }, + Head { number: 1735373, timestamp: ts(1677557088), ..Default::default() }, ForkId { hash: ForkHash([0xf7, 0xf9, 0xbc, 0x08]), next: 1706655072 }, ), // Last Shanghai block ( - Head { number: 1735374, timestamp: 1706655071, ..Default::default() }, + Head { number: 1735374, timestamp: ts(1706655071), ..Default::default() }, ForkId { hash: ForkHash([0xf7, 0xf9, 0xbc, 0x08]), next: 1706655072 }, ), // First Cancun block ( - Head { number: 1735375, timestamp: 1706655072, ..Default::default() }, + Head { number: 1735375, timestamp: ts(1706655072), ..Default::default() }, ForkId { hash: ForkHash([0x88, 0xcf, 0x81, 0xd9]), next: 1741159776 }, ), // Last Cancun block ( - Head { number: 1735376, timestamp: 1741159775, ..Default::default() }, + Head { number: 1735376, timestamp: ts(1741159775), ..Default::default() }, ForkId { hash: ForkHash([0x88, 0xcf, 0x81, 0xd9]), next: 1741159776 }, ), // First Prague block ( - Head { number: 1735377, timestamp: 1741159776, ..Default::default() }, + Head { number: 1735377, timestamp: ts(1741159776), ..Default::default() }, ForkId { hash: ForkHash([0xed, 0x88, 0xb5, 0xfd]), next: 0 }, ), ], @@ -1721,31 +1763,31 @@ Head { number: 15050000, timestamp: 0, ..Default::default() }, ForkId { hash: ForkHash([0xf0, 0xaf, 0xd0, 0xe3]), next: 1681338455 }, ), // First Gray Glacier block ( - Head { number: 19999999, timestamp: 1667999999, ..Default::default() }, + Head { number: 19999999, timestamp: ts(1667999999), ..Default::default() }, ForkId { hash: ForkHash([0xf0, 0xaf, 0xd0, 0xe3]), next: 1681338455 }, ), // Last Gray Glacier block ( - Head { number: 20000000, timestamp: 1681338455, ..Default::default() }, + Head { number: 20000000, timestamp: ts(1681338455), ..Default::default() }, ForkId { hash: ForkHash([0xdc, 0xe9, 0x6c, 0x2d]), next: 1710338135 }, ), // Last Shanghai block ( - Head { number: 20000001, timestamp: 1710338134, ..Default::default() }, + Head { number: 20000001, timestamp: ts(1710338134), ..Default::default() }, ForkId { hash: ForkHash([0xdc, 0xe9, 0x6c, 0x2d]), next: 1710338135 }, ), // First Cancun block ( - Head { number: 20000002, timestamp: 1710338135, ..Default::default() }, + Head { number: 20000002, timestamp: ts(1710338135), ..Default::default() }, ForkId { hash: ForkHash([0x9f, 0x3d, 0x22, 0x54]), next: 1746612311 }, ), // Last Cancun block ( - Head { number: 20000003, timestamp: 1746612310, ..Default::default() }, + Head { number: 20000003, timestamp: ts(1746612310), ..Default::default() }, ForkId { hash: ForkHash([0x9f, 0x3d, 0x22, 0x54]), next: 1746612311 }, ), // First Prague block ( - Head { number: 20000004, timestamp: 1746612311, ..Default::default() }, + Head { number: 20000004, timestamp: ts(1746612311), ..Default::default() }, ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 }, ), // Future Prague block ( - Head { number: 20000004, timestamp: 2000000000, ..Default::default() }, + Head { number: 20000004, timestamp: ts(2000000000), ..Default::default() }, ForkId { hash: ForkHash([0xc3, 0x76, 0xcf, 0x8b]), next: 0 }, ), ], @@ -1774,7 +1816,7 @@ fn test_timestamp_fork_in_genesis() { let timestamp = 1690475657u64; let default_spec_builder = ChainSpecBuilder::default() .chain(Chain::from_id(1337)) - .genesis(Genesis::default().with_timestamp(timestamp)) + .genesis(Genesis::default().with_timestamp(ts(timestamp))) .paris_activated();   // test format: (chain spec, expected next value) - the forkhash will be determined by the @@ -2204,7 +2246,7 @@ // make sure we are at ForkHash("bc0c2605") with Head post-cancun let expected_forkid = ForkId { hash: ForkHash([0xbc, 0x0c, 0x26, 0x05]), next: 0 }; let got_forkid = - chainspec.fork_id(&Head { number: 73, timestamp: 840, ..Default::default() }); + chainspec.fork_id(&Head { number: 73, timestamp: ts(840), ..Default::default() });   // check that they're the same assert_eq!(got_forkid, expected_forkid);
diff --git reth/crates/cli/cli/Cargo.toml seismic-reth/crates/cli/cli/Cargo.toml index 34e3dc8d442283400a6867a2a023bb9157f37bab..c370139a75cfeb5a0f508042e22b1af8e570fcf9 100644 --- reth/crates/cli/cli/Cargo.toml +++ seismic-reth/crates/cli/cli/Cargo.toml @@ -11,10 +11,12 @@ [lints] workspace = true   [dependencies] +# ethereum +alloy-genesis.workspace = true + # reth reth-cli-runner.workspace = true reth-db.workspace = true -alloy-genesis.workspace = true   # misc clap.workspace = true
diff --git reth/crates/cli/cli/src/lib.rs seismic-reth/crates/cli/cli/src/lib.rs index 52e972891128c6bab170405e341e046801a23832..7be38c39d5a9d69c208ee56ab7de35a6ff46877e 100644 --- reth/crates/cli/cli/src/lib.rs +++ seismic-reth/crates/cli/cli/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/cli/commands/Cargo.toml seismic-reth/crates/cli/commands/Cargo.toml index 961c4a2116d0471c3b680301ea3e92acd3d76c7d..5b3b46f826b5bf54518db12b982ffb345a5dce8f 100644 --- reth/crates/cli/commands/Cargo.toml +++ seismic-reth/crates/cli/commands/Cargo.toml @@ -10,6 +10,9 @@ [lints]   [dependencies] +# seismic +seismic-alloy-genesis.workspace = true + # reth reth-chainspec.workspace = true reth-cli.workspace = true
diff --git reth/crates/cli/commands/src/lib.rs seismic-reth/crates/cli/commands/src/lib.rs index 84586359b36efa477384d32ed52fe4925698144a..b75d0b1ce914c003c6c15889b10458c58cdc7260 100644 --- reth/crates/cli/commands/src/lib.rs +++ seismic-reth/crates/cli/commands/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/cli/commands/src/node.rs seismic-reth/crates/cli/commands/src/node.rs index 1714a06d678597548528491a6a692961c9737532..35b5e4a98d07c2c4f2f4933d1a2c66bc74562d72 100644 --- reth/crates/cli/commands/src/node.rs +++ seismic-reth/crates/cli/commands/src/node.rs @@ -172,6 +172,7 @@ } = self;   // set up node config let mut node_config = NodeConfig { + enclave: reth_node_core::args::EnclaveArgs::default(), datadir, config, chain,
diff --git reth/crates/cli/commands/src/p2p/mod.rs seismic-reth/crates/cli/commands/src/p2p/mod.rs index c3a202316385c0a2c088645b2f2ad347fa4d652c..6d14e1bac0196f2ba50971c05a129e9c9bb4880f 100644 --- reth/crates/cli/commands/src/p2p/mod.rs +++ seismic-reth/crates/cli/commands/src/p2p/mod.rs @@ -194,7 +194,12 @@ .peer_config(config.peers_config_with_basic_nodes_from_file(None)) .external_ip_resolver(self.network.nat) .boot_nodes(boot_nodes.clone()) .apply(|builder| { - self.network.discovery.apply_to_builder(builder, rlpx_socket, boot_nodes) + self.network.discovery.apply_to_builder( + builder, + rlpx_socket, + boot_nodes, + self.network.nat, + ) }) .build_with_noop_provider(self.chain.clone()) .manager()
diff --git reth/crates/cli/commands/src/stage/drop.rs seismic-reth/crates/cli/commands/src/stage/drop.rs index 1684264213d61635e877b63772fac09343b11aa7..907dec94db809cea7d5f5706a1efc7a30d3256ec 100644 --- reth/crates/cli/commands/src/stage/drop.rs +++ seismic-reth/crates/cli/commands/src/stage/drop.rs @@ -108,7 +108,14 @@ reset_prune_checkpoint(tx, PruneSegment::Receipts)?; reset_prune_checkpoint(tx, PruneSegment::ContractLogs)?; reset_stage_checkpoint(tx, StageId::Execution)?;   - let alloc = &self.env.chain.genesis().alloc; + let alloc: std::collections::BTreeMap<_, seismic_alloy_genesis::GenesisAccount> = + self.env + .chain + .genesis() + .alloc + .iter() + .map(|(addr, account)| (*addr, account.clone().into())) + .collect(); insert_genesis_state(&provider_rw, alloc.iter())?; } StageEnum::AccountHashing => { @@ -147,7 +154,15 @@ reset_stage_checkpoint(tx, StageId::IndexAccountHistory)?; reset_stage_checkpoint(tx, StageId::IndexStorageHistory)?;   - insert_genesis_history(&provider_rw, self.env.chain.genesis().alloc.iter())?; + let alloc: std::collections::BTreeMap<_, seismic_alloy_genesis::GenesisAccount> = + self.env + .chain + .genesis() + .alloc + .iter() + .map(|(addr, account)| (*addr, account.clone().into())) + .collect(); + insert_genesis_history(&provider_rw, alloc.iter())?; } StageEnum::TxLookup => { tx.clear::<tables::TransactionHashNumbers>()?;
diff --git reth/crates/cli/runner/src/lib.rs seismic-reth/crates/cli/runner/src/lib.rs index 71af165ab9d68875f48eacb3dad7c0dccf17702b..02fcacc9eb09c9d20d3d18277c0dfa01ef697070 100644 --- reth/crates/cli/runner/src/lib.rs +++ seismic-reth/crates/cli/runner/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/cli/util/src/lib.rs seismic-reth/crates/cli/util/src/lib.rs index a82c3ba57f7d8ccf4dbeffb479951298ce8742be..d82e66d9e9a555f3dd481d7982659dc7c21326a4 100644 --- reth/crates/cli/util/src/lib.rs +++ seismic-reth/crates/cli/util/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/cli/util/src/sigsegv_handler.rs seismic-reth/crates/cli/util/src/sigsegv_handler.rs index b0a195391ffa3f0e8a36f1d02fb7747e777c04a2..5a68f96ca1c6f815ceb40a619735987c3ba826d2 100644 --- reth/crates/cli/util/src/sigsegv_handler.rs +++ seismic-reth/crates/cli/util/src/sigsegv_handler.rs @@ -126,7 +126,7 @@ alt_stack.ss_size = alt_stack_size; libc::sigaltstack(&raw const alt_stack, ptr::null_mut());   let mut sa: libc::sigaction = mem::zeroed(); - sa.sa_sigaction = print_stack_trace as libc::sighandler_t; + sa.sa_sigaction = print_stack_trace as *const () as libc::sighandler_t; sa.sa_flags = libc::SA_NODEFER | libc::SA_RESETHAND | libc::SA_ONSTACK; libc::sigemptyset(&raw mut sa.sa_mask); libc::sigaction(libc::SIGSEGV, &raw const sa, ptr::null_mut());
diff --git reth/crates/config/src/lib.rs seismic-reth/crates/config/src/lib.rs index 1e81e18ec42915ecbdc2d6cd06d3a56ab118d263..55a352c01b622c79a4e12ae846c9b084a3a9583b 100644 --- reth/crates/config/src/lib.rs +++ seismic-reth/crates/config/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/consensus/common/src/lib.rs seismic-reth/crates/consensus/common/src/lib.rs index b6971a0d528d908c2f0c8454a3da0e5883dc738e..e0fa7fcda747ed6e38e1448c3d26f582e920ac7d 100644 --- reth/crates/consensus/common/src/lib.rs +++ seismic-reth/crates/consensus/common/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/consensus/common/src/validation.rs seismic-reth/crates/consensus/common/src/validation.rs index c1b60c95afc74c8f29e9ae985f49d1b63ec1f5c0..283037b38f537077c5c31f5888f364a545c5b67b 100644 --- reth/crates/consensus/common/src/validation.rs +++ seismic-reth/crates/consensus/common/src/validation.rs @@ -186,15 +186,15 @@ )) }   // EIP-4895: Beacon chain push withdrawals as operations - if chain_spec.is_shanghai_active_at_timestamp(block.timestamp()) { + if chain_spec.is_shanghai_active_at_timestamp(block.timestamp_seconds()) { validate_shanghai_withdrawals(block)?; }   - if chain_spec.is_cancun_active_at_timestamp(block.timestamp()) { + if chain_spec.is_cancun_active_at_timestamp(block.timestamp_seconds()) { validate_cancun_gas(block)?; }   - if chain_spec.is_osaka_active_at_timestamp(block.timestamp()) && + if chain_spec.is_osaka_active_at_timestamp(block.timestamp_seconds()) && block.rlp_length() > MAX_RLP_BLOCK_SIZE { return Err(ConsensusError::BlockTooLarge { @@ -300,7 +300,7 @@ { alloy_eips::eip1559::INITIAL_BASE_FEE } else { chain_spec - .next_block_base_fee(parent, header.timestamp()) + .next_block_base_fee(parent, header.timestamp_seconds()) .ok_or(ConsensusError::BaseFeeMissing)? }; if expected_base_fee != base_fee { @@ -322,8 +322,8 @@ parent: &H, ) -> Result<(), ConsensusError> { if header.timestamp() <= parent.timestamp() { return Err(ConsensusError::TimestampIsInPast { - parent_timestamp: parent.timestamp(), - timestamp: header.timestamp(), + parent_timestamp: parent.timestamp_seconds(), + timestamp: header.timestamp_seconds(), }) } Ok(()) @@ -347,8 +347,9 @@ let parent_gas_limit = if !chain_spec.is_london_active_at_block(parent.number()) && chain_spec.is_london_active_at_block(header.number()) { parent.gas_limit() * - chain_spec.base_fee_params_at_timestamp(header.timestamp()).elasticity_multiplier - as u64 + chain_spec + .base_fee_params_at_timestamp(header.timestamp_seconds()) + .elasticity_multiplier as u64 } else { parent.gas_limit() };
diff --git reth/crates/consensus/consensus/src/lib.rs seismic-reth/crates/consensus/consensus/src/lib.rs index a2aa8db729c2a2d3e3b104e184a8b074dde8c88d..d1b42e33713bda110597a330f38d2f07d5d3ccd4 100644 --- reth/crates/consensus/consensus/src/lib.rs +++ seismic-reth/crates/consensus/consensus/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/consensus/debug-client/src/lib.rs seismic-reth/crates/consensus/debug-client/src/lib.rs index bc244fafeb0799a139717a071674cdc9c2a2222f..fb05eee1a8f016db20aa7af9a9e4f9b80d05fbb3 100644 --- reth/crates/consensus/debug-client/src/lib.rs +++ seismic-reth/crates/consensus/debug-client/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/engine/local/Cargo.toml seismic-reth/crates/engine/local/Cargo.toml index 98793a24b21d53d32f3545147b881ad5a9f4e21d..e2ff3f39874f706526358406cd0bcbef954c5629 100644 --- reth/crates/engine/local/Cargo.toml +++ seismic-reth/crates/engine/local/Cargo.toml @@ -9,6 +9,12 @@ repository.workspace = true exclude.workspace = true   [dependencies] +# reth-engine-service.workspace = true +# reth-engine-tree.workspace = true +# reth-node-types.workspace = true +# reth-node-core.workspace = true +# reth-evm.workspace = true + # reth reth-chainspec.workspace = true reth-engine-primitives.workspace = true @@ -33,14 +39,19 @@ eyre.workspace = true tracing.workspace = true   op-alloy-rpc-types-engine = { workspace = true, optional = true } -reth-optimism-chainspec = { workspace = true, optional = true } +# seismic: remove this dep to avoid pulling them optimism crates that don't compile implicitly by cargo/lsp/etc. +# The optimism crates don't compile because of type changes we made that affects them, such as FlaggedStorage. +# reth-optimism-chainspec = { workspace = true, optional = true }   [lints] workspace = true   [features] +timestamp-in-seconds = [] op = [ "dep:op-alloy-rpc-types-engine", - "dep:reth-optimism-chainspec", + # seismic: remove this dep to avoid pulling them optimism crates that don't compile implicitly by cargo/lsp/etc. + # The optimism crates don't compile because of type changes we made that affects them, such as FlaggedStorage. + # "dep:reth-optimism-chainspec", "reth-payload-primitives/op", ]
diff --git reth/crates/engine/local/src/lib.rs seismic-reth/crates/engine/local/src/lib.rs index 072b42a030e2d5638e855cc077b24849f2ac25c8..eb9655ee41350f7432237f8655de6761989aee69 100644 --- reth/crates/engine/local/src/lib.rs +++ seismic-reth/crates/engine/local/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/engine/local/src/miner.rs seismic-reth/crates/engine/local/src/miner.rs index 46d2ee49c3836a22aa8056b75ae2f99272276319..db897b15dfa239ebfdbb16d1b92828e9e8cd841c 100644 --- reth/crates/engine/local/src/miner.rs +++ seismic-reth/crates/engine/local/src/miner.rs @@ -107,6 +107,8 @@ mode: MiningMode<Pool>, /// The payload builder for the engine payload_builder: PayloadBuilderHandle<T>, /// Timestamp for the next block. + /// NOTE: this is in MILLISECONDS when timestamp-in-seconds feature is disabled. + /// Different from upstream reth, which holds this in seconds last_timestamp: u64, /// Stores latest mined blocks. last_block_hashes: VecDeque<B256>, @@ -126,6 +128,7 @@ to_engine: ConsensusEngineHandle<T>, mode: MiningMode<Pool>, payload_builder: PayloadBuilderHandle<T>, ) -> Self { + // NOTE: header block timestamp should be in milliseconds here let latest_header = provider.sealed_header(provider.best_block_number().unwrap()).unwrap().unwrap();   @@ -192,12 +195,21 @@ /// Generates payload attributes for a new block, passes them to FCU and inserts built payload /// through newPayload. async fn advance(&mut self) -> eyre::Result<()> { + #[cfg(feature = "timestamp-in-seconds")] let timestamp = std::cmp::max( self.last_timestamp + 1, std::time::SystemTime::now() .duration_since(UNIX_EPOCH) .expect("cannot be earlier than UNIX_EPOCH") .as_secs(), + ); + #[cfg(not(feature = "timestamp-in-seconds"))] + let timestamp = std::cmp::max( + self.last_timestamp + 1000, + std::time::SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("cannot be earlier than UNIX_EPOCH") + .as_millis() as u64, );   let res = self @@ -222,6 +234,7 @@ eyre::bail!("No payload") };   let block = payload.block(); + tracing::debug!("local_miner: advance: block: {:?}", block.body());   let payload = T::block_to_payload(payload.block().clone()); let res = self.to_engine.new_payload(payload).await?;
diff --git reth/crates/engine/local/src/payload.rs seismic-reth/crates/engine/local/src/payload.rs index 408ea2b8d059f2169e8ec66ec85e0c01641d9aca..2738c06afa5a7e201d6980072569566324dbf168 100644 --- reth/crates/engine/local/src/payload.rs +++ seismic-reth/crates/engine/local/src/payload.rs @@ -27,18 +27,25 @@ for LocalPayloadAttributesBuilder<ChainSpec> where ChainSpec: Send + Sync + EthereumHardforks + 'static, { + /// Timestamp is in milliseconds when passed into here. + /// Will store it as milliseconds in payload attributes + /// (similar to payload attributes emitted from consensus layer) + /// Use timestamp in seconds for is_shanghai_active_at_timestamp and + /// is_cancun_active_at_timestamp fn build(&self, timestamp: u64) -> EthPayloadAttributes { + let timestamp_seconds = + if cfg!(feature = "timestamp-in-seconds") { timestamp } else { timestamp / 1000 }; EthPayloadAttributes { timestamp, prev_randao: B256::random(), suggested_fee_recipient: Address::random(), withdrawals: self .chain_spec - .is_shanghai_active_at_timestamp(timestamp) + .is_shanghai_active_at_timestamp(timestamp_seconds) .then(Default::default), parent_beacon_block_root: self .chain_spec - .is_cancun_active_at_timestamp(timestamp) + .is_cancun_active_at_timestamp(timestamp_seconds) .then(B256::random), } }
diff --git reth/crates/engine/local/src/service.rs seismic-reth/crates/engine/local/src/service.rs new file mode 100644 index 0000000000000000000000000000000000000000..3c6c989926d4fde1c5843da68b98514f20880cf1 --- /dev/null +++ seismic-reth/crates/engine/local/src/service.rs @@ -0,0 +1,170 @@ +//! Provides a local dev service engine that can be used to run a dev chain. +//! +//! [`LocalEngineService`] polls the payload builder based on a mining mode +//! which can be set to `Instant` or `Interval`. The `Instant` mode will +//! constantly poll the payload builder and initiate block building +//! with a single transaction. The `Interval` mode will initiate block +//! building at a fixed interval. + +use core::fmt; +use std::{ + fmt::{Debug, Formatter}, + pin::Pin, + sync::Arc, + task::{Context, Poll}, +}; + +use crate::miner::{LocalMiner, MiningMode}; +use futures_util::{Stream, StreamExt}; +use reth_chainspec::EthChainSpec; +use reth_consensus::{ConsensusError, FullConsensus}; +use reth_engine_primitives::{BeaconConsensusEngineEvent, BeaconEngineMessage, EngineValidator}; +use reth_engine_service::service::EngineMessageStream; +use reth_engine_tree::{ + backup::BackupHandle, + chain::{ChainEvent, HandlerEvent}, + engine::{ + EngineApiKind, EngineApiRequest, EngineApiRequestHandler, EngineRequestHandler, FromEngine, + RequestHandlerEvent, + }, + persistence::PersistenceHandle, + tree::{EngineApiTreeHandler, InvalidBlockHook, TreeConfig}, +}; +use reth_evm::ConfigureEvm; +use reth_node_types::BlockTy; +use reth_payload_builder::PayloadBuilderHandle; +use reth_payload_primitives::{PayloadAttributesBuilder, PayloadTypes}; +use reth_provider::{ + providers::{BlockchainProvider, ProviderNodeTypes}, + ChainSpecProvider, ProviderFactory, +}; +use reth_prune::PrunerWithFactory; +use reth_stages_api::MetricEventsSender; +use tokio::sync::mpsc::UnboundedSender; +use tracing::error; + +// seismic imports not used by upstream +use reth_node_core::dirs::{ChainPath, DataDirPath}; + +/// Provides a local dev service engine that can be used to drive the +/// chain forward. +/// +/// This service both produces and consumes [`BeaconEngineMessage`]s. This is done to allow +/// modifications of the stream +pub struct LocalEngineService<N> +where + N: ProviderNodeTypes, +{ + /// Processes requests. + /// + /// This type is responsible for processing incoming requests. + handler: EngineApiRequestHandler<EngineApiRequest<N::Payload, N::Primitives>, N::Primitives>, + /// Receiver for incoming requests (from the engine API endpoint) that need to be processed. + incoming_requests: EngineMessageStream<N::Payload>, +} + +impl<N> LocalEngineService<N> +where + N: ProviderNodeTypes, +{ + /// Constructor for [`LocalEngineService`]. + #[expect(clippy::too_many_arguments)] + pub fn new<B, V, C>( + consensus: Arc<dyn FullConsensus<N::Primitives, Error = ConsensusError>>, + provider: ProviderFactory<N>, + blockchain_db: BlockchainProvider<N>, + pruner: PrunerWithFactory<ProviderFactory<N>>, + payload_builder: PayloadBuilderHandle<N::Payload>, + payload_validator: V, + tree_config: TreeConfig, + invalid_block_hook: Box<dyn InvalidBlockHook<N::Primitives>>, + sync_metrics_tx: MetricEventsSender, + to_engine: UnboundedSender<BeaconEngineMessage<N::Payload>>, + from_engine: EngineMessageStream<N::Payload>, + mode: MiningMode, + payload_attributes_builder: B, + evm_config: C, + data_dir: ChainPath<DataDirPath>, + ) -> Self + where + B: PayloadAttributesBuilder<<N::Payload as PayloadTypes>::PayloadAttributes>, + V: EngineValidator<N::Payload, Block = BlockTy<N>>, + C: ConfigureEvm<Primitives = N::Primitives> + 'static, + { + let chain_spec = provider.chain_spec(); + let engine_kind = + if chain_spec.is_optimism() { EngineApiKind::OpStack } else { EngineApiKind::Ethereum }; + + let persistence_handle = + PersistenceHandle::<N::Primitives>::spawn_service(provider, pruner, sync_metrics_tx); + let canonical_in_memory_state = blockchain_db.canonical_in_memory_state(); + let backup_handle = BackupHandle::spawn_service(data_dir); + + let (to_tree_tx, from_tree) = EngineApiTreeHandler::<N::Primitives, _, _, _, _>::spawn_new( + blockchain_db.clone(), + consensus, + payload_validator, + persistence_handle, + payload_builder.clone(), + canonical_in_memory_state, + tree_config, + invalid_block_hook, + engine_kind, + evm_config, + backup_handle, + ); + + let handler = EngineApiRequestHandler::new(to_tree_tx, from_tree); + + LocalMiner::spawn_new( + blockchain_db, + payload_attributes_builder, + to_engine, + mode, + payload_builder, + ); + + Self { handler, incoming_requests: from_engine } + } +} + +impl<N> Stream for LocalEngineService<N> +where + N: ProviderNodeTypes, +{ + type Item = ChainEvent<BeaconConsensusEngineEvent<N::Primitives>>; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { + let this = self.get_mut(); + + if let Poll::Ready(ev) = this.handler.poll(cx) { + return match ev { + RequestHandlerEvent::HandlerEvent(ev) => match ev { + HandlerEvent::BackfillAction(_) => { + error!(target: "engine::local", "received backfill request in local engine"); + Poll::Ready(Some(ChainEvent::FatalError)) + } + HandlerEvent::Event(ev) => Poll::Ready(Some(ChainEvent::Handler(ev))), + HandlerEvent::FatalError => Poll::Ready(Some(ChainEvent::FatalError)), + }, + RequestHandlerEvent::Download(_) => { + error!(target: "engine::local", "received download request in local engine"); + Poll::Ready(Some(ChainEvent::FatalError)) + } + } + } + + // forward incoming requests to the handler + while let Poll::Ready(Some(req)) = this.incoming_requests.poll_next_unpin(cx) { + this.handler.on_event(FromEngine::Request(req.into())); + } + + Poll::Pending + } +} + +impl<N: ProviderNodeTypes> Debug for LocalEngineService<N> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("LocalEngineService").finish_non_exhaustive() + } +}
diff --git reth/crates/engine/primitives/src/config.rs seismic-reth/crates/engine/primitives/src/config.rs index 03c83e0895322d48e6a44475c8a131e4f618e1ce..f342b28c3969ffdb25970863353acacde72b9f55 100644 --- reth/crates/engine/primitives/src/config.rs +++ seismic-reth/crates/engine/primitives/src/config.rs @@ -1,7 +1,8 @@ //! Engine tree configuration.   /// Triggers persistence when the number of canonical blocks in memory exceeds this threshold. -pub const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 2; +pub const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 0; // todo(dalton): Maybe feature flag this? We need this so archive nodes can get an accurate + // snapshot. benchmarks dont signal this is of great cost to us   /// How close to the canonical head we persist blocks. pub const DEFAULT_MEMORY_BLOCK_BUFFER_TARGET: u64 = 0;
diff --git reth/crates/engine/primitives/src/lib.rs seismic-reth/crates/engine/primitives/src/lib.rs index 0173ad8a45663662e87cd7a1b093b1d62a2f8e26..7c0fb1d540a4eeffb0961db0dc9d50360971cf43 100644 --- reth/crates/engine/primitives/src/lib.rs +++ seismic-reth/crates/engine/primitives/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/engine/service/Cargo.toml seismic-reth/crates/engine/service/Cargo.toml index 89eb6bdda51780e428fc5e27919ffa2f7cf2c982..db7784f06fa44583b2b93e93e253fe5e599c32b6 100644 --- reth/crates/engine/service/Cargo.toml +++ seismic-reth/crates/engine/service/Cargo.toml @@ -23,6 +23,7 @@ reth-prune.workspace = true reth-stages-api.workspace = true reth-tasks.workspace = true reth-node-types.workspace = true +reth-node-core.workspace = true reth-chainspec.workspace = true reth-engine-primitives.workspace = true
diff --git reth/crates/engine/service/src/lib.rs seismic-reth/crates/engine/service/src/lib.rs index a707ae9ff933b759dcfdd8c9b9f37927a81593fe..73e7ed474b4cc4069a73bc54aea2358eef77ac71 100644 --- reth/crates/engine/service/src/lib.rs +++ seismic-reth/crates/engine/service/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/engine/service/src/service.rs seismic-reth/crates/engine/service/src/service.rs index 24dcc8f31be8f4e2959ff0f01b6299639cf2cc7b..76783d03c6f87f7869e75f72abced200db2c5495 100644 --- reth/crates/engine/service/src/service.rs +++ seismic-reth/crates/engine/service/src/service.rs @@ -5,6 +5,7 @@ use reth_consensus::{ConsensusError, FullConsensus}; use reth_engine_primitives::{BeaconEngineMessage, ConsensusEngineEvent}; use reth_engine_tree::{ backfill::PipelineSync, + backup::BackupHandle, download::BasicBlockDownloader, engine::{EngineApiKind, EngineApiRequest, EngineApiRequestHandler, EngineHandler}, persistence::PersistenceHandle, @@ -31,6 +32,9 @@ pin::Pin, sync::Arc, task::{Context, Poll}, }; + +// seismic imports that upstream doesn't use +use reth_node_core::dirs::{ChainPath, DataDirPath};   /// Alias for consensus engine stream. pub type EngineMessageStream<T> = Pin<Box<dyn Stream<Item = BeaconEngineMessage<T>> + Send + Sync>>; @@ -84,6 +88,7 @@ payload_validator: V, tree_config: TreeConfig, sync_metrics_tx: MetricEventsSender, evm_config: C, + data_dir: ChainPath<DataDirPath>, ) -> Self where V: EngineValidator<N::Payload>, @@ -99,6 +104,8 @@ PersistenceHandle::<EthPrimitives>::spawn_service(provider, pruner, sync_metrics_tx);   let canonical_in_memory_state = blockchain_db.canonical_in_memory_state();   + let backup_handle = BackupHandle::spawn_service(data_dir); + let (to_tree_tx, from_tree) = EngineApiTreeHandler::<N::Primitives, _, _, _, _>::spawn_new( blockchain_db, consensus, @@ -109,6 +116,7 @@ canonical_in_memory_state, tree_config, engine_kind, evm_config, + backup_handle, );   let engine_handler = EngineApiRequestHandler::new(to_tree_tx, from_tree); @@ -154,6 +162,7 @@ use reth_ethereum_engine_primitives::EthEngineTypes; use reth_evm_ethereum::EthEvmConfig; use reth_exex_types::FinishedExExHeight; use reth_network_p2p::test_utils::TestFullBlockClient; + use reth_node_core::dirs::MaybePlatformPath; use reth_node_ethereum::EthereumEngineValidator; use reth_primitives_traits::SealedHeader; use reth_provider::{ @@ -206,7 +215,7 @@ let (sync_metrics_tx, _sync_metrics_rx) = unbounded_channel(); let (tx, _rx) = unbounded_channel(); let _eth_service = EngineService::new( consensus, - chain_spec, + chain_spec.clone(), client, Box::pin(incoming_requests), pipeline, @@ -219,6 +228,7 @@ engine_validator, TreeConfig::default(), sync_metrics_tx, evm_config, + MaybePlatformPath::chain_default(chain_spec.chain.clone()), ); } }
diff --git reth/crates/engine/tree/Cargo.toml seismic-reth/crates/engine/tree/Cargo.toml index 9be7d4957634563d4828a8c4803389913cb65dd6..a9bfd075b5cae5ea8c077fd3c5ec5aeac78b5e5f 100644 --- reth/crates/engine/tree/Cargo.toml +++ seismic-reth/crates/engine/tree/Cargo.toml @@ -9,9 +9,7 @@ repository.workspace = true   [lints] workspace = true - -[dependencies] -# reth +[dependencies] # reth reth-chain-state.workspace = true reth-chainspec = { workspace = true, optional = true } reth-consensus.workspace = true @@ -35,6 +33,7 @@ reth-trie-parallel.workspace = true reth-trie-sparse = { workspace = true, features = ["std", "metrics"] } reth-trie-sparse-parallel = { workspace = true, features = ["std"] } reth-trie.workspace = true +reth-node-core.workspace = true   # alloy alloy-evm.workspace = true @@ -46,6 +45,7 @@ alloy-rpc-types-engine.workspace = true   revm.workspace = true revm-primitives.workspace = true +revm-state.workspace = true   # common futures.workspace = true @@ -112,6 +112,7 @@ name = "state_root_task" harness = false   [features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] test-utils = [ "reth-chain-state/test-utils", "reth-chainspec/test-utils", @@ -131,7 +132,6 @@ "reth-static-file", "reth-tracing", "reth-trie/test-utils", "reth-trie-sparse/test-utils", - "reth-prune-types?/test-utils", "reth-trie-db/test-utils", "reth-trie-parallel/test-utils", "reth-ethereum-primitives/test-utils",
diff --git reth/crates/engine/tree/benches/channel_perf.rs seismic-reth/crates/engine/tree/benches/channel_perf.rs index 41dd651c8907bbee90050696f4142b81255bfee5..ab7587475706cd1fdd39a9320c1add706cd8ef58 100644 --- reth/crates/engine/tree/benches/channel_perf.rs +++ seismic-reth/crates/engine/tree/benches/channel_perf.rs @@ -7,7 +7,9 @@ use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion}; use proptest::test_runner::TestRunner; use rand::Rng; use revm_primitives::{Address, HashMap}; -use revm_state::{Account, AccountInfo, AccountStatus, EvmState, EvmStorage, EvmStorageSlot}; +use revm_state::{ + Account, AccountInfo, AccountStatus, EvmState, EvmStorage, EvmStorageSlot, FlaggedStorage, +}; use std::{hint::black_box, thread};   /// Creates a mock state with the specified number of accounts for benchmarking @@ -17,8 +19,10 @@ let mut rng = runner.rng().clone(); let mut state_changes = HashMap::default();   for i in 0..num_accounts { - let storage = - EvmStorage::from_iter([(U256::from(i), EvmStorageSlot::new(U256::from(i + 1), 0))]); + let storage = EvmStorage::from_iter([( + U256::from(i), + EvmStorageSlot::new(FlaggedStorage::public(i + 1), 0), + )]);   let account = Account { info: AccountInfo {
diff --git reth/crates/engine/tree/benches/state_root_task.rs seismic-reth/crates/engine/tree/benches/state_root_task.rs index 9f61e62d2f9b3b0b584d7e27ecbf412e7e86d520..f2b48f735cde91e92d01ff77d57d2d2b7fcb8708 100644 --- reth/crates/engine/tree/benches/state_root_task.rs +++ seismic-reth/crates/engine/tree/benches/state_root_task.rs @@ -26,7 +26,9 @@ AccountReader, ChainSpecProvider, HashingWriter, ProviderFactory, }; use reth_trie::TrieInput; use revm_primitives::{HashMap, U256}; -use revm_state::{Account as RevmAccount, AccountInfo, AccountStatus, EvmState, EvmStorageSlot}; +use revm_state::{ + Account as RevmAccount, AccountInfo, AccountStatus, EvmState, EvmStorageSlot, FlaggedStorage, +}; use std::{hint::black_box, sync::Arc};   #[derive(Debug, Clone)] @@ -77,8 +79,8 @@ .map(|_| { ( U256::from(rng.random::<u64>()), EvmStorageSlot::new_changed( - U256::ZERO, - U256::from(rng.random::<u64>()), + FlaggedStorage::ZERO, + FlaggedStorage::public(rng.random::<u64>()), 0, ), )
diff --git reth/crates/engine/tree/src/backup.rs seismic-reth/crates/engine/tree/src/backup.rs new file mode 100644 index 0000000000000000000000000000000000000000..5c191ec0708ace38387c13267be1aa8bdecad1c7 --- /dev/null +++ seismic-reth/crates/engine/tree/src/backup.rs @@ -0,0 +1,226 @@ +//! reth's database backup functionality +use alloy_eips::BlockNumHash; +use reth_errors::ProviderError; +use reth_node_core::dirs::{ChainPath, DataDirPath}; +use std::{ + path::PathBuf, + sync::mpsc::{Receiver, Sender}, + time::Instant, +}; +use thiserror::Error; +use tokio::sync::oneshot; +use tracing::*; + +/// Configuration for the backup service +#[derive(Debug, Clone)] +pub struct BackupConfig { + /// Source directory to backup + pub source_dir: PathBuf, + /// Destination directory for backups + pub dest_dir: PathBuf, +} + +/// Service that handles database backups based on block events +#[derive(Debug)] +pub struct BackupService { + /// Incoming backup requests + incoming: Receiver<BackupAction>, + /// The data directory for the engine tree. + data_dir: ChainPath<DataDirPath>, +} +/// A signal to the backup service that a backup should be performed. +#[derive(Debug)] +pub enum BackupAction { + /// Perform a backup at the given block number. + BackupAtBlock(BlockNumHash, oneshot::Sender<Option<BlockNumHash>>), +} +impl BackupService { + /// Create a new backup service + pub fn new(incoming: Receiver<BackupAction>, data_dir: ChainPath<DataDirPath>) -> Self { + Self { incoming, data_dir } + } + + /// Main loop that processes backup actions + pub fn run(self) -> Result<(), ProviderError> { + debug!(target: "engine::backup", service=?self, "Backup service starting to run"); + while let Ok(action) = self.incoming.recv() { + debug!(target: "engine::backup", action=?action, "Backup service received action"); + match action { + BackupAction::BackupAtBlock(block_number, sender) => { + let result = self.perform_backup(block_number); + if let Err(e) = result { + error!(target: "engine::backup", ?e, "Backup failed"); + let _ = sender.send(None); + } else { + let _ = sender.send(Some(block_number)); + } + } + } + } + Ok(()) + } + + /// Perform the actual backup operation + fn perform_backup(&self, block_number: BlockNumHash) -> Result<(), ProviderError> { + debug!(target: "engine::backup", ?block_number, "Starting backup"); + let backup_path = PathBuf::from(format!("{}_backup", self.data_dir.data_dir().display(),)); + + // Perform the actual backup using the provider + BackupService::backup_dir(&PathBuf::from(self.data_dir.data_dir()), &backup_path)?; + + info!( + target: "engine::backup", + ?block_number, + "Backup completed successfully" + ); + + Ok(()) + } + + /// Recursively copies the source directory to the destination directory. + /// + /// This function uses asynchronous file operations to perform the backup. + /// + /// # Arguments + /// + /// * `source` - The source directory to backup. + /// * `destination` - The destination directory where the backup will be stored. + /// + /// # Returns + /// + /// * `Ok(())` if the backup is successful. + /// * `Err(anyhow::Error)` if an error occurs during the backup. + pub fn backup_dir(source: &PathBuf, destination: &PathBuf) -> Result<(), ProviderError> { + debug!(target: "engine::backup", ?source, ?destination); + + let source_path = source.as_path(); + let destination_path = destination.as_path(); + + // Retrieve the metadata of the source path + let metadata = std::fs::metadata(source_path) + .expect(&format!("Failed to access source path: {} ", source_path.display(),)); + + // If the source is a directory, create the destination directory if it does not exist + if metadata.is_dir() { + if !destination_path.exists() { + std::fs::create_dir_all(destination_path) + .expect(&format!("Failed to create destination directory")); + } + + // Stack to manage recursive copying + let mut entries_stack = + vec![(source_path.to_path_buf(), destination_path.to_path_buf())]; + + while let Some((current_src, current_dst)) = entries_stack.pop() { + let mut entries = std::fs::read_dir(&current_src) + .expect(&format!("Failed to read directory {}", current_src.display(),)); + + while let Some(entry) = + entries.next().transpose().expect(&format!("Failed to get diredctory entry")) + { + let entry_path = entry.path(); + let entry_name = entry.file_name(); + let dst_path = current_dst.join(&entry_name); + let entry_metadata = + entry.metadata().expect(&format!("Failed to get diredctory entry")); + + if entry_metadata.is_dir() { + if !dst_path.exists() { + std::fs::create_dir_all(&dst_path).expect(&format!( + "Failed to create directory {}", + dst_path.display(), + )); + } + entries_stack.push((entry_path, dst_path)); + } else { + std::fs::copy(&entry_path, &dst_path).expect(&format!( + "Failed to copy file from {} to {}", + entry_path.display(), + dst_path.display(), + )); + } + } + } + } else { + // If the source is a file, copy it directly, creating parent directories if necessary + if let Some(parent) = destination_path.parent() { + if !parent.exists() { + std::fs::create_dir_all(parent) + .expect( + &format!("Failed to create parent directory {}", parent.display(),), + ); + } + } + std::fs::copy(source_path, destination_path).expect(&format!( + "Failed to copy file from {} to {}", + source_path.display(), + destination_path.display(), + )); + } + + Ok(()) + } +} + +/// Errors that can occur during backup operations +#[derive(Debug, Error)] +pub enum BackupError { + /// IO error + #[error(transparent)] + Io(#[from] std::io::Error), + /// Provider error + #[error(transparent)] + Provider(#[from] reth_provider::ProviderError), +} + +/// Handle to interact with the backup service +#[derive(Debug)] +pub struct BackupHandle { + /// The sender for backup actions + pub sender: Sender<BackupAction>, + /// The receiver from backup service + pub rx: Option<(oneshot::Receiver<Option<BlockNumHash>>, Instant)>, + /// The latest backup block number + pub latest_backup_block: BlockNumHash, +} + +impl BackupHandle { + /// Create a new backup handle + pub fn new(sender: Sender<BackupAction>) -> Self { + Self { sender, rx: None, latest_backup_block: BlockNumHash::default() } + } + + /// Spawn a new backup service + pub fn spawn_service(data_dir: ChainPath<DataDirPath>) -> BackupHandle { + let (tx, rx) = std::sync::mpsc::channel(); + let handle = BackupHandle::new(tx); + + let service = BackupService::new(rx, data_dir); + std::thread::Builder::new() + .name("Backup Service".to_string()) + .spawn(move || { + if let Err(err) = service.run() { + error!(target: "engine::backup", ?err, "Backup service failed"); + } + }) + .unwrap(); + + handle + } + + /// Checks if a backup is currently in progress. + pub fn in_progress(&self) -> bool { + self.rx.is_some() + } + + /// Sets state for a started backup task. + pub(crate) fn start(&mut self, rx: oneshot::Receiver<Option<BlockNumHash>>) { + self.rx = Some((rx, Instant::now())); + } + + /// Sets state for a finished backup task. + pub fn finish(&mut self, block_number: BlockNumHash) { + self.latest_backup_block = block_number; + self.rx = None; + } +}
diff --git reth/crates/engine/tree/src/lib.rs seismic-reth/crates/engine/tree/src/lib.rs index 6149d67bb82d0bc4d82b769fe09eea5b816b37ab..63e6d037c4786ecc2809b804fae03c48eee3d5a8 100644 --- reth/crates/engine/tree/src/lib.rs +++ seismic-reth/crates/engine/tree/src/lib.rs @@ -87,13 +87,15 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]   /// Support for backfill sync mode. pub mod backfill; +/// The background backup service +pub mod backup; /// The type that drives the chain forward. pub mod chain; /// Support for downloading blocks on demand for live sync.
diff --git reth/crates/engine/tree/src/tree/cached_state.rs seismic-reth/crates/engine/tree/src/tree/cached_state.rs index bce9949564f67e6dd89cd42ae8721b36b38b8d06..11eb947f688efd4ad8705c26e21345aa583f3479 100644 --- reth/crates/engine/tree/src/tree/cached_state.rs +++ seismic-reth/crates/engine/tree/src/tree/cached_state.rs @@ -1,5 +1,5 @@ //! Implements a state provider that has a shared cache in front of it. -use alloy_primitives::{Address, StorageKey, StorageValue, B256}; +use alloy_primitives::{Address, StorageKey, B256}; use metrics::Gauge; use mini_moka::sync::CacheBuilder; use reth_errors::ProviderResult; @@ -17,6 +17,8 @@ }; use revm_primitives::map::DefaultHashBuilder; use std::time::Duration; use tracing::trace; + +use revm_state::FlaggedStorage as StorageValue;   pub(crate) type Cache<K, V> = mini_moka::sync::Cache<K, V, alloy_primitives::map::DefaultHashBuilder>; @@ -658,7 +660,7 @@ println!("Base AccountStorageCache overhead: {base_overhead} bytes"); let mut rng = rand::rng();   let key = StorageKey::random(); - let value = StorageValue::from(rng.random::<u128>()); + let value = StorageValue::public(rng.random::<u128>()); let (first_slot, _) = measure_allocation(|| { cache.insert_storage(key, Some(value)); }); @@ -668,7 +670,7 @@ const TOTAL_SLOTS: usize = 10_000; let (test_slots, _) = measure_allocation(|| { for _ in 0..TOTAL_SLOTS { let key = StorageKey::random(); - let value = StorageValue::from(rng.random::<u128>()); + let value = StorageValue::public(rng.random::<u128>()); cache.insert_storage(key, Some(value)); } }); @@ -708,8 +710,8 @@ // make sure when we have something uncached, we get the cached value let address = Address::random(); let storage_key = StorageKey::random(); let storage_value = U256::from(1); - let account = - ExtendedAccount::new(0, U256::ZERO).extend_storage(vec![(storage_key, storage_value)]); + let account = ExtendedAccount::new(0, U256::ZERO) + .extend_storage(vec![(storage_key, storage_value.into())]);   // note that we extend storage here with one value let provider = MockEthProvider::default(); @@ -722,7 +724,7 @@ // check that the storage is empty let res = state_provider.storage(address, storage_key); assert!(res.is_ok()); - assert_eq!(res.unwrap(), Some(storage_value)); + assert_eq!(res.unwrap(), Some(storage_value.into())); }   #[test] @@ -734,11 +736,11 @@ let storage_value = U256::from(1);   // insert into caches directly let caches = ProviderCacheBuilder::default().build_caches(1000); - caches.insert_storage(address, storage_key, Some(storage_value)); + caches.insert_storage(address, storage_key, Some(storage_value.into()));   // check that the storage is empty let slot_status = caches.get_storage(&address, &storage_key); - assert_eq!(slot_status, SlotStatus::Value(storage_value)); + assert_eq!(slot_status, SlotStatus::Value(storage_value.into())); }   #[test]
diff --git reth/crates/engine/tree/src/tree/instrumented_state.rs seismic-reth/crates/engine/tree/src/tree/instrumented_state.rs index 9d96aca3a2e143f6f08c416cd7b784e433bc27e0..d5410e0824642809a95eb731baf5fbd114952291 100644 --- reth/crates/engine/tree/src/tree/instrumented_state.rs +++ seismic-reth/crates/engine/tree/src/tree/instrumented_state.rs @@ -1,5 +1,5 @@ //! Implements a state provider that tracks latency metrics. -use alloy_primitives::{Address, StorageKey, StorageValue, B256}; +use alloy_primitives::{Address, StorageKey, B256}; use metrics::{Gauge, Histogram}; use reth_errors::ProviderResult; use reth_metrics::Metrics; @@ -16,6 +16,9 @@ use std::{ sync::atomic::{AtomicU64, Ordering}, time::{Duration, Instant}, }; + +// Seismic imports not used upstream +use revm_state::FlaggedStorage as StorageValue;   /// Nanoseconds per second const NANOS_PER_SEC: u32 = 1_000_000_000;
diff --git reth/crates/engine/tree/src/tree/metrics.rs seismic-reth/crates/engine/tree/src/tree/metrics.rs index 60be5c4e044f93b09436344532fa84f6c2c43c2e..10fa010d2fec95325e133991cdf2b8acf8064a28 100644 --- reth/crates/engine/tree/src/tree/metrics.rs +++ seismic-reth/crates/engine/tree/src/tree/metrics.rs @@ -367,8 +367,10 @@ // Create a state with some data let state = { let mut state = EvmState::default(); - let storage = - EvmStorage::from_iter([(U256::from(1), EvmStorageSlot::new(U256::from(2), 0))]); + let storage = EvmStorage::from_iter([( + U256::from(1), + EvmStorageSlot::new(U256::from(2).into(), 0), + )]); state.insert( Default::default(), Account {
diff --git reth/crates/engine/tree/src/tree/mod.rs seismic-reth/crates/engine/tree/src/tree/mod.rs index de5876b0fc68bd4486198b7147b15d956c4114b1..d5b08ba184a92c9bef6f60822d53b84cc0e84094 100644 --- reth/crates/engine/tree/src/tree/mod.rs +++ seismic-reth/crates/engine/tree/src/tree/mod.rs @@ -1,5 +1,6 @@ use crate::{ backfill::{BackfillAction, BackfillSyncState}, + backup::{BackupAction, BackupHandle}, chain::FromOrchestrator, engine::{DownloadRequest, EngineApiEvent, EngineApiKind, EngineApiRequest, FromEngine}, persistence::PersistenceHandle, @@ -64,6 +65,7 @@ mod metrics; mod payload_processor; pub mod payload_validator; mod persistence_state; +#[allow(unused)] pub mod precompile_cache; #[cfg(test)] mod tests; @@ -282,6 +284,8 @@ /// The engine API variant of this handler engine_kind: EngineApiKind, /// The EVM configuration. evm_config: C, + /// The backup handler + backup: BackupHandle, }   impl<N, P: Debug, T: PayloadTypes + Debug, V: Debug, C> std::fmt::Debug @@ -341,6 +345,7 @@ payload_builder: PayloadBuilderHandle<T>, config: TreeConfig, engine_kind: EngineApiKind, evm_config: C, + backup: BackupHandle, ) -> Self { let (incoming_tx, incoming) = std::sync::mpsc::channel();   @@ -361,6 +366,7 @@ metrics: Default::default(), incoming_tx, engine_kind, evm_config, + backup, } }   @@ -380,6 +386,7 @@ canonical_in_memory_state: CanonicalInMemoryState<N>, config: TreeConfig, kind: EngineApiKind, evm_config: C, + backup: BackupHandle, ) -> (Sender<FromEngine<EngineApiRequest<T, N>, N::Block>>, UnboundedReceiver<EngineApiEvent<N>>) { let best_block_number = provider.best_block_number().unwrap_or(0); @@ -411,6 +418,7 @@ payload_builder, config, kind, evm_config, + backup, ); let incoming = task.incoming_tx.clone(); std::thread::Builder::new().name("Engine Task".to_string()).spawn(|| task.run()).unwrap(); @@ -446,6 +454,10 @@ }   if let Err(err) = self.advance_persistence() { error!(target: "engine::tree", %err, "Advancing persistence failed"); + return + } + if let Err(err) = self.advance_backup() { + error!(target: "engine::tree", %err, "Advancing backup failed"); return } } @@ -1148,7 +1160,7 @@ #[expect(clippy::type_complexity)] fn try_recv_engine_message( &self, ) -> Result<Option<FromEngine<EngineApiRequest<T, N>, N::Block>>, RecvError> { - if self.persistence_state.in_progress() { + if self.persistence_state.in_progress() || self.backup.in_progress() { // try to receive the next request with a timeout to not block indefinitely match self.incoming.recv_timeout(std::time::Duration::from_millis(500)) { Ok(msg) => Ok(Some(msg)), @@ -1246,6 +1258,51 @@ Ok(()) }   + fn advance_backup(&mut self) -> Result<(), AdvancePersistenceError> { + debug!(target: "engine::tree", "advance_backup called"); + if !self.backup.in_progress() { + if self.should_backup() { + debug!(target: "engine::tree", "sending backup action"); + let (tx, rx) = oneshot::channel(); + let _ = self.backup.sender.send(BackupAction::BackupAtBlock( + self.persistence_state.last_persisted_block, + tx, + )); + self.backup.start(rx); + } + } + + if self.backup.in_progress() { + let (mut rx, start_time) = self + .backup + .rx + .take() + .expect("if a backup task is in progress Receiver must be Some"); + // Check if persistence has complete + match rx.try_recv() { + Ok(last_backup_hash_num) => { + let Some(BlockNumHash { + hash: last_backup_block_hash, + number: last_backup_block_number, + }) = last_backup_hash_num + else { + warn!(target: "engine::tree", "Backup task completed but did not backup any blocks"); + return Ok(()) + }; + + debug!(target: "engine::tree", ?last_backup_hash_num, "Finished backup, calling finish"); + self.backup.finish(BlockNumHash::new( + last_backup_block_number, + last_backup_block_hash, + )); + } + Err(TryRecvError::Closed) => return Err(TryRecvError::Closed.into()), + Err(TryRecvError::Empty) => self.backup.rx = Some((rx, start_time)), + } + } + Ok(()) + } + /// Handles a message from the engine. fn on_engine_message( &mut self, @@ -1326,6 +1383,7 @@ error!(target: "engine::tree", "Failed to send event: {err:?}"); } } BeaconEngineMessage::NewPayload { payload, tx } => { + debug!("receiving beacon engine message: payload: {:?}", payload); let mut output = self.on_new_payload(payload);   let maybe_event = @@ -1562,6 +1620,14 @@ let min_block = self.persistence_state.last_persisted_block.number; self.state.tree_state.canonical_block_number().saturating_sub(min_block) > self.config.persistence_threshold() + } + + /// Returns true if the canonical chain length minus the last persisted + /// block is greater than or equal to the backup threshold and + /// backfill is not running. + fn should_backup(&self) -> bool { + debug!(target: "engine::tree", "checking if we should backup"); + return false; }   /// Returns a batch of consecutive canonical blocks to persist in the range
diff --git reth/crates/engine/tree/src/tree/payload_processor/configured_sparse_trie.rs seismic-reth/crates/engine/tree/src/tree/payload_processor/configured_sparse_trie.rs index d59f14c796a181aee893ef7ec259a95b345654e9..6201362facf57c8451b0aebbb9a70af05747ad65 100644 --- reth/crates/engine/tree/src/tree/payload_processor/configured_sparse_trie.rs +++ seismic-reth/crates/engine/tree/src/tree/payload_processor/configured_sparse_trie.rs @@ -94,11 +94,12 @@ fn update_leaf<P: TrieNodeProvider>( &mut self, full_path: Nibbles, value: Vec<u8>, + is_private: bool, provider: P, ) -> SparseTrieResult<()> { match self { - Self::Serial(trie) => trie.update_leaf(full_path, value, provider), - Self::Parallel(trie) => trie.update_leaf(full_path, value, provider), + Self::Serial(trie) => trie.update_leaf(full_path, value, is_private, provider), + Self::Parallel(trie) => trie.update_leaf(full_path, value, is_private, provider), } }
diff --git reth/crates/engine/tree/src/tree/payload_processor/mod.rs seismic-reth/crates/engine/tree/src/tree/payload_processor/mod.rs index 6c298d7625540c4ecf2badeb120335d677b3a918..b3ec3a4f811e92ff1fe6de8ca873d3e7ff57fd69 100644 --- reth/crates/engine/tree/src/tree/payload_processor/mod.rs +++ seismic-reth/crates/engine/tree/src/tree/payload_processor/mod.rs @@ -610,8 +610,8 @@ let slot = U256::from(rng.random::<u64>()); storage.insert( slot, EvmStorageSlot::new_changed( - U256::ZERO, - U256::from(rng.random::<u64>()), + U256::ZERO.into(), + U256::from(rng.random::<u64>()).into(), 0, ), ); @@ -648,8 +648,10 @@ let genesis_hash = init_genesis(&factory).unwrap();   let state_updates = create_mock_state_updates(10, 10); let mut hashed_state = HashedPostState::default(); - let mut accumulated_state: HashMap<Address, (Account, HashMap<B256, U256>)> = - HashMap::default(); + let mut accumulated_state: HashMap< + Address, + (Account, HashMap<B256, alloy_primitives::FlaggedStorage>), + > = HashMap::default();   { let provider_rw = factory.provider_rw().expect("failed to get provider"); @@ -677,9 +679,8 @@ }   for update in &state_updates { hashed_state.extend(evm_state_to_hashed_post_state(update.clone())); - for (address, account) in update { - let storage: HashMap<B256, U256> = account + let storage: HashMap<B256, alloy_primitives::FlaggedStorage> = account .storage .iter() .map(|(k, v)| (B256::from(*k), v.present_value))
diff --git reth/crates/engine/tree/src/tree/payload_processor/multiproof.rs seismic-reth/crates/engine/tree/src/tree/payload_processor/multiproof.rs index 93c72b73f143c0a7a9ca11a674996a12a946ac27..020d756cc20956f91bcdbbe673af4204ba076a73 100644 --- reth/crates/engine/tree/src/tree/payload_processor/multiproof.rs +++ seismic-reth/crates/engine/tree/src/tree/payload_processor/multiproof.rs @@ -1287,8 +1287,8 @@ let mut storage = HashedStorage::default(); let slot1 = B256::random(); let slot2 = B256::random(); - storage.storage.insert(slot1, U256::ZERO); - storage.storage.insert(slot2, U256::from(1)); + storage.storage.insert(slot1, U256::ZERO.into()); + storage.storage.insert(slot2, U256::from(1).into()); state.storages.insert(addr1, storage);   state @@ -1393,8 +1393,8 @@ state.accounts.insert(addr1, Some(Default::default())); state.accounts.insert(addr2, Some(Default::default()));   let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::ZERO); - storage.storage.insert(slot2, U256::from(1)); + storage.storage.insert(slot1, U256::ZERO.into()); + storage.storage.insert(slot2, U256::from(1).into()); state.storages.insert(addr1, storage);   let mut fetched_slots = HashSet::default(); @@ -1420,8 +1420,8 @@ // don't add the account to state.accounts (simulating unmodified account) // but add storage updates for this account let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::from(1)); - storage.storage.insert(slot2, U256::from(2)); + storage.storage.insert(slot1, U256::from(1).into()); + storage.storage.insert(slot2, U256::from(2).into()); state.storages.insert(addr, storage);   assert!(!state.accounts.contains_key(&addr)); @@ -1534,8 +1534,8 @@ state.accounts.insert(addr, Some(Default::default()));   // add storage updates let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::from(100)); - storage.storage.insert(slot2, U256::from(200)); + storage.storage.insert(slot1, U256::from(100).into()); + storage.storage.insert(slot2, U256::from(200).into()); state.storages.insert(addr, storage);   // mark slot1 as already fetched @@ -1546,7 +1546,7 @@ // update multi_added_removed_keys to mark slot1 as removed let mut removed_state = HashedPostState::default(); let mut removed_storage = HashedStorage::default(); - removed_storage.storage.insert(slot1, U256::ZERO); // U256::ZERO marks as removed + removed_storage.storage.insert(slot1, U256::ZERO.into()); // U256::ZERO marks as removed removed_state.storages.insert(addr, removed_storage); multi_added_removed_keys.update_with_state(&removed_state);   @@ -1574,7 +1574,7 @@ state.accounts.insert(addr, Some(Default::default()));   // add wiped storage let mut storage = HashedStorage::new(true); - storage.storage.insert(slot1, U256::from(100)); + storage.storage.insert(slot1, U256::from(100).into()); state.storages.insert(addr, storage);   let targets = get_proof_targets(&state, &fetched, &multi_added_removed_keys); @@ -1602,8 +1602,8 @@ state.accounts.insert(addr, Some(Default::default()));   // add storage updates for slot1 and slot2 only let mut storage = HashedStorage::default(); - storage.storage.insert(slot1, U256::from(100)); - storage.storage.insert(slot2, U256::from(200)); + storage.storage.insert(slot1, U256::from(100).into()); + storage.storage.insert(slot2, U256::from(200).into()); state.storages.insert(addr, storage);   // mark all slots as already fetched @@ -1616,7 +1616,7 @@ // mark slot3 as removed (even though it's not in the state update) let mut removed_state = HashedPostState::default(); let mut removed_storage = HashedStorage::default(); - removed_storage.storage.insert(slot3, U256::ZERO); + removed_storage.storage.insert(slot3, U256::ZERO.into()); removed_state.storages.insert(addr, removed_storage); multi_added_removed_keys.update_with_state(&removed_state);
diff --git reth/crates/engine/tree/src/tree/payload_processor/prewarm.rs seismic-reth/crates/engine/tree/src/tree/payload_processor/prewarm.rs index 4d31d55d2219d6231ff471e24344af91312843ac..346ac89c196364f69806eaf8345aac5e8595a150 100644 --- reth/crates/engine/tree/src/tree/payload_processor/prewarm.rs +++ seismic-reth/crates/engine/tree/src/tree/payload_processor/prewarm.rs @@ -5,7 +5,7 @@ cached_state::{CachedStateMetrics, CachedStateProvider, ProviderCaches, SavedCache}, payload_processor::{ executor::WorkloadExecutor, multiproof::MultiProofMessage, ExecutionCache, }, - precompile_cache::{CachedPrecompile, PrecompileCacheMap}, + precompile_cache::PrecompileCacheMap, ExecutionEnv, StateProviderBuilder, }; use alloy_evm::Database; @@ -224,6 +224,7 @@ pub(super) metrics: PrewarmMetrics, /// An atomic bool that tells prewarm tasks to not start any more execution. pub(super) terminate_execution: Arc<AtomicBool>, pub(super) precompile_cache_disabled: bool, + #[allow(dead_code)] pub(super) precompile_cache_map: PrecompileCacheMap<SpecFor<Evm>>, }   @@ -245,7 +246,7 @@ provider, metrics, terminate_execution, precompile_cache_disabled, - mut precompile_cache_map, + precompile_cache_map: _, } = self;   let state_provider = match provider.build() { @@ -273,19 +274,27 @@ // doesn't match what's on chain. evm_env.cfg_env.disable_nonce_check = true;   // create a new executor and disable nonce checks in the env + /* let spec_id = *evm_env.spec_id(); + */ + #[allow(unused_variables, unused_mut)] let mut evm = evm_config.evm_with_env(state_provider, evm_env);   if !precompile_cache_disabled { + // TODO(usm): see if new logic fixes this below comment's concerns + // seismic upstream merge: we do not enable precompile cache since it breaks our + // stateful precompiles create a new executor and disable nonce checks in + // the env + // Only cache pure precompiles to avoid issues with stateful precompiles - evm.precompiles_mut().map_pure_precompiles(|address, precompile| { - CachedPrecompile::wrap( - precompile, - precompile_cache_map.cache_for_address(*address), - spec_id, - None, // No metrics for prewarm - ) - }); + // evm.precompiles_mut().map_pure_precompiles(|address, precompile| { + // CachedPrecompile::wrap( + // precompile, + // precompile_cache_map.cache_for_address(*address), + // spec_id, + // None, // No metrics for prewarm + // ) + // }); }   Some((evm, metrics, terminate_execution))
diff --git reth/crates/engine/tree/src/tree/payload_processor/sparse_trie.rs seismic-reth/crates/engine/tree/src/tree/payload_processor/sparse_trie.rs index b458d7d58ea11fd8a67c35ecc610dd83dd0a8d79..3bace473477cfce48ff71a83294dfab4bfed1390 100644 --- reth/crates/engine/tree/src/tree/payload_processor/sparse_trie.rs +++ seismic-reth/crates/engine/tree/src/tree/payload_processor/sparse_trie.rs @@ -183,6 +183,7 @@ for (slot, value) in storage.storage { let slot_nibbles = Nibbles::unpack(slot);   if value.is_zero() { + // TODO(usm): make sure this is correct; removed what we had removed_slots.push(slot_nibbles); continue; } @@ -191,6 +192,7 @@ trace!(target: "engine::root::sparse", ?slot_nibbles, "Updating storage slot"); storage_trie.update_leaf( slot_nibbles, alloy_rlp::encode_fixed_size(&value).to_vec(), + value.is_private, &storage_provider, )?; }
diff --git reth/crates/engine/tree/src/tree/payload_validator.rs seismic-reth/crates/engine/tree/src/tree/payload_validator.rs index 749f14f1bd83745512d92db370b42d96331c3599..ef71e323e960584a8f26b1ff219246857d1541d1 100644 --- reth/crates/engine/tree/src/tree/payload_validator.rs +++ seismic-reth/crates/engine/tree/src/tree/payload_validator.rs @@ -7,14 +7,13 @@ executor::WorkloadExecutor, instrumented_state::InstrumentedStateProvider, payload_processor::PayloadProcessor, persistence_state::CurrentPersistenceAction, - precompile_cache::{CachedPrecompile, CachedPrecompileMetrics, PrecompileCacheMap}, + precompile_cache::{CachedPrecompileMetrics, PrecompileCacheMap}, sparse_trie::StateRootComputeOutcome, ConsistentDbView, EngineApiMetrics, EngineApiTreeState, ExecutionEnv, PayloadHandle, PersistenceState, PersistingKind, StateProviderBuilder, StateProviderDatabase, TreeConfig, }; use alloy_consensus::transaction::Either; use alloy_eips::{eip1898::BlockWithParent, NumHash}; -use alloy_evm::Evm; use alloy_primitives::B256; use reth_chain_state::{ CanonicalInMemoryState, ExecutedBlock, ExecutedBlockWithTrieUpdates, ExecutedTrieUpdates, @@ -24,10 +23,7 @@ use reth_engine_primitives::{ ConfigureEngineEvm, ExecutableTxIterator, ExecutionPayload, InvalidBlockHook, PayloadValidator, }; use reth_errors::{BlockExecutionError, ProviderResult}; -use reth_evm::{ - block::BlockExecutor, execute::ExecutableTxFor, ConfigureEvm, EvmEnvFor, ExecutionCtxFor, - SpecFor, -}; +use reth_evm::{execute::ExecutableTxFor, ConfigureEvm, EvmEnvFor, ExecutionCtxFor, SpecFor}; use reth_payload_primitives::{ BuiltPayload, InvalidPayloadAttributesError, NewPayloadError, PayloadTypes, }; @@ -151,8 +147,10 @@ config: TreeConfig, /// Payload processor for state root computation. payload_processor: PayloadProcessor<Evm>, /// Precompile cache map. + #[allow(dead_code)] precompile_cache_map: PrecompileCacheMap<SpecFor<Evm>>, /// Precompile cache metrics. + #[allow(dead_code)] precompile_cache_metrics: HashMap<alloy_primitives::Address, CachedPrecompileMetrics>, /// Hook to call when invalid blocks are encountered. #[debug(skip)] @@ -676,23 +674,25 @@ .build();   let evm = self.evm_config.evm_with_env(&mut db, env.evm_env.clone()); let ctx = self.execution_ctx_for(input); + + #[allow(unused_mut)] let mut executor = self.evm_config.create_executor(evm, ctx);   if !self.config.precompile_cache_disabled() { // Only cache pure precompiles to avoid issues with stateful precompiles - executor.evm_mut().precompiles_mut().map_pure_precompiles(|address, precompile| { - let metrics = self - .precompile_cache_metrics - .entry(*address) - .or_insert_with(|| CachedPrecompileMetrics::new_with_address(*address)) - .clone(); - CachedPrecompile::wrap( - precompile, - self.precompile_cache_map.cache_for_address(*address), - *env.evm_env.spec_id(), - Some(metrics), - ) - }); + // executor.evm_mut().precompiles_mut().map_pure_precompiles(|address, precompile| { + // let metrics = self + // .precompile_cache_metrics + // .entry(*address) + // .or_insert_with(|| CachedPrecompileMetrics::new_with_address(*address)) + // .clone(); + // CachedPrecompile::wrap( + // precompile, + // self.precompile_cache_map.cache_for_address(*address), + // *env.evm_env.spec_id(), + // Some(metrics), + // ) + // }); }   let execution_start = Instant::now();
diff --git reth/crates/engine/tree/src/tree/tests.rs seismic-reth/crates/engine/tree/src/tree/tests.rs index 2aa9f3e2c562f6307c66ab740c128942db4e8244..10f45be1ffd8dae358824305e6b540554398e9e8 100644 --- reth/crates/engine/tree/src/tree/tests.rs +++ seismic-reth/crates/engine/tree/src/tree/tests.rs @@ -1,5 +1,5 @@ use super::*; -use crate::persistence::PersistenceAction; +use crate::{backup::BackupHandle, persistence::PersistenceAction}; use alloy_consensus::Header; use alloy_primitives::{ map::{HashMap, HashSet}, @@ -187,6 +187,9 @@ TreeConfig::default(), Box::new(NoopInvalidBlockHook::default()), );   + let (backup_tx, _backup_rx) = channel(); + let backup_handle = BackupHandle::new(backup_tx); + let tree = EngineApiTreeHandler::new( provider.clone(), consensus, @@ -201,6 +204,7 @@ // always assume enough parallelism for tests TreeConfig::default().with_legacy_state_root(false).with_has_enough_parallelism(true), EngineApiKind::Ethereum, evm_config, + backup_handle, );   let block_builder = TestBlockBuilder::default().with_chain_spec((*chain_spec).clone()); @@ -426,6 +430,7 @@ } }   #[tokio::test] +#[ignore = "We have persistence threshold set to 0 for snapshot purposes so this test no longer works or serves a purpose"] async fn test_engine_request_during_backfill() { let tree_config = TreeConfig::default(); let blocks: Vec<_> = TestBlockBuilder::eth()
diff --git reth/crates/errors/src/error.rs seismic-reth/crates/errors/src/error.rs index 676a9c015d94413744f0ffc0bb9755b52f459281..0923ba9d902bc082f4a8ce3d143a6bab5b1e2618 100644 --- reth/crates/errors/src/error.rs +++ seismic-reth/crates/errors/src/error.rs @@ -61,8 +61,8 @@ const _: [(); $sz] = [(); core::mem::size_of::<$t>()]; }; }   - static_assert_size!(RethError, 56); - static_assert_size!(BlockExecutionError, 56); + static_assert_size!(RethError, 64); + static_assert_size!(BlockExecutionError, 64); static_assert_size!(ConsensusError, 48); static_assert_size!(DatabaseError, 32); static_assert_size!(ProviderError, 48);
diff --git reth/crates/errors/src/lib.rs seismic-reth/crates/errors/src/lib.rs index 7deba98f8aa05ccc0073fb31adb2adedb033564a..b4da8a35abf28483d008a9a11f6fee0c709eb357 100644 --- reth/crates/errors/src/lib.rs +++ seismic-reth/crates/errors/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/ethereum/cli/Cargo.toml seismic-reth/crates/ethereum/cli/Cargo.toml index 491d818eb92ba278e85d42b6f426d0795f527866..823b3e3a367729bc6b018d82810caec95ef7cf43 100644 --- reth/crates/ethereum/cli/Cargo.toml +++ seismic-reth/crates/ethereum/cli/Cargo.toml @@ -35,7 +35,7 @@ tempfile.workspace = true   [features] default = ["jemalloc"] - +timestamp-in-seconds = [] dev = ["reth-cli-commands/arbitrary"]   asm-keccak = [
diff --git reth/crates/ethereum/cli/src/lib.rs seismic-reth/crates/ethereum/cli/src/lib.rs index 067d49d1682dc3f8ab11ba95ede6193274ea237a..11e06daf7d87f8f6e54d9d7af6d36f08a5211201 100644 --- reth/crates/ethereum/cli/src/lib.rs +++ seismic-reth/crates/ethereum/cli/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/ethereum/consensus/src/lib.rs seismic-reth/crates/ethereum/consensus/src/lib.rs index e9aceb2b3fc3ad7685abdfe012a4ce8445cfe364..a33d31edf4386a6e7f9073da4ed45dcbf0a0f90f 100644 --- reth/crates/ethereum/consensus/src/lib.rs +++ seismic-reth/crates/ethereum/consensus/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -115,11 +115,11 @@ .duration_since(std::time::SystemTime::UNIX_EPOCH) .unwrap() .as_secs();   - if header.timestamp() > + if header.timestamp_seconds() > present_timestamp + alloy_eips::merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS { return Err(ConsensusError::TimestampIsInFuture { - timestamp: header.timestamp(), + timestamp: header.timestamp_seconds(), present_timestamp, }); } @@ -130,22 +130,22 @@ validate_header_gas(header)?; validate_header_base_fee(header, &self.chain_spec)?;   // EIP-4895: Beacon chain push withdrawals as operations - if self.chain_spec.is_shanghai_active_at_timestamp(header.timestamp()) && + if self.chain_spec.is_shanghai_active_at_timestamp(header.timestamp_seconds()) && header.withdrawals_root().is_none() { return Err(ConsensusError::WithdrawalsRootMissing) - } else if !self.chain_spec.is_shanghai_active_at_timestamp(header.timestamp()) && + } else if !self.chain_spec.is_shanghai_active_at_timestamp(header.timestamp_seconds()) && header.withdrawals_root().is_some() { return Err(ConsensusError::WithdrawalsRootUnexpected) }   // Ensures that EIP-4844 fields are valid once cancun is active. - if self.chain_spec.is_cancun_active_at_timestamp(header.timestamp()) { + if self.chain_spec.is_cancun_active_at_timestamp(header.timestamp_seconds()) { validate_4844_header_standalone( header, self.chain_spec - .blob_params_at_timestamp(header.timestamp()) + .blob_params_at_timestamp(header.timestamp_seconds()) .unwrap_or_else(BlobParams::cancun), )?; } else if header.blob_gas_used().is_some() { @@ -156,7 +156,7 @@ } else if header.parent_beacon_block_root().is_some() { return Err(ConsensusError::ParentBeaconBlockRootUnexpected) }   - if self.chain_spec.is_prague_active_at_timestamp(header.timestamp()) { + if self.chain_spec.is_prague_active_at_timestamp(header.timestamp_seconds()) { if header.requests_hash().is_none() { return Err(ConsensusError::RequestsHashMissing) } @@ -185,7 +185,9 @@ &self.chain_spec, )?;   // ensure that the blob gas fields for this block - if let Some(blob_params) = self.chain_spec.blob_params_at_timestamp(header.timestamp()) { + if let Some(blob_params) = + self.chain_spec.blob_params_at_timestamp(header.timestamp_seconds()) + { validate_against_parent_4844(header.header(), parent.header(), blob_params)?; }
diff --git reth/crates/ethereum/consensus/src/validation.rs seismic-reth/crates/ethereum/consensus/src/validation.rs index 485828e6080849349ec0771d3bfcfd7ed2b0334c..8ff11a27dc06c89bb91d36fc5cee47316bde92fb 100644 --- reth/crates/ethereum/consensus/src/validation.rs +++ seismic-reth/crates/ethereum/consensus/src/validation.rs @@ -51,7 +51,7 @@ } }   // Validate that the header requests hash matches the calculated requests hash - if chain_spec.is_prague_active_at_timestamp(block.header().timestamp()) { + if chain_spec.is_prague_active_at_timestamp(block.timestamp_seconds()) { let Some(header_requests_hash) = block.header().requests_hash() else { return Err(ConsensusError::RequestsHashMissing) };
diff --git reth/crates/ethereum/engine-primitives/Cargo.toml seismic-reth/crates/ethereum/engine-primitives/Cargo.toml index db42e79aa71dcc8d47212c5002e6bf7778787d8f..e46cbc818914bdeb6b4b2e4499b74df65d1d92fe 100644 --- reth/crates/ethereum/engine-primitives/Cargo.toml +++ seismic-reth/crates/ethereum/engine-primitives/Cargo.toml @@ -11,6 +11,10 @@ [lints] workspace = true   [dependencies] +# seismic +reth-seismic-primitives.workspace = true +alloy-consensus.workspace = true + # reth reth-ethereum-primitives.workspace = true reth-primitives-traits.workspace = true @@ -33,6 +37,7 @@ serde_json.workspace = true   [features] default = ["std"] +timestamp-in-seconds = ["reth-primitives-traits/timestamp-in-seconds"] std = [ "reth-ethereum-primitives/std", "alloy-primitives/std",
diff --git reth/crates/ethereum/engine-primitives/src/lib.rs seismic-reth/crates/ethereum/engine-primitives/src/lib.rs index dcd73232db6e0eb568545abeda94261ce5e2097a..c97b6197a2d95ac9caeefa8841d234e9bef76614 100644 --- reth/crates/ethereum/engine-primitives/src/lib.rs +++ seismic-reth/crates/ethereum/engine-primitives/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/ethereum/engine-primitives/src/payload.rs seismic-reth/crates/ethereum/engine-primitives/src/payload.rs index 444747716eeb442a23fb972b75c6cd62d0ebafc6..d1aa3de4401711d0db068f64794be9ea22d05f9b 100644 --- reth/crates/ethereum/engine-primitives/src/payload.rs +++ seismic-reth/crates/ethereum/engine-primitives/src/payload.rs @@ -18,8 +18,12 @@ use core::convert::Infallible; use reth_ethereum_primitives::{Block, EthPrimitives}; use reth_payload_primitives::{BuiltPayload, PayloadBuilderAttributes}; use reth_primitives_traits::SealedBlock; +use reth_seismic_primitives::SeismicPrimitives;   use crate::BuiltPayloadConversionError; + +// Seismic imports not used upstream +use reth_primitives_traits::NodePrimitives;   /// Contains the built payload. /// @@ -27,11 +31,11 @@ /// According to the [engine API specification](https://github.com/ethereum/execution-apis/blob/main/src/engine/README.md) the execution layer should build the initial version of the payload with an empty transaction set and then keep update it in order to maximize the revenue. /// Therefore, the empty-block here is always available and full-block will be set/updated /// afterward. #[derive(Debug, Clone)] -pub struct EthBuiltPayload { +pub struct EthBuiltPayload<N: NodePrimitives = EthPrimitives> { /// Identifier of the payload pub(crate) id: PayloadId, /// The built block - pub(crate) block: Arc<SealedBlock<Block>>, + pub(crate) block: Arc<SealedBlock<N::Block>>, /// The fees of the block pub(crate) fees: U256, /// The blobs, proofs, and commitments in the block. If the block is pre-cancun, this will be @@ -43,13 +47,17 @@ }   // === impl BuiltPayload ===   -impl EthBuiltPayload { +impl<N> EthBuiltPayload<N> +where + N: NodePrimitives, + N::Block: Into<alloy_consensus::Block<N::SignedTx>>, +{ /// Initializes the payload with the given initial block /// /// Caution: This does not set any [`BlobSidecars`]. pub const fn new( id: PayloadId, - block: Arc<SealedBlock<Block>>, + block: Arc<SealedBlock<N::Block>>, fees: U256, requests: Option<Requests>, ) -> Self { @@ -62,7 +70,7 @@ self.id }   /// Returns the built block(sealed) - pub fn block(&self) -> &SealedBlock<Block> { + pub fn block(&self) -> &SealedBlock<N::Block> { &self.block }   @@ -99,7 +107,7 @@ Ok(ExecutionPayloadEnvelopeV3 { execution_payload: ExecutionPayloadV3::from_block_unchecked( block.hash(), - &Arc::unwrap_or_clone(block).into_block(), + &Arc::unwrap_or_clone(block).into_block().into(), ), block_value: fees, // From the engine API spec: @@ -121,7 +129,7 @@ /// Returns an error if the payload contains non EIP-4844 sidecar. pub fn try_into_v4(self) -> Result<ExecutionPayloadEnvelopeV4, BuiltPayloadConversionError> { Ok(ExecutionPayloadEnvelopeV4 { execution_requests: self.requests.clone().unwrap_or_default(), - envelope_inner: self.try_into()?, + envelope_inner: self.try_into_v3()?, }) }   @@ -140,7 +148,7 @@ Ok(ExecutionPayloadEnvelopeV5 { execution_payload: ExecutionPayloadV3::from_block_unchecked( block.hash(), - &Arc::unwrap_or_clone(block).into_block(), + &Arc::unwrap_or_clone(block).into_block().into(), ), block_value: fees, // From the engine API spec: @@ -174,51 +182,102 @@ self.requests.clone() } }   +type SeismicBuiltPayload = EthBuiltPayload<SeismicPrimitives>; + +impl SeismicBuiltPayload { + /// Create a new [`SeismicBuiltPayload`]. + pub fn new_seismic_payload( + id: PayloadId, + block: Arc<SealedBlock<reth_seismic_primitives::SeismicBlock>>, + fees: U256, + sidecars: BlobSidecars, + requests: Option<Requests>, + ) -> Self { + Self { id, block, fees, sidecars, requests } + } +} + +impl BuiltPayload for SeismicBuiltPayload { + type Primitives = reth_seismic_primitives::SeismicPrimitives; + + fn block(&self) -> &SealedBlock<reth_seismic_primitives::SeismicBlock> { + &self.block + } + + fn fees(&self) -> U256 { + self.fees + } + + fn requests(&self) -> Option<Requests> { + self.requests.clone() + } +} + // V1 engine_getPayloadV1 response -impl From<EthBuiltPayload> for ExecutionPayloadV1 { - fn from(value: EthBuiltPayload) -> Self { +impl<N> From<EthBuiltPayload<N>> for ExecutionPayloadV1 +where + N: NodePrimitives, + N::Block: Into<alloy_consensus::Block<N::SignedTx>>, +{ + fn from(value: EthBuiltPayload<N>) -> Self { Self::from_block_unchecked( value.block().hash(), - &Arc::unwrap_or_clone(value.block).into_block(), + &Arc::unwrap_or_clone(value.clone().block).into_block().into(), ) } }   // V2 engine_getPayloadV2 response -impl From<EthBuiltPayload> for ExecutionPayloadEnvelopeV2 { - fn from(value: EthBuiltPayload) -> Self { +impl<N> From<EthBuiltPayload<N>> for ExecutionPayloadEnvelopeV2 +where + N: NodePrimitives, + N::Block: Into<alloy_consensus::Block<N::SignedTx>>, +{ + fn from(value: EthBuiltPayload<N>) -> Self { let EthBuiltPayload { block, fees, .. } = value;   Self { block_value: fees, execution_payload: ExecutionPayloadFieldV2::from_block_unchecked( block.hash(), - &Arc::unwrap_or_clone(block).into_block(), + &Arc::unwrap_or_clone(block).into_block().into(), ), } } }   -impl TryFrom<EthBuiltPayload> for ExecutionPayloadEnvelopeV3 { +impl<N> TryFrom<EthBuiltPayload<N>> for ExecutionPayloadEnvelopeV3 +where + N: NodePrimitives, + N::Block: Into<alloy_consensus::Block<N::SignedTx>>, +{ type Error = BuiltPayloadConversionError;   - fn try_from(value: EthBuiltPayload) -> Result<Self, Self::Error> { + fn try_from(value: EthBuiltPayload<N>) -> Result<Self, Self::Error> { value.try_into_v3() } }   -impl TryFrom<EthBuiltPayload> for ExecutionPayloadEnvelopeV4 { +impl<N> TryFrom<EthBuiltPayload<N>> for ExecutionPayloadEnvelopeV4 +where + N: NodePrimitives, + N::Block: Into<alloy_consensus::Block<N::SignedTx>>, +{ type Error = BuiltPayloadConversionError;   - fn try_from(value: EthBuiltPayload) -> Result<Self, Self::Error> { + fn try_from(value: EthBuiltPayload<N>) -> Result<Self, Self::Error> { value.try_into_v4() } }   -impl TryFrom<EthBuiltPayload> for ExecutionPayloadEnvelopeV5 { +impl<N> TryFrom<EthBuiltPayload<N>> for ExecutionPayloadEnvelopeV5 +where + N: NodePrimitives, + N::Block: Into<alloy_consensus::Block<N::SignedTx>>, +{ type Error = BuiltPayloadConversionError;   - fn try_from(value: EthBuiltPayload) -> Result<Self, Self::Error> { + fn try_from(value: EthBuiltPayload<N>) -> Result<Self, Self::Error> { value.try_into_v5() } } @@ -311,6 +370,8 @@ } }   /// Container type for all components required to build a payload. +/// NOTE: modified miner such that timestamp is in milliseconds (similar to payload attributes +/// emitted from consensus layer) #[derive(Debug, Clone, PartialEq, Eq, Default)] pub struct EthPayloadBuilderAttributes { /// Id of the payload @@ -319,7 +380,7 @@ /// Parent block to build the payload on top pub parent: B256, /// Unix timestamp for the generated payload /// - /// Number of seconds since the Unix epoch. + /// MODIFIED: Number of milliseconds since the Unix epoch instead of seconds. pub timestamp: u64, /// Address of the recipient for collecting transaction fee pub suggested_fee_recipient: Address, @@ -337,6 +398,15 @@ impl EthPayloadBuilderAttributes { /// Returns the identifier of the payload. pub const fn payload_id(&self) -> PayloadId { self.id + } + + /// Returns the timestamp in seconds, assuming the timestamp is in milliseconds. + pub fn timestamp_seconds(&self) -> u64 { + if cfg!(feature = "timestamp-in-seconds") { + self.timestamp + } else { + self.timestamp / 1000 + } }   /// Creates a new payload builder for the given parent block and the attributes. @@ -422,7 +492,7 @@ hasher.update(parent_beacon_block); }   let out = hasher.finalize(); - PayloadId::new(out.as_slice()[..8].try_into().expect("sufficient length")) + PayloadId::new(out[..8].try_into().expect("sufficient length")) }   #[cfg(test)]
diff --git reth/crates/ethereum/evm/Cargo.toml seismic-reth/crates/ethereum/evm/Cargo.toml index fbbbeeed836609c648f965826699bcc6eb7e5da3..618ec2fbb2640175f4b11a3b505ba28fec593789 100644 --- reth/crates/ethereum/evm/Cargo.toml +++ seismic-reth/crates/ethereum/evm/Cargo.toml @@ -38,14 +38,17 @@ reth-evm = { workspace = true, features = ["test-utils"] } secp256k1.workspace = true alloy-genesis.workspace = true   +serde_json.workspace = true +tokio.workspace = true + [features] default = ["std"] +timestamp-in-seconds = ["revm/timestamp-in-seconds", "reth-evm/timestamp-in-seconds", "alloy-evm/timestamp-in-seconds"] std = [ "alloy-consensus/std", "alloy-eips/std", "alloy-genesis/std", "alloy-primitives/std", - "secp256k1/std", "reth-ethereum-forks/std", "reth-chainspec/std", "alloy-evm/std",
diff --git reth/crates/ethereum/evm/src/build.rs seismic-reth/crates/ethereum/evm/src/build.rs index f37ba6431d11936e966612bcff84e66632f294d3..2f2a345166a5157be84f4cc8cd35e121c4addaf3 100644 --- reth/crates/ethereum/evm/src/build.rs +++ seismic-reth/crates/ethereum/evm/src/build.rs @@ -1,3 +1,4 @@ +//! Ethereum block assemblers use alloc::sync::Arc; use alloy_consensus::{ proofs, Block, BlockBody, BlockHeader, Header, Transaction, TxReceipt, EMPTY_OMMER_ROOT_HASH, @@ -53,6 +54,8 @@ .. } = input;   let timestamp = evm_env.block_env.timestamp.saturating_to(); + let timestamp_seconds = + if cfg!(feature = "timestamp-in-seconds") { timestamp } else { timestamp / 1000 };   let transactions_root = proofs::calculate_transaction_root(&transactions); let receipts_root = Receipt::calculate_receipt_root_no_memo(receipts); @@ -60,35 +63,36 @@ let logs_bloom = logs_bloom(receipts.iter().flat_map(|r| r.logs()));   let withdrawals = self .chain_spec - .is_shanghai_active_at_timestamp(timestamp) + .is_shanghai_active_at_timestamp(timestamp_seconds) .then(|| ctx.withdrawals.map(|w| w.into_owned()).unwrap_or_default());   let withdrawals_root = withdrawals.as_deref().map(|w| proofs::calculate_withdrawals_root(w)); let requests_hash = self .chain_spec - .is_prague_active_at_timestamp(timestamp) + .is_prague_active_at_timestamp(timestamp_seconds) .then(|| requests.requests_hash());   let mut excess_blob_gas = None; let mut blob_gas_used = None;   // only determine cancun fields when active - if self.chain_spec.is_cancun_active_at_timestamp(timestamp) { + if self.chain_spec.is_cancun_active_at_timestamp(timestamp_seconds) { blob_gas_used = Some(transactions.iter().map(|tx| tx.blob_gas_used().unwrap_or_default()).sum()); - excess_blob_gas = if self.chain_spec.is_cancun_active_at_timestamp(parent.timestamp) { - parent.maybe_next_block_excess_blob_gas( - self.chain_spec.blob_params_at_timestamp(timestamp), - ) - } else { - // for the first post-fork block, both parent.blob_gas_used and - // parent.excess_blob_gas are evaluated as 0 - Some( - alloy_eips::eip7840::BlobParams::cancun() - .next_block_excess_blob_gas_osaka(0, 0, 0), - ) - }; + excess_blob_gas = + if self.chain_spec.is_cancun_active_at_timestamp(parent.timestamp_seconds()) { + parent.maybe_next_block_excess_blob_gas( + self.chain_spec.blob_params_at_timestamp(timestamp_seconds), + ) + } else { + // for the first post-fork block, both parent.blob_gas_used and + // parent.excess_blob_gas are evaluated as 0 + Some( + alloy_eips::eip7840::BlobParams::cancun() + .next_block_excess_blob_gas_osaka(0, 0, 0), + ) + }; }   let header = Header {
diff --git reth/crates/ethereum/evm/src/lib.rs seismic-reth/crates/ethereum/evm/src/lib.rs index 573a161656c0ee0738ad8db0fb4845a737ead0c6..ed2c1d2e8e87b30122345c2d58a693ef7a99f98e 100644 --- reth/crates/ethereum/evm/src/lib.rs +++ seismic-reth/crates/ethereum/evm/src/lib.rs @@ -9,7 +9,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -31,8 +31,8 @@ use core::{convert::Infallible, fmt::Debug}; use reth_chainspec::{ChainSpec, EthChainSpec, EthereumHardforks, MAINNET}; use reth_ethereum_primitives::{Block, EthPrimitives, TransactionSigned}; use reth_evm::{ - precompiles::PrecompilesMap, ConfigureEngineEvm, ConfigureEvm, EvmEnv, EvmEnvFor, EvmFactory, - ExecutableTxIterator, ExecutionCtxFor, NextBlockEnvAttributes, TransactionEnv, + ConfigureEngineEvm, ConfigureEvm, EvmEnv, EvmEnvFor, EvmFactory, ExecutableTxIterator, + ExecutionCtxFor, NextBlockEnvAttributes, TransactionEnv, }; use reth_primitives_traits::{ constants::MAX_TX_GAS_LIMIT_OSAKA, SealedBlock, SealedHeader, SignedTransaction, TxTy, @@ -50,6 +50,8 @@ use alloy_evm::eth::spec::EthExecutorSpec; pub use config::{revm_spec, revm_spec_by_timestamp_and_block_number}; use reth_ethereum_forks::{EthereumHardfork, Hardforks};   +use reth_primitives_traits::BlockHeader as _; + /// Helper type with backwards compatible methods to obtain Ethereum executor /// providers. #[doc(hidden)] @@ -60,7 +62,7 @@ #[deprecated(note = "Use `EthEvmConfig` instead")] pub type EthExecutorProvider = EthEvmConfig; }   -mod build; +pub mod build; pub use build::EthBlockAssembler;   mod receipt; @@ -132,7 +134,7 @@ Tx: TransactionEnv + FromRecoveredTx<TransactionSigned> + FromTxWithEncoded<TransactionSigned>, Spec = SpecId, - Precompiles = PrecompilesMap, + // Precompiles<EmptyDBTyped<Infallible>> = PrecompilesMap, > + Clone + Debug + Send @@ -155,8 +157,13 @@ &self.block_assembler }   fn evm_env(&self, header: &Header) -> EvmEnv { - let blob_params = self.chain_spec().blob_params_at_timestamp(header.timestamp); - let spec = config::revm_spec(self.chain_spec(), header); + let timestamp_seconds = header.timestamp_seconds(); + let blob_params = self.chain_spec().blob_params_at_timestamp(timestamp_seconds); + let spec = config::revm_spec_by_timestamp_and_block_number( + self.chain_spec(), + timestamp_seconds, + header.number(), + );   // configure evm env based on parent block let mut cfg_env = @@ -166,7 +173,7 @@ if let Some(blob_params) = &blob_params { cfg_env.set_max_blobs_per_tx(blob_params.max_blobs_per_tx); }   - if self.chain_spec().is_osaka_active_at_timestamp(header.timestamp) { + if self.chain_spec().is_osaka_active_at_timestamp(timestamp_seconds) { cfg_env.tx_gas_limit_cap = Some(MAX_TX_GAS_LIMIT_OSAKA); }   @@ -199,10 +206,10 @@ attributes: &NextBlockEnvAttributes, ) -> Result<EvmEnv, Self::Error> { // ensure we're not missing any timestamp based hardforks let chain_spec = self.chain_spec(); - let blob_params = chain_spec.blob_params_at_timestamp(attributes.timestamp); + let blob_params = chain_spec.blob_params_at_timestamp(attributes.timestamp_seconds()); let spec_id = revm_spec_by_timestamp_and_block_number( chain_spec, - attributes.timestamp, + attributes.timestamp_seconds(), parent.number() + 1, );   @@ -229,7 +236,7 @@ blob_params.unwrap_or_else(BlobParams::cancun).calc_blob_fee(excess_blob_gas); BlobExcessGasAndPrice { excess_blob_gas, blob_gasprice } });   - let mut basefee = chain_spec.next_block_base_fee(parent, attributes.timestamp); + let mut basefee = chain_spec.next_block_base_fee(parent, attributes.timestamp_seconds());   let mut gas_limit = attributes.gas_limit;   @@ -239,7 +246,7 @@ if self.chain_spec().fork(EthereumHardfork::London).transitions_at_block(parent.number + 1) { let elasticity_multiplier = self .chain_spec() - .base_fee_params_at_timestamp(attributes.timestamp) + .base_fee_params_at_timestamp(attributes.timestamp_seconds()) .elasticity_multiplier;   // multiply the gas limit by the elasticity multiplier @@ -296,7 +303,7 @@ Tx: TransactionEnv + FromRecoveredTx<TransactionSigned> + FromTxWithEncoded<TransactionSigned>, Spec = SpecId, - Precompiles = PrecompilesMap, + // Precompiles<EmptyDBTyped<Infallible>> = PrecompilesMap, > + Clone + Debug + Send @@ -306,11 +313,16 @@ + 'static, { fn evm_env_for_payload(&self, payload: &ExecutionData) -> EvmEnvFor<Self> { let timestamp = payload.payload.timestamp(); + let timestamp_seconds = + if cfg!(feature = "timestamp-in-seconds") { timestamp } else { timestamp / 1000 }; let block_number = payload.payload.block_number();   - let blob_params = self.chain_spec().blob_params_at_timestamp(timestamp); - let spec = - revm_spec_by_timestamp_and_block_number(self.chain_spec(), timestamp, block_number); + let blob_params = self.chain_spec().blob_params_at_timestamp(timestamp_seconds); + let spec = revm_spec_by_timestamp_and_block_number( + self.chain_spec(), + timestamp_seconds, + block_number, + );   // configure evm env based on parent block let mut cfg_env = @@ -320,7 +332,7 @@ if let Some(blob_params) = &blob_params { cfg_env.set_max_blobs_per_tx(blob_params.max_blobs_per_tx); }   - if self.chain_spec().is_osaka_active_at_timestamp(timestamp) { + if self.chain_spec().is_osaka_active_at_timestamp(timestamp_seconds) { cfg_env.tx_gas_limit_cap = Some(MAX_TX_GAS_LIMIT_OSAKA); }   @@ -392,7 +404,7 @@ // Build the ChainSpec for Ethereum mainnet, activating London, Paris, and Shanghai // hardforks let chain_spec = ChainSpec::builder() .chain(Chain::mainnet()) - .genesis(Genesis::default()) + .genesis(Genesis::default().into()) .london_activated() .paris_activated() .shanghai_activated()
diff --git reth/crates/ethereum/hardforks/src/lib.rs seismic-reth/crates/ethereum/hardforks/src/lib.rs index 44c05e24a38c7ddc4a73991209e2467c41a99e0a..5f770a9692c55c3dea72c3059196d5fb7cfbd08c 100644 --- reth/crates/ethereum/hardforks/src/lib.rs +++ seismic-reth/crates/ethereum/hardforks/src/lib.rs @@ -9,7 +9,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/ethereum/node/Cargo.toml seismic-reth/crates/ethereum/node/Cargo.toml index 3c0efdb0394f6564e9b7b025e164f9e6ab8bd017..a2904fc3abac3b9187b48990373a6ef5f949fd27 100644 --- reth/crates/ethereum/node/Cargo.toml +++ seismic-reth/crates/ethereum/node/Cargo.toml @@ -55,6 +55,10 @@ # misc eyre.workspace = true   [dev-dependencies] +# seismic +seismic-alloy-genesis.workspace = true + +reth-chainspec.workspace = true reth-db.workspace = true reth-exex.workspace = true reth-node-core.workspace = true @@ -77,6 +81,7 @@ rand.workspace = true   [features] default = [] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] asm-keccak = [ "alloy-primitives/asm-keccak", "reth-node-core/asm-keccak",
diff --git reth/crates/ethereum/node/src/lib.rs seismic-reth/crates/ethereum/node/src/lib.rs index 1d4096f33f64a4493bcaadc91eec09927a842888..ddaededa3c858bea678fc24053a1154bc8b5ad3f 100644 --- reth/crates/ethereum/node/src/lib.rs +++ seismic-reth/crates/ethereum/node/src/lib.rs @@ -6,7 +6,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/ethereum/payload/Cargo.toml seismic-reth/crates/ethereum/payload/Cargo.toml index 42d159fb844e3cd3c00b32e5070110c06f5bf0f0..a95c19c5556b80408d00a60f137cdb43b831b09a 100644 --- reth/crates/ethereum/payload/Cargo.toml +++ seismic-reth/crates/ethereum/payload/Cargo.toml @@ -35,9 +35,12 @@ revm.workspace = true alloy-rpc-types-engine.workspace = true   # alloy -alloy-eips.workspace = true alloy-consensus.workspace = true alloy-primitives.workspace = true +alloy-eips.workspace = true   # misc tracing.workspace = true + +[features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"]
diff --git reth/crates/ethereum/payload/src/lib.rs seismic-reth/crates/ethereum/payload/src/lib.rs index 1e81d37de72513efb2c80f1f871fa19fcd51812c..48f6fe3a8a60ca86b657e064db36b1144b0776dd 100644 --- reth/crates/ethereum/payload/src/lib.rs +++ seismic-reth/crates/ethereum/payload/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -197,11 +197,11 @@ let mut block_blob_count = 0; let mut block_transactions_rlp_length = 0;   - let blob_params = chain_spec.blob_params_at_timestamp(attributes.timestamp); + let blob_params = chain_spec.blob_params_at_timestamp(attributes.timestamp_seconds()); let max_blob_count = blob_params.as_ref().map(|params| params.max_blob_count).unwrap_or_default();   - let is_osaka = chain_spec.is_osaka_active_at_timestamp(attributes.timestamp); + let is_osaka = chain_spec.is_osaka_active_at_timestamp(attributes.timestamp_seconds());   while let Some(pool_tx) = best_txs.next() { // ensure we still have capacity for this transaction @@ -353,7 +353,7 @@ let BlockBuilderOutcome { execution_result, block, .. } = builder.finish(&state_provider)?;   let requests = chain_spec - .is_prague_active_at_timestamp(attributes.timestamp) + .is_prague_active_at_timestamp(attributes.timestamp_seconds()) .then_some(execution_result.requests);   let sealed_block = Arc::new(block.sealed_block().clone());
diff --git reth/crates/ethereum/payload/src/validator.rs seismic-reth/crates/ethereum/payload/src/validator.rs index ccace26ef805507ccbfe23c7fcf91ebb49e47d25..5dbb1a310f859e74b8bd2698e7aaadbf1d619b36 100644 --- reth/crates/ethereum/payload/src/validator.rs +++ seismic-reth/crates/ethereum/payload/src/validator.rs @@ -88,19 +88,19 @@ }   shanghai::ensure_well_formed_fields( sealed_block.body(), - chain_spec.is_shanghai_active_at_timestamp(sealed_block.timestamp), + chain_spec.is_shanghai_active_at_timestamp(sealed_block.timestamp_seconds()), )?;   cancun::ensure_well_formed_fields( &sealed_block, sidecar.cancun(), - chain_spec.is_cancun_active_at_timestamp(sealed_block.timestamp), + chain_spec.is_cancun_active_at_timestamp(sealed_block.timestamp_seconds()), )?;   prague::ensure_well_formed_fields( sealed_block.body(), sidecar.prague(), - chain_spec.is_prague_active_at_timestamp(sealed_block.timestamp), + chain_spec.is_prague_active_at_timestamp(sealed_block.timestamp_seconds()), )?;   Ok(sealed_block)
diff --git reth/crates/ethereum/primitives/Cargo.toml seismic-reth/crates/ethereum/primitives/Cargo.toml index b99f2d34e58e1343192a01c32c7ba443d798f5c8..b2a47e3a26eb07a1ad981abc9b5b3c1438406125 100644 --- reth/crates/ethereum/primitives/Cargo.toml +++ seismic-reth/crates/ethereum/primitives/Cargo.toml @@ -12,6 +12,9 @@ [lints] workspace = true   [dependencies] +# Seismic imports +alloy-serde = { workspace = true, optional = true } + # reth reth-codecs = { workspace = true, optional = true } reth-primitives-traits.workspace = true @@ -47,6 +50,8 @@ default = ["std"] test-utils = [ "reth-codecs?/test-utils", "reth-primitives-traits/test-utils", + "serde", + "serde-bincode-compat", ] std = [ "alloy-consensus/std",
diff --git reth/crates/ethereum/primitives/src/lib.rs seismic-reth/crates/ethereum/primitives/src/lib.rs index 2cd5d278346e8630cd273b9fd615f5842b0a3e76..68896c42f01c11ec6d0193491b5bf2a97ac1b178 100644 --- reth/crates/ethereum/primitives/src/lib.rs +++ seismic-reth/crates/ethereum/primitives/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/ethereum/primitives/src/receipt.rs seismic-reth/crates/ethereum/primitives/src/receipt.rs index 4d2d231ac45886d8f2121bbebe3cb7d5b85b7513..6053f9c02ae09f9d484e7314374d20ca8cfcc57d 100644 --- reth/crates/ethereum/primitives/src/receipt.rs +++ seismic-reth/crates/ethereum/primitives/src/receipt.rs @@ -490,8 +490,8 @@ #[cfg(feature = "reth-codec")] mod compact { use super::*; use reth_codecs::{ - Compact, __private::{modular_bitfield::prelude::*, Buf}, + Compact, };   impl Receipt {
diff --git reth/crates/ethereum/reth/Cargo.toml seismic-reth/crates/ethereum/reth/Cargo.toml index 959b7c1b65f7059a7b0ea0e3ab368845cc609321..dd345c6cfa1dfdc2e53ae066f3bfc1a6c626e528 100644 --- reth/crates/ethereum/reth/Cargo.toml +++ seismic-reth/crates/ethereum/reth/Cargo.toml @@ -115,7 +115,6 @@ cli = ["dep:reth-ethereum-cli", "dep:reth-cli-util"] consensus = [ "dep:reth-consensus", "dep:reth-consensus-common", - "dep:reth-ethereum-consensus", ] evm = ["dep:reth-evm", "dep:reth-evm-ethereum", "dep:reth-revm"] exex = ["provider", "dep:reth-exex"]
diff --git reth/crates/etl/src/lib.rs seismic-reth/crates/etl/src/lib.rs index 46d41d704d062ec9c429190e841c627c792fb5e9..6e57f33d017fd5bc7e36ef37e4d86bc3f85be188 100644 --- reth/crates/etl/src/lib.rs +++ seismic-reth/crates/etl/src/lib.rs @@ -9,7 +9,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/evm/evm/Cargo.toml seismic-reth/crates/evm/evm/Cargo.toml index 4bc8ef06dbbd6ab46e72cf1c74db0c9c8292ae52..5412fb465749c3fd868c2e06405b97300795aa94 100644 --- reth/crates/evm/evm/Cargo.toml +++ seismic-reth/crates/evm/evm/Cargo.toml @@ -11,6 +11,10 @@ [lints] workspace = true   [dependencies] +# Seismic +op-revm = { workspace = true, optional = true } +seismic-revm = { workspace = true } + # reth reth-execution-errors.workspace = true reth-execution-types.workspace = true @@ -39,6 +43,7 @@ reth-ethereum-forks.workspace = true   [features] default = ["std"] +timestamp-in-seconds = ["revm/timestamp-in-seconds", "seismic-revm/timestamp-in-seconds", "alloy-evm/timestamp-in-seconds"] std = [ "reth-primitives-traits/std", "alloy-eips/std",
diff --git reth/crates/evm/evm/src/execute.rs seismic-reth/crates/evm/evm/src/execute.rs index 8f5505e70a5cb5252df9455633d0cbf2e8656e1b..7479e72a39a7535123a6980067e78690db6c5267 100644 --- reth/crates/evm/evm/src/execute.rs +++ seismic-reth/crates/evm/evm/src/execute.rs @@ -317,6 +317,17 @@ ) -> Result<u64, BlockExecutionError> { self.execute_transaction_with_result_closure(tx, |_| ()) }   + /// Add transaction + /// + /// Seismic team added this function to the trait for our stuff, + /// default unimplemented for backward compatibility + fn add_transaction( + &mut self, + _tx: Recovered<TxTy<Self::Primitives>>, + ) -> Result<u64, BlockExecutionError> { + unimplemented!("BlockBuilder trait's add_transaction function is not implemented") + } + /// Completes the block building process and returns the [`BlockBuilderOutcome`]. fn finish( self, @@ -483,6 +494,14 @@ let block = RecoveredBlock::new_unhashed(block, senders);   Ok(BlockBuilderOutcome { execution_result: result, hashed_state, trie_updates, block }) + } + + fn add_transaction( + &mut self, + tx: Recovered<TxTy<Self::Primitives>>, + ) -> Result<u64, BlockExecutionError> { + self.transactions.push(tx); + Ok(self.transactions.len() as u64) }   fn executor_mut(&mut self) -> &mut Self::Executor {
diff --git reth/crates/evm/evm/src/lib.rs seismic-reth/crates/evm/evm/src/lib.rs index dc47fecb9c22be84660769ccb6cf74e38ffcab24..566f713a66bbd738cf3caf6fca0ed96b3e71af92 100644 --- reth/crates/evm/evm/src/lib.rs +++ seismic-reth/crates/evm/evm/src/lib.rs @@ -9,7 +9,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -24,10 +24,7 @@ eip2718::{EIP2930_TX_TYPE_ID, LEGACY_TX_TYPE_ID}, eip2930::AccessList, eip4895::Withdrawals, }; -use alloy_evm::{ - block::{BlockExecutorFactory, BlockExecutorFor}, - precompiles::PrecompilesMap, -}; +use alloy_evm::block::{BlockExecutorFactory, BlockExecutorFor}; use alloy_primitives::{Address, B256}; use core::{error::Error, fmt::Debug}; use execute::{BasicBlockExecutor, BlockAssembler, BlockBuilder}; @@ -202,7 +199,7 @@ EvmFactory: EvmFactory< Tx: TransactionEnv + FromRecoveredTx<TxTy<Self::Primitives>> + FromTxWithEncoded<TxTy<Self::Primitives>>, - Precompiles = PrecompilesMap, + // Precompiles<EmptyDBTyped<Infallible>> = PrecompilesMap, >, >;   @@ -482,6 +479,8 @@ /// - **Configuration** (what parameters to use) - handled by `NextBlockEnvAttributes` /// - **Execution** (running transactions) - handled by `BlockExecutor` /// - **Assembly** (creating the final block) - handled by `BlockAssembler` #[derive(Debug, Clone, PartialEq, Eq)] +// NOTE: this is created in crates/payload/basic/src/lib.rs +// => timestamp should be in milliseconds pub struct NextBlockEnvAttributes { /// The timestamp of the next block. pub timestamp: u64, @@ -497,6 +496,17 @@ /// Withdrawals pub withdrawals: Option<Withdrawals>, }   +impl NextBlockEnvAttributes { + /// Returns the timestamp in seconds, assuming the timestamp is in milliseconds. + pub fn timestamp_seconds(&self) -> u64 { + if cfg!(feature = "timestamp-in-seconds") { + self.timestamp + } else { + self.timestamp / 1000 + } + } +} + /// Abstraction over transaction environment. pub trait TransactionEnv: revm::context_interface::Transaction + Debug + Clone + Send + Sync + 'static @@ -574,3 +584,21 @@ fn set_access_list(&mut self, access_list: AccessList) { self.base.set_access_list(access_list); } } + +impl<T: TransactionEnv> TransactionEnv for seismic_revm::SeismicTransaction<T> { + fn set_gas_limit(&mut self, gas_limit: u64) { + self.base.set_gas_limit(gas_limit); + } + + fn nonce(&self) -> u64 { + TransactionEnv::nonce(&self.base) + } + + fn set_nonce(&mut self, nonce: u64) { + self.base.set_nonce(nonce); + } + + fn set_access_list(&mut self, access_list: AccessList) { + self.base.set_access_list(access_list); + } +}
diff --git reth/crates/evm/execution-errors/src/lib.rs seismic-reth/crates/evm/execution-errors/src/lib.rs index b8ddd1b44693143f5a2b409d35da9bcb9b95445e..c9c230e3e0a00cb0090f1029beb155dc488dd477 100644 --- reth/crates/evm/execution-errors/src/lib.rs +++ seismic-reth/crates/evm/execution-errors/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/evm/execution-types/Cargo.toml seismic-reth/crates/evm/execution-types/Cargo.toml index 6c53e315b32fd7130b8b360fb70c06ba27181895..64f29f8676397507598f12a2073e617cfbcf2775 100644 --- reth/crates/evm/execution-types/Cargo.toml +++ seismic-reth/crates/evm/execution-types/Cargo.toml @@ -38,6 +38,7 @@ rand.workspace = true   [features] default = ["std"] +timestamp-in-seconds = ["reth-primitives-traits/timestamp-in-seconds"] serde = [ "dep:serde", "rand/serde",
diff --git reth/crates/evm/execution-types/src/execution_outcome.rs seismic-reth/crates/evm/execution-types/src/execution_outcome.rs index 49c352472977a9f467ce1dbac3c261692532d085..7828b19a426c1ff283c7c28456a4c3cc846987ff 100644 --- reth/crates/evm/execution-types/src/execution_outcome.rs +++ seismic-reth/crates/evm/execution-types/src/execution_outcome.rs @@ -6,12 +6,14 @@ use reth_primitives_traits::{Account, Bytecode, Receipt, StorageEntry}; use reth_trie_common::{HashedPostState, KeyHasher}; use revm::{ database::{states::BundleState, BundleAccount}, - state::AccountInfo, + state::{AccountInfo, FlaggedStorage}, };   /// Type used to initialize revms bundle state. -pub type BundleStateInit = - HashMap<Address, (Option<Account>, Option<Account>, HashMap<B256, (U256, U256)>)>; +pub type BundleStateInit = HashMap< + Address, + (Option<Account>, Option<Account>, HashMap<B256, (FlaggedStorage, FlaggedStorage)>), +>;   /// Types used inside `RevertsInit` to initialize revms reverts. pub type AccountRevertInit = (Option<Option<Account>>, Vec<StorageEntry>); @@ -109,7 +111,10 @@ ( address, original.map(Into::into), present.map(Into::into), - storage.into_iter().map(|(k, s)| (k.into(), s)).collect(), + storage + .into_iter() + .map(|(k, (orig_value, new_value))| (k.into(), (orig_value, new_value))) + .collect(), ) }), reverts.into_iter().map(|(_, reverts)| { @@ -185,7 +190,7 @@ /// Get storage if value is known. /// /// This means that depending on status we can potentially return `U256::ZERO`. - pub fn storage(&self, address: &Address, storage_key: U256) -> Option<U256> { + pub fn storage(&self, address: &Address, storage_key: U256) -> Option<FlaggedStorage> { self.bundle.account(address).and_then(|a| a.storage_slot(storage_key)) }
diff --git reth/crates/evm/execution-types/src/lib.rs seismic-reth/crates/evm/execution-types/src/lib.rs index 04dd84731347a2d92c756ba99a19c25777f5bb57..c45e06a675f93ffec231c9dfc6a60f625f79db8c 100644 --- reth/crates/evm/execution-types/src/lib.rs +++ seismic-reth/crates/evm/execution-types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/exex/exex/Cargo.toml seismic-reth/crates/exex/exex/Cargo.toml index 0d09f0a8c6800904e4948d4c14027b707fc2377b..76adcbee16acff6ac742d9d52a026aafe3e149fa 100644 --- reth/crates/exex/exex/Cargo.toml +++ seismic-reth/crates/exex/exex/Cargo.toml @@ -52,6 +52,9 @@ thiserror.workspace = true tracing.workspace = true   [dev-dependencies] +# seismic +seismic-alloy-genesis.workspace = true + reth-db-common.workspace = true reth-evm-ethereum.workspace = true reth-primitives-traits = { workspace = true, features = ["test-utils"] }
diff --git reth/crates/exex/exex/src/backfill/stream.rs seismic-reth/crates/exex/exex/src/backfill/stream.rs index aa7cacdba4a1a6cb10a985b980ccb73b01577b02..400532e22d3b035ff2f461ba2334b58b94c6337b 100644 --- reth/crates/exex/exex/src/backfill/stream.rs +++ seismic-reth/crates/exex/exex/src/backfill/stream.rs @@ -268,7 +268,7 @@ use reth_testing_utils::{generators, generators::sign_tx_with_key_pair}; use secp256k1::Keypair; use std::sync::Arc;   - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn test_single_blocks() -> eyre::Result<()> { reth_tracing::init_test_tracing();   @@ -305,7 +305,7 @@ Ok(()) }   - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn test_batch() -> eyre::Result<()> { reth_tracing::init_test_tracing();
diff --git reth/crates/exex/exex/src/lib.rs seismic-reth/crates/exex/exex/src/lib.rs index d5da6a18faa56bbc8c7ead226321868034d5912d..7e86cf4fd37972fa0b872903129455bf209df019 100644 --- reth/crates/exex/exex/src/lib.rs +++ seismic-reth/crates/exex/exex/src/lib.rs @@ -83,7 +83,7 @@ //! [`CanonStateNotification`]: reth_provider::CanonStateNotification #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/exex/exex/src/notifications.rs seismic-reth/crates/exex/exex/src/notifications.rs index c624fd4ff4ee8251a4490203d2b0b5f68efb1818..3e2f2c3c7721b695443dc3cc57b8ae5d19579086 100644 --- reth/crates/exex/exex/src/notifications.rs +++ seismic-reth/crates/exex/exex/src/notifications.rs @@ -462,7 +462,7 @@ }; use reth_testing_utils::generators::{self, random_block, BlockParams}; use tokio::sync::mpsc;   - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn exex_notifications_behind_head_canonical() -> eyre::Result<()> { let mut rng = generators::rng();   @@ -591,7 +591,7 @@ Ok(()) }   - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn exex_notifications_same_head_non_canonical() -> eyre::Result<()> { let mut rng = generators::rng();
diff --git reth/crates/exex/test-utils/src/lib.rs seismic-reth/crates/exex/test-utils/src/lib.rs index ed90edc8f37927c6890c161702acbc4453aba12b..70462b18ce95ffb21571a180fda572bc2a356316 100644 --- reth/crates/exex/test-utils/src/lib.rs +++ seismic-reth/crates/exex/test-utils/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/exex/types/src/lib.rs seismic-reth/crates/exex/types/src/lib.rs index ffed819d6ec1f2f9f5acd9b616f146c51e91eed9..69e182f312b5127ea457eb7bc6af443c421b102a 100644 --- reth/crates/exex/types/src/lib.rs +++ seismic-reth/crates/exex/types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/fs-util/src/lib.rs seismic-reth/crates/fs-util/src/lib.rs index d3195ad27fe7917286db1c6f4cd11038d4ce9631..dce5fbbee0341863473e38eefe20c23284898d9b 100644 --- reth/crates/fs-util/src/lib.rs +++ seismic-reth/crates/fs-util/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] use serde::{de::DeserializeOwned, Serialize};
diff --git reth/crates/genesis-builder/Cargo.toml seismic-reth/crates/genesis-builder/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..7ab95b78b8d9d3f50ec4a2ef5fec283f31aaebc0 --- /dev/null +++ seismic-reth/crates/genesis-builder/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "reth-genesis-builder" +version.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +exclude.workspace = true + +[dependencies] +serde = { workspace = true, features = ["derive"] } +reqwest = { workspace = true, default-features = false, features = ["blocking"] } +alloy-primitives = { workspace = true, features = ["serde"] } +serde_json = { workspace = true } +thiserror = { workspace = true } +toml = { workspace = true } +tracing = { workspace = true } + +[lints] +workspace = true
diff --git reth/crates/genesis-builder/src/artifact.rs seismic-reth/crates/genesis-builder/src/artifact.rs new file mode 100644 index 0000000000000000000000000000000000000000..a76054c06606aa02c8534ff9fe1f44a4e5d2f818 --- /dev/null +++ seismic-reth/crates/genesis-builder/src/artifact.rs @@ -0,0 +1,94 @@ +use crate::{ + error::{BuilderError, Result}, + types::ContractArtifact, +}; +use alloy_primitives::{hex, Bytes}; +use serde_json::Value; +use std::time::Duration; +use tracing::info; + +/// Default timeout for loading contract artifacts from remote +pub const DEFAULT_ARTIFACT_TIMEOUT: Duration = Duration::from_secs(30); + +/// Client for loading contract artifacts +#[derive(Debug, Clone)] +pub struct ArtifactLoader { + /// HTTP client + client: reqwest::blocking::Client, +} + +impl ArtifactLoader { + /// Create a new artifact loader with default settings + pub fn new() -> Result<Self> { + Self::with_timeout(DEFAULT_ARTIFACT_TIMEOUT) + } + + /// Create a new artifact loader with custom timeout + pub fn with_timeout(timeout: Duration) -> Result<Self> { + let client = + reqwest::blocking::Client::builder().timeout(timeout).build().map_err(|e| { + BuilderError::RemoteFetchFailed("client initialization".to_string(), e.to_string()) + })?; + + Ok(Self { client }) + } + + /// Load contract artifact from a remote URL + pub fn load_artifact(&self, url: &str) -> Result<ContractArtifact> { + info!("Fetching {}", url); + + let data = self.fetch_remote(url)?; + + let json: Value = serde_json::from_slice(&data)?; + + let deployed_bytecode = Self::extract_bytecode(&json, url)?; + + let name = Self::extract_name(&json, url); + + Ok(ContractArtifact { name, deployed_bytecode }) + } + + /// Fetch artifact from GitHub via HTTP + fn fetch_remote(&self, url: &str) -> Result<Vec<u8>> { + let response = self + .client + .get(url) + .send() + .map_err(|e| BuilderError::RemoteFetchFailed(url.to_string(), e.to_string()))?; + + let data = response + .bytes() + .map_err(|e| BuilderError::RemoteFetchFailed(url.to_string(), e.to_string()))? + .to_vec(); + + Ok(data) + } + + /// Extract bytecode from artifact JSON + fn extract_bytecode(json: &Value, url: &str) -> Result<Bytes> { + if let Some(deployed) = json.get("deployedBytecode") { + if let Some(hex) = deployed.get("object").and_then(|o| o.as_str()) { + return Self::parse_hex_bytecode(hex, url); + } + } + + Err(BuilderError::MissingBytecode(url.to_string())) + } + + /// Parse hex string into bytecode + fn parse_hex_bytecode(hex: &str, url: &str) -> Result<Bytes> { + hex::decode(hex) + .map(Bytes::from) + .map_err(|_| BuilderError::InvalidHex(format!("Invalid hex in bytecode: {}", url))) + } + + /// Extract contract name from artifact JSON or URL + fn extract_name(json: &Value, url: &str) -> String { + if let Some(name) = json.get("contractName").and_then(|n| n.as_str()) { + return name.to_string(); + } + + // Fallback to filename from URL + url.split('/').last().and_then(|s| s.strip_suffix(".json")).unwrap_or("unknown").to_string() + } +}
diff --git reth/crates/genesis-builder/src/builder.rs seismic-reth/crates/genesis-builder/src/builder.rs new file mode 100644 index 0000000000000000000000000000000000000000..74015e54eace60807aa633859c758bae82d23f88 --- /dev/null +++ seismic-reth/crates/genesis-builder/src/builder.rs @@ -0,0 +1,121 @@ +use crate::{ + artifact::ArtifactLoader, + error::{BuilderError, Result}, + types::{Genesis, GenesisAccount, Manifest}, +}; +use alloy_primitives::{hex, Address}; +use std::io::{self, Write}; +use tracing::{info, warn}; + +/// Default nonce for the genesis file +pub const DEFAULT_NONCE: &str = "0x1"; + +/// Default balance for the genesis file +pub const DEFAULT_BALANCE: &str = "0x0"; + +/// Builder for constructing genesis files with contracts +#[derive(Debug)] +pub struct GenesisBuilder { + /// Manifest containing the contracts to deploy + manifest: Manifest, + /// Genesis file to build + genesis: Genesis, + /// Loader for fetching contract artifacts + loader: ArtifactLoader, + /// Number of contracts added to the genesis file + contracts_added: usize, + /// Say "yes" to every overwrite question + yes_overwrite: bool, +} + +impl GenesisBuilder { + /// Create a new genesis builder + pub fn new(manifest: Manifest, genesis: Genesis, yes_overwrite: bool) -> Result<Self> { + let loader = ArtifactLoader::new()?; + + Ok(Self { manifest, genesis, loader, contracts_added: 0, yes_overwrite }) + } + + /// Execute the build process + pub fn build(mut self) -> Result<Genesis> { + info!( + "Building genesis with {} contracts from {}", + self.manifest.contracts.len(), + self.manifest.metadata.base_url() + ); + + for (name, config) in &self.manifest.contracts.clone() { + self.add_contract(name, config)?; + } + + info!("Added {} contracts to genesis", self.contracts_added); + Ok(self.genesis) + } + + /// Add a single contract to genesis + fn add_contract(&mut self, name: &str, config: &crate::types::ContractConfig) -> Result<()> { + let url = format!( + "{}/{}", + self.manifest.metadata.base_url().trim_end_matches('/'), + config.artifact.trim_start_matches('/') + ); + println!("Url: {}", url); + + let artifact = self.loader.load_artifact(&url)?; + + let address = parse_address(&config.address)?; + + if self.genesis.alloc.contains_key(&address) { + if !self.yes_overwrite && !overwrite_address(name, &config.address)? { + info!("Skipping {} @ {} (user declined overwrite)", name, config.address); + return Ok(()); + } + warn!("Overwriting existing contract at {}", config.address); + } + + let account = GenesisAccount { + code: Some(format!("0x{}", hex::encode(&artifact.deployed_bytecode))), + balance: config.balance.clone().unwrap_or_else(|| DEFAULT_BALANCE.to_string()), + nonce: config.nonce.clone(), + storage: config.storage.clone(), + }; + + self.genesis.alloc.insert(address, account); + self.contracts_added += 1; + + info!("Added {} @ {}", name, config.address); + + Ok(()) + } +} + +/// Parse address from hex string +fn parse_address(hex_str: &str) -> Result<Address> { + let hex_str = hex_str.strip_prefix("0x").unwrap_or(hex_str); + + let padded = if hex_str.len() < 40 { format!("{:0>40}", hex_str) } else { hex_str.to_string() }; + + let bytes = + hex::decode(&padded).map_err(|_| BuilderError::InvalidAddress(hex_str.to_string()))?; + + if bytes.len() != 20 { + return Err(BuilderError::InvalidAddress(hex_str.to_string())); + } + + Ok(Address::from_slice(&bytes)) +} + +/// Prompt the user to confirm overwriting an existing contract +fn overwrite_address(name: &str, address: &str) -> Result<bool> { + print!( + "Address collision: {} ({}) already exists in genesis. Overwrite? [y/N]: ", + name, address + ); + io::stdout().flush()?; + + let mut input = String::new(); + io::stdin().read_line(&mut input)?; + + let input = input.trim().to_lowercase(); + Ok(input == "y" || input == "yes") +}
diff --git reth/crates/genesis-builder/src/error.rs seismic-reth/crates/genesis-builder/src/error.rs new file mode 100644 index 0000000000000000000000000000000000000000..50844cd0c3465a5ca60949afb8544a41636f0251 --- /dev/null +++ seismic-reth/crates/genesis-builder/src/error.rs @@ -0,0 +1,41 @@ +use std::path::PathBuf; +use thiserror::Error; +use toml::de::Error as TomlError; + +/// Errors that can occur during genesis building +#[derive(Debug, Error)] +pub enum BuilderError { + /// Manifest not found + #[error("Manifest not found: {}", .0.display())] + ManifestNotFound(PathBuf), + /// No contracts defined in manifest + #[error("No contracts defined in manifest")] + NoContractsDefined, + /// Genesis file not found + #[error("Genesis file not found: {}", .0.display())] + GenesisNotFound(PathBuf), + /// Invalid address format + #[error("Invalid address format: {0}")] + InvalidAddress(String), + /// Invalid hex format + #[error("Invalid hex format: {0}")] + InvalidHex(String), + /// Contract bytecode missing or empty + #[error("Contract bytecode missing or empty: {0}")] + MissingBytecode(String), + /// Failed to fetch artifact from remote source + #[error("Failed to fetch artifact from {0}: {1}")] + RemoteFetchFailed(String, String), + /// IO error + #[error("IO error: {0}")] + Io(#[from] std::io::Error), + /// JSON parse error + #[error("JSON parse error: {0}")] + Json(#[from] serde_json::Error), + /// TOML parse error + #[error("TOML parse error: {0}")] + Toml(#[from] TomlError), +} + +/// Result type for genesis builder operations +pub type Result<T> = std::result::Result<T, BuilderError>;
diff --git reth/crates/genesis-builder/src/genesis.rs seismic-reth/crates/genesis-builder/src/genesis.rs new file mode 100644 index 0000000000000000000000000000000000000000..da71f52e1adc770428c553b60c527d92ac92b4f4 --- /dev/null +++ seismic-reth/crates/genesis-builder/src/genesis.rs @@ -0,0 +1,25 @@ +use crate::{ + error::{BuilderError, Result}, + types::Genesis, +}; +use std::{fs, path::Path}; + +/// Load genesis JSON file +pub fn load_genesis(path: &Path) -> Result<Genesis> { + if !path.exists() { + return Err(BuilderError::GenesisNotFound(path.to_path_buf())); + } + + let content = fs::read_to_string(path)?; + let genesis: Genesis = serde_json::from_str(&content)?; + + Ok(genesis) +} + +/// Write genesis JSON file with pretty printing +pub fn write_genesis(genesis: &Genesis, path: &Path) -> Result<()> { + let json = serde_json::to_string_pretty(genesis)?; + fs::write(path, json)?; + + Ok(()) +}
diff --git reth/crates/genesis-builder/src/lib.rs seismic-reth/crates/genesis-builder/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..b91e1664baac257e723661f41d15ccea0b294aef --- /dev/null +++ seismic-reth/crates/genesis-builder/src/lib.rs @@ -0,0 +1,14 @@ +//! Genesis builder for constructing genesis files with contracts + +/// Artifact loader for fetching contract artifacts +pub mod artifact; +/// Genesis builder for constructing genesis files +pub mod builder; +/// Error types +pub mod error; +/// Genesis file handling +pub mod genesis; +/// Manifest file handling +pub mod manifest; +/// Common types +pub mod types;
diff --git reth/crates/genesis-builder/src/manifest.rs seismic-reth/crates/genesis-builder/src/manifest.rs new file mode 100644 index 0000000000000000000000000000000000000000..0349cbe35becc530ef0b740d236373d6377c98ce --- /dev/null +++ seismic-reth/crates/genesis-builder/src/manifest.rs @@ -0,0 +1,44 @@ +use crate::{ + error::{BuilderError, Result}, + types::Manifest, +}; +use std::{fs, path::Path}; + +/// Load and parse the genesis contracts manifest from a TOML file +pub fn load_manifest(path: &Path) -> Result<Manifest> { + if !path.exists() { + return Err(BuilderError::ManifestNotFound(path.to_path_buf())); + } + + let content = fs::read_to_string(path)?; + let manifest: Manifest = toml::from_str(&content)?; + + validate_manifest(&manifest)?; + + Ok(manifest) +} + +/// Validate the addresses in the manifest +fn validate_addresses(manifest: &Manifest) -> Result<()> { + for (name, config) in &manifest.contracts { + if !config.address.starts_with("0x") { + return Err(BuilderError::InvalidAddress(format!( + "{}: address must start with 0x", + name + ))); + } + } + Ok(()) +} + +/// Validate the manifest structure +fn validate_manifest(manifest: &Manifest) -> Result<()> { + // Check if contracts exist + if manifest.contracts.is_empty() { + return Err(BuilderError::NoContractsDefined); + } + + validate_addresses(manifest)?; + + Ok(()) +}
diff --git reth/crates/genesis-builder/src/types.rs seismic-reth/crates/genesis-builder/src/types.rs new file mode 100644 index 0000000000000000000000000000000000000000..80fd4c25c3002a39399b009cbc9b882b2dc93109 --- /dev/null +++ seismic-reth/crates/genesis-builder/src/types.rs @@ -0,0 +1,89 @@ +use alloy_primitives::{Address, Bytes}; +use serde::{Deserialize, Serialize}; +use std::collections::{BTreeMap, HashMap}; + +/// Default base URL for the manifest which will be +/// used if a base URL is not provided explicitly +pub const DEFAULT_BASE_URL: &str = + "https://raw.githubusercontent.com/SeismicSystems/seismic/refs/heads/main/contracts"; + +/// Contract configuration from manifest +#[derive(Debug, Deserialize, Clone)] +pub struct ContractConfig { + /// Relative path to the artifact file + pub artifact: String, + /// Address where the contract will be deployed + pub address: String, + /// Optional balance for the contract (defaults to "0x0") + pub balance: Option<String>, + /// Optional nonce for the contract + pub nonce: Option<String>, + /// Optional storage to initialize at the contract address + #[serde(default)] + pub storage: BTreeMap<String, String>, +} + +/// Full manifest structure +#[derive(Debug, Deserialize)] +pub struct Manifest { + /// Metadata in `manifest.toml` + pub metadata: ManifestMetadata, + /// Contracts to deploy + pub contracts: HashMap<String, ContractConfig>, +} + +#[derive(Debug, Deserialize)] +/// Metadata in `manifest.toml` +pub struct ManifestMetadata { + /// Version of the manifest + pub version: String, + /// Description of the manifest + pub description: Option<String>, + /// Base GitHub URL for all artifacts + /// If not provided, the default base URL will be used + pub base_url: Option<String>, +} + +impl ManifestMetadata { + /// Get the base URL for the manifest + pub fn base_url(&self) -> &str { + self.base_url.as_deref().unwrap_or(DEFAULT_BASE_URL) + } +} + +/// Contract artifact from JSON +#[derive(Debug)] +pub struct ContractArtifact { + /// Name of the contract + pub name: String, + /// Bytecode of the contract + pub deployed_bytecode: Bytes, +} + +/// Genesis file structure +#[derive(Debug, Serialize, Deserialize)] +pub struct Genesis { + /// Configuration of the genesis file + pub config: serde_json::Value, + /// Allocations of the genesis file + pub alloc: BTreeMap<Address, GenesisAccount>, + /// Other fields of the genesis file + #[serde(flatten)] + pub other: BTreeMap<String, serde_json::Value>, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +/// Account in the genesis file +pub struct GenesisAccount { + /// Balance of the account + pub balance: String, + /// Code of the account + #[serde(skip_serializing_if = "Option::is_none")] + pub code: Option<String>, + /// Nonce of the account + #[serde(skip_serializing_if = "Option::is_none")] + pub nonce: Option<String>, + /// Storage of the account + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] + pub storage: BTreeMap<String, String>, +}
diff --git reth/crates/metrics/src/lib.rs seismic-reth/crates/metrics/src/lib.rs index a5411b617c9cbfbf80f97355b5949e651dcbb1bb..486831af9d370723783fa5d42a3067a35b665ab1 100644 --- reth/crates/metrics/src/lib.rs +++ seismic-reth/crates/metrics/src/lib.rs @@ -8,7 +8,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/banlist/src/lib.rs seismic-reth/crates/net/banlist/src/lib.rs index 29cf8eb76a4a54cbd4a1acaaee89a90622148bcd..48afec4e77d3a622e3c271271fbf4e35ddaad64a 100644 --- reth/crates/net/banlist/src/lib.rs +++ seismic-reth/crates/net/banlist/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/discv4/src/lib.rs seismic-reth/crates/net/discv4/src/lib.rs index 976ade1728fff287149c8bdd792ce5580c721690..2ba897262d0f3ac07e19de9ed4e83e340d6905bb 100644 --- reth/crates/net/discv4/src/lib.rs +++ seismic-reth/crates/net/discv4/src/lib.rs @@ -19,7 +19,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/discv5/Cargo.toml seismic-reth/crates/net/discv5/Cargo.toml index 7c3dfa20095634674ee5c8e72d80beb54bd8e85c..bb843844e1888df49d38bd0f5cf8999553348269 100644 --- reth/crates/net/discv5/Cargo.toml +++ seismic-reth/crates/net/discv5/Cargo.toml @@ -16,6 +16,7 @@ # reth reth-chainspec.workspace = true reth-ethereum-forks.workspace = true reth-metrics.workspace = true +reth-net-nat.workspace = true reth-network-peers = { workspace = true, features = ["secp256k1"] }   # ethereum
diff --git reth/crates/net/discv5/src/config.rs seismic-reth/crates/net/discv5/src/config.rs index ef89e72da57d93026fe04f3113d834cd2e26b0a1..2252c31dae45402efc76dbc874fd288b29972cbd 100644 --- reth/crates/net/discv5/src/config.rs +++ seismic-reth/crates/net/discv5/src/config.rs @@ -13,6 +13,7 @@ multiaddr::{Multiaddr, Protocol}, ListenConfig, }; use reth_ethereum_forks::{EnrForkIdEntry, ForkId}; +use reth_net_nat::NatResolver; use reth_network_peers::NodeRecord; use tracing::debug;   @@ -85,6 +86,8 @@ bootstrap_lookup_countdown: Option<u64>, /// Custom filter rules to apply to a discovered peer in order to determine if it should be /// passed up to rlpx or dropped. discovered_peer_filter: Option<MustNotIncludeKeys>, + /// NAT resolver for determining external IP to advertise in the ENR. + nat: NatResolver, }   impl ConfigBuilder { @@ -100,6 +103,7 @@ lookup_interval, bootstrap_lookup_interval, bootstrap_lookup_countdown, discovered_peer_filter, + nat, } = discv5_config;   Self { @@ -112,6 +116,7 @@ lookup_interval: Some(lookup_interval), bootstrap_lookup_interval: Some(bootstrap_lookup_interval), bootstrap_lookup_countdown: Some(bootstrap_lookup_countdown), discovered_peer_filter: Some(discovered_peer_filter), + nat, } }   @@ -214,6 +219,12 @@ self.discovered_peer_filter = Some(filter); self }   + /// Sets the NAT resolver for determining the external IP to advertise in the ENR. + pub fn nat(mut self, nat: NatResolver) -> Self { + self.nat = nat; + self + } + /// Returns a new [`Config`]. pub fn build(self) -> Config { let Self { @@ -226,11 +237,15 @@ lookup_interval, bootstrap_lookup_interval, bootstrap_lookup_countdown, discovered_peer_filter, + nat, } = self;   let mut discv5_config = discv5_config.unwrap_or_else(|| { discv5::ConfigBuilder::new(DEFAULT_DISCOVERY_V5_LISTEN_CONFIG).build() }); + + // Always set the table filter to only allow seismic nodes into kbuckets + discv5_config.table_filter = |enr| enr.get_raw_rlp(NetworkStackId::SEISMIC).is_some();   discv5_config.listen_config = amend_listen_config_wrt_rlpx(&discv5_config.listen_config, tcp_socket.ip()); @@ -256,6 +271,7 @@ lookup_interval, bootstrap_lookup_interval, bootstrap_lookup_countdown, discovered_peer_filter, + nat, } } } @@ -289,6 +305,8 @@ pub(super) bootstrap_lookup_countdown: u64, /// Custom filter rules to apply to a discovered peer in order to determine if it should be /// passed up to rlpx or dropped. pub(super) discovered_peer_filter: MustNotIncludeKeys, + /// NAT resolver for determining external IP to advertise in the ENR. + pub(super) nat: NatResolver, }   impl Config { @@ -305,6 +323,7 @@ lookup_interval: None, bootstrap_lookup_interval: None, bootstrap_lookup_countdown: None, discovered_peer_filter: None, + nat: NatResolver::None, } }
diff --git reth/crates/net/discv5/src/lib.rs seismic-reth/crates/net/discv5/src/lib.rs index e4e93bce7870755f6f5866cf7d98b43de8ae6b38..d14e3492351b9647469573804f3851d6a039e049 100644 --- reth/crates/net/discv5/src/lib.rs +++ seismic-reth/crates/net/discv5/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -164,9 +164,11 @@ sk: &SecretKey, discv5_config: Config, ) -> Result<(Self, mpsc::Receiver<discv5::Event>, NodeRecord), Error> { // - // 1. make local enr from listen config + // 1. resolve external IP via NAT and make local enr from listen config // - let (enr, bc_enr, fork_key, rlpx_ip_mode) = build_local_enr(sk, &discv5_config); + let external_ip = discv5_config.nat.external_addr().await; + let (enr, bc_enr, fork_key, rlpx_ip_mode) = + build_local_enr(sk, &discv5_config, external_ip);   trace!(target: "net::discv5", ?enr, @@ -320,10 +322,7 @@ return None }   - // todo: extend for all network stacks in reth-network rlpx logic - let fork_id = (self.fork_key == Some(NetworkStackId::ETH)) - .then(|| self.get_fork_id(enr).ok()) - .flatten(); + let fork_id = self.fork_key.and_then(|_| self.get_fork_id(enr).ok());   trace!(target: "net::discv5", ?fork_id, @@ -439,6 +438,7 @@ /// Builds the local ENR with the supplied key. pub fn build_local_enr( sk: &SecretKey, config: &Config, + external_ip: Option<IpAddr>, ) -> (Enr<SecretKey>, NodeRecord, Option<&'static [u8]>, IpMode) { let mut builder = discv5::enr::Enr::builder();   @@ -446,7 +446,14 @@ let Config { discv5_config, fork, tcp_socket, other_enr_kv_pairs, .. } = config;   let socket = match discv5_config.listen_config { ListenConfig::Ipv4 { ip, port } => { - if ip != Ipv4Addr::UNSPECIFIED { + let enr_ip = if ip != Ipv4Addr::UNSPECIFIED { + Some(ip) + } else if let Some(IpAddr::V4(ext)) = external_ip { + Some(ext) + } else { + None + }; + if let Some(ip) = enr_ip { builder.ip4(ip); } builder.udp4(port); @@ -669,6 +676,7 @@ use super::*; use ::enr::{CombinedKey, EnrKey}; use rand_08::thread_rng; use reth_chainspec::MAINNET; + use reth_ethereum_forks::{ForkHash, ForkId}; use tracing::trace;   fn discv5_noop() -> Discv5 { @@ -700,6 +708,7 @@ let discv5_listen_config = ListenConfig::from(discv5_addr); let discv5_config = Config::builder(rlpx_addr) .discv5_config(discv5::ConfigBuilder::new(discv5_listen_config).build()) + .fork(NetworkStackId::SEISMIC, ForkId { hash: ForkHash([0; 4]), next: 0 }) .build();   Discv5::start(&secret_key, discv5_config).await.expect("should build discv5") @@ -890,7 +899,7 @@ .fork(NetworkStackId::ETH, fork_id) .build();   let sk = SecretKey::new(&mut thread_rng()); - let (enr, _, _, _) = build_local_enr(&sk, &config); + let (enr, _, _, _) = build_local_enr(&sk, &config, None);   let decoded_fork_id = enr .get_decodable::<EnrForkIdEntry>(NetworkStackId::ETH)
diff --git reth/crates/net/discv5/src/network_stack_id.rs seismic-reth/crates/net/discv5/src/network_stack_id.rs index a7b6944f355ab10dfee6b92ed582619f635ac14e..c3ca8789f4f5653e60f2d64e5c73360af6cb72f0 100644 --- reth/crates/net/discv5/src/network_stack_id.rs +++ seismic-reth/crates/net/discv5/src/network_stack_id.rs @@ -20,10 +20,15 @@ /// ENR fork ID kv-pair key, for an Optimism CL node. pub const OPSTACK: &'static [u8] = b"opstack";   + /// ENR fork ID kv-pair key, for a Seismic EL node. + pub const SEISMIC: &'static [u8] = b"seismic"; + /// Returns the [`NetworkStackId`] that matches the given chain spec. pub fn id(chain: impl EthChainSpec) -> Option<&'static [u8]> { if chain.is_optimism() { return Some(Self::OPEL) + } else if chain.is_seismic() { + return Some(Self::SEISMIC) } else if chain.is_ethereum() { return Some(Self::ETH) }
diff --git reth/crates/net/dns/src/lib.rs seismic-reth/crates/net/dns/src/lib.rs index 14a78ab7cc632433656776c960c4d0acaab6a1d3..a33a824e6a35b9640dfda1bb7578e968e883e347 100644 --- reth/crates/net/dns/src/lib.rs +++ seismic-reth/crates/net/dns/src/lib.rs @@ -8,7 +8,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/downloaders/src/lib.rs seismic-reth/crates/net/downloaders/src/lib.rs index 8d50b6fbc03094f34a4029adfbd35a5198e049cc..8e234d8a6b29bcad8c9c51dda20ab1af7118f7cc 100644 --- reth/crates/net/downloaders/src/lib.rs +++ seismic-reth/crates/net/downloaders/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/ecies/src/lib.rs seismic-reth/crates/net/ecies/src/lib.rs index b2dcdac6709a0e76dbcad816c6fba95ad86f8e3c..c2cfb0110d1daf8195601705d4ab0a411e99bd9c 100644 --- reth/crates/net/ecies/src/lib.rs +++ seismic-reth/crates/net/ecies/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/eth-wire-types/src/lib.rs seismic-reth/crates/net/eth-wire-types/src/lib.rs index c0a7dca4051e4d87caf87b3718c83aa539583ad4..f5a162e18dec3e3ca772855d21bb7803914b1632 100644 --- reth/crates/net/eth-wire-types/src/lib.rs +++ seismic-reth/crates/net/eth-wire-types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/eth-wire-types/src/message.rs seismic-reth/crates/net/eth-wire-types/src/message.rs index 5f36115204b70f7eb3a9b57cd901971f0eefe2ff..8c87b5eb5d2eb86584773ed05fb1b364b21218c5 100644 --- reth/crates/net/eth-wire-types/src/message.rs +++ seismic-reth/crates/net/eth-wire-types/src/message.rs @@ -100,16 +100,12 @@ EthMessageID::PooledTransactions => { EthMessage::PooledTransactions(RequestPair::decode(buf)?) } EthMessageID::GetNodeData => { - if version >= EthVersion::Eth67 { - return Err(MessageError::Invalid(version, EthMessageID::GetNodeData)) - } - EthMessage::GetNodeData(RequestPair::decode(buf)?) + // GetNodeData is disabled in all versions to prevent privacy leaks + return Err(MessageError::Invalid(version, EthMessageID::GetNodeData)) } EthMessageID::NodeData => { - if version >= EthVersion::Eth67 { - return Err(MessageError::Invalid(version, EthMessageID::GetNodeData)) - } - EthMessage::NodeData(RequestPair::decode(buf)?) + // NodeData is disabled in all versions to prevent privacy leaks + return Err(MessageError::Invalid(version, EthMessageID::NodeData)) } EthMessageID::GetReceipts => EthMessage::GetReceipts(RequestPair::decode(buf)?), EthMessageID::Receipts => { @@ -684,6 +680,37 @@ let buf = encode(ProtocolMessage { message_type: EthMessageID::NodeData, message: node_data }); let msg = ProtocolMessage::<EthNetworkPrimitives>::decode_message( crate::EthVersion::Eth67, + &mut &buf[..], + ); + assert!(matches!(msg, Err(MessageError::Invalid(..)))); + } + + #[test] + fn test_get_node_data_disabled_for_privacy() { + // Test that GetNodeData is rejected in ETH66 to prevent privacy leaks + let get_node_data = EthMessage::<EthNetworkPrimitives>::GetNodeData(RequestPair { + request_id: 1337, + message: GetNodeData(vec![]), + }); + let buf = encode(ProtocolMessage { + message_type: EthMessageID::GetNodeData, + message: get_node_data, + }); + let msg = ProtocolMessage::<EthNetworkPrimitives>::decode_message( + crate::EthVersion::Eth66, + &mut &buf[..], + ); + assert!(matches!(msg, Err(MessageError::Invalid(..)))); + + // Test that NodeData is also rejected in ETH66 + let node_data = EthMessage::<EthNetworkPrimitives>::NodeData(RequestPair { + request_id: 1337, + message: NodeData(vec![]), + }); + let buf = + encode(ProtocolMessage { message_type: EthMessageID::NodeData, message: node_data }); + let msg = ProtocolMessage::<EthNetworkPrimitives>::decode_message( + crate::EthVersion::Eth66, &mut &buf[..], ); assert!(matches!(msg, Err(MessageError::Invalid(..))));
diff --git reth/crates/net/eth-wire-types/src/status.rs seismic-reth/crates/net/eth-wire-types/src/status.rs index db363695c3215239f30f321b7d2a94557f040ac6..055d819dc43c1275636fd41df79b7ab8a00ecc6d 100644 --- reth/crates/net/eth-wire-types/src/status.rs +++ seismic-reth/crates/net/eth-wire-types/src/status.rs @@ -723,7 +723,8 @@ (EthereumHardfork::London, ForkCondition::Block(8)), (EthereumHardfork::Shanghai, ForkCondition::Timestamp(13)), ];   - let mut chainspec = ChainSpec::builder().genesis(genesis).chain(Chain::from_id(1337)); + let mut chainspec = + ChainSpec::builder().genesis(genesis.into()).chain(Chain::from_id(1337));   for (fork, condition) in &hardforks { chainspec = chainspec.with_fork(*fork, *condition);
diff --git reth/crates/net/eth-wire/src/lib.rs seismic-reth/crates/net/eth-wire/src/lib.rs index a2cb35ae7fd7934940b8bbea2e02761954cb2689..3799af7b1581756658393e751c4752ed48fb9425 100644 --- reth/crates/net/eth-wire/src/lib.rs +++ seismic-reth/crates/net/eth-wire/src/lib.rs @@ -8,7 +8,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/nat/src/lib.rs seismic-reth/crates/net/nat/src/lib.rs index c7466b44012c62d501e3a18319c53cf72b323fce..b787ed876dfaf397dbb88cf5c9a091508ab4ef0f 100644 --- reth/crates/net/nat/src/lib.rs +++ seismic-reth/crates/net/nat/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -25,7 +25,7 @@ str::FromStr, task::{Context, Poll}, time::Duration, }; -use tracing::{debug, error}; +use tracing::debug;   use crate::net_if::resolve_net_if_ip; #[cfg(feature = "serde")]
diff --git reth/crates/net/network-api/src/lib.rs seismic-reth/crates/net/network-api/src/lib.rs index 4c71f168608d8a9a118b76040e4a3481ad7505c4..7fc9fef43100eedf946e63ea104b32f72c6c723e 100644 --- reth/crates/net/network-api/src/lib.rs +++ seismic-reth/crates/net/network-api/src/lib.rs @@ -9,7 +9,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/network-types/src/lib.rs seismic-reth/crates/net/network-types/src/lib.rs index 8bbf8182d1d7437674a93d3562dd7fd28f775530..953c4b86760787beea154a0527903343276f873b 100644 --- reth/crates/net/network-types/src/lib.rs +++ seismic-reth/crates/net/network-types/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/network/src/config.rs seismic-reth/crates/net/network/src/config.rs index 0e7fe614d16875adb5f39453d651029e7ef54058..cb011a3954267850e53f7b4d6b6e4a183dec4850 100644 --- reth/crates/net/network/src/config.rs +++ seismic-reth/crates/net/network/src/config.rs @@ -762,23 +762,32 @@ }   #[test] fn test_discv5_fork_id_default() { - const GENESIS_TIME: u64 = 151_515; + const GENESIS_TIME: u64 = 151_515_000; + // ForkCondition::Timestamp stores seconds (upstream alloy-hardforks convention), + // while header/head timestamps store ms (Seismic uses 300-400ms block times). + // This unit mismatch is the source of the `timestamp-in-seconds` feature flag + // and scattered `/ 1000` conversions across the codebase. + // TODO(samlaf): think we could convert ForkCondition to also use ms, and then only keep the + // feature-flag for ef-tests. + const GENESIS_TIME_SECONDS: u64 = 151_515;   let genesis = Genesis::default().with_timestamp(GENESIS_TIME);   - let active_fork = (EthereumHardfork::Shanghai, ForkCondition::Timestamp(GENESIS_TIME)); - let future_fork = (EthereumHardfork::Cancun, ForkCondition::Timestamp(GENESIS_TIME + 1)); + let active_fork = + (EthereumHardfork::Shanghai, ForkCondition::Timestamp(GENESIS_TIME_SECONDS)); + let future_fork = + (EthereumHardfork::Cancun, ForkCondition::Timestamp(GENESIS_TIME_SECONDS + 1));   let chain_spec = ChainSpecBuilder::default() .chain(Chain::dev()) - .genesis(genesis) + .genesis(genesis.into()) .with_fork(active_fork.0, active_fork.1) .with_fork(future_fork.0, future_fork.1) .build();   // get the fork id to advertise on discv5 let genesis_fork_hash = ForkHash::from(chain_spec.genesis_hash()); - let fork_id = ForkId { hash: genesis_fork_hash, next: GENESIS_TIME + 1 }; + let fork_id = ForkId { hash: genesis_fork_hash, next: GENESIS_TIME_SECONDS + 1 }; // check the fork id is set to active fork and _not_ yet future fork assert_eq!( fork_id, @@ -804,6 +813,7 @@ let (local_enr, _, _, _) = build_local_enr( &config.secret_key, &config.discovery_v5_config.expect("should build config"), + None, );   // peers on the odyssey network will check discovered enrs for the 'odyssey' key and
diff --git reth/crates/net/network/src/discovery.rs seismic-reth/crates/net/network/src/discovery.rs index 5809380aa8af1a4de0217ed9044c4d2557b0960a..92748c1d55850cc1c96d32fb3ddc71f574516f89 100644 --- reth/crates/net/network/src/discovery.rs +++ seismic-reth/crates/net/network/src/discovery.rs @@ -359,7 +359,8 @@ .unwrap(); }   use reth_discv4::Discv4ConfigBuilder; - use reth_discv5::{enr::EnrCombinedKeyWrapper, enr_to_discv4_id}; + use reth_discv5::{enr::EnrCombinedKeyWrapper, enr_to_discv4_id, NetworkStackId}; + use reth_ethereum_forks::{ForkHash, ForkId}; use tracing::trace;   async fn start_discovery_node(udp_port_discv4: u16, udp_port_discv5: u16) -> Discovery { @@ -374,6 +375,7 @@ let discv5_listen_config = discv5::ListenConfig::from(discv5_addr); let discv5_config = reth_discv5::Config::builder(discv5_addr) .discv5_config(discv5::ConfigBuilder::new(discv5_listen_config).build()) + .fork(NetworkStackId::SEISMIC, ForkId { hash: ForkHash([0; 4]), next: 0 }) .build();   Discovery::new(
diff --git reth/crates/net/network/src/lib.rs seismic-reth/crates/net/network/src/lib.rs index a6de95512f84725d03255372170d43bf80530f44..b3763c3194f7c8e3da37051de1c28241e166bda4 100644 --- reth/crates/net/network/src/lib.rs +++ seismic-reth/crates/net/network/src/lib.rs @@ -111,7 +111,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![allow(unreachable_pub)] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/net/network/src/metrics.rs seismic-reth/crates/net/network/src/metrics.rs index 241a7788691a8124f7526024eb7d0ef78f53ba2d..7ad63775ca9aa12435a28ec21603003cf975398b 100644 --- reth/crates/net/network/src/metrics.rs +++ seismic-reth/crates/net/network/src/metrics.rs @@ -349,6 +349,9 @@ pub(crate) eip4844: Histogram,   /// Histogram for tracking frequency of EIP-7702 transaction type pub(crate) eip7702: Histogram, + + /// Histogram for tracking frequency of seismic transaction type + pub(crate) seismic: Histogram, }   /// Counts the number of transactions by their type in a block or collection. @@ -371,6 +374,9 @@ pub(crate) eip4844: usize,   /// Count of transactions conforming to EIP-7702 (Restricted Storage Windows). pub(crate) eip7702: usize, + + /// Count of seismic transactions conforming + pub(crate) seismic: usize, }   impl TxTypesCounter { @@ -404,5 +410,6 @@ self.eip2930.record(tx_types_counter.eip2930 as f64); self.eip1559.record(tx_types_counter.eip1559 as f64); self.eip4844.record(tx_types_counter.eip4844 as f64); self.eip7702.record(tx_types_counter.eip7702 as f64); + self.seismic.record(tx_types_counter.seismic as f64); } }
diff --git reth/crates/net/network/src/session/active.rs seismic-reth/crates/net/network/src/session/active.rs index 4a70289bfd6ab95082450bfe914a7ce338ce638f..82c54f9a4b2b5cb91ac75c0b2610c2bf763a0f9b 100644 --- reth/crates/net/network/src/session/active.rs +++ seismic-reth/crates/net/network/src/session/active.rs @@ -261,10 +261,22 @@ EthMessage::PooledTransactions(resp) => { on_response!(resp, GetPooledTransactions) } EthMessage::GetNodeData(req) => { - on_request!(req, NodeData, GetNodeData) + // GetNodeData is disabled to prevent privacy leaks - treat as bad message + return OnIncomingMessageOutcome::BadMessage { + error: EthStreamError::InvalidMessage(MessageError::Other( + "GetNodeData message is disabled to prevent privacy leaks".to_string(), + )), + message: EthMessage::GetNodeData(req), + } } EthMessage::NodeData(resp) => { - on_response!(resp, GetNodeData) + // NodeData is disabled to prevent privacy leaks - treat as bad message + return OnIncomingMessageOutcome::BadMessage { + error: EthStreamError::InvalidMessage(MessageError::Other( + "NodeData message is disabled to prevent privacy leaks".to_string(), + )), + message: EthMessage::NodeData(resp), + } } EthMessage::GetReceipts(req) => { if self.conn.version() >= EthVersion::Eth69 {
diff --git reth/crates/net/p2p/src/lib.rs seismic-reth/crates/net/p2p/src/lib.rs index dead0f43bae60d33c371229eda4521786db3e717..b971fe001d526c8fff68dbf1ffdb8b29bf3390f7 100644 --- reth/crates/net/p2p/src/lib.rs +++ seismic-reth/crates/net/p2p/src/lib.rs @@ -6,7 +6,7 @@ //! - `test-utils`: Export utilities for testing #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/net/peers/src/lib.rs seismic-reth/crates/net/peers/src/lib.rs index bfca16a82fc17cd6ee12794d093f243f0b6e6c2b..ad3dea56d91385de4f8da3113123574defe6949f 100644 --- reth/crates/net/peers/src/lib.rs +++ seismic-reth/crates/net/peers/src/lib.rs @@ -48,7 +48,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/node/api/Cargo.toml seismic-reth/crates/node/api/Cargo.toml index 7bd6196318df7f4bc76128d8b4c10b053c5673b1..2747928b0c6b436f827dbaced236d632856a920f 100644 --- reth/crates/node/api/Cargo.toml +++ seismic-reth/crates/node/api/Cargo.toml @@ -31,3 +31,6 @@ alloy-rpc-types-engine.workspace = true   eyre.workspace = true + +[features] +timestamp-in-seconds = ["reth-db-api/timestamp-in-seconds"]
diff --git reth/crates/node/api/src/lib.rs seismic-reth/crates/node/api/src/lib.rs index b7cd087be3dffd3f0554524ee52c8cbf16c700e2..d052113e69363bd1e3e91085847142c7b479bc14 100644 --- reth/crates/node/api/src/lib.rs +++ seismic-reth/crates/node/api/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/node/builder/Cargo.toml seismic-reth/crates/node/builder/Cargo.toml index f0c62f3252a23bf46aac2d857b141448aaf63c15..5e16088707c3dc76630dae19ade082fe9f7e2c63 100644 --- reth/crates/node/builder/Cargo.toml +++ seismic-reth/crates/node/builder/Cargo.toml @@ -50,6 +50,7 @@ reth-rpc-engine-api.workspace = true reth-rpc-eth-types.workspace = true reth-rpc-layer.workspace = true reth-stages.workspace = true +reth-storage-api.workspace = true reth-static-file.workspace = true reth-tasks.workspace = true reth-tokio-util.workspace = true @@ -95,6 +96,7 @@ reth-evm-ethereum = { workspace = true, features = ["test-utils"] }   [features] default = [] +timestamp-in-seconds = ["reth-engine-local/timestamp-in-seconds"] js-tracer = ["reth-rpc/js-tracer"] test-utils = [ "dep:reth-db",
diff --git reth/crates/node/builder/src/builder/mod.rs seismic-reth/crates/node/builder/src/builder/mod.rs index 118ead96ee9664e44ed2704c81c52fafc22ee320..b79eb198435b2a21b81863a8d993acc5fcca2efc 100644 --- reth/crates/node/builder/src/builder/mod.rs +++ seismic-reth/crates/node/builder/src/builder/mod.rs @@ -731,7 +731,7 @@ pub const fn config(&self) -> &NodeConfig<<Node::Types as NodeTypes>::ChainSpec> { &self.config_container.config }   - /// Returns the loaded reh.toml config. + /// Returns the loaded reth.toml config. pub const fn reth_config(&self) -> &reth_config::Config { &self.config_container.toml_config }
diff --git reth/crates/node/builder/src/launch/engine.rs seismic-reth/crates/node/builder/src/launch/engine.rs index 9c2576c8a2c2a4f645e7a91f061cca639f022594..70891c21c78d2575bc995decb3926c7438296016 100644 --- reth/crates/node/builder/src/launch/engine.rs +++ seismic-reth/crates/node/builder/src/launch/engine.rs @@ -230,6 +230,7 @@ engine_validator, engine_tree_config, ctx.sync_metrics_tx(), ctx.components().evm_config().clone(), + ctx.data_dir().clone(), );   info!(target: "reth::cli", "Consensus engine initialized"); @@ -290,7 +291,7 @@ } } event = engine_service.next() => { let Some(event) = event else { break }; - debug!(target: "reth::cli", "Event: {event}"); + // debug!(target: "reth::cli", "ChainEvent: {event}"); match event { ChainEvent::BackfillSyncFinished => { if terminate_after_backfill {
diff --git reth/crates/node/builder/src/lib.rs seismic-reth/crates/node/builder/src/lib.rs index b29e2c09dc0ba0a6304d45a67d6f3d6f158150a8..886f21382d4eebfff4a9b41722d181e0b42e2dc2 100644 --- reth/crates/node/builder/src/lib.rs +++ seismic-reth/crates/node/builder/src/lib.rs @@ -6,7 +6,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/node/builder/src/rpc.rs seismic-reth/crates/node/builder/src/rpc.rs index 70adcc83d6934c6216c391f80d7783b353ee9930..799469e4678b0bca4d684c4f4efb07b32d93562f 100644 --- reth/crates/node/builder/src/rpc.rs +++ seismic-reth/crates/node/builder/src/rpc.rs @@ -24,20 +24,23 @@ version::{version_metadata, CLIENT_CODE}, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadStore}; use reth_rpc::eth::{core::EthRpcConverterFor, EthApiTypes, FullEthApiServer}; -use reth_rpc_api::{eth::helpers::AddDevSigners, IntoEngineApiRpcModule}; +use reth_rpc_api::{eth::helpers::AddDevSigners, IntoEngineApiRpcModule, OpsApiServer}; use reth_rpc_builder::{ auth::{AuthRpcModule, AuthServerHandle}, + body_auth::{BodyAuthRpcModule, BodyAuthServerConfig, BodyAuthServerHandle}, config::RethRpcServerConfig, RpcModuleBuilder, RpcRegistryInner, RpcServerConfig, RpcServerHandle, TransportRpcModules, }; use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi}; use reth_rpc_eth_types::{cache::cache_new_blocks_task, EthConfig, EthStateCache}; +use reth_rpc_layer::{SignatureAuthConfig, Whitelist}; use reth_tokio_util::EventSender; use reth_tracing::tracing::{debug, info}; use std::{ fmt::{self, Debug}, future::Future, ops::{Deref, DerefMut}, + sync::Arc, };   /// Contains the handles to the spawned RPC servers. @@ -49,6 +52,8 @@ /// The regular RPC server handle to all configured transports. pub rpc: RpcServerHandle, /// The handle to the auth server (engine API) pub auth: AuthServerHandle, + /// The handle to the ops threshold-auth server, if enabled. + pub ops: Option<reth_rpc_builder::body_auth::BodyAuthServerHandle>, }   /// Contains hooks that are called during the rpc setup. @@ -471,6 +476,7 @@ registry: RpcRegistry<Node, EthApi>, on_rpc_started: Box<dyn OnRpcStarted<Node, EthApi>>, engine_events: EventSender<ConsensusEngineEvent<<Node::Types as NodeTypes>::Primitives>>, engine_handle: ConsensusEngineHandle<<Node::Types as NodeTypes>::Payload>, + ops_whitelist: Option<Whitelist>, }   /// Node add-ons containing RPC server configuration, with customizable eth API handler. @@ -508,6 +514,8 @@ /// See [`RpcAddOns::with_rpc_middleware`] for more details. rpc_middleware: RpcMiddleware, /// Optional custom tokio runtime for the RPC server. tokio_runtime: Option<tokio::runtime::Handle>, + /// Pre-created ops whitelist shared with the eth API for sentinel tx interception. + pub ops_whitelist: Option<Whitelist>, }   impl<Node, EthB, PVB, EB, EVB, RpcMiddleware> Debug @@ -552,6 +560,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime: None, + ops_whitelist: None, } }   @@ -567,6 +576,7 @@ payload_validator_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, .. } = self; RpcAddOns { @@ -577,6 +587,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, } }   @@ -592,6 +603,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, .. } = self; RpcAddOns { @@ -602,6 +614,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, } }   @@ -617,6 +630,7 @@ payload_validator_builder, engine_api_builder, rpc_middleware, tokio_runtime, + ops_whitelist, .. } = self; RpcAddOns { @@ -627,6 +641,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, } }   @@ -679,6 +694,7 @@ payload_validator_builder, engine_api_builder, engine_validator_builder, tokio_runtime, + ops_whitelist, .. } = self; RpcAddOns { @@ -689,6 +705,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, } }   @@ -703,6 +720,7 @@ payload_validator_builder, engine_validator_builder, engine_api_builder, rpc_middleware, + ops_whitelist, .. } = self; Self { @@ -713,6 +731,7 @@ engine_validator_builder, engine_api_builder, rpc_middleware, tokio_runtime, + ops_whitelist, } }   @@ -729,6 +748,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, } = self; let rpc_middleware = Stack::new(rpc_middleware, layer); RpcAddOns { @@ -739,6 +759,7 @@ engine_api_builder, engine_validator_builder, rpc_middleware, tokio_runtime, + ops_whitelist, } }   @@ -827,6 +848,7 @@ mut registry, on_rpc_started, engine_events, engine_handle, + ops_whitelist: _, } = setup_ctx;   let server_config = config @@ -836,8 +858,11 @@ .set_rpc_middleware(rpc_middleware) .with_tokio_runtime(tokio_runtime); let rpc_server_handle = Self::launch_rpc_server_internal(server_config, &modules).await?;   - let handles = - RethRpcServerHandles { rpc: rpc_server_handle.clone(), auth: AuthServerHandle::noop() }; + let handles = RethRpcServerHandles { + rpc: rpc_server_handle.clone(), + auth: AuthServerHandle::noop(), + ops: None, + }; Self::finalize_rpc_setup( &mut registry, &mut modules, @@ -898,6 +923,7 @@ mut registry, on_rpc_started, engine_events, engine_handle, + ops_whitelist, } = setup_ctx;   let server_config = config @@ -921,7 +947,18 @@ .await?; (rpc, auth) };   - let handles = RethRpcServerHandles { rpc, auth }; + // Launch the ops signature-auth server if enabled. + let chain_id = node.provider().chain_spec().chain().id(); + let ops = Self::maybe_launch_ops_server( + config, + node.provider().clone(), + Box::new(node.task_executor().clone()), + chain_id, + ops_whitelist, + ) + .await?; + + let handles = RethRpcServerHandles { rpc, auth, ops };   Self::finalize_rpc_setup( &mut registry, @@ -950,7 +987,7 @@ ) -> eyre::Result<RpcSetupContext<'a, N, EthB::EthApi>> where F: FnOnce(RpcModuleContainer<'_, N, EthB::EthApi>) -> eyre::Result<()>, { - let Self { eth_api_builder, engine_api_builder, hooks, .. } = self; + let Self { eth_api_builder, engine_api_builder, hooks, ops_whitelist, .. } = self;   let engine_api = engine_api_builder.build_engine_api(&ctx).await?; let AddOnsContext { node, config, beacon_engine_handle, jwt_secret, engine_events } = ctx; @@ -973,7 +1010,13 @@ }), );   let eth_config = config.rpc.eth_config().max_batch_size(config.txpool.max_batch_size()); - let ctx = EthApiCtx { components: &node, config: eth_config, cache }; + let ops_whitelist = ops_whitelist.or_else(|| config.rpc.ops_enable.then(Whitelist::new)); + let ctx = EthApiCtx { + components: &node, + config: eth_config, + cache, + ops_whitelist: ops_whitelist.clone(), + }; let eth_api = eth_api_builder.build_eth_api(ctx).await?;   let auth_config = config.rpc.auth_server_config(jwt_secret)?; @@ -1022,6 +1065,7 @@ registry, on_rpc_started, engine_events, engine_handle: beacon_engine_handle, + ops_whitelist, }) }   @@ -1066,6 +1110,75 @@ } }) }   + /// Helper to launch the ops signature-auth server if enabled. + async fn maybe_launch_ops_server<P>( + config: &NodeConfig<<N::Types as NodeTypes>::ChainSpec>, + provider: P, + task_spawner: Box<dyn reth_tasks::TaskSpawner>, + chain_id: u64, + whitelist: Option<Whitelist>, + ) -> eyre::Result<Option<BodyAuthServerHandle>> + where + P: reth_storage_api::StateProviderFactory + reth_storage_api::BlockIdReader + 'static, + { + use reth_rpc_layer::{OPS_AUTH_CONTRACT, OPS_AUTH_SLOT}; + + if !config.rpc.ops_enable { + return Ok(None); + } + + let provider = Arc::new(provider); + + // Read governance address for startup validation and logging. + let governance_address = { + let state = provider.latest().map_err(|e| { + eyre::eyre!("failed to read latest state for ops governance validation: {e}") + })?; + let value = state + .storage(OPS_AUTH_CONTRACT, OPS_AUTH_SLOT) + .map_err(|e| eyre::eyre!("failed to read ops governance slot: {e}"))? + .ok_or_else(|| eyre::eyre!("ops governance slot is unset"))?; + let bytes = value.value.to_be_bytes::<32>(); + let address = alloy_primitives::Address::from_slice(&bytes[12..]); + if address.is_zero() { + return Err(eyre::eyre!("ops governance address resolved to zero address")); + } + address + }; + + let whitelist = whitelist.unwrap_or_default(); + let mut auth_config = SignatureAuthConfig::new(whitelist, chain_id); + let nonces = Arc::new(std::sync::RwLock::new(std::collections::HashMap::new())); + auth_config.nonces = nonces.clone(); + + // Create the OpsApi handler. + let ops_api = reth_rpc::OpsApi::new(provider, task_spawner, nonces); + + // Register it in a module. + let mut module = BodyAuthRpcModule::empty(); + module + .merge_methods(ops_api.into_rpc()) + .map_err(|e| eyre::eyre!("failed to register ops methods: {e}"))?; + + // Build and start the server. + let addr = std::net::SocketAddr::new(config.rpc.ops_addr, config.rpc.ops_port); + let server_config = BodyAuthServerConfig::builder(auth_config).socket_addr(addr).build(); + + let handle = server_config + .start(module) + .await + .map_err(|e| eyre::eyre!("failed to start ops server: {e}"))?; + + info!( + target: "reth::cli", + url=%handle.local_addr(), + governance_address=%governance_address, + "RPC ops signature-auth server started" + ); + + Ok(Some(handle)) + } + /// Helper to finalize RPC setup by creating context and calling hooks fn finalize_rpc_setup( registry: &mut RpcRegistry<N, EthB::EthApi>, @@ -1136,6 +1249,8 @@ /// Eth API configuration pub config: EthConfig, /// Cache for eth state pub cache: EthStateCache<PrimitivesTy<N::Types>>, + /// Shared ops whitelist used by specialized eth APIs. + pub ops_whitelist: Option<Whitelist>, }   impl<'a, N: FullNodeComponents<Types: NodeTypes<ChainSpec: Hardforks + EthereumHardforks>>> @@ -1155,6 +1270,7 @@ .gas_oracle_config(self.config.gas_oracle) .max_batch_size(self.config.max_batch_size) .pending_block_kind(self.config.pending_block_kind) .raw_tx_forwarder(self.config.raw_tx_forwarder) + .enable_storage_apis(self.config.enable_storage_apis) } }
diff --git reth/crates/node/core/Cargo.toml seismic-reth/crates/node/core/Cargo.toml index 2240fa98837726ba849ed15c61afdd3fb610a5c9..0b718a613f040b0d7e195b2caac4c05618fdbd72 100644 --- reth/crates/node/core/Cargo.toml +++ seismic-reth/crates/node/core/Cargo.toml @@ -11,6 +11,7 @@ [lints] workspace = true   [dependencies] + # reth reth-chainspec.workspace = true reth-consensus.workspace = true
diff --git reth/crates/node/core/src/args/enclave.rs seismic-reth/crates/node/core/src/args/enclave.rs new file mode 100644 index 0000000000000000000000000000000000000000..48b5c9b31cd065662bf0edb42534ad3e591b8709 --- /dev/null +++ seismic-reth/crates/node/core/src/args/enclave.rs @@ -0,0 +1,80 @@ +//! clap [Args](clap::Args) for RPC related arguments. +use clap::Args; +use std::net::{IpAddr, Ipv4Addr}; + +const ENCLAVE_DEFAULT_ENDPOINT_PORT: u16 = 7878; +const ENCLAVE_DEFAULT_ENDPOINT_IP: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); + +/// Parameters for configuring the enclave more granularity via CLI +#[derive(Debug, Clone, Args, PartialEq, Eq, Copy)] +#[command(next_help_heading = "Enclave")] +pub struct EnclaveArgs { + /// Auth server address to listen on + #[arg(long = "enclave.endpoint-addr", default_value_t = ENCLAVE_DEFAULT_ENDPOINT_IP.try_into().unwrap())] + pub enclave_server_addr: IpAddr, + + /// Auth server port to listen on + #[arg(long = "enclave.endpoint-port", default_value_t = ENCLAVE_DEFAULT_ENDPOINT_PORT)] + pub enclave_server_port: u16, + + /// How many failures to tolerate before we panic + #[arg(long = "enclave.retries", default_value_t = 0)] + pub retries: u32, + + /// How many seconds to pause between retries + #[arg(long = "enclave.retry-seconds", default_value_t = 30)] + pub retry_seconds: u16, + + /// Spin up mock server for testing purpose + #[arg(long = "enclave.mock-server", action = clap::ArgAction::SetTrue)] + pub mock_server: bool, + + /// Enclave client timeout + #[arg(long = "enclave.timeout", default_value_t = 5)] + pub enclave_timeout: u64, +} + +impl Default for EnclaveArgs { + fn default() -> Self { + Self { + enclave_server_addr: ENCLAVE_DEFAULT_ENDPOINT_IP, + enclave_server_port: ENCLAVE_DEFAULT_ENDPOINT_PORT, + mock_server: false, + enclave_timeout: 5, + retries: 5, + retry_seconds: 30, + } + } +} + +impl AsRef<EnclaveArgs> for EnclaveArgs { + fn as_ref(&self) -> &EnclaveArgs { + self + } +} + +#[cfg(test)] +mod tests { + use super::*; + use clap::{Args, Parser}; + + /// A helper type to parse Args more easily + #[derive(Parser)] + struct CommandParser<T: Args> { + #[command(flatten)] + args: T, + } + + #[test] + fn test_enclave_args_parser() { + let args = CommandParser::<EnclaveArgs>::parse_from(["reth node"]).args; + + let addr = args.enclave_server_addr; + let port = args.enclave_server_port; + let mock = args.mock_server; + + assert_eq!(port, ENCLAVE_DEFAULT_ENDPOINT_PORT); + assert_eq!(addr, ENCLAVE_DEFAULT_ENDPOINT_IP); + assert_eq!(mock, false); + } +}
diff --git reth/crates/node/core/src/args/mod.rs seismic-reth/crates/node/core/src/args/mod.rs index 6799fe418dcb045b6f3b48c5a22066cd4206afe2..2b40b9e4cefab34751b2a7229e660728448ef0c0 100644 --- reth/crates/node/core/src/args/mod.rs +++ seismic-reth/crates/node/core/src/args/mod.rs @@ -1,4 +1,7 @@ //! Parameters for configuring the rpc more granularity via CLI +/// EnclaveArgs struct for configuring the enclave +mod enclave; +pub use enclave::EnclaveArgs;   /// NetworkArg struct for configuring the network mod network;
diff --git reth/crates/node/core/src/args/network.rs seismic-reth/crates/node/core/src/args/network.rs index a93b0b0c1e3ad1f6aa1132fd3f0eb4aec8d6be37..1ef727057d3ab7115dff9174988b92bcacda8d92 100644 --- reth/crates/node/core/src/args/network.rs +++ seismic-reth/crates/node/core/src/args/network.rs @@ -278,7 +278,7 @@ }) // apply discovery settings .apply(|builder| { let rlpx_socket = (addr, self.port).into(); - self.discovery.apply_to_builder(builder, rlpx_socket, chain_bootnodes) + self.discovery.apply_to_builder(builder, rlpx_socket, chain_bootnodes, self.nat) }) .listener_addr(SocketAddr::new( addr, // set discovery port based on instance number @@ -444,6 +444,7 @@ &self, mut network_config_builder: NetworkConfigBuilder<N>, rlpx_tcp_socket: SocketAddr, boot_nodes: impl IntoIterator<Item = NodeRecord>, + nat: NatResolver, ) -> NetworkConfigBuilder<N> where N: NetworkPrimitives, @@ -463,7 +464,7 @@ }   if self.should_enable_discv5() { network_config_builder = network_config_builder - .discovery_v5(self.discovery_v5_builder(rlpx_tcp_socket, boot_nodes)); + .discovery_v5(self.discovery_v5_builder(rlpx_tcp_socket, boot_nodes, nat)); }   network_config_builder @@ -474,6 +475,7 @@ pub fn discovery_v5_builder( &self, rlpx_tcp_socket: SocketAddr, boot_nodes: impl IntoIterator<Item = NodeRecord>, + nat: NatResolver, ) -> reth_discv5::ConfigBuilder { let Self { discv5_addr, @@ -508,6 +510,7 @@ .add_unsigned_boot_nodes(boot_nodes) .lookup_interval(*discv5_lookup_interval) .bootstrap_lookup_interval(*discv5_bootstrap_lookup_interval) .bootstrap_lookup_countdown(*discv5_bootstrap_lookup_countdown) + .nat(nat) }   /// Returns true if discv5 discovery should be configured
diff --git reth/crates/node/core/src/args/rpc_server.rs seismic-reth/crates/node/core/src/args/rpc_server.rs index aef7a1f8c629ac614d9afdc99b9e6a8d070628a6..9c29d1689efd859c6ddd8bbc1a7356c6754f9021 100644 --- reth/crates/node/core/src/args/rpc_server.rs +++ seismic-reth/crates/node/core/src/args/rpc_server.rs @@ -232,6 +232,28 @@ /// Endpoint to forward transactions to. #[arg(long = "rpc.forwarder", alias = "rpc-forwarder", value_name = "FORWARDER")] pub rpc_forwarder: Option<Url>,   + /// Enable storage APIs (eth_getStorageAt, eth_getFlaggedStorageAt). + /// Disabled by default to protect private storage information. + /// Automatically enabled in dev mode. + #[arg( + long = "rpc.enable-storage-apis", + default_value_if("dev", "true", "true"), + default_value_t = false + )] + pub rpc_enable_storage_apis: bool, + + /// Enable the ops signature-auth RPC server. + #[arg(long = "ops.enable", default_value_t = false)] + pub ops_enable: bool, + + /// Ops server address to listen on. + #[arg(long = "ops.addr", default_value_t = IpAddr::V4(Ipv4Addr::LOCALHOST))] + pub ops_addr: IpAddr, + + /// Port for the ops signature-auth RPC server. Defaults to 8552. + #[arg(long = "ops.port", value_name = "PORT", default_value_t = 8552)] + pub ops_port: u16, + /// Path to file containing disallowed addresses, json-encoded list of strings. Block /// validation API will reject blocks containing transactions from these addresses. #[arg(long = "builder.disallow", value_name = "PATH", value_parser = reth_cli_util::parsers::read_json_from_file::<HashSet<Address>>)] @@ -402,6 +424,10 @@ gas_price_oracle: GasPriceOracleArgs::default(), rpc_state_cache: RpcStateCacheArgs::default(), rpc_proof_permits: constants::DEFAULT_PROOF_PERMITS, rpc_forwarder: None, + rpc_enable_storage_apis: false, + ops_enable: false, + ops_addr: Ipv4Addr::LOCALHOST.into(), + ops_port: 8552, builder_disallow: Default::default(), } }
diff --git reth/crates/node/core/src/lib.rs seismic-reth/crates/node/core/src/lib.rs index b999121c5e971e20a5a9715826198d41586228a7..b9356b4fd28e69f5f0b67168ead8257ed763b6dd 100644 --- reth/crates/node/core/src/lib.rs +++ seismic-reth/crates/node/core/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/node/core/src/node_config.rs seismic-reth/crates/node/core/src/node_config.rs index 96fa8cc8dfa0029c348c56626a4945a9bf455624..d2bbe7d25b0d97843dc110fc187fa4d4e42f6dc8 100644 --- reth/crates/node/core/src/node_config.rs +++ seismic-reth/crates/node/core/src/node_config.rs @@ -2,8 +2,8 @@ //! Support for customizing the node   use crate::{ args::{ - DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EngineArgs, NetworkArgs, PayloadBuilderArgs, - PruningArgs, RpcServerArgs, TxPoolArgs, + DatabaseArgs, DatadirArgs, DebugArgs, DevArgs, EnclaveArgs, EngineArgs, NetworkArgs, + PayloadBuilderArgs, PruningArgs, RpcServerArgs, TxPoolArgs, }, dirs::{ChainPath, DataDirPath}, utils::get_single_header, @@ -40,7 +40,8 @@ DEFAULT_RESERVED_CPU_CORES, };   /// Triggers persistence when the number of canonical blocks in memory exceeds this threshold. -pub const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 2; +pub const DEFAULT_PERSISTENCE_THRESHOLD: u64 = 0; // todo(dalton): Maybe feature flag this? We need this so archive nodes can get an accurate + // snapshot. benchmarks dont signal this is of great cost to us   /// Default size of cross-block cache in megabytes. pub const DEFAULT_CROSS_BLOCK_CACHE_SIZE_MB: u64 = 4 * 1024; @@ -152,6 +153,8 @@ /// All engine related arguments pub engine: EngineArgs,   + /// All enclave related arguments + pub enclave: EnclaveArgs, /// All ERA import related arguments with --era prefix pub era: EraArgs, } @@ -183,6 +186,7 @@ dev: DevArgs::default(), pruning: PruningArgs::default(), datadir: DatadirArgs::default(), engine: EngineArgs::default(), + enclave: EnclaveArgs::default(), era: EraArgs::default(), } } @@ -280,6 +284,12 @@ /// Set the dev args for the node pub const fn with_dev(mut self, dev: DevArgs) -> Self { self.dev = dev; + self + } + + /// Set the enclave args for the node + pub const fn with_enclave(mut self, enclave: EnclaveArgs) -> Self { + self.enclave = enclave; self }   @@ -489,6 +499,7 @@ db: self.db, dev: self.dev, pruning: self.pruning, engine: self.engine, + enclave: self.enclave, era: self.era, } } @@ -529,6 +540,7 @@ dev: self.dev, pruning: self.pruning.clone(), datadir: self.datadir.clone(), engine: self.engine.clone(), + enclave: self.enclave.clone(), era: self.era.clone(), } }
diff --git reth/crates/node/events/src/lib.rs seismic-reth/crates/node/events/src/lib.rs index e4665066c70c95a6d76608bcdb83d3063f87c263..be3f9247962c677061739a6baab5cd4c412dcee9 100644 --- reth/crates/node/events/src/lib.rs +++ seismic-reth/crates/node/events/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/node/metrics/src/lib.rs seismic-reth/crates/node/metrics/src/lib.rs index d74a8aeffba0468ca9d04d0235ce70e850cdc985..d9ebfc637884baa43f3ae23549901322f81bbea6 100644 --- reth/crates/node/metrics/src/lib.rs +++ seismic-reth/crates/node/metrics/src/lib.rs @@ -2,7 +2,7 @@ //! Metrics utilities for the node. #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/node/types/src/lib.rs seismic-reth/crates/node/types/src/lib.rs index 49c1f8fee8647d83e58dfa97aeb849116c5c188e..25a9647f664253be70058560bd6aba66429bfc33 100644 --- reth/crates/node/types/src/lib.rs +++ seismic-reth/crates/node/types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/payload/basic/src/lib.rs seismic-reth/crates/payload/basic/src/lib.rs index fa55a6313427685d6c698e684aee3b29aecf9ee5..2c532e24bc3382e6dbd4df32344c2017eb6de009 100644 --- reth/crates/payload/basic/src/lib.rs +++ seismic-reth/crates/payload/basic/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/payload/builder-primitives/src/lib.rs seismic-reth/crates/payload/builder-primitives/src/lib.rs index d181531ca328f02b261421d9f79b8b5ce0321487..35be88cb15fc1918ddd5f40e1d3e85d29f5b09ae 100644 --- reth/crates/payload/builder-primitives/src/lib.rs +++ seismic-reth/crates/payload/builder-primitives/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/payload/builder/Cargo.toml seismic-reth/crates/payload/builder/Cargo.toml index 166c538f7a14b51429657c5450755f5923834972..65a86dddacace11b629bf519a430a1c73a483d3f 100644 --- reth/crates/payload/builder/Cargo.toml +++ seismic-reth/crates/payload/builder/Cargo.toml @@ -40,6 +40,7 @@ [dev-dependencies] tokio = { workspace = true, features = ["sync", "rt"] }   [features] +timestamp-in-seconds = ["reth-primitives-traits/timestamp-in-seconds"] test-utils = [ "reth-chain-state/test-utils", "reth-primitives-traits/test-utils",
diff --git reth/crates/payload/builder/src/lib.rs seismic-reth/crates/payload/builder/src/lib.rs index 54254b53fb8b48868a8cda9ebe2601cc0cf86f33..befaf005e5e64d61db29161f32f0b0b4f03aec47 100644 --- reth/crates/payload/builder/src/lib.rs +++ seismic-reth/crates/payload/builder/src/lib.rs @@ -102,7 +102,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/payload/primitives/src/lib.rs seismic-reth/crates/payload/primitives/src/lib.rs index 811b9da7f1916e2e70824ceffcefc6cffc5f5a3b..3f616c3f00238c2e2ecab98e7854ac5fad4d5581 100644 --- reth/crates/payload/primitives/src/lib.rs +++ seismic-reth/crates/payload/primitives/src/lib.rs @@ -5,7 +5,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/payload/primitives/src/traits.rs seismic-reth/crates/payload/primitives/src/traits.rs index 868929c2b1bef9f8fd74d7994172544b518f654e..2947a1f22c98f7de7a2a6c245e071a8ea3ae932d 100644 --- reth/crates/payload/primitives/src/traits.rs +++ seismic-reth/crates/payload/primitives/src/traits.rs @@ -71,6 +71,7 @@ /// Returns the hash of the parent block this payload builds on. fn parent(&self) -> B256;   /// Returns the timestamp to be used in the payload's header. + /// NOTE: Assumes timestamp is in milliseconds since from CL node fn timestamp(&self) -> u64;   /// Returns the beacon chain block root from the parent block.
diff --git reth/crates/payload/util/src/lib.rs seismic-reth/crates/payload/util/src/lib.rs index ffffc936fe19a72b203fc37600b77bcc24232fb9..0bd2df1d634fce4ee3119ff5ce430e07549f1b3e 100644 --- reth/crates/payload/util/src/lib.rs +++ seismic-reth/crates/payload/util/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/payload/validator/src/lib.rs seismic-reth/crates/payload/validator/src/lib.rs index de952ebd6afd51ba2c25fd1742ca18d7fefd968e..46bbdefb5207328c8410a62e3896c0eda5e83dcc 100644 --- reth/crates/payload/validator/src/lib.rs +++ seismic-reth/crates/payload/validator/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/primitives-traits/Cargo.toml seismic-reth/crates/primitives-traits/Cargo.toml index 8d09ecb14f975132cc463bf712c22f09de297489..3fb93f3c344cf4217c9bc16c2101907d5072e352 100644 --- reth/crates/primitives-traits/Cargo.toml +++ seismic-reth/crates/primitives-traits/Cargo.toml @@ -12,19 +12,24 @@ [lints] workspace = true   [dependencies] +# seimsic +seismic-alloy-consensus = { workspace = true, features = ["k256", "serde"] } +seismic-alloy-genesis.workspace = true +alloy-genesis.workspace = true + # reth reth-codecs = { workspace = true, optional = true }   # ethereum alloy-consensus = { workspace = true, features = ["k256"] } alloy-eips.workspace = true -alloy-genesis.workspace = true alloy-primitives = { workspace = true, features = ["k256"] } alloy-rlp.workspace = true alloy-trie.workspace = true revm-primitives.workspace = true revm-bytecode.workspace = true revm-state.workspace = true +# alloy-rpc-types-eth.workspace = true   # op op-alloy-consensus = { workspace = true, optional = true, features = ["k256"] } @@ -73,6 +78,7 @@ test-fuzz.workspace = true   [features] default = ["std"] +timestamp-in-seconds = [] std = [ "alloy-consensus/std", "alloy-eips/std", @@ -136,7 +142,6 @@ "alloy-primitives/serde", "bytes/serde", "rand/serde", "reth-codecs?/serde", - "revm-primitives/serde", "revm-primitives/serde", "op-alloy-consensus?/serde", "secp256k1?/serde",
diff --git reth/crates/primitives-traits/src/account.rs seismic-reth/crates/primitives-traits/src/account.rs index 34a533fc4a4441c3496dddce5ae7e0a08c1fa2e7..1171b41749f7a136c6b97afb74995990d1038829 100644 --- reth/crates/primitives-traits/src/account.rs +++ seismic-reth/crates/primitives-traits/src/account.rs @@ -5,6 +5,7 @@ use alloy_trie::TrieAccount; use derive_more::Deref; use revm_bytecode::{Bytecode as RevmBytecode, BytecodeDecodeError}; use revm_state::AccountInfo; +use seismic_alloy_genesis::GenesisAccount as SeismicGenesisAccount;   #[cfg(any(test, feature = "reth-codec"))] /// Identifiers used in [`Compact`](reth_codecs::Compact) encoding of [`Bytecode`]. @@ -196,6 +197,16 @@ }   impl From<&GenesisAccount> for Account { fn from(value: &GenesisAccount) -> Self { + Self { + nonce: value.nonce.unwrap_or_default(), + balance: value.balance, + bytecode_hash: value.code.as_ref().map(keccak256), + } + } +} + +impl From<&SeismicGenesisAccount> for Account { + fn from(value: &SeismicGenesisAccount) -> Self { Self { nonce: value.nonce.unwrap_or_default(), balance: value.balance,
diff --git reth/crates/primitives-traits/src/block/header.rs seismic-reth/crates/primitives-traits/src/block/header.rs index c4df8ecf542ffecce04b1ff19bcdd5df0af0b94c..e885bdf475b13f7c9964bcac81556dcb49332591 100644 --- reth/crates/primitives-traits/src/block/header.rs +++ seismic-reth/crates/primitives-traits/src/block/header.rs @@ -34,6 +34,14 @@ + MaybeSerdeBincodeCompat + AsRef<Self> + 'static { + /// Returns the timestamp in seconds, assuming the timestamp is in milliseconds. + fn timestamp_seconds(&self) -> u64 { + if cfg!(feature = "timestamp-in-seconds") { + self.timestamp() + } else { + self.timestamp() / 1000 + } + } }   impl BlockHeader for alloy_consensus::Header {}
diff --git reth/crates/primitives-traits/src/block/sealed.rs seismic-reth/crates/primitives-traits/src/block/sealed.rs index 5c43178146baa25c50fe58857a0149d3030b0214..a5d50ef3e02069d8e462362e0244e229a8e5960a 100644 --- reth/crates/primitives-traits/src/block/sealed.rs +++ seismic-reth/crates/primitives-traits/src/block/sealed.rs @@ -194,6 +194,15 @@ pub fn block_with_parent(&self) -> BlockWithParent { BlockWithParent { parent: self.parent_hash(), block: self.num_hash() } }   + /// Returns the timestamp in seconds, assuming the timestamp is in milliseconds. + pub fn timestamp_seconds(&self) -> u64 { + if cfg!(feature = "timestamp-in-seconds") { + self.timestamp() + } else { + self.timestamp() / 1000 + } + } + /// Returns the Sealed header. pub const fn sealed_header(&self) -> &SealedHeader<B::Header> { &self.header
diff --git reth/crates/primitives-traits/src/header/sealed.rs seismic-reth/crates/primitives-traits/src/header/sealed.rs index bcf69813f971aaa3f23e50034b32b26564e21907..d88c5d12c92c9c885342251b9f398fccb5dd9d1a 100644 --- reth/crates/primitives-traits/src/header/sealed.rs +++ seismic-reth/crates/primitives-traits/src/header/sealed.rs @@ -127,6 +127,15 @@ /// Return a [`BlockWithParent`] for this header. pub fn block_with_parent(&self) -> BlockWithParent { BlockWithParent { parent: self.parent_hash(), block: self.num_hash() } } + + /// Returns the timestamp in seconds (header timestamp is in milliseconds) + pub fn timestamp_seconds(&self) -> u64 { + if cfg!(feature = "timestamp-in-seconds") { + self.header.timestamp() + } else { + self.header.timestamp() / 1000 + } + } }   impl<H: Sealable> Eq for SealedHeader<H> {}
diff --git reth/crates/primitives-traits/src/lib.rs seismic-reth/crates/primitives-traits/src/lib.rs index 841ba333b98ce623e9e4959ea514f0542b190792..f0b2ad486b32ee4ac97f7abc1289542f12c07d0a 100644 --- reth/crates/primitives-traits/src/lib.rs +++ seismic-reth/crates/primitives-traits/src/lib.rs @@ -108,7 +108,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/primitives-traits/src/size.rs seismic-reth/crates/primitives-traits/src/size.rs index 734ae78b191985612ad506acaefd99ef97154060..2f9a91f6d2921a81915d05bdfd0a109b7ffeebc9 100644 --- reth/crates/primitives-traits/src/size.rs +++ seismic-reth/crates/primitives-traits/src/size.rs @@ -50,7 +50,15 @@ )* }; }   -impl_in_mem_size!(Header, TxLegacy, TxEip2930, TxEip1559, TxEip7702, TxEip4844); +impl_in_mem_size!( + Header, + TxLegacy, + TxEip2930, + TxEip1559, + TxEip7702, + TxEip4844, + seismic_alloy_consensus::TxSeismic +);   impl<T: TxEip4844Sidecar> InMemorySize for TxEip4844Variant<T> { #[inline] @@ -67,7 +75,7 @@ } }   #[cfg(feature = "op")] -impl_in_mem_size_size_of!(op_alloy_consensus::OpTxType); +impl_in_mem_size_size_of!(op_alloy_consensus::OpTxType, seismic_alloy_consensus::SeismicTxType);   impl InMemorySize for alloy_consensus::Receipt { fn size(&self) -> usize { @@ -121,6 +129,36 @@ impl InMemorySize for u64 { fn size(&self) -> usize { core::mem::size_of::<Self>() + } +} + +mod seismic { + use super::*; + + impl InMemorySize for seismic_alloy_consensus::SeismicTypedTransaction { + fn size(&self) -> usize { + match self { + Self::Legacy(tx) => tx.size(), + Self::Eip2930(tx) => tx.size(), + Self::Eip1559(tx) => tx.size(), + Self::Eip4844(tx) => tx.size(), + Self::Eip7702(tx) => tx.size(), + Self::Seismic(tx) => tx.size(), + } + } + } + + impl InMemorySize for seismic_alloy_consensus::SeismicTxEnvelope { + fn size(&self) -> usize { + match self { + Self::Legacy(tx) => tx.size(), + Self::Eip2930(tx) => tx.size(), + Self::Eip1559(tx) => tx.size(), + Self::Eip4844(tx) => tx.size(), + Self::Eip7702(tx) => tx.size(), + Self::Seismic(tx) => tx.size(), + } + } } }
diff --git reth/crates/primitives-traits/src/storage.rs seismic-reth/crates/primitives-traits/src/storage.rs index c6b9b1e11c753233ab04b16c89a211b4d6f91813..4c543f46bf2096bf849c39f589b827e13d33332f 100644 --- reth/crates/primitives-traits/src/storage.rs +++ seismic-reth/crates/primitives-traits/src/storage.rs @@ -1,5 +1,7 @@ use alloy_primitives::{B256, U256};   +use alloy_primitives::FlaggedStorage; + /// Account storage entry. /// /// `key` is the subkey when used as a value in the `StorageChangeSets` table. @@ -11,19 +13,42 @@ pub struct StorageEntry { /// Storage key. pub key: B256, /// Value on storage key. - pub value: U256, + pub value: FlaggedStorage, }   impl StorageEntry { /// Create a new `StorageEntry` with given key and value. - pub const fn new(key: B256, value: U256) -> Self { + pub const fn new(key: B256, value: U256, is_private: bool) -> Self { + Self { key, value: FlaggedStorage { value, is_private } } + } + + /// Convert the storage entry to a flagged storage entry. + pub const fn to_flagged_storage(self) -> FlaggedStorage { + self.value + } +} + +impl From<(B256, U256, bool)> for StorageEntry { + fn from((key, value, is_private): (B256, U256, bool)) -> Self { + Self::new(key, value, is_private) + } +} + +impl From<(B256, (U256, bool))> for StorageEntry { + fn from((key, (value, is_private)): (B256, (U256, bool))) -> Self { + Self::new(key, value, is_private) + } +} + +impl From<(B256, FlaggedStorage)> for StorageEntry { + fn from((key, value): (B256, FlaggedStorage)) -> Self { Self { key, value } } }   -impl From<(B256, U256)> for StorageEntry { - fn from((key, value): (B256, U256)) -> Self { - Self { key, value } +impl From<StorageEntry> for FlaggedStorage { + fn from(entry: StorageEntry) -> Self { + entry.value } }   @@ -38,12 +63,14 @@ B: bytes::BufMut + AsMut<[u8]>, { // for now put full bytes and later compress it. buf.put_slice(&self.key[..]); - self.value.to_compact(buf) + 32 + buf.put_u8(self.value.is_private as u8); + self.value.value.to_compact(buf) + 32 + 1 }   fn from_compact(buf: &[u8], len: usize) -> (Self, &[u8]) { let key = B256::from_slice(&buf[..32]); - let (value, out) = U256::from_compact(&buf[32..], len - 32); - (Self { key, value }, out) + let is_private = buf[32] != 0; + let (value, out) = U256::from_compact(&buf[32 + 1..], len - 32 - 1); + (Self { key, value: FlaggedStorage { value, is_private } }, out) } }
diff --git reth/crates/primitives-traits/src/transaction/error.rs seismic-reth/crates/primitives-traits/src/transaction/error.rs index b87405e4abd88fa56c1e04947673a5025c081cf2..294e85c75b658530add9c6453f3652924db81eed 100644 --- reth/crates/primitives-traits/src/transaction/error.rs +++ seismic-reth/crates/primitives-traits/src/transaction/error.rs @@ -64,6 +64,9 @@ SignerAccountHasBytecode, /// Thrown post Osaka if gas limit is too high. #[error("gas limit too high")] GasLimitTooHigh, + /// Seismic transaction error + #[error("seismic transaction error: {0}")] + SeismicTx(String), }   /// Represents error variants that can happen when trying to convert a transaction to pooled
diff --git reth/crates/primitives-traits/src/transaction/signed.rs seismic-reth/crates/primitives-traits/src/transaction/signed.rs index 104555db0f7c25781d43414ecb804abf16a28ab4..b54aea03b8916e52fe8a83d890d04be53a18d8e6 100644 --- reth/crates/primitives-traits/src/transaction/signed.rs +++ seismic-reth/crates/primitives-traits/src/transaction/signed.rs @@ -147,6 +147,19 @@ } } }   +impl SignedTransaction for seismic_alloy_consensus::SeismicTxEnvelope { + fn tx_hash(&self) -> &TxHash { + match self { + Self::Legacy(tx) => tx.hash(), + Self::Eip2930(tx) => tx.hash(), + Self::Eip1559(tx) => tx.hash(), + Self::Eip4844(tx) => tx.hash(), + Self::Eip7702(tx) => tx.hash(), + Self::Seismic(tx) => tx.hash(), + } + } +} + #[cfg(feature = "op")] mod op { use super::*;
diff --git reth/crates/primitives/src/lib.rs seismic-reth/crates/primitives/src/lib.rs index a80e83db0deea53182e81c50d4d58e0b97ce8552..89a89004457a16fcb889420b5fd4845aee66f41c 100644 --- reth/crates/primitives/src/lib.rs +++ seismic-reth/crates/primitives/src/lib.rs @@ -12,7 +12,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/prune/prune/src/lib.rs seismic-reth/crates/prune/prune/src/lib.rs index ef3ee0de2dbe08cf55e09604d53cce4d06fd1779..2a3d2a513688a3ae918dc781dd24a7941d3e6dde 100644 --- reth/crates/prune/prune/src/lib.rs +++ seismic-reth/crates/prune/prune/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![allow(missing_docs)]
diff --git reth/crates/prune/types/src/lib.rs seismic-reth/crates/prune/types/src/lib.rs index c1d268a0fb7a7810ec21e42dc07d2269a6ded569..4c5a0c37c5e0f536e57e877c82b793fbed83aef3 100644 --- reth/crates/prune/types/src/lib.rs +++ seismic-reth/crates/prune/types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/ress/provider/src/recorder.rs seismic-reth/crates/ress/provider/src/recorder.rs index ec5afacbf0cad3b249dfb7f18fc0f491ecc1e352..8d3467a9ddf122d0328f4f7481d4678efd7456ee 100644 --- reth/crates/ress/provider/src/recorder.rs +++ seismic-reth/crates/ress/provider/src/recorder.rs @@ -1,6 +1,6 @@ use alloy_primitives::{keccak256, Address, B256, U256}; use reth_revm::{ - state::{AccountInfo, Bytecode}, + state::{AccountInfo, Bytecode, FlaggedStorage}, Database, }; use reth_trie::{HashedPostState, HashedStorage}; @@ -34,7 +34,7 @@ self.state.accounts.insert(hashed_address, maybe_account.as_ref().map(|acc| acc.into())); Ok(maybe_account) }   - fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> { + fn storage(&mut self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> { let value = self.database.storage(address, index)?; let hashed_address = keccak256(address); let hashed_slot = keccak256(B256::from(index));
diff --git reth/crates/revm/Cargo.toml seismic-reth/crates/revm/Cargo.toml index 488a685b38298e20495cc8d8c1d1e3039f6cee32..e12a9754b0ffcf5b963a479cdf644ccd14d2ec4f 100644 --- reth/crates/revm/Cargo.toml +++ seismic-reth/crates/revm/Cargo.toml @@ -31,6 +31,7 @@ alloy-consensus.workspace = true   [features] default = ["std"] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] std = [ "reth-primitives-traits/std", "alloy-primitives/std",
diff --git reth/crates/revm/src/cached.rs seismic-reth/crates/revm/src/cached.rs index bf4bd6d5d1ba520f72d5e3c745de09409050cdda..12783cb2f16080bebc7afb41f9effe696f1fc058 100644 --- reth/crates/revm/src/cached.rs +++ seismic-reth/crates/revm/src/cached.rs @@ -4,7 +4,11 @@ map::{Entry, HashMap}, Address, B256, U256, }; use core::cell::RefCell; -use revm::{bytecode::Bytecode, state::AccountInfo, Database, DatabaseRef}; +use revm::{ + bytecode::Bytecode, + state::{AccountInfo, FlaggedStorage}, + Database, DatabaseRef, +};   /// A container type that caches reads from an underlying [`DatabaseRef`]. /// @@ -55,7 +59,7 @@ pub fn insert_account( &mut self, address: Address, info: AccountInfo, - storage: HashMap<U256, U256>, + storage: HashMap<U256, FlaggedStorage>, ) { self.accounts.insert(address, CachedAccount { info: Some(info), storage }); } @@ -122,7 +126,7 @@ }; Ok(code) }   - fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> { + fn storage(&mut self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> { match self.cached.accounts.entry(address) { Entry::Occupied(mut acc_entry) => match acc_entry.get_mut().storage.entry(index) { Entry::Occupied(entry) => Ok(*entry.get()), @@ -137,7 +141,7 @@ let mut account = CachedAccount::new(info); account.storage.insert(index, value); (account, value) } else { - (CachedAccount::new(info), U256::ZERO) + (CachedAccount::new(info), FlaggedStorage::ZERO) }; acc_entry.insert(account); Ok(value) @@ -175,7 +179,7 @@ fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> { self.inner.borrow_mut().code_by_hash(code_hash) }   - fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> { + fn storage_ref(&self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> { self.inner.borrow_mut().storage(address, index) }   @@ -191,7 +195,7 @@ pub struct CachedAccount { /// Account state. pub info: Option<AccountInfo>, /// Account's storage. - pub storage: HashMap<U256, U256>, + pub storage: HashMap<U256, FlaggedStorage>, }   impl CachedAccount {
diff --git reth/crates/revm/src/database.rs seismic-reth/crates/revm/src/database.rs index 6b829c3d734538c44f79c4b16e7afa7f267162cf..3b4caa946243d67cfe31c4df5b44eadd20fd5d4e 100644 --- reth/crates/revm/src/database.rs +++ seismic-reth/crates/revm/src/database.rs @@ -1,10 +1,14 @@ -use crate::primitives::alloy_primitives::{BlockNumber, StorageKey, StorageValue}; +use crate::primitives::alloy_primitives::{BlockNumber, StorageKey}; use alloy_primitives::{Address, B256, U256}; use core::ops::{Deref, DerefMut}; use reth_primitives_traits::Account; use reth_storage_api::{AccountReader, BlockHashReader, BytecodeReader, StateProvider}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; -use revm::{bytecode::Bytecode, state::AccountInfo, Database, DatabaseRef}; +use revm::{ + bytecode::Bytecode, + state::{AccountInfo, FlaggedStorage}, + Database, DatabaseRef, +};   /// A helper trait responsible for providing state necessary for EVM execution. /// @@ -30,7 +34,7 @@ fn storage( &self, account: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>>; + ) -> ProviderResult<Option<FlaggedStorage>>; }   // Blanket implementation of EvmStateProvider for any type that implements StateProvider. @@ -54,8 +58,8 @@ fn storage( &self, account: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<StorageValue>> { - <T as StateProvider>::storage(self, account, storage_key) + ) -> ProviderResult<Option<FlaggedStorage>> { + <T as reth_storage_api::StateProvider>::storage(self, account, storage_key) } }   @@ -123,7 +127,7 @@ /// Retrieves the storage value at a specific index for a given address. /// /// Returns `Ok` with the storage value, or the default value if not found. - fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> { + fn storage(&mut self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> { self.storage_ref(address, index) }   @@ -157,7 +161,7 @@ /// Retrieves the storage value at a specific index for a given address. /// /// Returns `Ok` with the storage value, or the default value if not found. - fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> { + fn storage_ref(&self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> { Ok(self.0.storage(address, B256::new(index.to_be_bytes()))?.unwrap_or_default()) }
diff --git reth/crates/revm/src/lib.rs seismic-reth/crates/revm/src/lib.rs index ecc5b576a84ee4fc4b6c85d5aedf399fb35510fc..52689997835f419dbb24d5d97e28633686615eca 100644 --- reth/crates/revm/src/lib.rs +++ seismic-reth/crates/revm/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/revm/src/test_utils.rs seismic-reth/crates/revm/src/test_utils.rs index e0d40070878e3a457a34291cc83420df09c3d209..ba9fead2dc3614a666119de8293402fea5fae063 100644 --- reth/crates/revm/src/test_utils.rs +++ seismic-reth/crates/revm/src/test_utils.rs @@ -1,7 +1,5 @@ use alloc::vec::Vec; -use alloy_primitives::{ - keccak256, map::HashMap, Address, BlockNumber, Bytes, StorageKey, B256, U256, -}; +use alloy_primitives::{keccak256, map::HashMap, Address, BlockNumber, Bytes, StorageKey, B256}; use reth_primitives_traits::{Account, Bytecode}; use reth_storage_api::{ AccountReader, BlockHashReader, BytecodeReader, HashedPostStateProvider, StateProofProvider, @@ -13,10 +11,14 @@ updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, KeccakKeyHasher, MultiProof, MultiProofTargets, StorageMultiProof, StorageProof, TrieInput, };   +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; +use revm::state::FlaggedStorage; + /// Mock state for testing #[derive(Debug, Default, Clone, Eq, PartialEq)] pub struct StateProviderTest { - accounts: HashMap<Address, (HashMap<StorageKey, U256>, Account)>, + accounts: HashMap<Address, (HashMap<StorageKey, FlaggedStorage>, Account)>, contracts: HashMap<B256, Bytecode>, block_hash: HashMap<u64, B256>, } @@ -28,7 +30,7 @@ &mut self, address: Address, mut account: Account, bytecode: Option<Bytes>, - storage: HashMap<StorageKey, U256>, + storage: HashMap<StorageKey, FlaggedStorage>, ) { if let Some(bytecode) = bytecode { let hash = keccak256(&bytecode); @@ -155,7 +157,7 @@ fn storage( &self, account: Address, storage_key: StorageKey, - ) -> ProviderResult<Option<alloy_primitives::StorageValue>> { + ) -> ProviderResult<Option<FlaggedStorage>> { Ok(self.accounts.get(&account).and_then(|(storage, _)| storage.get(&storage_key).copied())) } }
diff --git reth/crates/rpc/ipc/src/lib.rs seismic-reth/crates/rpc/ipc/src/lib.rs index ae7a8b221f279f30a4525e3ffe649ec13f9d171c..e98cfc89fe9bb917eaa936f39e408181b259a2f4 100644 --- reth/crates/rpc/ipc/src/lib.rs +++ seismic-reth/crates/rpc/ipc/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/rpc/rpc-api/src/lib.rs seismic-reth/crates/rpc/rpc-api/src/lib.rs index 59debf923af1dfea4fb203b084992bf0998c845b..4216c3b3146b9fc14913287735736d220dacaf71 100644 --- reth/crates/rpc/rpc-api/src/lib.rs +++ seismic-reth/crates/rpc/rpc-api/src/lib.rs @@ -9,7 +9,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -22,6 +22,7 @@ mod hardhat; mod mev; mod miner; mod net; +mod ops; mod otterscan; mod reth; mod rpc; @@ -42,6 +43,7 @@ engine::{EngineApiServer, EngineEthApiServer, IntoEngineApiRpcModule}, mev::{MevFullApiServer, MevSimApiServer}, miner::MinerApiServer, net::NetApiServer, + ops::OpsApiServer, otterscan::OtterscanServer, reth::RethApiServer, rpc::RpcApiServer, @@ -72,6 +74,7 @@ hardhat::HardhatApiClient, mev::{MevFullApiClient, MevSimApiClient}, miner::MinerApiClient, net::NetApiClient, + ops::OpsApiClient, otterscan::OtterscanClient, reth::RethApiClient, rpc::RpcApiServer,
diff --git reth/crates/rpc/rpc-api/src/ops.rs seismic-reth/crates/rpc/rpc-api/src/ops.rs new file mode 100644 index 0000000000000000000000000000000000000000..5843e53ccfb7bd48bca8575702de4efaa6f248e0 --- /dev/null +++ seismic-reth/crates/rpc/rpc-api/src/ops.rs @@ -0,0 +1,28 @@ +use alloy_eips::BlockId; +use alloy_primitives::{Address, B256}; +use alloy_serde::JsonStorageKey; +use jsonrpsee::{core::RpcResult, proc_macros::rpc}; + +/// Ops namespace rpc interface for privileged operations protected by signature auth. +#[cfg_attr(not(feature = "client"), rpc(server, namespace = "ops"))] +#[cfg_attr(feature = "client", rpc(server, client, namespace = "ops"))] +pub trait OpsApi { + /// Returns the value from a storage position at a given address, bypassing the storage API + /// gate. Requires a whitelisted key. + /// + /// This endpoint uses incrementing nonce protection. The nonce must match the current expected + /// nonce for the authenticated signer. + #[method(name = "getStorageAt")] + async fn get_storage_at( + &self, + address: Address, + index: JsonStorageKey, + block_number: Option<BlockId>, + ) -> RpcResult<B256>; + + /// Returns the next expected nonce for a whitelisted key. + /// + /// The request must be authenticated by the same whitelisted address passed in `address`. + #[method(name = "getNonce")] + async fn get_nonce(&self, address: Address) -> RpcResult<u64>; +}
diff --git reth/crates/rpc/rpc-builder/Cargo.toml seismic-reth/crates/rpc/rpc-builder/Cargo.toml index b824e76daa592ef8c5229a83b94834a74172fd62..432f0730f5f0664819583c965252610a0f820b4b 100644 --- reth/crates/rpc/rpc-builder/Cargo.toml +++ seismic-reth/crates/rpc/rpc-builder/Cargo.toml @@ -66,6 +66,8 @@ reth-engine-primitives.workspace = true reth-node-ethereum.workspace = true   alloy-primitives.workspace = true +alloy-consensus.workspace = true +alloy-sol-types.workspace = true alloy-rpc-types-eth.workspace = true alloy-rpc-types-trace.workspace = true alloy-eips.workspace = true @@ -73,3 +75,10 @@ alloy-rpc-types-engine.workspace = true   serde_json.workspace = true clap = { workspace = true, features = ["derive"] } +reqwest.workspace = true +alloy-signer.workspace = true +alloy-signer-local.workspace = true +reth-rpc.workspace = true +reth-rpc-layer.workspace = true +reth-storage-api.workspace = true +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
diff --git reth/crates/rpc/rpc-builder/src/body_auth.rs seismic-reth/crates/rpc/rpc-builder/src/body_auth.rs new file mode 100644 index 0000000000000000000000000000000000000000..27dd7dd0fb87ba15d147b9da7f539e16e7068068 --- /dev/null +++ seismic-reth/crates/rpc/rpc-builder/src/body_auth.rs @@ -0,0 +1,246 @@ +use crate::{ + error::{RpcError, ServerKind}, + middleware::RethRpcMiddleware, +}; +use jsonrpsee::{ + core::RegisterMethodError, + server::{AlreadyStoppedError, RpcModule, ServerConfig, ServerConfigBuilder}, + ws_client::RpcServiceBuilder, + Methods, +}; +use reth_rpc_eth_types::EthSubscriptionIdProvider; +use reth_rpc_layer::{SignatureAuthConfig, SignatureAuthLayer}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use tower::layer::util::Identity; + +pub use jsonrpsee::server::ServerBuilder; + +/// Default port for the ops RPC server. +pub const DEFAULT_BODY_AUTH_PORT: u16 = 8552; + +/// Server configuration for an RPC server authenticated via secp256k1 signatures. +#[derive(Debug)] +pub struct BodyAuthServerConfig<RpcMiddleware = Identity> { + /// Where the server should listen. + pub(crate) socket_addr: SocketAddr, + /// Signature authentication configuration. + pub(crate) auth_config: SignatureAuthConfig, + /// Configs for JSON-RPC Http. + pub(crate) server_config: ServerConfigBuilder, + /// Configurable RPC middleware. + pub(crate) rpc_middleware: RpcMiddleware, +} + +impl BodyAuthServerConfig { + /// Convenience function to create a new builder. + pub fn builder(auth_config: SignatureAuthConfig) -> BodyAuthServerConfigBuilder { + BodyAuthServerConfigBuilder::new(auth_config) + } +} + +impl<RpcMiddleware> BodyAuthServerConfig<RpcMiddleware> { + /// Returns the address the server will listen on. + pub const fn address(&self) -> SocketAddr { + self.socket_addr + } + + /// Configures the rpc middleware. + pub fn with_rpc_middleware<T>(self, rpc_middleware: T) -> BodyAuthServerConfig<T> { + let Self { socket_addr, auth_config, server_config, .. } = self; + BodyAuthServerConfig { socket_addr, auth_config, server_config, rpc_middleware } + } + + /// Convenience function to start a server in one step. + pub async fn start(self, module: BodyAuthRpcModule) -> Result<BodyAuthServerHandle, RpcError> + where + RpcMiddleware: RethRpcMiddleware, + { + let Self { socket_addr, auth_config, server_config, rpc_middleware } = self; + + // Create signature-auth middleware. + let middleware = tower::ServiceBuilder::new().layer(SignatureAuthLayer::new(auth_config)); + + let rpc_middleware = RpcServiceBuilder::default().layer(rpc_middleware); + + // Disable WebSocket — the ops server is HTTP-only. The auth middleware + // inspects per-request HTTP bodies and would not re-run on individual + // WebSocket frames after upgrade, bypassing authorization. + let server = ServerBuilder::new() + .set_config(server_config.http_only().build()) + .set_http_middleware(middleware) + .set_rpc_middleware(rpc_middleware) + .build(socket_addr) + .await + .map_err(|err| RpcError::server_error(err, ServerKind::BodyAuth(socket_addr)))?; + + let local_addr = server + .local_addr() + .map_err(|err| RpcError::server_error(err, ServerKind::BodyAuth(socket_addr)))?; + + let handle = server.start(module.inner); + + Ok(BodyAuthServerHandle { handle: Some(handle), local_addr }) + } +} + +/// Builder type for configuring a [`BodyAuthServerConfig`]. +#[derive(Debug)] +pub struct BodyAuthServerConfigBuilder<RpcMiddleware = Identity> { + socket_addr: Option<SocketAddr>, + auth_config: SignatureAuthConfig, + server_config: Option<ServerConfigBuilder>, + rpc_middleware: RpcMiddleware, +} + +impl BodyAuthServerConfigBuilder { + /// Create a new builder with the given auth configuration. + pub fn new(auth_config: SignatureAuthConfig) -> Self { + Self { + socket_addr: None, + auth_config, + server_config: None, + rpc_middleware: Identity::new(), + } + } +} + +impl<RpcMiddleware> BodyAuthServerConfigBuilder<RpcMiddleware> { + /// Configures the rpc middleware. + pub fn with_rpc_middleware<T>(self, rpc_middleware: T) -> BodyAuthServerConfigBuilder<T> { + let Self { socket_addr, auth_config, server_config, .. } = self; + BodyAuthServerConfigBuilder { socket_addr, auth_config, server_config, rpc_middleware } + } + + /// Set the socket address for the server. + pub const fn socket_addr(mut self, socket_addr: SocketAddr) -> Self { + self.socket_addr = Some(socket_addr); + self + } + + /// Set the socket address for the server. + pub const fn maybe_socket_addr(mut self, socket_addr: Option<SocketAddr>) -> Self { + self.socket_addr = socket_addr; + self + } + + /// Configures the JSON-RPC server. + /// + /// Note: this always configures an [`EthSubscriptionIdProvider`] + /// [`IdProvider`](jsonrpsee::server::IdProvider) for convenience. + pub fn with_server_config(mut self, config: ServerConfigBuilder) -> Self { + self.server_config = Some(config.set_id_provider(EthSubscriptionIdProvider::default())); + self + } + + /// Build the [`BodyAuthServerConfig`]. + pub fn build(self) -> BodyAuthServerConfig<RpcMiddleware> { + BodyAuthServerConfig { + socket_addr: self.socket_addr.unwrap_or_else(|| { + SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), DEFAULT_BODY_AUTH_PORT) + }), + auth_config: self.auth_config, + server_config: self.server_config.unwrap_or_else(|| { + ServerConfig::builder() + .max_response_body_size(128 * 1024 * 1024) + .max_connections(100) + .max_request_body_size(16 * 1024 * 1024) + .set_id_provider(EthSubscriptionIdProvider::default()) + }), + rpc_middleware: self.rpc_middleware, + } + } +} + +/// Holds installed modules for the ops server. +#[derive(Debug, Clone)] +pub struct BodyAuthRpcModule { + pub(crate) inner: RpcModule<()>, +} + +impl BodyAuthRpcModule { + /// Create a new `BodyAuthRpcModule` from an `RpcModule`. + pub fn new(module: RpcModule<()>) -> Self { + Self { inner: module } + } + + /// Create an empty `BodyAuthRpcModule`. + pub fn empty() -> Self { + Self { inner: RpcModule::new(()) } + } + + /// Get a mutable reference to the inner `RpcModule`. + pub fn module_mut(&mut self) -> &mut RpcModule<()> { + &mut self.inner + } + + /// Merge the given [Methods] into the configured methods. + /// + /// Fails if any of the methods in other is present already. + pub fn merge_methods( + &mut self, + other: impl Into<Methods>, + ) -> Result<bool, RegisterMethodError> { + self.module_mut().merge(other.into()).map(|_| true) + } + + /// Removes the method with the given name. + /// + /// Returns `true` if the method was found and removed, `false` otherwise. + pub fn remove_method(&mut self, method_name: &'static str) -> bool { + self.module_mut().remove_method(method_name).is_some() + } + + /// Removes the given methods. + pub fn remove_methods(&mut self, methods: impl IntoIterator<Item = &'static str>) { + for name in methods { + self.remove_method(name); + } + } + + /// Replace the given [Methods] in the configured methods. + pub fn replace_methods( + &mut self, + other: impl Into<Methods>, + ) -> Result<bool, RegisterMethodError> { + let other = other.into(); + self.remove_methods(other.method_names()); + self.merge_methods(other) + } + + /// Convenience function for starting a server. + pub async fn start_server<RpcMiddleware: RethRpcMiddleware>( + self, + config: BodyAuthServerConfig<RpcMiddleware>, + ) -> Result<BodyAuthServerHandle, RpcError> { + config.start(self).await + } +} + +/// A handle to the spawned ops server. +/// +/// When this type is dropped or [`BodyAuthServerHandle::stop`] has been called the server will be +/// stopped. +#[derive(Clone, Debug)] +#[must_use = "Server stops if dropped"] +pub struct BodyAuthServerHandle { + local_addr: SocketAddr, + handle: Option<jsonrpsee::server::ServerHandle>, +} + +impl BodyAuthServerHandle { + /// Returns the [`SocketAddr`] of the server. + pub const fn local_addr(&self) -> SocketAddr { + self.local_addr + } + + /// Tell the server to stop without waiting for the server to stop. + pub fn stop(self) -> Result<(), AlreadyStoppedError> { + let Some(handle) = self.handle else { return Ok(()) }; + handle.stop() + } + + /// Returns the url to the http server. + pub fn http_url(&self) -> String { + format!("http://{}", self.local_addr) + } +}
diff --git reth/crates/rpc/rpc-builder/src/config.rs seismic-reth/crates/rpc/rpc-builder/src/config.rs index a8349a17524e1c24f8df08012539d95d09920589..b36bc28a4f08f302bd7697c2a42e98a28db29180 100644 --- reth/crates/rpc/rpc-builder/src/config.rs +++ seismic-reth/crates/rpc/rpc-builder/src/config.rs @@ -105,6 +105,7 @@ .gpo_config(self.gas_price_oracle_config()) .proof_permits(self.rpc_proof_permits) .pending_block_kind(self.rpc_pending_block) .raw_tx_forwarder(self.rpc_forwarder.clone()) + .enable_storage_apis(self.rpc_enable_storage_apis) }   fn flashbots_config(&self) -> ValidationApiConfig { @@ -269,6 +270,20 @@ assert_eq!(config.rpc_gas_cap, 1000);   let args = CommandParser::<RpcServerArgs>::try_parse_from(["reth", "--rpc.gascap", "0"]); assert!(args.is_err()); + } + + #[test] + fn test_rpc_enable_storage_apis() { + // Default: storage APIs disabled + let args = CommandParser::<RpcServerArgs>::parse_from(["reth"]).args; + let config = args.eth_config(); + assert!(!config.enable_storage_apis); + + // Enabled via flag + let args = + CommandParser::<RpcServerArgs>::parse_from(["reth", "--rpc.enable-storage-apis"]).args; + let config = args.eth_config(); + assert!(config.enable_storage_apis); }   #[test]
diff --git reth/crates/rpc/rpc-builder/src/error.rs seismic-reth/crates/rpc/rpc-builder/src/error.rs index cc55d232c9053dc1704a7fc2125d4e4b8d061dd6..926e0e9aecf94f4a0362254f3733ccb2f41a8c1a 100644 --- reth/crates/rpc/rpc-builder/src/error.rs +++ seismic-reth/crates/rpc/rpc-builder/src/error.rs @@ -17,6 +17,8 @@ /// WS and http on the same port WsHttp(SocketAddr), /// Auth. Auth(SocketAddr), + /// Body auth. + BodyAuth(SocketAddr), }   impl ServerKind { @@ -27,6 +29,7 @@ Self::Http(_) => "--http.port", Self::WS(_) => "--ws.port", Self::WsHttp(_) => "--ws.port and --http.port", Self::Auth(_) => "--authrpc.port", + Self::BodyAuth(_) => "--body-auth.port", } } } @@ -38,6 +41,7 @@ Self::Http(addr) => write!(f, "{addr} (HTTP-RPC server)"), Self::WS(addr) => write!(f, "{addr} (WS-RPC server)"), Self::WsHttp(addr) => write!(f, "{addr} (WS-HTTP-RPC server)"), Self::Auth(addr) => write!(f, "{addr} (AUTH server)"), + Self::BodyAuth(addr) => write!(f, "{addr} (BODY-AUTH server)"), } } } @@ -141,6 +145,7 @@ ServerKind::Http(addr), ServerKind::WS(addr), ServerKind::WsHttp(addr), ServerKind::Auth(addr), + ServerKind::BodyAuth(addr), ];   for kind in &kinds {
diff --git reth/crates/rpc/rpc-builder/src/lib.rs seismic-reth/crates/rpc/rpc-builder/src/lib.rs index 1f6b0d0380fa2b668eb74117dca291aa7d261bd1..d2457a86bd4427170415fa1ac32c6c153b5f5faf 100644 --- reth/crates/rpc/rpc-builder/src/lib.rs +++ seismic-reth/crates/rpc/rpc-builder/src/lib.rs @@ -14,7 +14,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -79,6 +79,9 @@ pub use tower::layer::util::{Identity, Stack};   /// Auth server utilities. pub mod auth; + +/// Body-auth server utilities for signature-based authentication. +pub mod body_auth;   /// RPC server utilities. pub mod config;
diff --git reth/crates/rpc/rpc-convert/Cargo.toml seismic-reth/crates/rpc/rpc-convert/Cargo.toml index abaf8d8d04b6110ac64514043b7cb3d449e737b0..7ccea0dba5320be30e0a76d93b37acd36aa4edb8 100644 --- reth/crates/rpc/rpc-convert/Cargo.toml +++ seismic-reth/crates/rpc/rpc-convert/Cargo.toml @@ -30,7 +30,9 @@ # optimism op-alloy-consensus = { workspace = true, optional = true } op-alloy-rpc-types = { workspace = true, optional = true } op-alloy-network = { workspace = true, optional = true } -reth-optimism-primitives = { workspace = true, optional = true } +# seismic: remove this dep to avoid pulling them optimism crates that don't compile implicitly by cargo/lsp/etc. +# The optimism crates don't compile because of type changes we made that affects them, such as FlaggedStorage. +# reth-optimism-primitives = { workspace = true, optional = true } op-revm = { workspace = true, optional = true }   # revm @@ -48,7 +50,9 @@ op = [ "dep:op-alloy-consensus", "dep:op-alloy-rpc-types", "dep:op-alloy-network", - "dep:reth-optimism-primitives", + # seismic: remove this dep to avoid pulling them optimism crates that don't compile implicitly by cargo/lsp/etc. + # The optimism crates don't compile because of type changes we made that affects them, such as FlaggedStorage. + # "dep:reth-optimism-primitives", "dep:reth-storage-api", "dep:op-revm", "reth-evm/op",
diff --git reth/crates/rpc/rpc-e2e-tests/src/lib.rs seismic-reth/crates/rpc/rpc-e2e-tests/src/lib.rs index c8c6dfe280edb1a01df3bd1971c54675bfbb5c3d..bdceb443f10341f799d7ab526ee4e368f08a8e23 100644 --- reth/crates/rpc/rpc-e2e-tests/src/lib.rs +++ seismic-reth/crates/rpc/rpc-e2e-tests/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/rpc/rpc-engine-api/src/lib.rs seismic-reth/crates/rpc/rpc-engine-api/src/lib.rs index 65088eac5af4a94e000f4d2c96b48e485723ecf4..f4e07b3f944d006f7670efcb67e49fd3021e70fa 100644 --- reth/crates/rpc/rpc-engine-api/src/lib.rs +++ seismic-reth/crates/rpc/rpc-engine-api/src/lib.rs @@ -4,7 +4,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/rpc/rpc-eth-api/Cargo.toml seismic-reth/crates/rpc/rpc-eth-api/Cargo.toml index 44637d1931c329f281744301250fcd7fdd2bc91f..448c281ddef4ed20643ab158065210cb4dd859bf 100644 --- reth/crates/rpc/rpc-eth-api/Cargo.toml +++ seismic-reth/crates/rpc/rpc-eth-api/Cargo.toml @@ -42,7 +42,7 @@ alloy-network.workspace = true alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true alloy-rpc-types-mev.workspace = true -alloy-consensus.workspace = true +alloy-consensus = { workspace = true, features = ["k256"] }   # rpc jsonrpsee = { workspace = true, features = ["server", "macros"] } @@ -60,6 +60,7 @@ dyn-clone.workspace = true tracing.workspace = true   [features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] js-tracer = ["revm-inspectors/js-tracer", "reth-rpc-eth-types/js-tracer"] client = ["jsonrpsee/client", "jsonrpsee/async-client"] op = [
diff --git reth/crates/rpc/rpc-eth-api/src/core.rs seismic-reth/crates/rpc/rpc-eth-api/src/core.rs index a4881abd394a74dd3443df54a54a38aa112a849c..70dda3ab0f2c6d15d4004916a90e3f532a89ff14 100644 --- reth/crates/rpc/rpc-eth-api/src/core.rs +++ seismic-reth/crates/rpc/rpc-eth-api/src/core.rs @@ -7,7 +7,7 @@ }; use alloy_dyn_abi::TypedData; use alloy_eips::{eip2930::AccessListResult, BlockId, BlockNumberOrTag}; use alloy_json_rpc::RpcObject; -use alloy_primitives::{Address, Bytes, B256, B64, U256, U64}; +use alloy_primitives::{Address, Bytes, FlaggedStorage, B256, B64, U256, U64}; use alloy_rpc_types_eth::{ simulate::{SimulatePayload, SimulatedBlock}, state::{EvmOverrides, StateOverride}, @@ -189,6 +189,18 @@ index: JsonStorageKey, block_number: Option<BlockId>, ) -> RpcResult<B256>;   + /// Returns the value from a storage position at a given address, including the `is_private` + /// flag. Returns `0x000...000` as the value and `true` for the `is_private` flag for + /// private storage slots. Returns the value and `false` for the `is_public` flag for public + /// storage slots. + #[method(name = "getFlaggedStorageAt")] + async fn flagged_storage_at( + &self, + address: Address, + index: JsonStorageKey, + block_number: Option<BlockId>, + ) -> RpcResult<FlaggedStorage>; + /// Returns the number of transactions sent from an address at given block number. #[method(name = "getTransactionCount")] async fn transaction_count( @@ -314,7 +326,7 @@ #[method(name = "hashrate")] async fn hashrate(&self) -> RpcResult<U256>;   /// Returns the hash of the current block, the seedHash, and the boundary condition to be met - /// (“target”) + /// (`target`) #[method(name = "getWork")] async fn get_work(&self) -> RpcResult<Work>;   @@ -622,6 +634,16 @@ trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getStorageAt"); Ok(EthState::storage_at(self, address, index, block_number).await?) }   + /// Handler for: `eth_getFlaggedStorageAt` + async fn flagged_storage_at( + &self, + address: Address, + index: JsonStorageKey, + block_number: Option<BlockId>, + ) -> RpcResult<FlaggedStorage> { + trace!(target: "rpc::eth", ?address, ?block_number, "Serving eth_getFlaggedStorageAt"); + Ok(EthState::flagged_storage_at(self, address, index, block_number).await?) + } /// Handler for: `eth_getTransactionCount` async fn transaction_count( &self,
diff --git reth/crates/rpc/rpc-eth-api/src/helpers/config.rs seismic-reth/crates/rpc/rpc-eth-api/src/helpers/config.rs index 3d65336cfff11783bd787e3b54fed2767fd01b60..a5ae5c749d40c68876aeba0a2ea31d9cc5976358 100644 --- reth/crates/rpc/rpc-eth-api/src/helpers/config.rs +++ seismic-reth/crates/rpc/rpc-eth-api/src/helpers/config.rs @@ -2,14 +2,15 @@ //! Loads chain configuration.   use alloy_consensus::{BlockHeader, Header}; use alloy_eips::eip7910::{EthConfig, EthForkConfig, SystemContract}; -use alloy_evm::precompiles::Precompile; use alloy_primitives::Address; use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use reth_chainspec::{ChainSpecProvider, EthChainSpec, EthereumHardforks, Hardforks, Head}; use reth_errors::{ProviderError, RethError}; -use reth_evm::{precompiles::PrecompilesMap, ConfigureEvm, Evm}; +use reth_evm::{ + precompiles::{Precompile, PrecompilesMap}, + ConfigureEvm, Evm, +}; use reth_node_api::NodePrimitives; -use reth_revm::db::EmptyDB; use reth_rpc_eth_types::EthApiError; use reth_storage_api::BlockReaderIdExt; use revm::precompile::PrecompileId; @@ -29,6 +30,7 @@ /// Ref: <https://eips.ethereum.org/EIPS/eip-7910> #[derive(Debug, Clone)] pub struct EthConfigHandler<Provider, Evm> { provider: Provider, + #[allow(unused)] evm_config: Evm, }   @@ -94,13 +96,17 @@ if !chain_spec.is_cancun_active_at_timestamp(latest.timestamp()) { return Err(RethError::msg("cancun has not been activated")) }   + /* let current_precompiles = evm_to_precompiles_map(self.evm_config.evm_for_block(EmptyDB::default(), &latest)); + */ + let current_precompiles = BTreeMap::new();   let mut fork_timestamps = chain_spec.forks_iter().filter_map(|(_, cond)| cond.as_timestamp()).collect::<Vec<_>>(); fork_timestamps.dedup();   + #[allow(unused_variables)] let (current_fork_idx, current_fork_timestamp) = fork_timestamps .iter() .position(|ts| &latest.timestamp < ts) @@ -113,6 +119,9 @@ let current = self .build_fork_config_at(current_fork_timestamp, current_precompiles) .ok_or_else(|| RethError::msg("no fork config for current fork"))?;   + let config = EthConfig { current, next: None, last: None }; + + /* let mut config = EthConfig { current, next: None, last: None };   if let Some(last_fork_idx) = current_fork_idx.checked_sub(1) { @@ -142,6 +151,7 @@ );   config.next = self.build_fork_config_at(next_fork_timestamp, next_precompiles); } + */   Ok(config) } @@ -159,6 +169,7 @@ Ok(self.config().map_err(EthApiError::from)?) } }   +#[allow(unused)] fn evm_to_precompiles_map( evm: impl Evm<Precompiles = PrecompilesMap>, ) -> BTreeMap<String, Address> {
diff --git reth/crates/rpc/rpc-eth-api/src/helpers/fee.rs seismic-reth/crates/rpc/rpc-eth-api/src/helpers/fee.rs index ae558d405598367290eafba8982334e0887c9812..729408cfe5ad205240ef654fea498906db40fd13 100644 --- reth/crates/rpc/rpc-eth-api/src/helpers/fee.rs +++ seismic-reth/crates/rpc/rpc-eth-api/src/helpers/fee.rs @@ -16,6 +16,8 @@ }; use reth_storage_api::{BlockIdReader, BlockReaderIdExt, HeaderProvider, ProviderHeader}; use tracing::debug;   +use reth_primitives_traits::BlockHeader as _; + /// Fee related functions for the [`EthApiServer`](crate::EthApiServer) trait in the /// `eth_` namespace. pub trait EthFees: @@ -161,7 +163,10 @@ // next block base_fee_per_gas.push( self.provider() .chain_spec() - .next_block_base_fee(&last_entry.header, last_entry.header.timestamp()) + .next_block_base_fee( + &last_entry.header, + last_entry.header.timestamp_seconds(), + ) .unwrap_or_default() as u128, );   @@ -181,7 +186,7 @@ base_fee_per_gas.push(header.base_fee_per_gas().unwrap_or_default() as u128); gas_used_ratio.push(header.gas_used() as f64 / header.gas_limit() as f64);   let blob_params = chain_spec - .blob_params_at_timestamp(header.timestamp()) + .blob_params_at_timestamp(header.timestamp_seconds()) .unwrap_or_else(BlobParams::cancun);   base_fee_per_blob_gas.push(header.blob_fee(blob_params).unwrap_or_default()); @@ -220,7 +225,7 @@ // The unwrap is safe since we checked earlier that we got at least 1 header. let last_header = headers.last().expect("is present"); base_fee_per_gas.push( chain_spec - .next_block_base_fee(last_header.header(), last_header.timestamp()) + .next_block_base_fee(last_header.header(), last_header.timestamp_seconds()) .unwrap_or_default() as u128, ); // Same goes for the `base_fee_per_blob_gas`: @@ -228,7 +233,7 @@ // > "[..] includes the next block after the newest of the returned range, because this value can be derived from the newest block. base_fee_per_blob_gas.push( last_header .maybe_next_block_blob_fee( - chain_spec.blob_params_at_timestamp(last_header.timestamp()) + chain_spec.blob_params_at_timestamp(last_header.timestamp_seconds()) ).unwrap_or_default() ); }; @@ -364,7 +369,9 @@ .latest_header() .map_err(Self::Error::from_eth_err)? .and_then(|h| { h.maybe_next_block_blob_fee( - self.provider().chain_spec().blob_params_at_timestamp(h.timestamp()), + self.provider() + .chain_spec() + .blob_params_at_timestamp(h.timestamp_seconds()), ) }) .ok_or(EthApiError::ExcessBlobGasNotSet.into())
diff --git reth/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs seismic-reth/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs index e1a9102cb209f7d369cfbf20a21c153018175f0c..7c3b6d1974d18552dfc97c22935379c11ace9063 100644 --- reth/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs +++ seismic-reth/crates/rpc/rpc-eth-api/src/helpers/pending_block.rs @@ -257,7 +257,7 @@ let blob_params = self .provider() .chain_spec() - .blob_params_at_timestamp(parent.timestamp()) + .blob_params_at_timestamp(parent.timestamp_seconds()) .unwrap_or_else(BlobParams::cancun); let mut cumulative_gas_used = 0; let mut sum_blob_gas_used = 0; @@ -416,8 +416,10 @@ }   impl<H: BlockHeader> BuildPendingEnv<H> for NextBlockEnvAttributes { fn build_pending_env(parent: &SealedHeader<H>) -> Self { + // NOTE: 12000 is block time in ms (MODIFIED) + let td = if cfg!(feature = "timestamp-in-seconds") { 12 } else { 12000 }; Self { - timestamp: parent.timestamp().saturating_add(12), + timestamp: parent.timestamp().saturating_add(td), suggested_fee_recipient: parent.beneficiary(), prev_randao: B256::random(), gas_limit: parent.gas_limit(),
diff --git reth/crates/rpc/rpc-eth-api/src/helpers/state.rs seismic-reth/crates/rpc/rpc-eth-api/src/helpers/state.rs index eab08450c81f9033794dd6736916ee78c75baf63..8a4d73c9c741cb624a859cdc0ee7c559a5ce24f3 100644 --- reth/crates/rpc/rpc-eth-api/src/helpers/state.rs +++ seismic-reth/crates/rpc/rpc-eth-api/src/helpers/state.rs @@ -5,7 +5,7 @@ use super::{EthApiSpec, LoadPendingBlock, SpawnBlocking}; use crate::{EthApiTypes, FromEthApiError, RpcNodeCore, RpcNodeCoreExt}; use alloy_consensus::constants::KECCAK_EMPTY; use alloy_eips::BlockId; -use alloy_primitives::{Address, Bytes, B256, U256}; +use alloy_primitives::{Address, Bytes, FlaggedStorage, B256, U256}; use alloy_rpc_types_eth::{Account, AccountInfo, EIP1186AccountProofResponse}; use alloy_serde::JsonStorageKey; use futures::Future; @@ -24,6 +24,10 @@ /// Helper methods for `eth_` methods relating to state (accounts). pub trait EthState: LoadState + SpawnBlocking { /// Returns the maximum number of blocks into the past for generating state proofs. fn max_proof_window(&self) -> u64; + + /// Returns whether storage APIs (eth_getStorageAt, eth_getFlaggedStorageAt) are enabled. + /// Disabled by default to protect private storage information. + fn storage_apis_enabled(&self) -> bool;   /// Returns the number of transactions sent from an address at the given block identifier. /// @@ -63,22 +67,72 @@ }) }   /// Returns values stored of given account, at given blocknumber. + /// + /// Returns an error if storage APIs are disabled (to protect private storage information). fn storage_at( &self, address: Address, index: JsonStorageKey, block_id: Option<BlockId>, ) -> impl Future<Output = Result<B256, Self::Error>> + Send { - self.spawn_blocking_io_fut(move |this| async move { - Ok(B256::new( - this.state_at_block_id_or_latest(block_id) + async move { + if !self.storage_apis_enabled() { + return Err(EthApiError::Unsupported( + "Storage APIs are disabled. Use --enable-storage-apis to enable.", + ) + .into()); + } + + self.spawn_blocking_io_fut(move |this| async move { + let storage_value = this + .state_at_block_id_or_latest(block_id) .await? .storage(address, index.as_b256()) .map_err(Self::Error::from_eth_err)? - .unwrap_or_default() - .to_be_bytes(), - )) - }) + .unwrap_or_default(); + match storage_value.is_public() { + true => Ok(B256::new(storage_value.value.to_be_bytes())), + false => Ok(B256::ZERO), + } + }) + .await + } + } + + /// Returns storage value with privacy flag at given address and block. + /// + /// Returns an error if storage APIs are disabled (to protect private storage information). + fn flagged_storage_at( + &self, + address: Address, + index: JsonStorageKey, + block_id: Option<BlockId>, + ) -> impl Future<Output = Result<FlaggedStorage, Self::Error>> + Send { + async move { + if !self.storage_apis_enabled() { + return Err(EthApiError::Unsupported( + "Storage APIs are disabled. Use --enable-storage-apis to enable.", + ) + .into()); + } + + self.spawn_blocking_io_fut(move |this| async move { + let storage_value = this + .state_at_block_id_or_latest(block_id) + .await? + .storage(address, index.as_b256()) + .map_err(Self::Error::from_eth_err)? + .unwrap_or_default(); + + match storage_value.is_public() { + true => Ok(FlaggedStorage::new(storage_value.value, false)), /* public storage */ + // value + false => Ok(FlaggedStorage::new(U256::ZERO, true)), /* return 0x000...000 for + * private storage value */ + } + }) + .await + } }   /// Returns values stored of given account, with Merkle-proof, at given blocknumber.
diff --git reth/crates/rpc/rpc-eth-api/src/lib.rs seismic-reth/crates/rpc/rpc-eth-api/src/lib.rs index a44c7600b9ddfc4b8f028a04e91e1f56cc89e214..a9b673e224717b78618bf56e85b9ff268590f550 100644 --- reth/crates/rpc/rpc-eth-api/src/lib.rs +++ seismic-reth/crates/rpc/rpc-eth-api/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/rpc/rpc-eth-types/Cargo.toml seismic-reth/crates/rpc/rpc-eth-types/Cargo.toml index cd173168b268069e89b553153b285a218544b57d..bc958e9352ee4b43ccc56d760cf3f1eac3495e99 100644 --- reth/crates/rpc/rpc-eth-types/Cargo.toml +++ seismic-reth/crates/rpc/rpc-eth-types/Cargo.toml @@ -12,6 +12,7 @@ [lints] workspace = true   [dependencies] +# reth reth-chainspec.workspace = true reth-chain-state.workspace = true reth-errors.workspace = true @@ -67,4 +68,5 @@ [dev-dependencies] serde_json.workspace = true   [features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] js-tracer = ["revm-inspectors/js-tracer"]
diff --git reth/crates/rpc/rpc-eth-types/src/builder/config.rs seismic-reth/crates/rpc/rpc-eth-types/src/builder/config.rs index d4c6cd95f68247562c700814f93a97153931f362..51ab4f806aa92e3239441e4885748bc99eb369be 100644 --- reth/crates/rpc/rpc-eth-types/src/builder/config.rs +++ seismic-reth/crates/rpc/rpc-eth-types/src/builder/config.rs @@ -60,6 +60,8 @@ /// Additional config values for the eth namespace. #[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)] pub struct EthConfig { + /// Whether to enable the storage APIs. + pub enable_storage_apis: bool, /// Settings for the caching layer pub cache: EthStateCacheConfig, /// Settings for the gas price oracle @@ -123,11 +125,18 @@ proof_permits: DEFAULT_PROOF_PERMITS, max_batch_size: 1, pending_block_kind: PendingBlockKind::Full, raw_tx_forwarder: ForwardConfig::default(), + enable_storage_apis: false, } } }   impl EthConfig { + /// Configures whether to enable the storage APIs. + pub const fn enable_storage_apis(mut self, enable_storage_apis: bool) -> Self { + self.enable_storage_apis = enable_storage_apis; + self + } + /// Configures the caching layer settings pub const fn state_cache(mut self, cache: EthStateCacheConfig) -> Self { self.cache = cache;
diff --git reth/crates/rpc/rpc-eth-types/src/cache/db.rs seismic-reth/crates/rpc/rpc-eth-types/src/cache/db.rs index abb8983485a313c6ad96df315243db7d2cdcd81c..87ebb6053a617a3e99e898302b4f537035c2376d 100644 --- reth/crates/rpc/rpc-eth-types/src/cache/db.rs +++ seismic-reth/crates/rpc/rpc-eth-types/src/cache/db.rs @@ -14,6 +14,8 @@ state::{AccountInfo, Bytecode}, Database, DatabaseCommit, };   +use revm::state::FlaggedStorage; + /// Helper alias type for the state's [`CacheDB`] pub type StateCacheDb<'a> = CacheDB<StateProviderDatabase<StateProviderTraitObjWrapper<'a>>>;   @@ -151,7 +153,7 @@ fn storage( &self, account: Address, storage_key: alloy_primitives::StorageKey, - ) -> reth_errors::ProviderResult<Option<alloy_primitives::StorageValue>> { + ) -> reth_errors::ProviderResult<Option<FlaggedStorage>> { self.0.storage(account, storage_key) }   @@ -200,7 +202,7 @@ fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> { self.0.code_by_hash(code_hash) }   - fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> { + fn storage(&mut self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> { self.0.storage(address, index) }   @@ -220,7 +222,7 @@ fn code_by_hash_ref(&self, code_hash: B256) -> Result<Bytecode, Self::Error> { self.0.code_by_hash_ref(code_hash) }   - fn storage_ref(&self, address: Address, index: U256) -> Result<U256, Self::Error> { + fn storage_ref(&self, address: Address, index: U256) -> Result<FlaggedStorage, Self::Error> { self.0.storage_ref(address, index) }
diff --git reth/crates/rpc/rpc-eth-types/src/error/mod.rs seismic-reth/crates/rpc/rpc-eth-types/src/error/mod.rs index c82fc93c67b5f2b9b809cb1746c9596f6d37e6f2..971fda9ff4f1f47a56751aad4cf6104e42fc752f 100644 --- reth/crates/rpc/rpc-eth-types/src/error/mod.rs +++ seismic-reth/crates/rpc/rpc-eth-types/src/error/mod.rs @@ -26,7 +26,6 @@ }; use revm_inspectors::tracing::MuxError; use std::convert::Infallible; use tokio::sync::oneshot::error::RecvError; -use tracing::error;   /// A trait to convert an error to an RPC error. pub trait ToRpcError: core::error::Error + Send + Sync + 'static { @@ -116,6 +115,9 @@ InvalidBlockData(#[from] BlockError), /// Thrown when an `AccountOverride` contains conflicting `state` and `stateDiff` fields #[error("account {0:?} has both 'state' and 'stateDiff'")] BothStateAndStateDiffInOverride(Address), + /// Code overrides are not permitted (Seismic privacy) + #[error("code overrides are not permitted on Seismic (account: {0:?})")] + CodeOverrideNotPermitted(Address), /// Other internal error #[error(transparent)] Internal(RethError), @@ -126,7 +128,7 @@ /// Thrown when a requested transaction is not found #[error("transaction not found")] TransactionNotFound, /// Some feature is unsupported - #[error("unsupported")] + #[error("unsupported: {0}")] Unsupported(&'static str), /// General purpose error for invalid params #[error("{0}")] @@ -255,6 +257,7 @@ EthApiError::ExceedsMaxProofWindow | EthApiError::ConflictingFeeFieldsInRequest | EthApiError::Signing(_) | EthApiError::BothStateAndStateDiffInOverride(_) | + EthApiError::CodeOverrideNotPermitted(_) | EthApiError::InvalidTracerConfig | EthApiError::TransactionConversionError | EthApiError::InvalidRewardPercentiles | @@ -350,6 +353,9 @@ } StateOverrideError::BothStateAndStateDiff(address) => { Self::BothStateAndStateDiffInOverride(address) } + StateOverrideError::CodeOverrideNotPermitted(address) => { + Self::CodeOverrideNotPermitted(address) + } StateOverrideError::Database(err) => err.into(), } } @@ -644,6 +650,9 @@ PriorityFeeBelowMinimum { /// Minimum required priority fee. minimum_priority_fee: u128, }, + /// Seismic transaction error + #[error("Seismic transaction error: {0}")] + SeismicTx(String), /// Any other error #[error("{0}")] Other(Box<dyn ToRpcError>), @@ -755,7 +764,7 @@ InvalidTransaction::MaxFeePerBlobGasNotSupported => Self::MaxFeePerBlobGasNotSupported, InvalidTransaction::BlobVersionedHashesNotSupported => { Self::BlobVersionedHashesNotSupported } - InvalidTransaction::BlobGasPriceGreaterThanMax => Self::BlobFeeCapTooLow, + InvalidTransaction::BlobGasPriceGreaterThanMax { .. } => Self::BlobFeeCapTooLow, InvalidTransaction::EmptyBlobs => Self::BlobTransactionMissingBlobHashes, InvalidTransaction::BlobVersionNotSupported => Self::BlobHashVersionMismatch, InvalidTransaction::TooManyBlobs { have, .. } => Self::TooManyBlobs { have }, @@ -797,7 +806,8 @@ InvalidTransactionError::ChainIdMismatch => Self::InvalidChainId, InvalidTransactionError::Eip2930Disabled | InvalidTransactionError::Eip1559Disabled | InvalidTransactionError::Eip4844Disabled | - InvalidTransactionError::Eip7702Disabled | + InvalidTransactionError::Eip7702Disabled => Self::TxTypeNotSupported, + InvalidTransactionError::SeismicTx(msg) => Self::SeismicTx(msg), InvalidTransactionError::TxTypeNotSupported => Self::TxTypeNotSupported, InvalidTransactionError::GasUintOverflow => Self::GasUintOverflow, InvalidTransactionError::GasTooLow => Self::GasTooLow,
diff --git reth/crates/rpc/rpc-eth-types/src/fee_history.rs seismic-reth/crates/rpc/rpc-eth-types/src/fee_history.rs index dd27fbfd103810d9fa306f9b1472894a97812a4f..63cf18ad4a9ca33e254f8684332b642e3c8062bb 100644 --- reth/crates/rpc/rpc-eth-types/src/fee_history.rs +++ seismic-reth/crates/rpc/rpc-eth-types/src/fee_history.rs @@ -89,7 +89,7 @@ // Insert all new blocks and calculate approximated rewards for (block, receipts) in blocks { let mut fee_history_entry = FeeHistoryEntry::<H>::new( block, - chain_spec.blob_params_at_timestamp(block.header().timestamp()), + chain_spec.blob_params_at_timestamp(block.timestamp_seconds()), ); fee_history_entry.rewards = calculate_reward_percentiles_for_block( &percentiles,
diff --git reth/crates/rpc/rpc-eth-types/src/lib.rs seismic-reth/crates/rpc/rpc-eth-types/src/lib.rs index 7e39eebbf98f60168464ded515e3e3eead9c85e7..c7a10270962545c0fcb53735ea90ae6e6178b75a 100644 --- reth/crates/rpc/rpc-eth-types/src/lib.rs +++ seismic-reth/crates/rpc/rpc-eth-types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/rpc/rpc-eth-types/src/receipt.rs seismic-reth/crates/rpc/rpc-eth-types/src/receipt.rs index 4ea4ad1daf569e0c4e75ee9ccca700a80183d7bd..731cdc62774f474684185fa28097ca0380d7f3c0 100644 --- reth/crates/rpc/rpc-eth-types/src/receipt.rs +++ seismic-reth/crates/rpc/rpc-eth-types/src/receipt.rs @@ -97,8 +97,13 @@ ) -> Result<Vec<Self::RpcReceipt>, Self::Error> { let mut receipts = Vec::with_capacity(inputs.len());   for input in inputs { + let timestamp_seconds = if cfg!(feature = "timestamp-in-seconds") { + input.meta.timestamp + } else { + input.meta.timestamp / 1000 + }; let tx_type = input.receipt.tx_type; - let blob_params = self.chain_spec.blob_params_at_timestamp(input.meta.timestamp); + let blob_params = self.chain_spec.blob_params_at_timestamp(timestamp_seconds); receipts.push(build_receipt(&input, blob_params, |receipt_with_bloom| { ReceiptEnvelope::from_typed(tx_type, receipt_with_bloom) }));
diff --git reth/crates/rpc/rpc-layer/Cargo.toml seismic-reth/crates/rpc/rpc-layer/Cargo.toml index 8d567fcf195a00a504372e6a6d9ea5c9ddcec5ef..c5d688a4796811f9d425e70ea4d6bcff3b4fe28e 100644 --- reth/crates/rpc/rpc-layer/Cargo.toml +++ seismic-reth/crates/rpc/rpc-layer/Cargo.toml @@ -11,17 +11,26 @@ [lints] workspace = true   [dependencies] +alloy-consensus.workspace = true +alloy-primitives.workspace = true alloy-rpc-types-engine = { workspace = true, features = ["jwt", "serde"] } +alloy-sol-types.workspace = true   http.workspace = true +http-body-util.workspace = true jsonrpsee-http-client.workspace = true pin-project.workspace = true +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true tower.workspace = true tower-http = { workspace = true, features = ["full"] } tracing.workspace = true   [dev-dependencies] +alloy-dyn-abi.workspace = true +alloy-signer.workspace = true +alloy-signer-local.workspace = true reqwest.workspace = true -tokio = { workspace = true, features = ["macros"] } +tokio = { workspace = true, features = ["macros", "time"] } jsonrpsee = { workspace = true, features = ["server"] } -http-body-util.workspace = true +reth-provider = { workspace = true, features = ["test-utils"] }
diff --git reth/crates/rpc/rpc-layer/src/lib.rs seismic-reth/crates/rpc/rpc-layer/src/lib.rs index 79a921145240a805e3aa80e922885c688dbd9bd6..e3de19621bf1309d694842449684ce73620f411c 100644 --- reth/crates/rpc/rpc-layer/src/lib.rs +++ seismic-reth/crates/rpc/rpc-layer/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] @@ -15,9 +15,16 @@ mod auth_client_layer; mod auth_layer; mod compression_layer; mod jwt_validator; +/// Single-signature authentication middleware using secp256k1 / Ethereum addresses. +pub mod signature_auth_layer;   pub use auth_layer::{AuthService, ResponseFuture}; pub use compression_layer::CompressionLayer; +pub use signature_auth_layer::{ + eip712_signing_hash, OpsWhitelistTxAuth, SignatureAuthConfig, SignatureAuthLayer, + SignatureAuthService, Whitelist, EIP712_DOMAIN_NAME, EIP712_DOMAIN_VERSION, NONCE_HEADER, + OPS_AUTH_CONTRACT, OPS_AUTH_SLOT, SIGNATURE_HEADER, WHITELIST_TX_SENTINEL, +};   // Export alloy JWT types pub use alloy_rpc_types_engine::{Claims, JwtError, JwtSecret};
diff --git reth/crates/rpc/rpc-layer/src/signature_auth_layer.rs seismic-reth/crates/rpc/rpc-layer/src/signature_auth_layer.rs new file mode 100644 index 0000000000000000000000000000000000000000..61a9990adb154897f70d83f9fdda36c5139faedf --- /dev/null +++ seismic-reth/crates/rpc/rpc-layer/src/signature_auth_layer.rs @@ -0,0 +1,362 @@ +use alloy_primitives::{address, Address, Signature, B256}; +use alloy_sol_types::{eip712_domain, sol, SolStruct}; +use http::{HeaderMap, Response, StatusCode}; +use http_body_util::BodyExt; +use jsonrpsee_http_client::{HttpBody, HttpRequest, HttpResponse}; +use serde::Deserialize; +use std::{ + collections::HashMap, + future::Future, + pin::Pin, + sync::{Arc, RwLock}, + task::{Context, Poll}, + time::{SystemTime, UNIX_EPOCH}, +}; +use tower::{Layer, Service}; + +// EIP-712 typed data definition for ops requests. +sol! { + #[derive(Debug)] + struct OpsRequest { + bytes body; + string nonce; + } + + interface OpsWhitelistTxAuth { + function whitelistKey(address target, uint64 expiresAt) external; + function revokeKey(address target) external; + } +} + +/// Header name for the hex-encoded secp256k1 signature. +pub const SIGNATURE_HEADER: &str = "X-Signature"; + +/// Header name for the nonce (replay protection). +pub const NONCE_HEADER: &str = "X-Nonce"; + +/// Sentinel address that ops governance transactions must target. +pub const WHITELIST_TX_SENTINEL: Address = address!("1000000000000000000000000000000000000006"); + +/// The Params contract address holding the authorized governance signer. +pub const OPS_AUTH_CONTRACT: Address = address!("0x0000000000000000000000000000506172616d73"); + +/// Storage slot 0 in the Params contract contains the admin address. +pub const OPS_AUTH_SLOT: B256 = B256::ZERO; + +/// Shared whitelist of temporarily authorized addresses with expiration times. +#[derive(Debug, Clone)] +pub struct Whitelist { + inner: Arc<RwLock<HashMap<Address, u64>>>, +} + +impl Whitelist { + /// Creates an empty whitelist. + pub fn new() -> Self { + Self { inner: Arc::new(RwLock::new(HashMap::new())) } + } + + /// Adds an address to the whitelist until the given Unix timestamp in seconds. + pub fn add(&self, address: Address, expires_at: u64) { + write_unpoisoned(&self.inner).insert(address, expires_at); + } + + /// Returns `true` if the address is whitelisted and not expired. + pub fn is_authorized(&self, address: &Address) -> bool { + let map = read_unpoisoned(&self.inner); + match map.get(address) { + Some(expiry) => current_unix_timestamp() < *expiry, + None => false, + } + } + + /// Removes an address from the whitelist. Returns `true` if it was present. + pub fn remove(&self, address: &Address) -> bool { + write_unpoisoned(&self.inner).remove(address).is_some() + } + + /// Removes expired entries. + pub fn evict_expired(&self) { + let now = current_unix_timestamp(); + write_unpoisoned(&self.inner).retain(|_, expiry| now < *expiry); + } +} + +impl Default for Whitelist { + fn default() -> Self { + Self::new() + } +} + +/// The EIP-712 domain name for ops requests. +pub const EIP712_DOMAIN_NAME: &str = "SeismicOps"; + +/// The EIP-712 domain version for ops requests. +pub const EIP712_DOMAIN_VERSION: &str = "1"; + +/// Configuration for the signature authentication layer. +/// +/// A shared whitelist holds temporarily authorized addresses for data endpoints. +/// Signatures use EIP-712 typed data with the `SeismicOps` domain. +#[derive(Debug, Clone)] +pub struct SignatureAuthConfig { + /// Shared whitelist of temporarily authorized addresses. + pub whitelist: Whitelist, + /// In-memory next expected nonce per whitelisted signer. + pub nonces: Arc<RwLock<HashMap<Address, u64>>>, + /// The chain ID for the EIP-712 domain separator. + pub chain_id: u64, +} + +impl SignatureAuthConfig { + /// Creates a new signature auth config. + pub fn new(whitelist: Whitelist, chain_id: u64) -> Self { + Self { whitelist, nonces: Arc::new(RwLock::new(HashMap::new())), chain_id } + } +} + +/// Compute the EIP-712 signing hash for an ops request. +pub fn eip712_signing_hash(body: &[u8], nonce: &str, chain_id: u64) -> B256 { + let domain = eip712_domain! { + name: EIP712_DOMAIN_NAME, + version: EIP712_DOMAIN_VERSION, + chain_id: chain_id, + }; + + let request = OpsRequest { body: body.to_vec().into(), nonce: nonce.to_string() }; + + request.eip712_signing_hash(&domain) +} + +/// Tower layer for ops authentication using EIP-712 request signatures. +/// +/// `ops_getStorageAt` and `ops_getNonce` use `X-Signature`. +/// `ops_getStorageAt` also requires `X-Nonce`. +#[expect(missing_debug_implementations)] +pub struct SignatureAuthLayer { + config: SignatureAuthConfig, +} + +impl SignatureAuthLayer { + /// Creates a new signature auth layer. + pub const fn new(config: SignatureAuthConfig) -> Self { + Self { config } + } +} + +impl<Svc> Layer<Svc> for SignatureAuthLayer { + type Service = SignatureAuthService<Svc>; + + fn layer(&self, inner: Svc) -> Self::Service { + SignatureAuthService { config: self.config.clone(), inner } + } +} + +/// Tower service that implements single-signature authentication. +/// +/// See [`SignatureAuthLayer`] for details. +#[derive(Clone)] +#[expect(missing_debug_implementations)] +pub struct SignatureAuthService<Svc> { + config: SignatureAuthConfig, + inner: Svc, +} + +impl<Svc> Service<HttpRequest> for SignatureAuthService<Svc> +where + Svc: Service<HttpRequest, Response = HttpResponse> + Clone + Send + 'static, + Svc::Future: Send + 'static, + Svc::Error: Send, +{ + type Response = HttpResponse; + type Error = Svc::Error; + type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>; + + fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, req: HttpRequest) -> Self::Future { + let mut inner = self.inner.clone(); + let config = self.config.clone(); + + Box::pin(async move { + // Collect the body. + let (parts, body) = req.into_parts(); + let body_bytes = match body.collect().await { + Ok(collected) => collected.to_bytes(), + Err(_) => { + return Ok(error_response( + StatusCode::BAD_REQUEST, + "Failed to read request body", + )) + } + }; + + // Parse the method name from the JSON body to avoid substring-matching + // bypasses via Unicode escapes (e.g. \u006f for 'o'). + let method = serde_json::from_slice::<RpcRequest>(&body_bytes) + .map(|r| r.method) + .unwrap_or_default(); + + let needs_nonce = method == "ops_getStorageAt"; + let is_get_nonce_method = method == "ops_getNonce"; + let nonce = if needs_nonce { + match extract_header(&parts.headers, NONCE_HEADER) { + Some(n) => Some(n.to_string()), + None => { + return Ok(error_response(StatusCode::BAD_REQUEST, "Missing X-Nonce header")) + } + } + } else { + None + }; + + // All remaining ops methods use EIP-712 signature auth. + let sig_hex = match extract_header(&parts.headers, SIGNATURE_HEADER) { + Some(s) => s.to_string(), + None => { + return Ok(error_response(StatusCode::BAD_REQUEST, "Missing X-Signature header")) + } + }; + + // Compute the EIP-712 signing hash. + let signing_nonce = nonce.as_deref().unwrap_or(""); + let hash = eip712_signing_hash(&body_bytes, signing_nonce, config.chain_id); + + // Parse the signature. + let sig_hex = sig_hex.strip_prefix("0x").unwrap_or(&sig_hex); + let sig_bytes = match alloy_primitives::hex::decode(sig_hex) { + Ok(b) => b, + Err(e) => { + return Ok(error_response( + StatusCode::BAD_REQUEST, + &format!("Invalid signature hex: {e}"), + )) + } + }; + + let signature = match Signature::try_from(sig_bytes.as_slice()) { + Ok(s) => s, + Err(e) => { + return Ok(error_response( + StatusCode::BAD_REQUEST, + &format!("Invalid signature: {e}"), + )) + } + }; + + // Recover the signer address. + let recovered_address = + match alloy_consensus::crypto::secp256k1::recover_signer(&signature, hash) { + Ok(addr) => addr, + Err(_) => { + return Ok(error_response( + StatusCode::UNAUTHORIZED, + "Signature recovery failed", + )) + } + }; + + if is_get_nonce_method { + config.whitelist.evict_expired(); + if !config.whitelist.is_authorized(&recovered_address) { + return Ok(error_response(StatusCode::UNAUTHORIZED, "Key not whitelisted")); + } + + let requested_address = match requested_nonce_address(&body_bytes) { + Ok(address) => address, + Err(err) => return Ok(error_response(StatusCode::BAD_REQUEST, &err)), + }; + + if requested_address != recovered_address { + return Ok(error_response( + StatusCode::UNAUTHORIZED, + "Can only query your own nonce", + )); + } + } else if needs_nonce { + // ops_getStorageAt: require whitelisted address. + config.whitelist.evict_expired(); + if !config.whitelist.is_authorized(&recovered_address) { + return Ok(error_response(StatusCode::UNAUTHORIZED, "Key not whitelisted")); + } + } else { + return Ok(error_response( + StatusCode::BAD_REQUEST, + "Unknown or unsupported ops method", + )); + } + + if needs_nonce { + let nonce = nonce.expect("nonce is required when needs_nonce is true"); + let nonce_value = match nonce.parse::<u64>() { + Ok(value) => value, + Err(_) => { + return Ok(error_response( + StatusCode::BAD_REQUEST, + "Nonce must be a valid u64", + )) + } + }; + + let mut nonces = write_unpoisoned(&config.nonces); + let expected = nonces.get(&recovered_address).copied().unwrap_or(0); + if nonce_value != expected { + return Ok(error_response( + StatusCode::UNAUTHORIZED, + &format!("Invalid nonce: expected {expected}"), + )); + } + nonces.insert(recovered_address, expected + 1); + } + + // Forward the request. + let new_body = HttpBody::from(body_bytes.to_vec()); + let new_req = HttpRequest::from_parts(parts, new_body); + inner.call(new_req).await + }) + } +} + +fn requested_nonce_address(body: &[u8]) -> Result<Address, String> { + let request: RpcRequest = serde_json::from_slice(body).map_err(|e| e.to_string())?; + if request.method != "ops_getNonce" { + return Err("Expected ops_getNonce request".to_string()); + } + parse_address_param(request.params.first(), "address") +} + +fn extract_header<'a>(headers: &'a HeaderMap, name: &str) -> Option<&'a str> { + headers.get(name).and_then(|v| v.to_str().ok()) +} + +fn error_response(status: StatusCode, message: &str) -> HttpResponse { + Response::builder() + .status(status) + .body(HttpBody::new(message.to_string())) + .expect("building error response should not fail") +} + +fn current_unix_timestamp() -> u64 { + SystemTime::now().duration_since(UNIX_EPOCH).expect("system clock before unix epoch").as_secs() +} + +fn read_unpoisoned<T>(lock: &RwLock<T>) -> std::sync::RwLockReadGuard<'_, T> { + lock.read().unwrap_or_else(|err| err.into_inner()) +} + +fn write_unpoisoned<T>(lock: &RwLock<T>) -> std::sync::RwLockWriteGuard<'_, T> { + lock.write().unwrap_or_else(|err| err.into_inner()) +} + +#[derive(Deserialize)] +struct RpcRequest { + method: String, + params: Vec<serde_json::Value>, +} + +fn parse_address_param(value: Option<&serde_json::Value>, field: &str) -> Result<Address, String> { + let value = value.ok_or_else(|| format!("Missing {field}"))?; + let addr = value.as_str().ok_or_else(|| format!("Invalid {field}"))?; + addr.parse::<Address>().map_err(|e| e.to_string()) +}
diff --git reth/crates/rpc/rpc-server-types/src/lib.rs seismic-reth/crates/rpc/rpc-server-types/src/lib.rs index c20b578816b82d6d09cad98f81df419c5a162138..61ec798a98732d45d680dfd5eadb4d2dc931985b 100644 --- reth/crates/rpc/rpc-server-types/src/lib.rs +++ seismic-reth/crates/rpc/rpc-server-types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/rpc/rpc-testing-util/src/lib.rs seismic-reth/crates/rpc/rpc-testing-util/src/lib.rs index ebf5090b715db885145bf1a58b5101ac3ed0e170..db9d8ac1f89056dd0812f9ad1208f96dc6d67f0d 100644 --- reth/crates/rpc/rpc-testing-util/src/lib.rs +++ seismic-reth/crates/rpc/rpc-testing-util/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/rpc/rpc/Cargo.toml seismic-reth/crates/rpc/rpc/Cargo.toml index 235fdd93643d5f8c26a3ad8d0e510fbe6a1b6028..dec939d756f79f06046c8b324806d0e6f40d2655 100644 --- reth/crates/rpc/rpc/Cargo.toml +++ seismic-reth/crates/rpc/rpc/Cargo.toml @@ -105,4 +105,5 @@ jsonrpsee = { workspace = true, features = ["client"] }   [features] +timestamp-in-seconds = ["revm/timestamp-in-seconds"] js-tracer = ["revm-inspectors/js-tracer", "reth-rpc-eth-types/js-tracer"]
diff --git reth/crates/rpc/rpc/src/debug.rs seismic-reth/crates/rpc/rpc/src/debug.rs index 43c6422605c8735bdab156469e4bf877b5d184c8..ad7ebbfa7f0fc482f24e119f5d6e87beaafa0a31 100644 --- reth/crates/rpc/rpc/src/debug.rs +++ seismic-reth/crates/rpc/rpc/src/debug.rs @@ -40,6 +40,7 @@ use reth_tasks::pool::BlockingTaskGuard; use reth_trie_common::{updates::TrieUpdates, HashedPostState}; use revm::{context_interface::Transaction, state::EvmState, DatabaseCommit}; use revm_inspectors::tracing::{ + trace_sanitizer::{sanitize_geth_trace, sanitize_trace_results_vec}, FourByteInspector, MuxInspector, TracingInspector, TracingInspectorConfig, TransactionContext, }; use std::sync::Arc; @@ -269,8 +270,9 @@ block_id: Option<BlockId>, opts: GethDebugTracingCallOptions, ) -> Result<GethTrace, Eth::Error> { let at = block_id.unwrap_or_default(); - let GethDebugTracingCallOptions { tracing_options, state_overrides, block_overrides } = - opts; + let GethDebugTracingCallOptions { + tracing_options, state_overrides, block_overrides, .. + } = opts; let overrides = EvmOverrides::new(state_overrides, block_overrides.map(Box::new)); let GethDebugTracingOptions { config, tracer, tracer_config, .. } = tracing_options;   @@ -451,7 +453,7 @@ // Note: this match is non-exhaustive in case we need to add support for // additional tracers Err(EthApiError::Unsupported("unsupported tracer").into()) } - } + }; }   // default structlog tracer @@ -487,7 +489,7 @@ state_context: Option<StateContext>, opts: Option<GethDebugTracingCallOptions>, ) -> Result<Vec<Vec<GethTrace>>, Eth::Error> { if bundles.is_empty() { - return Err(EthApiError::InvalidParams(String::from("bundles are empty.")).into()) + return Err(EthApiError::InvalidParams(String::from("bundles are empty.")).into()); }   let StateContext { transaction_index, block_number } = state_context.unwrap_or_default(); @@ -745,7 +747,7 @@ GethDebugTracerType::BuiltInTracer(tracer) => match tracer { GethDebugBuiltInTracerType::FourByteTracer => { let mut inspector = FourByteInspector::default(); let res = self.eth_api().inspect(db, evm_env, tx_env, &mut inspector)?; - return Ok((FourByteFrame::from(&inspector).into(), res.state)) + return Ok((FourByteFrame::from(&inspector).into(), res.state)); } GethDebugBuiltInTracerType::CallTracer => { let call_config = tracer_config @@ -768,7 +770,7 @@ let frame = inspector .geth_builder() .geth_call_traces(call_config, res.result.gas_used());   - return Ok((frame.into(), res.state)) + return Ok((frame.into(), res.state)); } GethDebugBuiltInTracerType::PreStateTracer => { let prestate_config = tracer_config @@ -791,7 +793,7 @@ .geth_builder() .geth_prestate_traces(&res, &prestate_config, db) .map_err(Eth::Error::from_eth_err)?;   - return Ok((frame.into(), res.state)) + return Ok((frame.into(), res.state)); } GethDebugBuiltInTracerType::NoopTracer => { Ok((NoopFrame::default().into(), Default::default())) @@ -810,7 +812,7 @@ self.eth_api().inspect(&mut *db, evm_env, tx_env, &mut inspector)?; let frame = inspector .try_into_mux_frame(&res, db, tx_info) .map_err(Eth::Error::from_eth_err)?; - return Ok((frame.into(), res.state)) + return Ok((frame.into(), res.state)); } GethDebugBuiltInTracerType::FlatCallTracer => { let flat_call_config = tracer_config @@ -864,7 +866,7 @@ // Note: this match is non-exhaustive in case we need to add support for // additional tracers Err(EthApiError::Unsupported("unsupported tracer").into()) } - } + }; }   // default structlog tracer @@ -902,6 +904,11 @@ .await } }   +// Seismic: every handler that returns trace data calls a `sanitize_*` function from +// `revm_inspectors::tracing::trace_sanitizer` before returning to the caller. This strips +// calldata, return data, stack, memory, VM trace payloads, and function selectors. +// Storage filtering is handled separately in the trace builders via `filter_private_storage`. +// See the seismic-revm-inspectors README for the full architecture. #[async_trait] impl<Eth> DebugApiServer<RpcTxReq<Eth::NetworkTypes>> for DebugApi<Eth> where @@ -998,6 +1005,7 @@ ) -> RpcResult<Vec<TraceResult>> { let _permit = self.acquire_trace_permit().await; Self::debug_trace_raw_block(self, rlp_block, opts.unwrap_or_default()) .await + .map(|results| sanitize_trace_results_vec(results)) .map_err(Into::into) }   @@ -1010,6 +1018,7 @@ ) -> RpcResult<Vec<TraceResult>> { let _permit = self.acquire_trace_permit().await; Self::debug_trace_block(self, block.into(), opts.unwrap_or_default()) .await + .map(|results| sanitize_trace_results_vec(results)) .map_err(Into::into) }   @@ -1022,6 +1031,7 @@ ) -> RpcResult<Vec<TraceResult>> { let _permit = self.acquire_trace_permit().await; Self::debug_trace_block(self, block.into(), opts.unwrap_or_default()) .await + .map(|results| sanitize_trace_results_vec(results)) .map_err(Into::into) }   @@ -1034,6 +1044,7 @@ ) -> RpcResult<GethTrace> { let _permit = self.acquire_trace_permit().await; Self::debug_trace_transaction(self, tx_hash, opts.unwrap_or_default()) .await + .map(sanitize_geth_trace) .map_err(Into::into) }   @@ -1047,6 +1058,7 @@ ) -> RpcResult<GethTrace> { let _permit = self.acquire_trace_permit().await; Self::debug_trace_call(self, request, block_id, opts.unwrap_or_default()) .await + .map(sanitize_geth_trace) .map_err(Into::into) }   @@ -1057,7 +1069,15 @@ state_context: Option<StateContext>, opts: Option<GethDebugTracingCallOptions>, ) -> RpcResult<Vec<Vec<GethTrace>>> { let _permit = self.acquire_trace_permit().await; - Self::debug_trace_call_many(self, bundles, state_context, opts).await.map_err(Into::into) + Self::debug_trace_call_many(self, bundles, state_context, opts) + .await + .map(|bundles| { + bundles + .into_iter() + .map(|traces| traces.into_iter().map(sanitize_geth_trace).collect()) + .collect() + }) + .map_err(Into::into) }   /// Handler for `debug_executionWitness`
diff --git reth/crates/rpc/rpc/src/engine.rs seismic-reth/crates/rpc/rpc/src/engine.rs index a0e0bd30931ce018d163afad6bcf8cc3e9102caa..ee70062ff25aee9ac3a4441d3266e65452f56467 100644 --- reth/crates/rpc/rpc/src/engine.rs +++ seismic-reth/crates/rpc/rpc/src/engine.rs @@ -7,12 +7,12 @@ use alloy_serde::JsonStorageKey; use jsonrpsee::core::RpcResult as Result; use reth_rpc_api::{EngineEthApiServer, EthApiServer}; use reth_rpc_convert::RpcTxReq; -/// Re-export for convenience -pub use reth_rpc_engine_api::EngineApi; use reth_rpc_eth_api::{ EngineEthFilter, FullEthApiTypes, QueryLimits, RpcBlock, RpcHeader, RpcReceipt, RpcTransaction, }; use tracing_futures::Instrument; + +pub use reth_rpc_engine_api::EngineApi;   macro_rules! engine_span { () => { @@ -118,8 +118,8 @@ self.eth.block_receipts(block_id).instrument(engine_span!()).await }   /// Handler for: `eth_sendRawTransaction` - async fn send_raw_transaction(&self, bytes: Bytes) -> Result<B256> { - self.eth.send_raw_transaction(bytes).instrument(engine_span!()).await + async fn send_raw_transaction(&self, tx: Bytes) -> Result<B256> { + self.eth.send_raw_transaction(tx).instrument(engine_span!()).await }   async fn transaction_receipt(
diff --git reth/crates/rpc/rpc/src/eth/builder.rs seismic-reth/crates/rpc/rpc/src/eth/builder.rs index 5ad836e84472750d81feaed1feae412e4fcf3074..ec772a3258990e47ed44fea12d483c48de2171db 100644 --- reth/crates/rpc/rpc/src/eth/builder.rs +++ seismic-reth/crates/rpc/rpc/src/eth/builder.rs @@ -28,6 +28,7 @@ #[derive(Debug)] pub struct EthApiBuilder<N: RpcNodeCore, Rpc, NextEnv = ()> { components: N, rpc_converter: Rpc, + enable_storage_apis: bool, gas_cap: GasCap, max_simulate_blocks: u64, eth_proof_window: u64, @@ -84,6 +85,7 @@ next_env, max_batch_size, pending_block_kind, raw_tx_forwarder, + enable_storage_apis, } = self; EthApiBuilder { components, @@ -103,6 +105,7 @@ next_env, max_batch_size, pending_block_kind, raw_tx_forwarder, + enable_storage_apis, } } } @@ -133,6 +136,7 @@ next_env: Default::default(), max_batch_size: 1, pending_block_kind: PendingBlockKind::Full, raw_tx_forwarder: ForwardConfig::default(), + enable_storage_apis: false, } } } @@ -170,6 +174,7 @@ next_env, max_batch_size, pending_block_kind, raw_tx_forwarder, + enable_storage_apis, } = self; EthApiBuilder { components, @@ -189,6 +194,7 @@ next_env, max_batch_size, pending_block_kind, raw_tx_forwarder, + enable_storage_apis, } }   @@ -215,6 +221,7 @@ next_env: _, max_batch_size, pending_block_kind, raw_tx_forwarder, + enable_storage_apis, } = self; EthApiBuilder { components, @@ -234,6 +241,7 @@ next_env, max_batch_size, pending_block_kind, raw_tx_forwarder, + enable_storage_apis, } }   @@ -323,6 +331,13 @@ self.raw_tx_forwarder = tx_forwarder; self }   + /// Enables or disables storage APIs (eth_getStorageAt, eth_getFlaggedStorageAt). + /// Disabled by default to protect private storage information. + pub const fn enable_storage_apis(mut self, enable: bool) -> Self { + self.enable_storage_apis = enable; + self + } + /// Builds the [`EthApiInner`] instance. /// /// If not configured, this will spawn the cache backend: [`EthStateCache::spawn`]. @@ -354,6 +369,7 @@ next_env, max_batch_size, pending_block_kind, raw_tx_forwarder, + enable_storage_apis, } = self;   let provider = components.provider().clone(); @@ -393,6 +409,7 @@ next_env, max_batch_size, pending_block_kind, raw_tx_forwarder.forwarder_client(), + enable_storage_apis, ) }
diff --git reth/crates/rpc/rpc/src/eth/bundle.rs seismic-reth/crates/rpc/rpc/src/eth/bundle.rs index 0ff7fb1dde466c9427375bcef70c3e4dfa739abf..d98f773ac2f63c8c25c8127c992058bfd3dfbbf9 100644 --- reth/crates/rpc/rpc/src/eth/bundle.rs +++ seismic-reth/crates/rpc/rpc/src/eth/bundle.rs @@ -2,7 +2,7 @@ //! `Eth` bundle implementation and helpers.   use alloy_consensus::{EnvKzgSettings, Transaction as _}; use alloy_eips::eip7840::BlobParams; -use alloy_primitives::{uint, Keccak256, U256}; +use alloy_primitives::{Keccak256, U256}; use alloy_rpc_types_mev::{EthCallBundle, EthCallBundleResponse, EthCallBundleTransactionResult}; use jsonrpsee::core::RpcResult; use reth_chainspec::{ChainSpecProvider, EthChainSpec}; @@ -95,7 +95,8 @@ // need to adjust the timestamp for the next block if let Some(timestamp) = timestamp { evm_env.block_env.timestamp = U256::from(timestamp); } else { - evm_env.block_env.timestamp += uint!(12_U256); + let increment: u64 = if cfg!(feature = "timestamp-in-seconds") { 12 } else { 12000 }; + evm_env.block_env.timestamp += U256::from(increment); }   if let Some(difficulty) = difficulty { @@ -110,7 +111,11 @@ let blob_params = self .eth_api() .provider() .chain_spec() - .blob_params_at_timestamp(evm_env.block_env.timestamp.saturating_to()) + .blob_params_at_timestamp(if cfg!(feature = "timestamp-in-seconds") { + evm_env.block_env.timestamp.saturating_to() + } else { + (evm_env.block_env.timestamp / U256::from(1000)).saturating_to() + }) .unwrap_or_else(BlobParams::cancun); if transactions.iter().filter_map(|tx| tx.blob_gas_used()).sum::<u64>() > blob_params.max_blob_gas_per_block()
diff --git reth/crates/rpc/rpc/src/eth/core.rs seismic-reth/crates/rpc/rpc/src/eth/core.rs index 1e8e99013af8b8ea55c7bd44b6cd9b18a801caa0..ac10768c4ab89c6250ae12f461c9dfb1989b2e77 100644 --- reth/crates/rpc/rpc/src/eth/core.rs +++ seismic-reth/crates/rpc/rpc/src/eth/core.rs @@ -154,6 +154,7 @@ rpc_converter: Rpc, max_batch_size: usize, pending_block_kind: PendingBlockKind, raw_tx_forwarder: ForwardConfig, + enable_storage_apis: bool, ) -> Self { let inner = EthApiInner::new( components, @@ -171,6 +172,7 @@ (), max_batch_size, pending_block_kind, raw_tx_forwarder.forwarder_client(), + enable_storage_apis, );   Self { inner: Arc::new(inner) } @@ -310,6 +312,10 @@ mpsc::UnboundedSender<BatchTxRequest<<N::Pool as TransactionPool>::Transaction>>,   /// Configuration for pending block construction. pending_block_kind: PendingBlockKind, + + /// Whether storage APIs (eth_getStorageAt, eth_getFlaggedStorageAt) are enabled. + /// Disabled by default to protect private storage information. + enable_storage_apis: bool, }   impl<N, Rpc> EthApiInner<N, Rpc> @@ -335,6 +341,7 @@ next_env: impl PendingEnvBuilder<N::Evm>, max_batch_size: usize, pending_block_kind: PendingBlockKind, raw_tx_forwarder: Option<RpcClient>, + enable_storage_apis: bool, ) -> Self { let signers = parking_lot::RwLock::new(Default::default()); // get the block number of the latest block @@ -375,6 +382,7 @@ tx_resp_builder, next_env_builder: Box::new(next_env), tx_batch_sender, pending_block_kind, + enable_storage_apis, } } } @@ -485,6 +493,12 @@ /// The maximum number of blocks into the past for generating state proofs. #[inline] pub const fn eth_proof_window(&self) -> u64 { self.eth_proof_window + } + + /// Returns whether storage APIs (eth_getStorageAt, eth_getFlaggedStorageAt) are enabled. + #[inline] + pub const fn storage_apis_enabled(&self) -> bool { + self.enable_storage_apis }   /// Returns reference to [`BlockingTaskGuard`].
diff --git reth/crates/rpc/rpc/src/eth/helpers/state.rs seismic-reth/crates/rpc/rpc/src/eth/helpers/state.rs index 3d9cc76309762e88af4846129d69013fd311ce31..527bf095e6b7509951cce356b1c43135d73f89b9 100644 --- reth/crates/rpc/rpc/src/eth/helpers/state.rs +++ seismic-reth/crates/rpc/rpc/src/eth/helpers/state.rs @@ -16,6 +16,10 @@ { fn max_proof_window(&self) -> u64 { self.inner.eth_proof_window() } + + fn storage_apis_enabled(&self) -> bool { + self.inner.storage_apis_enabled() + } }   impl<N, Rpc> LoadState for EthApi<N, Rpc> @@ -31,7 +35,7 @@ mod tests { use crate::eth::helpers::types::EthRpcConverter;   use super::*; - use alloy_primitives::{Address, StorageKey, StorageValue, U256}; + use alloy_primitives::{Address, StorageKey, U256}; use reth_chainspec::ChainSpec; use reth_evm_ethereum::EthEvmConfig; use reth_network_api::noop::NoopNetwork; @@ -43,6 +47,8 @@ use reth_rpc_eth_api::{helpers::EthState, node::RpcNodeCoreAdapter}; use reth_transaction_pool::test_utils::{testing_pool, TestPool}; use std::collections::HashMap;   + use revm::state::FlaggedStorage; + fn noop_eth_api() -> EthApi< RpcNodeCoreAdapter<NoopProvider, TestPool, NoopNetwork, EthEvmConfig>, EthRpcConverter<ChainSpec>, @@ -51,7 +57,9 @@ let provider = NoopProvider::default(); let pool = testing_pool(); let evm_config = EthEvmConfig::mainnet();   - EthApi::builder(provider, pool, NoopNetwork::default(), evm_config).build() + EthApi::builder(provider, pool, NoopNetwork::default(), evm_config) + .enable_storage_apis(true) // Enable storage APIs for tests + .build() }   fn mock_eth_api( @@ -66,7 +74,9 @@ let evm_config = EthEvmConfig::new(mock_provider.chain_spec()); mock_provider.extend_accounts(accounts);   - EthApi::builder(mock_provider, pool, NoopNetwork::default(), evm_config).build() + EthApi::builder(mock_provider, pool, NoopNetwork::default(), evm_config) + .enable_storage_apis(true) // Enable storage APIs for tests + .build() }   #[tokio::test] @@ -78,7 +88,7 @@ let storage = eth_api.storage_at(address, U256::ZERO.into(), None).await.unwrap(); assert_eq!(storage, U256::ZERO.to_be_bytes());   // === Mock === - let storage_value = StorageValue::from(1337); + let storage_value = FlaggedStorage::public(1337); let storage_key = StorageKey::random(); let storage = HashMap::from([(storage_key, storage_value)]);   @@ -88,7 +98,54 @@ let eth_api = mock_eth_api(accounts);   let storage_key: U256 = storage_key.into(); let storage = eth_api.storage_at(address, storage_key.into(), None).await.unwrap(); - assert_eq!(storage, storage_value.to_be_bytes()); + assert_eq!(storage, storage_value.value.to_be_bytes()); + } + + #[tokio::test] + async fn test_flagged_storage() { + // Noop - should return zero value with is_private = false + let eth_api = noop_eth_api(); + let address = Address::random(); + let result = eth_api.flagged_storage_at(address, U256::ZERO.into(), None).await.unwrap(); + assert_eq!(result.value, U256::ZERO); + assert!(!result.is_private); + + // Mock with public storage + let public_storage_value = FlaggedStorage::new(U256::from(1337), false); + let storage_key = StorageKey::random(); + let storage = HashMap::from([(storage_key, public_storage_value)]); + + let accounts = + HashMap::from([(address, ExtendedAccount::new(0, U256::ZERO).extend_storage(storage))]); + let eth_api = mock_eth_api(accounts); + + let storage_key_u256: U256 = storage_key.into(); + let result = + eth_api.flagged_storage_at(address, storage_key_u256.into(), None).await.unwrap(); + + // Public storage should return the actual value with is_private = false + assert_eq!(result.value, public_storage_value.value); + assert!(!result.is_private); + + // Mock with private storage + let address2 = Address::random(); + let private_storage_value = FlaggedStorage::new(U256::from(9999), true); + let storage_key2 = StorageKey::random(); + let storage2 = HashMap::from([(storage_key2, private_storage_value)]); + + let accounts2 = HashMap::from([( + address2, + ExtendedAccount::new(0, U256::ZERO).extend_storage(storage2), + )]); + let eth_api2 = mock_eth_api(accounts2); + + let storage_key2_u256: U256 = storage_key2.into(); + let result2 = + eth_api2.flagged_storage_at(address2, storage_key2_u256.into(), None).await.unwrap(); + + // Private storage should return 0x0 value with is_private = true + assert_eq!(result2.value, U256::ZERO); + assert!(result2.is_private); }   #[tokio::test] @@ -97,5 +154,46 @@ let eth_api = noop_eth_api(); let address = Address::random(); let account = eth_api.get_account(address, Default::default()).await.unwrap(); assert!(account.is_none()); + } + + fn noop_eth_api_storage_disabled() -> EthApi< + RpcNodeCoreAdapter<NoopProvider, TestPool, NoopNetwork, EthEvmConfig>, + EthRpcConverter<ChainSpec>, + > { + let provider = NoopProvider::default(); + let pool = testing_pool(); + let evm_config = EthEvmConfig::mainnet(); + + EthApi::builder(provider, pool, NoopNetwork::default(), evm_config).build() + } + + #[tokio::test] + async fn test_storage_disabled() { + let eth_api = noop_eth_api_storage_disabled(); + let address = Address::random(); + let result = eth_api.storage_at(address, U256::ZERO.into(), None).await; + + assert!(result.is_err()); + let err = result.unwrap_err(); + assert!( + err.to_string().contains("Storage APIs are disabled"), + "Expected error about disabled storage APIs, got: {}", + err + ); + } + + #[tokio::test] + async fn test_flagged_storage_disabled() { + let eth_api = noop_eth_api_storage_disabled(); + let address = Address::random(); + let result = eth_api.flagged_storage_at(address, U256::ZERO.into(), None).await; + + assert!(result.is_err()); + let err = result.unwrap_err(); + assert!( + err.to_string().contains("Storage APIs are disabled"), + "Expected error about disabled storage APIs, got: {}", + err + ); } }
diff --git reth/crates/rpc/rpc/src/lib.rs seismic-reth/crates/rpc/rpc/src/lib.rs index d29050959006966b071e2de918d3c152083f8211..034d1d1e31616bbf20f8f20e5d9a709f50493228 100644 --- reth/crates/rpc/rpc/src/lib.rs +++ seismic-reth/crates/rpc/rpc/src/lib.rs @@ -20,7 +20,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))] @@ -38,6 +38,7 @@ mod engine; pub mod eth; mod miner; mod net; +mod ops; mod otterscan; mod reth; mod rpc; @@ -52,6 +53,7 @@ pub use engine::{EngineApi, EngineEthApi}; pub use eth::{helpers::SyncListener, EthApi, EthApiBuilder, EthBundle, EthFilter, EthPubSub}; pub use miner::MinerApi; pub use net::NetApi; +pub use ops::OpsApi; pub use otterscan::OtterscanApi; pub use reth::RethApi; pub use reth_rpc_convert::RpcTypes;
diff --git reth/crates/rpc/rpc/src/ops.rs seismic-reth/crates/rpc/rpc/src/ops.rs new file mode 100644 index 0000000000000000000000000000000000000000..5f0189f4567fe8bfc1486c4fb690b6528d910c25 --- /dev/null +++ seismic-reth/crates/rpc/rpc/src/ops.rs @@ -0,0 +1,130 @@ +use std::{ + collections::HashMap, + sync::{Arc, RwLock}, +}; + +use alloy_eips::BlockId; +use alloy_primitives::{Address, B256}; +use alloy_serde::JsonStorageKey; +use async_trait::async_trait; +use jsonrpsee::core::RpcResult; +use reth_rpc_api::OpsApiServer; +use reth_storage_api::{BlockIdReader, StateProviderFactory}; +use reth_tasks::TaskSpawner; +use tokio::sync::oneshot; + +/// `ops` API implementation. +/// +/// Provides privileged storage read operations protected by signature authentication. +/// - `ops_getStorageAt`: whitelist-only, reads storage +/// - `ops_getNonce`: whitelist-only, returns the next expected nonce +#[derive(Clone)] +pub struct OpsApi<Provider> { + inner: Arc<OpsApiInner<Provider>>, +} + +struct OpsApiInner<Provider> { + /// State provider for storage reads. + provider: Provider, + /// Task spawner for blocking IO tasks. + task_spawner: Box<dyn TaskSpawner>, + /// Shared in-memory next expected nonce per whitelisted signer. + nonces: Arc<RwLock<HashMap<Address, u64>>>, +} + +impl<Provider> OpsApi<Provider> { + /// Creates a new instance of `OpsApi`. + pub fn new( + provider: Provider, + task_spawner: Box<dyn TaskSpawner>, + nonces: Arc<RwLock<HashMap<Address, u64>>>, + ) -> Self { + let inner = Arc::new(OpsApiInner { provider, task_spawner, nonces }); + Self { inner } + } +} + +impl<Provider> OpsApi<Provider> +where + Provider: StateProviderFactory + BlockIdReader + 'static, +{ + /// Executes a blocking IO task via the managed task spawner. + async fn spawn_blocking_io<F, R>( + &self, + f: F, + ) -> Result<R, jsonrpsee::types::ErrorObject<'static>> + where + F: FnOnce(Arc<OpsApiInner<Provider>>) -> Result<R, jsonrpsee::types::ErrorObject<'static>> + + Send + + 'static, + R: Send + 'static, + { + let (tx, rx) = oneshot::channel(); + let inner = self.inner.clone(); + self.inner.task_spawner.spawn_blocking(Box::pin(async move { + let res = f(inner); + let _ = tx.send(res); + })); + rx.await.map_err(|_| internal_err("blocking task cancelled".to_string()))? + } +} + +#[async_trait] +impl<Provider> OpsApiServer for OpsApi<Provider> +where + Provider: StateProviderFactory + BlockIdReader + 'static, +{ + async fn get_storage_at( + &self, + address: Address, + index: JsonStorageKey, + block_number: Option<BlockId>, + ) -> RpcResult<B256> { + self.spawn_blocking_io(move |inner| { + let state = if let Some(block_id) = block_number { + inner + .provider + .state_by_block_id(block_id) + .map_err(|e| internal_err(e.to_string()))? + } else { + inner.provider.latest().map_err(|e| internal_err(e.to_string()))? + }; + + let value = state + .storage(address, index.as_b256()) + .map_err(|e| internal_err(e.to_string()))? + .unwrap_or_default(); + + Ok(B256::new(value.value.to_be_bytes())) + }) + .await + } + + async fn get_nonce(&self, address: Address) -> RpcResult<u64> { + self.spawn_blocking_io(move |inner| { + let nonce = inner + .nonces + .read() + .map_err(|_| internal_err("nonce lock poisoned".to_string()))? + .get(&address) + .copied() + .unwrap_or(0); + Ok(nonce) + }) + .await + } +} + +impl<Provider> std::fmt::Debug for OpsApi<Provider> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("OpsApi").finish_non_exhaustive() + } +} + +fn internal_err(msg: String) -> jsonrpsee::types::ErrorObject<'static> { + jsonrpsee::types::ErrorObject::owned( + jsonrpsee::types::error::INTERNAL_ERROR_CODE, + msg, + None::<()>, + ) +}
diff --git reth/crates/rpc/rpc/src/trace.rs seismic-reth/crates/rpc/rpc/src/trace.rs index 445ee976841c4b91cef3a5794011067a225fba5b..562d10d4bcce0f952a1ca558461c30767748e9f6 100644 --- reth/crates/rpc/rpc/src/trace.rs +++ seismic-reth/crates/rpc/rpc/src/trace.rs @@ -35,7 +35,14 @@ use revm::DatabaseCommit; use revm_inspectors::{ opcode::OpcodeGasInspector, storage::StorageInspector, - tracing::{parity::populate_state_diff, TracingInspector, TracingInspectorConfig}, + tracing::{ + parity::populate_state_diff, + trace_sanitizer::{ + sanitize_localized_transaction_trace, sanitize_trace_results, + sanitize_trace_results_with_hash, + }, + TracingInspector, TracingInspectorConfig, + }, }; use serde::{Deserialize, Serialize}; use std::sync::Arc; @@ -523,7 +530,7 @@ // If statediffs were requested, populate them with the account balance and // nonce from pre-state if let Some(ref mut state_diff) = full_trace.state_diff { - populate_state_diff(state_diff, &ctx.db, ctx.state.iter()) + populate_state_diff(state_diff, &ctx.db, ctx.state.iter(), true) .map_err(Eth::Error::from_eth_err)?; }   @@ -608,6 +615,11 @@ })) } }   +// Seismic: every handler that returns trace data calls a `sanitize_*` function from +// `revm_inspectors::tracing::trace_sanitizer` before returning to the caller. This strips +// calldata, return data, stack, memory, VM trace payloads, and function selectors. +// Storage filtering is handled separately in the trace builders via `filter_private_storage`. +// See the seismic-revm-inspectors README for the full architecture. #[async_trait] impl<Eth> TraceApiServer<RpcTxReq<Eth::NetworkTypes>> for TraceApi<Eth> where @@ -627,7 +639,7 @@ ) -> RpcResult<TraceResults> { let _permit = self.acquire_trace_permit().await; let request = TraceCallRequest { call, trace_types, block_id, state_overrides, block_overrides }; - Ok(Self::trace_call(self, request).await.map_err(Into::into)?) + Ok(sanitize_trace_results(Self::trace_call(self, request).await.map_err(Into::into)?)) }   /// Handler for `trace_callMany` @@ -637,7 +649,8 @@ calls: Vec<(RpcTxReq<Eth::NetworkTypes>, HashSet<TraceType>)>, block_id: Option<BlockId>, ) -> RpcResult<Vec<TraceResults>> { let _permit = self.acquire_trace_permit().await; - Ok(Self::trace_call_many(self, calls, block_id).await.map_err(Into::into)?) + let results = Self::trace_call_many(self, calls, block_id).await.map_err(Into::into)?; + Ok(results.into_iter().map(sanitize_trace_results).collect()) }   /// Handler for `trace_rawTransaction` @@ -648,9 +661,11 @@ trace_types: HashSet<TraceType>, block_id: Option<BlockId>, ) -> RpcResult<TraceResults> { let _permit = self.acquire_trace_permit().await; - Ok(Self::trace_raw_transaction(self, data, trace_types, block_id) - .await - .map_err(Into::into)?) + Ok(sanitize_trace_results( + Self::trace_raw_transaction(self, data, trace_types, block_id) + .await + .map_err(Into::into)?, + )) }   /// Handler for `trace_replayBlockTransactions` @@ -660,9 +675,10 @@ block_id: BlockId, trace_types: HashSet<TraceType>, ) -> RpcResult<Option<Vec<TraceResultsWithTransactionHash>>> { let _permit = self.acquire_trace_permit().await; - Ok(Self::replay_block_transactions(self, block_id, trace_types) + let results = Self::replay_block_transactions(self, block_id, trace_types) .await - .map_err(Into::into)?) + .map_err(Into::into)?; + Ok(results.map(|traces| traces.into_iter().map(sanitize_trace_results_with_hash).collect())) }   /// Handler for `trace_replayTransaction` @@ -672,7 +688,9 @@ transaction: B256, trace_types: HashSet<TraceType>, ) -> RpcResult<TraceResults> { let _permit = self.acquire_trace_permit().await; - Ok(Self::replay_transaction(self, transaction, trace_types).await.map_err(Into::into)?) + let results = + Self::replay_transaction(self, transaction, trace_types).await.map_err(Into::into)?; + Ok(sanitize_trace_results(results)) }   /// Handler for `trace_block` @@ -681,7 +699,9 @@ &self, block_id: BlockId, ) -> RpcResult<Option<Vec<LocalizedTransactionTrace>>> { let _permit = self.acquire_trace_permit().await; - Ok(Self::trace_block(self, block_id).await.map_err(Into::into)?) + let traces = Self::trace_block(self, block_id).await.map_err(Into::into)?; + Ok(traces + .map(|traces| traces.into_iter().map(sanitize_localized_transaction_trace).collect())) }   /// Handler for `trace_filter` @@ -691,7 +711,8 @@ /// /// # Limitations /// This currently requires block filter fields, since reth does not have address indices yet. async fn trace_filter(&self, filter: TraceFilter) -> RpcResult<Vec<LocalizedTransactionTrace>> { - Ok(Self::trace_filter(self, filter).await.map_err(Into::into)?) + let traces = Self::trace_filter(self, filter).await.map_err(Into::into)?; + Ok(traces.into_iter().map(sanitize_localized_transaction_trace).collect()) }   /// Returns transaction trace at given index. @@ -702,9 +723,10 @@ hash: B256, indices: Vec<Index>, ) -> RpcResult<Option<LocalizedTransactionTrace>> { let _permit = self.acquire_trace_permit().await; - Ok(Self::trace_get(self, hash, indices.into_iter().map(Into::into).collect()) + let trace = Self::trace_get(self, hash, indices.into_iter().map(Into::into).collect()) .await - .map_err(Into::into)?) + .map_err(Into::into)?; + Ok(trace.map(sanitize_localized_transaction_trace)) }   /// Handler for `trace_transaction` @@ -713,7 +735,9 @@ &self, hash: B256, ) -> RpcResult<Option<Vec<LocalizedTransactionTrace>>> { let _permit = self.acquire_trace_permit().await; - Ok(Self::trace_transaction(self, hash).await.map_err(Into::into)?) + let traces = Self::trace_transaction(self, hash).await.map_err(Into::into)?; + Ok(traces + .map(|traces| traces.into_iter().map(sanitize_localized_transaction_trace).collect())) }   /// Handler for `trace_transactionOpcodeGas`
diff --git reth/crates/stages/api/src/lib.rs seismic-reth/crates/stages/api/src/lib.rs index ec01876c9951b116a03fa4de15d9409b4f1332e7..08757beca9d0726d48d567ff0abfb0b313d3ad33 100644 --- reth/crates/stages/api/src/lib.rs +++ seismic-reth/crates/stages/api/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/stages/stages/src/lib.rs seismic-reth/crates/stages/stages/src/lib.rs index 2c29bad8710a1da46e292369bbc3eabeba81be83..9649606e6714f4299dcbf838113b13c74fd16ae6 100644 --- reth/crates/stages/stages/src/lib.rs +++ seismic-reth/crates/stages/stages/src/lib.rs @@ -77,7 +77,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/stages/stages/src/stages/execution.rs seismic-reth/crates/stages/stages/src/stages/execution.rs index 1270033b885eecd933857df459357b96a499c228..5d50ce4a216317c7a55fbd3ce94cc2aa3cf2844a 100644 --- reth/crates/stages/stages/src/stages/execution.rs +++ seismic-reth/crates/stages/stages/src/stages/execution.rs @@ -843,7 +843,7 @@ } }) if total == block.gas_used); }   - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn sanity_execution_of_block() { let factory = create_test_provider_factory(); let provider = factory.provider_rw().unwrap(); @@ -968,7 +968,7 @@ // assert storage // Get on dupsort would return only first value. This is good enough for this test. assert!(matches!( provider.tx_ref().get::<tables::PlainStorageState>(account1), - Ok(Some(entry)) if entry.key == B256::with_last_byte(1) && entry.value == U256::from(2) + Ok(Some(entry)) if entry == (B256::with_last_byte(1), alloy_primitives::FlaggedStorage::public(2)).into() ));   let mut provider = factory.database_provider_rw().unwrap(); @@ -985,7 +985,7 @@ provider.commit().unwrap(); } }   - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn sanity_execute_unwind() { let factory = create_test_provider_factory(); let provider = factory.provider_rw().unwrap(); @@ -1093,7 +1093,7 @@ assert!(matches!(provider.receipt(0), Ok(None))); } }   - #[tokio::test] + #[tokio::test(flavor = "multi_thread")] async fn test_selfdestruct() { let test_db = TestStageDB::default(); let provider = test_db.factory.database_provider_rw().unwrap(); @@ -1149,14 +1149,17 @@ provider .tx_ref() .put::<tables::PlainStorageState>( destroyed_address, - StorageEntry { key: B256::ZERO, value: U256::ZERO }, + StorageEntry { key: B256::ZERO, value: alloy_primitives::FlaggedStorage::ZERO }, ) .unwrap(); provider .tx_ref() .put::<tables::PlainStorageState>( destroyed_address, - StorageEntry { key: B256::with_last_byte(1), value: U256::from(1u64) }, + StorageEntry { + key: B256::with_last_byte(1), + value: alloy_primitives::FlaggedStorage::public(1u64), + }, ) .unwrap();   @@ -1227,11 +1230,14 @@ storage_changesets, vec![ ( (block.number, destroyed_address).into(), - StorageEntry { key: B256::ZERO, value: U256::ZERO } + StorageEntry { key: B256::ZERO, value: alloy_primitives::FlaggedStorage::ZERO } ), ( (block.number, destroyed_address).into(), - StorageEntry { key: B256::with_last_byte(1), value: U256::from(1u64) } + StorageEntry { + key: B256::with_last_byte(1), + value: alloy_primitives::FlaggedStorage::public(1u64) + } ) ] );
diff --git reth/crates/stages/stages/src/stages/hashing_storage.rs seismic-reth/crates/stages/stages/src/stages/hashing_storage.rs index e0eb97165376f4325d850a9af34080814dee75c8..81fdbe95cd784ec2accaff08bcc33997c5c3e831 100644 --- reth/crates/stages/stages/src/stages/hashing_storage.rs +++ seismic-reth/crates/stages/stages/src/stages/hashing_storage.rs @@ -102,10 +102,11 @@ let chunk = chunk.collect::<Result<Vec<_>, _>>()?; // Spawn the hashing task onto the global rayon pool rayon::spawn(move || { for (address, slot) in chunk { - let mut addr_key = Vec::with_capacity(64); - addr_key.put_slice(keccak256(address).as_slice()); - addr_key.put_slice(keccak256(slot.key).as_slice()); - let _ = tx.send((addr_key, CompactU256::from(slot.value))); + let mut addr_key_is_private = Vec::with_capacity(65); + addr_key_is_private.put_slice(keccak256(address).as_slice()); + addr_key_is_private.put_slice(keccak256(slot.key).as_slice()); + addr_key_is_private.put_u8(slot.value.is_private as u8); + let _ = tx.send((addr_key_is_private, CompactU256::from(slot.value.value))); } });   @@ -129,12 +130,16 @@ "Inserting hashes" ); }   - let (addr_key, value) = item?; + let (addr_key_is_private, val) = item?; + cursor.append_dup( - B256::from_slice(&addr_key[..32]), + B256::from_slice(&addr_key_is_private[..32]), StorageEntry { - key: B256::from_slice(&addr_key[32..]), - value: CompactU256::decompress_owned(value)?.into(), + key: B256::from_slice(&addr_key_is_private[32..64]), + value: alloy_primitives::FlaggedStorage { + value: CompactU256::decompress(&val)?.into(), + is_private: addr_key_is_private[64] != 0, + }, }, )?; } @@ -212,7 +217,7 @@ use crate::test_utils::{ stage_test_suite_ext, ExecuteStageTestRunner, StageTestRunner, TestRunnerError, TestStageDB, UnwindStageTestRunner, }; - use alloy_primitives::{Address, U256}; + use alloy_primitives::{Address, FlaggedStorage}; use assert_matches::assert_matches; use rand::Rng; use reth_db_api::{ @@ -369,7 +374,9 @@ for _ in 0..2 { let new_entry = StorageEntry { key: keccak256([rng.random::<u8>()]), - value: U256::from(rng.random::<u8>() % 30 + 1), + value: alloy_primitives::FlaggedStorage::public( + rng.random::<u8>() % 30 + 1, + ), }; self.insert_storage_entry( tx, @@ -392,7 +399,9 @@ tx, (block_number, Address::random()).into(), StorageEntry { key: keccak256("mining"), - value: U256::from(rng.random::<u32>()), + value: alloy_primitives::FlaggedStorage::public( + rng.random::<u32>(), + ), }, progress.number == stage_progress, )?; @@ -488,13 +497,17 @@ tx.delete::<tables::PlainStorageState>(bn_address.address(), Some(e)) .expect("failed to delete entry"); e } - _ => StorageEntry { key: entry.key, value: U256::from(0) }, + _ => StorageEntry { key: entry.key, value: FlaggedStorage::ZERO }, }; tx.put::<tables::PlainStorageState>(bn_address.address(), entry)?;   if hash { let hashed_address = keccak256(bn_address.address()); - let hashed_entry = StorageEntry { key: keccak256(entry.key), value: entry.value }; + let hashed_entry = StorageEntry { + key: keccak256(entry.key), + value: entry.value, + ..Default::default() + };   if let Some(e) = tx .cursor_dup_write::<tables::HashedStorages>()?
diff --git reth/crates/stages/stages/src/stages/index_storage_history.rs seismic-reth/crates/stages/stages/src/stages/index_storage_history.rs index 09c9030cb39c984b48c2892433fa412bad775cb5..f9b9333b992f925e583be2ef2c3d37266eeaa5fd 100644 --- reth/crates/stages/stages/src/stages/index_storage_history.rs +++ seismic-reth/crates/stages/stages/src/stages/index_storage_history.rs @@ -153,7 +153,7 @@ use crate::test_utils::{ stage_test_suite_ext, ExecuteStageTestRunner, StageTestRunner, TestRunnerError, TestStageDB, UnwindStageTestRunner, }; - use alloy_primitives::{address, b256, Address, BlockNumber, B256, U256}; + use alloy_primitives::{address, b256, Address, BlockNumber, FlaggedStorage, B256}; use itertools::Itertools; use reth_db_api::{ cursor::DbCursorRO, @@ -181,7 +181,7 @@ const MAX_BLOCK: BlockNumber = NUM_OF_INDICES_IN_SHARD as BlockNumber + 2;   const fn storage(key: B256) -> StorageEntry { // Value is not used in indexing stage. - StorageEntry { key, value: U256::ZERO } + StorageEntry { key, value: FlaggedStorage::ZERO } }   const fn block_number_address(block_number: u64) -> BlockNumberAddress {
diff --git reth/crates/stages/stages/src/stages/merkle.rs seismic-reth/crates/stages/stages/src/stages/merkle.rs index c511531624386d6dc27450b8b3ccbd82573a99b6..5dbefabd779f1386b4ed8a955a2e03ee78299a3c 100644 --- reth/crates/stages/stages/src/stages/merkle.rs +++ seismic-reth/crates/stages/stages/src/stages/merkle.rs @@ -448,7 +448,7 @@ }; use alloy_primitives::{keccak256, U256}; use assert_matches::assert_matches; use reth_db_api::cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO}; - use reth_primitives_traits::{SealedBlock, StorageEntry}; + use reth_primitives_traits::SealedBlock; use reth_provider::{providers::StaticFileWriter, StaticFileProviderFactory}; use reth_stages_api::StageUnitCheckpoint; use reth_static_file_types::StaticFileSegment; @@ -726,7 +726,11 @@ .collect::<Vec<_>>(); accounts.insert(key, (account, storage)); }   - Ok(state_root_prehashed(accounts.into_iter())) + Ok(state_root_prehashed( + accounts + .into_iter() + .map(|(key, (a, b))| (key, (a, b.into_iter().map(|(k, v)| (k, v))))), + )) })?;   let static_file_provider = self.db.factory.static_file_provider(); @@ -770,7 +774,8 @@ tx.cursor_dup_read::<tables::StorageChangeSets>().unwrap(); let mut storage_cursor = tx.cursor_dup_write::<tables::HashedStorages>().unwrap();   - let mut tree: BTreeMap<B256, BTreeMap<B256, U256>> = BTreeMap::new(); + let mut tree: BTreeMap<B256, BTreeMap<B256, alloy_primitives::FlaggedStorage>> = + BTreeMap::new();   let mut rev_changeset_walker = storage_changesets_cursor.walk_back(None).unwrap(); @@ -795,7 +800,7 @@ storage_cursor.delete_current().unwrap(); }   if !value.is_zero() { - let storage_entry = StorageEntry { key: hashed_slot, value }; + let storage_entry = (hashed_slot, value).into(); storage_cursor.upsert(hashed_address, &storage_entry).unwrap(); } }
diff --git reth/crates/stages/types/src/lib.rs seismic-reth/crates/stages/types/src/lib.rs index f6149d9eb07112136febba2afb9ceda617d7f7b9..e5f7cb76ddd06574910f2be2efcb66b484bdaa62 100644 --- reth/crates/stages/types/src/lib.rs +++ seismic-reth/crates/stages/types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/stateless/src/trie.rs seismic-reth/crates/stateless/src/trie.rs index 49d1f6cf0fd2618370664766aa7d3816b0d58527..149392f5a758811aef2b90222b3346a06cc04e37 100644 --- reth/crates/stateless/src/trie.rs +++ seismic-reth/crates/stateless/src/trie.rs @@ -34,7 +34,11 @@ /// Returns the storage slot value that corresponds to the given (address, slot) tuple. /// /// This method will error if the `ExecutionWitness` is not able to guarantee /// that the storage was missing from the Trie _and_ the witness was complete. - fn storage(&self, address: Address, slot: U256) -> Result<U256, ProviderError>; + fn storage( + &self, + address: Address, + slot: U256, + ) -> Result<alloy_primitives::FlaggedStorage, ProviderError>;   /// Computes the new state root from the `HashedPostState`. fn calculate_state_root( @@ -87,12 +91,16 @@ /// Returns the storage slot value that corresponds to the given (address, slot) tuple. /// /// This method will error if the `ExecutionWitness` is not able to guarantee /// that the storage was missing from the Trie _and_ the witness was complete. - pub fn storage(&self, address: Address, slot: U256) -> Result<U256, ProviderError> { + pub fn storage( + &self, + address: Address, + slot: U256, + ) -> Result<alloy_primitives::FlaggedStorage, ProviderError> { let hashed_address = keccak256(address); let hashed_slot = keccak256(B256::from(slot));   if let Some(raw) = self.inner.get_storage_slot_value(&hashed_address, &hashed_slot) { - return Ok(U256::decode(&mut raw.as_slice())?) + return Ok(alloy_primitives::FlaggedStorage::decode(&mut raw.as_slice())?) }   // Storage slot value is not present in the trie, validate that the witness is complete. @@ -116,7 +124,7 @@ "incomplete account witness for {hashed_address:?}" ))); }   - Ok(U256::ZERO) + Ok(alloy_primitives::FlaggedStorage::ZERO) }   /// Computes the new state root from the `HashedPostState`. @@ -141,7 +149,11 @@ fn account(&self, address: Address) -> Result<Option<TrieAccount>, ProviderError> { self.account(address) }   - fn storage(&self, address: Address, slot: U256) -> Result<U256, ProviderError> { + fn storage( + &self, + address: Address, + slot: U256, + ) -> Result<alloy_primitives::FlaggedStorage, ProviderError> { self.storage(address, slot) }   @@ -262,6 +274,7 @@ } else { storage_trie.update_leaf( nibbles, alloy_rlp::encode_fixed_size(&value).to_vec(), + value.is_private, &storage_provider, )?; }
diff --git reth/crates/stateless/src/witness_db.rs seismic-reth/crates/stateless/src/witness_db.rs index 4a99c286ad374bbc95d3b509abb41f750b08a1c6..a2042f41d7b45199a367d9d3705be6822b10ccd6 100644 --- reth/crates/stateless/src/witness_db.rs +++ seismic-reth/crates/stateless/src/witness_db.rs @@ -89,7 +89,11 @@ /// Get storage value of an account at a specific slot. /// /// Returns `U256::ZERO` if the slot is not found in the trie. - fn storage(&mut self, address: Address, slot: U256) -> Result<U256, Self::Error> { + fn storage( + &mut self, + address: Address, + slot: U256, + ) -> Result<alloy_primitives::FlaggedStorage, Self::Error> { self.trie.storage(address, slot) }
diff --git reth/crates/static-file/static-file/src/lib.rs seismic-reth/crates/static-file/static-file/src/lib.rs index 1e9ffa15c66584e957bbf183476d5691aee78988..bbb9c906d3240f06e65e9a0a484117a0ee3ab404 100644 --- reth/crates/static-file/static-file/src/lib.rs +++ seismic-reth/crates/static-file/static-file/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/static-file/types/src/lib.rs seismic-reth/crates/static-file/types/src/lib.rs index 7f9f3d393088015487c72657609a0ad19e49cef9..7d18d2d5705e345715e6a15f6273c01e6184b29d 100644 --- reth/crates/static-file/types/src/lib.rs +++ seismic-reth/crates/static-file/types/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/tasks/src/lib.rs seismic-reth/crates/tasks/src/lib.rs index 5f72037f7babf63a2b7a3086bb53de8ca7530288..8ee65edde74956e5425c0149dbe2f6f0f1e0b4d3 100644 --- reth/crates/tasks/src/lib.rs +++ seismic-reth/crates/tasks/src/lib.rs @@ -7,7 +7,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/tokio-util/src/lib.rs seismic-reth/crates/tokio-util/src/lib.rs index e476c4063d9e305b744707e4b38ca77b1ece373f..a739ba694937dd8902b60d0dca3043ff7573855b 100644 --- reth/crates/tokio-util/src/lib.rs +++ seismic-reth/crates/tokio-util/src/lib.rs @@ -3,7 +3,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/tracing/src/lib.rs seismic-reth/crates/tracing/src/lib.rs index 8c01cde55867cb5f2f41b90cf80816f01a8b73cc..3e1b186445567ad84c6bb7bf964b218d69473e61 100644 --- reth/crates/tracing/src/lib.rs +++ seismic-reth/crates/tracing/src/lib.rs @@ -38,7 +38,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
diff --git reth/crates/transaction-pool/Cargo.toml seismic-reth/crates/transaction-pool/Cargo.toml index 0203071984017aa09a76fe7b19320b615516b230..d8f6adf6297057825d647e71e0673cd009ef9a56 100644 --- reth/crates/transaction-pool/Cargo.toml +++ seismic-reth/crates/transaction-pool/Cargo.toml @@ -30,6 +30,7 @@ alloy-eips = { workspace = true, features = ["kzg"] } alloy-primitives.workspace = true alloy-rlp.workspace = true alloy-consensus = { workspace = true, features = ["kzg"] } +seismic-alloy-consensus.workspace = true   # async/futures futures-util.workspace = true @@ -76,6 +77,7 @@ tokio = { workspace = true, features = ["rt-multi-thread"] } futures.workspace = true   [features] +timestamp-in-seconds = ["revm-interpreter/timestamp-in-seconds", "reth-primitives-traits/timestamp-in-seconds"] serde = [ "reth-execution-types/serde", "reth-eth-wire-types/serde", @@ -93,6 +95,11 @@ "reth-ethereum-primitives/serde", "reth-chain-state/serde", "reth-storage-api/serde", ] +serde-bincode-compat = [ + "reth-ethereum-primitives/serde-bincode-compat", + "reth-execution-types/serde-bincode-compat", +] +reth-codec = ["reth-ethereum-primitives/reth-codec"] test-utils = [ "rand", "paste", @@ -119,6 +126,7 @@ "revm-interpreter/arbitrary", "reth-ethereum-primitives/arbitrary", "revm-primitives/arbitrary", ] +   [[bench]] name = "truncate"
diff --git reth/crates/transaction-pool/src/config.rs seismic-reth/crates/transaction-pool/src/config.rs index c6fb4ecc88bd4bb88f639324e984e823791123b3..4d43b581858d88cab5a6d2c75d4d3b53a980ff87 100644 --- reth/crates/transaction-pool/src/config.rs +++ seismic-reth/crates/transaction-pool/src/config.rs @@ -72,6 +72,11 @@ /// The maximum allowed inflight transactions a delegated sender can have. /// /// This restricts how many executable transaction a delegated sender can stack. pub max_inflight_delegated_slot_limit: usize, + /// When true, the pool will not demote transactions to the queued sub-pool due to + /// insufficient native balance. This is useful for chains where gas can be paid in an + /// alternative token (e.g. USDC on Seismic) so that native balance is not relevant for + /// transaction ordering. + pub disable_balance_check: bool, }   impl PoolConfig { @@ -88,6 +93,14 @@ /// Ethereum's EIP-1559 base fee can't drop below [`MIN_PROTOCOL_BASE_FEE`] hence this is /// enforced by default in the pool. pub const fn with_protocol_base_fee(mut self, protocol_base_fee: u64) -> Self { self.minimal_protocol_basefee = protocol_base_fee; + self + } + + /// Disables native balance checks in the pool, so transactions are never demoted to the + /// queued sub-pool due to insufficient native balance. Useful for chains where gas is paid + /// in an alternative token. + pub const fn with_disabled_balance_check(mut self) -> Self { + self.disable_balance_check = true; self }   @@ -129,6 +142,7 @@ new_tx_listener_buffer_size: NEW_TX_LISTENER_BUFFER_SIZE, max_new_pending_txs_notifications: MAX_NEW_PENDING_TXS_NOTIFICATIONS, max_queued_lifetime: MAX_QUEUED_TRANSACTION_LIFETIME, max_inflight_delegated_slot_limit: DEFAULT_MAX_INFLIGHT_DELEGATED_SLOTS, + disable_balance_check: false, } } }
diff --git reth/crates/transaction-pool/src/error.rs seismic-reth/crates/transaction-pool/src/error.rs index 0a40c60602d2dd1073b35286b5696c58effd2c64..e9dc49fdcb5d138aa31c90d6e916af19da381588 100644 --- reth/crates/transaction-pool/src/error.rs +++ seismic-reth/crates/transaction-pool/src/error.rs @@ -320,6 +320,7 @@ InvalidTransactionError::Eip7702Disabled => { // settings false } + InvalidTransactionError::SeismicTx(_) => false, InvalidTransactionError::OldLegacyChainId | InvalidTransactionError::ChainIdMismatch | InvalidTransactionError::GasUintOverflow |
diff --git reth/crates/transaction-pool/src/lib.rs seismic-reth/crates/transaction-pool/src/lib.rs index c543d4128424715bae96c3b4503e318d0019f4ad..c41565353fcdff427dc78706ecedb1277d56b242 100644 --- reth/crates/transaction-pool/src/lib.rs +++ seismic-reth/crates/transaction-pool/src/lib.rs @@ -265,7 +265,7 @@ #![doc( html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxyz/reth/issues/" + issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/" )] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(test), warn(unused_crate_dependencies))]
diff --git reth/crates/transaction-pool/src/maintain.rs seismic-reth/crates/transaction-pool/src/maintain.rs index 9f48590d9d9d1fa141f033cd158e5f4ba9426244..1358e6bb202f106e314b74494f34692e5058d2b7 100644 --- reth/crates/transaction-pool/src/maintain.rs +++ seismic-reth/crates/transaction-pool/src/maintain.rs @@ -22,7 +22,9 @@ use reth_fs_util::FsPathError; use reth_primitives_traits::{ transaction::signed::SignedTransaction, NodePrimitives, SealedHeader, }; -use reth_storage_api::{errors::provider::ProviderError, BlockReaderIdExt, StateProviderFactory}; +use reth_storage_api::{ + errors::provider::ProviderError, BlockReaderIdExt, StateProvider, StateProviderFactory, +}; use reth_tasks::TaskSpawner; use serde::{Deserialize, Serialize}; use std::{ @@ -91,6 +93,26 @@ Self { transactions_path: Some(transactions_path) } } }   +/// Hook to transform changed accounts before they are passed to the pool. +/// +/// This is used by Seismic to augment native balances with USDC balances so that +/// the pool can make accurate demotion decisions for accounts paying gas in USDC. +pub trait ChangedAccountsHook: Send + Sync + 'static { + /// Transforms the changed accounts list in place. Implementations may read + /// additional state (e.g. ERC-20 storage) and adjust the `balance` field of + /// each [`ChangedAccount`]. + /// + /// The [`StateProvider`] is the same snapshot the maintenance loop used to + /// load native balance/nonce, so implementations always see a consistent + /// view of the chain. + fn transform(&self, state: &dyn StateProvider, accounts: &mut Vec<ChangedAccount>); +} + +/// No-op implementation for chains that don't need balance augmentation. +impl ChangedAccountsHook for () { + fn transform(&self, _state: &dyn StateProvider, _accounts: &mut Vec<ChangedAccount>) {} +} + /// Returns a spawnable future for maintaining the state of the transaction pool. pub fn maintain_transaction_pool_future<N, Client, P, St, Tasks>( client: Client, @@ -110,8 +132,33 @@ P: TransactionPoolExt<Transaction: PoolTransaction<Consensus = N::SignedTx>> + 'static, St: Stream<Item = CanonStateNotification<N>> + Send + Unpin + 'static, Tasks: TaskSpawner + 'static, { + maintain_transaction_pool_future_with_hook(client, pool, events, task_spawner, config, ()) +} + +/// Like [`maintain_transaction_pool_future`] but accepts a [`ChangedAccountsHook`] +/// that can transform account balances before the pool processes them. +pub fn maintain_transaction_pool_future_with_hook<N, Client, P, St, Tasks, H>( + client: Client, + pool: P, + events: St, + task_spawner: Tasks, + config: MaintainPoolConfig, + hook: H, +) -> BoxFuture<'static, ()> +where + N: NodePrimitives, + Client: StateProviderFactory + + BlockReaderIdExt<Header = N::BlockHeader> + + ChainSpecProvider<ChainSpec: EthChainSpec<Header = N::BlockHeader>> + + Clone + + 'static, + P: TransactionPoolExt<Transaction: PoolTransaction<Consensus = N::SignedTx>> + 'static, + St: Stream<Item = CanonStateNotification<N>> + Send + Unpin + 'static, + Tasks: TaskSpawner + 'static, + H: ChangedAccountsHook, +{ async move { - maintain_transaction_pool(client, pool, events, task_spawner, config).await; + maintain_transaction_pool_with_hook(client, pool, events, task_spawner, config, hook).await; } .boxed() } @@ -122,9 +169,32 @@ /// This listens for any new blocks and reorgs and updates the transaction pool's state accordingly pub async fn maintain_transaction_pool<N, Client, P, St, Tasks>( client: Client, pool: P, + events: St, + task_spawner: Tasks, + config: MaintainPoolConfig, +) where + N: NodePrimitives, + Client: StateProviderFactory + + BlockReaderIdExt<Header = N::BlockHeader> + + ChainSpecProvider<ChainSpec: EthChainSpec<Header = N::BlockHeader>> + + Clone + + 'static, + P: TransactionPoolExt<Transaction: PoolTransaction<Consensus = N::SignedTx>> + 'static, + St: Stream<Item = CanonStateNotification<N>> + Send + Unpin + 'static, + Tasks: TaskSpawner + 'static, +{ + maintain_transaction_pool_with_hook(client, pool, events, task_spawner, config, ()).await +} + +/// Like [`maintain_transaction_pool`] but accepts a [`ChangedAccountsHook`] that +/// can transform account balances before the pool processes them. +pub async fn maintain_transaction_pool_with_hook<N, Client, P, St, Tasks, H>( + client: Client, + pool: P, mut events: St, task_spawner: Tasks, config: MaintainPoolConfig, + hook: H, ) where N: NodePrimitives, Client: StateProviderFactory @@ -135,6 +205,7 @@ + 'static, P: TransactionPoolExt<Transaction: PoolTransaction<Consensus = N::SignedTx>> + 'static, St: Stream<Item = CanonStateNotification<N>> + Send + Unpin + 'static, Tasks: TaskSpawner + 'static, + H: ChangedAccountsHook, { let metrics = MaintainPoolMetrics::default(); let MaintainPoolConfig { max_update_depth, max_reload_accounts, .. } = config; @@ -147,10 +218,11 @@ block_gas_limit: latest.gas_limit(), last_seen_block_hash: latest.hash(), last_seen_block_number: latest.number(), pending_basefee: chain_spec - .next_block_base_fee(latest.header(), latest.timestamp()) + .next_block_base_fee(latest.header(), latest.timestamp_seconds()) .unwrap_or_default(), - pending_blob_fee: latest - .maybe_next_block_blob_fee(chain_spec.blob_params_at_timestamp(latest.timestamp())), + pending_blob_fee: latest.maybe_next_block_blob_fee( + chain_spec.blob_params_at_timestamp(latest.timestamp_seconds()), + ), }; pool.set_block_info(info); } @@ -285,10 +357,13 @@ } } // handle the result of the account reload match reloaded { - Some(Ok(Ok(LoadedAccounts { accounts, failed_to_load }))) => { + Some(Ok(Ok(LoadedAccounts { mut accounts, failed_to_load }))) => { // reloaded accounts successfully // extend accounts we failed to load from database dirty_addresses.extend(failed_to_load); + if let Ok(state) = client.history_by_block_hash(pool_info.last_seen_block_hash) { + hook.transform(&*state, &mut accounts); + } // update the pool with the loaded accounts pool.update_accounts(accounts); } @@ -327,10 +402,10 @@ let chain_spec = client.chain_spec();   // fees for the next block: `new_tip+1` let pending_block_base_fee = chain_spec - .next_block_base_fee(new_tip.header(), new_tip.timestamp()) + .next_block_base_fee(new_tip.header(), new_tip.timestamp_seconds()) .unwrap_or_default(); let pending_block_blob_fee = new_tip.header().maybe_next_block_blob_fee( - chain_spec.blob_params_at_timestamp(new_tip.timestamp()), + chain_spec.blob_params_at_timestamp(new_tip.timestamp_seconds()), );   // we know all changed account in the new chain @@ -368,6 +443,9 @@ // also include all accounts from new chain // we can use extend here because they are unique changed_accounts.extend(new_changed_accounts.into_iter().map(|entry| entry.0)); + if let Ok(state) = client.history_by_block_hash(new_tip.hash()) { + hook.transform(&*state, &mut changed_accounts); + }   // all transactions mined in the new chain let new_mined_transactions: HashSet<_> = new_blocks.transaction_hashes().collect(); @@ -430,10 +508,10 @@ let chain_spec = client.chain_spec();   // fees for the next block: `tip+1` let pending_block_base_fee = chain_spec - .next_block_base_fee(tip.header(), tip.timestamp()) + .next_block_base_fee(tip.header(), tip.timestamp_seconds()) .unwrap_or_default(); let pending_block_blob_fee = tip.header().maybe_next_block_blob_fee( - chain_spec.blob_params_at_timestamp(tip.timestamp()), + chain_spec.blob_params_at_timestamp(tip.timestamp_seconds()), );   let first_block = blocks.first(); @@ -471,6 +549,9 @@ for acc in state.changed_accounts() { // we can always clear the dirty flag for this account dirty_addresses.remove(&acc.address); changed_accounts.push(acc); + } + if let Ok(tip_state) = client.history_by_block_hash(tip.hash()) { + hook.transform(&*tip_state, &mut changed_accounts); }   let mined_transactions = blocks.transaction_hashes().collect();
diff --git reth/crates/transaction-pool/src/pool/mod.rs seismic-reth/crates/transaction-pool/src/pool/mod.rs index 97f248003bb351221a825df1a0d98a6f59249b30..e0f8aba2ed578b336bcf80be70d710a69f3a14f8 100644 --- reth/crates/transaction-pool/src/pool/mod.rs +++ seismic-reth/crates/transaction-pool/src/pool/mod.rs @@ -510,7 +510,16 @@ };   let added = pool.add_transaction(tx, balance, state_nonce, bytecode_hash)?; let hash = *added.hash(); - let state = match added.subpool() { + let subpool = added.subpool(); + debug!( + target: "txpool", + tx_hash = %hash, + ?subpool, + reported_balance = %balance, + state_nonce, + "transaction added to pool" + ); + let state = match subpool { SubPool::Pending => AddedTransactionState::Pending, _ => AddedTransactionState::Queued, };
diff --git reth/crates/transaction-pool/src/pool/txpool.rs seismic-reth/crates/transaction-pool/src/pool/txpool.rs index eebf3fa242630253d6cab6956744003e0d585e2f..ae79245c82df314b9f789b899bdca3c3b4d10aee 100644 --- reth/crates/transaction-pool/src/pool/txpool.rs +++ seismic-reth/crates/transaction-pool/src/pool/txpool.rs @@ -1062,7 +1062,6 @@ ) { // We trace here instead of in structs directly, because the `ParkedPool` type is // generic and it would not be possible to distinguish whether a transaction is being // added to the `BaseFee` pool, or the `Queued` pool. - trace!(target: "txpool", hash=%tx.transaction.hash(), ?pool, "Adding transaction to a subpool"); match pool { SubPool::Queued => self.queued_pool.add_transaction(tx), SubPool::Pending => { @@ -1264,6 +1263,9 @@ /// How to handle [`TransactionOrigin::Local`](crate::TransactionOrigin) transactions. local_transactions_config: LocalTransactionConfig, /// All accounts with a pooled authorization auths: FxHashMap<SenderId, HashSet<TxHash>>, + /// When true, skip native balance checks so transactions are never demoted due to + /// insufficient native balance. Used for chains where gas is paid in an alternative token. + disable_balance_check: bool, /// All Transactions metrics metrics: AllTransactionsMetrics, } @@ -1277,6 +1279,7 @@ price_bumps: config.price_bumps, local_transactions_config: config.local_transactions_config.clone(), minimal_protocol_basefee: config.minimal_protocol_basefee, block_gas_limit: config.gas_limit, + disable_balance_check: config.disable_balance_check, ..Default::default() } } @@ -1419,7 +1422,9 @@ if ancestor.is_none() { tx.state.insert(TxState::NO_NONCE_GAPS); tx.state.insert(TxState::NO_PARKED_ANCESTORS); tx.cumulative_cost = U256::ZERO; - if tx.transaction.cost() > &info.balance { + if self.disable_balance_check { + tx.state.insert(TxState::ENOUGH_BALANCE); + } else if tx.transaction.cost() > &info.balance { // sender lacks sufficient funds to pay for this transaction tx.state.remove(TxState::ENOUGH_BALANCE); } else { @@ -1480,7 +1485,9 @@ cumulative_cost = tx.next_cumulative_cost();   // If the account changed in the block, check the balance. if let Some(changed_balance) = changed_balance { - if &cumulative_cost > changed_balance { + if self.disable_balance_check { + tx.state.insert(TxState::ENOUGH_BALANCE); + } else if &cumulative_cost > changed_balance { // sender lacks sufficient funds to pay for this transaction tx.state.remove(TxState::ENOUGH_BALANCE); } else { @@ -1943,6 +1950,7 @@ }   // The next transaction of this sender let on_chain_id = TransactionId::new(transaction.sender_id(), on_chain_nonce); + let skip_balance_check = self.disable_balance_check; { // Tracks the next nonce we expect if the transactions are gapless let mut next_nonce = on_chain_id.nonce; @@ -1971,7 +1979,9 @@ // Update for next transaction cumulative_cost = tx.next_cumulative_cost();   - if cumulative_cost > on_chain_balance { + if skip_balance_check { + tx.state.insert(TxState::ENOUGH_BALANCE); + } else if cumulative_cost > on_chain_balance { // sender lacks sufficient funds to pay for this transaction tx.state.remove(TxState::ENOUGH_BALANCE); } else { @@ -2015,7 +2025,8 @@ }   self.update_size_metrics();   - Ok(InsertOk { transaction, move_to: state.into(), state, replaced_tx, updates }) + let res = Ok(InsertOk { transaction, move_to: state.into(), state, replaced_tx, updates }); + res }   /// Number of transactions in the entire pool @@ -2061,6 +2072,7 @@ pending_fees: Default::default(), price_bumps: Default::default(), local_transactions_config: Default::default(), auths: Default::default(), + disable_balance_check: false, metrics: Default::default(), } }
diff --git reth/crates/transaction-pool/src/validate/eth.rs seismic-reth/crates/transaction-pool/src/validate/eth.rs index 9e657ba1ed01b5d9c11329c719caa42c8dca39e3..a03a7cd538d4d9efbd20d7295954b1cea416c4e0 100644 --- reth/crates/transaction-pool/src/validate/eth.rs +++ seismic-reth/crates/transaction-pool/src/validate/eth.rs @@ -32,6 +32,7 @@ GotExpected, SealedBlock, }; use reth_storage_api::{AccountInfoReader, BytecodeReader, StateProviderFactory}; use reth_tasks::TaskSpawner; +use seismic_alloy_consensus::SEISMIC_TX_TYPE_ID; use std::{ marker::PhantomData, sync::{ @@ -292,6 +293,10 @@ transaction, InvalidTransactionError::Eip7702Disabled.into(), )) } + } + + SEISMIC_TX_TYPE_ID => { + // Accept seismic transactions }   _ => { @@ -723,26 +728,30 @@ .collect() }   fn on_new_head_block<T: BlockHeader>(&self, new_tip_block: &T) { + let timestamp = if cfg!(feature = "timestamp-in-seconds") { + new_tip_block.timestamp() + } else { + new_tip_block.timestamp() / 1000 + }; + // update all forks - if self.chain_spec().is_shanghai_active_at_timestamp(new_tip_block.timestamp()) { + if self.chain_spec().is_shanghai_active_at_timestamp(timestamp) { self.fork_tracker.shanghai.store(true, std::sync::atomic::Ordering::Relaxed); }   - if self.chain_spec().is_cancun_active_at_timestamp(new_tip_block.timestamp()) { + if self.chain_spec().is_cancun_active_at_timestamp(timestamp) { self.fork_tracker.cancun.store(true, std::sync::atomic::Ordering::Relaxed); }   - if self.chain_spec().is_prague_active_at_timestamp(new_tip_block.timestamp()) { + if self.chain_spec().is_prague_active_at_timestamp(timestamp) { self.fork_tracker.prague.store(true, std::sync::atomic::Ordering::Relaxed); }   - if self.chain_spec().is_osaka_active_at_timestamp(new_tip_block.timestamp()) { + if self.chain_spec().is_osaka_active_at_timestamp(timestamp) { self.fork_tracker.osaka.store(true, std::sync::atomic::Ordering::Relaxed); }   - if let Some(blob_params) = - self.chain_spec().blob_params_at_timestamp(new_tip_block.timestamp()) - { + if let Some(blob_params) = self.chain_spec().blob_params_at_timestamp(timestamp) { self.fork_tracker .max_blob_count .store(blob_params.max_blobs_per_tx, std::sync::atomic::Ordering::Relaxed);
diff --git reth/deny.toml seismic-reth/deny.toml index fd2eb5c11cdf24e638c0e0470a571b26f9d8500c..5fe99e41f57cb1e0613338187c816eb897bb41e9 100644 --- reth/deny.toml +++ seismic-reth/deny.toml @@ -82,10 +82,10 @@ # in the allow list is encountered unknown-git = "deny" allow-git = [ # TODO: Please avoid adding new entries to this list. - "https://github.com/alloy-rs/alloy", + "https://github.com/SeismicSystems/seismic-alloy", "https://github.com/foundry-rs/block-explorers", - "https://github.com/bluealloy/revm", - "https://github.com/paradigmxyz/revm-inspectors", + "https://github.com/SeismicSystems/seismic-revm", + "https://github.com/SeismicSystems/seismic-revm-inspectors", "https://github.com/alloy-rs/evm", "https://github.com/alloy-rs/hardforks", "https://github.com/paradigmxyz/jsonrpsee",
diff --git reth/docker-build.sh seismic-reth/docker-build.sh new file mode 100755 index 0000000000000000000000000000000000000000..49691b0f318d1f1f8d5d9e282e4ffb2805af9d7b --- /dev/null +++ seismic-reth/docker-build.sh @@ -0,0 +1,2 @@ +#/bin/sh +DOCKER_BUILDKIT=1 docker build -t seismic-reth --ssh default=$SSH_AUTH_SOCK .
diff --git reth/examples/exex-subscription/src/main.rs seismic-reth/examples/exex-subscription/src/main.rs index b234c1c71f9eac2cddb57eabe016758cc9d162a2..1016fa5144ba554895bca954e5682b5c1c68e524 100644 --- reth/examples/exex-subscription/src/main.rs +++ seismic-reth/examples/exex-subscription/src/main.rs @@ -125,8 +125,8 @@ for (key, slot) in &change.1.storage { let diff = StorageDiff { address: *change.0, key: *key, - old_value: slot.original_value(), - new_value: slot.present_value(), + old_value: slot.original_value().into(), + new_value: slot.present_value().into(), }; // Send diff to all the active subscribers senders.retain(|sender| sender.send(diff).is_ok());
diff --git reth/lefthook.yml seismic-reth/lefthook.yml new file mode 100644 index 0000000000000000000000000000000000000000..64a2b330cc07df86ce2e0da572f479cf80e24f0f --- /dev/null +++ seismic-reth/lefthook.yml @@ -0,0 +1,31 @@ +pre-commit: + commands: + fmt: + run: cargo +nightly fmt --all + stage_fixed: true + +pre-push: + commands: + clippy: + run: > + cargo clippy + -p reth-seismic-primitives + -p reth-seismic-chainspec + -p reth-seismic-evm + -p reth-seismic-payload-builder + -p reth-seismic-node + -p reth-seismic-rpc + -p reth-seismic-cli + -p reth-seismic-txpool + -p reth-seismic-forks + -p seismic-reth + --lib --tests --no-deps + -- -D warnings + -W clippy::unwrap_used + -W clippy::expect_used + -W clippy::indexing_slicing + -W clippy::panic + -W clippy::unreachable + -W clippy::todo + typos: + run: typos
diff --git reth/network_params.yaml seismic-reth/network_params.yaml new file mode 100644 index 0000000000000000000000000000000000000000..15e69b6a9d2d055005fb53ee8bf4eb117c2ea53f --- /dev/null +++ seismic-reth/network_params.yaml @@ -0,0 +1,11 @@ +participants: + - el_type: reth + el_image: seismic-reth + el_extra_params: ["--enclave.mock-server"] + cl_type: lighthouse + cl_image: sigp/lighthouse:v6.0.0 +additional_services: ["tx_spammer"] +tx_spammer_params: + image: seismic-spammer + tx_spammer_extra_args: [] +global_log_level: debug
diff --git reth/package.json seismic-reth/package.json new file mode 100644 index 0000000000000000000000000000000000000000..5e8afb7276d3c003cb15baca4bc94d662363171b --- /dev/null +++ seismic-reth/package.json @@ -0,0 +1,12 @@ +{ + "workspaces": [ + "testing/viem-tests" + ], + "private": true, + "scripts": { + "viem:test": "bun run --cwd testing/viem-tests test" + }, + "dependencies": { + "seismic-viem": "^1.1.0" + } +}
diff --git reth/taplo.toml seismic-reth/taplo.toml new file mode 100644 index 0000000000000000000000000000000000000000..70d0524da24ef05fb5d3bec32a44210b9d07cff7 --- /dev/null +++ seismic-reth/taplo.toml @@ -0,0 +1,17 @@ +# Keep dependency declarations compact (e.g. features on one line) instead of +# taplo's default behavior of expanding arrays/inline tables to multiline. +# eg. taplo will default to: +# +# secp256k1 = { version = "0.30", default-features = false, features = [ +# "global-context", +# "recovery", +# ] } +# +# but with these settings, we'll keep the upstream formatting style of: +# +# secp256k1 = { version = "0.30", default-features = false, features = ["global-context", "recovery"] } +[formatting] +array_auto_expand = false +array_auto_collapse = true +inline_table_expand = false +column_width = 120
diff --git reth/Cargo.lock seismic-reth/Cargo.lock index 40057e73353008d371d08dab466324a8cd592f3e..f82b94070fda994580bdf87f3956f67bcbd7e855 100644 --- reth/Cargo.lock +++ seismic-reth/Cargo.lock @@ -3,15 +3,6 @@ # It is not intended for manual editing. version = 4   [[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] name = "adler2" version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -59,7 +50,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "version_check", "zerocopy", @@ -67,9 +58,9 @@ ]   [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -97,9 +88,9 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"   [[package]] name = "alloy-chains" -version = "0.2.9" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8ff73a143281cb77c32006b04af9c047a6b8fe5860e85a88ad325328965355" +checksum = "b163ff4acf0eac29af05a911397cc418a76e153467b859398adc26cb9335a611" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -112,9 +103,9 @@ ]   [[package]] name = "alloy-consensus" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d213580c17d239ae83c0d897ac3315db7cda83d2d4936a9823cc3517552f2e24" +checksum = "90d103d3e440ad6f703dd71a5b58a6abd24834563bde8a5fabe706e00242f810" dependencies = [ "alloy-eips", "alloy-primitives", @@ -125,22 +116,23 @@ "alloy-tx-macros", "arbitrary", "auto_impl", "c-kzg", - "derive_more", + "derive_more 2.1.1", "either", "k256", "once_cell", "rand 0.8.5", "secp256k1 0.30.0", "serde", + "serde_json", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-consensus-any" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81443e3b8dccfeac7cd511aced15928c97ff253f4177acbb97de97178e543f6c" +checksum = "48ead76c8c84ab3a50c31c56bc2c748c2d64357ad2131c32f9b10ab790a25e1a" dependencies = [ "alloy-consensus", "alloy-eips", @@ -153,9 +145,9 @@ ]   [[package]] name = "alloy-contract" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de217ab604f1bcfa2e3b0aff86d50812d5931d47522f9f0a949cc263ec2d108e" +checksum = "d5903097e4c131ad2dd80d87065f23c715ccb9cdb905fa169dffab8e1e798bae" dependencies = [ "alloy-consensus", "alloy-dyn-abi", @@ -170,21 +162,22 @@ "alloy-transport", "futures", "futures-util", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-dyn-abi" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3f56873f3cac7a2c63d8e98a4314b8311aa96adb1a0f82ae923eb2119809d2c" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "alloy-json-abi", "alloy-primitives", "alloy-sol-type-parser", "alloy-sol-types", - "derive_more", + "arbitrary", + "derive_more 2.1.1", "itoa", + "proptest", "serde", "serde_json", "winnow", @@ -202,43 +195,45 @@ "arbitrary", "crc", "rand 0.8.5", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-eip2930" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b82752a889170df67bbb36d42ca63c531eb16274f0d7299ae2a680facba17bd" +checksum = "9441120fa82df73e8959ae0e4ab8ade03de2aaae61be313fbf5746277847ce25" dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", + "borsh", "rand 0.8.5", "serde", ]   [[package]] name = "alloy-eip7702" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d4769c6ffddca380b0070d71c8b7f30bed375543fe76bb2f74ec0acf4b7cd16" +checksum = "2919c5a56a1007492da313e7a3b6d45ef5edc5d33416fdec63c0d7a2702a0d20" dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", + "borsh", "k256", "rand 0.8.5", "serde", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-eips" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a15b4b0f6bab47aae017d52bb5a739bda381553c09fb9918b7172721ef5f5de" +checksum = "7bdbec74583d0067798d77afa43d58f00d93035335d7ceaa5d3f93857d461bb9" dependencies = [ "alloy-eip2124", "alloy-eip2930", @@ -249,21 +244,20 @@ "alloy-serde", "arbitrary", "auto_impl", "c-kzg", - "derive_more", + "derive_more 2.1.1", "either", "ethereum_ssz", "ethereum_ssz_derive", "serde", "serde_with", - "sha2 0.10.9", - "thiserror 2.0.16", + "sha2", + "thiserror 2.0.17", ]   [[package]] name = "alloy-evm" version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dbe7c66c859b658d879b22e8aaa19546dab726b0639f4649a424ada3d99349e" +source = "git+https://github.com/SeismicSystems/seismic-evm.git?rev=c33f3076495d153eefbde07dd81c3a575f3d19b8#c33f3076495d153eefbde07dd81c3a575f3d19b8" dependencies = [ "alloy-consensus", "alloy-eips", @@ -272,18 +266,20 @@ "alloy-primitives", "alloy-rpc-types-eth", "alloy-sol-types", "auto_impl", - "derive_more", + "derive_more 2.1.1", "op-alloy-consensus", "op-revm", "revm", - "thiserror 2.0.16", + "seismic-alloy-consensus", + "seismic-revm", + "thiserror 2.0.17", ]   [[package]] name = "alloy-genesis" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ba1cbc25a07e0142e8875fcbe80e1fdb02be8160ae186b90f4b9a69a72ed2b" +checksum = "c25d5acb35706e683df1ea333c862bdb6b7c5548836607cd5bb56e501cca0b4f" dependencies = [ "alloy-eips", "alloy-primitives", @@ -309,9 +305,8 @@ ]   [[package]] name = "alloy-json-abi" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125a1c373261b252e53e04d6e92c37d881833afc1315fceab53fd46045695640" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "alloy-primitives", "alloy-sol-type-parser", @@ -321,24 +316,24 @@ ]   [[package]] name = "alloy-json-rpc" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8882ec8e4542cfd02aadc6dccbe90caa73038f60016d936734eb6ced53d2167" +checksum = "31b67c5a702121e618217f7a86f314918acb2622276d0273490e2d4534490bc0" dependencies = [ "alloy-primitives", "alloy-sol-types", "http", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ]   [[package]] name = "alloy-network" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d6d87d588bda509881a7a66ae77c86514bd1193ac30fbff0e0f24db95eb5a5" +checksum = "612296e6b723470bb1101420a73c63dfd535aa9bf738ce09951aedbd4ab7292e" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -353,18 +348,18 @@ "alloy-signer", "alloy-sol-types", "async-trait", "auto_impl", - "derive_more", + "derive_more 2.1.1", "futures-utils-wasm", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-network-primitives" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b14fa9ba5774e0b30ae6a04176d998211d516c8af69c9c530af7c6c42a8c508" +checksum = "a0e7918396eecd69d9c907046ec8a93fb09b89e2f325d5e7ea9c4e3929aa0dd2" dependencies = [ "alloy-consensus", "alloy-eips", @@ -374,56 +369,26 @@ "serde", ]   [[package]] -name = "alloy-op-evm" -version = "0.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9b726869a13d5d958f2f78fbef7ce522689c4d40d613c16239f5e286fbeb1a" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-evm", - "alloy-op-hardforks", - "alloy-primitives", - "auto_impl", - "op-alloy-consensus", - "op-revm", - "revm", -] - -[[package]] -name = "alloy-op-hardforks" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07953246c78130f119855393ba0235d22539c60b6a627f737cdf0ae692f042f6" -dependencies = [ - "alloy-chains", - "alloy-hardforks", - "auto_impl", - "serde", -] - -[[package]] name = "alloy-primitives" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9485c56de23438127a731a6b4c87803d49faf1a7068dcd1d8768aca3a9edb9" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "alloy-rlp", "arbitrary", "bytes", "cfg-if", "const-hex", - "derive_more", - "foldhash", - "getrandom 0.3.3", - "hashbrown 0.15.5", - "indexmap 2.11.0", + "derive_more 2.1.1", + "foldhash 0.2.0", + "getrandom 0.3.4", + "hashbrown 0.16.1", + "indexmap 2.12.1", "itoa", "k256", "keccak-asm", "paste", "proptest", - "proptest-derive", + "proptest-derive 0.6.0", "rand 0.9.2", "ruint", "rustc-hash 2.1.1", @@ -434,9 +399,9 @@ ]   [[package]] name = "alloy-provider" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "475a5141313c3665b75d818be97d5fa3eb5e0abb7e832e9767edd94746db28e3" +checksum = "55c1313a527a2e464d067c031f3c2ec073754ef615cc0eabca702fd0fe35729c" dependencies = [ "alloy-chains", "alloy-consensus", @@ -448,7 +413,6 @@ "alloy-primitives", "alloy-pubsub", "alloy-rpc-client", "alloy-rpc-types-debug", - "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-rpc-types-trace", "alloy-signer", @@ -470,7 +434,7 @@ "pin-project", "reqwest", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "url", @@ -479,9 +443,9 @@ ]   [[package]] name = "alloy-pubsub" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97c18795ce1ce8151c5539ce1e4200940389674173f677c7455f79bfb00e5df" +checksum = "810766eeed6b10ffa11815682b3f37afc5019809e3b470b23555297d5770ce63" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -494,7 +458,7 @@ "serde", "serde_json", "tokio", "tokio-stream", - "tower", + "tower 0.5.2", "tracing", "wasmtimer", ] @@ -518,14 +482,14 @@ checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "alloy-rpc-client" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25289674cd8c58fcca2568b5350423cb0dd7bca8c596c5e2869bfe4c5c57ed14" +checksum = "45f802228273056528dfd6cc8845cc91a7c7e0c6fc1a66d19e8673743dacdc7e" dependencies = [ "alloy-json-rpc", "alloy-primitives", @@ -541,7 +505,7 @@ "serde", "serde_json", "tokio", "tokio-stream", - "tower", + "tower 0.5.2", "tracing", "url", "wasmtimer", @@ -549,9 +513,9 @@ ]   [[package]] name = "alloy-rpc-types" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39676beaa50db545cf15447fc94ec5513b64e85a48357a0625b9a04aef08a910" +checksum = "33ff3df608dcabd6bdd197827ff2b8faaa6cefe0c462f7dc5e74108666a01f56" dependencies = [ "alloy-primitives", "alloy-rpc-types-engine", @@ -562,9 +526,9 @@ ]   [[package]] name = "alloy-rpc-types-admin" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65acc9264342069decb617aa344847f55180ba3aeab1c8d1db062d0619881029" +checksum = "00e11a40c917c704888aa5aa6ffa563395123b732868d2e072ec7dd46c3d4672" dependencies = [ "alloy-genesis", "alloy-primitives", @@ -574,9 +538,9 @@ ]   [[package]] name = "alloy-rpc-types-anvil" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9c8cad42fa936000be72ab80fcd97386a6a226c35c2989212756da9e76c1521" +checksum = "ac2bc988d7455e02dfb53460e1caa61f932b3f8452e12424e68ba8dcf60bba90" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -586,9 +550,9 @@ ]   [[package]] name = "alloy-rpc-types-any" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01bac57c987c93773787619e20f89167db74d460a2d1d40f591d94fb7c22c379" +checksum = "cdbf6d1766ca41e90ac21c4bc5cbc5e9e965978a25873c3f90b3992d905db4cb" dependencies = [ "alloy-consensus-any", "alloy-rpc-types-eth", @@ -597,40 +561,41 @@ ]   [[package]] name = "alloy-rpc-types-beacon" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3c0e6cc87a8be5582d08f929f96db25843f44cb636a0985a4a6bf02609c02f" +checksum = "ab94e446a003dcef86843eea60d05a6cec360eb8e1829e4cf388ef94d799b5cf" dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", + "derive_more 2.1.1", "ethereum_ssz", "ethereum_ssz_derive", "serde", "serde_json", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", "tree_hash", "tree_hash_derive", ]   [[package]] name = "alloy-rpc-types-debug" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2fe118e6c152d54cb4549b9835fb87d38b12754bb121375183ee3ec84bd0849" +checksum = "977698b458738369ba5ca645d2cdb4d51ba07a81db37306ff85322853161ea3a" dependencies = [ "alloy-primitives", - "derive_more", + "derive_more 2.1.1", "serde", "serde_with", ]   [[package]] name = "alloy-rpc-types-engine" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a41624eb84bc743e414198bf10eb48b611a5554d6a9fd6205f7384d57dfd7f" +checksum = "07da696cc7fbfead4b1dda8afe408685cae80975cbb024f843ba74d9639cd0d3" dependencies = [ "alloy-consensus", "alloy-eips", @@ -638,7 +603,7 @@ "alloy-primitives", "alloy-rlp", "alloy-serde", "arbitrary", - "derive_more", + "derive_more 2.1.1", "ethereum_ssz", "ethereum_ssz_derive", "jsonwebtoken", @@ -649,9 +614,9 @@ ]   [[package]] name = "alloy-rpc-types-eth" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd1e1b4dcdf13eaa96343e5c0dafc2d2e8ce5d20b90347169d46a1df0dec210" +checksum = "a15e4831b71eea9d20126a411c1c09facf1d01d5cac84fd51d532d3c429cfc26" dependencies = [ "alloy-consensus", "alloy-consensus-any", @@ -666,14 +631,14 @@ "itertools 0.14.0", "serde", "serde_json", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-rpc-types-mev" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01620baa48d3f49fc908c781eb91ded71f3226e719bb6404697c2851cac4e098" +checksum = "4c5d8f6f2c3b68af83a32d5c7fa1353d9b2e30441a3f0b8c3c5657c603b7238c" dependencies = [ "alloy-consensus", "alloy-eips", @@ -686,23 +651,23 @@ ]   [[package]] name = "alloy-rpc-types-trace" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc33d9d0e0b3cfe9c2e82a1a427c9ed516fcfebe764f0adf7ceb8107f702dd1" +checksum = "fb0c800e2ce80829fca1491b3f9063c29092850dc6cf19249d5f678f0ce71bb0" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-rpc-types-txpool" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fa9e9b3e613425d2a2ee1a322bdad5f1cedf835406fd4b59538822500b44bc" +checksum = "2f82e3068673a3cf93fbbc2f60a59059395cd54bbe39af895827faa5e641cc8f" dependencies = [ "alloy-primitives", "alloy-rpc-types-eth", @@ -711,10 +676,27 @@ "serde", ]   [[package]] +name = "alloy-seismic-evm" +version = "0.20.1" +source = "git+https://github.com/SeismicSystems/seismic-evm.git?rev=c33f3076495d153eefbde07dd81c3a575f3d19b8#c33f3076495d153eefbde07dd81c3a575f3d19b8" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-evm", + "alloy-hardforks", + "alloy-primitives", + "auto_impl", + "revm", + "seismic-alloy-consensus", + "seismic-enclave", + "seismic-revm", +] + +[[package]] name = "alloy-serde" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b3b1078b8775077525bc9fe9f6577e815ceaecd6c412a4f3b4d8aa2836e8f6" +checksum = "751d1887f7d202514a82c5b3caf28ee8bd4a2ad9549e4f498b6f0bff99b52add" dependencies = [ "alloy-primitives", "arbitrary", @@ -724,9 +706,9 @@ ]   [[package]] name = "alloy-signer" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10ab1b8d4649bf7d0db8ab04e31658a6cc20364d920795484d886c35bed3bab4" +checksum = "9cf0b42ffbf558badfecf1dde0c3c5ed91f29bb7e97876d0bed008c3d5d67171" dependencies = [ "alloy-primitives", "async-trait", @@ -734,14 +716,14 @@ "auto_impl", "either", "elliptic-curve", "k256", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "alloy-signer-local" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bdeec36c8d9823102b571b3eab8b323e053dc19c12da14a9687bd474129bf2a" +checksum = "3e7d555ee5f27be29af4ae312be014b57c6cff9acb23fe2cf008500be6ca7e33" dependencies = [ "alloy-consensus", "alloy-network", @@ -752,63 +734,60 @@ "coins-bip32", "coins-bip39", "k256", "rand 0.8.5", - "thiserror 2.0.16", + "thiserror 2.0.17", "zeroize", ]   [[package]] name = "alloy-sol-macro" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20d867dcf42019d4779519a1ceb55eba8d7f3d0e4f0a89bcba82b8f9eb01e48" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "alloy-sol-macro-expander" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74e91b0b553c115d14bd0ed41898309356dc85d0e3d4b9014c4e7715e48c8ad" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap 2.11.0", + "indexmap 2.12.1", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", "syn-solidity", "tiny-keccak", ]   [[package]] name = "alloy-sol-macro-input" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84194d31220803f5f62d0a00f583fd3a062b36382e2bea446f1af96727754565" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ + "alloy-json-abi", "const-hex", "dunce", "heck", "macro-string", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", "syn-solidity", ]   [[package]] name = "alloy-sol-type-parser" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe8c27b3cf6b2bb8361904732f955bc7c05e00be5f469cec7e2280b6167f3ff0" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "serde", "winnow", @@ -816,9 +795,8 @@ ]   [[package]] name = "alloy-sol-types" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5383d34ea00079e6dd89c652bcbdb764db160cef84e6250926961a0b2295d04" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "alloy-json-abi", "alloy-primitives", @@ -828,23 +806,22 @@ ]   [[package]] name = "alloy-transport" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce5129146a76ca6139a19832c75ad408857a56bcd18cd2c684183b8eacd78d8" +checksum = "71b3deee699d6f271eab587624a9fa84d02d0755db7a95a043d52a6488d16ebe" dependencies = [ "alloy-json-rpc", - "alloy-primitives", "auto_impl", "base64 0.22.1", - "derive_more", + "derive_more 2.1.1", "futures", "futures-utils-wasm", "parking_lot", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", - "tower", + "tower 0.5.2", "tracing", "url", "wasmtimer", @@ -852,24 +829,24 @@ ]   [[package]] name = "alloy-transport-http" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2379d998f46d422ec8ef2b61603bc28cda931e5e267aea1ebe71f62da61d101" +checksum = "1720bd2ba8fe7e65138aca43bb0f680e4e0bcbd3ca39bf9d3035c9d7d2757f24" dependencies = [ "alloy-json-rpc", "alloy-transport", "reqwest", "serde_json", - "tower", + "tower 0.5.2", "tracing", "url", ]   [[package]] name = "alloy-transport-ipc" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "041aa5db2e907692a9a93a0a908057665c03e59364e1fbbeed613511a0159289" +checksum = "ea89c214c7ddd2bcad100da929d6b642bbfed85788caf3b1be473abacd3111f9" dependencies = [ "alloy-json-rpc", "alloy-pubsub", @@ -887,9 +864,9 @@ ]   [[package]] name = "alloy-transport-ws" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6d44395e6793566e9c89bd82297cc4b0566655c1e78a1d69362640814784cc6" +checksum = "571aadf0afce0d515a28b2c6352662a39cb9f48b4eeff9a5c34557d6ea126730" dependencies = [ "alloy-pubsub", "alloy-transport", @@ -906,18 +883,17 @@ [[package]] name = "alloy-trie" version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5" +source = "git+https://github.com/SeismicSystems/seismic-trie.git?rev=2787e2265d492fa8eaee00424585b8f7e522178f#2787e2265d492fa8eaee00424585b8f7e522178f" dependencies = [ "alloy-primitives", "alloy-rlp", "arbitrary", "arrayvec", "derive_arbitrary", - "derive_more", + "derive_more 2.1.1", "nybbles", "proptest", - "proptest-derive", + "proptest-derive 0.5.1", "serde", "smallvec", "tracing", @@ -925,22 +901,15 @@ ]   [[package]] name = "alloy-tx-macros" -version = "1.0.30" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b5becb9c269a7d05a2f28d549f86df5a5dbc923e2667eff84fdecac8cda534c" +checksum = "cd7ce8ed34106acd6e21942022b6a15be6454c2c3ead4d76811d3bdcd63cf771" dependencies = [ - "alloy-primitives", "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ] - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"   [[package]] name = "android_system_properties" @@ -959,9 +928,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"   [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -974,9 +943,9 @@ ]   [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"   [[package]] name = "anstyle-parse" @@ -989,29 +958,29 @@ ]   [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ]   [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ]   [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"   [[package]] name = "aquamarine" @@ -1024,7 +993,7 @@ "itertools 0.10.5", "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -1166,7 +1135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -1204,7 +1173,7 @@ "num-bigint", "num-traits", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -1293,7 +1262,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -1354,21 +1323,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9"   [[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] name = "async-compression" -version = "0.4.30" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "977eb15ea9efd848bb8a4a1a2500347ed7f0bf794edf0dc3ddcf439f43d36b23" +checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37" dependencies = [ "compression-codecs", "compression-core", @@ -1378,20 +1336,6 @@ "tokio", ]   [[package]] -name = "async-sse" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e6fa871e4334a622afd6bb2f611635e8083a6f5e2936c0f90f37c7ef9856298" -dependencies = [ - "async-channel", - "futures-lite", - "http-types", - "log", - "memchr", - "pin-project-lite", -] - -[[package]] name = "async-stream" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1410,7 +1354,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -1421,7 +1365,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -1459,7 +1403,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -1476,30 +1420,15 @@ checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"   [[package]] name = "backon" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d" +checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" dependencies = [ - "fastrand 2.3.0", + "fastrand", "tokio", ]   [[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] name = "base-x" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1512,10 +1441,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"   [[package]] -name = "base64" -version = "0.13.1" +name = "base256emoji" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "b5e9430d9a245a77c92176e649af6e275f20839a48389859d1661e9a128d077c" +dependencies = [ + "const-str", + "match-lookup", +]   [[package]] name = "base64" @@ -1531,9 +1464,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"   [[package]] name = "base64ct" -version = "1.8.0" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" +checksum = "7d809780667f4410e7c41b07f52439b94d2bdf8528eeedc287fa38d3b7f95d82"   [[package]] name = "bech32" @@ -1582,7 +1515,7 @@ version = "0.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -1591,7 +1524,25 @@ "quote", "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.106", + "syn 2.0.113", +] + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.10.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.1", + "shlex", + "syn 2.0.113", ]   [[package]] @@ -1611,15 +1562,15 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"   [[package]] name = "bitcoin-io" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" +checksum = "2dee39a0ee5b4095224a0cfc6bf4cc1baf0f9624b96b367e53b66d974e51d953"   [[package]] name = "bitcoin_hashes" -version = "0.14.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16" +checksum = "26ec84b80c482df901772e931a9a681e26a1b9ee2302edeff23cb30328745c8b" dependencies = [ "bitcoin-io", "hex-conservative", @@ -1633,12 +1584,12 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"   [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ "arbitrary", - "serde", + "serde_core", ]   [[package]] @@ -1656,15 +1607,6 @@ ]   [[package]] name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" @@ -1683,9 +1625,9 @@ ]   [[package]] name = "blst" -version = "0.3.15" +version = "0.3.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd49896f12ac9b6dcd7a5998466b9b58263a695a3dd1ecc1aaca2e12a90b080" +checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45" dependencies = [ "cc", "glob", @@ -1694,149 +1636,33 @@ "zeroize", ]   [[package]] -name = "boa_ast" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c340fe0f0b267787095cbe35240c6786ff19da63ec7b69367ba338eace8169b" -dependencies = [ - "bitflags 2.9.4", - "boa_interner", - "boa_macros", - "boa_string", - "indexmap 2.11.0", - "num-bigint", - "rustc-hash 2.1.1", -] - -[[package]] -name = "boa_engine" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f620c3f06f51e65c0504ddf04978be1b814ac6586f0b45f6019801ab5efd37f9" -dependencies = [ - "arrayvec", - "bitflags 2.9.4", - "boa_ast", - "boa_gc", - "boa_interner", - "boa_macros", - "boa_parser", - "boa_profiler", - "boa_string", - "bytemuck", - "cfg-if", - "dashmap 6.1.0", - "fast-float2", - "hashbrown 0.15.5", - "icu_normalizer 1.5.0", - "indexmap 2.11.0", - "intrusive-collections", - "itertools 0.13.0", - "num-bigint", - "num-integer", - "num-traits", - "num_enum", - "once_cell", - "pollster", - "portable-atomic", - "rand 0.8.5", - "regress", - "rustc-hash 2.1.1", - "ryu-js", - "serde", - "serde_json", - "sptr", - "static_assertions", - "tap", - "thin-vec", - "thiserror 2.0.16", - "time", -] - -[[package]] -name = "boa_gc" -version = "0.20.0" +name = "borsh" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2425c0b7720d42d73eaa6a883fbb77a5c920da8694964a3d79a67597ac55cce2" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" dependencies = [ - "boa_macros", - "boa_profiler", - "boa_string", - "hashbrown 0.15.5", - "thin-vec", + "borsh-derive", + "cfg_aliases", ]   [[package]] -name = "boa_interner" -version = "0.20.0" +name = "borsh-derive" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42407a3b724cfaecde8f7d4af566df4b56af32a2f11f0956f5570bb974e7f749" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" dependencies = [ - "boa_gc", - "boa_macros", - "hashbrown 0.15.5", - "indexmap 2.11.0", "once_cell", - "phf", - "rustc-hash 2.1.1", - "static_assertions", -] - -[[package]] -name = "boa_macros" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fd3f870829131332587f607a7ff909f1af5fc523fd1b192db55fbbdf52e8d3c" -dependencies = [ + "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.106", - "synstructure", -] - -[[package]] -name = "boa_parser" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc142dac798cdc6e2dbccfddeb50f36d2523bb977a976e19bdb3ae19b740804" -dependencies = [ - "bitflags 2.9.4", - "boa_ast", - "boa_interner", - "boa_macros", - "boa_profiler", - "fast-float2", - "icu_properties 1.5.1", - "num-bigint", - "num-traits", - "regress", - "rustc-hash 2.1.1", -] - -[[package]] -name = "boa_profiler" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4064908e7cdf9b6317179e9b04dcb27f1510c1c144aeab4d0394014f37a0f922" - -[[package]] -name = "boa_string" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7debc13fbf7997bf38bf8e9b20f1ad5e2a7d27a900e1f6039fe244ce30f589b5" -dependencies = [ - "fast-float2", - "paste", - "rustc-hash 2.1.1", - "sptr", - "static_assertions", + "syn 2.0.113", ]   [[package]] name = "boyer-moore-magiclen" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95e6233f2d926b5b123caf9d58e3885885255567fbe7776a7fdcae2a4d7241c4" +checksum = "7441b4796eb8a7107d4cd99d829810be75f5573e1081c37faa0e8094169ea0d6" dependencies = [ "debug-helper", ] @@ -1868,15 +1694,15 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "sha2 0.10.9", + "sha2", "tinyvec", ]   [[package]] name = "bstr" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", @@ -1885,9 +1711,9 @@ ]   [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"   [[package]] name = "byte-slice-cast" @@ -1903,23 +1729,9 @@ checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e"   [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" -dependencies = [ - "bytemuck_derive", -] - -[[package]] -name = "bytemuck_derive" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"   [[package]] name = "byteorder" @@ -1929,18 +1741,18 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"   [[package]] name = "bytes" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" dependencies = [ "serde", ]   [[package]] name = "c-kzg" -version = "2.1.1" +version = "2.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7318cfa722931cb5fe0838b98d3ce5621e75f6a6408abc21721d80de9223f2e4" +checksum = "e00bf4b112b07b505472dbefd19e37e53307e2bfed5a79e0cc161d58ccd0e687" dependencies = [ "arbitrary", "blst", @@ -1954,11 +1766,11 @@ ]   [[package]] name = "camino" -version = "1.1.12" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ - "serde", + "serde_core", ]   [[package]] @@ -1978,7 +1790,7 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.26", + "semver 1.0.27", "serde", "serde_json", ] @@ -1991,10 +1803,10 @@ checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", "cargo-platform", - "semver 1.0.26", + "semver 1.0.27", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -2046,9 +1858,9 @@ ]   [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"   [[package]] name = "cfg_aliases" @@ -2058,17 +1870,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"   [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link 0.1.3", + "windows-link", ]   [[package]] @@ -2121,9 +1932,9 @@ ]   [[package]] name = "clap" -version = "4.5.47" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "c6e6ff9dcd79cff5cd969a17a545d79e84ab086e444102a591e288a8aa3ce394" dependencies = [ "clap_builder", "clap_derive", @@ -2131,9 +1942,9 @@ ]   [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "fa42cf4d2b7a41bc8f663a7cab4031ebafa1bf3875705bfaf8466dc60ab52c00" dependencies = [ "anstream", "anstyle", @@ -2143,21 +1954,21 @@ ]   [[package]] name = "clap_derive" -version = "4.5.47" +version = "4.5.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"   [[package]] name = "cmake" @@ -2235,7 +2046,7 @@ "digest 0.10.7", "hmac", "k256", "serde", - "sha2 0.10.9", + "sha2", "thiserror 1.0.69", ]   @@ -2251,7 +2062,7 @@ "hmac", "once_cell", "pbkdf2", "rand 0.8.5", - "sha2 0.10.9", + "sha2", "thiserror 1.0.69", ]   @@ -2269,7 +2080,7 @@ "digest 0.10.7", "generic-array", "ripemd", "serde", - "sha2 0.10.9", + "sha2", "sha3", "thiserror 1.0.69", ] @@ -2302,9 +2113,9 @@ ]   [[package]] name = "comfy-table" -version = "7.2.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f8e18d0dca9578507f13f9803add0df13362b02c501c1c17734f0dbb52eaf0b" +checksum = "b03b7db8e0b4b2fdad6c551e634134e99ec000e5c8c3b6856c65e8bbaded7a3b" dependencies = [ "crossterm 0.29.0", "unicode-segmentation", @@ -2327,9 +2138,9 @@ ]   [[package]] name = "compression-codecs" -version = "0.4.30" +version = "0.4.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "485abf41ac0c8047c07c87c72c8fb3eb5197f6e9d7ded615dfd1a00ae00a0f64" +checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" dependencies = [ "brotli", "compression-core", @@ -2341,9 +2152,9 @@ ]   [[package]] name = "compression-core" -version = "0.4.29" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb" +checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d"   [[package]] name = "concat-kdf" @@ -2355,15 +2166,6 @@ "digest 0.10.7", ]   [[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] name = "console" version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2377,15 +2179,14 @@ ]   [[package]] name = "const-hex" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dccd746bf9b1038c0507b7cec21eb2b11222db96a2902c96e8c185d6d20fb9c4" +checksum = "3bb320cac8a0750d7f25280aa97b09c26edfe161164238ecbbb31092b079e735" dependencies = [ "cfg-if", "cpufeatures", - "hex", "proptest", - "serde", + "serde_core", ]   [[package]] @@ -2395,10 +2196,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"   [[package]] +name = "const-str" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f421161cb492475f1661ddc9815a745a1c894592070661180fdec3d4872e9c3" + +[[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] @@ -2419,12 +2226,31 @@ name = "convert_case" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb402b8d4c85569410425650ce3eddc7d698ed96d39a73f941b08fb63082f1e7" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" dependencies = [ "unicode-segmentation", ]   [[package]] name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" @@ -2459,9 +2285,9 @@ ]   [[package]] name = "crc" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" dependencies = [ "crc-catalog", ] @@ -2537,7 +2363,7 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "crossterm_winapi", "mio", "parking_lot", @@ -2553,11 +2379,11 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "crossterm_winapi", "document-features", "parking_lot", - "rustix 1.0.8", + "rustix 1.1.3", "winapi", ]   @@ -2590,9 +2416,9 @@ ]   [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -2600,27 +2426,6 @@ "typenum", ]   [[package]] -name = "csv" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "csv-core" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" -dependencies = [ - "memchr", -] - -[[package]] name = "ctr" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2653,7 +2458,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -2677,6 +2482,16 @@ "darling_macro 0.21.3", ]   [[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] name = "darling_core" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2687,7 +2502,7 @@ "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -2702,7 +2517,20 @@ "proc-macro2", "quote", "serde", "strsim", - "syn 2.0.106", + "syn 2.0.113", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.113", ]   [[package]] @@ -2713,7 +2541,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -2724,7 +2552,18 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.106", + "syn 2.0.113", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.113", ]   [[package]] @@ -2777,7 +2616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d162beedaa69905488a8da94f5ac3edb4dd4788b732fadb7bd120b2625c1976" dependencies = [ "data-encoding", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -2809,12 +2648,12 @@ ]   [[package]] name = "deranged" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", - "serde", + "serde_core", ]   [[package]] @@ -2836,7 +2675,7 @@ checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -2847,7 +2686,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -2868,7 +2707,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -2878,28 +2717,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "derive_more" -version = "2.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "derive_more-impl", + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl 2.1.1", ]   [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "convert_case", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "convert_case 0.10.0", + "proc-macro2", + "quote", + "rustc_version 0.4.1", + "syn 2.0.113", "unicode-xid", ]   @@ -2924,7 +2785,7 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer 0.10.4", + "block-buffer", "const-oid", "crypto-common", "subtle", @@ -2958,7 +2819,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.61.0", + "windows-sys 0.61.2", ]   [[package]] @@ -3013,7 +2874,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -3024,9 +2885,9 @@ checksum = "aac81fa3e28d21450aa4d2ac065992ba96a1d7303efbce51a95f4fd175b67562"   [[package]] name = "document-features" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" dependencies = [ "litrs", ] @@ -3078,7 +2939,7 @@ "curve25519-dalek", "ed25519", "rand_core 0.6.4", "serde", - "sha2 0.10.9", + "sha2", "subtle", "zeroize", ] @@ -3092,7 +2953,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -3130,9 +2991,10 @@ "reth-tracing", "reth-trie", "reth-trie-db", "revm", + "seismic-alloy-genesis", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "walkdir", ]   @@ -3200,27 +3062,27 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "enum-ordinalize" -version = "4.3.0" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0" dependencies = [ "enum-ordinalize-derive", ]   [[package]] name = "enum-ordinalize-derive" -version = "4.3.1" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -3231,12 +3093,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"   [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ]   [[package]] @@ -3256,7 +3118,7 @@ checksum = "c853bd72c9e5787f8aafc3df2907c2ed03cff3150c3acd94e2e53a98ab70a8ab" dependencies = [ "cpufeatures", "ring", - "sha2 0.10.9", + "sha2", ]   [[package]] @@ -3274,9 +3136,9 @@ ]   [[package]] name = "ethereum_ssz" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca8ba45b63c389c6e115b095ca16381534fdcc03cf58176a3f8554db2dbe19b" +checksum = "0dcddb2554d19cde19b099fadddde576929d7a4d0c1cd3512d1fd95cf174375c" dependencies = [ "alloy-primitives", "ethereum_serde_utils", @@ -3289,434 +3151,14 @@ ]   [[package]] name = "ethereum_ssz_derive" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd55d08012b4e0dfcc92b8d6081234df65f2986ad34cc76eeed69c5e2ce7506" +checksum = "a657b6b3b7e153637dc6bdc6566ad9279d9ee11a15b12cfb24a2e04360637e9f" dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.106", -] - -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "example-beacon-api-sidecar-fetcher" -version = "0.1.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rpc-types-beacon", - "clap", - "eyre", - "futures-util", - "reqwest", - "reth-ethereum", - "serde", - "serde_json", - "thiserror 2.0.16", -] - -[[package]] -name = "example-beacon-api-sse" -version = "0.0.0" -dependencies = [ - "alloy-rpc-types-beacon", - "clap", - "futures-util", - "mev-share-sse", - "reth-ethereum", - "tokio", - "tracing", -] - -[[package]] -name = "example-bsc-p2p" -version = "0.0.0" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "alloy-rpc-types", - "bytes", - "futures", - "reth-chainspec", - "reth-discv4", - "reth-engine-primitives", - "reth-eth-wire", - "reth-eth-wire-types", - "reth-ethereum-forks", - "reth-network", - "reth-network-api", - "reth-network-peers", - "reth-node-ethereum", - "reth-payload-primitives", - "reth-primitives", - "reth-primitives-traits", - "reth-provider", - "reth-tracing", - "secp256k1 0.30.0", - "serde", - "serde_json", - "thiserror 2.0.16", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "example-custom-beacon-withdrawals" -version = "0.0.0" -dependencies = [ - "alloy-eips", - "alloy-evm", - "alloy-sol-macro", - "alloy-sol-types", - "eyre", - "reth-ethereum", -] - -[[package]] -name = "example-custom-dev-node" -version = "0.0.0" -dependencies = [ - "alloy-genesis", - "alloy-primitives", - "eyre", - "futures-util", - "reth-ethereum", - "serde_json", - "tokio", -] - -[[package]] -name = "example-custom-engine-types" -version = "0.0.0" -dependencies = [ - "alloy-eips", - "alloy-genesis", - "alloy-primitives", - "alloy-rpc-types", - "eyre", - "reth-basic-payload-builder", - "reth-ethereum", - "reth-ethereum-payload-builder", - "reth-payload-builder", - "reth-tracing", - "serde", - "thiserror 2.0.16", - "tokio", -] - -[[package]] -name = "example-custom-evm" -version = "0.0.0" -dependencies = [ - "alloy-evm", - "alloy-genesis", - "alloy-primitives", - "eyre", - "reth-ethereum", - "reth-tracing", - "tokio", -] - -[[package]] -name = "example-custom-inspector" -version = "0.0.0" -dependencies = [ - "alloy-eips", - "alloy-evm", - "alloy-primitives", - "alloy-rpc-types-eth", - "clap", - "futures-util", - "reth-ethereum", -] - -[[package]] -name = "example-custom-node" -version = "0.0.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-evm", - "alloy-genesis", - "alloy-network", - "alloy-op-evm", - "alloy-primitives", - "alloy-rlp", - "alloy-rpc-types-engine", - "alloy-rpc-types-eth", - "alloy-serde", - "async-trait", - "derive_more", - "eyre", - "jsonrpsee", - "modular-bitfield", - "op-alloy-consensus", - "op-alloy-rpc-types", - "op-alloy-rpc-types-engine", - "op-revm", - "reth-chain-state", - "reth-codecs", - "reth-db-api", - "reth-engine-primitives", - "reth-ethereum", - "reth-network-peers", - "reth-node-builder", - "reth-op", - "reth-optimism-flashblocks", - "reth-optimism-forks", - "reth-payload-builder", - "reth-rpc-api", - "reth-rpc-engine-api", - "revm", - "revm-primitives", - "serde", - "test-fuzz", - "thiserror 2.0.16", -] - -[[package]] -name = "example-custom-node-components" -version = "0.0.0" -dependencies = [ - "eyre", - "reth-ethereum", - "reth-tracing", -] - -[[package]] -name = "example-custom-payload-builder" -version = "0.0.0" -dependencies = [ - "alloy-eips", - "eyre", - "futures-util", - "reth-basic-payload-builder", - "reth-ethereum", - "reth-ethereum-payload-builder", - "reth-payload-builder", - "tracing", -] - -[[package]] -name = "example-custom-rlpx-subprotocol" -version = "0.0.0" -dependencies = [ - "alloy-primitives", - "eyre", - "futures", - "reth-ethereum", - "tokio", - "tokio-stream", - "tracing", -] - -[[package]] -name = "example-db-access" -version = "0.0.0" -dependencies = [ - "alloy-primitives", - "eyre", - "reth-ethereum", -] - -[[package]] -name = "example-engine-api-access" -version = "0.0.0" -dependencies = [ - "reth-db", - "reth-node-builder", - "reth-optimism-chainspec", - "reth-optimism-node", - "tokio", -] - -[[package]] -name = "example-exex-hello-world" -version = "0.0.0" -dependencies = [ - "clap", - "eyre", - "futures", - "reth-ethereum", - "reth-op", - "reth-tracing", - "tokio", -] - -[[package]] -name = "example-exex-test" -version = "0.0.0" -dependencies = [ - "eyre", - "futures-util", - "reth-e2e-test-utils", - "reth-ethereum", - "serde_json", - "tokio", -] - -[[package]] -name = "example-full-contract-state" -version = "1.7.0" -dependencies = [ - "eyre", - "reth-ethereum", -] - -[[package]] -name = "example-manual-p2p" -version = "0.0.0" -dependencies = [ - "alloy-consensus", - "eyre", - "futures", - "reth-discv4", - "reth-ecies", - "reth-ethereum", - "reth-network-peers", - "secp256k1 0.30.0", - "tokio", -] - -[[package]] -name = "example-network" -version = "0.0.0" -dependencies = [ - "eyre", - "futures", - "reth-ethereum", - "tokio", -] - -[[package]] -name = "example-network-proxy" -version = "0.0.0" -dependencies = [ - "eyre", - "futures", - "reth-ethereum", - "reth-tracing", - "tokio", -] - -[[package]] -name = "example-network-txpool" -version = "0.0.0" -dependencies = [ - "eyre", - "reth-ethereum", - "tokio", -] - -[[package]] -name = "example-node-builder-api" -version = "0.0.0" -dependencies = [ - "reth-ethereum", -] - -[[package]] -name = "example-node-custom-rpc" -version = "0.0.0" -dependencies = [ - "clap", - "jsonrpsee", - "reth-ethereum", - "serde_json", - "tokio", -] - -[[package]] -name = "example-node-event-hooks" -version = "0.0.0" -dependencies = [ - "reth-ethereum", -] - -[[package]] -name = "example-op-db-access" -version = "0.0.0" -dependencies = [ - "eyre", - "reth-op", -] - -[[package]] -name = "example-polygon-p2p" -version = "0.0.0" -dependencies = [ - "alloy-genesis", - "reth-discv4", - "reth-ethereum", - "reth-tracing", - "secp256k1 0.30.0", - "serde_json", - "tokio", - "tokio-stream", -] - -[[package]] -name = "example-precompile-cache" -version = "0.0.0" -dependencies = [ - "alloy-evm", - "alloy-genesis", - "alloy-primitives", - "eyre", - "parking_lot", - "reth-ethereum", - "reth-tracing", - "schnellru", - "tokio", -] - -[[package]] -name = "example-rpc-db" -version = "0.0.0" -dependencies = [ - "eyre", - "futures", - "jsonrpsee", - "reth-ethereum", - "tokio", -] - -[[package]] -name = "example-txpool-tracing" -version = "0.0.0" -dependencies = [ - "alloy-network", - "alloy-primitives", - "alloy-rpc-types-trace", - "clap", - "eyre", - "futures-util", - "reth-ethereum", -] - -[[package]] -name = "exex-subscription" -version = "1.7.0" -dependencies = [ - "alloy-primitives", - "clap", - "eyre", - "futures", - "jsonrpsee", - "reth-ethereum", - "serde", - "serde_json", - "tokio", - "tracing", + "syn 2.0.113", ]   [[package]] @@ -3727,21 +3169,6 @@ checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", -] - -[[package]] -name = "fast-float2" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8eb564c5c7423d25c886fb561d1e4ee69f72354d16918afa32c08811f6b6a55" - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", ]   [[package]] @@ -3824,9 +3251,9 @@ ]   [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", @@ -3845,6 +3272,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"   [[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] name = "form_urlencoded" version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3917,21 +3365,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"   [[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - -[[package]] name = "futures-macro" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3939,7 +3372,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -3990,16 +3423,17 @@ checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9"   [[package]] name = "generator" -version = "0.8.7" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "605183a538e3e2a9c1038635cc5c2d194e2ee8fd0d1b66b8349fad7dbacce5a2" +checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" dependencies = [ "cc", "cfg-if", "libc", "log", "rustversion", - "windows 0.61.3", + "windows-link", + "windows-result 0.4.1", ]   [[package]] @@ -4015,14 +3449,13 @@ "zeroize", ]   [[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +name = "genesis-builder" +version = "1.7.0" dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", + "clap", + "reth-genesis-builder", + "tracing", + "tracing-subscriber 0.3.22", ]   [[package]] @@ -4034,25 +3467,35 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ]   [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi", - "wasi 0.14.4+wasi-0.2.4", + "wasip2", "wasm-bindgen", ]   [[package]] +name = "getrandom_or_panic" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" +dependencies = [ + "rand 0.8.5", + "rand_core 0.6.4", +] + +[[package]] name = "ghash" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4063,18 +3506,12 @@ "polyval", ]   [[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] name = "git2" -version = "0.20.2" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2deb07a133b1520dc1a5690e9bd08950108873d7ed5de38dcc74d3b5ebffa110" +checksum = "3e2b37e2f62729cdada11f0e6b3b6fe383c69c29fc619e391223e12856af308c" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", "libgit2-sys", "log", @@ -4156,9 +3593,9 @@ ]   [[package]] name = "h2" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" dependencies = [ "atomic-waker", "bytes", @@ -4166,7 +3603,7 @@ "fnv", "futures-core", "futures-sink", "http", - "indexmap 2.11.0", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -4175,12 +3612,13 @@ ]   [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", ]   [[package]] @@ -4218,8 +3656,18 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash 0.2.0", "serde", + "serde_core", ]   [[package]] @@ -4258,15 +3706,12 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -]   [[package]] name = "hex-conservative" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd" +checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f" dependencies = [ "arrayvec", ] @@ -4290,7 +3735,7 @@ "once_cell", "rand 0.9.2", "ring", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tinyvec", "tokio", "tracing", @@ -4314,7 +3759,7 @@ "rand 0.9.2", "resolv-conf", "serde", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -4339,12 +3784,11 @@ ]   [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ]   @@ -4378,26 +3822,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c"   [[package]] -name = "http-types" -version = "2.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9b187a72d63adbfba487f48095306ac823049cb504ee195541e91c7775f5ad" -dependencies = [ - "anyhow", - "async-channel", - "base64 0.13.1", - "futures-lite", - "infer", - "pin-project-lite", - "rand 0.7.3", - "serde", - "serde_json", - "serde_qs", - "serde_urlencoded", - "url", -] - -[[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4417,9 +3841,9 @@ checksum = "91f255a4535024abf7640cb288260811fc14794f62b063652ed349f9a6c2348e"   [[package]] name = "humantime" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"   [[package]] name = "humantime-serde" @@ -4433,9 +3857,9 @@ ]   [[package]] name = "hyper" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", @@ -4470,14 +3894,30 @@ "rustls-pki-types", "tokio", "tokio-rustls", "tower-service", - "webpki-roots 1.0.2", + "webpki-roots 1.0.5", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", ]   [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "base64 0.22.1", "bytes", @@ -4491,7 +3931,7 @@ "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2 0.6.1", "tokio", "tower-service", "tracing", @@ -4499,9 +3939,9 @@ ]   [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -4509,7 +3949,7 @@ "iana-time-zone-haiku", "js-sys", "log", "wasm-bindgen", - "windows-core 0.61.2", + "windows-core 0.62.2", ]   [[package]] @@ -4523,206 +3963,83 @@ ]   [[package]] name = "icu_collections" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" -dependencies = [ - "displaydoc", - "yoke 0.7.5", - "zerofrom", - "zerovec 0.10.4", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", - "yoke 0.8.0", + "yoke", "zerofrom", - "zerovec 0.11.4", + "zerovec", ]   [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", - "litemap 0.8.0", - "tinystr 0.8.1", - "writeable 0.6.1", - "zerovec 0.11.4", + "litemap", + "tinystr", + "writeable", + "zerovec", ]   [[package]] -name = "icu_locid" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" -dependencies = [ - "displaydoc", - "litemap 0.7.5", - "tinystr 0.7.6", - "writeable 0.5.5", - "zerovec 0.10.4", -] - -[[package]] -name = "icu_locid_transform" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider 1.5.0", - "tinystr 0.7.6", - "zerovec 0.10.4", -] - -[[package]] -name = "icu_locid_transform_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" - -[[package]] name = "icu_normalizer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" -dependencies = [ - "displaydoc", - "icu_collections 1.5.0", - "icu_normalizer_data 1.5.1", - "icu_properties 1.5.1", - "icu_provider 1.5.0", - "smallvec", - "utf16_iter", - "utf8_iter", - "write16", - "zerovec 0.10.4", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", - "icu_collections 2.0.0", - "icu_normalizer_data 2.0.0", - "icu_properties 2.0.1", - "icu_provider 2.0.0", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", "smallvec", - "zerovec 0.11.4", + "zerovec", ]   [[package]] name = "icu_normalizer_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "1.5.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" -dependencies = [ - "displaydoc", - "icu_collections 1.5.0", - "icu_locid_transform", - "icu_properties_data 1.5.1", - "icu_provider 1.5.0", - "tinystr 0.7.6", - "zerovec 0.10.4", -] +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a"   [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ - "displaydoc", - "icu_collections 2.0.0", + "icu_collections", "icu_locale_core", - "icu_properties_data 2.0.1", - "icu_provider 2.0.0", - "potential_utf", + "icu_properties_data", + "icu_provider", "zerotrie", - "zerovec 0.11.4", + "zerovec", ]   [[package]] name = "icu_properties_data" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "1.5.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" -dependencies = [ - "displaydoc", - "icu_locid", - "icu_provider_macros", - "stable_deref_trait", - "tinystr 0.7.6", - "writeable 0.5.5", - "yoke 0.7.5", - "zerofrom", - "zerovec 0.10.4", -] +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af"   [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr 0.8.1", - "writeable 0.6.1", - "yoke 0.8.0", + "writeable", + "yoke", "zerofrom", "zerotrie", - "zerovec 0.11.4", -] - -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "zerovec", ]   [[package]] @@ -4748,8 +4065,8 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ - "icu_normalizer 2.0.0", - "icu_properties 2.0.1", + "icu_normalizer", + "icu_properties", ]   [[package]] @@ -4779,7 +4096,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -4820,27 +4137,25 @@ ]   [[package]] name = "indexmap" -version = "2.11.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "serde", + "serde_core", ]   [[package]] name = "indoc" -version = "2.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" - -[[package]] -name = "infer" -version = "0.2.3" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e9829a50b42bb782c1df523f78d332fe371b10c661e78b7a3c34b0198e9fac" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +]   [[package]] name = "inotify" @@ -4848,7 +4163,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "inotify-sys", "libc", ] @@ -4874,24 +4189,15 @@ ]   [[package]] name = "instability" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" +checksum = "357b7205c6cd18dd2c86ed312d1e70add149aea98e7ef72b9fdf0270e555c11d" dependencies = [ - "darling 0.20.11", + "darling 0.23.0", "indoc", "proc-macro2", "quote", - "syn 2.0.106", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", + "syn 2.0.113", ]   [[package]] @@ -4910,26 +4216,6 @@ "windows-sys 0.52.0", ]   [[package]] -name = "intrusive-collections" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "189d0897e4cbe8c75efedf3502c18c887b05046e59d28404d4d8e46cbc4d1e86" -dependencies = [ - "memoffset", -] - -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - -[[package]] name = "ipconfig" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4949,9 +4235,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"   [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" dependencies = [ "memchr", "serde", @@ -4959,20 +4245,20 @@ ]   [[package]] name = "is-terminal" -version = "0.4.16" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ]   [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"   [[package]] name = "itertools" @@ -5003,9 +4289,9 @@ ]   [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"   [[package]] name = "jni" @@ -5035,15 +4321,15 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ]   [[package]] name = "js-sys" -version = "0.3.78" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -5051,24 +4337,65 @@ ]   [[package]] name = "jsonrpsee" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e281ae70cc3b98dac15fced3366a880949e65fc66e345ce857a5682d152f3e62" +dependencies = [ + "jsonrpsee-client-transport 0.24.10", + "jsonrpsee-core 0.24.10", + "jsonrpsee-http-client 0.24.10", + "jsonrpsee-proc-macros 0.24.10", + "jsonrpsee-types 0.24.10", + "jsonrpsee-wasm-client 0.24.10", + "jsonrpsee-ws-client 0.24.10", + "tracing", +] + +[[package]] +name = "jsonrpsee" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f3f48dc3e6b8bd21e15436c1ddd0bc22a6a54e8ec46fedd6adf3425f396ec6a" dependencies = [ - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-http-client", - "jsonrpsee-proc-macros", + "jsonrpsee-client-transport 0.26.0", + "jsonrpsee-core 0.26.0", + "jsonrpsee-http-client 0.26.0", + "jsonrpsee-proc-macros 0.26.0", "jsonrpsee-server", - "jsonrpsee-types", - "jsonrpsee-wasm-client", - "jsonrpsee-ws-client", + "jsonrpsee-types 0.26.0", + "jsonrpsee-wasm-client 0.26.0", + "jsonrpsee-ws-client 0.26.0", "tokio", "tracing", ]   [[package]] name = "jsonrpsee-client-transport" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4280b709ac3bb5e16cf3bad5056a0ec8df55fa89edfe996361219aadc2c7ea" +dependencies = [ + "base64 0.22.1", + "futures-channel", + "futures-util", + "gloo-net", + "http", + "jsonrpsee-core 0.24.10", + "pin-project", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "soketto", + "thiserror 1.0.69", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-client-transport" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf36eb27f8e13fa93dcb50ccb44c417e25b818cfa1a481b5470cd07b19c60b98" @@ -5078,13 +4405,13 @@ "futures-channel", "futures-util", "gloo-net", "http", - "jsonrpsee-core", + "jsonrpsee-core 0.26.0", "pin-project", "rustls", "rustls-pki-types", "rustls-platform-verifier", "soketto", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-rustls", "tokio-util", @@ -5094,6 +4421,33 @@ ]   [[package]] name = "jsonrpsee-core" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "348ee569eaed52926b5e740aae20863762b16596476e943c9e415a6479021622" +dependencies = [ + "async-trait", + "bytes", + "futures-timer", + "futures-util", + "http", + "http-body", + "http-body-util", + "jsonrpsee-types 0.24.10", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tracing", + "wasm-bindgen-futures", +] + +[[package]] +name = "jsonrpsee-core" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "316c96719901f05d1137f19ba598b5fe9c9bc39f4335f67f6be8613921946480" @@ -5105,23 +4459,48 @@ "futures-util", "http", "http-body", "http-body-util", - "jsonrpsee-types", + "jsonrpsee-types 0.26.0", "parking_lot", "pin-project", "rand 0.9.2", "rustc-hash 2.1.1", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", - "tower", + "tower 0.5.2", "tracing", "wasm-bindgen-futures", ]   [[package]] name = "jsonrpsee-http-client" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f50c389d6e6a52eb7c3548a6600c90cf74d9b71cb5912209833f00a5479e9a01" +dependencies = [ + "async-trait", + "base64 0.22.1", + "http-body", + "hyper", + "hyper-rustls", + "hyper-util", + "jsonrpsee-core 0.24.10", + "jsonrpsee-types 0.24.10", + "rustls", + "rustls-platform-verifier", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tower 0.4.13", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-http-client" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "790bedefcec85321e007ff3af84b4e417540d5c87b3c9779b9e247d1bcc3dab8" @@ -5131,20 +4510,33 @@ "http-body", "hyper", "hyper-rustls", "hyper-util", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.26.0", + "jsonrpsee-types 0.26.0", "rustls", "rustls-platform-verifier", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", - "tower", + "tower 0.5.2", "url", ]   [[package]] name = "jsonrpsee-proc-macros" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7398cddf5013cca4702862a2692b66c48a3bd6cf6ec681a47453c93d63cf8de5" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.113", +] + +[[package]] +name = "jsonrpsee-proc-macros" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da3f8ab5ce1bb124b6d082e62dffe997578ceaf0aeb9f3174a214589dc00f07" @@ -5153,7 +4545,7 @@ "heck", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -5168,23 +4560,35 @@ "http-body", "http-body-util", "hyper", "hyper-util", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.26.0", + "jsonrpsee-types 0.26.0", "pin-project", "route-recognizer", "serde", "serde_json", "soketto", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", - "tower", + "tower 0.5.2", "tracing", ]   [[package]] name = "jsonrpsee-types" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0f05e0028e55b15dbd2107163b3c744cd3bb4474f193f95d9708acbf5677e44" +dependencies = [ + "http", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonrpsee-types" version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc88ff4688e43cc3fa9883a8a95c6fa27aa2e76c96e610b737b6554d650d7fd5" @@ -5192,7 +4596,18 @@ dependencies = [ "http", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", +] + +[[package]] +name = "jsonrpsee-wasm-client" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d745e4f543fc10fc0e2b11aa1f3be506b1e475d412167e7191a65ecd239f1c" +dependencies = [ + "jsonrpsee-client-transport 0.24.10", + "jsonrpsee-core 0.24.10", + "jsonrpsee-types 0.24.10", ]   [[package]] @@ -5201,10 +4616,23 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7902885de4779f711a95d82c8da2d7e5f9f3a7c7cfa44d51c067fd1c29d72a3c" dependencies = [ - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", - "tower", + "jsonrpsee-client-transport 0.26.0", + "jsonrpsee-core 0.26.0", + "jsonrpsee-types 0.26.0", + "tower 0.5.2", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.24.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78fc744f17e7926d57f478cf9ca6e1ee5d8332bf0514860b1a3cdf1742e614cc" +dependencies = [ + "http", + "jsonrpsee-client-transport 0.24.10", + "jsonrpsee-core 0.24.10", + "jsonrpsee-types 0.24.10", + "url", ]   [[package]] @@ -5214,10 +4642,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b6fceceeb05301cc4c065ab3bd2fa990d41ff4eb44e4ca1b30fa99c057c3e79" dependencies = [ "http", - "jsonrpsee-client-transport", - "jsonrpsee-core", - "jsonrpsee-types", - "tower", + "jsonrpsee-client-transport 0.26.0", + "jsonrpsee-core 0.26.0", + "jsonrpsee-types 0.26.0", + "tower 0.5.2", "url", ]   @@ -5247,7 +4675,7 @@ "ecdsa", "elliptic-curve", "once_cell", "serdect", - "sha2 0.10.9", + "sha2", "signature", ]   @@ -5298,15 +4726,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"   [[package]] name = "libc" -version = "0.2.175" +version = "0.2.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f"   [[package]] name = "libgit2-sys" -version = "0.18.2+1.9.1" +version = "0.18.3+1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c42fe03df2bd3c53a3a9c7317ad91d80c81cd1fb0caec8d7cc4cd2bfa10c222" +checksum = "c9b3acc4b91781bb0b3386669d325163746af5f6e4f73e6d2d630e09a35f3487" dependencies = [ "cc", "libc", @@ -5316,12 +4744,12 @@ ]   [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link", ]   [[package]] @@ -5332,9 +4760,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"   [[package]] name = "libp2p-identity" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3104e13b51e4711ff5738caa1fb54467c8604c2e94d607e27745bcf709068774" +checksum = "f0c7892c221730ba55f7196e98b0b8ba5e04b4155651736036628e9f73ed6fc3" dependencies = [ "asn1_der", "bs58", @@ -5343,85 +4771,39 @@ "hkdf", "k256", "multihash", "quick-protobuf", - "sha2 0.10.9", - "thiserror 2.0.16", + "sha2", + "thiserror 2.0.17", "tracing", "zeroize", ]   [[package]] name = "libproc" -version = "0.14.10" +version = "0.14.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78a09b56be5adbcad5aa1197371688dc6bb249a26da3bca2011ee2fb987ebfb" +checksum = "a54ad7278b8bc5301d5ffd2a94251c004feb971feba96c971ea4063645990757" dependencies = [ - "bindgen", + "bindgen 0.72.1", "errno", "libc", ]   [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", - "redox_syscall", -] - -[[package]] -name = "libsecp256k1" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79019718125edc905a079a70cfa5f3820bc76139fc91d6f9abc27ea2a887139" -dependencies = [ - "arrayref", - "base64 0.22.1", - "digest 0.9.0", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand 0.8.5", - "serde", - "sha2 0.9.9", -] - -[[package]] -name = "libsecp256k1-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" -dependencies = [ - "libsecp256k1-core", + "redox_syscall 0.7.0", ]   [[package]] name = "libz-sys" -version = "1.1.22" +version = "1.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" dependencies = [ "cc", "libc", @@ -5437,12 +4819,12 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"   [[package]] name = "linked_hash_set" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae85b5be22d9843c80e5fc80e9b64c8a3b1f98f867c709956eca3efff4e92e2" +checksum = "984fb35d06508d1e69fc91050cceba9c0b748f983e6739fa2c7a9237154c52c8" dependencies = [ "linked-hash-map", - "serde", + "serde_core", ]   [[package]] @@ -5453,44 +4835,37 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"   [[package]] name = "linux-raw-sys" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" - -[[package]] -name = "litemap" -version = "0.7.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"   [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77"   [[package]] name = "litrs" -version = "0.4.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"   [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", "serde", ]   [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"   [[package]] name = "loom" @@ -5502,7 +4877,7 @@ "cfg-if", "generator", "scoped-tls", "tracing", - "tracing-subscriber 0.3.20", + "tracing-subscriber 0.3.22", ]   [[package]] @@ -5556,9 +4931,9 @@ checksum = "08ab2867e3eeeca90e844d1940eab391c9dc5228783db2ed999acbc0a9ed375a"   [[package]] name = "mach2" -version = "0.4.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +checksum = "6a1b95cd5421ec55b445b5ae102f5ea0e768de1f82bd3001e11f426c269c3aea" dependencies = [ "libc", ] @@ -5571,7 +4946,18 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", +] + +[[package]] +name = "match-lookup" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1265724d8cb29dbbc2b0f06fffb8bf1a8c0cf73a78eede9ba73a4a66c52a981e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ]   [[package]] @@ -5585,33 +4971,36 @@ ]   [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"   [[package]] name = "memmap2" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843a98750cd611cc2965a8213b53b43e715f13c37a9e096c6408e69990961db7" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ]   [[package]] -name = "memoffset" -version = "0.9.1" +name = "merlin" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" dependencies = [ - "autocfg", + "byteorder", + "keccak", + "rand_core 0.6.4", + "zeroize", ]   [[package]] name = "metrics" -version = "0.24.2" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dea7ac8057892855ec285c440160265225438c3c45072613c25a4b26e98ef5" +checksum = "5d5312e9ba3771cfa961b585728215e3d972c950a3eed9252aa093d6301277e8" dependencies = [ "ahash", "portable-atomic", @@ -5626,7 +5015,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -5636,7 +5025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd7399781913e5393588a8d8c6a2867bf85fb38eaf2502fdce465aad2dc6f034" dependencies = [ "base64 0.22.1", - "indexmap 2.11.0", + "indexmap 2.12.1", "metrics", "metrics-util", "quanta", @@ -5645,18 +5034,18 @@ ]   [[package]] name = "metrics-process" -version = "2.4.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a82c8add4382f29a122fa64fff1891453ed0f6b2867d971e7d60cb8dfa322ff" +checksum = "f615e08e049bd14a44c4425415782efb9bcd479fc1e19ddeb971509074c060d0" dependencies = [ "libc", "libproc", "mach2", "metrics", "once_cell", - "procfs", + "procfs 0.18.0", "rlimit", - "windows 0.58.0", + "windows 0.62.2", ]   [[package]] @@ -5668,7 +5057,7 @@ dependencies = [ "crossbeam-epoch", "crossbeam-utils", "hashbrown 0.15.5", - "indexmap 2.11.0", + "indexmap 2.12.1", "metrics", "ordered-float", "quanta", @@ -5678,26 +5067,6 @@ "sketches-ddsketch", ]   [[package]] -name = "mev-share-sse" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd9e517b6c1d1143b35b716ec1107a493b2ce1143a35cbb9788e81f69c6f574c" -dependencies = [ - "alloy-rpc-types-mev", - "async-sse", - "bytes", - "futures-util", - "http-types", - "pin-project-lite", - "reqwest", - "serde", - "serde_json", - "thiserror 2.0.16", - "tokio", - "tracing", -] - -[[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5741,19 +5110,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", - "serde", + "simd-adler32", ]   [[package]] name = "mio" -version = "1.0.4" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "log", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "wasi", + "windows-sys 0.61.2", ]   [[package]] @@ -5779,20 +5148,18 @@ ]   [[package]] name = "moka" -version = "0.12.10" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" dependencies = [ "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", - "loom", + "equivalent", "parking_lot", "portable-atomic", - "rustc_version 0.4.1", "smallvec", "tagptr", - "thiserror 1.0.69", "uuid", ]   @@ -5823,11 +5190,12 @@ ]   [[package]] name = "multibase" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +checksum = "8694bb4835f452b0e3bb06dbebb1d6fc5385b6ca1caf2e55fd165c042390ec77" dependencies = [ "base-x", + "base256emoji", "data-encoding", "data-encoding-macro", ] @@ -5843,6 +5211,23 @@ "unsigned-varint", ]   [[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe 0.1.6", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + +[[package]] name = "nom" version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5858,7 +5243,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "fsevent-sys", "inotify", "kqueue", @@ -5878,20 +5263,20 @@ checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d"   [[package]] name = "ntapi" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" dependencies = [ "winapi", ]   [[package]] name = "nu-ansi-term" -version = "0.50.1" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ]   [[package]] @@ -5916,7 +5301,6 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", - "serde", ]   [[package]] @@ -5987,9 +5371,9 @@ ]   [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", "rustversion", @@ -5997,14 +5381,14 @@ ]   [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -6018,9 +5402,9 @@ ]   [[package]] name = "nybbles" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63cb50036b1ad148038105af40aaa70ff24d8a14fbc44ae5c914e1348533d12e" +checksum = "2c4b5ecbd0beec843101bffe848217f770e8b8da81d8355b7d6e226f2199b3dc" dependencies = [ "alloy-rlp", "arbitrary", @@ -6032,15 +5416,6 @@ "smallvec", ]   [[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6052,9 +5427,9 @@ ]   [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"   [[package]] name = "oorandom" @@ -6076,19 +5451,13 @@ "alloy-rlp", "alloy-rpc-types-eth", "alloy-serde", "arbitrary", - "derive_more", + "derive_more 2.1.1", "serde", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] -name = "op-alloy-flz" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a79f352fc3893dcd670172e615afef993a41798a1d3fc0db88a3e60ef2e70ecc" - -[[package]] name = "op-alloy-network" version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6105,16 +5474,6 @@ "op-alloy-rpc-types", ]   [[package]] -name = "op-alloy-rpc-jsonrpsee" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa85f170bf8f914a7619e1447918781a8c5bd1041bb6629940b851e865487156" -dependencies = [ - "alloy-primitives", - "jsonrpsee", -] - -[[package]] name = "op-alloy-rpc-types" version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6126,12 +5485,11 @@ "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-eth", "alloy-serde", - "arbitrary", - "derive_more", + "derive_more 2.1.1", "op-alloy-consensus", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -6145,40 +5503,18 @@ "alloy-eips", "alloy-primitives", "alloy-rlp", "alloy-rpc-types-engine", - "alloy-serde", - "arbitrary", - "derive_more", + "derive_more 2.1.1", "ethereum_ssz", "ethereum_ssz_derive", "op-alloy-consensus", - "serde", "snap", - "thiserror 2.0.16", -] - -[[package]] -name = "op-reth" -version = "1.7.0" -dependencies = [ - "clap", - "reth-cli-util", - "reth-optimism-chainspec", - "reth-optimism-cli", - "reth-optimism-consensus", - "reth-optimism-evm", - "reth-optimism-forks", - "reth-optimism-node", - "reth-optimism-payload-builder", - "reth-optimism-primitives", - "reth-optimism-rpc", - "tracing", + "thiserror 2.0.17", ]   [[package]] name = "op-revm" version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba21d705bbbfc947a423cba466d75e4af0c7d43ee89ba0a0f1cfa04963cede9" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "auto_impl", "revm", @@ -6192,12 +5528,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"   [[package]] +name = "openssl" +version = "0.10.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" +dependencies = [ + "bitflags 2.10.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] + +[[package]] name = "openssl-probe" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"   [[package]] +name = "openssl-probe" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f50d9b3dabb09ecd771ad0aa242ca6894994c130308ca3d7684634df8037391" + +[[package]] +name = "openssl-sys" +version = "0.9.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] name = "opentelemetry" version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6207,7 +5587,7 @@ "futures-core", "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ]   @@ -6239,7 +5619,7 @@ "opentelemetry-proto", "opentelemetry_sdk", "prost", "reqwest", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ]   @@ -6275,7 +5655,7 @@ "opentelemetry", "percent-encoding", "rand 0.9.2", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ]   @@ -6303,7 +5683,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "sha2 0.10.9", + "sha2", ]   [[package]] @@ -6343,20 +5723,14 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -6364,15 +5738,15 @@ ]   [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link", ]   [[package]] @@ -6393,12 +5767,12 @@ ]   [[package]] name = "pem" -version = "3.0.5" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ "base64 0.22.1", - "serde", + "serde_core", ]   [[package]] @@ -6409,12 +5783,11 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"   [[package]] name = "pest" -version = "2.8.1" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" dependencies = [ "memchr", - "thiserror 2.0.16", "ucd-trie", ]   @@ -6430,9 +5803,9 @@ ]   [[package]] name = "phf" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" dependencies = [ "phf_macros", "phf_shared", @@ -6441,32 +5814,32 @@ ]   [[package]] name = "phf_generator" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" dependencies = [ + "fastrand", "phf_shared", - "rand 0.8.5", ]   [[package]] name = "phf_macros" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" dependencies = [ "phf_generator", "phf_shared", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "phf_shared" -version = "0.11.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" dependencies = [ "siphasher", ] @@ -6488,7 +5861,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -6557,12 +5930,6 @@ "plotters-backend", ]   [[package]] -name = "pollster" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" - -[[package]] name = "polyval" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -6576,17 +5943,17 @@ ]   [[package]] name = "portable-atomic" -version = "1.11.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"   [[package]] name = "potential_utf" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ - "zerovec 0.11.4", + "zerovec", ]   [[package]] @@ -6621,7 +5988,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -6646,11 +6013,11 @@ ]   [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit", + "toml_edit 0.23.10+spec-1.0.0", ]   [[package]] @@ -6672,14 +6039,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] @@ -6690,35 +6057,55 @@ version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "chrono", "flate2", "hex", - "procfs-core", + "procfs-core 0.17.0", "rustix 0.38.44", ]   [[package]] +name = "procfs" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7" +dependencies = [ + "bitflags 2.10.0", + "procfs-core 0.18.0", + "rustix 1.1.3", +] + +[[package]] name = "procfs-core" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "chrono", + "hex", +] + +[[package]] +name = "procfs-core" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405" +dependencies = [ + "bitflags 2.10.0", "hex", ]   [[package]] name = "proptest" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.9.4", - "lazy_static", + "bitflags 2.10.0", "num-traits", "rand 0.9.2", "rand_chacha 0.9.0", @@ -6747,7 +6134,18 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", +] + +[[package]] +name = "proptest-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "095a99f75c69734802359b682be8daaf8980296731f6470434ea2c652af1dd30" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", ]   [[package]] @@ -6770,7 +6168,7 @@ "anyhow", "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -6779,7 +6177,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "memchr", "unicase", ] @@ -6794,7 +6192,7 @@ "crossbeam-utils", "libc", "once_cell", "raw-cpuid", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "web-sys", "winapi", ] @@ -6827,8 +6225,8 @@ "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", "rustls", - "socket2 0.6.0", - "thiserror 2.0.16", + "socket2 0.6.1", + "thiserror 2.0.17", "tokio", "tracing", "web-time", @@ -6841,7 +6239,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" dependencies = [ "bytes", - "getrandom 0.3.3", + "getrandom 0.3.4", "lru-slab", "rand 0.9.2", "ring", @@ -6849,7 +6247,7 @@ "rustc-hash 2.1.1", "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.16", + "thiserror 2.0.17", "tinyvec", "tracing", "web-time", @@ -6864,16 +6262,16 @@ dependencies = [ "cfg_aliases", "libc", "once_cell", - "socket2 0.6.0", + "socket2 0.6.1", "tracing", "windows-sys 0.60.2", ]   [[package]] name = "quote" -version = "1.0.40" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" dependencies = [ "proc-macro2", ] @@ -6892,19 +6290,6 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"   [[package]] name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", -] - -[[package]] -name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" @@ -6928,16 +6313,6 @@ ]   [[package]] name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" @@ -6958,15 +6333,6 @@ ]   [[package]] name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" @@ -6980,20 +6346,11 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "serde", ]   [[package]] -name = "rand_hc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -dependencies = [ - "rand_core 0.5.1", -] - -[[package]] name = "rand_xorshift" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7017,7 +6374,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cassowary", "compact_str", "crossterm 0.28.1", @@ -7038,7 +6395,7 @@ version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ]   [[package]] @@ -7069,11 +6426,20 @@ checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175"   [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", +] + +[[package]] +name = "redox_syscall" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" +dependencies = [ + "bitflags 2.10.0", ]   [[package]] @@ -7095,34 +6461,34 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "ref-cast" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ]   [[package]] name = "ref-cast-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "regex" -version = "1.11.2" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -7132,9 +6498,9 @@ ]   [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -7143,19 +6509,9 @@ ]   [[package]] name = "regex-syntax" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" - -[[package]] -name = "regress" -version = "0.10.4" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145bb27393fe455dd64d6cbc8d059adfa392590a45eadf079c01b11857e7b010" -dependencies = [ - "hashbrown 0.15.5", - "memchr", -] +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"   [[package]] name = "relative-path" @@ -7165,9 +6521,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2"   [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64 0.22.1", "bytes", @@ -7179,9 +6535,11 @@ "http-body", "http-body-util", "hyper", "hyper-rustls", + "hyper-tls", "hyper-util", "js-sys", "log", + "native-tls", "percent-encoding", "pin-project-lite", "quinn", @@ -7193,9 +6551,10 @@ "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", + "tokio-native-tls", "tokio-rustls", "tokio-util", - "tower", + "tower 0.5.2", "tower-http", "tower-service", "url", @@ -7203,61 +6562,14 @@ "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 1.0.2", + "webpki-roots 1.0.5", ]   [[package]] name = "resolv-conf" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95325155c684b1c89f7765e30bc1c42e4a6da51ca513615660cb8a62ef9a88e3" - -[[package]] -name = "reth" -version = "1.7.0" -dependencies = [ - "alloy-rpc-types", - "aquamarine", - "backon", - "clap", - "eyre", - "reth-chainspec", - "reth-cli-runner", - "reth-cli-util", - "reth-consensus", - "reth-consensus-common", - "reth-db", - "reth-ethereum-cli", - "reth-ethereum-payload-builder", - "reth-ethereum-primitives", - "reth-evm", - "reth-network", - "reth-network-api", - "reth-node-api", - "reth-node-builder", - "reth-node-core", - "reth-node-ethereum", - "reth-node-metrics", - "reth-payload-builder", - "reth-payload-primitives", - "reth-primitives", - "reth-provider", - "reth-ress-protocol", - "reth-ress-provider", - "reth-revm", - "reth-rpc", - "reth-rpc-api", - "reth-rpc-builder", - "reth-rpc-convert", - "reth-rpc-eth-types", - "reth-rpc-server-types", - "reth-tasks", - "reth-tokio-util", - "reth-transaction-pool", - "tempfile", - "tokio", - "tracing", -] +checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7"   [[package]] name = "reth-basic-payload-builder" @@ -7283,45 +6595,6 @@ "tracing", ]   [[package]] -name = "reth-bench" -version = "1.7.0" -dependencies = [ - "alloy-eips", - "alloy-json-rpc", - "alloy-primitives", - "alloy-provider", - "alloy-pubsub", - "alloy-rpc-client", - "alloy-rpc-types-engine", - "alloy-transport", - "alloy-transport-http", - "alloy-transport-ipc", - "alloy-transport-ws", - "async-trait", - "clap", - "csv", - "eyre", - "futures", - "humantime", - "op-alloy-consensus", - "op-alloy-rpc-types-engine", - "reqwest", - "reth-cli-runner", - "reth-cli-util", - "reth-fs-util", - "reth-node-api", - "reth-node-core", - "reth-primitives-traits", - "reth-tracing", - "serde", - "serde_json", - "thiserror 2.0.16", - "tokio", - "tower", - "tracing", -] - -[[package]] name = "reth-chain-state" version = "1.7.0" dependencies = [ @@ -7330,7 +6603,7 @@ "alloy-eips", "alloy-primitives", "alloy-signer", "alloy-signer-local", - "derive_more", + "derive_more 2.1.1", "metrics", "parking_lot", "pin-project", @@ -7363,9 +6636,10 @@ "alloy-evm", "alloy-genesis", "alloy-primitives", "alloy-rlp", + "alloy-seismic-evm", "alloy-trie", "auto_impl", - "derive_more", + "derive_more 2.1.1", "reth-ethereum-forks", "reth-network-peers", "reth-primitives-traits", @@ -7456,6 +6730,7 @@ "reth-trie", "reth-trie-common", "reth-trie-db", "secp256k1 0.30.0", + "seismic-alloy-genesis", "serde", "serde_json", "tar", @@ -7490,7 +6765,7 @@ "reth-fs-util", "secp256k1 0.30.0", "serde", "snmalloc-rs", - "thiserror 2.0.16", + "thiserror 2.0.17", "tikv-jemallocator", "tracy-client", ] @@ -7513,6 +6788,9 @@ "proptest-arbitrary-interop", "reth-codecs-derive", "reth-zstd-compressors", "rstest", + "seismic-alloy-consensus", + "seismic-alloy-genesis", + "seismic-enclave", "serde", "serde_json", "test-fuzz", @@ -7523,11 +6801,11 @@ [[package]] name = "reth-codecs-derive" version = "1.7.0" dependencies = [ - "convert_case", + "convert_case 0.7.1", "proc-macro2", "quote", "similar-asserts", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -7556,7 +6834,7 @@ "alloy-primitives", "auto_impl", "reth-execution-types", "reth-primitives-traits", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -7584,7 +6862,7 @@ "alloy-primitives", "alloy-provider", "alloy-rpc-types-engine", "auto_impl", - "derive_more", + "derive_more 2.1.1", "eyre", "futures", "reqwest", @@ -7606,7 +6884,7 @@ "alloy-primitives", "arbitrary", "assert_matches", "codspeed-criterion-compat", - "derive_more", + "derive_more 2.1.1", "eyre", "metrics", "page_size", @@ -7628,7 +6906,7 @@ "serde_json", "strum 0.27.2", "sysinfo", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -7636,11 +6914,10 @@ name = "reth-db-api" version = "1.7.0" dependencies = [ "alloy-consensus", - "alloy-genesis", "alloy-primitives", "arbitrary", "bytes", - "derive_more", + "derive_more 2.1.1", "metrics", "modular-bitfield", "parity-scale-codec", @@ -7650,13 +6927,14 @@ "rand 0.9.2", "reth-codecs", "reth-db-models", "reth-ethereum-primitives", - "reth-optimism-primitives", "reth-primitives-traits", "reth-prune-types", + "reth-seismic-primitives", "reth-stages-types", "reth-storage-errors", "reth-trie-common", "roaring", + "seismic-alloy-genesis", "serde", "test-fuzz", ] @@ -7685,9 +6963,10 @@ "reth-stages-types", "reth-static-file-types", "reth-trie", "reth-trie-db", + "seismic-alloy-genesis", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ]   @@ -7729,7 +7008,7 @@ "reth-tracing", "schnellru", "secp256k1 0.30.0", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -7741,7 +7020,7 @@ version = "1.7.0" dependencies = [ "alloy-primitives", "alloy-rlp", - "derive_more", + "derive_more 2.1.1", "discv5", "enr", "futures", @@ -7752,10 +7031,11 @@ "rand 0.9.2", "reth-chainspec", "reth-ethereum-forks", "reth-metrics", + "reth-net-nat", "reth-network-peers", "reth-tracing", "secp256k1 0.30.0", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -7782,7 +7062,7 @@ "schnellru", "secp256k1 0.30.0", "serde", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -7820,7 +7100,7 @@ "reth-tasks", "reth-testing-utils", "reth-tracing", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", @@ -7841,10 +7121,11 @@ "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-signer", "alloy-signer-local", - "derive_more", + "derive_more 2.1.1", "eyre", "futures-util", - "jsonrpsee", + "jsonrpsee 0.26.0", + "op-alloy-rpc-types-engine", "reth-chainspec", "reth-cli-commands", "reth-config", @@ -7853,6 +7134,7 @@ "reth-db", "reth-db-common", "reth-engine-local", "reth-ethereum-primitives", + "reth-evm", "reth-network-api", "reth-network-p2p", "reth-network-peers", @@ -7903,9 +7185,9 @@ "pin-project", "rand 0.8.5", "reth-network-peers", "secp256k1 0.30.0", - "sha2 0.10.9", + "sha2", "sha3", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", @@ -7926,7 +7208,6 @@ "op-alloy-rpc-types-engine", "reth-chainspec", "reth-engine-primitives", "reth-ethereum-engine-primitives", - "reth-optimism-chainspec", "reth-payload-builder", "reth-payload-primitives", "reth-provider", @@ -7956,7 +7237,7 @@ "reth-payload-primitives", "reth-primitives-traits", "reth-trie-common", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", ]   @@ -7977,6 +7258,7 @@ "reth-evm", "reth-evm-ethereum", "reth-exex-types", "reth-network-p2p", + "reth-node-core", "reth-node-ethereum", "reth-node-types", "reth-payload-builder", @@ -7985,7 +7267,7 @@ "reth-provider", "reth-prune", "reth-stages-api", "reth-tasks", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", ] @@ -8003,7 +7285,7 @@ "alloy-rpc-types-engine", "assert_matches", "codspeed-criterion-compat", "crossbeam-channel", - "derive_more", + "derive_more 2.1.1", "eyre", "futures", "metrics", @@ -8031,6 +7313,7 @@ "reth-execution-types", "reth-exex-types", "reth-metrics", "reth-network-p2p", + "reth-node-core", "reth-node-ethereum", "reth-payload-builder", "reth-payload-primitives", @@ -8056,7 +7339,7 @@ "revm-state", "schnellru", "serde_json", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -8106,7 +7389,7 @@ "reth-ethereum-primitives", "snap", "tempfile", "test-case", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", ]   @@ -8121,7 +7404,7 @@ "futures", "futures-util", "reqwest", "reth-fs-util", - "sha2 0.10.9", + "sha2", "tempfile", "test-case", "tokio", @@ -8160,7 +7443,7 @@ dependencies = [ "reth-consensus", "reth-execution-errors", "reth-storage-errors", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -8175,7 +7458,7 @@ "alloy-rlp", "arbitrary", "async-stream", "bytes", - "derive_more", + "derive_more 2.1.1", "futures", "pin-project", "proptest", @@ -8194,7 +7477,7 @@ "secp256k1 0.30.0", "serde", "snap", "test-fuzz", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", @@ -8214,7 +7497,7 @@ "alloy-primitives", "alloy-rlp", "arbitrary", "bytes", - "derive_more", + "derive_more 2.1.1", "proptest", "proptest-arbitrary-interop", "rand 0.9.2", @@ -8223,7 +7506,7 @@ "reth-codecs-derive", "reth-ethereum-primitives", "reth-primitives-traits", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -8307,6 +7590,7 @@ [[package]] name = "reth-ethereum-engine-primitives" version = "1.7.0" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", @@ -8315,10 +7599,11 @@ "reth-engine-primitives", "reth-ethereum-primitives", "reth-payload-primitives", "reth-primitives-traits", + "reth-seismic-primitives", "serde", "serde_json", - "sha2 0.10.9", - "thiserror 2.0.16", + "sha2", + "thiserror 2.0.17", ]   [[package]] @@ -8370,9 +7655,10 @@ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rlp", + "alloy-serde", "arbitrary", "bincode 1.3.3", - "derive_more", + "derive_more 2.1.1", "modular-bitfield", "proptest", "proptest-arbitrary-interop", @@ -8405,9 +7691,10 @@ "alloy-eips", "alloy-evm", "alloy-primitives", "auto_impl", - "derive_more", + "derive_more 2.1.1", "futures-util", "metrics", + "op-revm", "reth-ethereum-forks", "reth-ethereum-primitives", "reth-execution-errors", @@ -8418,6 +7705,7 @@ "reth-storage-api", "reth-storage-errors", "reth-trie-common", "revm", + "seismic-revm", ]   [[package]] @@ -8430,7 +7718,7 @@ "alloy-evm", "alloy-genesis", "alloy-primitives", "alloy-rpc-types-engine", - "derive_more", + "derive_more 2.1.1", "parking_lot", "reth-chainspec", "reth-ethereum-forks", @@ -8442,6 +7730,8 @@ "reth-storage-errors", "reth-testing-utils", "revm", "secp256k1 0.30.0", + "serde_json", + "tokio", ]   [[package]] @@ -8453,7 +7743,7 @@ "alloy-primitives", "alloy-rlp", "nybbles", "reth-storage-errors", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -8466,7 +7756,7 @@ "alloy-evm", "alloy-primitives", "arbitrary", "bincode 1.3.3", - "derive_more", + "derive_more 2.1.1", "rand 0.9.2", "reth-ethereum-primitives", "reth-primitives-traits", @@ -8513,8 +7803,9 @@ "reth-testing-utils", "reth-tracing", "rmp-serde", "secp256k1 0.30.0", + "seismic-alloy-genesis", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", @@ -8547,7 +7838,7 @@ "reth-provider", "reth-tasks", "reth-transaction-pool", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", ]   @@ -8574,7 +7865,20 @@ version = "1.7.0" dependencies = [ "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", +] + +[[package]] +name = "reth-genesis-builder" +version = "1.7.0" +dependencies = [ + "alloy-primitives", + "reqwest", + "serde", + "serde_json", + "thiserror 2.0.17", + "toml", + "tracing", ]   [[package]] @@ -8587,7 +7891,7 @@ "alloy-rlp", "alloy-rpc-types-debug", "eyre", "futures", - "jsonrpsee", + "jsonrpsee 0.26.0", "pretty_assertions", "reth-engine-primitives", "reth-evm", @@ -8611,17 +7915,17 @@ "bytes", "futures", "futures-util", "interprocess", - "jsonrpsee", + "jsonrpsee 0.26.0", "pin-project", "rand 0.9.2", "reth-tracing", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", - "tower", + "tower 0.5.2", "tracing", ]   @@ -8629,18 +7933,18 @@ [[package]] name = "reth-libmdbx" version = "1.7.0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "byteorder", "codspeed-criterion-compat", "dashmap 6.1.0", - "derive_more", - "indexmap 2.11.0", + "derive_more 2.1.1", + "indexmap 2.12.1", "parking_lot", "rand 0.9.2", "reth-mdbx-sys", "smallvec", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", ]   @@ -8648,7 +7952,7 @@ [[package]] name = "reth-mdbx-sys" version = "1.7.0" dependencies = [ - "bindgen", + "bindgen 0.70.1", "cc", ]   @@ -8679,7 +7983,7 @@ "if-addrs", "reqwest", "reth-tracing", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -8696,7 +8000,7 @@ "alloy-rlp", "aquamarine", "auto_impl", "codspeed-criterion-compat", - "derive_more", + "derive_more 2.1.1", "discv5", "enr", "futures", @@ -8736,7 +8040,7 @@ "schnellru", "secp256k1 0.30.0", "serde", "smallvec", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-util", @@ -8753,7 +8057,7 @@ "alloy-primitives", "alloy-rpc-types-admin", "alloy-rpc-types-eth", "auto_impl", - "derive_more", + "derive_more 2.1.1", "enr", "futures", "reth-eth-wire-types", @@ -8763,7 +8067,7 @@ "reth-network-peers", "reth-network-types", "reth-tokio-util", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", ] @@ -8776,7 +8080,7 @@ "alloy-consensus", "alloy-eips", "alloy-primitives", "auto_impl", - "derive_more", + "derive_more 2.1.1", "futures", "parking_lot", "reth-consensus", @@ -8802,7 +8106,7 @@ "rand 0.9.2", "secp256k1 0.30.0", "serde_json", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "url", ] @@ -8826,14 +8130,14 @@ version = "1.7.0" dependencies = [ "anyhow", "bincode 1.3.3", - "derive_more", + "derive_more 2.1.1", "lz4_flex", "memmap2", "rand 0.9.2", "reth-fs-util", "serde", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tracing", "zstd", ] @@ -8875,7 +8179,7 @@ "aquamarine", "eyre", "fdlimit", "futures", - "jsonrpsee", + "jsonrpsee 0.26.0", "rayon", "reth-basic-payload-builder", "reth-chain-state", @@ -8920,6 +8224,7 @@ "reth-rpc-eth-types", "reth-rpc-layer", "reth-stages", "reth-static-file", + "reth-storage-api", "reth-tasks", "reth-tokio-util", "reth-tracing", @@ -8941,7 +8246,7 @@ "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", "clap", - "derive_more", + "derive_more 2.1.1", "dirs-next", "eyre", "futures", @@ -8976,7 +8281,7 @@ "secp256k1 0.30.0", "serde", "shellexpand", "strum 0.27.2", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "toml", "tracing", @@ -9034,6 +8339,7 @@ "reth-tasks", "reth-tracing", "reth-transaction-pool", "revm", + "seismic-alloy-genesis", "serde_json", "tokio", ] @@ -9053,7 +8359,7 @@ "reth-storage-api", "reth-transaction-pool", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tokio-tungstenite", @@ -9069,7 +8375,7 @@ "alloy-consensus", "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", - "derive_more", + "derive_more 2.1.1", "futures", "humantime", "pin-project", @@ -9095,14 +8401,14 @@ "metrics", "metrics-exporter-prometheus", "metrics-process", "metrics-util", - "procfs", + "procfs 0.17.0", "reqwest", "reth-metrics", "reth-tasks", "socket2 0.5.10", "tikv-jemalloc-ctl", "tokio", - "tower", + "tower 0.5.2", "tracing", ]   @@ -9118,459 +8424,6 @@ "reth-primitives-traits", ]   [[package]] -name = "reth-op" -version = "1.7.0" -dependencies = [ - "reth-chainspec", - "reth-cli-util", - "reth-codecs", - "reth-consensus", - "reth-consensus-common", - "reth-db", - "reth-engine-local", - "reth-eth-wire", - "reth-evm", - "reth-exex", - "reth-network", - "reth-network-api", - "reth-node-api", - "reth-node-builder", - "reth-node-core", - "reth-optimism-chainspec", - "reth-optimism-cli", - "reth-optimism-consensus", - "reth-optimism-evm", - "reth-optimism-node", - "reth-optimism-primitives", - "reth-optimism-rpc", - "reth-primitives-traits", - "reth-provider", - "reth-revm", - "reth-rpc", - "reth-rpc-api", - "reth-rpc-builder", - "reth-rpc-eth-types", - "reth-storage-api", - "reth-tasks", - "reth-transaction-pool", - "reth-trie", - "reth-trie-db", -] - -[[package]] -name = "reth-optimism-chainspec" -version = "1.7.0" -dependencies = [ - "alloy-chains", - "alloy-consensus", - "alloy-eips", - "alloy-genesis", - "alloy-hardforks", - "alloy-primitives", - "derive_more", - "miniz_oxide", - "op-alloy-consensus", - "op-alloy-rpc-types", - "paste", - "reth-chainspec", - "reth-ethereum-forks", - "reth-network-peers", - "reth-optimism-forks", - "reth-optimism-primitives", - "reth-primitives-traits", - "serde", - "serde_json", - "tar-no-std", - "thiserror 2.0.16", -] - -[[package]] -name = "reth-optimism-cli" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "clap", - "derive_more", - "eyre", - "futures-util", - "op-alloy-consensus", - "proptest", - "reth-chainspec", - "reth-cli", - "reth-cli-commands", - "reth-cli-runner", - "reth-consensus", - "reth-db", - "reth-db-api", - "reth-db-common", - "reth-downloaders", - "reth-execution-types", - "reth-fs-util", - "reth-node-builder", - "reth-node-core", - "reth-node-events", - "reth-node-metrics", - "reth-optimism-chainspec", - "reth-optimism-consensus", - "reth-optimism-evm", - "reth-optimism-node", - "reth-optimism-primitives", - "reth-primitives-traits", - "reth-provider", - "reth-prune", - "reth-stages", - "reth-static-file", - "reth-static-file-types", - "reth-tracing", - "serde", - "tempfile", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "reth-optimism-consensus" -version = "1.7.0" -dependencies = [ - "alloy-chains", - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-trie", - "op-alloy-consensus", - "reth-chainspec", - "reth-consensus", - "reth-consensus-common", - "reth-db-common", - "reth-execution-types", - "reth-optimism-chainspec", - "reth-optimism-forks", - "reth-optimism-node", - "reth-optimism-primitives", - "reth-primitives-traits", - "reth-provider", - "reth-revm", - "reth-storage-api", - "reth-storage-errors", - "reth-trie", - "reth-trie-common", - "revm", - "thiserror 2.0.16", - "tracing", -] - -[[package]] -name = "reth-optimism-evm" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-evm", - "alloy-genesis", - "alloy-op-evm", - "alloy-primitives", - "op-alloy-consensus", - "op-alloy-rpc-types-engine", - "op-revm", - "reth-chainspec", - "reth-evm", - "reth-execution-errors", - "reth-execution-types", - "reth-optimism-chainspec", - "reth-optimism-consensus", - "reth-optimism-forks", - "reth-optimism-primitives", - "reth-primitives-traits", - "reth-revm", - "reth-rpc-eth-api", - "reth-storage-errors", - "revm", - "thiserror 2.0.16", -] - -[[package]] -name = "reth-optimism-flashblocks" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rpc-types-engine", - "alloy-serde", - "brotli", - "eyre", - "futures-util", - "reth-chain-state", - "reth-errors", - "reth-evm", - "reth-execution-types", - "reth-optimism-evm", - "reth-optimism-primitives", - "reth-primitives-traits", - "reth-revm", - "reth-rpc-eth-types", - "reth-storage-api", - "reth-tasks", - "serde", - "serde_json", - "test-case", - "tokio", - "tokio-tungstenite", - "tracing", - "url", -] - -[[package]] -name = "reth-optimism-forks" -version = "1.7.0" -dependencies = [ - "alloy-op-hardforks", - "alloy-primitives", - "once_cell", - "reth-ethereum-forks", -] - -[[package]] -name = "reth-optimism-node" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-genesis", - "alloy-network", - "alloy-primitives", - "alloy-rpc-types-engine", - "alloy-rpc-types-eth", - "clap", - "eyre", - "futures", - "op-alloy-consensus", - "op-alloy-network", - "op-alloy-rpc-types-engine", - "op-revm", - "reth-chainspec", - "reth-consensus", - "reth-db", - "reth-e2e-test-utils", - "reth-engine-local", - "reth-evm", - "reth-network", - "reth-node-api", - "reth-node-builder", - "reth-node-core", - "reth-optimism-chainspec", - "reth-optimism-consensus", - "reth-optimism-evm", - "reth-optimism-forks", - "reth-optimism-node", - "reth-optimism-payload-builder", - "reth-optimism-primitives", - "reth-optimism-rpc", - "reth-optimism-storage", - "reth-optimism-txpool", - "reth-payload-builder", - "reth-payload-util", - "reth-primitives-traits", - "reth-provider", - "reth-revm", - "reth-rpc", - "reth-rpc-api", - "reth-rpc-engine-api", - "reth-rpc-eth-types", - "reth-rpc-server-types", - "reth-tasks", - "reth-tracing", - "reth-transaction-pool", - "reth-trie-common", - "revm", - "serde", - "serde_json", - "tokio", - "url", -] - -[[package]] -name = "reth-optimism-payload-builder" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "alloy-rpc-types-debug", - "alloy-rpc-types-engine", - "derive_more", - "op-alloy-consensus", - "op-alloy-rpc-types-engine", - "reth-basic-payload-builder", - "reth-chain-state", - "reth-chainspec", - "reth-evm", - "reth-execution-types", - "reth-optimism-evm", - "reth-optimism-forks", - "reth-optimism-primitives", - "reth-optimism-txpool", - "reth-payload-builder", - "reth-payload-builder-primitives", - "reth-payload-primitives", - "reth-payload-util", - "reth-payload-validator", - "reth-primitives-traits", - "reth-revm", - "reth-storage-api", - "reth-transaction-pool", - "revm", - "serde", - "sha2 0.10.9", - "thiserror 2.0.16", - "tracing", -] - -[[package]] -name = "reth-optimism-primitives" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-primitives", - "alloy-rlp", - "arbitrary", - "bincode 1.3.3", - "bytes", - "modular-bitfield", - "op-alloy-consensus", - "proptest", - "proptest-arbitrary-interop", - "rand 0.8.5", - "rand 0.9.2", - "reth-codecs", - "reth-primitives-traits", - "reth-zstd-compressors", - "rstest", - "secp256k1 0.30.0", - "serde", - "serde_json", - "serde_with", -] - -[[package]] -name = "reth-optimism-rpc" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-json-rpc", - "alloy-primitives", - "alloy-rpc-client", - "alloy-rpc-types-debug", - "alloy-rpc-types-engine", - "alloy-rpc-types-eth", - "alloy-transport", - "alloy-transport-http", - "async-trait", - "derive_more", - "eyre", - "jsonrpsee", - "jsonrpsee-core", - "jsonrpsee-types", - "metrics", - "op-alloy-consensus", - "op-alloy-network", - "op-alloy-rpc-jsonrpsee", - "op-alloy-rpc-types", - "op-alloy-rpc-types-engine", - "op-revm", - "reqwest", - "reth-chainspec", - "reth-evm", - "reth-metrics", - "reth-node-api", - "reth-node-builder", - "reth-optimism-chainspec", - "reth-optimism-evm", - "reth-optimism-flashblocks", - "reth-optimism-forks", - "reth-optimism-payload-builder", - "reth-optimism-primitives", - "reth-optimism-txpool", - "reth-primitives-traits", - "reth-rpc", - "reth-rpc-api", - "reth-rpc-engine-api", - "reth-rpc-eth-api", - "reth-rpc-eth-types", - "reth-rpc-server-types", - "reth-storage-api", - "reth-tasks", - "reth-transaction-pool", - "revm", - "serde_json", - "thiserror 2.0.16", - "tokio", - "tower", - "tracing", -] - -[[package]] -name = "reth-optimism-storage" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-primitives", - "reth-chainspec", - "reth-codecs", - "reth-db-api", - "reth-node-api", - "reth-optimism-primitives", - "reth-primitives-traits", - "reth-provider", - "reth-prune-types", - "reth-stages-types", - "reth-storage-api", -] - -[[package]] -name = "reth-optimism-txpool" -version = "1.7.0" -dependencies = [ - "alloy-consensus", - "alloy-eips", - "alloy-json-rpc", - "alloy-primitives", - "alloy-rpc-client", - "alloy-rpc-types-eth", - "alloy-serde", - "c-kzg", - "derive_more", - "futures-util", - "metrics", - "op-alloy-consensus", - "op-alloy-flz", - "op-alloy-rpc-types", - "op-revm", - "parking_lot", - "reth-chain-state", - "reth-chainspec", - "reth-metrics", - "reth-optimism-chainspec", - "reth-optimism-evm", - "reth-optimism-forks", - "reth-optimism-primitives", - "reth-primitives-traits", - "reth-provider", - "reth-storage-api", - "reth-transaction-pool", - "serde", - "thiserror 2.0.16", - "tokio", - "tracing", -] - -[[package]] name = "reth-payload-builder" version = "1.7.0" dependencies = [ @@ -9616,7 +8469,7 @@ "reth-chainspec", "reth-errors", "reth-primitives-traits", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", ]   @@ -9676,7 +8529,7 @@ "auto_impl", "bincode 1.3.3", "byteorder", "bytes", - "derive_more", + "derive_more 2.1.1", "modular-bitfield", "once_cell", "op-alloy-consensus", @@ -9691,11 +8544,13 @@ "revm-bytecode", "revm-primitives", "revm-state", "secp256k1 0.30.0", + "seismic-alloy-consensus", + "seismic-alloy-genesis", "serde", "serde_json", "serde_with", "test-fuzz", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -9774,7 +8629,7 @@ "reth-testing-utils", "reth-tokio-util", "reth-tracing", "rustc-hash 2.1.1", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -9786,7 +8641,7 @@ dependencies = [ "alloy-primitives", "arbitrary", "assert_matches", - "derive_more", + "derive_more 2.1.1", "modular-bitfield", "proptest", "proptest-arbitrary-interop", @@ -9794,7 +8649,7 @@ "reth-codecs", "serde", "serde_json", "test-fuzz", - "thiserror 2.0.16", + "thiserror 2.0.17", "toml", ]   @@ -9890,14 +8745,14 @@ "alloy-serde", "alloy-signer", "alloy-signer-local", "async-trait", - "derive_more", + "derive_more 2.1.1", "futures", "http", "http-body", "hyper", "itertools 0.14.0", - "jsonrpsee", - "jsonrpsee-types", + "jsonrpsee 0.26.0", + "jsonrpsee-types 0.26.0", "jsonwebtoken", "parking_lot", "pin-project", @@ -9937,11 +8792,11 @@ "revm-inspectors", "revm-primitives", "serde", "serde_json", - "sha2 0.10.9", - "thiserror 2.0.16", + "sha2", + "thiserror 2.0.17", "tokio", "tokio-stream", - "tower", + "tower 0.5.2", "tracing", "tracing-futures", ] @@ -9965,7 +8820,7 @@ "alloy-rpc-types-mev", "alloy-rpc-types-trace", "alloy-rpc-types-txpool", "alloy-serde", - "jsonrpsee", + "jsonrpsee 0.26.0", "reth-chain-state", "reth-engine-primitives", "reth-network-peers", @@ -9982,8 +8837,8 @@ "alloy-primitives", "alloy-rpc-types-eth", "alloy-rpc-types-trace", "futures", - "jsonrpsee", - "jsonrpsee-http-client", + "jsonrpsee 0.26.0", + "jsonrpsee-http-client 0.26.0", "reth-ethereum-primitives", "reth-rpc-api", "reth-rpc-eth-api", @@ -9996,6 +8851,7 @@ [[package]] name = "reth-rpc-builder" version = "1.7.0" dependencies = [ + "alloy-consensus", "alloy-eips", "alloy-network", "alloy-primitives", @@ -10003,11 +8859,15 @@ "alloy-provider", "alloy-rpc-types-engine", "alloy-rpc-types-eth", "alloy-rpc-types-trace", + "alloy-signer", + "alloy-signer-local", + "alloy-sol-types", "clap", "http", - "jsonrpsee", + "jsonrpsee 0.26.0", "metrics", "pin-project", + "reqwest", "reth-chain-state", "reth-chainspec", "reth-consensus", @@ -10038,10 +8898,10 @@ "reth-tracing", "reth-transaction-pool", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-util", - "tower", + "tower 0.5.2", "tower-http", "tracing", ] @@ -10056,18 +8916,17 @@ "alloy-network", "alloy-primitives", "alloy-rpc-types-eth", "alloy-signer", - "jsonrpsee-types", + "jsonrpsee-types 0.26.0", "op-alloy-consensus", "op-alloy-network", "op-alloy-rpc-types", "op-revm", "reth-ethereum-primitives", "reth-evm", - "reth-optimism-primitives", "reth-primitives-traits", "reth-storage-api", "revm-context", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -10078,7 +8937,7 @@ "alloy-genesis", "alloy-rpc-types-engine", "eyre", "futures-util", - "jsonrpsee", + "jsonrpsee 0.26.0", "reth-chainspec", "reth-e2e-test-utils", "reth-node-api", @@ -10100,8 +8959,8 @@ "alloy-rlp", "alloy-rpc-types-engine", "assert_matches", "async-trait", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.26.0", + "jsonrpsee-types 0.26.0", "metrics", "parking_lot", "reth-chainspec", @@ -10121,7 +8980,7 @@ "reth-tasks", "reth-testing-utils", "reth-transaction-pool", "serde", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -10145,8 +9004,8 @@ "async-trait", "auto_impl", "dyn-clone", "futures", - "jsonrpsee", - "jsonrpsee-types", + "jsonrpsee 0.26.0", + "jsonrpsee-types 0.26.0", "parking_lot", "reth-chain-state", "reth-chainspec", @@ -10182,11 +9041,11 @@ "alloy-rpc-client", "alloy-rpc-types-eth", "alloy-sol-types", "alloy-transport", - "derive_more", + "derive_more 2.1.1", "futures", "itertools 0.14.0", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.26.0", + "jsonrpsee-types 0.26.0", "metrics", "rand 0.9.2", "reqwest", @@ -10210,7 +9069,7 @@ "revm-inspectors", "schnellru", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -10220,15 +9079,24 @@ [[package]] name = "reth-rpc-layer" version = "1.7.0" dependencies = [ + "alloy-consensus", + "alloy-dyn-abi", + "alloy-primitives", "alloy-rpc-types-engine", + "alloy-signer", + "alloy-signer-local", + "alloy-sol-types", "http", "http-body-util", - "jsonrpsee", - "jsonrpsee-http-client", + "jsonrpsee 0.26.0", + "jsonrpsee-http-client 0.26.0", "pin-project", "reqwest", + "reth-provider", + "serde", + "serde_json", "tokio", - "tower", + "tower 0.5.2", "tower-http", "tracing", ] @@ -10240,8 +9108,8 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rpc-types-engine", - "jsonrpsee-core", - "jsonrpsee-types", + "jsonrpsee-core 0.26.0", + "jsonrpsee-types 0.26.0", "reth-errors", "reth-network-api", "serde", @@ -10249,6 +9117,403 @@ "strum 0.27.2", ]   [[package]] +name = "reth-seismic" +version = "1.7.0" +dependencies = [ + "reth-chainspec", + "reth-consensus", + "reth-consensus-common", + "reth-db", + "reth-evm", + "reth-network", + "reth-node-api", + "reth-primitives-traits", + "reth-provider", + "reth-rpc", + "reth-rpc-api", + "reth-rpc-builder", + "reth-rpc-eth-types", + "reth-seismic-chainspec", + "reth-seismic-cli", + "reth-seismic-evm", + "reth-seismic-node", + "reth-seismic-primitives", + "reth-seismic-rpc", + "reth-storage-api", + "reth-trie", +] + +[[package]] +name = "reth-seismic-chainspec" +version = "1.7.0" +dependencies = [ + "alloy-chains", + "alloy-consensus", + "alloy-eips", + "alloy-genesis", + "alloy-hardforks", + "alloy-primitives", + "derive_more 2.1.1", + "once_cell", + "reth-chainspec", + "reth-ethereum-forks", + "reth-network-peers", + "reth-primitives-traits", + "reth-seismic-forks", + "reth-seismic-primitives", + "seismic-alloy-consensus", + "seismic-alloy-rpc-types", + "serde_json", + "thiserror 2.0.17", +] + +[[package]] +name = "reth-seismic-cli" +version = "1.7.0" +dependencies = [ + "clap", + "eyre", + "futures-util", + "proptest", + "reth-chainspec", + "reth-cli", + "reth-cli-commands", + "reth-cli-runner", + "reth-db", + "reth-db-common", + "reth-node-builder", + "reth-node-core", + "reth-node-ethereum", + "reth-node-metrics", + "reth-seismic-chainspec", + "reth-seismic-node", + "reth-stages", + "reth-tracing", + "seismic-alloy-consensus", + "tempfile", + "tracing", +] + +[[package]] +name = "reth-seismic-evm" +version = "1.7.0" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-evm", + "alloy-genesis", + "alloy-primitives", + "alloy-rpc-types-engine", + "alloy-seismic-evm", + "derive_more 2.1.1", + "k256", + "reth-chainspec", + "reth-consensus", + "reth-consensus-common", + "reth-ethereum-forks", + "reth-ethereum-primitives", + "reth-evm", + "reth-execution-errors", + "reth-execution-types", + "reth-primitives-traits", + "reth-revm", + "reth-seismic-chainspec", + "reth-seismic-forks", + "reth-seismic-primitives", + "reth-storage-errors", + "reth-testing-utils", + "revm", + "revm-state", + "schnorrkel", + "secp256k1 0.30.0", + "seismic-alloy-consensus", + "seismic-alloy-genesis", + "seismic-enclave", + "seismic-revm", + "thiserror 2.0.17", + "tracing", +] + +[[package]] +name = "reth-seismic-forks" +version = "1.7.0" +dependencies = [ + "alloy-chains", + "alloy-hardforks", + "alloy-primitives", + "auto_impl", + "once_cell", + "reth-ethereum-forks", + "serde", +] + +[[package]] +name = "reth-seismic-fuzz" +version = "1.7.0" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-evm", + "alloy-primitives", + "alloy-rlp", + "alloy-seismic-evm", + "arbitrary", + "proptest", + "proptest-arbitrary-interop", + "reth-codecs", + "reth-db", + "reth-db-api", + "reth-primitives-traits", + "reth-seismic-chainspec", + "reth-seismic-evm", + "reth-seismic-primitives", + "revm", + "seismic-alloy-consensus", + "seismic-enclave", + "seismic-revm", +] + +[[package]] +name = "reth-seismic-node" +version = "1.7.0" +dependencies = [ + "alloy-chains", + "alloy-consensus", + "alloy-dyn-abi", + "alloy-eips", + "alloy-genesis", + "alloy-json-abi", + "alloy-network", + "alloy-primitives", + "alloy-provider", + "alloy-rpc-types", + "alloy-rpc-types-engine", + "alloy-rpc-types-eth", + "alloy-signer", + "alloy-signer-local", + "alloy-sol-types", + "eyre", + "futures", + "jsonrpsee 0.26.0", + "jsonrpsee-http-client 0.26.0", + "k256", + "rand 0.9.2", + "reqwest", + "reth-chainspec", + "reth-consensus", + "reth-db", + "reth-e2e-test-utils", + "reth-engine-local", + "reth-engine-primitives", + "reth-eth-wire-types", + "reth-ethereum-payload-builder", + "reth-evm", + "reth-exex", + "reth-network", + "reth-node-api", + "reth-node-builder", + "reth-node-core", + "reth-node-ethereum", + "reth-payload-builder", + "reth-payload-primitives", + "reth-primitives-traits", + "reth-provider", + "reth-revm", + "reth-rpc", + "reth-rpc-api", + "reth-rpc-builder", + "reth-rpc-e2e-tests", + "reth-rpc-eth-api", + "reth-rpc-eth-types", + "reth-rpc-layer", + "reth-rpc-server-types", + "reth-seismic-chainspec", + "reth-seismic-evm", + "reth-seismic-forks", + "reth-seismic-node", + "reth-seismic-payload-builder", + "reth-seismic-primitives", + "reth-seismic-rpc", + "reth-seismic-txpool", + "reth-tasks", + "reth-tracing", + "reth-transaction-pool", + "reth-trie-db", + "revm", + "secp256k1 0.30.0", + "seismic-alloy-consensus", + "seismic-alloy-genesis", + "seismic-alloy-network", + "seismic-alloy-provider", + "seismic-alloy-rpc-types", + "seismic-enclave", + "seismic-revm", + "serde", + "serde_json", + "tokio", + "tracing", +] + +[[package]] +name = "reth-seismic-payload-builder" +version = "1.7.0" +dependencies = [ + "alloy-consensus", + "alloy-evm", + "alloy-primitives", + "proptest", + "proptest-arbitrary-interop", + "reth-basic-payload-builder", + "reth-chainspec", + "reth-errors", + "reth-ethereum-payload-builder", + "reth-ethereum-primitives", + "reth-evm", + "reth-execution-errors", + "reth-execution-types", + "reth-payload-builder", + "reth-payload-builder-primitives", + "reth-payload-primitives", + "reth-primitives-traits", + "reth-revm", + "reth-seismic-evm", + "reth-seismic-primitives", + "reth-storage-api", + "reth-storage-errors", + "reth-transaction-pool", + "reth-trie-common", + "revm", + "seismic-enclave", + "tracing", +] + +[[package]] +name = "reth-seismic-primitives" +version = "1.7.0" +dependencies = [ + "alloy-consensus", + "alloy-dyn-abi", + "alloy-eips", + "alloy-evm", + "alloy-network", + "alloy-primitives", + "alloy-rlp", + "alloy-rpc-types", + "alloy-signer-local", + "anyhow", + "arbitrary", + "bincode 1.3.3", + "bytes", + "derive_more 2.1.1", + "enr", + "k256", + "modular-bitfield", + "proptest", + "proptest-arbitrary-interop", + "rand 0.8.5", + "rand 0.9.2", + "reth-codecs", + "reth-primitives-traits", + "reth-zstd-compressors", + "revm-context", + "rstest", + "secp256k1 0.30.0", + "seismic-alloy-consensus", + "seismic-alloy-network", + "seismic-alloy-rpc-types", + "seismic-enclave", + "seismic-revm", + "serde", + "serde_json", + "serde_with", + "tracing", +] + +[[package]] +name = "reth-seismic-rpc" +version = "1.7.0" +dependencies = [ + "alloy-consensus", + "alloy-dyn-abi", + "alloy-eips", + "alloy-json-rpc", + "alloy-primitives", + "alloy-rpc-types", + "alloy-rpc-types-engine", + "alloy-rpc-types-eth", + "alloy-signer-local", + "alloy-sol-types", + "enr", + "eyre", + "futures", + "jsonrpsee 0.26.0", + "jsonrpsee-types 0.26.0", + "k256", + "reth-consensus", + "reth-e2e-test-utils", + "reth-engine-primitives", + "reth-ethereum-engine-primitives", + "reth-evm", + "reth-evm-ethereum", + "reth-node-api", + "reth-node-builder", + "reth-node-ethereum", + "reth-payload-builder", + "reth-primitives", + "reth-primitives-traits", + "reth-provider", + "reth-rpc", + "reth-rpc-builder", + "reth-rpc-convert", + "reth-rpc-engine-api", + "reth-rpc-eth-api", + "reth-rpc-eth-types", + "reth-rpc-layer", + "reth-rpc-server-types", + "reth-seismic-chainspec", + "reth-seismic-evm", + "reth-seismic-primitives", + "reth-seismic-txpool", + "reth-storage-api", + "reth-tasks", + "reth-tracing", + "reth-transaction-pool", + "revm", + "revm-context", + "secp256k1 0.30.0", + "seismic-alloy-consensus", + "seismic-alloy-network", + "seismic-alloy-rpc-types", + "seismic-enclave", + "seismic-revm", + "serde", + "thiserror 2.0.17", + "tokio", + "tracing", +] + +[[package]] +name = "reth-seismic-txpool" +version = "1.7.0" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "c-kzg", + "derive_more 2.1.1", + "reth-chainspec", + "reth-execution-types", + "reth-primitives-traits", + "reth-provider", + "reth-seismic-chainspec", + "reth-seismic-primitives", + "reth-transaction-pool", + "seismic-alloy-consensus", + "tokio", + "tracing", +] + +[[package]] name = "reth-stages" version = "1.7.0" dependencies = [ @@ -10300,7 +9565,7 @@ "reth-testing-utils", "reth-trie", "reth-trie-db", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -10328,7 +9593,7 @@ "reth-static-file", "reth-static-file-types", "reth-testing-utils", "reth-tokio-util", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -10373,7 +9638,7 @@ "reth-trie-common", "reth-trie-sparse", "serde", "serde_with", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -10405,7 +9670,7 @@ version = "1.7.0" dependencies = [ "alloy-primitives", "clap", - "derive_more", + "derive_more 2.1.1", "reth-nippy-jar", "serde", "strum 0.27.2", @@ -10431,6 +9696,7 @@ "reth-stages-types", "reth-storage-errors", "reth-trie-common", "revm-database", + "revm-state", ]   [[package]] @@ -10440,12 +9706,12 @@ dependencies = [ "alloy-eips", "alloy-primitives", "alloy-rlp", - "derive_more", + "derive_more 2.1.1", "reth-primitives-traits", "reth-prune-types", "reth-static-file-types", "revm-database-interface", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] @@ -10488,7 +9754,7 @@ "metrics", "pin-project", "rayon", "reth-metrics", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tracing", "tracing-futures", @@ -10500,13 +9766,13 @@ version = "1.7.0" dependencies = [ "alloy-consensus", "alloy-eips", - "alloy-genesis", "alloy-primitives", "rand 0.8.5", "rand 0.9.2", "reth-ethereum-primitives", "reth-primitives-traits", "secp256k1 0.30.0", + "seismic-alloy-genesis", ]   [[package]] @@ -10529,7 +9795,7 @@ "tracing", "tracing-appender", "tracing-journald", "tracing-logfmt", - "tracing-subscriber 0.3.20", + "tracing-subscriber 0.3.22", ]   [[package]] @@ -10542,7 +9808,7 @@ "opentelemetry-semantic-conventions", "opentelemetry_sdk", "tracing", "tracing-opentelemetry", - "tracing-subscriber 0.3.20", + "tracing-subscriber 0.3.22", ]   [[package]] @@ -10556,7 +9822,7 @@ "alloy-rlp", "aquamarine", "assert_matches", "auto_impl", - "bitflags 2.9.4", + "bitflags 2.10.0", "codspeed-criterion-compat", "futures", "futures-util", @@ -10583,11 +9849,12 @@ "revm-interpreter", "revm-primitives", "rustc-hash 2.1.1", "schnellru", + "seismic-alloy-consensus", "serde", "serde_json", "smallvec", "tempfile", - "thiserror 2.0.16", + "thiserror 2.0.17", "tokio", "tokio-stream", "tracing", @@ -10641,7 +9908,7 @@ "arbitrary", "bincode 1.3.3", "bytes", "codspeed-criterion-compat", - "derive_more", + "derive_more 2.1.1", "hash-db", "itertools 0.14.0", "nybbles", @@ -10653,6 +9920,7 @@ "reth-codecs", "reth-primitives-traits", "revm-database", "revm-state", + "seismic-alloy-genesis", "serde", "serde_json", "serde_with", @@ -10677,6 +9945,8 @@ "reth-trie", "reth-trie-common", "revm", "revm-database", + "revm-primitives", + "revm-state", "serde_json", "similar-asserts", "tracing", @@ -10690,7 +9960,7 @@ dependencies = [ "alloy-primitives", "alloy-rlp", "codspeed-criterion-compat", - "derive_more", + "derive_more 2.1.1", "itertools 0.14.0", "metrics", "proptest", @@ -10707,7 +9977,9 @@ "reth-trie", "reth-trie-common", "reth-trie-db", "reth-trie-sparse", - "thiserror 2.0.16", + "revm-primitives", + "revm-state", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -10784,8 +10056,7 @@ [[package]] name = "revm" version = "29.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c278b6ee9bba9e25043e3fae648fdce632d1944d3ba16f5203069b43bddd57f" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "revm-bytecode", "revm-context", @@ -10803,8 +10074,7 @@ [[package]] name = "revm-bytecode" version = "6.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c52031b73cae95d84cd1b07725808b5fd1500da3e5e24574a3b2dc13d9f16d" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "bitvec", "phf", @@ -10815,8 +10085,7 @@ [[package]] name = "revm-context" version = "9.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fb02c5dab3b535aa5b18277b1d21c5117a25d42af717e6ce133df0ea56663e1" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "bitvec", "cfg-if", @@ -10832,8 +10101,7 @@ [[package]] name = "revm-context-interface" version = "10.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8e9311d27cf75fbf819e7ba4ca05abee1ae02e44ff6a17301c7ab41091b259" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "alloy-eip2930", "alloy-eip7702", @@ -10848,8 +10116,7 @@ [[package]] name = "revm-database" version = "7.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39a276ed142b4718dcf64bc9624f474373ed82ef20611025045c3fb23edbef9c" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "alloy-eips", "revm-bytecode", @@ -10862,8 +10129,7 @@ [[package]] name = "revm-database-interface" version = "7.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c523c77e74eeedbac5d6f7c092e3851dbe9c7fec6f418b85992bd79229db361" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "auto_impl", "either", @@ -10875,8 +10141,7 @@ [[package]] name = "revm-handler" version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528d2d81cc918d311b8231c35330fac5fba8b69766ddc538833e2b5593ee016e" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "auto_impl", "derive-where", @@ -10894,8 +10159,7 @@ [[package]] name = "revm-inspector" version = "10.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf443b664075999a14916b50c5ae9e35a7d71186873b8f8302943d50a672e5e0" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "auto_impl", "either", @@ -10911,41 +10175,43 @@ ]   [[package]] name = "revm-inspectors" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1a292fa860bf3f5448b07f9f7ceff08ff49da5cb9f812065fc03766f8d1626" +version = "0.29.0" +source = "git+https://github.com/SeismicSystems/seismic-revm-inspectors.git?rev=24652f3b9ef6a8057bc46203b26d1d9857f7ae30#24652f3b9ef6a8057bc46203b26d1d9857f7ae30" dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-network-primitives", "alloy-primitives", "alloy-rpc-types-eth", "alloy-rpc-types-trace", + "alloy-serde", "alloy-sol-types", + "alloy-tx-macros", "anstyle", - "boa_engine", - "boa_gc", "colorchoice", "revm", "serde", "serde_json", - "thiserror 2.0.16", + "thiserror 2.0.17", ]   [[package]] name = "revm-interpreter" version = "25.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d6406b711fac73b4f13120f359ed8e65964380dd6182bd12c4c09ad0d4641f" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "revm-bytecode", "revm-context-interface", "revm-primitives", + "revm-state", "serde", ]   [[package]] name = "revm-precompile" version = "27.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b57d4bd9e6b5fe469da5452a8a137bc2d030a3cd47c46908efc615bbc699da" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -10958,20 +10224,18 @@ "blst", "c-kzg", "cfg-if", "k256", - "libsecp256k1", "p256", "revm-primitives", "ripemd", "rug", "secp256k1 0.31.1", - "sha2 0.10.9", + "sha2", ]   [[package]] name = "revm-primitives" version = "20.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa29d9da06fe03b249b6419b33968ecdf92ad6428e2f012dc57bcd619b5d94e" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ "alloy-primitives", "num_enum", @@ -10982,10 +10246,9 @@ [[package]] name = "revm-state" version = "7.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f64fbacb86008394aaebd3454f9643b7d5a782bd251135e17c5b33da592d84d" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "revm-bytecode", "revm-primitives", "serde", @@ -11051,22 +10314,19 @@ ]   [[package]] name = "rmp" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +checksum = "4ba8be72d372b2c9b35542551678538b562e7cf86c3315773cae48dfbfe7790c" dependencies = [ - "byteorder", "num-traits", - "paste", ]   [[package]] name = "rmp-serde" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +checksum = "72f81bee8c8ef9b577d1681a70ebbc962c232461e397b22c208c43c04b67a155" dependencies = [ - "byteorder", "rmp", "serde", ] @@ -11122,7 +10382,7 @@ "quote", "regex", "relative-path", "rustc_version 0.4.1", - "syn 2.0.106", + "syn 2.0.113", "unicode-ident", ]   @@ -11140,14 +10400,15 @@ ]   [[package]] name = "ruint" -version = "1.16.0" +version = "1.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecb38f82477f20c5c3d62ef52d7c4e536e38ea9b73fb570a20c5cae0e14bcf6" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" dependencies = [ "alloy-rlp", "arbitrary", "ark-ff 0.3.0", "ark-ff 0.4.2", + "ark-ff 0.5.0", "bytes", "fastrlp 0.3.1", "fastrlp 0.4.0", @@ -11161,7 +10422,7 @@ "rand 0.8.5", "rand 0.9.2", "rlp", "ruint-macro", - "serde", + "serde_core", "valuable", "zeroize", ] @@ -11214,7 +10475,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.26", + "semver 1.0.27", ]   [[package]] @@ -11223,7 +10484,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -11232,22 +10493,22 @@ ]   [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ]   [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ "log", "once_cell", @@ -11260,21 +10521,21 @@ ]   [[package]] name = "rustls-native-certs" -version = "0.8.1" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "openssl-probe", + "openssl-probe 0.2.0", "rustls-pki-types", "schannel", - "security-framework", + "security-framework 3.5.1", ]   [[package]] name = "rustls-pki-types" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "web-time", "zeroize", @@ -11286,7 +10547,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19787cda76408ec5404443dc8b31795c87cd8fec49762dc75fa727740d34acc1" dependencies = [ - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", "jni", "log", @@ -11295,7 +10556,7 @@ "rustls", "rustls-native-certs", "rustls-platform-verifier-android", "rustls-webpki", - "security-framework", + "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs 0.26.11", "windows-sys 0.59.0", @@ -11309,9 +10570,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"   [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "ring", "rustls-pki-types", @@ -11326,9 +10587,9 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"   [[package]] name = "rusty-fork" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" dependencies = [ "fnv", "quick-error", @@ -11338,15 +10599,9 @@ ]   [[package]] name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "ryu-js" -version = "1.0.2" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd29631678d6fb0903b69223673e122c32e9ae559d0960a38d574695ebc0ea15" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"   [[package]] name = "same-file" @@ -11359,11 +10614,11 @@ ]   [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ]   [[package]] @@ -11380,9 +10635,9 @@ ]   [[package]] name = "schemars" -version = "1.0.4" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" dependencies = [ "dyn-clone", "ref-cast", @@ -11402,6 +10657,27 @@ "hashbrown 0.13.2", ]   [[package]] +name = "schnorrkel" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9fcb6c2e176e86ec703e22560d99d65a5ee9056ae45a08e13e84ebf796296f" +dependencies = [ + "aead", + "arrayref", + "arrayvec", + "cfg-if", + "curve25519-dalek", + "getrandom_or_panic", + "merlin", + "rand_core 0.6.4", + "serde", + "serde_bytes", + "sha2", + "subtle", + "zeroize", +] + +[[package]] name = "scoped-tls" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -11471,12 +10747,25 @@ ]   [[package]] name = "security-framework" -version = "3.3.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.4", - "core-foundation", + "bitflags 2.10.0", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.10.0", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -11484,15 +10773,182 @@ ]   [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", ]   [[package]] +name = "seismic-alloy-consensus" +version = "0.0.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy.git?rev=c8fad0b93da53f2b423d2f6720abdb4a6cbb9082#c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" +dependencies = [ + "alloy-consensus", + "alloy-dyn-abi", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-rpc-types-eth", + "alloy-serde", + "anyhow", + "arbitrary", + "derive_more 1.0.0", + "jsonrpsee 0.24.10", + "k256", + "rand 0.8.5", + "secp256k1 0.30.0", + "seismic-enclave", + "serde", + "serde_json", + "serde_with", + "thiserror 2.0.17", +] + +[[package]] +name = "seismic-alloy-genesis" +version = "0.0.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy.git?rev=c8fad0b93da53f2b423d2f6720abdb4a6cbb9082#c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" +dependencies = [ + "alloy-genesis", + "alloy-primitives", + "alloy-serde", + "alloy-trie", + "serde", + "serde_json", +] + +[[package]] +name = "seismic-alloy-network" +version = "0.0.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy.git?rev=c8fad0b93da53f2b423d2f6720abdb4a6cbb9082#c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" +dependencies = [ + "alloy-consensus", + "alloy-eip7702", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives", + "alloy-provider", + "alloy-rpc-client", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-transport", + "async-trait", + "derive_more 1.0.0", + "futures", + "reqwest", + "seismic-alloy-consensus", + "seismic-alloy-rpc-types", + "seismic-enclave", + "serde", + "tokio", +] + +[[package]] +name = "seismic-alloy-provider" +version = "0.0.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy.git?rev=c8fad0b93da53f2b423d2f6720abdb4a6cbb9082#c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" +dependencies = [ + "alloy-contract", + "alloy-network", + "alloy-primitives", + "alloy-provider", + "alloy-rpc-client", + "alloy-sol-types", + "alloy-transport", + "async-trait", + "reqwest", + "seismic-alloy-consensus", + "seismic-alloy-network", + "seismic-alloy-rpc-types", + "seismic-enclave", + "thiserror 2.0.17", +] + +[[package]] +name = "seismic-alloy-rpc-types" +version = "0.0.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy.git?rev=c8fad0b93da53f2b423d2f6720abdb4a6cbb9082#c8fad0b93da53f2b423d2f6720abdb4a6cbb9082" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-types-eth", + "alloy-serde", + "derive_more 1.0.0", + "seismic-alloy-consensus", + "seismic-enclave", + "serde", + "serde_json", +] + +[[package]] +name = "seismic-enclave" +version = "0.1.0" +source = "git+https://github.com/SeismicSystems/enclave.git?rev=f90b02f38a6190e8b2ff2d051d9043f3480cd3ac#f90b02f38a6190e8b2ff2d051d9043f3480cd3ac" +dependencies = [ + "aes-gcm", + "anyhow", + "hkdf", + "jsonrpsee 0.26.0", + "rand 0.9.2", + "schnorrkel", + "secp256k1 0.30.0", + "serde", + "sha2", + "tracing", +] + +[[package]] +name = "seismic-reth" +version = "1.7.0" +dependencies = [ + "alloy-network", + "alloy-primitives", + "alloy-signer-local", + "clap", + "eyre", + "jsonrpsee-http-client 0.26.0", + "reth-cli-commands", + "reth-cli-util", + "reth-node-builder", + "reth-node-core", + "reth-node-ethereum", + "reth-node-metrics", + "reth-primitives", + "reth-provider", + "reth-seismic-cli", + "reth-seismic-node", + "reth-seismic-rpc", + "reth-tracing", + "seismic-alloy-consensus", + "seismic-alloy-rpc-types", + "seismic-enclave", + "tokio", + "tracing", +] + +[[package]] +name = "seismic-revm" +version = "1.0.0" +source = "git+https://github.com/SeismicSystems/seismic-revm.git?rev=2861f865d2b9249ebb0da4946be5052ec8ab41a0#2861f865d2b9249ebb0da4946be5052ec8ab41a0" +dependencies = [ + "auto_impl", + "hkdf", + "once_cell", + "revm", + "schnorrkel", + "secp256k1 0.31.1", + "seismic-enclave", + "serde", + "sha2", +] + +[[package]] name = "semver" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -11503,11 +10959,12 @@ ]   [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ]   [[package]] @@ -11533,55 +10990,65 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"   [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ]   [[package]] +name = "serde_bytes" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] name = "serde_combinators" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de5fb30ae2918667d3cee99ef4b112f1f7ca0a6c58fa349d7d9e76035c72f8b" dependencies = [ "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", ]   [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.12.1", "itoa", "memchr", - "ryu", "serde", -] - -[[package]] -name = "serde_qs" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7715380eec75f029a4ef7de39a9200e0a63823176b759d055b613f5a87df6a6" -dependencies = [ - "percent-encoding", - "serde", - "thiserror 1.0.69", + "serde_core", + "zmij", ]   [[package]] @@ -11607,19 +11074,18 @@ ]   [[package]] name = "serde_with" -version = "3.14.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.11.0", + "indexmap 2.12.1", "schemars 0.9.0", - "schemars 1.0.4", - "serde", - "serde_derive", + "schemars 1.2.0", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -11627,14 +11093,14 @@ ]   [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" dependencies = [ - "darling 0.20.11", + "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -11656,19 +11122,6 @@ dependencies = [ "cfg-if", "cpufeatures", "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", ]   [[package]] @@ -11738,9 +11191,9 @@ ]   [[package]] name = "signal-hook-mio" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", "mio", @@ -11749,10 +11202,11 @@ ]   [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ]   @@ -11767,6 +11221,12 @@ "rand_core 0.6.4", ]   [[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] name = "similar" version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -11795,7 +11255,7 @@ checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" dependencies = [ "num-bigint", "num-traits", - "thiserror 2.0.16", + "thiserror 2.0.17", "time", ]   @@ -11879,12 +11339,12 @@ ]   [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ]   [[package]] @@ -11914,16 +11374,10 @@ "der", ]   [[package]] -name = "sptr" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9b39299b249ad65f3b7e96443bad61c02ca5cd3589f46cb6d610a0fd6c0d6a" - -[[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"   [[package]] name = "static_assertions" @@ -11965,7 +11419,7 @@ "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -11977,7 +11431,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -11999,9 +11453,9 @@ ]   [[package]] name = "syn" -version = "2.0.106" +version = "2.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" dependencies = [ "proc-macro2", "quote", @@ -12010,14 +11464,13 @@ ]   [[package]] name = "syn-solidity" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0b198d366dbec045acfcd97295eb653a7a2b40e4dc764ef1e79aafcad439d3c" +version = "1.4.1" +source = "git+https://github.com/SeismicSystems/seismic-alloy-core.git?rev=994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7#994f7b3fbc4582c2e06a00d03c7f3fe476b1b7c7" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -12037,7 +11490,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -12077,27 +11530,16 @@ "xattr", ]   [[package]] -name = "tar-no-std" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9ee8b664c9f1740cd813fea422116f8ba29997bb7c878d1940424889802897" -dependencies = [ - "bitflags 2.9.4", - "log", - "num-traits", -] - -[[package]] name = "tempfile" -version = "3.21.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b61f8f20e3a6f7e0649d825294eaf317edce30f82cf6026e7e4cb9222a7d1e" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ - "fastrand 2.3.0", - "getrandom 0.3.3", + "fastrand", + "getrandom 0.3.4", "once_cell", - "rustix 1.0.8", - "windows-sys 0.60.2", + "rustix 1.1.3", + "windows-sys 0.61.2", ]   [[package]] @@ -12118,7 +11560,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -12129,15 +11571,15 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", "test-case-core", ]   [[package]] name = "test-fuzz" -version = "7.2.4" +version = "7.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6696b1bcee3edb0553566f632c31b3b18fda42cf4d529327ca47f230c4acd3ab" +checksum = "11e5c77910b1d5b469a342be541cf44933f0ad2c4b8d5acb32ee46697fd60546" dependencies = [ "serde", "serde_combinators", @@ -12148,9 +11590,9 @@ ]   [[package]] name = "test-fuzz-internal" -version = "7.2.4" +version = "7.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5988511fdb342582013a17a4263e994bce92828a1bae039f92a2f05a5f95ce78" +checksum = "4d25f2f0ee315b130411a98570dd128dfe344bfaa0a28bf33d38f4a1fe85f39b" dependencies = [ "bincode 2.0.1", "cargo_metadata 0.19.2", @@ -12159,9 +11601,9 @@ ]   [[package]] name = "test-fuzz-macro" -version = "7.2.4" +version = "7.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8893e583c5af79a67761a9285535d26612cb1617fcbf388c3abc0c1d35a0b89" +checksum = "b8c03ba0a9e3e4032f94d71c85e149af147843c6f212e4ca4383542d606b04a6" dependencies = [ "darling 0.21.3", "heck", @@ -12169,14 +11611,14 @@ "itertools 0.14.0", "prettyplease", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "test-fuzz-runtime" -version = "7.2.4" +version = "7.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47be06afdb9cb50c76ef938e2e4bda2e28e1cbb4d3d305603d57a5e374a6d6e7" +checksum = "f9a4ac481aa983d386e857a7be0006c2f0ef26e0c5326bbc7262f73c2891b91d" dependencies = [ "hex", "num-traits", @@ -12186,12 +11628,6 @@ "test-fuzz-internal", ]   [[package]] -name = "thin-vec" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d" - -[[package]] name = "thiserror" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -12202,11 +11638,11 @@ ]   [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.16", + "thiserror-impl 2.0.17", ]   [[package]] @@ -12217,18 +11653,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -12251,9 +11687,9 @@ ]   [[package]] name = "tikv-jemalloc-ctl" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21f216790c8df74ce3ab25b534e0718da5a1916719771d3fec23315c99e468b" +checksum = "661f1f6a57b3a36dc9174a2c10f19513b4866816e13425d3e418b11cc37bc24c" dependencies = [ "libc", "paste", @@ -12262,9 +11698,9 @@ ]   [[package]] name = "tikv-jemalloc-sys" -version = "0.6.0+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" +version = "0.6.1+5.3.0-1-ge13ca993e8ccb9ba9847cc330696e02839f328f7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3c60906412afa9c2b5b5a48ca6a5abe5736aec9eb48ad05037a677e52e4e2d" +checksum = "cd8aa5b2ab86a2cefa406d889139c162cbb230092f7d1d7cbc1716405d852a3b" dependencies = [ "cc", "libc", @@ -12272,9 +11708,9 @@ ]   [[package]] name = "tikv-jemallocator" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cec5ff18518d81584f477e9bfdf957f5bb0979b0bac3af4ca30b5b3ae2d2865" +checksum = "0359b4327f954e0567e69fb191cf1436617748813819c94b8cd4a431422d053a" dependencies = [ "libc", "tikv-jemalloc-sys", @@ -12282,12 +11718,12 @@ ]   [[package]] name = "time" -version = "0.3.43" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", - "js-sys", + "itoa", "libc", "num-conv", "num_threads", @@ -12324,22 +11760,12 @@ ]   [[package]] name = "tinystr" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" -dependencies = [ - "displaydoc", - "zerovec 0.10.4", -] - -[[package]] -name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", - "zerovec 0.11.4", + "zerovec", ]   [[package]] @@ -12369,40 +11795,47 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"   [[package]] name = "tokio" -version = "1.47.1" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2 0.6.0", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ]   [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", ]   [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -12410,9 +11843,9 @@ ]   [[package]] name = "tokio-stream" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -12439,9 +11872,9 @@ ]   [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", @@ -12460,8 +11893,8 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", - "toml_edit", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ]   [[package]] @@ -12474,20 +11907,50 @@ "serde", ]   [[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] name = "toml_edit" version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.11.0", + "indexmap 2.12.1", "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_write", "winnow", ]   [[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap 2.12.1", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow", +] + +[[package]] name = "toml_write" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -12516,6 +11979,21 @@ ]   [[package]] name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" @@ -12523,7 +12001,7 @@ dependencies = [ "futures-core", "futures-util", "hdrhistogram", - "indexmap 2.11.0", + "indexmap 2.12.1", "pin-project-lite", "slab", "sync_wrapper", @@ -12536,13 +12014,13 @@ ]   [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "async-compression", "base64 0.22.1", - "bitflags 2.9.4", + "bitflags 2.10.0", "bytes", "futures-core", "futures-util", @@ -12558,7 +12036,7 @@ "percent-encoding", "pin-project-lite", "tokio", "tokio-util", - "tower", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -12579,9 +12057,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"   [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -12591,32 +12069,32 @@ ]   [[package]] name = "tracing-appender" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" +checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 1.0.69", + "thiserror 2.0.17", "time", - "tracing-subscriber 0.3.20", + "tracing-subscriber 0.3.22", ]   [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -12634,13 +12112,13 @@ ]   [[package]] name = "tracing-journald" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0b4143302cf1022dac868d521e36e8b27691f72c84b3311750d5188ebba657" +checksum = "2d3a81ed245bfb62592b1e2bc153e77656d94ee6a0497683a65a12ccaf2438d0" dependencies = [ "libc", "tracing-core", - "tracing-subscriber 0.3.20", + "tracing-subscriber 0.3.22", ]   [[package]] @@ -12663,7 +12141,7 @@ dependencies = [ "time", "tracing", "tracing-core", - "tracing-subscriber 0.3.20", + "tracing-subscriber 0.3.22", ]   [[package]] @@ -12680,7 +12158,7 @@ "smallvec", "tracing", "tracing-core", "tracing-log", - "tracing-subscriber 0.3.20", + "tracing-subscriber 0.3.22", "web-time", ]   @@ -12705,9 +12183,9 @@ ]   [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -12726,9 +12204,9 @@ ]   [[package]] name = "tracy-client" -version = "0.18.2" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef54005d3d760186fd662dad4b7bb27ecd5531cdef54d1573ebd3f20a9205ed7" +checksum = "a4f6fc3baeac5d86ab90c772e9e30620fc653bf1864295029921a15ef478e6a5" dependencies = [ "loom", "once_cell", @@ -12738,9 +12216,9 @@ ]   [[package]] name = "tracy-client-sys" -version = "0.26.1" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "319c70195101a93f56db4c74733e272d720768e13471f400c78406a326b172b0" +checksum = "c5f7c95348f20c1c913d72157b3c6dee6ea3e30b3d19502c5a7f6d3f160dacbf" dependencies = [ "cc", "windows-targets 0.52.6", @@ -12768,7 +12246,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -12783,9 +12261,9 @@ ]   [[package]] name = "triomphe" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" +checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39"   [[package]] name = "try-lock" @@ -12808,15 +12286,15 @@ "rand 0.9.2", "rustls", "rustls-pki-types", "sha1", - "thiserror 2.0.16", + "thiserror 2.0.17", "utf-8", ]   [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"   [[package]] name = "ucd-trie" @@ -12856,15 +12334,15 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"   [[package]] name = "unicase" -version = "2.8.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"   [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"   [[package]] name = "unicode-segmentation" @@ -12931,14 +12409,15 @@ checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae"   [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", "percent-encoding", "serde", + "serde_derive", ]   [[package]] @@ -12948,12 +12427,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"   [[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - -[[package]] name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -12967,11 +12440,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"   [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", "wasm-bindgen", ] @@ -13049,7 +12522,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -13060,12 +12533,6 @@ checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] - -[[package]] -name = "waker-fn" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7"   [[package]] name = "walkdir" @@ -13088,30 +12555,24 @@ ]   [[package]] name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"   [[package]] -name = "wasi" -version = "0.14.4+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ "wit-bindgen", ]   [[package]] name = "wasm-bindgen" -version = "0.2.101" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -13121,24 +12582,10 @@ "wasm-bindgen-shared", ]   [[package]] -name = "wasm-bindgen-backend" -version = "0.2.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-shared", -] - -[[package]] name = "wasm-bindgen-futures" -version = "0.4.51" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", "js-sys", @@ -13149,9 +12596,9 @@ ]   [[package]] name = "wasm-bindgen-macro" -version = "0.2.101" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -13159,22 +12606,22 @@ ]   [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.101" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.106", - "wasm-bindgen-backend", + "syn 2.0.113", "wasm-bindgen-shared", ]   [[package]] name = "wasm-bindgen-shared" -version = "0.2.101" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] @@ -13208,9 +12655,9 @@ ]   [[package]] name = "web-sys" -version = "0.3.78" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -13232,14 +12679,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75c7f0ef91146ebfb530314f5f1d24528d7f0767efbfd31dce919275413e393e" dependencies = [ - "webpki-root-certs 1.0.2", + "webpki-root-certs 1.0.5", ]   [[package]] name = "webpki-root-certs" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4ffd8df1c57e87c325000a3d6ef93db75279dc3a231125aac571650f22b12a" +checksum = "36a29fc0408b113f68cf32637857ab740edfafdf460c326cd2afaa2d84cc05dc" dependencies = [ "rustls-pki-types", ] @@ -13250,23 +12697,23 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.2", + "webpki-roots 1.0.5", ]   [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "12bed680863276c63889429bfd6cab3b99943659923822de1c8a39c49e4d722c" dependencies = [ "rustls-pki-types", ]   [[package]] name = "widestring" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd7cf3379ca1aac9eea11fba24fd7e315d621f8dfe35c8d7d2be8b793726e07d" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471"   [[package]] name = "winapi" @@ -13286,11 +12733,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"   [[package]] name = "winapi-util" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ]   [[package]] @@ -13311,34 +12758,23 @@ ]   [[package]] name = "windows" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" -dependencies = [ - "windows-core 0.58.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows" -version = "0.61.3" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ "windows-collections", - "windows-core 0.61.2", + "windows-core 0.62.2", "windows-future", - "windows-link 0.1.3", "windows-numerics", ]   [[package]] name = "windows-collections" -version = "0.2.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-core 0.61.2", + "windows-core 0.62.2", ]   [[package]] @@ -13355,38 +12791,25 @@ ]   [[package]] name = "windows-core" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" -dependencies = [ - "windows-implement 0.58.0", - "windows-interface 0.58.0", - "windows-result 0.2.0", - "windows-strings 0.1.0", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-core" -version = "0.61.2" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ - "windows-implement 0.60.0", - "windows-interface 0.59.1", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link", + "windows-result 0.4.1", + "windows-strings", ]   [[package]] name = "windows-future" -version = "0.2.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core 0.62.2", + "windows-link", "windows-threading", ]   @@ -13398,29 +12821,18 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", -] - -[[package]] -name = "windows-implement" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -13431,51 +12843,34 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", -] - -[[package]] -name = "windows-interface" -version = "0.58.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"   [[package]] name = "windows-numerics" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core 0.62.2", + "windows-link", ]   [[package]] @@ -13489,39 +12884,20 @@ ]   [[package]] name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-result 0.2.0", - "windows-targets 0.52.6", + "windows-link", ]   [[package]] name = "windows-strings" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.1.3", + "windows-link", ]   [[package]] @@ -13566,16 +12942,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", ]   [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.0", + "windows-link", ]   [[package]] @@ -13626,28 +13002,28 @@ ]   [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ]   [[package]] name = "windows-threading" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link 0.1.3", + "windows-link", ]   [[package]] @@ -13670,9 +13046,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"   [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"   [[package]] name = "windows_aarch64_msvc" @@ -13694,9 +13070,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"   [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"   [[package]] name = "windows_i686_gnu" @@ -13718,9 +13094,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"   [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"   [[package]] name = "windows_i686_gnullvm" @@ -13730,9 +13106,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"   [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"   [[package]] name = "windows_i686_msvc" @@ -13754,9 +13130,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"   [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"   [[package]] name = "windows_x86_64_gnu" @@ -13778,9 +13154,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"   [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"   [[package]] name = "windows_x86_64_gnullvm" @@ -13802,9 +13178,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"   [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"   [[package]] name = "windows_x86_64_msvc" @@ -13826,15 +13202,15 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"   [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"   [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] @@ -13851,27 +13227,15 @@ ]   [[package]] name = "wit-bindgen" -version = "0.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" - -[[package]] -name = "write16" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" - -[[package]] -name = "writeable" -version = "0.5.5" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"   [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9"   [[package]] name = "ws_stream_wasm" @@ -13886,7 +13250,7 @@ "log", "pharos", "rustc_version 0.4.1", "send_wrapper 0.6.0", - "thiserror 2.0.16", + "thiserror 2.0.17", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -13903,12 +13267,12 @@ ]   [[package]] name = "xattr" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" dependencies = [ "libc", - "rustix 1.0.8", + "rustix 1.1.3", ]   [[package]] @@ -13919,70 +13283,45 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"   [[package]] name = "yoke" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive 0.7.5", - "zerofrom", -] - -[[package]] -name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", - "yoke-derive 0.8.0", + "yoke-derive", "zerofrom", ]   [[package]] name = "yoke-derive" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "synstructure", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", "synstructure", ]   [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ]   [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] @@ -14002,84 +13341,68 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", "synstructure", ]   [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ]   [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", - "yoke 0.8.0", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" -dependencies = [ - "yoke 0.7.5", + "yoke", "zerofrom", - "zerovec-derive 0.10.3", ]   [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ - "yoke 0.8.0", + "yoke", "zerofrom", - "zerovec-derive 0.11.1", + "zerovec-derive", ]   [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.113", ]   [[package]] -name = "zerovec-derive" -version = "0.11.1" +name = "zmij" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] +checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8"   [[package]] name = "zstd"
diff --git reth/fork.yaml seismic-reth/fork.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e10527858f1e786e430b4fd9b9020b00c6ecd2d3 --- /dev/null +++ seismic-reth/fork.yaml @@ -0,0 +1,105 @@ +# Uses https://github.com/protolambda/forkdiff to generate a diff overview index.html page. +# To use: +# 1. install forkdiff: `go install github.com/protolambda/forkdiff@latest` +# 2. run `forkdiff` +title: "SeismicSystems/seismic-reth" # Define the HTML page title +logo: "logo.png" +footer: | # define the footer with markdown + SeismicSystems' [seismic-reth](https://github.com/SeismicSystems/seismic-reth) fork overview - created with [Forkdiff](https://github.com/protolambda/forkdiff) +# We compare the fork against the base branch, which matches the upstream repo's main branch +# at the point where the fork was created. +base: + name: reth + url: https://github.com/SeismicSystems/seismic-reth + ref: refs/remotes/origin/main +fork: + name: seismic-reth + url: https://github.com/SeismicSystems/seismic-reth + ref: refs/remotes/origin/seismic +def: + title: "Seismic-Reth fork diff" + description: | # description in markdown + - Original reth codebase: [`https://github.com/paradigmxyz/reth`](https://github.com/paradigmxyz/reth). + - Seismic reth fork: [`https://github.com/SeismicSystems/seismic-reth`](https://github.com/SeismicSystems/seismic-reth). + sub: + - title: "Seismic crate" + description: | + TODO + sub: + - title: "evm" + globs: + - "crates/seismic/evm/**" + + - title: "node" + globs: + - "crates/seismic/node/**" + + - title: "rpc" + globs: + - "crates/seismic/rpc/**" + + - title: "primitives" + globs: + - "crates/seismic/primitives/**" + + - title: "txpool" + globs: + - "crates/seismic/txpool/**" + + - title: "chainspec" + globs: + - "crates/seismic/chainspec/**" + - "crates/seismic/hardforks/**" + + - title: "misc" + globs: + - "crates/seismic/**" + + - title: "Crates" + description: | + Changes to other crates in the repo. + sub: + - title: "trie" + globs: + - "crates/trie/**" + + - title: "storage" + globs: + - "crates/storage/**" + + - title: "Docs" + description: | + Changes to documentation files. + sub: + - title: "markdown docs" + globs: + - "**/*.md" + - "**/*.mdx" + + - title: "Tests" + description: | + tests ^.^ + sub: + - title: "tests" + globs: + - "**/tests/**" + - "testing/**" + + - title: "test utils" + globs: + - "crates/e2e-test-utils/**" + + - title: "CICD" + description: | + Changes to CICD workflows to support our custom testing and deployment. + sub: + - title: "Github workflows" + globs: + - ".github/**" + - ".circleci/**" + +# files can be ignored globally, these will be listed in a separate grayed-out section, +# and do not count towards the total line count. +ignore: + - "**/Cargo.lock" + - "fork.yaml"