From 036fd1f4c73ab6d37228f35faf394bbd46f7f164 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 14:15:42 +0100 Subject: [PATCH 01/56] mark: 0xaatif/trace-decoder-backend-rewrite4 From 1b89a359399746ef5d476587e197d247a0ba6185 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 14:15:54 +0100 Subject: [PATCH 02/56] refactor: initial implementation --- Cargo.lock | 11 + .../src/cpu/kernel/constants/mod.rs | 4 +- trace_decoder/Cargo.toml | 2 + trace_decoder/src/decoding.rs | 2 +- trace_decoder/src/imp.rs | 506 ++++++++++++++++++ trace_decoder/src/lib.rs | 15 +- trace_decoder/src/processed_block_trace.rs | 22 +- trace_decoder/src/typed_mpt.rs | 113 +++- 8 files changed, 637 insertions(+), 38 deletions(-) create mode 100644 trace_decoder/src/imp.rs diff --git a/Cargo.lock b/Cargo.lock index 11feda934..fe9988dc2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -83,6 +83,16 @@ dependencies = [ "strum", ] +[[package]] +name = "alloy-compat" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6216c5ab5502a6824ec87a7bcd5c52ca14137f00b37dea3ab321a1656ff46383" +dependencies = [ + "alloy-primitives", + "ethereum-types", +] + [[package]] name = "alloy-consensus" version = "0.3.0" @@ -5092,6 +5102,7 @@ name = "trace_decoder" version = "0.6.0" dependencies = [ "alloy", + "alloy-compat", "anyhow", "bitflags 2.6.0", "bitvec", diff --git a/evm_arithmetization/src/cpu/kernel/constants/mod.rs b/evm_arithmetization/src/cpu/kernel/constants/mod.rs index 577bfb875..fb8ae054b 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/mod.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/mod.rs @@ -397,7 +397,9 @@ pub mod cancun_constants { hex!("000000000000000000000000000000001666c54b0a32529503432fcae0181b4bef79de09fc63671fda5ed1ba9bfa07899495346f3d7ac9cd23048ef30d0a154f"), // y_im ]; - pub const HISTORY_BUFFER_LENGTH: (&str, u64) = ("HISTORY_BUFFER_LENGTH", 8191); + pub const HISTORY_BUFFER_LENGTH_VALUE: u64 = 8191; + pub const HISTORY_BUFFER_LENGTH: (&str, u64) = + ("HISTORY_BUFFER_LENGTH", HISTORY_BUFFER_LENGTH_VALUE); // Beacon constants /////////////////// diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 4308a0ebe..7ebfcdb9b 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -10,6 +10,8 @@ homepage.workspace = true keywords.workspace = true [dependencies] +alloy.workspace = true +alloy-compat = "0.1.0" anyhow.workspace = true bitflags = { workspace = true } bitvec = { workspace = true } diff --git a/trace_decoder/src/decoding.rs b/trace_decoder/src/decoding.rs index 758951b45..ebb293b2c 100644 --- a/trace_decoder/src/decoding.rs +++ b/trace_decoder/src/decoding.rs @@ -692,7 +692,7 @@ fn create_trie_subset_wrapped( .context(format!("missing keys when creating {}", trie_type)) } -fn eth_to_gwei(eth: U256) -> U256 { +pub fn eth_to_gwei(eth: U256) -> U256 { // 1 ether = 10^9 gwei. eth * U256::from(10).pow(9.into()) } diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs new file mode 100644 index 000000000..d5b370ea0 --- /dev/null +++ b/trace_decoder/src/imp.rs @@ -0,0 +1,506 @@ +use std::{ + collections::{BTreeMap, BTreeSet}, + mem, + ops::Range, +}; + +use alloy_compat::Compat as _; +use anyhow::{anyhow, ensure, Context as _}; +use ethereum_types::{Address, U256}; +use evm_arithmetization::{ + generation::{mpt::AccountRlp, TrieInputs}, + proof::TrieRoots, + testing_utils::{BEACON_ROOTS_CONTRACT_ADDRESS, HISTORY_BUFFER_LENGTH_VALUE}, + GenerationInputs, +}; +use itertools::Itertools as _; +use keccak_hash::H256; +use mpt_trie::partial_trie::PartialTrie as _; +use nunny::NonEmpty; + +use crate::{ + decoding::eth_to_gwei, + processed_block_trace::{map_receipt_bytes, Hash2Code}, + typed_mpt::{ReceiptTrie, StateMpt, StateTrie, StorageTrie, TransactionTrie, TrieKey}, + BlockLevelData, BlockTrace, BlockTraceTriePreImages, CombinedPreImages, ContractCodeUsage, + OtherBlockData, SeparateStorageTriesPreImage, SeparateTriePreImage, SeparateTriePreImages, + TxnInfo, TxnMeta, TxnTrace, +}; + +/// TODO(0xaatif): doc +pub fn entrypoint( + trace: BlockTrace, + other: OtherBlockData, + batch_size: usize, + use_burn_addr: bool, +) -> anyhow::Result> { + ensure!(batch_size != 0); + + let BlockTrace { + trie_pre_images, + code_db, + txn_info, + } = trace; + let (state, storage, mut code) = start(trie_pre_images)?; + code.extend(code_db); + + let OtherBlockData { + b_data: + BlockLevelData { + b_meta, + b_hashes, + mut withdrawals, + }, + checkpoint_state_trie_root, + } = other; + + // TODO(0xaatif): docs for the RPC field say this is gwei already... + // in any case, this shouldn't be our problem. + for (_, amt) in &mut withdrawals { + *amt = eth_to_gwei(*amt) + } + + let batches = middle( + state, + storage, + txn_info + .into_iter() + .pad_using(2, |_ix| TxnInfo::default()) + .chunks(batch_size) + .into_iter() + .map(FromIterator::from_iter) + .collect(), + &mut code, + b_meta.block_timestamp, + b_meta.parent_beacon_block_root, + withdrawals, + )?; + + let mut running_gas_used = 0; + Ok(batches + .into_iter() + .map( + |Batch { + first_txn_ix, + gas_used, + contract_code, + byte_code, + before: + IntraBlockTries { + state, + storage, + transaction, + receipt, + }, + after, + withdrawals, + }| GenerationInputs { + txn_number_before: first_txn_ix.into(), + gas_used_before: running_gas_used.into(), + gas_used_after: { + running_gas_used += gas_used; + running_gas_used.into() + }, + signed_txns: byte_code.into_iter().map(Into::into).collect(), + withdrawals, + global_exit_roots: vec![], + tries: TrieInputs { + state_trie: state.into(), + transactions_trie: transaction.into(), + receipts_trie: receipt.into(), + storage_tries: storage.into_iter().map(|(k, v)| (k, v.into())).collect(), + }, + trie_roots_after: after, + checkpoint_state_trie_root, + contract_code: contract_code + .into_iter() + .map(|it| (keccak_hash::keccak(&it), it)) + .collect(), + block_metadata: b_meta.clone(), + block_hashes: b_hashes.clone(), + burn_addr: use_burn_addr.then_some(Address::zero()), + }, + ) + .collect()) +} + +fn start( + pre_images: BlockTraceTriePreImages, +) -> anyhow::Result<(StateMpt, BTreeMap, Hash2Code)> { + Ok(match pre_images { + // TODO(0xaatif): refactor our convoluted input types + BlockTraceTriePreImages::Separate(SeparateTriePreImages { + state: SeparateTriePreImage::Direct(state), + storage: SeparateStorageTriesPreImage::MultipleTries(storage), + }) => { + let state = state.items().try_fold( + StateMpt::default(), + |mut acc, (nibbles, hash_or_val)| { + let path = TrieKey::from_nibbles(nibbles); + match hash_or_val { + mpt_trie::trie_ops::ValOrHash::Val(bytes) => { + #[expect(deprecated)] // this is MPT specific + acc.insert_by_hashed_address( + path.into_hash() + .context("invalid path length in direct state trie")?, + rlp::decode(&bytes) + .context("invalid AccountRlp in direct state trie")?, + )?; + } + mpt_trie::trie_ops::ValOrHash::Hash(h) => { + acc.insert_hash_by_key(path, h)?; + } + }; + anyhow::Ok(acc) + }, + )?; + let storage = storage + .into_iter() + .map(|(k, SeparateTriePreImage::Direct(v))| { + v.items() + .try_fold(StorageTrie::default(), |mut acc, (nibbles, hash_or_val)| { + let path = TrieKey::from_nibbles(nibbles); + match hash_or_val { + mpt_trie::trie_ops::ValOrHash::Val(value) => { + acc.insert(path, value)?; + } + mpt_trie::trie_ops::ValOrHash::Hash(h) => { + acc.insert_hash(path, h)?; + } + }; + anyhow::Ok(acc) + }) + .map(|v| (k, v)) + }) + .collect::>()?; + (state, storage, Hash2Code::new()) + } + BlockTraceTriePreImages::Combined(CombinedPreImages { compact }) => { + let instructions = crate::wire::parse(&compact) + .context("couldn't parse instructions from binary format")?; + let crate::type1::Frontend { + state, + storage, + code, + } = crate::type1::frontend(instructions)?; + (state, storage, code.into_iter().map(Into::into).collect()) + } + }) +} + +#[derive(Debug)] +struct Batch { + pub first_txn_ix: usize, + pub gas_used: u64, + /// See [`GenerationInputs::contract_code`]. + pub contract_code: BTreeSet>, + /// For each transaction in batch, in order. + pub byte_code: Vec>>, + + pub before: IntraBlockTries, + pub after: TrieRoots, + + /// Empty for all but the final batch + pub withdrawals: Vec<(Address, U256)>, +} + +/// [`evm_arithmetization::generation::TrieInputs`], +/// generic over state trie representation. +#[derive(Debug)] +struct IntraBlockTries { + pub state: StateTrieT, + pub storage: BTreeMap, + pub transaction: TransactionTrie, + pub receipt: ReceiptTrie, +} + +fn middle( + // state at the beginning of the block + mut state_trie: StateTrieT, + // storage at the beginning of the block + mut storage: BTreeMap, + batches: Vec>, + code: &mut Hash2Code, + block_timestamp: U256, + parent_beacon_block_root: H256, + mut withdrawals: Vec<(Address, U256)>, +) -> anyhow::Result>> { + // Initialise the storage tries. + for (haddr, acct) in state_trie.iter() { + let storage = storage.entry(haddr).or_insert({ + let mut it = StorageTrie::default(); + it.insert_hash(TrieKey::default(), acct.storage_root) + .expect("empty trie insert cannot fail"); + it + }); + ensure!( + storage.root() == acct.storage_root, + "inconsistent initial storage for hashed address {haddr:x}" + ) + } + + // These are the per-block tries. + let mut transaction_trie = TransactionTrie::new(); + let mut receipt_trie = ReceiptTrie::new(); + + let mut out = vec![]; + + let mut curr_txn_ix = 0; + let len_txns = batches.iter().flatten().count(); + for batch in batches { + let batch_first_txn_ix = curr_txn_ix; // GOTCHA: if there are no transactions in this batch + let mut batch_gas_used = 0; + let mut batch_byte_code = vec![]; + let mut batch_contract_code = BTreeSet::from([vec![]]); // always include empty code + + let mut before = IntraBlockTries { + state: state_trie.clone(), + transaction: transaction_trie.clone(), + receipt: receipt_trie.clone(), + storage: storage.clone(), + }; + // We want to trim the TrieInputs above, + // but won't know the bounds until after the loop below, + // so store that information here. + let mut storage_masks = BTreeMap::<_, BTreeSet>::new(); + let mut state_mask = BTreeSet::new(); + + if curr_txn_ix == 0 { + cancun_hook( + block_timestamp, + &mut storage, + &mut storage_masks, + parent_beacon_block_root, + &mut state_mask, + &mut state_trie, + )?; + } + + for TxnInfo { + traces, + meta: + TxnMeta { + byte_code: txn_byte_code, + new_receipt_trie_node_byte, + gas_used: txn_gas_used, + }, + } in batch + { + if let Ok(nonempty) = nunny::Vec::new(txn_byte_code) { + batch_byte_code.push(nonempty.clone()); + transaction_trie.insert(curr_txn_ix, nonempty.into())?; + receipt_trie.insert( + curr_txn_ix, + map_receipt_bytes(new_receipt_trie_node_byte.clone())?, + )?; + } + + batch_gas_used += txn_gas_used; + + for ( + addr, + empty, + TxnTrace { + balance, + nonce, + storage_read, + storage_written, + code_usage, + self_destructed, + }, + ) in traces + .into_iter() + .map(|(addr, trc)| (addr, trc == TxnTrace::default(), trc)) + { + let (mut acct, born) = state_trie + .get_by_address(addr) + .map(|acct| (acct, false)) + .unwrap_or((AccountRlp::default(), true)); + + let commit = match born { + false => !empty, + true => { + let (_, _, receipt) = evm_arithmetization::generation::mpt::decode_receipt( + &map_receipt_bytes(new_receipt_trie_node_byte.clone())?, + ) + .map_err(|e| anyhow!("{e:?}")) + .context("couldn't decode receipt")?; + receipt.status && !empty + } // if txn failed, don't commit changes to trie + }; + + if commit { + acct.balance = balance.unwrap_or(acct.balance); + acct.nonce = nonce.unwrap_or(acct.nonce); + acct.code_hash = code_usage + .map(|it| match it { + ContractCodeUsage::Read(hash) => { + batch_contract_code.insert(code.get(hash)?); + anyhow::Ok(hash) + } + ContractCodeUsage::Write(bytes) => { + code.insert(bytes.clone()); + let hash = keccak_hash::keccak(&bytes); + batch_contract_code.insert(bytes); + Ok(hash) + } + }) + .transpose()? + .unwrap_or(acct.code_hash); + + let trim_storage = storage_masks.entry(addr).or_default(); + + trim_storage.extend( + storage_written + .keys() + .chain(&storage_read) + .map(|it| TrieKey::from_hash(keccak_hash::keccak(it))), + ); + + let storage_trie_change = !storage_written.is_empty(); + + if storage_trie_change { + let storage = match born { + true => storage.entry(keccak_hash::keccak(addr)).or_default(), + false => storage + .get_mut(&keccak_hash::keccak(addr)) + .context(format!("missing storage trie for address {addr:x}"))?, + }; + + for (k, v) in storage_written { + let slot = TrieKey::from_hash(keccak_hash::keccak(k)); + match v.is_zero() { + // this is actually a delete + true => trim_storage.extend(storage.reporting_remove(slot)?), + false => { + storage.insert(slot, rlp::encode(&v).to_vec())?; + } + } + } + acct.storage_root = storage.root(); + } + + state_trie.insert_by_address(addr, acct)?; + } + + if self_destructed { + storage.remove(&keccak_hash::keccak(addr)); + state_mask.extend(state_trie.reporting_remove(addr)?) + } + + let is_precompile = + PRECOMPILE_ADDRESS_RANGE.contains(&U256::from_big_endian(addr.as_bytes())); + + // Trie witnesses will only include accessed precompile accounts as hash + // nodes if the transaction calling them reverted. If this is the case, we + // shouldn't include them in this transaction's `state_accesses` to allow the + // decoder to build a minimal state trie without hitting any hash node. + + if !is_precompile || state_trie.get_by_address(addr).is_some() { + state_mask.insert(TrieKey::from_address(addr)); + } + } + + curr_txn_ix += 1; + } // txn in batch + + out.push(Batch { + first_txn_ix: batch_first_txn_ix, + gas_used: batch_gas_used, + contract_code: batch_contract_code, + byte_code: batch_byte_code, + withdrawals: match curr_txn_ix == len_txns { + true => { + for (addr, amt) in &withdrawals { + state_mask.insert(TrieKey::from_address(*addr)); + let mut acct = state_trie + .get_by_address(*addr) + .context("missing address for withdrawal")?; + acct.balance += *amt; + state_trie + .insert_by_address(*addr, acct) + // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 + // Add an entry API + .expect("insert must succeed with the same key as a successful `get`"); + } + mem::take(&mut withdrawals) + } + false => vec![], + }, + before: { + before.state.trim_to(state_mask)?; + before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; + before + .transaction + .trim_to(batch_first_txn_ix..curr_txn_ix)?; + + for (addr, mask) in storage_masks { + if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { + it.trim_to(mask)? + } // TODO(0xaatif): why is this fallible? + } + before + }, + after: TrieRoots { + state_root: state_trie.root(), + transactions_root: transaction_trie.root(), + receipts_root: receipt_trie.root(), + }, + }); + } // batch in batches + + Ok(out) +} + +fn cancun_hook( + block_timestamp: U256, + storage: &mut BTreeMap, + trim_storage: &mut BTreeMap>, + parent_beacon_block_root: H256, + trim_state: &mut BTreeSet, + state_trie: &mut StateTrieT, +) -> anyhow::Result<()> { + let history_buffer_length = U256::from(HISTORY_BUFFER_LENGTH_VALUE); + let history_timestamp = block_timestamp % history_buffer_length; + let history_timestamp_next = history_timestamp + history_buffer_length; + let beacon_storage = storage + .get_mut(&keccak_hash::keccak(BEACON_ROOTS_CONTRACT_ADDRESS)) + .context("missing beacon contract storage trie")?; + let beacon_trim = trim_storage + .entry(BEACON_ROOTS_CONTRACT_ADDRESS) + .or_default(); + for (ix, u) in [ + (history_timestamp, block_timestamp), + ( + history_timestamp_next, + U256::from_big_endian(parent_beacon_block_root.as_bytes()), + ), + ] { + let mut h = [0; 32]; + ix.to_big_endian(&mut h); + let slot = TrieKey::from_hash(keccak_hash::keccak(H256::from_slice(&h))); + beacon_trim.insert(slot); + + match u.is_zero() { + true => beacon_trim.extend(beacon_storage.reporting_remove(slot)?), + false => { + beacon_storage.insert(slot, alloy::rlp::encode(u.compat()))?; + beacon_trim.insert(slot); + } + } + } + trim_state.insert(TrieKey::from_address(BEACON_ROOTS_CONTRACT_ADDRESS)); + let mut beacon_acct = state_trie + .get_by_address(BEACON_ROOTS_CONTRACT_ADDRESS) + .context("missing beacon contract address")?; + beacon_acct.storage_root = beacon_storage.root(); + state_trie + .insert_by_address(BEACON_ROOTS_CONTRACT_ADDRESS, beacon_acct) + // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 + // Add an entry API + .expect("insert must succeed with the same key as a successful `get`"); + Ok(()) +} + +// TODO(0xaatif): is this _meant_ to exclude the final member? +const PRECOMPILE_ADDRESS_RANGE: Range = U256([1, 0, 0, 0])..U256([10, 0, 0, 0]); diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index 2202d58c5..d8de6447c 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -178,7 +178,7 @@ pub enum SeparateStorageTriesPreImage { } /// Info specific to txns in the block. -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, Default)] pub struct TxnInfo { /// Trace data for the txn. This is used by the protocol to: /// - Mutate it's own trie state between txns to arrive at the correct trie @@ -192,7 +192,7 @@ pub struct TxnInfo { } /// Structure holding metadata for one transaction. -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, Default)] pub struct TxnMeta { /// Txn byte code. This is also the raw RLP bytestring inserted into the txn /// trie by this txn. Note that the key is not included and this is only @@ -214,7 +214,7 @@ pub struct TxnMeta { /// /// Specifically, since we can not execute the txn before proof generation, we /// rely on a separate EVM to run the txn and supply this data for us. -#[derive(Clone, Debug, Deserialize, Serialize, Default)] +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] pub struct TxnTrace { /// If the balance changed, then the new balance will appear here. Will be /// `None` if no change. @@ -250,7 +250,7 @@ fn is_false(b: &bool) -> bool { } /// Contract code access type. Used by txn traces. -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] #[serde(rename_all = "snake_case")] pub enum ContractCodeUsage { /// Contract was read. @@ -282,9 +282,14 @@ pub struct BlockLevelData { pub withdrawals: Vec<(Address, U256)>, } +pub use entrypoint_old as entrypoint; +pub use imp::entrypoint as entrypoint_new; + +mod imp; + /// TODO(0xaatif): /// document this once we have the API finalized -pub fn entrypoint( +pub fn entrypoint_old( trace: BlockTrace, other: OtherBlockData, mut batch_size: usize, diff --git a/trace_decoder/src/processed_block_trace.rs b/trace_decoder/src/processed_block_trace.rs index f2e4fcb5e..7be1fb297 100644 --- a/trace_decoder/src/processed_block_trace.rs +++ b/trace_decoder/src/processed_block_trace.rs @@ -52,23 +52,29 @@ impl Hash2Code { inner: HashMap::new(), } } - fn get(&mut self, hash: H256) -> anyhow::Result> { + pub fn get(&mut self, hash: H256) -> anyhow::Result> { match self.inner.get(&hash) { Some(code) => Ok(code.clone()), None => bail!("no code for hash {}", hash), } } - fn insert(&mut self, code: Vec) { + pub fn insert(&mut self, code: Vec) { self.inner.insert(hash(&code), code); } } +impl Extend> for Hash2Code { + fn extend>>(&mut self, iter: II) { + for it in iter { + self.insert(it) + } + } +} + impl FromIterator> for Hash2Code { fn from_iter>>(iter: II) -> Self { let mut this = Self::new(); - for code in iter { - this.insert(code) - } + this.extend(iter); this } } @@ -238,9 +244,7 @@ impl TxnInfo { false => Some(txn.meta.byte_code.clone()), true => None, }, - receipt_node_bytes: check_receipt_bytes( - txn.meta.new_receipt_trie_node_byte.clone(), - )?, + receipt_node_bytes: map_receipt_bytes(txn.meta.new_receipt_trie_node_byte.clone())?, gas_used: txn.meta.gas_used, created_accounts, }); @@ -254,7 +258,7 @@ impl TxnInfo { } } -fn check_receipt_bytes(bytes: Vec) -> anyhow::Result> { +pub fn map_receipt_bytes(bytes: Vec) -> anyhow::Result> { match rlp::decode::(&bytes) { Ok(_) => Ok(bytes), Err(_) => { diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index 8409e74c0..c26991da3 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -186,6 +186,9 @@ pub struct TransactionTrie { } impl TransactionTrie { + pub fn new() -> Self { + Self::default() + } pub fn insert(&mut self, txn_ix: usize, val: Vec) -> anyhow::Result>> { let prev = self .untyped @@ -201,6 +204,22 @@ impl TransactionTrie { pub fn as_hashed_partial_trie(&self) -> &mpt_trie::partial_trie::HashedPartialTrie { &self.untyped } + /// Defer (hash) parts of the trie that aren't in `txn_ixs`. + pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + self.untyped = mpt_trie::trie_subsets::create_trie_subset( + &self.untyped, + txn_ixs + .into_iter() + .map(|it| TrieKey::from_txn_ix(it).into_nibbles()), + )?; + Ok(()) + } +} + +impl From for HashedPartialTrie { + fn from(value: TransactionTrie) -> Self { + value.untyped + } } /// Per-block, `txn_ix -> [u8]`. @@ -212,6 +231,9 @@ pub struct ReceiptTrie { } impl ReceiptTrie { + pub fn new() -> Self { + Self::default() + } pub fn insert(&mut self, txn_ix: usize, val: Vec) -> anyhow::Result>> { let prev = self .untyped @@ -227,6 +249,37 @@ impl ReceiptTrie { pub fn as_hashed_partial_trie(&self) -> &mpt_trie::partial_trie::HashedPartialTrie { &self.untyped } + /// Defer (hash) parts of the trie that aren't in `txn_ixs`. + pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + self.untyped = mpt_trie::trie_subsets::create_trie_subset( + &self.untyped, + txn_ixs + .into_iter() + .map(|it| TrieKey::from_txn_ix(it).into_nibbles()), + )?; + Ok(()) + } +} + +impl From for HashedPartialTrie { + fn from(value: ReceiptTrie) -> Self { + value.untyped + } +} + +pub trait StateTrie { + fn insert_by_address( + &mut self, + address: Address, + account: AccountRlp, + ) -> anyhow::Result>; + fn insert_hash_by_key(&mut self, key: TrieKey, hash: H256) -> anyhow::Result<()>; + fn get_by_address(&self, address: Address) -> Option; + fn reporting_remove(&mut self, address: Address) -> anyhow::Result>; + fn contains_address(&self, address: Address) -> bool; + fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; + fn iter(&self) -> impl Iterator + '_; + fn root(&self) -> H256; } /// Global, [`Address`] `->` [`AccountRlp`]. @@ -254,17 +307,9 @@ impl StateMpt { ) -> anyhow::Result> { self.typed.insert(TrieKey::from_hash(key), account) } - pub fn iter(&self) -> impl Iterator + '_ { - self.typed - .iter() - .map(|(key, rlp)| (key.into_hash().expect("key is always H256"), rlp)) - } pub fn as_hashed_partial_trie(&self) -> &mpt_trie::partial_trie::HashedPartialTrie { self.typed.as_hashed_partial_trie() } - pub fn root(&self) -> H256 { - self.typed.root() - } } impl StateTrie for StateMpt { @@ -310,6 +355,14 @@ impl StateTrie for StateMpt { }; Ok(()) } + fn iter(&self) -> impl Iterator + '_ { + self.typed + .iter() + .map(|(key, rlp)| (key.into_hash().expect("key is always H256"), rlp)) + } + fn root(&self) -> H256 { + self.typed.root() + } } impl From for HashedPartialTrie { @@ -326,19 +379,6 @@ pub struct StateSmt { deferred: BTreeMap, } -pub trait StateTrie { - fn insert_by_address( - &mut self, - address: Address, - account: AccountRlp, - ) -> anyhow::Result>; - fn insert_hash_by_key(&mut self, key: TrieKey, hash: H256) -> anyhow::Result<()>; - fn get_by_address(&self, address: Address) -> Option; - fn reporting_remove(&mut self, address: Address) -> anyhow::Result>; - fn contains_address(&self, address: Address) -> bool; - fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; -} - impl StateTrie for StateSmt { fn insert_by_address( &mut self, @@ -365,6 +405,14 @@ impl StateTrie for StateSmt { let _ = address; Ok(()) } + fn iter(&self) -> impl Iterator + '_ { + self.address2state + .iter() + .map(|(addr, acct)| (keccak_hash::keccak(addr), *acct)) + } + fn root(&self) -> H256 { + todo!() + } } /// Global, per-account. @@ -395,8 +443,29 @@ impl StorageTrie { pub fn as_hashed_partial_trie(&self) -> &HashedPartialTrie { &self.untyped } - + pub fn reporting_remove(&mut self, key: TrieKey) -> anyhow::Result> { + Ok( + crate::decoding::delete_node_and_report_remaining_key_if_branch_collapsed( + &mut self.untyped, + &key, + )?, + ) + } pub fn as_mut_hashed_partial_trie_unchecked(&mut self) -> &mut HashedPartialTrie { &mut self.untyped } + /// Defer (hash) the parts of the trie that aren't in `paths`. + pub fn trim_to(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { + self.untyped = mpt_trie::trie_subsets::create_trie_subset( + &self.untyped, + paths.into_iter().map(TrieKey::into_nibbles), + )?; + Ok(()) + } +} + +impl From for HashedPartialTrie { + fn from(value: StorageTrie) -> Self { + value.untyped + } } From 3fdd2bc9085466c0cc535045b05100e3de1dcc01 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 14:16:41 +0100 Subject: [PATCH 03/56] refactor: switcheroo --- trace_decoder/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index d8de6447c..ac0869271 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -282,8 +282,8 @@ pub struct BlockLevelData { pub withdrawals: Vec<(Address, U256)>, } -pub use entrypoint_old as entrypoint; -pub use imp::entrypoint as entrypoint_new; +// pub use entrypoint_old as entrypoint; +pub use imp::entrypoint; mod imp; From 844971f5114db516298b94e8c989d31a3d03c973 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 14:34:27 +0100 Subject: [PATCH 04/56] fix: batch --- trace_decoder/src/imp.rs | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index d5b370ea0..def975931 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -1,4 +1,5 @@ use std::{ + cmp, collections::{BTreeMap, BTreeSet}, mem, ops::Range, @@ -63,13 +64,7 @@ pub fn entrypoint( let batches = middle( state, storage, - txn_info - .into_iter() - .pad_using(2, |_ix| TxnInfo::default()) - .chunks(batch_size) - .into_iter() - .map(FromIterator::from_iter) - .collect(), + batch(txn_info, batch_size), &mut code, b_meta.block_timestamp, b_meta.parent_beacon_block_root, @@ -188,6 +183,33 @@ fn start( }) } +/// Break `txns` into batches of length `hint`, prioritising creating at least +/// two batches. +fn batch(mut txns: Vec, hint: usize) -> Vec> { + let hint = cmp::min(hint, 1); + let n_batches = txns.iter().chunks(hint).into_iter().count(); + match (txns.len(), n_batches) { + // enough + (_, 2..) => txns + .into_iter() + .chunks(hint) + .into_iter() + .map(FromIterator::from_iter) + .collect(), + // not enough batches at `hint`, but enough real transactions + (2.., ..2) => { + let second = txns.split_off(txns.len() / 2); + vec![txns, second] + } + // add padding + (0 | 1, _) => txns + .into_iter() + .pad_using(2, |_ix| TxnInfo::default()) + .map(|it| vec![it]) + .collect(), + } +} + #[derive(Debug)] struct Batch { pub first_txn_ix: usize, From 0407031bfca63c182f3cfd6844d4e767703811ee Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 17:38:39 +0100 Subject: [PATCH 05/56] refactor: trace_decoder tests do not expect json array in files --- trace_decoder/tests/trace_decoder_tests.rs | 76 ++++++++++------------ 1 file changed, 35 insertions(+), 41 deletions(-) diff --git a/trace_decoder/tests/trace_decoder_tests.rs b/trace_decoder/tests/trace_decoder_tests.rs index 6db98749f..f77e7a901 100644 --- a/trace_decoder/tests/trace_decoder_tests.rs +++ b/trace_decoder/tests/trace_decoder_tests.rs @@ -53,7 +53,7 @@ fn find_witness_data_files(dir: &str) -> anyhow::Result> { .context(format!("Failed to find witness files in dir {dir}")) } -fn read_witness_file(file_path: &Path) -> anyhow::Result> { +fn read_witness_file(file_path: &Path) -> anyhow::Result { let witness = fs::File::open(file_path).context("Unable to read file")?; let mut reader = std::io::BufReader::new(witness); let jd = &mut serde_json::Deserializer::from_reader(&mut reader); @@ -183,38 +183,35 @@ fn test_parsing_decoding_proving(#[case] test_witness_directory: &str) { read_witness_file(&file_path) } }) - .map_ok(|block_prover_inputs| { - block_prover_inputs.into_iter().map(|block_prover_input| { - // Run trace decoder, create list of generation inputs - let block_generation_inputs = - decode_generation_inputs(block_prover_input, use_burn_addr)?; - block_generation_inputs - .into_par_iter() - .map(|generation_inputs| { - // For every generation input, simulate execution. - // Execution will be simulated in parallel. - // If system runs out of memory, limit the rayon - // with setting env variable RAYON_NUM_THREADS=. - let timing = TimingTree::new( - &format!( - "simulate zkEVM CPU for block {}, txns {:?}..{:?}.", - generation_inputs.block_metadata.block_number, - generation_inputs.txn_number_before, - generation_inputs.txn_number_before - + generation_inputs.signed_txns.len() - ), - log::Level::Info, - ); - simulate_execution_all_segments::(generation_inputs, 19)?; - timing.filter(Duration::from_millis(100)).print(); - Ok::<(), anyhow::Error>(()) - }) - .collect::, anyhow::Error>>() - }) + .map_ok(|block_prover_input| { + // Run trace decoder, create list of generation inputs + let block_generation_inputs = + decode_generation_inputs(block_prover_input, use_burn_addr)?; + block_generation_inputs + .into_par_iter() + .map(|generation_inputs| { + // For every generation input, simulate execution. + // Execution will be simulated in parallel. + // If system runs out of memory, limit the rayon + // with setting env variable RAYON_NUM_THREADS=. + let timing = TimingTree::new( + &format!( + "simulate zkEVM CPU for block {}, txns {:?}..{:?}.", + generation_inputs.block_metadata.block_number, + generation_inputs.txn_number_before, + generation_inputs.txn_number_before + + generation_inputs.signed_txns.len() + ), + log::Level::Info, + ); + simulate_execution_all_segments::(generation_inputs, 19)?; + timing.filter(Duration::from_millis(100)).print(); + Ok::<(), anyhow::Error>(()) + }) + .collect::, anyhow::Error>>() }) .flatten_ok() - .map(|it| it?) - .collect::>>(); + .collect::>>(); results.iter().for_each(|it| { if let Err(e) = it { @@ -249,19 +246,16 @@ fn test_generation_inputs_consistency(#[case] test_witness_directory: &str) { header_file_path.display() ))?; let mut header_reader = std::io::BufReader::new(header_file); - let block_headers = serde_json::from_reader::<_, Vec
>(&mut header_reader) - .context(format!( - "Failed to deserialize header json file {}", - header_file_path.display() - ))?; + let hdr = + serde_json::from_reader::<_, Header>(&mut header_reader).context(format!( + "Failed to deserialize header json file {}", + header_file_path.display() + ))?; // Read one json witness file and get list of BlockProverInputs - let block_prover_inputs = read_witness_file(&file_path)?; - Ok(block_headers - .into_iter() - .zip(block_prover_inputs.into_iter())) + let bpi = read_witness_file(&file_path)?; + Ok((hdr, bpi)) } }) - .flatten_ok() .map_ok(|(block_header, block_prover_input)| { let other_block_data = block_prover_input.other_data.clone(); // Run trace decoder, create generation inputs for this block From 408273a5fff2552b2eeac022c1a964a7214c3d98 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 17:41:12 +0100 Subject: [PATCH 06/56] chore: trace_decoder test inputs are no longer arrays --- .../tests/data/witnesses/zero_jerigon/b19807080_main.json | 3 +-- .../data/witnesses/zero_jerigon/b19807080_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b19840104_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b19840104_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b20240052_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b20240052_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b20240058_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b20240058_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b20472570_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b20472570_main_header.json | 3 +-- trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json | 3 +-- .../tests/data/witnesses/zero_jerigon/b28_dev_header.json | 3 +-- trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json | 4 ++-- .../tests/data/witnesses/zero_jerigon/b4_dev_header.json | 2 +- 14 files changed, 19 insertions(+), 23 deletions(-) diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json index 3a09e82d0..ec0f90155 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json @@ -1,4 +1,4 @@ -[ + { "block_trace": { "trie_pre_images": { @@ -1013,4 +1013,3 @@ "checkpoint_state_trie_root": "0xbbd66174555d27c88e285ff4797de401470d8d2486d15513ab36e491e864bca2" } } -] \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json index 74d58e786..288889c82 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json @@ -1 +1 @@ -[{"number":"0x12e3b68","hash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","transactions":[{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x485c7c9ae78a17af338eef77267accbf73d3a24be86cceff8ab041ce10388b20","yParity":"0x1","accessList":[],"transactionIndex":"0x0","type":"0x2","nonce":"0x8e","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000071f755898886f79efa73334450f05a824faeae0200000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0x3efde0059a9e20313ee5a466273604b3e79d199a60b2c44e753f5f2fe56eb987","s":"0x40eca86c1d87c685a3024af4a0224dab92758dc1990b8f8ecb6040f88498ab1e","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0x71f755898886f79efa73334450f05a824faeae02","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b832f7b98df73773fee549f702b87332ab605baeab66a725582089dfb8c8716","yParity":"0x1","accessList":[],"transactionIndex":"0x1","type":"0x2","nonce":"0x6a","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000a890e6b83ac95c7de4ffd4549d4cd282b407b49500000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xa884ab9e5c1057e2e741e5ad4c6335f655a0dd248b3a6b7d7d0eb450ac2cff8e","s":"0x7befa7f3480ddc589444e0d4498e0fd68fa765747676bafd9a128c6dcd91d5a1","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0xa890e6b83ac95c7de4ffd4549d4cd282b407b495","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xd119b49569af4d5882efa6c72c84158bc1a9b8ac8f632706ce810f627ab13fb3","yParity":"0x1","accessList":[],"transactionIndex":"0x2","type":"0x2","nonce":"0xa18","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000dee90fc88ef3aceace9a22d2b2921906b724455200000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xd244c53d24ffc3b2fcdfaf692d82593c0bb8cf3369b2a94c91c2c0249c4510a7","s":"0x751ca6879dce7d240443728d6e5756fa78be470b7ebd94cf984a1cb94f9f2c30","chainId":"0x1","v":"0x1","gas":"0x35b60","maxPriorityFeePerGas":"0xb4ad34500","from":"0xdee90fc88ef3aceace9a22d2b2921906b7244552","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x1cd918d39380020","gasPrice":"0xc6ded450f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xc02ea02af1da253b9cf3d1de648c3355211f490cf4b8641b3146e69450870ba6","yParity":"0x0","accessList":[],"transactionIndex":"0x3","type":"0x2","nonce":"0x28b","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000fe6cf59162f319fb2c536f63a6121eb88dc85a3400000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xb66d674b17cb04d44900455636b496131fdae9b8e4c81f790854bda351130e83","s":"0xdb241292520a7c135d381b0fd18788c9490aff4b756d397453a6454da4e0a3c","chainId":"0x1","v":"0x0","gas":"0x35b60","maxPriorityFeePerGas":"0xaa9e48a00","from":"0xfe6cf59162f319fb2c536f63a6121eb88dc85a34","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x102a336dba60000","gasPrice":"0xbccfe8a0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b66220ea1cfac82ed5639293cbb0b5acaa956a348999648aacfc202f5a6451b","yParity":"0x0","accessList":[],"transactionIndex":"0x4","type":"0x2","nonce":"0xba3","input":"0x3d0e3ec50000000000000000000000000000000000000000000000000001d57eaddeea78000000000000000000000000000000000000000000000000023bb9178b0192be00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000c58e4d309c4f5c88afe355c260ee9a1a699ed1dd00000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000008b683c400457ef31f3c27c90acb6ab69304d1b77000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","r":"0xdd70145d23e041328d8242858ca9815cbb03bf408dd7d81e30532932497838fc","s":"0x496bf86926d61a533fa5824c9d21271b8b1597b48014282168a48575f8cf417c","chainId":"0x1","v":"0x0","gas":"0x4dc2f","maxPriorityFeePerGas":"0xb2d05e00","from":"0xc58e4d309c4f5c88afe355c260ee9a1a699ed1dd","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x0","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xa16262586a442817e5766675bd6ec767ebe3815e7ae325248acdcf54de4561aa","yParity":"0x1","accessList":[],"transactionIndex":"0x5","type":"0x2","nonce":"0x162c","input":"0x088890dc000000000000000000000000000000000000000000000000007af53217af31b800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008693ca3483daf299aad023eae75221436d6c11a000000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f1001ad1ee7743e0f6715f50cdaeb1397d5cb4fa","r":"0x2c9a9ab0d7eb2503a5ebbfe1a66c2f08a9170e1da5b14cdb142fce831522a43a","s":"0x360ecd3be1f224118862ddb78787cf31ad7600994b6c7a4a947ae3a071619a8b","chainId":"0x1","v":"0x1","gas":"0x461c6","maxPriorityFeePerGas":"0xb2d05e00","from":"0x8693ca3483daf299aad023eae75221436d6c11a0","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x2c68af0bb140000","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x1d0969550eee06cc9bd992ccceaab28c5762feec4d69cdca3dbc50927263bed9","transactionIndex":"0x6","type":"0x0","nonce":"0x0","input":"0x","r":"0x6b6a8c636721916ee32404201135745eeb2bfad873e662f5a59c331cb6647a95","s":"0x452ae97ab3fb5bd8e4cc7890b28876a662430c40bf643239303e0c86770c96bf","chainId":"0x1","v":"0x26","gas":"0x5208","from":"0x17032783b5f29c8a68e0fafba4db021f248409e4","to":"0xb27b03580c193d324931acb143f6a1f3477e702e","value":"0x1ff118a94dfd000","gasPrice":"0x1a13b8600"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x923e060de69675c90d67472ca7a33e61630f64b92e20224db08055c5cd4eaaf3","yParity":"0x1","accessList":[],"transactionIndex":"0x7","type":"0x2","nonce":"0xbcb0","input":"0xa000000000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f56400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000099f388994000000000000000000000000000000000000000000000000b6ea0676d933c915000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","r":"0x269fa6d550e1ce6f76884a87645bd2a462c303dca06423f2f0638a572109f0f7","s":"0x776dab3e59d703ff24cc45be1b856a73f66facbd0c5d6c41ecc940ca7e02416f","chainId":"0x1","v":"0x1","gas":"0x61a80","maxPriorityFeePerGas":"0x34fd4acd","from":"0x93793bd1f3e35a0efd098c30e486a860a0ef7551","to":"0x9def7cde171841a9f0724124ca0b01a622d749e4","maxFeePerGas":"0x158174adc","value":"0x12e3b68","gasPrice":"0x158174adc"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x71845c70b3ee8a2894f8e5bb833639d1a6a80286eaf2d5b732ecbe8e30ec1346","yParity":"0x1","accessList":[],"transactionIndex":"0x8","type":"0x2","nonce":"0xe5ad7","input":"0x","r":"0xe0c1666544ae41c9fecaba65277c51af8755838a43c6e5bdc15c83970af18461","s":"0x405b701cfa1a3b22fc547c21955d55210f7fdd87b576466a2cf30cb27e9fb442","chainId":"0x1","v":"0x1","gas":"0x6ac1","maxPriorityFeePerGas":"0x0","from":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","to":"0x617c8de5bde54ffbb8d92716cc947858ca38f582","maxFeePerGas":"0x1231a000f","value":"0x6ca54625d8e66f","gasPrice":"0x1231a000f"}],"logsBloom":"0x002000000100000000000000801000044000000000080000800100000401010008008000000000080000084000080000020000000800a0005000000000a0000000000000000000080a000008000000200000100100400000000000008000040000001020020000000000400008000001000000000000041100000010000880000000000000080000004000000000048140000001010008090800004000400000020500000000200000000048000008000000000001000000002008000088000020000002000000000000200000000a00000000000000401000000042000020000050200000000810800010800000000000000000800000400008000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x322e0b5db82824020e3247d491fe8e36688d881392cd63af55f958df0aa95725","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x611a5e88d0ffbe176e4f6409bf229792668d5c96d6e47b519a3d5653fc723973","baseFeePerGas":"0x1231a000f","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11a0834","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96b","validatorIndex":"0x4626c"},{"amount":"0x11a27fc","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96c","validatorIndex":"0x4626d"},{"amount":"0x11b88e3","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96d","validatorIndex":"0x4626e"},{"amount":"0x11be16e","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96e","validatorIndex":"0x4626f"},{"amount":"0x11a1416","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96f","validatorIndex":"0x46270"},{"amount":"0x11a2dc0","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c970","validatorIndex":"0x46271"},{"amount":"0x11a42a8","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c971","validatorIndex":"0x46272"},{"amount":"0x119940e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c972","validatorIndex":"0x46273"},{"amount":"0x1199000","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c973","validatorIndex":"0x46274"},{"amount":"0x11a046e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c974","validatorIndex":"0x46275"},{"amount":"0x119d364","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c975","validatorIndex":"0x46276"},{"amount":"0x3bc7b17","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c976","validatorIndex":"0x46277"},{"amount":"0x1192ee6","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c977","validatorIndex":"0x46278"},{"amount":"0x119bcc9","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c978","validatorIndex":"0x46279"},{"amount":"0x118f663","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c979","validatorIndex":"0x4627a"},{"amount":"0x119b5ce","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c97a","validatorIndex":"0x4627b"}],"excessBlobGas":"0x0","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x121cc2","uncles":[],"parentBeaconBlockRoot":"0xb2fdced42678407cdb560649f70178a2a0e4095543930548bf164b7b936eff36","size":"0xf8b","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x0aaa0d653c3a6ac90de9ad896e60eef01d41c95863411c6b24bd31e59e32fea4","stateRoot":"0xc258b8b986b5003f4a051c625c427e7d93fbdf653669468727bbcc25b1fd1919","mixHash":"0x253d73a8035e2de53f82869fbdd8a700c96604da0485d0a02b05eebc53f615e3","parentHash":"0x27c8003b8d5ed3a0dfb4313cf8e969478176df308cb8ff7590f86323469046e2","blobGasUsed":"0x0","timestamp":"0x663811c7"}] +{"number":"0x12e3b68","hash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","transactions":[{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x485c7c9ae78a17af338eef77267accbf73d3a24be86cceff8ab041ce10388b20","yParity":"0x1","accessList":[],"transactionIndex":"0x0","type":"0x2","nonce":"0x8e","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000071f755898886f79efa73334450f05a824faeae0200000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0x3efde0059a9e20313ee5a466273604b3e79d199a60b2c44e753f5f2fe56eb987","s":"0x40eca86c1d87c685a3024af4a0224dab92758dc1990b8f8ecb6040f88498ab1e","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0x71f755898886f79efa73334450f05a824faeae02","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b832f7b98df73773fee549f702b87332ab605baeab66a725582089dfb8c8716","yParity":"0x1","accessList":[],"transactionIndex":"0x1","type":"0x2","nonce":"0x6a","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000a890e6b83ac95c7de4ffd4549d4cd282b407b49500000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xa884ab9e5c1057e2e741e5ad4c6335f655a0dd248b3a6b7d7d0eb450ac2cff8e","s":"0x7befa7f3480ddc589444e0d4498e0fd68fa765747676bafd9a128c6dcd91d5a1","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0xa890e6b83ac95c7de4ffd4549d4cd282b407b495","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xd119b49569af4d5882efa6c72c84158bc1a9b8ac8f632706ce810f627ab13fb3","yParity":"0x1","accessList":[],"transactionIndex":"0x2","type":"0x2","nonce":"0xa18","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000dee90fc88ef3aceace9a22d2b2921906b724455200000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xd244c53d24ffc3b2fcdfaf692d82593c0bb8cf3369b2a94c91c2c0249c4510a7","s":"0x751ca6879dce7d240443728d6e5756fa78be470b7ebd94cf984a1cb94f9f2c30","chainId":"0x1","v":"0x1","gas":"0x35b60","maxPriorityFeePerGas":"0xb4ad34500","from":"0xdee90fc88ef3aceace9a22d2b2921906b7244552","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x1cd918d39380020","gasPrice":"0xc6ded450f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xc02ea02af1da253b9cf3d1de648c3355211f490cf4b8641b3146e69450870ba6","yParity":"0x0","accessList":[],"transactionIndex":"0x3","type":"0x2","nonce":"0x28b","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000fe6cf59162f319fb2c536f63a6121eb88dc85a3400000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xb66d674b17cb04d44900455636b496131fdae9b8e4c81f790854bda351130e83","s":"0xdb241292520a7c135d381b0fd18788c9490aff4b756d397453a6454da4e0a3c","chainId":"0x1","v":"0x0","gas":"0x35b60","maxPriorityFeePerGas":"0xaa9e48a00","from":"0xfe6cf59162f319fb2c536f63a6121eb88dc85a34","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x102a336dba60000","gasPrice":"0xbccfe8a0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b66220ea1cfac82ed5639293cbb0b5acaa956a348999648aacfc202f5a6451b","yParity":"0x0","accessList":[],"transactionIndex":"0x4","type":"0x2","nonce":"0xba3","input":"0x3d0e3ec50000000000000000000000000000000000000000000000000001d57eaddeea78000000000000000000000000000000000000000000000000023bb9178b0192be00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000c58e4d309c4f5c88afe355c260ee9a1a699ed1dd00000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000008b683c400457ef31f3c27c90acb6ab69304d1b77000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","r":"0xdd70145d23e041328d8242858ca9815cbb03bf408dd7d81e30532932497838fc","s":"0x496bf86926d61a533fa5824c9d21271b8b1597b48014282168a48575f8cf417c","chainId":"0x1","v":"0x0","gas":"0x4dc2f","maxPriorityFeePerGas":"0xb2d05e00","from":"0xc58e4d309c4f5c88afe355c260ee9a1a699ed1dd","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x0","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xa16262586a442817e5766675bd6ec767ebe3815e7ae325248acdcf54de4561aa","yParity":"0x1","accessList":[],"transactionIndex":"0x5","type":"0x2","nonce":"0x162c","input":"0x088890dc000000000000000000000000000000000000000000000000007af53217af31b800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008693ca3483daf299aad023eae75221436d6c11a000000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f1001ad1ee7743e0f6715f50cdaeb1397d5cb4fa","r":"0x2c9a9ab0d7eb2503a5ebbfe1a66c2f08a9170e1da5b14cdb142fce831522a43a","s":"0x360ecd3be1f224118862ddb78787cf31ad7600994b6c7a4a947ae3a071619a8b","chainId":"0x1","v":"0x1","gas":"0x461c6","maxPriorityFeePerGas":"0xb2d05e00","from":"0x8693ca3483daf299aad023eae75221436d6c11a0","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x2c68af0bb140000","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x1d0969550eee06cc9bd992ccceaab28c5762feec4d69cdca3dbc50927263bed9","transactionIndex":"0x6","type":"0x0","nonce":"0x0","input":"0x","r":"0x6b6a8c636721916ee32404201135745eeb2bfad873e662f5a59c331cb6647a95","s":"0x452ae97ab3fb5bd8e4cc7890b28876a662430c40bf643239303e0c86770c96bf","chainId":"0x1","v":"0x26","gas":"0x5208","from":"0x17032783b5f29c8a68e0fafba4db021f248409e4","to":"0xb27b03580c193d324931acb143f6a1f3477e702e","value":"0x1ff118a94dfd000","gasPrice":"0x1a13b8600"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x923e060de69675c90d67472ca7a33e61630f64b92e20224db08055c5cd4eaaf3","yParity":"0x1","accessList":[],"transactionIndex":"0x7","type":"0x2","nonce":"0xbcb0","input":"0xa000000000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f56400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000099f388994000000000000000000000000000000000000000000000000b6ea0676d933c915000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","r":"0x269fa6d550e1ce6f76884a87645bd2a462c303dca06423f2f0638a572109f0f7","s":"0x776dab3e59d703ff24cc45be1b856a73f66facbd0c5d6c41ecc940ca7e02416f","chainId":"0x1","v":"0x1","gas":"0x61a80","maxPriorityFeePerGas":"0x34fd4acd","from":"0x93793bd1f3e35a0efd098c30e486a860a0ef7551","to":"0x9def7cde171841a9f0724124ca0b01a622d749e4","maxFeePerGas":"0x158174adc","value":"0x12e3b68","gasPrice":"0x158174adc"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x71845c70b3ee8a2894f8e5bb833639d1a6a80286eaf2d5b732ecbe8e30ec1346","yParity":"0x1","accessList":[],"transactionIndex":"0x8","type":"0x2","nonce":"0xe5ad7","input":"0x","r":"0xe0c1666544ae41c9fecaba65277c51af8755838a43c6e5bdc15c83970af18461","s":"0x405b701cfa1a3b22fc547c21955d55210f7fdd87b576466a2cf30cb27e9fb442","chainId":"0x1","v":"0x1","gas":"0x6ac1","maxPriorityFeePerGas":"0x0","from":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","to":"0x617c8de5bde54ffbb8d92716cc947858ca38f582","maxFeePerGas":"0x1231a000f","value":"0x6ca54625d8e66f","gasPrice":"0x1231a000f"}],"logsBloom":"0x002000000100000000000000801000044000000000080000800100000401010008008000000000080000084000080000020000000800a0005000000000a0000000000000000000080a000008000000200000100100400000000000008000040000001020020000000000400008000001000000000000041100000010000880000000000000080000004000000000048140000001010008090800004000400000020500000000200000000048000008000000000001000000002008000088000020000002000000000000200000000a00000000000000401000000042000020000050200000000810800010800000000000000000800000400008000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x322e0b5db82824020e3247d491fe8e36688d881392cd63af55f958df0aa95725","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x611a5e88d0ffbe176e4f6409bf229792668d5c96d6e47b519a3d5653fc723973","baseFeePerGas":"0x1231a000f","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11a0834","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96b","validatorIndex":"0x4626c"},{"amount":"0x11a27fc","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96c","validatorIndex":"0x4626d"},{"amount":"0x11b88e3","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96d","validatorIndex":"0x4626e"},{"amount":"0x11be16e","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96e","validatorIndex":"0x4626f"},{"amount":"0x11a1416","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96f","validatorIndex":"0x46270"},{"amount":"0x11a2dc0","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c970","validatorIndex":"0x46271"},{"amount":"0x11a42a8","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c971","validatorIndex":"0x46272"},{"amount":"0x119940e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c972","validatorIndex":"0x46273"},{"amount":"0x1199000","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c973","validatorIndex":"0x46274"},{"amount":"0x11a046e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c974","validatorIndex":"0x46275"},{"amount":"0x119d364","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c975","validatorIndex":"0x46276"},{"amount":"0x3bc7b17","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c976","validatorIndex":"0x46277"},{"amount":"0x1192ee6","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c977","validatorIndex":"0x46278"},{"amount":"0x119bcc9","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c978","validatorIndex":"0x46279"},{"amount":"0x118f663","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c979","validatorIndex":"0x4627a"},{"amount":"0x119b5ce","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c97a","validatorIndex":"0x4627b"}],"excessBlobGas":"0x0","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x121cc2","uncles":[],"parentBeaconBlockRoot":"0xb2fdced42678407cdb560649f70178a2a0e4095543930548bf164b7b936eff36","size":"0xf8b","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x0aaa0d653c3a6ac90de9ad896e60eef01d41c95863411c6b24bd31e59e32fea4","stateRoot":"0xc258b8b986b5003f4a051c625c427e7d93fbdf653669468727bbcc25b1fd1919","mixHash":"0x253d73a8035e2de53f82869fbdd8a700c96604da0485d0a02b05eebc53f615e3","parentHash":"0x27c8003b8d5ed3a0dfb4313cf8e969478176df308cb8ff7590f86323469046e2","blobGasUsed":"0x0","timestamp":"0x663811c7"} \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json index 6537bc456..d5d698878 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json @@ -1,4 +1,4 @@ -[{ +{ "block_trace": { "trie_pre_images": { "combined": { @@ -363,4 +363,4 @@ }, "checkpoint_state_trie_root": "0x319da7faf76836d1ca1c48e0540a97c0d7f2515b7fd7be7dfb1aef9ed5dd588a" } -}] \ No newline at end of file +} \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json index b2fc74151..59e76e72c 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json @@ -1 +1 @@ -[{"number":"0x12ebc68","hash":"0x3c869591ac4295afc75154eaaf7a8b59a41af3cdcbad9d8c48fb7ef9853f9ec6","transactions":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","extraData":"0xd883010e00846765746888676f312e32322e32856c696e7578","withdrawalsRoot":"0xe4d8d88a7e20aae7598822ee098c466e93c501377e1d302013f9f017944f8733","baseFeePerGas":"0x1aafac7f2","nonce":"0x0000000000000000","miner":"0x0000000000000000000000000000000000000000","withdrawals":[{"amount":"0x119204e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96b","validatorIndex":"0xfa8ea"},{"amount":"0x1193fa3","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96c","validatorIndex":"0xfa8eb"},{"amount":"0x118a669","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96d","validatorIndex":"0xfa8ec"},{"amount":"0x118d295","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96e","validatorIndex":"0xfa8ed"},{"amount":"0x1195db7","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96f","validatorIndex":"0xfa8ee"},{"amount":"0x3c46d9e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd970","validatorIndex":"0xfa8ef"},{"amount":"0x118b8bb","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd971","validatorIndex":"0xfa8f0"},{"amount":"0x11994d6","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd972","validatorIndex":"0xfa8f1"},{"amount":"0x11822b1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd973","validatorIndex":"0xfa8f2"},{"amount":"0x118b828","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd974","validatorIndex":"0xfa8f3"},{"amount":"0x118b7e1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd975","validatorIndex":"0xfa8f4"},{"amount":"0x117492d","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd976","validatorIndex":"0xfa8f5"},{"amount":"0x3c1adb5","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd977","validatorIndex":"0xfa8f6"},{"amount":"0x11713d0","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd978","validatorIndex":"0xfa8f7"},{"amount":"0x1197bef","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd979","validatorIndex":"0xfa8f8"},{"amount":"0x1181b16","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd97a","validatorIndex":"0xfa8f9"}],"excessBlobGas":"0x60000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x0","uncles":[],"parentBeaconBlockRoot":"0x5ab8b5a8f53fb6e010ee24d46334a9ce1051a5ba1691b6383ce8b2a03c10f158","size":"0x4aa","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","stateRoot":"0x101798b8e9f085f2faba1e2749df2916029c6c507f4f388c816ee6f9977a0a98","mixHash":"0x2e5e4c5b459345002e2597c5b8b556f0fb51fd9c6c45f7892eb98cb4de973795","parentHash":"0x290e2c3125591d2f128758525955799fe08eb933dc0e22519810e63a10f0ea69","blobGasUsed":"0x0","timestamp":"0x663e28fb"}] +{"number":"0x12ebc68","hash":"0x3c869591ac4295afc75154eaaf7a8b59a41af3cdcbad9d8c48fb7ef9853f9ec6","transactions":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","extraData":"0xd883010e00846765746888676f312e32322e32856c696e7578","withdrawalsRoot":"0xe4d8d88a7e20aae7598822ee098c466e93c501377e1d302013f9f017944f8733","baseFeePerGas":"0x1aafac7f2","nonce":"0x0000000000000000","miner":"0x0000000000000000000000000000000000000000","withdrawals":[{"amount":"0x119204e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96b","validatorIndex":"0xfa8ea"},{"amount":"0x1193fa3","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96c","validatorIndex":"0xfa8eb"},{"amount":"0x118a669","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96d","validatorIndex":"0xfa8ec"},{"amount":"0x118d295","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96e","validatorIndex":"0xfa8ed"},{"amount":"0x1195db7","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96f","validatorIndex":"0xfa8ee"},{"amount":"0x3c46d9e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd970","validatorIndex":"0xfa8ef"},{"amount":"0x118b8bb","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd971","validatorIndex":"0xfa8f0"},{"amount":"0x11994d6","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd972","validatorIndex":"0xfa8f1"},{"amount":"0x11822b1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd973","validatorIndex":"0xfa8f2"},{"amount":"0x118b828","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd974","validatorIndex":"0xfa8f3"},{"amount":"0x118b7e1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd975","validatorIndex":"0xfa8f4"},{"amount":"0x117492d","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd976","validatorIndex":"0xfa8f5"},{"amount":"0x3c1adb5","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd977","validatorIndex":"0xfa8f6"},{"amount":"0x11713d0","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd978","validatorIndex":"0xfa8f7"},{"amount":"0x1197bef","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd979","validatorIndex":"0xfa8f8"},{"amount":"0x1181b16","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd97a","validatorIndex":"0xfa8f9"}],"excessBlobGas":"0x60000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x0","uncles":[],"parentBeaconBlockRoot":"0x5ab8b5a8f53fb6e010ee24d46334a9ce1051a5ba1691b6383ce8b2a03c10f158","size":"0x4aa","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","stateRoot":"0x101798b8e9f085f2faba1e2749df2916029c6c507f4f388c816ee6f9977a0a98","mixHash":"0x2e5e4c5b459345002e2597c5b8b556f0fb51fd9c6c45f7892eb98cb4de973795","parentHash":"0x290e2c3125591d2f128758525955799fe08eb933dc0e22519810e63a10f0ea69","blobGasUsed":"0x0","timestamp":"0x663e28fb"} diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json index 247fd5df0..6889f1cce 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json @@ -1,4 +1,4 @@ -[ + { "block_trace": { "trie_pre_images": { @@ -9195,4 +9195,4 @@ "checkpoint_state_trie_root": "0xaeaab1c6af58526a7a36de5210273f9c7ce2dc936293520b2ecb19b1d786976a" } } -] + diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json index 9e6b54658..bd989382c 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json @@ -1 +1 @@ -[{"number":"0x134d6b4","hash":"0x500c31e728a280af1add4799095e7229d4a4cdfc6c9c73a62434703ffe34045c","transactions":["0x66324d0360eea71d5a5e6d0bc0dbbdf35cbfbc3a3f121d028ad34c11426efdd2","0xe305bf3385425fe0387d926334de3f03150b31233df76fedaef472d635560e78","0xe410fb642fc29d34a9ec92a1ed3cb48748e2ac8fa7cd9c8315fb29656a8fec1a","0x247fa2b38f1fbf6758609e6d5cdc0f9dc899f37735496ecb95bf734eafd360ea","0x9d10a0dd7850ff99c98ec13b3e65905d1242875784b2d5420be80ac2e3f45c4b","0x53d7fddb6491e17eb15ef6d1e8ff3027735905bfcdfa66b3dae56f973fc2576e","0x40c52b14161c3bb6ea8914fc8a7e55852e0a51d36be4a43835015eb9cc330063","0x5df2a9b9eb1d800c76a1c6c90019e0b6dedf71e85764ed80d9cbba1e8e75cc4b","0x0ee9f351711baf9f66d36fda5c4e436b45c4942936d088ac826dddf781f2bdd9","0x74109ee77c85494337ca6db2975e00c9aded34403b64c9189fe22e7bae3bc4e1","0x9c53f84c1993f87c5ddeaea655780c24c9e265644ff89c839564802de661e4d6","0xcd13d2d4292e2a03c099f60e5db2de058459262c5dbe70ac792f533e47e15b09","0x03b719dad83d99a2eb847751faf36d4663a43d936f1c66948b139c6fc82209dc","0x2f417d2c35961dbd7cb522fa0ee06c95aab12b3d6a707ca8f74f97953fa34227","0xc26f561629de18df96ae9c1271912a90e7d67a9b85d99f603b63e87bdfb68e93","0xa4c4e1851441c900b82d8b90808f59535599884ef3363a5f46c05ef309f12c68","0xd3fad4b38903dfc6ff22954674dcccaa232146c3c6b60687dd1fb6bb61b95c46","0xc2f6717a22fd5b1efc93f59751e2467ea872777782e9201160d4af85aa16f91c","0x4baed9c20161fb6ef4315a198386a4c894f146fc278555e3f87c7f6e18d76c06","0xb91012cc7b849eb66779a8706453556467547c41b93394c36503141b4213a508","0xa33cb80d6bd6e5994c35c49250a00c69d49714e9ef343ca18901a4962e95cc5a","0x1fba689d944205912a77de9fcc53f4ea553e58240f09439d9b6b984495ae16b5","0xeaf101fa2a459f6b9812bba88b42dde5357befda42a35b1f5b5651cbd514e9db","0xce1e34de415dc7ba30c2a4d655c3f3e650275c323518ff2a61015d65cdd5a0ec","0x3d87d050821056a3ed8c1a3ada5bdc1dafd6483459f09054f5ec5112c3e2e833","0x60a7e890a6db8b50d93992c461dc16b49f57f6855fc8dfaacb1a525830657ad6","0x143336aadce774b79d069b72eed4d615df1078df98859476982ac00f35dfef3c","0x17e5787cdadfe3c01ae34f23ecab84d90a0fde083d1a5770cb1349b48ea49d45","0xbdb4b34276389846d8e7cba137033a3fabee90c084fbd65c840839fffddc0d2f","0x230eca8906bf58d6017fd8f3057a2c7e05de885b302b5c349c9d587659cc366d","0xbda38f281b0127034ca3d9b3726fe9ac68c800f34990069edfc8c6ab8cfc43ce","0xd58df4c85b7002b5762707b82d29475628319fa5ebd98dfa4e57721c78d5adfd","0xba4ce9b4cd284b96eee2f8db9db065376bbc646656fa04b2d2a623778b24c300","0xd5c2b6ce545a05378dd92582f6e3c77d1aae42cd88a174bce287073697595f8d","0x3c4295faecb8b630259b5ab875e1de2433d0f384d72bd836718d4384d1c7325e","0x46f5f9ef7efca04abc8e45fa48cddb5fc80493ae07ad943af7f10d94df6d5575","0x43244bec21354c3c918afc71ad11ceeeacadc8d9a114de8ee867cfd592dc63ec","0x95da6a534725726a0f4522ad3b5a81f79dd611290136f58506b7eb6c71b6aa6d","0x5a06e4cf4a51e7060d772d3052dd752789d9a344bcccfd3d5642774f8bf21dc5","0xe6dc810bdebe5c422bd9dfa2b444aa848300a9e7caab28cb856c95a40b68182e","0x153b92c7a60749bb79016c97d717c9a1b68e17fc237ad20763d4bfe9eb31443f","0x3c57f44269511d1ebb682f5b4de53f45bc6cb7bbd455cb18d971cc2a5414f4cd","0xfb2f82babaaecfb5190912074f1382706095f5dc04d7b8851b3de2f115a6cd96","0xb930db9657d311ee70e826e1af1595eb34ab0d9fef21599761f8eb6b57289a72","0x26de40a55c59c5d3e10bb86db6f012536cf65fe1599c589c6eeb32b27d9e7a64","0x90faddb5707b8c30beb8efe3b47d4d2b6bb2174088dd5717263e73cd36936f95","0xefa678a2771fbd1534bf85857d20f4b902d6d26e87e7a96af0e1e512c449c76a","0xede6ca6bfe169da516d0b0a17950d6b88f6d97f9a01569fbcf611504a7815f75","0x132a5b1bd116f732dbe91146efbe8f002411fa80d2113c3ad43c60811b50ba33","0x42b01e6112cd30609f68aff8c90e999fa7d07c169a8bbbababe15ee5d38be66f","0xed60c7c83d4831f55fcb573c8d7417fbe9bdd5d449d54daf67fd3d8623f1a297","0x458ebf545d76f78dea87cb03417bc2d299d669223e2b9815bada877a026df63d","0xdf1ce874ef2e43bc1413e05bf0652acae985b6d94f8a9fdd060a70a61ea8e0e1","0xf977ded6ab95ef5a028d10344c960e16838b81837fcb3f3d15128e9c66ace584","0x733cac76207545f35f1c99ee1145b403d31e24da8cde0a70eb3c25515367fc7e","0x5d53e264ba107ae92f4683bc126c5f0c38aff9a6cda1fd1c743a453b4870f4c1","0xc347abe53a5b5020420ab0da3eb05ec67c3bed42ebbe091f2f94f6d9c2fa168a","0x94e61a2fb7550c453a0c7500fa279cabf1fc661ee8c8dedbcb2479d5a8982196","0x945bc4e094a800c26361b627f67616ef4835cec4dba6e58119d68f10e6a1afcf","0x9c4116447040232cb1f5e13059e4ba12c2db501e45f78cf97f60b0db24695b31","0xaf22df09e9921d45535a0f5f80ea607a860d51681e02b9b57e8c53d74cc36310","0x28e6ee2a48b3c780affb3c124d4ce27acec3d40121f4607ecd565c70701c085c","0x95aa1652585dd525dd926368cb936fac87f81625ff6f6eeab1f2288507b61289","0xa5f466f9b62fea39daf0e0fd3c47d783de4aed4dea1d11d93ab0502f3a4489c3","0xf5be04d59b7c36b75ce6d86f02161123f2e5ad02d5f6e8cc7bacd7f2ec1fd206","0x425a10965f389cfc278c7300ac9a27e7891b178fc39991abaac7848f7089d487","0x3be1373318ad87b9957f5b7b4ae602aa19087b4177f3ba255faa19c576a63f7a","0xf250f0ffb6d574b82a1dad285b17835d68779c7cdb59d7f96794fa945fd4feda","0x13d9d1cc11e7f1af51099490be740a996eb7eb4975daa1cec851081c76805e01","0x41f03ef64f0015f1e8ea93f4381407cd12c83581eca09f10d124c12864a24f35","0x4ca92077f33bdc962bd76f59eb1327a096b9330b7e69393c16589c71c61efe1a","0x499d2f13d41a9e444e882891f3105b493112db8c188e650101916a6c00aab571","0x63afc736e099316f08c559498fde320fda3c5175605aee71dc767c41ba00a2a7","0x481ff76b4c9b60212a2cd281bbe79d048c2429e00ff4be2a86ccb87b863165c0","0xb34048c9549de5042db2c0398988724104dbc5e9470088583c2cf6c348b3dd7c","0xba9f94b5b8372d6b431b8735ab4081101aa9b7bda951d912dc722499c598a83f","0xc5a6251e55564b17bf44f7aa6d21cdd20f658d61a8a84a25c04fe4581895d5aa","0x3235c94fcdb5f9ff29cf70efa34af3ec931a3d1694beb027f0fbd5069ff4ec65","0x5f7915e8d005d97fbd262f31ae861e10a3c585a57a0f118ff0789bf045588f99","0x1d6290be9ed40cb5a458c03bb04342b4f14143bc873b3d50c3fbd671f3db7438","0x65866fc1fba54dc4e6bc0e82746757b49869e359726dcabc98cde74d8ce00c63","0x3d515de1807167f4230d8e68393f3d90cd396821bc8dc05282088caa9191e9cc","0x8c2c4d28db1e21b60f29b19a1035a6911e892a1a91609009d38e373279a56243","0x83df9f5987e06e737e6a28e40175e261dc4936e7832b746207f28c87d8373c5a","0x2d7d7fd66d324c4c14d05dd100ebfc5bc9b945b85a4de4a4520decfeb86e531b","0x0a4acb940c53253539d4b3bbcf7752aba3ccf240285f664a4cfbbd72cb192d48","0x193376115ab2d506755b01beeb7b88012559cb78efed68131ee944addff240eb","0x489e003f7d85c8365f378af589c2d83d6a622e85b6fe0ba58e6ea03c62a08e4a","0x8de8197d07d9f2b47a4316871e1836bc0c405b050cc6a5a27dd9faed74ffffb2","0x592578b40c288a1e25e65f6a056da0124db8bc97fe1fc0a904251ee5f87828b9","0xef29e4bc8e60d8fa76eda5f33f961ac1d36f9f13efb6c1c7a58402733f17a9fb","0xa116a77605deec75b2070955445c9d793b05e50f099d4d1497e34eaf87ed5646","0xa15aae1355633ed2ae9283334bf6db5cf5cd76e0134870389ae8ae744a7bb24c","0xaccc10ec12c433e98e3c27d44e5d5f18400fcbe13a8ceed4dd68dfde57c15449","0x6cfb2131e6b7e25e1ac468a503728903690dd5581fc8bad33f1eff4794229a34","0x4ed2e2e41ec55d6a5b42f1672fb89c619183ba003af4474162f5499c1f163498","0xddbf5ffc8adc9379ee0cfc8a7642c88b327c399a85ed1edb8c9b3960ebcbb9ea","0x08d7c8342bab8fdb4e79fc3b7d75616254df38af409d1d9f84657fd3ddcf69f8","0xd4001d19e4225a3a5cbbfe2934d2775105a7d7d8818b7cb98703c33012716110","0x2062cc1d24beecc20057ad331d690508c748e21d3040ffb37b38965966a3d3f0","0xe3836b1fffecb32d2aef998b4d3c0d606ca9ca2b002661a8f184cbe4d15bbf78","0xbf814b35d87c58629568108a5e1176f67453a1eeb324a510d00b927c477182b0","0x769e8a0d5da47949435d6f4d10f0c61c5dad97e492423675fa6db41580c553dd","0xc7e5d496ba456c2e79f504bae6b2ad6759bd16fe24e1322c9ab69ff971cb6040","0xfb2a55d870229c5128aabd6ac21cf4fa02ec0938f507c95267239818ddbbc2eb","0xbacc62ef0a1edd91c4803c5be166926d737bd76bcb129f4a6f57553a09ce535b","0xda567db58bdd46ea35271e1a53d29375b06054c845bba8f4cff3b0493125d12d","0xc31700594d2f23e26a90d4dc5af926b35a64dd7ccdd4049916302426a491b188","0x40e80109207cb7d621545f8f1c5436e2c3997eec7b521c5e0ab8373b05365b64","0x6d24f1451e0477cf59b0d99c18d6bd1d5aef818728886b9be3643fe7ae10701e","0x906d4b0e8f0a3a1b129138e453ead10750ae4cecf517e01b6bb99340bdeedde4","0x44d615725dd6a00816fde0b1767256e8d4a6796a6d1b2d34844d1389763bad4a","0x42182c0aea8452bf6d86618a0b5ba0237882d158eca83591fd2a7e0c4e123d9c","0x22151212da28291a917d43c2420cc5bc3fe8a0379607325cbeba0eb753eee1a9","0x90019486ad21e98d87ab8965de800d56104267dc2416d399d689ea159221bffd","0x64c1844e0cd95031ca18564892dfc038ce8338ee1168ff61b50ea34f9aa1b937","0xf1d5278d5006bb81ce58798252d790ff95503b63947c1000e7a742a8b1e320b0","0x3dcea3438fdf4b53b23d996f5714d4af758ffac6b82a03ac7d153ec850866bd7","0xb357d9022b4ddab68631c1ed393b46ce5b8048a69f98b4f8a1ea0bc86036c88d","0xfb608c5fb250b761fe4c44479ec398cedcc0f19f8196e96912bd3c02bec93557","0x3c30908976f14f75f5d48c0e61f19af6d417544f79424a737902787382dd0966","0x80be3649036b61d382618ba38055e3a6dbad22906928de3e58ceff5448e414c9","0x8d6f918cf7e15bbf0b9bb90f58a6477e050a7be687a1566ee2e34cf71e9683b6","0xaa3663f978d98ec7c3f5db5bcc547c22b55473e072325444be995b49694b68e8","0xf0dfde881f6672c39b92559e62bfb686c1f396c123ad0b078215601cd7833de6","0x100032a9090d3436f4428af12e4ac03aefd95cf8f54d91dafb898553ac65bb76","0x0813eb4603deb99d240bc27fb033d79b750485b255ad5a21718844e68afda6e0","0x564cf32bc2ede84eb22061684320c87877b13805b378ec9cf351b880d94d0e90","0xaace17676be5b8a1d00e4b21cf8de0b31d611a6037d6b6ba427c518c5dee93df","0xabaf2c962dbd67db95c6fed916950ea39ee021ee2ca366dcbae0791c1995eddf","0x55d2836440ac765764d2bc093143f4d33e4c76a67b24b63282129567bdd18891","0x32fbd38f876ee907ab850539e8622734b2b6166bc3c497a63bd9705ab8ff309a","0xe6b3c13b048842c64b4b2285a3d95537bea9932568fe44a14da9d96fe32af38e","0x326a95b803ec456ecf879056c0a062ec867c2b1fe77b5d7543886f744f9fc054","0x76e3b1f93f0c70797f32d34ab16c22aba26897b262bf3b9fea05792c0e44bc99","0xa406ddd554632edbd8fb29bf48239d32379377d9964d63b56a4b58a6342211ae","0xe507f04062a919707c1c3646fd9dafa6466ba9a5b99a45a5f711444074dfdf1f","0x9d8f75b125afb460c73bc48045e8e188e23230c97c10d7c1af65115a9109a3c5","0x1fd09384af3072d7ee6072df6301516d3a116faf3d22dd9c6dc455b3f3928740","0x496962b25aed0d28012906d7a640d01fbab66f4018b462a1ae53a063c0dd3679","0x78063ab277b776b33f80e283670082686a2462fe895c9bb9d330c767c0658f18","0x6d131d2dc122bfb19c76093de5ec81953dd9af621fc7b4585a59ce285a864aca","0xeb51833fadd3b8bfad8a02e89f2e8ecd27d8ff53c7c52ae13c12b4188369d6f6","0x6b8cfc3843f0a4bbe3e386599824431c874d40fd2c175353670fee2e8b81533e","0x7e09208d802733a55e117295f0b57c82e3e5db785a15b739746148e86830e413","0xf0018894e8d2f87813830ebeed5461ecf5281508021664665742dd7e94b15941","0x2142c7fc110bca3accc867ce813dae6b488fed792140796c78785cfe8371c511","0xe6517260872c2d1cffc2bc7f58d3c86645182a272cb6fae9755b7c84f46e12c8","0xe1a71aef34f4be1bcf8bebe2cbae269e8b6e527f6be8f58954346459ad64e54c","0x778a07a701524315fb01cbe4d04e89258ee7cfa6e2b4cccb08ee14d23d83d0bb","0x33907d1183d22ba055b1ed6587a5c1da14824ae516557d1aaaf32990bbe14747","0x6c3bc5aa7785b1d2b87e50aefbaa2d6a567c5604cbda95a48688d71ae46bdece","0x931dfedfe7d7f1376930ff1d99b6a2029b230386b0cf75a39fbac8380fee8e35","0xd0c77c7c70597ce712d58817cfb5b6e97b48de4bd6af393a64a5965701355003","0xe4d21108ca8e6a470dafa942eea205523c296cfefdb49ae53e932dd01ddaf84f","0x0b6b90b3c8786d4a67178cab8c41fb640fe2f7ad63c3e149e12bb22dbfd18012","0xe606244314e4b255a5c6cce60b576c17674dace61c4154c7f9fcd41cc56cf322","0x960ba88a8b1bc543da5124bc09aa57199c17ef37202587dbc8af2a4d90a2e47e","0x839858692b3a211b079ab222e5b8562c6833102a675f0881adc7a8ab4e14cdcc","0x61cfc1d59bd8b930670181f27237f9474eb676cf9d852aa79b5f871c761a2af5","0x56bff44d1fa271202f8d55b54c78c9b75ed53dcb555e9b8f92c4810a270357ba","0xa3aadc8e65bc5430f528f93b0c726b015a2786539fd1f8d850e6920cfde0ea4b","0x12fd47af11eeb08a9115c967c8c409589a3a1d583641e446f54b7535b200bf62","0x5061b45dd10a197ce6d8b21f21075f3bb79e2bbc035fc38c2b4ea715f37be67f","0x84e9a7fefa6122f61a757515ad05f8851f4eef88b11d5612093ec9a206750790","0x9260caf0b005584f7ac5a391df5fe2a2ba270e3e26fa1bc8e522aa1d4c263e7d","0xcd8626836baa047d6459fa00a728097b5b7c740c8800b1630d2c581403fe3905","0x79cd85af2442851aa4fd2295ef741ed935b212e5a155e37aff20a6390b885c14","0x21fe3176027e96bc49a7f7c49e12333c158b663bd03ed64398a2ed3d84c2d094","0x73b5fadcd5aca1a0c30d21823772bdf89512d81336d666dd721abd7e55cf3241","0x8a76f963963517352fff4307ab8026c36777fd47c392622cf0dcaa1e02634b09","0x170c25cc700000097486d3e58a3282108d173d6cd05fb03f4ee338cf3a4e98d7","0x9d44390378e14f9386ef7ac2821d8a1502f242f568528a8776697a455f03443c","0xffcdbfb5ce2e40f33d2ff957faf7f28790a2fd50948b358f430fe3bf9a744442","0xb414778b97281156ca05a5a8620eed70cd7b6eac94cc7194b951b4a43f253c97","0xcf4aeb1257d707c611b02247bbbed867bd4d427cc5c65e4552d2a4842198eff6","0x26dfa7935ba3a3de6ad649e215a48d0602743867d4e7bc1fd55039114ebdbe25","0xa3db4bd9f6c5ab9c0394e592f6e2ad56b0e16ccf7ae5400d2fefba50cf6a13e0","0xd49951086f7c3cc0d78fa7f06241edd0c514ec180bc3dfcf7a6ffd790f6ded4c","0xc1d1fe0cbbd448f65829e2c10783a1461f555f9cc4b41a4ad0b9a7d1a765d9df","0x37c77b747b9efa641342e1bb85f5cc3f4306aec4d7449f7a12d43025c813fa47","0xa052f59e3732d89bee1d7d4490340a42be97c05a3d7b270baae0e715422e481d","0xd03708cd291234da34a99fa6bcf69aca54fbb9b43308b4057959b8534fbcea0f","0x21ccd23bd7f7d79f297d79c23ac3187b7405e1dac52c62bf9210a20bcde6bfd2","0x0ed28691c1b0913319fc7edde29153b7bfadf4ed5c11d75bbeb8a4711a04ab0f","0x08565c5067041f6d8f5f8cad5e39ccfc676d0371b960bd7edc6a631d9fa544c4","0x1f14dd0d18aeb08bd5345c41c31ec54674271c25ec4c442d82598ef1ee99596e","0x7ec78b696485e00fa80211d099c1c947b6a76afa64dcd21ed7fd11352e837bbc","0xdfa91502d2588788465cdafab98f01c934c5516eb043897158905169433773eb","0xf5d6107e5276b246713aa53a7e20a3bbfbaef981f7eda633dbe5402ffc4b1638","0x4fe1ec8d91b3aa59180a0414b33f2c6850e54729c03e22cf26391bee2371ccec","0x9290f637bdf1f5418702e4ddeccab62927659fea210916aff4e322dde9a1965e","0x2093ddc71f77133f222805e75ee536c1363d540bc64896d8854d980556b5eb78","0xe2135122b3adc2aafb5520f31dec24981d9500aa8edf97fdcc3ed03508ddab7f","0xf45b12961b80f82d864e3578f80ac92324b9ef2964ee66a71e58b6241402fff2","0x064a66b3cfe8921f5da142723d4fa2af7b24318305c05f2682ccd9a2904dbe48","0xbd5b0789cb9ba73eb665c8b0a9f8db68fed9ea6e8f965111696820b6e66947c3","0xf1cd611a0e1e5b54885c75d73db9e70aedd3dce765e4faebd2065a47593f39c9","0x17c9a4553d2f689e4da7e8ee5093596ddb3563a03a72fd7ee430b885bbbbc229","0x087120d0240951ec75b3c5c7b637e873ff02f347b97c73c8b2ff3186f3ba5f8d","0x5b0caa9b293799fe9a4ed68a88c74195c3102d3b2cf7b446b89d949b3f80f0c7","0x3f9581b4e3c61fd718c45b2490c8fcdb4e47489ab50a504825830b50bd1419b9","0xd47c0e12e513b6ede8fff4ea4f65aa7fe3ff751e0b16ab1416fb2627ccd81acf","0xf35a605751f0cdc926413a984506d4eab20ae09cd0a5edcc1f505e67dd426c64","0x876a67d7f9ed4e926fafb91272290a01758a9b9acb7af1ad43896c13b381ae69","0xdaff5644cfce09133cb6db783019f4de406f06f8686962e683fdbfd8edb47ee3","0x79f54807878a24229f57f9193ee144e9ad4ddf90f7cd38a70b9d63677f6b37d5","0x98e840f518c6fb10cfc6e2a59e907bb195d6a7abeaec350163d7242b772775aa","0x8b6ec07092cb61afbfeff775a9ebb6d26608e5d30a0039e59713a77874d02988","0x9cd465d2e0fc07c1806b64d34decc57e5426825527a61906413dd2156635c2ab","0x7afff2c624a94881faba70688887524c30539d9aa51060176902fb970da92c85","0xd891cb85ba08a9ceeae640d8dd38c19aebdf42fcb5f36bbee21368ba7975498c","0x513dac3a3f8156c50a837a6eb6c0b4d24aafb40d823905581e97f73a3bc67ae1","0x77cfb9ce0f011db6c1eadc298884fad690c9e92a67e31e5c44ae18cf346d93b1","0xe84a489566ebddce63c7a29c3b39c6b571312f16b01b40b39d8b253d70e2994f","0xbe3664ed0f7b6f45bd46896623d09f0f065a622595e8be9dac57ffc86f48264d","0xcd581e7dd7996363d5e0423f901ddab44e4a74003c7dd2086c3f3f2ae51f80b9","0x702c9f4aec5a17f4033543956e96216ec6ea2614ec6ed28d2cb017b668482d1b","0x82d92d5a9ea7f42b6704a2abc97da2ddd57f9d3ca5996bc8c9e5ee7abfd0c9dc","0x9d8ed0c4005c6114247549dfa93ad39aeabd65011bf8cd24bd904bf5bcbd5932","0x0d88d6d7fcdf2378636b709c13d7292089b1ead9a00f8d42559eb22b9dce2430","0xf29d043407991d3273105cf98898ce206b5222e1070a053f421dd67f76debc51","0xe13a05f255b6ed96309eea1d53672c01b04578ca3dcca4f9b5b157701e853c83","0x5c028819e9553e9241e65e708a97bf8cba9a21264e1bb766799a17fe75bb553a","0x453490ea5195716fcca9adefe393cb5b244ea36317a82f50ecfeaddf3942c6b4","0xa65d52957d4f30dfe1c7ec5b62901603d89ea42beaa4a07efdc10aac94e5b88e","0xcf7209723d41c5cb01b13b63222db5c21b59a5d713d80da55ee70c676c154d26","0xf6887497dc94f67fb82fb4c12716ce481300f7f58304823be885893e62e88444","0x794c1a37c5022eeaf034775994264379ed8df96609a23d8c6f1fa864b57f21c7","0x047cdfec0fcfc9db1fc7a19f82da9c6559ef428ca0348450ca885f1d442f9a02","0x72a9eda4af2f63511dd6c14968d21a54b593164f4059e45f60f8536a7aa7c9c8","0x0cae67e525a278502a93bec1534476561c268f61a10471a2361334f6fc0aa52e","0xc420e00f2fe8fcf4235cd0a1f27bf0501bd93b81d30e2f91335fab7c886c8649","0x2eb6e625ce3508dd5b90f47cb28385465366f1c4612b9ad57a8a305a28c19293"],"logsBloom":"0x5f3d66625185c33fde3dc0faec3998451b0b30bbaec520074f39c1fa8cafaf03887f5d8da0127c580b377b1cec1e0391eb91e3bd8aa4fcba4a91fac873be86e6415bc5eb860b5baa7d5e61acc3f18c2ba62cd0b9716c1ca27c3e5758c92e595656a974739e62f8b3cbf55dd04622ed4d0260f239555085aa8607a594576f3bd15358175086e6f34888e47951bbead0fec12123c7fd5b6e9cf720a07aeafc95397fd69d82fea2ef57431e58c1a8088529bcf8ac9a610dd8806769cffe8c9a83718b5734936e5acfa72044c62203155e4e3ee437864e6c0bbef9bd4d8e85816a8a02752c1e9c410419cdd5d887834f6a9d663a9eba720ee4c2690b281937c71485","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0xe1d506c96b5e7377ab0a6157e6d0c9d65c7a5fa7ed28a9fdaf02595e6889256c","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x4b42fc5bc316b8776e6fa1727c375ab18b2401624615fb71e0c95bd1400ef814","baseFeePerGas":"0x17b285303","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11c0f7f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2b","validatorIndex":"0x15923d"},{"amount":"0x11b3ebc","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2c","validatorIndex":"0x15923e"},{"amount":"0x11be4ab","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2d","validatorIndex":"0x15923f"},{"amount":"0x11bf791","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2e","validatorIndex":"0x159240"},{"amount":"0x11a64ae","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2f","validatorIndex":"0x159241"},{"amount":"0x11b943b","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e30","validatorIndex":"0x159242"},{"amount":"0x11b214e","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e31","validatorIndex":"0x159243"},{"amount":"0x11aee8c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e32","validatorIndex":"0x159244"},{"amount":"0x11adefa","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e33","validatorIndex":"0x159245"},{"amount":"0x11b899f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e34","validatorIndex":"0x159246"},{"amount":"0x11bd948","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e35","validatorIndex":"0x159247"},{"amount":"0x11b96ba","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e36","validatorIndex":"0x159248"},{"amount":"0x11c8e52","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e37","validatorIndex":"0x159249"},{"amount":"0x11ad72c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e38","validatorIndex":"0x15924a"},{"amount":"0x11c2bc8","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e39","validatorIndex":"0x15924b"},{"amount":"0x11ba27c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e3a","validatorIndex":"0x15924c"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0xeef652","uncles":[],"parentBeaconBlockRoot":"0x5515fd3785b9fe785db376b82d43a7349e1407f0ca6e82b05a48da5ae2bef7d0","size":"0x13671","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x71e763ffd2b9a8cb6e043f2acbd02eb1bec8e2370354ba74e6a5c75ae543cffc","stateRoot":"0xc6cf0be4bbea00f4e3492428da4cd4287cceb0f673ed66f6227ee2affca894cf","mixHash":"0x2a7b6019eff4f027dfc004a19822eef8216b63823ba062fe26e3cd5ad11e663a","parentHash":"0xa870f670ae8e85ad097cb45fbe57260ca4f053abafebad9b7d6ae7ba819e08bf","blobGasUsed":"0x0","timestamp":"0x6687daf3"}] +{"number":"0x134d6b4","hash":"0x500c31e728a280af1add4799095e7229d4a4cdfc6c9c73a62434703ffe34045c","transactions":["0x66324d0360eea71d5a5e6d0bc0dbbdf35cbfbc3a3f121d028ad34c11426efdd2","0xe305bf3385425fe0387d926334de3f03150b31233df76fedaef472d635560e78","0xe410fb642fc29d34a9ec92a1ed3cb48748e2ac8fa7cd9c8315fb29656a8fec1a","0x247fa2b38f1fbf6758609e6d5cdc0f9dc899f37735496ecb95bf734eafd360ea","0x9d10a0dd7850ff99c98ec13b3e65905d1242875784b2d5420be80ac2e3f45c4b","0x53d7fddb6491e17eb15ef6d1e8ff3027735905bfcdfa66b3dae56f973fc2576e","0x40c52b14161c3bb6ea8914fc8a7e55852e0a51d36be4a43835015eb9cc330063","0x5df2a9b9eb1d800c76a1c6c90019e0b6dedf71e85764ed80d9cbba1e8e75cc4b","0x0ee9f351711baf9f66d36fda5c4e436b45c4942936d088ac826dddf781f2bdd9","0x74109ee77c85494337ca6db2975e00c9aded34403b64c9189fe22e7bae3bc4e1","0x9c53f84c1993f87c5ddeaea655780c24c9e265644ff89c839564802de661e4d6","0xcd13d2d4292e2a03c099f60e5db2de058459262c5dbe70ac792f533e47e15b09","0x03b719dad83d99a2eb847751faf36d4663a43d936f1c66948b139c6fc82209dc","0x2f417d2c35961dbd7cb522fa0ee06c95aab12b3d6a707ca8f74f97953fa34227","0xc26f561629de18df96ae9c1271912a90e7d67a9b85d99f603b63e87bdfb68e93","0xa4c4e1851441c900b82d8b90808f59535599884ef3363a5f46c05ef309f12c68","0xd3fad4b38903dfc6ff22954674dcccaa232146c3c6b60687dd1fb6bb61b95c46","0xc2f6717a22fd5b1efc93f59751e2467ea872777782e9201160d4af85aa16f91c","0x4baed9c20161fb6ef4315a198386a4c894f146fc278555e3f87c7f6e18d76c06","0xb91012cc7b849eb66779a8706453556467547c41b93394c36503141b4213a508","0xa33cb80d6bd6e5994c35c49250a00c69d49714e9ef343ca18901a4962e95cc5a","0x1fba689d944205912a77de9fcc53f4ea553e58240f09439d9b6b984495ae16b5","0xeaf101fa2a459f6b9812bba88b42dde5357befda42a35b1f5b5651cbd514e9db","0xce1e34de415dc7ba30c2a4d655c3f3e650275c323518ff2a61015d65cdd5a0ec","0x3d87d050821056a3ed8c1a3ada5bdc1dafd6483459f09054f5ec5112c3e2e833","0x60a7e890a6db8b50d93992c461dc16b49f57f6855fc8dfaacb1a525830657ad6","0x143336aadce774b79d069b72eed4d615df1078df98859476982ac00f35dfef3c","0x17e5787cdadfe3c01ae34f23ecab84d90a0fde083d1a5770cb1349b48ea49d45","0xbdb4b34276389846d8e7cba137033a3fabee90c084fbd65c840839fffddc0d2f","0x230eca8906bf58d6017fd8f3057a2c7e05de885b302b5c349c9d587659cc366d","0xbda38f281b0127034ca3d9b3726fe9ac68c800f34990069edfc8c6ab8cfc43ce","0xd58df4c85b7002b5762707b82d29475628319fa5ebd98dfa4e57721c78d5adfd","0xba4ce9b4cd284b96eee2f8db9db065376bbc646656fa04b2d2a623778b24c300","0xd5c2b6ce545a05378dd92582f6e3c77d1aae42cd88a174bce287073697595f8d","0x3c4295faecb8b630259b5ab875e1de2433d0f384d72bd836718d4384d1c7325e","0x46f5f9ef7efca04abc8e45fa48cddb5fc80493ae07ad943af7f10d94df6d5575","0x43244bec21354c3c918afc71ad11ceeeacadc8d9a114de8ee867cfd592dc63ec","0x95da6a534725726a0f4522ad3b5a81f79dd611290136f58506b7eb6c71b6aa6d","0x5a06e4cf4a51e7060d772d3052dd752789d9a344bcccfd3d5642774f8bf21dc5","0xe6dc810bdebe5c422bd9dfa2b444aa848300a9e7caab28cb856c95a40b68182e","0x153b92c7a60749bb79016c97d717c9a1b68e17fc237ad20763d4bfe9eb31443f","0x3c57f44269511d1ebb682f5b4de53f45bc6cb7bbd455cb18d971cc2a5414f4cd","0xfb2f82babaaecfb5190912074f1382706095f5dc04d7b8851b3de2f115a6cd96","0xb930db9657d311ee70e826e1af1595eb34ab0d9fef21599761f8eb6b57289a72","0x26de40a55c59c5d3e10bb86db6f012536cf65fe1599c589c6eeb32b27d9e7a64","0x90faddb5707b8c30beb8efe3b47d4d2b6bb2174088dd5717263e73cd36936f95","0xefa678a2771fbd1534bf85857d20f4b902d6d26e87e7a96af0e1e512c449c76a","0xede6ca6bfe169da516d0b0a17950d6b88f6d97f9a01569fbcf611504a7815f75","0x132a5b1bd116f732dbe91146efbe8f002411fa80d2113c3ad43c60811b50ba33","0x42b01e6112cd30609f68aff8c90e999fa7d07c169a8bbbababe15ee5d38be66f","0xed60c7c83d4831f55fcb573c8d7417fbe9bdd5d449d54daf67fd3d8623f1a297","0x458ebf545d76f78dea87cb03417bc2d299d669223e2b9815bada877a026df63d","0xdf1ce874ef2e43bc1413e05bf0652acae985b6d94f8a9fdd060a70a61ea8e0e1","0xf977ded6ab95ef5a028d10344c960e16838b81837fcb3f3d15128e9c66ace584","0x733cac76207545f35f1c99ee1145b403d31e24da8cde0a70eb3c25515367fc7e","0x5d53e264ba107ae92f4683bc126c5f0c38aff9a6cda1fd1c743a453b4870f4c1","0xc347abe53a5b5020420ab0da3eb05ec67c3bed42ebbe091f2f94f6d9c2fa168a","0x94e61a2fb7550c453a0c7500fa279cabf1fc661ee8c8dedbcb2479d5a8982196","0x945bc4e094a800c26361b627f67616ef4835cec4dba6e58119d68f10e6a1afcf","0x9c4116447040232cb1f5e13059e4ba12c2db501e45f78cf97f60b0db24695b31","0xaf22df09e9921d45535a0f5f80ea607a860d51681e02b9b57e8c53d74cc36310","0x28e6ee2a48b3c780affb3c124d4ce27acec3d40121f4607ecd565c70701c085c","0x95aa1652585dd525dd926368cb936fac87f81625ff6f6eeab1f2288507b61289","0xa5f466f9b62fea39daf0e0fd3c47d783de4aed4dea1d11d93ab0502f3a4489c3","0xf5be04d59b7c36b75ce6d86f02161123f2e5ad02d5f6e8cc7bacd7f2ec1fd206","0x425a10965f389cfc278c7300ac9a27e7891b178fc39991abaac7848f7089d487","0x3be1373318ad87b9957f5b7b4ae602aa19087b4177f3ba255faa19c576a63f7a","0xf250f0ffb6d574b82a1dad285b17835d68779c7cdb59d7f96794fa945fd4feda","0x13d9d1cc11e7f1af51099490be740a996eb7eb4975daa1cec851081c76805e01","0x41f03ef64f0015f1e8ea93f4381407cd12c83581eca09f10d124c12864a24f35","0x4ca92077f33bdc962bd76f59eb1327a096b9330b7e69393c16589c71c61efe1a","0x499d2f13d41a9e444e882891f3105b493112db8c188e650101916a6c00aab571","0x63afc736e099316f08c559498fde320fda3c5175605aee71dc767c41ba00a2a7","0x481ff76b4c9b60212a2cd281bbe79d048c2429e00ff4be2a86ccb87b863165c0","0xb34048c9549de5042db2c0398988724104dbc5e9470088583c2cf6c348b3dd7c","0xba9f94b5b8372d6b431b8735ab4081101aa9b7bda951d912dc722499c598a83f","0xc5a6251e55564b17bf44f7aa6d21cdd20f658d61a8a84a25c04fe4581895d5aa","0x3235c94fcdb5f9ff29cf70efa34af3ec931a3d1694beb027f0fbd5069ff4ec65","0x5f7915e8d005d97fbd262f31ae861e10a3c585a57a0f118ff0789bf045588f99","0x1d6290be9ed40cb5a458c03bb04342b4f14143bc873b3d50c3fbd671f3db7438","0x65866fc1fba54dc4e6bc0e82746757b49869e359726dcabc98cde74d8ce00c63","0x3d515de1807167f4230d8e68393f3d90cd396821bc8dc05282088caa9191e9cc","0x8c2c4d28db1e21b60f29b19a1035a6911e892a1a91609009d38e373279a56243","0x83df9f5987e06e737e6a28e40175e261dc4936e7832b746207f28c87d8373c5a","0x2d7d7fd66d324c4c14d05dd100ebfc5bc9b945b85a4de4a4520decfeb86e531b","0x0a4acb940c53253539d4b3bbcf7752aba3ccf240285f664a4cfbbd72cb192d48","0x193376115ab2d506755b01beeb7b88012559cb78efed68131ee944addff240eb","0x489e003f7d85c8365f378af589c2d83d6a622e85b6fe0ba58e6ea03c62a08e4a","0x8de8197d07d9f2b47a4316871e1836bc0c405b050cc6a5a27dd9faed74ffffb2","0x592578b40c288a1e25e65f6a056da0124db8bc97fe1fc0a904251ee5f87828b9","0xef29e4bc8e60d8fa76eda5f33f961ac1d36f9f13efb6c1c7a58402733f17a9fb","0xa116a77605deec75b2070955445c9d793b05e50f099d4d1497e34eaf87ed5646","0xa15aae1355633ed2ae9283334bf6db5cf5cd76e0134870389ae8ae744a7bb24c","0xaccc10ec12c433e98e3c27d44e5d5f18400fcbe13a8ceed4dd68dfde57c15449","0x6cfb2131e6b7e25e1ac468a503728903690dd5581fc8bad33f1eff4794229a34","0x4ed2e2e41ec55d6a5b42f1672fb89c619183ba003af4474162f5499c1f163498","0xddbf5ffc8adc9379ee0cfc8a7642c88b327c399a85ed1edb8c9b3960ebcbb9ea","0x08d7c8342bab8fdb4e79fc3b7d75616254df38af409d1d9f84657fd3ddcf69f8","0xd4001d19e4225a3a5cbbfe2934d2775105a7d7d8818b7cb98703c33012716110","0x2062cc1d24beecc20057ad331d690508c748e21d3040ffb37b38965966a3d3f0","0xe3836b1fffecb32d2aef998b4d3c0d606ca9ca2b002661a8f184cbe4d15bbf78","0xbf814b35d87c58629568108a5e1176f67453a1eeb324a510d00b927c477182b0","0x769e8a0d5da47949435d6f4d10f0c61c5dad97e492423675fa6db41580c553dd","0xc7e5d496ba456c2e79f504bae6b2ad6759bd16fe24e1322c9ab69ff971cb6040","0xfb2a55d870229c5128aabd6ac21cf4fa02ec0938f507c95267239818ddbbc2eb","0xbacc62ef0a1edd91c4803c5be166926d737bd76bcb129f4a6f57553a09ce535b","0xda567db58bdd46ea35271e1a53d29375b06054c845bba8f4cff3b0493125d12d","0xc31700594d2f23e26a90d4dc5af926b35a64dd7ccdd4049916302426a491b188","0x40e80109207cb7d621545f8f1c5436e2c3997eec7b521c5e0ab8373b05365b64","0x6d24f1451e0477cf59b0d99c18d6bd1d5aef818728886b9be3643fe7ae10701e","0x906d4b0e8f0a3a1b129138e453ead10750ae4cecf517e01b6bb99340bdeedde4","0x44d615725dd6a00816fde0b1767256e8d4a6796a6d1b2d34844d1389763bad4a","0x42182c0aea8452bf6d86618a0b5ba0237882d158eca83591fd2a7e0c4e123d9c","0x22151212da28291a917d43c2420cc5bc3fe8a0379607325cbeba0eb753eee1a9","0x90019486ad21e98d87ab8965de800d56104267dc2416d399d689ea159221bffd","0x64c1844e0cd95031ca18564892dfc038ce8338ee1168ff61b50ea34f9aa1b937","0xf1d5278d5006bb81ce58798252d790ff95503b63947c1000e7a742a8b1e320b0","0x3dcea3438fdf4b53b23d996f5714d4af758ffac6b82a03ac7d153ec850866bd7","0xb357d9022b4ddab68631c1ed393b46ce5b8048a69f98b4f8a1ea0bc86036c88d","0xfb608c5fb250b761fe4c44479ec398cedcc0f19f8196e96912bd3c02bec93557","0x3c30908976f14f75f5d48c0e61f19af6d417544f79424a737902787382dd0966","0x80be3649036b61d382618ba38055e3a6dbad22906928de3e58ceff5448e414c9","0x8d6f918cf7e15bbf0b9bb90f58a6477e050a7be687a1566ee2e34cf71e9683b6","0xaa3663f978d98ec7c3f5db5bcc547c22b55473e072325444be995b49694b68e8","0xf0dfde881f6672c39b92559e62bfb686c1f396c123ad0b078215601cd7833de6","0x100032a9090d3436f4428af12e4ac03aefd95cf8f54d91dafb898553ac65bb76","0x0813eb4603deb99d240bc27fb033d79b750485b255ad5a21718844e68afda6e0","0x564cf32bc2ede84eb22061684320c87877b13805b378ec9cf351b880d94d0e90","0xaace17676be5b8a1d00e4b21cf8de0b31d611a6037d6b6ba427c518c5dee93df","0xabaf2c962dbd67db95c6fed916950ea39ee021ee2ca366dcbae0791c1995eddf","0x55d2836440ac765764d2bc093143f4d33e4c76a67b24b63282129567bdd18891","0x32fbd38f876ee907ab850539e8622734b2b6166bc3c497a63bd9705ab8ff309a","0xe6b3c13b048842c64b4b2285a3d95537bea9932568fe44a14da9d96fe32af38e","0x326a95b803ec456ecf879056c0a062ec867c2b1fe77b5d7543886f744f9fc054","0x76e3b1f93f0c70797f32d34ab16c22aba26897b262bf3b9fea05792c0e44bc99","0xa406ddd554632edbd8fb29bf48239d32379377d9964d63b56a4b58a6342211ae","0xe507f04062a919707c1c3646fd9dafa6466ba9a5b99a45a5f711444074dfdf1f","0x9d8f75b125afb460c73bc48045e8e188e23230c97c10d7c1af65115a9109a3c5","0x1fd09384af3072d7ee6072df6301516d3a116faf3d22dd9c6dc455b3f3928740","0x496962b25aed0d28012906d7a640d01fbab66f4018b462a1ae53a063c0dd3679","0x78063ab277b776b33f80e283670082686a2462fe895c9bb9d330c767c0658f18","0x6d131d2dc122bfb19c76093de5ec81953dd9af621fc7b4585a59ce285a864aca","0xeb51833fadd3b8bfad8a02e89f2e8ecd27d8ff53c7c52ae13c12b4188369d6f6","0x6b8cfc3843f0a4bbe3e386599824431c874d40fd2c175353670fee2e8b81533e","0x7e09208d802733a55e117295f0b57c82e3e5db785a15b739746148e86830e413","0xf0018894e8d2f87813830ebeed5461ecf5281508021664665742dd7e94b15941","0x2142c7fc110bca3accc867ce813dae6b488fed792140796c78785cfe8371c511","0xe6517260872c2d1cffc2bc7f58d3c86645182a272cb6fae9755b7c84f46e12c8","0xe1a71aef34f4be1bcf8bebe2cbae269e8b6e527f6be8f58954346459ad64e54c","0x778a07a701524315fb01cbe4d04e89258ee7cfa6e2b4cccb08ee14d23d83d0bb","0x33907d1183d22ba055b1ed6587a5c1da14824ae516557d1aaaf32990bbe14747","0x6c3bc5aa7785b1d2b87e50aefbaa2d6a567c5604cbda95a48688d71ae46bdece","0x931dfedfe7d7f1376930ff1d99b6a2029b230386b0cf75a39fbac8380fee8e35","0xd0c77c7c70597ce712d58817cfb5b6e97b48de4bd6af393a64a5965701355003","0xe4d21108ca8e6a470dafa942eea205523c296cfefdb49ae53e932dd01ddaf84f","0x0b6b90b3c8786d4a67178cab8c41fb640fe2f7ad63c3e149e12bb22dbfd18012","0xe606244314e4b255a5c6cce60b576c17674dace61c4154c7f9fcd41cc56cf322","0x960ba88a8b1bc543da5124bc09aa57199c17ef37202587dbc8af2a4d90a2e47e","0x839858692b3a211b079ab222e5b8562c6833102a675f0881adc7a8ab4e14cdcc","0x61cfc1d59bd8b930670181f27237f9474eb676cf9d852aa79b5f871c761a2af5","0x56bff44d1fa271202f8d55b54c78c9b75ed53dcb555e9b8f92c4810a270357ba","0xa3aadc8e65bc5430f528f93b0c726b015a2786539fd1f8d850e6920cfde0ea4b","0x12fd47af11eeb08a9115c967c8c409589a3a1d583641e446f54b7535b200bf62","0x5061b45dd10a197ce6d8b21f21075f3bb79e2bbc035fc38c2b4ea715f37be67f","0x84e9a7fefa6122f61a757515ad05f8851f4eef88b11d5612093ec9a206750790","0x9260caf0b005584f7ac5a391df5fe2a2ba270e3e26fa1bc8e522aa1d4c263e7d","0xcd8626836baa047d6459fa00a728097b5b7c740c8800b1630d2c581403fe3905","0x79cd85af2442851aa4fd2295ef741ed935b212e5a155e37aff20a6390b885c14","0x21fe3176027e96bc49a7f7c49e12333c158b663bd03ed64398a2ed3d84c2d094","0x73b5fadcd5aca1a0c30d21823772bdf89512d81336d666dd721abd7e55cf3241","0x8a76f963963517352fff4307ab8026c36777fd47c392622cf0dcaa1e02634b09","0x170c25cc700000097486d3e58a3282108d173d6cd05fb03f4ee338cf3a4e98d7","0x9d44390378e14f9386ef7ac2821d8a1502f242f568528a8776697a455f03443c","0xffcdbfb5ce2e40f33d2ff957faf7f28790a2fd50948b358f430fe3bf9a744442","0xb414778b97281156ca05a5a8620eed70cd7b6eac94cc7194b951b4a43f253c97","0xcf4aeb1257d707c611b02247bbbed867bd4d427cc5c65e4552d2a4842198eff6","0x26dfa7935ba3a3de6ad649e215a48d0602743867d4e7bc1fd55039114ebdbe25","0xa3db4bd9f6c5ab9c0394e592f6e2ad56b0e16ccf7ae5400d2fefba50cf6a13e0","0xd49951086f7c3cc0d78fa7f06241edd0c514ec180bc3dfcf7a6ffd790f6ded4c","0xc1d1fe0cbbd448f65829e2c10783a1461f555f9cc4b41a4ad0b9a7d1a765d9df","0x37c77b747b9efa641342e1bb85f5cc3f4306aec4d7449f7a12d43025c813fa47","0xa052f59e3732d89bee1d7d4490340a42be97c05a3d7b270baae0e715422e481d","0xd03708cd291234da34a99fa6bcf69aca54fbb9b43308b4057959b8534fbcea0f","0x21ccd23bd7f7d79f297d79c23ac3187b7405e1dac52c62bf9210a20bcde6bfd2","0x0ed28691c1b0913319fc7edde29153b7bfadf4ed5c11d75bbeb8a4711a04ab0f","0x08565c5067041f6d8f5f8cad5e39ccfc676d0371b960bd7edc6a631d9fa544c4","0x1f14dd0d18aeb08bd5345c41c31ec54674271c25ec4c442d82598ef1ee99596e","0x7ec78b696485e00fa80211d099c1c947b6a76afa64dcd21ed7fd11352e837bbc","0xdfa91502d2588788465cdafab98f01c934c5516eb043897158905169433773eb","0xf5d6107e5276b246713aa53a7e20a3bbfbaef981f7eda633dbe5402ffc4b1638","0x4fe1ec8d91b3aa59180a0414b33f2c6850e54729c03e22cf26391bee2371ccec","0x9290f637bdf1f5418702e4ddeccab62927659fea210916aff4e322dde9a1965e","0x2093ddc71f77133f222805e75ee536c1363d540bc64896d8854d980556b5eb78","0xe2135122b3adc2aafb5520f31dec24981d9500aa8edf97fdcc3ed03508ddab7f","0xf45b12961b80f82d864e3578f80ac92324b9ef2964ee66a71e58b6241402fff2","0x064a66b3cfe8921f5da142723d4fa2af7b24318305c05f2682ccd9a2904dbe48","0xbd5b0789cb9ba73eb665c8b0a9f8db68fed9ea6e8f965111696820b6e66947c3","0xf1cd611a0e1e5b54885c75d73db9e70aedd3dce765e4faebd2065a47593f39c9","0x17c9a4553d2f689e4da7e8ee5093596ddb3563a03a72fd7ee430b885bbbbc229","0x087120d0240951ec75b3c5c7b637e873ff02f347b97c73c8b2ff3186f3ba5f8d","0x5b0caa9b293799fe9a4ed68a88c74195c3102d3b2cf7b446b89d949b3f80f0c7","0x3f9581b4e3c61fd718c45b2490c8fcdb4e47489ab50a504825830b50bd1419b9","0xd47c0e12e513b6ede8fff4ea4f65aa7fe3ff751e0b16ab1416fb2627ccd81acf","0xf35a605751f0cdc926413a984506d4eab20ae09cd0a5edcc1f505e67dd426c64","0x876a67d7f9ed4e926fafb91272290a01758a9b9acb7af1ad43896c13b381ae69","0xdaff5644cfce09133cb6db783019f4de406f06f8686962e683fdbfd8edb47ee3","0x79f54807878a24229f57f9193ee144e9ad4ddf90f7cd38a70b9d63677f6b37d5","0x98e840f518c6fb10cfc6e2a59e907bb195d6a7abeaec350163d7242b772775aa","0x8b6ec07092cb61afbfeff775a9ebb6d26608e5d30a0039e59713a77874d02988","0x9cd465d2e0fc07c1806b64d34decc57e5426825527a61906413dd2156635c2ab","0x7afff2c624a94881faba70688887524c30539d9aa51060176902fb970da92c85","0xd891cb85ba08a9ceeae640d8dd38c19aebdf42fcb5f36bbee21368ba7975498c","0x513dac3a3f8156c50a837a6eb6c0b4d24aafb40d823905581e97f73a3bc67ae1","0x77cfb9ce0f011db6c1eadc298884fad690c9e92a67e31e5c44ae18cf346d93b1","0xe84a489566ebddce63c7a29c3b39c6b571312f16b01b40b39d8b253d70e2994f","0xbe3664ed0f7b6f45bd46896623d09f0f065a622595e8be9dac57ffc86f48264d","0xcd581e7dd7996363d5e0423f901ddab44e4a74003c7dd2086c3f3f2ae51f80b9","0x702c9f4aec5a17f4033543956e96216ec6ea2614ec6ed28d2cb017b668482d1b","0x82d92d5a9ea7f42b6704a2abc97da2ddd57f9d3ca5996bc8c9e5ee7abfd0c9dc","0x9d8ed0c4005c6114247549dfa93ad39aeabd65011bf8cd24bd904bf5bcbd5932","0x0d88d6d7fcdf2378636b709c13d7292089b1ead9a00f8d42559eb22b9dce2430","0xf29d043407991d3273105cf98898ce206b5222e1070a053f421dd67f76debc51","0xe13a05f255b6ed96309eea1d53672c01b04578ca3dcca4f9b5b157701e853c83","0x5c028819e9553e9241e65e708a97bf8cba9a21264e1bb766799a17fe75bb553a","0x453490ea5195716fcca9adefe393cb5b244ea36317a82f50ecfeaddf3942c6b4","0xa65d52957d4f30dfe1c7ec5b62901603d89ea42beaa4a07efdc10aac94e5b88e","0xcf7209723d41c5cb01b13b63222db5c21b59a5d713d80da55ee70c676c154d26","0xf6887497dc94f67fb82fb4c12716ce481300f7f58304823be885893e62e88444","0x794c1a37c5022eeaf034775994264379ed8df96609a23d8c6f1fa864b57f21c7","0x047cdfec0fcfc9db1fc7a19f82da9c6559ef428ca0348450ca885f1d442f9a02","0x72a9eda4af2f63511dd6c14968d21a54b593164f4059e45f60f8536a7aa7c9c8","0x0cae67e525a278502a93bec1534476561c268f61a10471a2361334f6fc0aa52e","0xc420e00f2fe8fcf4235cd0a1f27bf0501bd93b81d30e2f91335fab7c886c8649","0x2eb6e625ce3508dd5b90f47cb28385465366f1c4612b9ad57a8a305a28c19293"],"logsBloom":"0x5f3d66625185c33fde3dc0faec3998451b0b30bbaec520074f39c1fa8cafaf03887f5d8da0127c580b377b1cec1e0391eb91e3bd8aa4fcba4a91fac873be86e6415bc5eb860b5baa7d5e61acc3f18c2ba62cd0b9716c1ca27c3e5758c92e595656a974739e62f8b3cbf55dd04622ed4d0260f239555085aa8607a594576f3bd15358175086e6f34888e47951bbead0fec12123c7fd5b6e9cf720a07aeafc95397fd69d82fea2ef57431e58c1a8088529bcf8ac9a610dd8806769cffe8c9a83718b5734936e5acfa72044c62203155e4e3ee437864e6c0bbef9bd4d8e85816a8a02752c1e9c410419cdd5d887834f6a9d663a9eba720ee4c2690b281937c71485","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0xe1d506c96b5e7377ab0a6157e6d0c9d65c7a5fa7ed28a9fdaf02595e6889256c","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x4b42fc5bc316b8776e6fa1727c375ab18b2401624615fb71e0c95bd1400ef814","baseFeePerGas":"0x17b285303","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11c0f7f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2b","validatorIndex":"0x15923d"},{"amount":"0x11b3ebc","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2c","validatorIndex":"0x15923e"},{"amount":"0x11be4ab","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2d","validatorIndex":"0x15923f"},{"amount":"0x11bf791","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2e","validatorIndex":"0x159240"},{"amount":"0x11a64ae","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2f","validatorIndex":"0x159241"},{"amount":"0x11b943b","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e30","validatorIndex":"0x159242"},{"amount":"0x11b214e","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e31","validatorIndex":"0x159243"},{"amount":"0x11aee8c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e32","validatorIndex":"0x159244"},{"amount":"0x11adefa","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e33","validatorIndex":"0x159245"},{"amount":"0x11b899f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e34","validatorIndex":"0x159246"},{"amount":"0x11bd948","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e35","validatorIndex":"0x159247"},{"amount":"0x11b96ba","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e36","validatorIndex":"0x159248"},{"amount":"0x11c8e52","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e37","validatorIndex":"0x159249"},{"amount":"0x11ad72c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e38","validatorIndex":"0x15924a"},{"amount":"0x11c2bc8","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e39","validatorIndex":"0x15924b"},{"amount":"0x11ba27c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e3a","validatorIndex":"0x15924c"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0xeef652","uncles":[],"parentBeaconBlockRoot":"0x5515fd3785b9fe785db376b82d43a7349e1407f0ca6e82b05a48da5ae2bef7d0","size":"0x13671","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x71e763ffd2b9a8cb6e043f2acbd02eb1bec8e2370354ba74e6a5c75ae543cffc","stateRoot":"0xc6cf0be4bbea00f4e3492428da4cd4287cceb0f673ed66f6227ee2affca894cf","mixHash":"0x2a7b6019eff4f027dfc004a19822eef8216b63823ba062fe26e3cd5ad11e663a","parentHash":"0xa870f670ae8e85ad097cb45fbe57260ca4f053abafebad9b7d6ae7ba819e08bf","blobGasUsed":"0x0","timestamp":"0x6687daf3"} \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json index 37f5ba2cb..a912ac113 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json @@ -1,4 +1,4 @@ -[ + { "block_trace": { "trie_pre_images": { @@ -10043,4 +10043,4 @@ "checkpoint_state_trie_root": "0xbe6449b0d590db000103d74f27cd54f4eaf3ed103cdc1c50f7db1ec5dbc26bbc" } } -] + diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json index 3c394e779..495731756 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json @@ -1 +1 @@ -[{"number":"0x134d6ba","hash":"0xea53668c4b92ba05c647ea3eeecea693115e775f028b7c1e3bad98afe60c1714","transactions":["0x10baa77ae90bbb5e0807753270a2cd7c1f1e3a49fc75147b9a88ae48266fbaca","0x77d24c7cc1926bdd6abdd67be8702f35b6fe426eca66f2600eadcd25e6bc8703","0xbf27555961012f41458bedada26bdac910f0d312afdb21274e6c0de6cc78ff94","0x3eb53d0c7b5a1549e40221f1862695f577c626480c82993110d020862ef324e1","0x386e5b6d2ce47704cdafd673a76fe8135f3c2056804a52d39c052ce13dcf8613","0x0f89b4d12682ac5743e129f9a047800c6e50776fa3bce1c813cf5c292c3b2b0d","0x3fe7460edb922780ce85a7549c3ac85446a6c694793aa8133e437b5bcf06a378","0x726cc27a5888b23e9a242b7af92d55666afc74f58f18ca0b9a731e3cbe7b6be2","0x54a4c143966f32c7cf6c3b7d4bf527f12cb8083fc6abaf10cc8d5dcd66949973","0x12e2ada283210d0a191c577b305212bb767b4d9f24a715dd078aaf993ed6daeb","0xac75df8c1b2a3baa88a489847bfd0812ad43b3df5306816f3b7fe6b530a0e0b1","0xb80ecd4058cabd710abd7168df90c0c1074955a72017d0576f39587796058b78","0x4b873cba45ca049dc9c54aced8c85484a6f4dc0479349f166f9799aa55731ed0","0xff1f1da5ff35ff6ceddbf8af4836642ad7c432a2dcd05b2d091cabf568fafa91","0x5396249894a92c61ee03437f583df3abeaba49066fdce4d7a424f4106ea47e81","0x31b014a918e48373e058381f25ec70f767525a54e6a45e4d4e4eaa700c55fce1","0xe933e99cfdafcaa300fd1334a99a18eb8ca99ff00647e82246ae1547b154205a","0x3c02338348d916fb192d9ceadb8c291677e5d9f9d8a057fd3451183bf8d1db35","0x1affe87eb0739605fecddd51d2710491cb5274f7a1c556555c8252a2de3b98bc","0x62d8051d4d588fdfca1bbd86d8710e1fcf0c104ac823a501fb75cdadaf387363","0x71a4b962cc272ac70cb55f442013c9b2417541719dde483cd723adf1c97201af","0x3ef1cf8f935b3403bd55c0400f70d0c38ec60f8c1d436dc369d200cf64436377","0xc5b5d3e42f6e190f7e1c3a6c4e3ad8a88a4d0eaf990aecfe8313ecef5e9a9128","0x35b9e8138d24392e5c468f5fb9f045a55dc97df9ee7012869482f8eb76a2ff95","0xebc1b559aff8b1169c6aa9157cdb58f670aa37aa91b975ca5c85006efa0ad2be","0x09fc8f0bde542bc39a48b3ce581ee1e838d3c2f2c190a4f345106e41f5daed9f","0xef49e0da2b7eddadb3c7a965c8f641d70cb7c610f485909151b3c06fa857a518","0x874b826ce0d5650cfa5362f1ceaf74450c717efde705cf70207774438371bde2","0x88d95f46d2b7ac417547ccf0a2bf69ce416613ac8c3368d76cb30ca612264cf4","0xbc681b4df99190ae4cd4dc275d1b904b4818631274540e55bca51281483553d5","0x5b54f41876cb3cbc485b03fd94b52da8890c9b8bf5266d7b8ab975299cdd9b07","0x91d878fc932f13234e2e04f73c4499c6adb7a96113479de34e8d4d6cd582e135","0x2ee8dda8d5a4ab8222d48f608af256ff5b76e321f5e83d4bc226a4ec6473b13b","0x75774b82857238ff577c92b7ec3d2a1ead2c98b5cd71939a913565f1cbbd03e7","0xc3c996a8aa60218995539f3889c715938f367cc954d4440e105060a0d67851da","0xca71b9732bcebd82fd2209076aa065f0503938cd950765fb84e19e1d9adbc603","0xc16c7be2ad78299e0557c554ed69404cd4ba95c2130239eac3d864fd2ee0d89f","0xdc9f750b6b20ddde07d36ec8c54827db2b18ab03372872b7566fca07629e9154","0x2232c45b71c80f53b508f9c45f20c246531e84978aa15968d902716425d4917d","0xc236b6f0458d5647d04c0587fcb443c72a2163fe6b3f18440ad983616374e5b9","0x2720e362091731118f26233c9836bd20585b2c257291029d919ebc6ba65d3735","0xfed2b19d1ccdaf10431b470a0258728cf741095a67675d74f140dc62a7f65cb4","0x00f38dec524f4f63181d6bb93d9ad409396973099e62cbbcd85b323ecee4f428","0x1a0e9585365d26f349cc65d6abeb46e7dc7a1a555d032c89ce1b6453dea9671d","0xe447be5cbfdbfc80884730c315da1cb383977de39b9123cee840688f4c2c28a3","0x2e6e2d10a00d84fd99f566aa1dd99f2a7b18adb71ad9ccd065ea93c46bbca7a2","0x5324cb46e39ac05b71e7133abf896421efc63808efdc482c10f94fcc91c01e5d","0xd98710b2e278015f2708fd350a99720eeaefe5dd63d7cba4da75b19ac641b358","0x80d47003d915faa7f5ce9bbd6f07e0755ae3e0a658ff6e395b283d0172f5bf0d","0x4cb1a391f5b19321d94d27c3d63ce64cdf475ca90010339cc9c0f5e13a5928a3","0x6ddcad7af6f7ff28e831e84e5e80491e7eebe8188f360b0e434cb9fb956b9576","0x24b2e8db688cf6e2e917e9c076c00372d1adb446bcb5965dc275d185cf6aeab7","0x0e0706dd9c73d3bc7e3fdb2b387107538e6346caaba24681343f4aef4a2173ce","0x68e345e1222ff5572f669058f3a7aa6486b0d93f8802a59230c8779752a13333","0x59513960a1ec9b050d5afd5f44573434fecda4063cb5fef74afd49f7cc2c07ec","0xd6b8bc16304f418e5b4d522fa5ed1382fdfb17d120504550d56e98e540a794ec","0xd22a565135512654cb9cdedf4872171f3cdc1ee5e01db63ae9daa29ecec25715","0xc850ac5666def336b01091ab11926a852ade6fa6cf4eb266a198abe570859baf","0xa7725d08276962aee9287c922e07622dd7f2f8e5e52d55a8cf0c10507b0952a2","0xeee01015b80e1b5b2717728d390fa5f44bceedde7a0f5dcfb1f90defeddd5a0a","0x2cf289ba14235df97bd0b1c1d9e010103581edca9dcba2c3e132324edc447ea9","0xf845efbe35808ab9f70af15d1b795285cdd49267fe6fe7d9545d7d93ab1c73fa","0x6d55e82e7c3452eebadd71ceed1b7b354f41f53fc5965a098143ed05750a5003","0x525716fec0f78fcf2282a4d919364d6c07b3741b3a202d5ff91ff27bd0d08def","0x7268d21087c95dbd95da156406b23a11a471945c9755cf7809d3b1b7a2fa55c2","0xb7881dac0a2b3c2a08860dabb2b405d7c1b11cc587c5eefd6392cb060aab3ac8","0x39f6bf42069184a39c1419961fa950d257eb06d0590901aa17b77dd48ffce25f","0x48d03398da8e7d3761ed077731238c0e49bdafdad01882c3502cfacc39e02f71","0xee8b4074d8ad32fa7d35d65d7cf9ad679e0d48cda98a5afef8cc4760dd9b3199","0xe974917ba0cb0ee41f0c4a51a9994cf325275b84de1ff43eee039fcab2c68c2b","0xed565eb3c53274d8454837145a4ac2ae8c04b7141817062c02c3dc65b5b052f0","0x08f8b93e429e9fdc516eff22a5c9d6b65ef97f426cf10355f37b3d34ccb0a98b","0xb005ede15def2e558811dcfded45063fbfdb9353545ea8c25339ff34629ebb2b","0xf5bcbb9071b56246fc1e9e6eed234a4732ac6a47a6ee8855e0864cfd48b6bd1a","0x384c0b9a378a3a45422f2494b945d7f61359bf42c82fa24958d0ee949ad99209","0x8792746825f7744b105c9a60d46aff76064a88e7d3b10f1362605c2bf191e2fb","0x2cddd834594a187bc5c366fc3dd182c18d5500450ecb0afe349062921486bfc6","0x2d50abc7283174efbab8b7581a2b16bd9f1b540fac2377868c5102b659881a2c","0x746be019b3f29ee14030012a22fce027327c933ff03a1a1d47517d6a57965f51","0xe47a41aae99976487b7861d80bb805a79f6f82478e2e518e6179f68ba9b42b31","0x37ee8ef168c13c050174e99e5e3307c8f9f2bd8f7baf2ece14596c39bfeda4c6","0xc607251204ea412f33ca9967b31e742a56c84f37e77a634c8ddc9720202c8ff6","0xd57584bd4f4d8d2758fa56fd98fb00f71780d1b441b5100a28c2720c0f2cf47c","0xe6e64b5de0a9c5a5d0a9f60829187ef8fb1cd1450b3decee82d764c6b4b47e72","0x4840d343f17b6af3491da5b17eb814b4c0861f2f6565f727703f4059aa9e0a31","0x2982540ab35ad428ff6cd55611c3c63c70e6dc4eeb65adb8e4f6daf0629899a5","0x1974aa5c6ae0de183cd630431921bbfed02d242fdc2fcaf61d263d738329895a","0xb63fab5abc247582f6873ad9bb71674e52a0f84ae8964d73c65c5a49a47f4a4b","0x511373f5bf71db16feaf4bfae68ce3af071b6c8e0b0da8b9cc202e83129a9bb9","0xcac4fd8b34138af38dd1fb5643508f37ce7e1ddfe2616c681e0d5c13a594147d","0xb5a5b55502855bd77a6e2b0e05771365bbbd4c30dd552fcfa638d7e896100a1d","0x4b28388c454889248e39ede01790dff88df4c206771fc3f203edccb6589a19b6","0xd31018bdf2c850549e89ad32a74d03ed66a372cff95ba7f386fac51b09f15b31","0xc2357b735a078287707f89b2a129568d9656e34cb6c11f9cd32e02a7d10c9b58","0x62684c02698bdb752d100e3237f5f8baeefa4b2871341a258ac5b6aaf23e8997","0x288cab54801a082ab3f34e79ce775810473ad46716777a19d64a832252db3eca","0x9c03d9019d1581a6fa8fdca0d9729305b111206510b8afeb4d292bfe3bb5011b","0xc117516a08df8a4f910536dd277d65c99c31a28011486ec1ecbdd0ae398b920b","0x9dd43e24e8df009cae824eebe27b8b4197a588896b6af22c4f69aafc57ba0aa2","0x96752d10ceaf86cd13d8d1958be1722d73f48272f9a25acea6c05976a208453f","0xee5490a31c607ba2e7c722095fb3df4e78d8d955a11f51db76a5b19c4d986b15","0x6f75ab1e059f61dd7cb3bc850d9e74a09c079cee4545873c26d01f3b3c35a189","0xa2c022b754d237e61da5a5bf43f0689960ab9cb88b078cac92750293d456658e","0x6c14f1f209b216d853f79549face498b87a7b65e393408181eb953ecb106f685","0xd7fc1912f1d55a0b69844c753949a1382afe642f8c3241c8b9d2dcbc0ee9c8a8","0xa60d1c8ce457390f0b98eef052cc50c8f239e3abedda3141228041b23049c868","0x6604e2160f5dedee6c5649a6fb2099d129a8254984c12e37183654630a5d45a1","0x6586195f7a0a5066849f975cc1046a9d5acf380ca97e10675032fa541b025455","0x0fd528ac75228717c50bf1301c629f031866b41e82645c35863aea79f028cc94","0x4c4686359b8fbd8299f4228d94fda2fbbb8cc517216e88ccccb864d4d8572f20","0xeb448c538c0945da91b490d0a59e05e376bb9a54b417f994f4ede53cb9b9f1b8","0x0c04689b4bbf1a97ecd907316fbd68d8991861683f02bea93193095b7623011d","0xa11ac8f6306c1f17764edfeec331240e0e14fb62741a4a5587ad56ed3e27a9dd","0x5207d8f111587146689fbae84187265753efac48f897301554bf28a0bad35f11","0x7f9fe8a0c25b3a3aebb2338efbcca8507a62bc333ac1acf9aaad9f5eb8d5bac9","0xb66bf9556a9cc63af9e9fae9dbc1161fbbc943ae2beca33b275bdfc12a1272d9","0x4ca39d13b8c40f8160d7332125bcee201d2fe2e98f29e342481a86a97ee23701","0x49e1c6c7a5f72ce8aaf3f71b2fc94bc87b78b3c092a13ba1542e542c415c5b24","0xcc8111473c669a1a23dd48017538b6f2062ba6b20611f94d5d91b540f2b63708","0xc0944eaf281709f025830f99534f4d852563e4f3ade385e170cd85ac6502fc9a","0xc4080487c0e97dcde9a4c4223fb0b654f6e7e617c5444d14692872d165b346aa","0x029b0ac5bb4937aa82f786b559c8f5231e48ad5339026a365a9791be7a782065","0x88bf20195821a0b25565d1a8a2a56836c8880b2dfd385de91610ff374fa63cfa","0xf1ec225976bce5f4fcf1a855e3a6a36d23556d161a0a6b941fad665f2b245d4d","0xa0d3a7ca1d9940db2cb63c0e65bc7e68599c6d995816e1fd337b7b637b2931d2","0xe489a5a7c85280cb7c2064309f6c01cf1e6e0f63e14952587a3d998230d639d8","0x0ff21c69a9f0f7a91ec9f499d2228458a46c3d57d795c5cf0730b858713c0abd","0x03a1540d0095e65d250f5cf0e5f2b136768e00193926ad3971050b48f31a2369","0xd57a95ff6ef9b56207634cddf4d2660cf6149fe12adeea17535d16e95038f23c","0x384f873d81a5d731f80a0707727e78150f455f5371e99d250c4c865438317869","0x39bace2e1faf0b5118a3be2bddfcc51e2f6ebe763b9b9e6af9935ecfc957a7e3","0x9968bf9c49afec7d2e7cf051c768d6449fe6f4c584b251a6ff843c7746b076ec","0xd29a7a5e67eff1e6104ed8984de58da25a23ee5dd759d80fd0021d0e73c3d406","0x758446fd04f04c5c580f8d1b6071e6bff33d67a40726f3859357482afd9f9293","0x02e2cdddf431c1bb4d10cc13c7867d8d5e604b70bdd9100a18c500c34877f05d","0xe0db184b098442ea2c26e76556b3f7af4ffa11c34c1e6ee39b0a882f7557cd26","0x1f609d9dbf86d674f22d93bb0d47688b3cff475680d2ebab953ec36aadad32ab","0xc3d79aabc793ac679261a343cd5702f4c979f534d89d0b4b00b65972545767de","0xbeba1496b81d2bb9c06f1f0c2ea16e59629b8c05d207cc0663afa208f743452d","0x28acf438f77db69fe3d684dec096d74eb4c7b419b3c8d65c6b3373a5706666ab","0x399ea33e26af1af647fa20f03791a5857cb1a7683f906e030777a123d9c50c13","0x1670cec5842c964925f025b07601d22019c2173cf90911ad3bf4435cfc07052e","0xcbbac283d4170c58f4d7f4fae0fc11c4b133d4ed136354e1bea4736b32220f1e","0x440528c529d924386b77527b79a140672796a755fbca8c497c98bc4b9f14cda0","0xdb4b4375f06fcfaccb7e16a8b211caa31e0900e1d1306ee223ea34dddc3dd9c7","0x465cec9a2a565f139190619d6172467161439dfad6953dff7096faf9200c13f8","0x1906c1aa056cfcea858ff1a560442cf8edf73c37c87f10e0acfad9ccfdd7280d","0xcdec80307ec0b778f36627413a637988424750c39a0d7f1d6f1e72a7c8ebc3e0","0xf279eeb6504229de3b3a3238717024503c74d717b2e8bea735b8c1d91245d308","0x6f1352967be840b2651cd967470a9700a2957689331dd425b06f4dd1eabcc2c6","0x98c26320cf118bb7ac0efe52a10d12e5b008d01c79375105b27c33dfa99a3acb","0x57524e0e9f1b36c1c2f1b684b3297d8fbbeb48fa0cfb73d53e86913849efbe3f","0x6ccee1ef3ae9021354557935aff4a2188fc3ff3eac74dd098f199d57be42f0fc","0x77245274cc95e8cca862b656a139b091db748d71e7ba725f9fb62f853ec2286e","0x01d57155d7e2b5769068b5d0ebe2b79c5e935c825c1f9394d31c15cd74eb57ce","0x9b812683207a9e895ed493ef96b3652278026c54cd4c45c45e6a58c4e284affa","0xe1cb09e8b24094426cc94044ae065d2445816f58091ac4c731d6f60a26b030ff","0xd1a39e7787f28514d694b1fdf4138260ec1afd0dc5e8b227f5affbba63202dff","0xde540710a5d8420b7af7d66ab5c7b5a0f7a8ca65bd12ed43a8f2f76583fbb5f4","0x2891945b74450f5272b2ef4a0860631acdcd9f3a43f44024e6b2da2d84cc96e0","0x00f5b59a0065cc39303b9e4795fd7a3146c88872c92daf23b62c1163328ff523","0xc46f39a441deb988f4f5874750b89d02a46ebbfa1b076751668a490a686f7a58","0xa4ec981b6bbf6bea2231428e3750a96a4fd2e88fe392bd7b9bcd128a5acf986e","0x0ce6e946916365e6e183a459e614d8dda6da6f0bff8c27261e763b31ac9c4932","0x6c982987bcb5285b8a2dd9bf5b0ad11fd9d9731ef514018299261626fe3e27b5","0x2e81866d489807990cbdb3ba207ba99fe19586d3c33cbd00c89352bd89477f61","0x357b51b9a081ea8ccc580f4d9d5d0f1aff19c817e8dc2f80dda96fb5ae55abbb","0x4352395fe3596197074b5bfd0525e26e7a9b09226454b1639aa4afca90b67425","0xea31f572d3d12d0ca6119b5d0bb90299de162d69c160248eb88e9b562e10ece6","0xa83eccd8193c8acdec102098d9dfa800bc63ff9e2f0ed4cf657740135b39ffff","0x11c9ea43918e04ee2eb81d7172b095eca1f51f66ac6a801ad9fe8f68521ecda9","0x36cb56905c616f7f25920efbcf8667384bc3ecabe54cd06216e02b1c09fc511d","0xf7b92d4fa89f4eb5e9929a198971bf78c689b3f59b3d8e6c6f19121d3d3e9ef1","0xe2f2e0dfeaf13f4b48e1b77789e3685db85fa8b440eebd7b0df48b14392eb0fb","0x547a5462e235657e9735d1c90745c25fc5ade0a346700b1479f1c4f3f777aa19","0x9efe99afde7352893354505767a3321ab68d03bb7816fcf7d41432e1c58a9bdf","0x1612f38b4d50af9b149bdb909b47f50f1c6e51877f7ce544ae0c0ed0b786b5f1","0x8f75557eb8bc30fe6d73b3bac604fc213544d9d6bc91d657248396f9d84d6248","0xfec7202862e3c9e507337abf1df29c69b79bd3213ec26bdb190e8ab93def24f6","0x9ec3bb4ee77b686018a916c711fecd831e0cf72d7083ab5c603a4844d4542ca2","0x107394bfbd5d863ec343d38f439e1235069f5b9e15e77d98f20ffa0f9efd2db5","0xde07614ec99fea2d583d5c162b71c8f672f542c7a47d3d92245d36faa9d2e2fb","0x757e42e38ec7bdfa62d298bc15f6c3b1b9c8b3fdf807ad202b23ab64638b1e67","0x7b6e2f8903befe1a9a43366163e2210e3504293ba1718f66cfaa8f04eed4f5c7","0x929ab21581ddfedbfa9f391e390ab8f398b6567e614d0c3e51f15c8babd5f24b","0x2b4b05bcd91636475b5afd95f68e1f98d7c57ead038b7352accaea3f00689435","0x6e9922b730896c42c5a769952be52af8f3002c1a441cdbed4e00c23304235549","0xf5a5d30614bc475d65e3eae8c8c46bc874c1b6366d38ae89070906b313e46d89"],"logsBloom":"0xde2f665ae7cb727d5f7fcbc2ffb49173d9bb9a9aabe1790e2e1fb2507f72bff1460745a5a63b6c78e60bfbf2dab7c7c57bc3bb10bbaa6d319bfffc6c11aaebf04e03cffe4c770e7fddccc10bf73cb2ebd68e783985503e34aa53ce4aca6fdeded63b8575c26ed62eb3ddfcfb6ba9bf1b023f36ee32d12728db55cfd5ed0dfef79b49954db57f616c8851f94fafe3c57cc561ffc52d45bdfbf7231e7273f7177feb86504e9fb1f6be7e37d1c4b814ed7f3d91c94838e7cc479ff7fb36b6f940dd4bfcb0e32e6e19b3d90ecebbda1bdfdc76d48266b56b6a73aaa75457c0b2ed8268faae44c127403250ed9fcdaed6b722f37ef75579beacc69093835c636f5419","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x9f07488a43cee51187acfaf324a7675d3810e4f604a591d35788fa456c4a37b1","extraData":"0x546974616e2028746974616e6275696c6465722e78797a29","withdrawalsRoot":"0x28eb7d27ca24bb5ef9da7de28fcdb06838abd26b3b9529e7a5fdb3579c70d0d0","baseFeePerGas":"0x19239e5fb","nonce":"0x0000000000000000","miner":"0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97","withdrawals":[{"amount":"0x11bde51","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8b","validatorIndex":"0x15929d"},{"amount":"0x35d83ec","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8c","validatorIndex":"0x15929e"},{"amount":"0x11c3165","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8d","validatorIndex":"0x15929f"},{"amount":"0x11c27a3","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8e","validatorIndex":"0x1592a0"},{"amount":"0x11b6210","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8f","validatorIndex":"0x1592a1"},{"amount":"0x11b89fe","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e90","validatorIndex":"0x1592a2"},{"amount":"0x11ca1d7","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e91","validatorIndex":"0x1592a3"},{"amount":"0x11bb0ab","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e92","validatorIndex":"0x1592a4"},{"amount":"0x11c576c","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e93","validatorIndex":"0x1592a5"},{"amount":"0x3cfa2f5","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e94","validatorIndex":"0x1592a6"},{"amount":"0x11bb3b5","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e95","validatorIndex":"0x1592a7"},{"amount":"0x11b8745","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e96","validatorIndex":"0x1592a8"},{"amount":"0x11bdc4a","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e97","validatorIndex":"0x1592a9"},{"amount":"0x11b6cb3","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e98","validatorIndex":"0x1592aa"},{"amount":"0x11c29ef","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e99","validatorIndex":"0x1592ab"},{"amount":"0x11bc261","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e9a","validatorIndex":"0x1592ac"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x126b00b","uncles":[],"parentBeaconBlockRoot":"0x32183d6291e5f55aa67377a4a1bd2c2772192fd720d9880ae58df27d41c1d86c","size":"0x1a76f","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x868e868b70c53463e7762a56dc769448c365d2a5e673935eb0d9a8f61afa6bfb","stateRoot":"0x25e32f3be27638d39979675fbf041c089068ac66184b5ffb20c57e244d05711a","mixHash":"0x827b17bfa1d9627edd6397ff66376e31aeed366f9d6b52be8f82d6b81276f44f","parentHash":"0x1d49a3c0bc37f56fcb49f5cc457a65d28b32b4208403aad49371a715ffdc50e5","blobGasUsed":"0x40000","timestamp":"0x6687db3b"}] +{"number":"0x134d6ba","hash":"0xea53668c4b92ba05c647ea3eeecea693115e775f028b7c1e3bad98afe60c1714","transactions":["0x10baa77ae90bbb5e0807753270a2cd7c1f1e3a49fc75147b9a88ae48266fbaca","0x77d24c7cc1926bdd6abdd67be8702f35b6fe426eca66f2600eadcd25e6bc8703","0xbf27555961012f41458bedada26bdac910f0d312afdb21274e6c0de6cc78ff94","0x3eb53d0c7b5a1549e40221f1862695f577c626480c82993110d020862ef324e1","0x386e5b6d2ce47704cdafd673a76fe8135f3c2056804a52d39c052ce13dcf8613","0x0f89b4d12682ac5743e129f9a047800c6e50776fa3bce1c813cf5c292c3b2b0d","0x3fe7460edb922780ce85a7549c3ac85446a6c694793aa8133e437b5bcf06a378","0x726cc27a5888b23e9a242b7af92d55666afc74f58f18ca0b9a731e3cbe7b6be2","0x54a4c143966f32c7cf6c3b7d4bf527f12cb8083fc6abaf10cc8d5dcd66949973","0x12e2ada283210d0a191c577b305212bb767b4d9f24a715dd078aaf993ed6daeb","0xac75df8c1b2a3baa88a489847bfd0812ad43b3df5306816f3b7fe6b530a0e0b1","0xb80ecd4058cabd710abd7168df90c0c1074955a72017d0576f39587796058b78","0x4b873cba45ca049dc9c54aced8c85484a6f4dc0479349f166f9799aa55731ed0","0xff1f1da5ff35ff6ceddbf8af4836642ad7c432a2dcd05b2d091cabf568fafa91","0x5396249894a92c61ee03437f583df3abeaba49066fdce4d7a424f4106ea47e81","0x31b014a918e48373e058381f25ec70f767525a54e6a45e4d4e4eaa700c55fce1","0xe933e99cfdafcaa300fd1334a99a18eb8ca99ff00647e82246ae1547b154205a","0x3c02338348d916fb192d9ceadb8c291677e5d9f9d8a057fd3451183bf8d1db35","0x1affe87eb0739605fecddd51d2710491cb5274f7a1c556555c8252a2de3b98bc","0x62d8051d4d588fdfca1bbd86d8710e1fcf0c104ac823a501fb75cdadaf387363","0x71a4b962cc272ac70cb55f442013c9b2417541719dde483cd723adf1c97201af","0x3ef1cf8f935b3403bd55c0400f70d0c38ec60f8c1d436dc369d200cf64436377","0xc5b5d3e42f6e190f7e1c3a6c4e3ad8a88a4d0eaf990aecfe8313ecef5e9a9128","0x35b9e8138d24392e5c468f5fb9f045a55dc97df9ee7012869482f8eb76a2ff95","0xebc1b559aff8b1169c6aa9157cdb58f670aa37aa91b975ca5c85006efa0ad2be","0x09fc8f0bde542bc39a48b3ce581ee1e838d3c2f2c190a4f345106e41f5daed9f","0xef49e0da2b7eddadb3c7a965c8f641d70cb7c610f485909151b3c06fa857a518","0x874b826ce0d5650cfa5362f1ceaf74450c717efde705cf70207774438371bde2","0x88d95f46d2b7ac417547ccf0a2bf69ce416613ac8c3368d76cb30ca612264cf4","0xbc681b4df99190ae4cd4dc275d1b904b4818631274540e55bca51281483553d5","0x5b54f41876cb3cbc485b03fd94b52da8890c9b8bf5266d7b8ab975299cdd9b07","0x91d878fc932f13234e2e04f73c4499c6adb7a96113479de34e8d4d6cd582e135","0x2ee8dda8d5a4ab8222d48f608af256ff5b76e321f5e83d4bc226a4ec6473b13b","0x75774b82857238ff577c92b7ec3d2a1ead2c98b5cd71939a913565f1cbbd03e7","0xc3c996a8aa60218995539f3889c715938f367cc954d4440e105060a0d67851da","0xca71b9732bcebd82fd2209076aa065f0503938cd950765fb84e19e1d9adbc603","0xc16c7be2ad78299e0557c554ed69404cd4ba95c2130239eac3d864fd2ee0d89f","0xdc9f750b6b20ddde07d36ec8c54827db2b18ab03372872b7566fca07629e9154","0x2232c45b71c80f53b508f9c45f20c246531e84978aa15968d902716425d4917d","0xc236b6f0458d5647d04c0587fcb443c72a2163fe6b3f18440ad983616374e5b9","0x2720e362091731118f26233c9836bd20585b2c257291029d919ebc6ba65d3735","0xfed2b19d1ccdaf10431b470a0258728cf741095a67675d74f140dc62a7f65cb4","0x00f38dec524f4f63181d6bb93d9ad409396973099e62cbbcd85b323ecee4f428","0x1a0e9585365d26f349cc65d6abeb46e7dc7a1a555d032c89ce1b6453dea9671d","0xe447be5cbfdbfc80884730c315da1cb383977de39b9123cee840688f4c2c28a3","0x2e6e2d10a00d84fd99f566aa1dd99f2a7b18adb71ad9ccd065ea93c46bbca7a2","0x5324cb46e39ac05b71e7133abf896421efc63808efdc482c10f94fcc91c01e5d","0xd98710b2e278015f2708fd350a99720eeaefe5dd63d7cba4da75b19ac641b358","0x80d47003d915faa7f5ce9bbd6f07e0755ae3e0a658ff6e395b283d0172f5bf0d","0x4cb1a391f5b19321d94d27c3d63ce64cdf475ca90010339cc9c0f5e13a5928a3","0x6ddcad7af6f7ff28e831e84e5e80491e7eebe8188f360b0e434cb9fb956b9576","0x24b2e8db688cf6e2e917e9c076c00372d1adb446bcb5965dc275d185cf6aeab7","0x0e0706dd9c73d3bc7e3fdb2b387107538e6346caaba24681343f4aef4a2173ce","0x68e345e1222ff5572f669058f3a7aa6486b0d93f8802a59230c8779752a13333","0x59513960a1ec9b050d5afd5f44573434fecda4063cb5fef74afd49f7cc2c07ec","0xd6b8bc16304f418e5b4d522fa5ed1382fdfb17d120504550d56e98e540a794ec","0xd22a565135512654cb9cdedf4872171f3cdc1ee5e01db63ae9daa29ecec25715","0xc850ac5666def336b01091ab11926a852ade6fa6cf4eb266a198abe570859baf","0xa7725d08276962aee9287c922e07622dd7f2f8e5e52d55a8cf0c10507b0952a2","0xeee01015b80e1b5b2717728d390fa5f44bceedde7a0f5dcfb1f90defeddd5a0a","0x2cf289ba14235df97bd0b1c1d9e010103581edca9dcba2c3e132324edc447ea9","0xf845efbe35808ab9f70af15d1b795285cdd49267fe6fe7d9545d7d93ab1c73fa","0x6d55e82e7c3452eebadd71ceed1b7b354f41f53fc5965a098143ed05750a5003","0x525716fec0f78fcf2282a4d919364d6c07b3741b3a202d5ff91ff27bd0d08def","0x7268d21087c95dbd95da156406b23a11a471945c9755cf7809d3b1b7a2fa55c2","0xb7881dac0a2b3c2a08860dabb2b405d7c1b11cc587c5eefd6392cb060aab3ac8","0x39f6bf42069184a39c1419961fa950d257eb06d0590901aa17b77dd48ffce25f","0x48d03398da8e7d3761ed077731238c0e49bdafdad01882c3502cfacc39e02f71","0xee8b4074d8ad32fa7d35d65d7cf9ad679e0d48cda98a5afef8cc4760dd9b3199","0xe974917ba0cb0ee41f0c4a51a9994cf325275b84de1ff43eee039fcab2c68c2b","0xed565eb3c53274d8454837145a4ac2ae8c04b7141817062c02c3dc65b5b052f0","0x08f8b93e429e9fdc516eff22a5c9d6b65ef97f426cf10355f37b3d34ccb0a98b","0xb005ede15def2e558811dcfded45063fbfdb9353545ea8c25339ff34629ebb2b","0xf5bcbb9071b56246fc1e9e6eed234a4732ac6a47a6ee8855e0864cfd48b6bd1a","0x384c0b9a378a3a45422f2494b945d7f61359bf42c82fa24958d0ee949ad99209","0x8792746825f7744b105c9a60d46aff76064a88e7d3b10f1362605c2bf191e2fb","0x2cddd834594a187bc5c366fc3dd182c18d5500450ecb0afe349062921486bfc6","0x2d50abc7283174efbab8b7581a2b16bd9f1b540fac2377868c5102b659881a2c","0x746be019b3f29ee14030012a22fce027327c933ff03a1a1d47517d6a57965f51","0xe47a41aae99976487b7861d80bb805a79f6f82478e2e518e6179f68ba9b42b31","0x37ee8ef168c13c050174e99e5e3307c8f9f2bd8f7baf2ece14596c39bfeda4c6","0xc607251204ea412f33ca9967b31e742a56c84f37e77a634c8ddc9720202c8ff6","0xd57584bd4f4d8d2758fa56fd98fb00f71780d1b441b5100a28c2720c0f2cf47c","0xe6e64b5de0a9c5a5d0a9f60829187ef8fb1cd1450b3decee82d764c6b4b47e72","0x4840d343f17b6af3491da5b17eb814b4c0861f2f6565f727703f4059aa9e0a31","0x2982540ab35ad428ff6cd55611c3c63c70e6dc4eeb65adb8e4f6daf0629899a5","0x1974aa5c6ae0de183cd630431921bbfed02d242fdc2fcaf61d263d738329895a","0xb63fab5abc247582f6873ad9bb71674e52a0f84ae8964d73c65c5a49a47f4a4b","0x511373f5bf71db16feaf4bfae68ce3af071b6c8e0b0da8b9cc202e83129a9bb9","0xcac4fd8b34138af38dd1fb5643508f37ce7e1ddfe2616c681e0d5c13a594147d","0xb5a5b55502855bd77a6e2b0e05771365bbbd4c30dd552fcfa638d7e896100a1d","0x4b28388c454889248e39ede01790dff88df4c206771fc3f203edccb6589a19b6","0xd31018bdf2c850549e89ad32a74d03ed66a372cff95ba7f386fac51b09f15b31","0xc2357b735a078287707f89b2a129568d9656e34cb6c11f9cd32e02a7d10c9b58","0x62684c02698bdb752d100e3237f5f8baeefa4b2871341a258ac5b6aaf23e8997","0x288cab54801a082ab3f34e79ce775810473ad46716777a19d64a832252db3eca","0x9c03d9019d1581a6fa8fdca0d9729305b111206510b8afeb4d292bfe3bb5011b","0xc117516a08df8a4f910536dd277d65c99c31a28011486ec1ecbdd0ae398b920b","0x9dd43e24e8df009cae824eebe27b8b4197a588896b6af22c4f69aafc57ba0aa2","0x96752d10ceaf86cd13d8d1958be1722d73f48272f9a25acea6c05976a208453f","0xee5490a31c607ba2e7c722095fb3df4e78d8d955a11f51db76a5b19c4d986b15","0x6f75ab1e059f61dd7cb3bc850d9e74a09c079cee4545873c26d01f3b3c35a189","0xa2c022b754d237e61da5a5bf43f0689960ab9cb88b078cac92750293d456658e","0x6c14f1f209b216d853f79549face498b87a7b65e393408181eb953ecb106f685","0xd7fc1912f1d55a0b69844c753949a1382afe642f8c3241c8b9d2dcbc0ee9c8a8","0xa60d1c8ce457390f0b98eef052cc50c8f239e3abedda3141228041b23049c868","0x6604e2160f5dedee6c5649a6fb2099d129a8254984c12e37183654630a5d45a1","0x6586195f7a0a5066849f975cc1046a9d5acf380ca97e10675032fa541b025455","0x0fd528ac75228717c50bf1301c629f031866b41e82645c35863aea79f028cc94","0x4c4686359b8fbd8299f4228d94fda2fbbb8cc517216e88ccccb864d4d8572f20","0xeb448c538c0945da91b490d0a59e05e376bb9a54b417f994f4ede53cb9b9f1b8","0x0c04689b4bbf1a97ecd907316fbd68d8991861683f02bea93193095b7623011d","0xa11ac8f6306c1f17764edfeec331240e0e14fb62741a4a5587ad56ed3e27a9dd","0x5207d8f111587146689fbae84187265753efac48f897301554bf28a0bad35f11","0x7f9fe8a0c25b3a3aebb2338efbcca8507a62bc333ac1acf9aaad9f5eb8d5bac9","0xb66bf9556a9cc63af9e9fae9dbc1161fbbc943ae2beca33b275bdfc12a1272d9","0x4ca39d13b8c40f8160d7332125bcee201d2fe2e98f29e342481a86a97ee23701","0x49e1c6c7a5f72ce8aaf3f71b2fc94bc87b78b3c092a13ba1542e542c415c5b24","0xcc8111473c669a1a23dd48017538b6f2062ba6b20611f94d5d91b540f2b63708","0xc0944eaf281709f025830f99534f4d852563e4f3ade385e170cd85ac6502fc9a","0xc4080487c0e97dcde9a4c4223fb0b654f6e7e617c5444d14692872d165b346aa","0x029b0ac5bb4937aa82f786b559c8f5231e48ad5339026a365a9791be7a782065","0x88bf20195821a0b25565d1a8a2a56836c8880b2dfd385de91610ff374fa63cfa","0xf1ec225976bce5f4fcf1a855e3a6a36d23556d161a0a6b941fad665f2b245d4d","0xa0d3a7ca1d9940db2cb63c0e65bc7e68599c6d995816e1fd337b7b637b2931d2","0xe489a5a7c85280cb7c2064309f6c01cf1e6e0f63e14952587a3d998230d639d8","0x0ff21c69a9f0f7a91ec9f499d2228458a46c3d57d795c5cf0730b858713c0abd","0x03a1540d0095e65d250f5cf0e5f2b136768e00193926ad3971050b48f31a2369","0xd57a95ff6ef9b56207634cddf4d2660cf6149fe12adeea17535d16e95038f23c","0x384f873d81a5d731f80a0707727e78150f455f5371e99d250c4c865438317869","0x39bace2e1faf0b5118a3be2bddfcc51e2f6ebe763b9b9e6af9935ecfc957a7e3","0x9968bf9c49afec7d2e7cf051c768d6449fe6f4c584b251a6ff843c7746b076ec","0xd29a7a5e67eff1e6104ed8984de58da25a23ee5dd759d80fd0021d0e73c3d406","0x758446fd04f04c5c580f8d1b6071e6bff33d67a40726f3859357482afd9f9293","0x02e2cdddf431c1bb4d10cc13c7867d8d5e604b70bdd9100a18c500c34877f05d","0xe0db184b098442ea2c26e76556b3f7af4ffa11c34c1e6ee39b0a882f7557cd26","0x1f609d9dbf86d674f22d93bb0d47688b3cff475680d2ebab953ec36aadad32ab","0xc3d79aabc793ac679261a343cd5702f4c979f534d89d0b4b00b65972545767de","0xbeba1496b81d2bb9c06f1f0c2ea16e59629b8c05d207cc0663afa208f743452d","0x28acf438f77db69fe3d684dec096d74eb4c7b419b3c8d65c6b3373a5706666ab","0x399ea33e26af1af647fa20f03791a5857cb1a7683f906e030777a123d9c50c13","0x1670cec5842c964925f025b07601d22019c2173cf90911ad3bf4435cfc07052e","0xcbbac283d4170c58f4d7f4fae0fc11c4b133d4ed136354e1bea4736b32220f1e","0x440528c529d924386b77527b79a140672796a755fbca8c497c98bc4b9f14cda0","0xdb4b4375f06fcfaccb7e16a8b211caa31e0900e1d1306ee223ea34dddc3dd9c7","0x465cec9a2a565f139190619d6172467161439dfad6953dff7096faf9200c13f8","0x1906c1aa056cfcea858ff1a560442cf8edf73c37c87f10e0acfad9ccfdd7280d","0xcdec80307ec0b778f36627413a637988424750c39a0d7f1d6f1e72a7c8ebc3e0","0xf279eeb6504229de3b3a3238717024503c74d717b2e8bea735b8c1d91245d308","0x6f1352967be840b2651cd967470a9700a2957689331dd425b06f4dd1eabcc2c6","0x98c26320cf118bb7ac0efe52a10d12e5b008d01c79375105b27c33dfa99a3acb","0x57524e0e9f1b36c1c2f1b684b3297d8fbbeb48fa0cfb73d53e86913849efbe3f","0x6ccee1ef3ae9021354557935aff4a2188fc3ff3eac74dd098f199d57be42f0fc","0x77245274cc95e8cca862b656a139b091db748d71e7ba725f9fb62f853ec2286e","0x01d57155d7e2b5769068b5d0ebe2b79c5e935c825c1f9394d31c15cd74eb57ce","0x9b812683207a9e895ed493ef96b3652278026c54cd4c45c45e6a58c4e284affa","0xe1cb09e8b24094426cc94044ae065d2445816f58091ac4c731d6f60a26b030ff","0xd1a39e7787f28514d694b1fdf4138260ec1afd0dc5e8b227f5affbba63202dff","0xde540710a5d8420b7af7d66ab5c7b5a0f7a8ca65bd12ed43a8f2f76583fbb5f4","0x2891945b74450f5272b2ef4a0860631acdcd9f3a43f44024e6b2da2d84cc96e0","0x00f5b59a0065cc39303b9e4795fd7a3146c88872c92daf23b62c1163328ff523","0xc46f39a441deb988f4f5874750b89d02a46ebbfa1b076751668a490a686f7a58","0xa4ec981b6bbf6bea2231428e3750a96a4fd2e88fe392bd7b9bcd128a5acf986e","0x0ce6e946916365e6e183a459e614d8dda6da6f0bff8c27261e763b31ac9c4932","0x6c982987bcb5285b8a2dd9bf5b0ad11fd9d9731ef514018299261626fe3e27b5","0x2e81866d489807990cbdb3ba207ba99fe19586d3c33cbd00c89352bd89477f61","0x357b51b9a081ea8ccc580f4d9d5d0f1aff19c817e8dc2f80dda96fb5ae55abbb","0x4352395fe3596197074b5bfd0525e26e7a9b09226454b1639aa4afca90b67425","0xea31f572d3d12d0ca6119b5d0bb90299de162d69c160248eb88e9b562e10ece6","0xa83eccd8193c8acdec102098d9dfa800bc63ff9e2f0ed4cf657740135b39ffff","0x11c9ea43918e04ee2eb81d7172b095eca1f51f66ac6a801ad9fe8f68521ecda9","0x36cb56905c616f7f25920efbcf8667384bc3ecabe54cd06216e02b1c09fc511d","0xf7b92d4fa89f4eb5e9929a198971bf78c689b3f59b3d8e6c6f19121d3d3e9ef1","0xe2f2e0dfeaf13f4b48e1b77789e3685db85fa8b440eebd7b0df48b14392eb0fb","0x547a5462e235657e9735d1c90745c25fc5ade0a346700b1479f1c4f3f777aa19","0x9efe99afde7352893354505767a3321ab68d03bb7816fcf7d41432e1c58a9bdf","0x1612f38b4d50af9b149bdb909b47f50f1c6e51877f7ce544ae0c0ed0b786b5f1","0x8f75557eb8bc30fe6d73b3bac604fc213544d9d6bc91d657248396f9d84d6248","0xfec7202862e3c9e507337abf1df29c69b79bd3213ec26bdb190e8ab93def24f6","0x9ec3bb4ee77b686018a916c711fecd831e0cf72d7083ab5c603a4844d4542ca2","0x107394bfbd5d863ec343d38f439e1235069f5b9e15e77d98f20ffa0f9efd2db5","0xde07614ec99fea2d583d5c162b71c8f672f542c7a47d3d92245d36faa9d2e2fb","0x757e42e38ec7bdfa62d298bc15f6c3b1b9c8b3fdf807ad202b23ab64638b1e67","0x7b6e2f8903befe1a9a43366163e2210e3504293ba1718f66cfaa8f04eed4f5c7","0x929ab21581ddfedbfa9f391e390ab8f398b6567e614d0c3e51f15c8babd5f24b","0x2b4b05bcd91636475b5afd95f68e1f98d7c57ead038b7352accaea3f00689435","0x6e9922b730896c42c5a769952be52af8f3002c1a441cdbed4e00c23304235549","0xf5a5d30614bc475d65e3eae8c8c46bc874c1b6366d38ae89070906b313e46d89"],"logsBloom":"0xde2f665ae7cb727d5f7fcbc2ffb49173d9bb9a9aabe1790e2e1fb2507f72bff1460745a5a63b6c78e60bfbf2dab7c7c57bc3bb10bbaa6d319bfffc6c11aaebf04e03cffe4c770e7fddccc10bf73cb2ebd68e783985503e34aa53ce4aca6fdeded63b8575c26ed62eb3ddfcfb6ba9bf1b023f36ee32d12728db55cfd5ed0dfef79b49954db57f616c8851f94fafe3c57cc561ffc52d45bdfbf7231e7273f7177feb86504e9fb1f6be7e37d1c4b814ed7f3d91c94838e7cc479ff7fb36b6f940dd4bfcb0e32e6e19b3d90ecebbda1bdfdc76d48266b56b6a73aaa75457c0b2ed8268faae44c127403250ed9fcdaed6b722f37ef75579beacc69093835c636f5419","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x9f07488a43cee51187acfaf324a7675d3810e4f604a591d35788fa456c4a37b1","extraData":"0x546974616e2028746974616e6275696c6465722e78797a29","withdrawalsRoot":"0x28eb7d27ca24bb5ef9da7de28fcdb06838abd26b3b9529e7a5fdb3579c70d0d0","baseFeePerGas":"0x19239e5fb","nonce":"0x0000000000000000","miner":"0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97","withdrawals":[{"amount":"0x11bde51","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8b","validatorIndex":"0x15929d"},{"amount":"0x35d83ec","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8c","validatorIndex":"0x15929e"},{"amount":"0x11c3165","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8d","validatorIndex":"0x15929f"},{"amount":"0x11c27a3","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8e","validatorIndex":"0x1592a0"},{"amount":"0x11b6210","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8f","validatorIndex":"0x1592a1"},{"amount":"0x11b89fe","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e90","validatorIndex":"0x1592a2"},{"amount":"0x11ca1d7","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e91","validatorIndex":"0x1592a3"},{"amount":"0x11bb0ab","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e92","validatorIndex":"0x1592a4"},{"amount":"0x11c576c","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e93","validatorIndex":"0x1592a5"},{"amount":"0x3cfa2f5","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e94","validatorIndex":"0x1592a6"},{"amount":"0x11bb3b5","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e95","validatorIndex":"0x1592a7"},{"amount":"0x11b8745","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e96","validatorIndex":"0x1592a8"},{"amount":"0x11bdc4a","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e97","validatorIndex":"0x1592a9"},{"amount":"0x11b6cb3","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e98","validatorIndex":"0x1592aa"},{"amount":"0x11c29ef","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e99","validatorIndex":"0x1592ab"},{"amount":"0x11bc261","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e9a","validatorIndex":"0x1592ac"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x126b00b","uncles":[],"parentBeaconBlockRoot":"0x32183d6291e5f55aa67377a4a1bd2c2772192fd720d9880ae58df27d41c1d86c","size":"0x1a76f","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x868e868b70c53463e7762a56dc769448c365d2a5e673935eb0d9a8f61afa6bfb","stateRoot":"0x25e32f3be27638d39979675fbf041c089068ac66184b5ffb20c57e244d05711a","mixHash":"0x827b17bfa1d9627edd6397ff66376e31aeed366f9d6b52be8f82d6b81276f44f","parentHash":"0x1d49a3c0bc37f56fcb49f5cc457a65d28b32b4208403aad49371a715ffdc50e5","blobGasUsed":"0x40000","timestamp":"0x6687db3b"} \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json index 208deb5bf..25afceede 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json @@ -1,4 +1,4 @@ -[ + { "block_trace": { "trie_pre_images": { @@ -3342,4 +3342,4 @@ "checkpoint_state_trie_root": "0x349c33a12c9ac7fee19b759a1aff095d5d734fda61db4295bc8f783b345f10fd" } } -] + diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json index 14c6fb8bc..aaf7ac96f 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json @@ -1,4 +1,4 @@ -[ + { "number": "0x13862fa", "hash": "0xd130f124c32962894a74ce0d07fe5b2fe081a2ac5659df122a309a10b87cd2cb", @@ -197,4 +197,3 @@ "blobGasUsed": "0x20000", "timestamp": "0x66b2a627" } -] \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json index a51aac3db..9e263fe02 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json @@ -1,4 +1,4 @@ -[ + { "block_trace": { "trie_pre_images": { @@ -321,4 +321,3 @@ "checkpoint_state_trie_root": "0x106d584f6804109c493182d0bb8ef06380aea582090f4c2927276869a8d1e436" } } -] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json index abf62be05..e1247d601 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json @@ -1,4 +1,4 @@ -[ + { "baseFeePerGas": "0x174e475", "blobGasUsed": "0x0", @@ -29,4 +29,3 @@ "withdrawals": [], "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } -] \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json index 46ed3e6c9..994c1a06b 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json @@ -1,4 +1,4 @@ -[ + { "block_trace": { "trie_pre_images": { @@ -469,4 +469,4 @@ "checkpoint_state_trie_root": "0x765b89dc0bbd05503b9074455cb6b1f65f23147cc2f7e7f6cd56b262569ce02e" } } -] + diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json index 1aceefbf7..20c3c657e 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json @@ -1 +1 @@ -[{"baseFeePerGas":"0x22f4b3ea","blobGasUsed":"0x0","difficulty":"0x0","excessBlobGas":"0x0","extraData":"0x","gasLimit":"0x17ef641","gasUsed":"0x2625a0","hash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","mixHash":"0x147c45372cfe0101a4898b634160af19063e603c11d7c6bf63457e31e8ca81a7","nonce":"0x0000000000000000","number":"0x4","parentBeaconBlockRoot":"0x6ee1f74e9c9bf2a28a7342e4ff7866c37c97ce2a89f95a875f351d786b14d323","parentHash":"0x8ca953b07297729a687b40e05bf17c2c4db4e0f53c3683308b50467724485ae3","receiptsRoot":"0x36832caba1c5339c7a9ff4e63a03149d5b5de5bcee60eaac6d2a21f3a7d88b00","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2b5b","stateRoot":"0x038e7e3c67c9166523c4b2bae746f5d7cf72480af4294bb900f252faf05d04e9","timestamp":"0x66964056","totalDifficulty":"0x1","transactions":[{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x7656fbe97bca00617166f052d7c2bf678249767efe2d58699b437b64979e5122","input":"0x7d877b065e1ddb12872b21f5f4de038b91f077f802d40ae712b1072515259b7302e7a43ef8bdc60dceda1e2cf2c5f6dc5630e87855642dc7bfdd125c15476bfc17bba053f7bbb13b66e4907d00d8e968b6d30283e23c43e883ad1939067ca414f58888d9f32332a3b63473e5e6d6bd31f6914447a4566d1d4afcbd54110b4091903d3a76f94b7dff9f73f28bd04bf374e6dffc49c49e2750211a2a441c641ac30e12f705057ac95cdd9faf3f6b221ee0108fc305e3a33e10900db88f2ea0f0cdef6beb22f898d8de3f8a472e932e9315383a349276338bbc8b7a4ae5b3c5e62dc521cd4ce07fa69a4ced73f51533016f253b6a59d97f8e583b9ac1ede01e4ab64587873f929817340b3663653075c57f0272a1ccd3196e4df246d0f908a33eb6a224444bc1a9f062128aaf7bbbb58c716b0eb64dd0a51162e0bdfd8dd47c18c28ea5e179a03358a31435f4af590a636dc4972fd0fcaa5627e713b1811b53608760d1477eebcf65536a6d57076acfd4f6bfa729892d14ec6c7fa8a9207d9d60bf56c6ad7edd2de9f8223ba4e2bc7df194dd41bc109180a1390ea1a68342b64f05166d325913176a37b05dd46d09604217094a60d555147eff53c583cf904662898844d05a37dc7eff4ab537ac138d066d4bb7af4212925463fdea1cf059126aeaa9794e679b6f38311a9c63196315d1165947116ad759c2f0aa148f30074c214070a74675e3326b11566505c6013297e40f2c8392346ee33e81a26b978a48952b0a754e1347543f6a37d407ed6722ac724a9a507c4916251078d7af4627cb6a0ac24f311a5042798c66cf3904b81381c93c60374912545f7011df013e31a8c7a1cdc2d44372d016431b371a0463d54be2751a3d351d40700e5129404d3f76331c72f6b3255b270f826181b46fec687a29ad18b8226004774b78a4b37c1a5e6a499ae6d8d24b780b56950970132e6f90e28a2cee18a7121d4287a26e6b596d45ed322af4e4bd582e2cbd148852927b522f63d6b0c18033ab44ca81c1a543161615dd31c70070e7eae6bc706a2de10dc395f4c39b632a75671588e91195e604e45f445d3070a0a95436c8b6c5fea9defcc71fa59e3dbc33147abed46c83313a308a746c5689da0699db748fd0f4ab894053e584626b0ff24821fc7fadd2e988894504404463e9e758754273976124a360ddb9a4c11285ac798248659f5868094152748e64b9a3c928123722ec84d417efc8e619a5c4366606607b82307dd8b9bf24f1f7c1f25aa931bcbcfded75bc1e2a575a1f782773768d5adc2d036a4bba4518bc068c47030bc65f6a13252f29b8168fd64957211c6e11b752b1f4144b0ae905d821a935d55a6f6e49c96a8300905615efacebe94ae4bb956c4dd84a0f8b53cd087888d356e160517109f6151359d245488c918847aef5527beca916770bdde14ee846cc22542e62b9db5617db816edf58a373f41a18913344994745739e12fcc980ce06ab4a05999f1fde39c41dfaae47087c1512c75b71cdb23b572730ed055dab87d307f11da0eeae0bc671ba994c3f35718e8f55bb19cc50e03107f33bfb647891f463390300","nonce":"0x2","to":null,"transactionIndex":"0x0","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x283977096b0fa526e636c9ef2a4f988d71354afbb2b9f39200bf2d9939173021","s":"0x3f384055facc74f5d465b3d6600b7973d7a2fd6888f1676dc2836cf1bdb70ad7"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xf5bfe3c2772f0eb210ae36291ac3a1c2612de813db636967017d385ed3f61331","input":"0x6281730779f6d4e88d5c0f26c588e39464798d0e09d6d146ad2d2cf019e5b03f757f5222d42413a1854986a62791201822573bf0b584958116665b8fff83a5aa6d5b677db32c7e35af172e0a6ccb5b6aeb93ea07e199e36fdc647ec500249255bb4dcc8071166debd343ee52ada0f071c81fd4e0153764325b876bc36a46235b798471ca5bbfab1b7437f98e64ae89ec087ca98bb45344142d659b8c16e80a506e72da543eb31bae4fe6a86ee8e4ca6a5914403f5f65c941ef1806b30938903a086d6ca24fe1a7bf3ee5936fac73f6335f1831803550067fa731c9e26a5582dc3792bde1c3d2ba9f5bb03775638cd8ee38fdad626aef958e3f5b65e9c5e215728571b4b3db781f13a5cf5588639944aadf43e4270202175b6854c6b8b248d1e1691161eb025890756dd29827592cb1852236b020e82631eaa6d8d21f9807198259805d3d68f0485ab07e2e6c1ef97b9b0a1781584a676a71a8f6ee7d2f20e2bbd75bdc0fb8bef831515da4787d6c4a12c2ed00fc292387d8c1f284f7926774b3d92895bc7f023d60c93f845571814311568810f5d78742360266ef1f64112b3542724877e14348e0062400379dbed5812312a8eeeb46843d634a1876cf5b49a46c2ba8cd9a3f3b35c13a55645ef3945145361d070938537aba4f5a9135bc16146be05c42421816f5122a6b42489b3cfeac24eb708e6ed0537e5aa9bd41327c7a5eed3741b83b70ba81bd5dd3a6b9cd1d67a0cf7654b5fa4aa05444360965c202effd4c493283455c5548453e747cdc0772d1422b06dfa128e967a9319ad09fbae0d81166ed70237c838f275b4a3b668b12aac2afd6e5733436e0a455e7c67450988a4b20ad0eec20d1eb5b764171b25fc048261ea2cedc8e4da6ee5aa5f11d9f9bf67614363a6226c075905f704fdd3dcb81f1db2dfc697cb45a797938a44471069d4a6976c485eba5a6cb643901d2aa4dec96193d83593684677568b6bea2929090123109123191707d93b413cee3cbd6a88b07e9ca17207e357de30e32f5f8b989a810b3d7b3a24da8f73ab1a35c81450f3c0b9eaacad4611109100100","nonce":"0x3","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0xf7a4dd0b626d2fa57e6e3edc804fecef9b367aafc239ecd8aabcbd917d73fe43","s":"0x6780e0f00ba63a8e9b86888d169319248c186e313516c62bb3ce35a736e93a88"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x21ae9124df7c63aae240083d98b152f1e71bb63b31cd5e8b2927e7fce841c1a1","input":"0x5a6e78adf9e9c860090527daf5786ef962077bf962f7156d7620dc0c8f6cc19a1d9063cffd426fdc040f0f9b3474af111945173d8091157925a03bbe35662a8b5c7e7282a5cf05014ae32e5aaf51c4440d1709811c353b3d306d7d1ca284ae95773ddfda82302667501b01647b20ae9c8770b6065442d3df94925a314b0f7517ea43de1b067112a8cdde51c1be9d622612cff5cd1f5e361a7c3fdfebf14c15967b526de0d94e33b2c7b8ed15e40a7274fbbf49d2acf1106236b710732b6b01ec732c4290df6f262a73b989b21f3e79093637423d6c956af497051acacfb61b73169975ead207fac61be7e1b89410f38392fbe639efe9c0ae4a817d3bb53994df71826e55696aea8dde32418d46215ed66dcf1ad4dd206e149573918e63fdd5e7017185e1fae415d17d0ac36c088f44778d52900812c606c8c65d889a5e280730e2ff0a62c2424922387199ccf61ea3f8e950eae428957f2a6bb6f94e31792a17ed550aa5b128a0ba393263931a2f9f556190704db80be47084996a67b3b9145810fa41f371203334496cc5fa6355cc75e37d271be63e290b1668ac5fc04a6c85db2d928473dae050e5d0478b40656acfcbb32223c1145decce504a639e837b0314730a1ce5670c21ebbc05423e357cf537e345c4109c805c086c51574cd3226261df76c4a4a39a137c8b087db775847b8684b3c20ac384ee4d4225a133d922e0f93a30d1dab2904640076f6b1952877021ff81ec9e94b0e2f6332082816d7c3097b99ea4c163368d6c0e3f8c1948331a497f0e049d679a1527ddde74350fa3a20df460308237e771db53670559375ad1d06833507f57fd63b05727d4e401ef39e13c471149984d98c7f31adf456a1e42e6c8c2a160596502c378d3064a4576e8bbe143996f49f344897194145f1fa60c62cf66df6a8e31157d598c35ad06e7a46408fe2f893a8deda14dfe7ebc56fc0c61368fada78fca4a764496c68976b9067066e678fd4eb3cf9e113a2a36cdfecc7ded22ae3b074b9b8c661e4d212fc6dd3ff8c46c9fab1b2d6eebdfdcede05c0543554a7948d33ead88a2b15c13707534db5fc93d7e9d14b1ce0a418e72898273d45bce6ae6d5c127ec5e8c5f4dddf61c8802e23b34065875862f58a8f8e455464265faba4e70b00c66bda42be441793416d9a0534d3c4c6f85e3eb551a9bd3c8b16437943b9c82d92d10097259afae8b5947a5f82d4b2f16f69405203ed3a0300740611fb0963d3585460260b65a97440a7c334b52e7e538d491be6962a23759e2e37e0e1fb18acece799d633c7b90706501f1784e37d6fb0ae8bbf22ab7bae51761f72e501746483d611ecd3d1d134646a267771b76d614a61d996384e10ee76d19bdead538a3ac820a4f52ede2324859f3","nonce":"0x4","to":null,"transactionIndex":"0x2","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xfbebb228bd4889062bb381b6985560c11673c93decfa7f7f0a92994443e52e46","s":"0x242b17a736b410de42f7f8883cdd68bda91e1fa0c56a2e49497db67f569f4916"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6462b263a2526b1b7b7ab7e13d4d6ab9f60b27fbb8de818fcb13a53b1c0476a6","input":"0x654bd6d64e3263453501652f5d7a6a9f467e021a48e0e2e63d740b7f4e030d0efd24fdf327b78a560bd159686f809555d15d7f3cce1cb5c233ad51eead13a143aecd01cd2848576ee548524b8903af4cb3821775142b0f844092b91738a8e662a8c9a6068bd839941a6e3576364d042af044db4f0cc60711b7aa9cc27c76e27ee6059c7809dcb918d279096edd4e4c74118213ba23f600dec5640ac5021a5b6d7949bd674cd05cd14799ab3f136854491d6e757d8d46c121ead807cac1af9a6d126ec8fd2e39e65bab737d564980a733e2650d0172668895485f0b355062bb37a27bfc5d044379e1fc9779b9d4987ec4c11c4a518be9d2e2becbe15b85e2781684377a9156d3cca334b67190a690ae5260237706bcbdecf9436a2c7ede7f125b1260600cc0384154380a6682b49ed2ecbb7968479553e8408b0a1e1011806ee4b49031b09b89b757ac450382f1453b4544944431629dfc957f07d86177d05403434747a7f98981a18b14929c1e04be6fa90705a08ac133e008326487e2b9afb334792946d3850e77fc5ba555cfe29c5473b2c70d567e139af63170de94611a056cacb0336a3d0912028af7773b047dd4b1b8bde125aba206f0f3b2f131ff1fc5288f1b6c08363500d2bf8bef47906fa7c93bc9e7054e6ff13ce45dd0bd420a774d4f35a1ff1e0b365e96e1b11eaf0b0cc051ef508db86a3135389e72bf4b76e7f5dffaaad9986ca679a47c7b6cd5641c0850421446306e8bb50c49c9e52572b32a8570b83ec336956ab1241aa5c4ec3fcf3d0c2f3a63c79c5a1a3507817400b545f6d3c816fbb03147f8919549bdac32a5081344025f54410602355235301a3d6d4c957cf68ee44c9fbd94df2ec34d6a2988d21e494254446fe655655995a22df0b87ee042745c41c23d8852a0a8848dda3201fe3eb275bc9b51d81ce4dbf4663890507939ca4d2742a0cd39b8f19fd9a320b0cd24623eb9352c1bcd9fbb80015a77ebe3560fa1f378146ae7c52c19b3acf75457c70b6d53e27a6e10749d40687ddbdfe68afc48baa17858406bd160cb79426e7151d3959df5114202727e83bc085148f16d7974f60afe2822ca2dab4701315b7638c4688673be125950aaf4ec2148bee12e591b94a63cc7907bd7b6130b6a2637be408f57ff64e809edb70d5843f95bf0e47268104b74e0a8d3c7a53f04d2740f6ad7275e929e088cba80e210917ef34d9a5f510b34789078d6c3b4505db8179c66790e7b493910d4e0d43c7e44825b848661416e556ad6a6142253354c2c9b4e28f3","nonce":"0x5","to":null,"transactionIndex":"0x3","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x1ce5515735ac68b86acc91f18344f8e74e73ed4071578ba31a8de536e4586c7a","s":"0x38e91803b82cd8b8654be58b313c349a940377f2633ca06a5104e4485db38c39"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6a4df1dc08c2d3aa7e0314a41d90a23a245fde2d225fbf9300d6ff90e9d3f4e8","input":"0x5862cf54ee7b567d587def34aef4eca73807be997b77ee9e8f1aeee284eb4869dad9748fc6dc83bd45f3010e3470f1065cd024d3fc5eae65486893986b78a873372cbe103f6f8632afaccf48b78450d5882152f56d7746020a7ddd255786c2faa44d55dc8d3b11659104c565e6516392c5059da076caba4d6e39ec331759a47988a218d5ff1b757c7c5efa6d42150b7a24cd3de45a1dddf03aa9a62451855579bf538a455c436c2a134a2f9d27b3b8f61a6b6ce169b81cf86e1115b41534733b156f989635db9686b550aefd3c6704db994c9441681003e33ae52bd7587c367bfa5eaa8f9f3bad48515ac3bf2795155655471c054d6559624262ff6f6632a9fc7cfab1e4301c783b524fef241e898b2cee25ea286abd4c9fedff90096d9d2579404649439f82464aa1983e71a770c79b172f37aa1de2e806cc3f15f707a47ca5a62fc6af987c598da291fbef81e5bd90d14691156669df20eadcd96e0273e384d83e195bc105cd433f33bcbd23114a5ece605b5a6a5c6626b98c770803e5a4c93536165d6792c4b5830ad0d4aa5a1c5a1136651cde8a70bf7465217b4460fd8b107cfa9acab56dafa8c4cd4c79e2c5d49b7754ade6eff8884764055805f6271519036558c7b712d4733f719295b1bd2dcbdb070335cd6cd3a3896c59ad4577473ae9acb5eb4a2fdc5f6ac73f94538bfea0cfc801701d2959664e00f07239c530905d047b8c2e6f43cd6b914b00f4129b513062a41df190a4eaa3c2a7eb0d871a926d6651f3391a7f086ead4af9d8b18d801313644564be67a66c7132204bfe57f2bb8da1d712956336d027d516446b0709ab6192da86c9a42a42284a7209f5f9e69eadbf2321e0a38392a77ef8b5c187591704100302726f627c6c08711bd91c261085ebe91d926691c736655c165d8a8c2d3b7dff9c8c532484ab475b434d46152c3c85cf91e70e249a395ad7898839d507a15d5a343b7fb2fd69136c6b1b50eeab706ef825aec6115339134537bf890f6d9b96f27c15ee74d37db6a9f2dac4e0dcf1fc6c4915eb96d63c49eecd77038e6e1206bfb93e2d6f8c82ea9b0d0e4ae117e01aa48b5d553d921d668f4baa8c02d3241d40451570ac90617839f7125487525183d96502390c7787ebac9684e510057870d07cd0e6fd3ee2cb1be4ccfcbd2637343864cb3fc84fc847081b304a7d8cfabf507db1167cba84578f818f321cb9596267cbd5a14aadf5ab61f58b163f3f0a503df3","nonce":"0x6","to":null,"transactionIndex":"0x4","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x501e2d2bd15996cc0eb097306f4f76de2077865f934e459029caabd094c5e578","s":"0x408264ad8649ee95afd43f869be7de87b296b364010aeb18a755fae3dd0a3c49"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xc43c27001eac721ba1d80d27040175725d521d8c7ce5b4f23cc4984952ff6527","input":"0x3a6699e1e7330c28da6f04c0a5ea93bb08f398feb8bcf76b06c47d5cd56ac9b7a09d33778872698a54bcf759f6ec9dea796b71070ceeafb7fd551a7562dba64309a4f0dde67311c854aaf000402a5676d299704e9b47599993a34826f2258904f27ff5d466dc1bf50204c4550b61439b5b620285235b41321d6b4439fca574c375a580ff328e1470c9d189f5491caa3ce96be3328210f927b7336cf46ae82840ee30a127f352a7003b6e47e055070125ff825c42bfde60673b1a3b6e4d6e353fdb998b93fa27cf318ca37018423a0767efaab50662eab61945066c7af69cd44ce8771c51991a996458831a79da2537379d33715d8433659007805988f338ff6412d24a9839bc3a117c86946d3d173aefc5bea29a1859dddfc8e66b08cbab1adadbd45cfeaf6b5542193410926d12059b59bdf54ab4ffdd93f0b2e9800b5b3178dfed60169b04a17365238fdf683d34c3fb2229e770e53d3c6e603982635f435133686856b881186053a6143703135c606b654cb634b4541d6dfee6775dc8ea6ec79fd0fa5d0c724878e34ea1b41bbf781e0907cb7222fd76a4ef1aaedf38b3e9bf7f0942636f920d823043488039385a6f2f01b71bef7f04713058ff70a8ca081c130b8032a368517893b5ab0dc908025b46927f6e8e97bc65e2a6f57bcc0ad8996dd29370da8d7748d50f65a0205df5cba0a2265f307eeea4108c370dfc8b8ba96f3303903933d6cd77221b735a238387bf09a0cb6c1b1832315f788f476a8a5c466423f9868486e88366b60bb331f3920418450f71d9c53bf2a6ce0f8651ccd6837242a438a2a56756e3e86bd181eaea14584608544a7481a83b687c2c2700e6225f57e5c76025da7bc0af2f1554682d3704e733b4a850a87b3af2ca511a0142bb1e09e7e36bb09244def2903aa07ba979735ea71e54051147363b3372bd5007b5b30fc60812d7dcb82f9b729a845875614947927565b8a58d8dcd807e8cc4063d8253728b6385fe15f98e3d34476c692f2d92a0d0f0efeedf0300d046197ad59f80110eb2e8efd3e79c4c8f91766544cfcfbcaaba1c7e7015677c89a9f3393a5072eac9a75380a14044404f5b989b1f397a20564d498147334461ab94f3","nonce":"0x7","to":null,"transactionIndex":"0x5","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xb2c37bb632e39954fbd9f339eb90e3fdd36d7714b7fdd9764a732a1fcb9213bb","s":"0x41e04a31f1b06c053d5d73daeab720564f10b1aef334293322646b358705019e"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd802558258227491da149469648c395dfd9e566d8baadbc0edee4b8a9350dcf7","input":"0x723f63030479b6750c82e768bc239a909d3cea3c5c5c40324507135a0b6d6c6671d356274c8b1fbc2a9d8ff1105a3a6036014320451562fadd213574af6d470e2141e029822e894cc777408dd90ea2a63c1d64701441ae7a916f6e0d10fd3c5a901dd08836d6c08bf71047421b44848680957a28bde7c3fef2d62d99d42079a6a200782ee8df64fe64b3ae835030a369116b0456291187341a7968c6eccfc186e478f3d15a7c52a9e8ecc880118b8e123e4a6dc78dc5897fc7faef850356eee2d7c58e8296404aa26495b08d9bd736920b1c058302a10260bc35553b6fe23560c77257896c3218c53d309217e7779fbe08d2200d896e7cf5264a73ee1ab68b392ef126446bc71a04609973f34ab88c15fbc3197da98d98a095e00f84faa9ae43455b0172b4beb4c32744615f2c7da670f1b7db0a9d5d6911611c3374e65622841c856f03909916f1e17cb4aaff4ae6e19c1a190212095468f4bb6e1fa915ea16c55f61fa08526e5ca93058aea7015c4f8dc1cc0a24aa3162e48d5e767d9fdf4138dfededa980cf45a0404b086fc56ad9e3affd50580317676730bb2d4e27676b1d6fb6cf2e65e73973859b58496c7f5257ec6eb7b88cb247e7b5b5a2cd7d85445831365f73ff856798e47349fffb0b92537d5b2f6396f0da0a60ea721cc98fb04ef8a5a171cdee4123bc01a9f16b5d8492075064dbfc9527bd451d503375f92f94e36303ed18b1d858a1d72c17191b3bab68eaad66f5083b769a9b7b710b5b8a9a1b2c0068550295cb2e165e678477807eea233c8e451b0dee921962b0a7b94a872a40b1181461b1157683d96e898c34505f627c5d6e1c134520476443f229209e59751142b0f45bfbc25aa225a0d0ec8acdd32c453118ed273d45556ef846b9418fd2e93d48b0411a64b362136efe3f4abb98ce57f08ff2085dbf46aa5f143d792f5b1b34162426557265bf21ca655ea91489da715049f2fbb11ca06875fb2b7655c86816fd65b83c4a33df561032303d7773976d1aef53f882f2e157848d5c9340d46de54b15fff6abf3","nonce":"0x8","to":null,"transactionIndex":"0x6","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x4d924fb5f571bce21868b25f94690c57d8fae822964dceb841f56b2228c3d1a2","s":"0x1f5bb6a84fe40b6cd56d5f4f99bafe472c7cebecd996ef0e0d3c78add601e7ef"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd78ed182d5b55254d6584a6f8baf2ff6a7c5ffd5f2c23d3d6b2b00c9b5e7fc07","input":"0x586719e3b335e5a05892455e79e08ce21a9afc02c83e5f768eae9fa00b39a158dd7091c4fa7a6b35364580046435b81b90097f197715cc6892806d41402f9e348f92a4bdd6baea99150349cbea59a2bb9635041154403011536d27ba3a210f1e39251f45b399acae38527bd52d2f458979698118a508d3dd9be2462db4bea525dd26e4d6a6b344757654b0fa84a1048dbb6441ced8bb6efe98493a4022ef0738330750415c04648b8df72298357dfd3d2006b16651c845c06c60a7f0990bdb7aa4cf31a6ae4a4ecbc6b52af04071988cbe72b7c034722389090b53e8facaaf5b79269b6dd4754f1109d9056dd94e2e58f1d4471385c5438cb11216063a9058657fb92e3fd5ff5a7f3e8f0db7c708432c4a9d73a5819af8c164f48ed2609154d895f9e2d463aea10561c8e36d3c0a55ff3302037a017ddeb547d66b945269d12a839b755b8af2ce491d367f1791e601faf06b7a85c1231a27e400a1899c7f49c99e2cf9bff0fa37496f67c65f801a3433347d93b23dd1dcdef91dee790a97e04fee26205bb52bddc2777a82edf2d4b8c58b5f55321166cc5704776063c54302318d383b448f90175f1c0535551a04841106525d74eea2d5f0460832323b3bbf10f62d22d5ba89e2f437437a506f09f7d5f64a5e751cf8e38a5469637d24c9443b88f8af3eaa867654dec790a4105c52f1df1a54511d78b55f439962bffa3041316e3f30c11a100b50278048fa7a7db73838350973e69ce694bca794ecb0c50887f8e7eccad276a086466c29b25d02248a064689199a56ea418580903d70a019acf7013b8c71acca923dfa062494185f63425b9c3f786b59228e4a4da2264f9381532a9934048e28fea3569d2f77ad61628a3f8d316a3c3fb639dc8ce4c740dad66e16048127d881c9f1ad2702f5ea96ca09107a787c6dc491941a810e9aa8f76e77efbfef3dc3b5ea37dac094332f07089250170768625554d6092aa82d744317625ad6fc495364a7c09b2ac53b74b35423a81c4baa75b35e3ee5d33822b6f152201e0a5c7c4f517f47cb1ba9e18c879dd88dea8fa53ee541d2163ab4fede017323f53105151c793f6c302f14785d053d591ee0d2d6e706c2fdb9cee826072f4cf1546e1ea8cc798345123cbe00af96ce94ac4a11765a6449ed7e0edf81c888c9bff074ac439bf598dbfe7fad83661b70142cb03b2164171718c5c739087019b6dc1960dd0cd875db87b3fd1707210379ed6df649fcc52b7ef38093b57105b6dc5960adde984da092cc0c7f99e9f4867471c5d770b67f3189213ddeca75170bb947fa6b68fc9cd8480f213a7774b20cd25d83ab90b3eb4465dc0e88e5c33a659239dbe97d3b712498bd66007b07593b93dd6cc2f2e014df307c9d477d6b368b004b2ac553f5c73e1a70bbf4c9061eafbc64bb339932783a446f2817e422c934754dbb654891dbea919e325a94035afd","nonce":"0x9","to":null,"transactionIndex":"0x7","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x6109e0c44e8f86754478f78ee90f0c3a8d249605655330407342c534bb8fda77","s":"0x3d1cc3c94d2d1b5ec319385ae1dee73c42b87a88800e9484e8ff91d62ebb1940"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x49b652060da03857f56659b1ac638fd132c6b80c7935e655430946c3493b8539","input":"0x7f17bd908166a67abe337de1b827fcc93e6b66bf994e2b9d80c4115880a8d6f0196f2809a0a7e8dbe569eb3f2ff48ac22951762de9b5aaef79ae2385b8da667a578501bbdbb78c42baf0335072f9c5b5cfd1774b78a180169e0a7efde997a52b31054a34440758480569e84779c4a9af1ce56e6f951010423fa1335c314a18774889b6b7f9eb3e198b15478d0c71a8e04d30070b312cd20f76b67c6f65309b0f1d0b77e407cc1d619b538fb7295788bd82100a492033183a7ba7f27908709cefcdece11f88a3c0ad85a3570bbc2591473f302ded85161d493462a2a668020761482e0366f502a93e08d516407b174d49e88f0558de52f828d15ae2a3af2cf0152e4c522cf8992350ca33457725e519df12dc87e0f0b5f8492a616da359baca2bf5091f7c4158461a6b74da6b9d63588b5a6e91e88015700730acdb62d1a948ec56a20bfa860099ae33180a5b4a473877ee13ea235ef70e7300c0a33c9cd3bb41854181774c952e4b93050b6dae8c3eec863075b74076e3904b297f202e328d9e774a935dc1e889c52d97e9904a2dfe890a420461a8f59be3eb2c2c3664f9941b919d5b357f6a47efea60ce84e43f7cff2e016340b2f7320799342da6cbe1b4d7a0f868747e6968ba423780ffb352ec23450a316f250100000000000000000000000000005780171d446e9474fbe92d88273f6f67a31e230a0743511a5c6914c61ef7031bc01321cc05437d810e73a7ef059f110ad8ff161313c4caf5c127033c11b8325715fde7d02b0467c271ba9f257852265e65ce6500d3c0cd3802356edd2f556fc26828cc3f0f364fc94aac491933746886084b89f565be10da4034d54a799ad85d649e09115f6bb061a180be0c83f510062ebd0a5f6d52eee67c06aad2e6e656ad2893a31736330477fe44808094d224ac4569193847ce947eab31145de843d1c115461b1b093347688bc316e54fdfad0dc702477e96b1087a022ae5d329a2c119e4eb3ccd65f0828f4f76382c4a500db9f714bf7e6dba39332866eaf69a0d71522a0f2a8766da60f9f8a4186fd54f34021c562e1778d865f76016c699f1370c8a9acb9654ef137bf146467de8cf50717fd4b7f2c5cb67680f5401cfe4f679bb26d3551814663a2232a3fbd5ee7af0f80df5741e1801c17c93557b2ddcf0da8024cc37c6e745c540066a3f80270928913ffaf223b74a0663625d012d5c654d3d0cabd12c6e4ce68f301251cdb75e93a5c4d73147356743dd7abc434dbfb25b601b5b935b5960147dfb22ad4a7efef3173066d59e8f4604e4c7caae5ef510787adb5f8a1fd1a8168479f19a76bdbcd60c12d1162871225f5b5479551e42f002039c454c47928a7bb525fbc374b6c7a19f3d0f344fb6077dea6d4cb6690cb9356b7ccaa95074ad46519fd18ad0b35a90e21c0c00b19bc581f98f9792423a6ec6e6078d6ea0a3ccd43f366305b685453f4106937ed56b85922c350ba46a747ca7666a11fda7c0a11abe269a097257f0181d212d685b7dd5dc2697fcd88908684dcf09f6e286dacfbb0a01629b432a905c7b0b4d46f35c6a274301fcfa70e0c371eb931f53682111565f5d7b9b3184785a1554a1ee1df94b52d9ecad8bbd118b52a1b8993462f366c54a78963084fa0506cb7ca18ec6675c6fadb89bd7e15f006c229b60176b0b78d5317562c7dc4363761f5940436d321acae8a4ecee4574a56810ee1b5c3e1602023a1c633fa66ec2721272d0ea4fac46693e75bc5db0a9b46e0457a3916c5e98d0b91798c5a137dbe92508365193011b5569004fe9a0ef75d73e226068fe826ed2eb9628aa8d00","nonce":"0xa","to":null,"transactionIndex":"0x8","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x3684ae7dfbbe8f075a746bf35c18f4d356f0fe3f8b36150d1d394b744b0d64f8","s":"0x65ab2592621c1f84e80f032b57827e9c4a462c91a253bf962d82ad5058acddbf"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x42d9a64ff889d6d809b0e0b8d2147380e69f07cc931bba7e5e956857a1f24a74","input":"0x3265be11bbdc2d0b62ed551c706a553c383a8376660605baed8d32e89be71912303d74f4a4aebf9563da189c9d329203ab1efe050eba2e1e6f4244e790e2bcef634ae7f82335cca4f035393202443735406d03651a7f23d8d15684607dfb5123703c15bdcf73c4b074ef8c1a2ae5d5630b297f02bf0839297fbdad3532ad6aced6ea91839045adbbaa995ac81ec175387683366d6865aeab5a1cae244a00b3672c8955140862a1ce9d63d2d4b3461671e3a7851fb5d8686faddef58d5204155361e2036bda45f7f808b4841cdf8a98927c850c1247852ff810df7c43735ec6ab45b25afd59a02953f5b04a1f852b5f7c874d390f0e28dc172477b4f9f4bc83d5ceade87719320fb398edbeffef3077f4cc1f2eb7309e14c2bee019b27833be93bf239dcbc861bf63d793bdef9674e0534fe6c558d896684ad7f6beba5d06074a6f6b0e757caf524e155fb43a53b895362ebb62efc0f390459790043f0335055b6ebc37afc27971790bdece822fd327843b0a74ec5e4a862fbbb7cca3c2c944a8ced4a6ff3c9b0312046c18822181cc59e16c88411baeac483414055374a6aba799aa8fa3925b04e2b3f0c0fcb0adb54bb9a97fb91b8540d072b82bf4450c71f602658bdbce963867a0233f5c763309cfa75a16650f03971c2d76497130d77ce731ae1cf3640c98892877bcb452ba31151d3b534a78ea60f5944cbb9223dff39982e2fca1580456587fec201f5f941d720225db2020ba4bc85af4fa135d4101b75eb628540a4075438f328ac4cd2263f17e6f9a71e7418c9e5f29f4418f413158080340077ca7efae6a77bb3e1b9e043ad62ea8ea47ca77df6c3b66112112bd6de16c7c7327c1efd8a0a400603f132f1e3021961c53a175b06a9ad504cf2dff6b82040b1d7c2522c08e24264811b48edecdeadc59cbfd7885c2884be1b00f2d3edcb214364a4a3660de7f75ccff410aec97a28d677e9d7cc1b1eb20f3d838a2f67eca0ad2c18f83705f0e7d864b976671612a69efc46169ba23a4ff4cc8929ceca71bd8b008b9a421fc467ff0adf3e8b4d7b712cc5a9096c5d0a05966bf5dfe0e4e42677c101f38a5ad595672b931c919cfcef0f2b9099bf013277af422896c7d574b7801902980f2e7b52fadd7dcb1e5f77f7d7316b6ba74e2395e005cf61b7579d89758aa392d8470c851ed8dc04dc3ca16b3c6e61d54361a095c4375add08f41772325037e8a48423fc75b0dfd8d4e23f00615650a12f8bac5536b23ef30f5ef21d419dfed66a71408465f6c02e408709d1c841cb5c624fafe4732436bf42069bf1e2a16ef9282fe6347106426df7c1c3f7bd766d0ecdba3618232f2a8895cf36867744bb20d26f2b658743a0b5d69f6f327d9ad6a212bc64067776f381dd4579a3061332b36453d3345708c70ddf50a8ebca1e08d183f03b084b1f662bb6608401c7c1f2d3d34c8330460ac9ce148b04c8b4b9d0e6ad5308c3bb29f9c3f4ffafd","nonce":"0xb","to":null,"transactionIndex":"0x9","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xa5cc300b87b70f6995f9f58f62766e4c941cf89a8899b2e35d5f717f23340dce","s":"0x62defb73ce79415784dfc9ee655aeff22ab9262b4dd4ee76f97f8e0fcd5ae23c"}],"transactionsRoot":"0x72a1709a55d218d846226d7fe3db24c83ef6ce88f130625731a6a28d8ae1147d","uncles":[],"withdrawals":[],"withdrawalsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"}] +{"baseFeePerGas":"0x22f4b3ea","blobGasUsed":"0x0","difficulty":"0x0","excessBlobGas":"0x0","extraData":"0x","gasLimit":"0x17ef641","gasUsed":"0x2625a0","hash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","mixHash":"0x147c45372cfe0101a4898b634160af19063e603c11d7c6bf63457e31e8ca81a7","nonce":"0x0000000000000000","number":"0x4","parentBeaconBlockRoot":"0x6ee1f74e9c9bf2a28a7342e4ff7866c37c97ce2a89f95a875f351d786b14d323","parentHash":"0x8ca953b07297729a687b40e05bf17c2c4db4e0f53c3683308b50467724485ae3","receiptsRoot":"0x36832caba1c5339c7a9ff4e63a03149d5b5de5bcee60eaac6d2a21f3a7d88b00","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2b5b","stateRoot":"0x038e7e3c67c9166523c4b2bae746f5d7cf72480af4294bb900f252faf05d04e9","timestamp":"0x66964056","totalDifficulty":"0x1","transactions":[{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x7656fbe97bca00617166f052d7c2bf678249767efe2d58699b437b64979e5122","input":"0x7d877b065e1ddb12872b21f5f4de038b91f077f802d40ae712b1072515259b7302e7a43ef8bdc60dceda1e2cf2c5f6dc5630e87855642dc7bfdd125c15476bfc17bba053f7bbb13b66e4907d00d8e968b6d30283e23c43e883ad1939067ca414f58888d9f32332a3b63473e5e6d6bd31f6914447a4566d1d4afcbd54110b4091903d3a76f94b7dff9f73f28bd04bf374e6dffc49c49e2750211a2a441c641ac30e12f705057ac95cdd9faf3f6b221ee0108fc305e3a33e10900db88f2ea0f0cdef6beb22f898d8de3f8a472e932e9315383a349276338bbc8b7a4ae5b3c5e62dc521cd4ce07fa69a4ced73f51533016f253b6a59d97f8e583b9ac1ede01e4ab64587873f929817340b3663653075c57f0272a1ccd3196e4df246d0f908a33eb6a224444bc1a9f062128aaf7bbbb58c716b0eb64dd0a51162e0bdfd8dd47c18c28ea5e179a03358a31435f4af590a636dc4972fd0fcaa5627e713b1811b53608760d1477eebcf65536a6d57076acfd4f6bfa729892d14ec6c7fa8a9207d9d60bf56c6ad7edd2de9f8223ba4e2bc7df194dd41bc109180a1390ea1a68342b64f05166d325913176a37b05dd46d09604217094a60d555147eff53c583cf904662898844d05a37dc7eff4ab537ac138d066d4bb7af4212925463fdea1cf059126aeaa9794e679b6f38311a9c63196315d1165947116ad759c2f0aa148f30074c214070a74675e3326b11566505c6013297e40f2c8392346ee33e81a26b978a48952b0a754e1347543f6a37d407ed6722ac724a9a507c4916251078d7af4627cb6a0ac24f311a5042798c66cf3904b81381c93c60374912545f7011df013e31a8c7a1cdc2d44372d016431b371a0463d54be2751a3d351d40700e5129404d3f76331c72f6b3255b270f826181b46fec687a29ad18b8226004774b78a4b37c1a5e6a499ae6d8d24b780b56950970132e6f90e28a2cee18a7121d4287a26e6b596d45ed322af4e4bd582e2cbd148852927b522f63d6b0c18033ab44ca81c1a543161615dd31c70070e7eae6bc706a2de10dc395f4c39b632a75671588e91195e604e45f445d3070a0a95436c8b6c5fea9defcc71fa59e3dbc33147abed46c83313a308a746c5689da0699db748fd0f4ab894053e584626b0ff24821fc7fadd2e988894504404463e9e758754273976124a360ddb9a4c11285ac798248659f5868094152748e64b9a3c928123722ec84d417efc8e619a5c4366606607b82307dd8b9bf24f1f7c1f25aa931bcbcfded75bc1e2a575a1f782773768d5adc2d036a4bba4518bc068c47030bc65f6a13252f29b8168fd64957211c6e11b752b1f4144b0ae905d821a935d55a6f6e49c96a8300905615efacebe94ae4bb956c4dd84a0f8b53cd087888d356e160517109f6151359d245488c918847aef5527beca916770bdde14ee846cc22542e62b9db5617db816edf58a373f41a18913344994745739e12fcc980ce06ab4a05999f1fde39c41dfaae47087c1512c75b71cdb23b572730ed055dab87d307f11da0eeae0bc671ba994c3f35718e8f55bb19cc50e03107f33bfb647891f463390300","nonce":"0x2","to":null,"transactionIndex":"0x0","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x283977096b0fa526e636c9ef2a4f988d71354afbb2b9f39200bf2d9939173021","s":"0x3f384055facc74f5d465b3d6600b7973d7a2fd6888f1676dc2836cf1bdb70ad7"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xf5bfe3c2772f0eb210ae36291ac3a1c2612de813db636967017d385ed3f61331","input":"0x6281730779f6d4e88d5c0f26c588e39464798d0e09d6d146ad2d2cf019e5b03f757f5222d42413a1854986a62791201822573bf0b584958116665b8fff83a5aa6d5b677db32c7e35af172e0a6ccb5b6aeb93ea07e199e36fdc647ec500249255bb4dcc8071166debd343ee52ada0f071c81fd4e0153764325b876bc36a46235b798471ca5bbfab1b7437f98e64ae89ec087ca98bb45344142d659b8c16e80a506e72da543eb31bae4fe6a86ee8e4ca6a5914403f5f65c941ef1806b30938903a086d6ca24fe1a7bf3ee5936fac73f6335f1831803550067fa731c9e26a5582dc3792bde1c3d2ba9f5bb03775638cd8ee38fdad626aef958e3f5b65e9c5e215728571b4b3db781f13a5cf5588639944aadf43e4270202175b6854c6b8b248d1e1691161eb025890756dd29827592cb1852236b020e82631eaa6d8d21f9807198259805d3d68f0485ab07e2e6c1ef97b9b0a1781584a676a71a8f6ee7d2f20e2bbd75bdc0fb8bef831515da4787d6c4a12c2ed00fc292387d8c1f284f7926774b3d92895bc7f023d60c93f845571814311568810f5d78742360266ef1f64112b3542724877e14348e0062400379dbed5812312a8eeeb46843d634a1876cf5b49a46c2ba8cd9a3f3b35c13a55645ef3945145361d070938537aba4f5a9135bc16146be05c42421816f5122a6b42489b3cfeac24eb708e6ed0537e5aa9bd41327c7a5eed3741b83b70ba81bd5dd3a6b9cd1d67a0cf7654b5fa4aa05444360965c202effd4c493283455c5548453e747cdc0772d1422b06dfa128e967a9319ad09fbae0d81166ed70237c838f275b4a3b668b12aac2afd6e5733436e0a455e7c67450988a4b20ad0eec20d1eb5b764171b25fc048261ea2cedc8e4da6ee5aa5f11d9f9bf67614363a6226c075905f704fdd3dcb81f1db2dfc697cb45a797938a44471069d4a6976c485eba5a6cb643901d2aa4dec96193d83593684677568b6bea2929090123109123191707d93b413cee3cbd6a88b07e9ca17207e357de30e32f5f8b989a810b3d7b3a24da8f73ab1a35c81450f3c0b9eaacad4611109100100","nonce":"0x3","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0xf7a4dd0b626d2fa57e6e3edc804fecef9b367aafc239ecd8aabcbd917d73fe43","s":"0x6780e0f00ba63a8e9b86888d169319248c186e313516c62bb3ce35a736e93a88"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x21ae9124df7c63aae240083d98b152f1e71bb63b31cd5e8b2927e7fce841c1a1","input":"0x5a6e78adf9e9c860090527daf5786ef962077bf962f7156d7620dc0c8f6cc19a1d9063cffd426fdc040f0f9b3474af111945173d8091157925a03bbe35662a8b5c7e7282a5cf05014ae32e5aaf51c4440d1709811c353b3d306d7d1ca284ae95773ddfda82302667501b01647b20ae9c8770b6065442d3df94925a314b0f7517ea43de1b067112a8cdde51c1be9d622612cff5cd1f5e361a7c3fdfebf14c15967b526de0d94e33b2c7b8ed15e40a7274fbbf49d2acf1106236b710732b6b01ec732c4290df6f262a73b989b21f3e79093637423d6c956af497051acacfb61b73169975ead207fac61be7e1b89410f38392fbe639efe9c0ae4a817d3bb53994df71826e55696aea8dde32418d46215ed66dcf1ad4dd206e149573918e63fdd5e7017185e1fae415d17d0ac36c088f44778d52900812c606c8c65d889a5e280730e2ff0a62c2424922387199ccf61ea3f8e950eae428957f2a6bb6f94e31792a17ed550aa5b128a0ba393263931a2f9f556190704db80be47084996a67b3b9145810fa41f371203334496cc5fa6355cc75e37d271be63e290b1668ac5fc04a6c85db2d928473dae050e5d0478b40656acfcbb32223c1145decce504a639e837b0314730a1ce5670c21ebbc05423e357cf537e345c4109c805c086c51574cd3226261df76c4a4a39a137c8b087db775847b8684b3c20ac384ee4d4225a133d922e0f93a30d1dab2904640076f6b1952877021ff81ec9e94b0e2f6332082816d7c3097b99ea4c163368d6c0e3f8c1948331a497f0e049d679a1527ddde74350fa3a20df460308237e771db53670559375ad1d06833507f57fd63b05727d4e401ef39e13c471149984d98c7f31adf456a1e42e6c8c2a160596502c378d3064a4576e8bbe143996f49f344897194145f1fa60c62cf66df6a8e31157d598c35ad06e7a46408fe2f893a8deda14dfe7ebc56fc0c61368fada78fca4a764496c68976b9067066e678fd4eb3cf9e113a2a36cdfecc7ded22ae3b074b9b8c661e4d212fc6dd3ff8c46c9fab1b2d6eebdfdcede05c0543554a7948d33ead88a2b15c13707534db5fc93d7e9d14b1ce0a418e72898273d45bce6ae6d5c127ec5e8c5f4dddf61c8802e23b34065875862f58a8f8e455464265faba4e70b00c66bda42be441793416d9a0534d3c4c6f85e3eb551a9bd3c8b16437943b9c82d92d10097259afae8b5947a5f82d4b2f16f69405203ed3a0300740611fb0963d3585460260b65a97440a7c334b52e7e538d491be6962a23759e2e37e0e1fb18acece799d633c7b90706501f1784e37d6fb0ae8bbf22ab7bae51761f72e501746483d611ecd3d1d134646a267771b76d614a61d996384e10ee76d19bdead538a3ac820a4f52ede2324859f3","nonce":"0x4","to":null,"transactionIndex":"0x2","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xfbebb228bd4889062bb381b6985560c11673c93decfa7f7f0a92994443e52e46","s":"0x242b17a736b410de42f7f8883cdd68bda91e1fa0c56a2e49497db67f569f4916"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6462b263a2526b1b7b7ab7e13d4d6ab9f60b27fbb8de818fcb13a53b1c0476a6","input":"0x654bd6d64e3263453501652f5d7a6a9f467e021a48e0e2e63d740b7f4e030d0efd24fdf327b78a560bd159686f809555d15d7f3cce1cb5c233ad51eead13a143aecd01cd2848576ee548524b8903af4cb3821775142b0f844092b91738a8e662a8c9a6068bd839941a6e3576364d042af044db4f0cc60711b7aa9cc27c76e27ee6059c7809dcb918d279096edd4e4c74118213ba23f600dec5640ac5021a5b6d7949bd674cd05cd14799ab3f136854491d6e757d8d46c121ead807cac1af9a6d126ec8fd2e39e65bab737d564980a733e2650d0172668895485f0b355062bb37a27bfc5d044379e1fc9779b9d4987ec4c11c4a518be9d2e2becbe15b85e2781684377a9156d3cca334b67190a690ae5260237706bcbdecf9436a2c7ede7f125b1260600cc0384154380a6682b49ed2ecbb7968479553e8408b0a1e1011806ee4b49031b09b89b757ac450382f1453b4544944431629dfc957f07d86177d05403434747a7f98981a18b14929c1e04be6fa90705a08ac133e008326487e2b9afb334792946d3850e77fc5ba555cfe29c5473b2c70d567e139af63170de94611a056cacb0336a3d0912028af7773b047dd4b1b8bde125aba206f0f3b2f131ff1fc5288f1b6c08363500d2bf8bef47906fa7c93bc9e7054e6ff13ce45dd0bd420a774d4f35a1ff1e0b365e96e1b11eaf0b0cc051ef508db86a3135389e72bf4b76e7f5dffaaad9986ca679a47c7b6cd5641c0850421446306e8bb50c49c9e52572b32a8570b83ec336956ab1241aa5c4ec3fcf3d0c2f3a63c79c5a1a3507817400b545f6d3c816fbb03147f8919549bdac32a5081344025f54410602355235301a3d6d4c957cf68ee44c9fbd94df2ec34d6a2988d21e494254446fe655655995a22df0b87ee042745c41c23d8852a0a8848dda3201fe3eb275bc9b51d81ce4dbf4663890507939ca4d2742a0cd39b8f19fd9a320b0cd24623eb9352c1bcd9fbb80015a77ebe3560fa1f378146ae7c52c19b3acf75457c70b6d53e27a6e10749d40687ddbdfe68afc48baa17858406bd160cb79426e7151d3959df5114202727e83bc085148f16d7974f60afe2822ca2dab4701315b7638c4688673be125950aaf4ec2148bee12e591b94a63cc7907bd7b6130b6a2637be408f57ff64e809edb70d5843f95bf0e47268104b74e0a8d3c7a53f04d2740f6ad7275e929e088cba80e210917ef34d9a5f510b34789078d6c3b4505db8179c66790e7b493910d4e0d43c7e44825b848661416e556ad6a6142253354c2c9b4e28f3","nonce":"0x5","to":null,"transactionIndex":"0x3","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x1ce5515735ac68b86acc91f18344f8e74e73ed4071578ba31a8de536e4586c7a","s":"0x38e91803b82cd8b8654be58b313c349a940377f2633ca06a5104e4485db38c39"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6a4df1dc08c2d3aa7e0314a41d90a23a245fde2d225fbf9300d6ff90e9d3f4e8","input":"0x5862cf54ee7b567d587def34aef4eca73807be997b77ee9e8f1aeee284eb4869dad9748fc6dc83bd45f3010e3470f1065cd024d3fc5eae65486893986b78a873372cbe103f6f8632afaccf48b78450d5882152f56d7746020a7ddd255786c2faa44d55dc8d3b11659104c565e6516392c5059da076caba4d6e39ec331759a47988a218d5ff1b757c7c5efa6d42150b7a24cd3de45a1dddf03aa9a62451855579bf538a455c436c2a134a2f9d27b3b8f61a6b6ce169b81cf86e1115b41534733b156f989635db9686b550aefd3c6704db994c9441681003e33ae52bd7587c367bfa5eaa8f9f3bad48515ac3bf2795155655471c054d6559624262ff6f6632a9fc7cfab1e4301c783b524fef241e898b2cee25ea286abd4c9fedff90096d9d2579404649439f82464aa1983e71a770c79b172f37aa1de2e806cc3f15f707a47ca5a62fc6af987c598da291fbef81e5bd90d14691156669df20eadcd96e0273e384d83e195bc105cd433f33bcbd23114a5ece605b5a6a5c6626b98c770803e5a4c93536165d6792c4b5830ad0d4aa5a1c5a1136651cde8a70bf7465217b4460fd8b107cfa9acab56dafa8c4cd4c79e2c5d49b7754ade6eff8884764055805f6271519036558c7b712d4733f719295b1bd2dcbdb070335cd6cd3a3896c59ad4577473ae9acb5eb4a2fdc5f6ac73f94538bfea0cfc801701d2959664e00f07239c530905d047b8c2e6f43cd6b914b00f4129b513062a41df190a4eaa3c2a7eb0d871a926d6651f3391a7f086ead4af9d8b18d801313644564be67a66c7132204bfe57f2bb8da1d712956336d027d516446b0709ab6192da86c9a42a42284a7209f5f9e69eadbf2321e0a38392a77ef8b5c187591704100302726f627c6c08711bd91c261085ebe91d926691c736655c165d8a8c2d3b7dff9c8c532484ab475b434d46152c3c85cf91e70e249a395ad7898839d507a15d5a343b7fb2fd69136c6b1b50eeab706ef825aec6115339134537bf890f6d9b96f27c15ee74d37db6a9f2dac4e0dcf1fc6c4915eb96d63c49eecd77038e6e1206bfb93e2d6f8c82ea9b0d0e4ae117e01aa48b5d553d921d668f4baa8c02d3241d40451570ac90617839f7125487525183d96502390c7787ebac9684e510057870d07cd0e6fd3ee2cb1be4ccfcbd2637343864cb3fc84fc847081b304a7d8cfabf507db1167cba84578f818f321cb9596267cbd5a14aadf5ab61f58b163f3f0a503df3","nonce":"0x6","to":null,"transactionIndex":"0x4","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x501e2d2bd15996cc0eb097306f4f76de2077865f934e459029caabd094c5e578","s":"0x408264ad8649ee95afd43f869be7de87b296b364010aeb18a755fae3dd0a3c49"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xc43c27001eac721ba1d80d27040175725d521d8c7ce5b4f23cc4984952ff6527","input":"0x3a6699e1e7330c28da6f04c0a5ea93bb08f398feb8bcf76b06c47d5cd56ac9b7a09d33778872698a54bcf759f6ec9dea796b71070ceeafb7fd551a7562dba64309a4f0dde67311c854aaf000402a5676d299704e9b47599993a34826f2258904f27ff5d466dc1bf50204c4550b61439b5b620285235b41321d6b4439fca574c375a580ff328e1470c9d189f5491caa3ce96be3328210f927b7336cf46ae82840ee30a127f352a7003b6e47e055070125ff825c42bfde60673b1a3b6e4d6e353fdb998b93fa27cf318ca37018423a0767efaab50662eab61945066c7af69cd44ce8771c51991a996458831a79da2537379d33715d8433659007805988f338ff6412d24a9839bc3a117c86946d3d173aefc5bea29a1859dddfc8e66b08cbab1adadbd45cfeaf6b5542193410926d12059b59bdf54ab4ffdd93f0b2e9800b5b3178dfed60169b04a17365238fdf683d34c3fb2229e770e53d3c6e603982635f435133686856b881186053a6143703135c606b654cb634b4541d6dfee6775dc8ea6ec79fd0fa5d0c724878e34ea1b41bbf781e0907cb7222fd76a4ef1aaedf38b3e9bf7f0942636f920d823043488039385a6f2f01b71bef7f04713058ff70a8ca081c130b8032a368517893b5ab0dc908025b46927f6e8e97bc65e2a6f57bcc0ad8996dd29370da8d7748d50f65a0205df5cba0a2265f307eeea4108c370dfc8b8ba96f3303903933d6cd77221b735a238387bf09a0cb6c1b1832315f788f476a8a5c466423f9868486e88366b60bb331f3920418450f71d9c53bf2a6ce0f8651ccd6837242a438a2a56756e3e86bd181eaea14584608544a7481a83b687c2c2700e6225f57e5c76025da7bc0af2f1554682d3704e733b4a850a87b3af2ca511a0142bb1e09e7e36bb09244def2903aa07ba979735ea71e54051147363b3372bd5007b5b30fc60812d7dcb82f9b729a845875614947927565b8a58d8dcd807e8cc4063d8253728b6385fe15f98e3d34476c692f2d92a0d0f0efeedf0300d046197ad59f80110eb2e8efd3e79c4c8f91766544cfcfbcaaba1c7e7015677c89a9f3393a5072eac9a75380a14044404f5b989b1f397a20564d498147334461ab94f3","nonce":"0x7","to":null,"transactionIndex":"0x5","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xb2c37bb632e39954fbd9f339eb90e3fdd36d7714b7fdd9764a732a1fcb9213bb","s":"0x41e04a31f1b06c053d5d73daeab720564f10b1aef334293322646b358705019e"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd802558258227491da149469648c395dfd9e566d8baadbc0edee4b8a9350dcf7","input":"0x723f63030479b6750c82e768bc239a909d3cea3c5c5c40324507135a0b6d6c6671d356274c8b1fbc2a9d8ff1105a3a6036014320451562fadd213574af6d470e2141e029822e894cc777408dd90ea2a63c1d64701441ae7a916f6e0d10fd3c5a901dd08836d6c08bf71047421b44848680957a28bde7c3fef2d62d99d42079a6a200782ee8df64fe64b3ae835030a369116b0456291187341a7968c6eccfc186e478f3d15a7c52a9e8ecc880118b8e123e4a6dc78dc5897fc7faef850356eee2d7c58e8296404aa26495b08d9bd736920b1c058302a10260bc35553b6fe23560c77257896c3218c53d309217e7779fbe08d2200d896e7cf5264a73ee1ab68b392ef126446bc71a04609973f34ab88c15fbc3197da98d98a095e00f84faa9ae43455b0172b4beb4c32744615f2c7da670f1b7db0a9d5d6911611c3374e65622841c856f03909916f1e17cb4aaff4ae6e19c1a190212095468f4bb6e1fa915ea16c55f61fa08526e5ca93058aea7015c4f8dc1cc0a24aa3162e48d5e767d9fdf4138dfededa980cf45a0404b086fc56ad9e3affd50580317676730bb2d4e27676b1d6fb6cf2e65e73973859b58496c7f5257ec6eb7b88cb247e7b5b5a2cd7d85445831365f73ff856798e47349fffb0b92537d5b2f6396f0da0a60ea721cc98fb04ef8a5a171cdee4123bc01a9f16b5d8492075064dbfc9527bd451d503375f92f94e36303ed18b1d858a1d72c17191b3bab68eaad66f5083b769a9b7b710b5b8a9a1b2c0068550295cb2e165e678477807eea233c8e451b0dee921962b0a7b94a872a40b1181461b1157683d96e898c34505f627c5d6e1c134520476443f229209e59751142b0f45bfbc25aa225a0d0ec8acdd32c453118ed273d45556ef846b9418fd2e93d48b0411a64b362136efe3f4abb98ce57f08ff2085dbf46aa5f143d792f5b1b34162426557265bf21ca655ea91489da715049f2fbb11ca06875fb2b7655c86816fd65b83c4a33df561032303d7773976d1aef53f882f2e157848d5c9340d46de54b15fff6abf3","nonce":"0x8","to":null,"transactionIndex":"0x6","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x4d924fb5f571bce21868b25f94690c57d8fae822964dceb841f56b2228c3d1a2","s":"0x1f5bb6a84fe40b6cd56d5f4f99bafe472c7cebecd996ef0e0d3c78add601e7ef"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd78ed182d5b55254d6584a6f8baf2ff6a7c5ffd5f2c23d3d6b2b00c9b5e7fc07","input":"0x586719e3b335e5a05892455e79e08ce21a9afc02c83e5f768eae9fa00b39a158dd7091c4fa7a6b35364580046435b81b90097f197715cc6892806d41402f9e348f92a4bdd6baea99150349cbea59a2bb9635041154403011536d27ba3a210f1e39251f45b399acae38527bd52d2f458979698118a508d3dd9be2462db4bea525dd26e4d6a6b344757654b0fa84a1048dbb6441ced8bb6efe98493a4022ef0738330750415c04648b8df72298357dfd3d2006b16651c845c06c60a7f0990bdb7aa4cf31a6ae4a4ecbc6b52af04071988cbe72b7c034722389090b53e8facaaf5b79269b6dd4754f1109d9056dd94e2e58f1d4471385c5438cb11216063a9058657fb92e3fd5ff5a7f3e8f0db7c708432c4a9d73a5819af8c164f48ed2609154d895f9e2d463aea10561c8e36d3c0a55ff3302037a017ddeb547d66b945269d12a839b755b8af2ce491d367f1791e601faf06b7a85c1231a27e400a1899c7f49c99e2cf9bff0fa37496f67c65f801a3433347d93b23dd1dcdef91dee790a97e04fee26205bb52bddc2777a82edf2d4b8c58b5f55321166cc5704776063c54302318d383b448f90175f1c0535551a04841106525d74eea2d5f0460832323b3bbf10f62d22d5ba89e2f437437a506f09f7d5f64a5e751cf8e38a5469637d24c9443b88f8af3eaa867654dec790a4105c52f1df1a54511d78b55f439962bffa3041316e3f30c11a100b50278048fa7a7db73838350973e69ce694bca794ecb0c50887f8e7eccad276a086466c29b25d02248a064689199a56ea418580903d70a019acf7013b8c71acca923dfa062494185f63425b9c3f786b59228e4a4da2264f9381532a9934048e28fea3569d2f77ad61628a3f8d316a3c3fb639dc8ce4c740dad66e16048127d881c9f1ad2702f5ea96ca09107a787c6dc491941a810e9aa8f76e77efbfef3dc3b5ea37dac094332f07089250170768625554d6092aa82d744317625ad6fc495364a7c09b2ac53b74b35423a81c4baa75b35e3ee5d33822b6f152201e0a5c7c4f517f47cb1ba9e18c879dd88dea8fa53ee541d2163ab4fede017323f53105151c793f6c302f14785d053d591ee0d2d6e706c2fdb9cee826072f4cf1546e1ea8cc798345123cbe00af96ce94ac4a11765a6449ed7e0edf81c888c9bff074ac439bf598dbfe7fad83661b70142cb03b2164171718c5c739087019b6dc1960dd0cd875db87b3fd1707210379ed6df649fcc52b7ef38093b57105b6dc5960adde984da092cc0c7f99e9f4867471c5d770b67f3189213ddeca75170bb947fa6b68fc9cd8480f213a7774b20cd25d83ab90b3eb4465dc0e88e5c33a659239dbe97d3b712498bd66007b07593b93dd6cc2f2e014df307c9d477d6b368b004b2ac553f5c73e1a70bbf4c9061eafbc64bb339932783a446f2817e422c934754dbb654891dbea919e325a94035afd","nonce":"0x9","to":null,"transactionIndex":"0x7","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x6109e0c44e8f86754478f78ee90f0c3a8d249605655330407342c534bb8fda77","s":"0x3d1cc3c94d2d1b5ec319385ae1dee73c42b87a88800e9484e8ff91d62ebb1940"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x49b652060da03857f56659b1ac638fd132c6b80c7935e655430946c3493b8539","input":"0x7f17bd908166a67abe337de1b827fcc93e6b66bf994e2b9d80c4115880a8d6f0196f2809a0a7e8dbe569eb3f2ff48ac22951762de9b5aaef79ae2385b8da667a578501bbdbb78c42baf0335072f9c5b5cfd1774b78a180169e0a7efde997a52b31054a34440758480569e84779c4a9af1ce56e6f951010423fa1335c314a18774889b6b7f9eb3e198b15478d0c71a8e04d30070b312cd20f76b67c6f65309b0f1d0b77e407cc1d619b538fb7295788bd82100a492033183a7ba7f27908709cefcdece11f88a3c0ad85a3570bbc2591473f302ded85161d493462a2a668020761482e0366f502a93e08d516407b174d49e88f0558de52f828d15ae2a3af2cf0152e4c522cf8992350ca33457725e519df12dc87e0f0b5f8492a616da359baca2bf5091f7c4158461a6b74da6b9d63588b5a6e91e88015700730acdb62d1a948ec56a20bfa860099ae33180a5b4a473877ee13ea235ef70e7300c0a33c9cd3bb41854181774c952e4b93050b6dae8c3eec863075b74076e3904b297f202e328d9e774a935dc1e889c52d97e9904a2dfe890a420461a8f59be3eb2c2c3664f9941b919d5b357f6a47efea60ce84e43f7cff2e016340b2f7320799342da6cbe1b4d7a0f868747e6968ba423780ffb352ec23450a316f250100000000000000000000000000005780171d446e9474fbe92d88273f6f67a31e230a0743511a5c6914c61ef7031bc01321cc05437d810e73a7ef059f110ad8ff161313c4caf5c127033c11b8325715fde7d02b0467c271ba9f257852265e65ce6500d3c0cd3802356edd2f556fc26828cc3f0f364fc94aac491933746886084b89f565be10da4034d54a799ad85d649e09115f6bb061a180be0c83f510062ebd0a5f6d52eee67c06aad2e6e656ad2893a31736330477fe44808094d224ac4569193847ce947eab31145de843d1c115461b1b093347688bc316e54fdfad0dc702477e96b1087a022ae5d329a2c119e4eb3ccd65f0828f4f76382c4a500db9f714bf7e6dba39332866eaf69a0d71522a0f2a8766da60f9f8a4186fd54f34021c562e1778d865f76016c699f1370c8a9acb9654ef137bf146467de8cf50717fd4b7f2c5cb67680f5401cfe4f679bb26d3551814663a2232a3fbd5ee7af0f80df5741e1801c17c93557b2ddcf0da8024cc37c6e745c540066a3f80270928913ffaf223b74a0663625d012d5c654d3d0cabd12c6e4ce68f301251cdb75e93a5c4d73147356743dd7abc434dbfb25b601b5b935b5960147dfb22ad4a7efef3173066d59e8f4604e4c7caae5ef510787adb5f8a1fd1a8168479f19a76bdbcd60c12d1162871225f5b5479551e42f002039c454c47928a7bb525fbc374b6c7a19f3d0f344fb6077dea6d4cb6690cb9356b7ccaa95074ad46519fd18ad0b35a90e21c0c00b19bc581f98f9792423a6ec6e6078d6ea0a3ccd43f366305b685453f4106937ed56b85922c350ba46a747ca7666a11fda7c0a11abe269a097257f0181d212d685b7dd5dc2697fcd88908684dcf09f6e286dacfbb0a01629b432a905c7b0b4d46f35c6a274301fcfa70e0c371eb931f53682111565f5d7b9b3184785a1554a1ee1df94b52d9ecad8bbd118b52a1b8993462f366c54a78963084fa0506cb7ca18ec6675c6fadb89bd7e15f006c229b60176b0b78d5317562c7dc4363761f5940436d321acae8a4ecee4574a56810ee1b5c3e1602023a1c633fa66ec2721272d0ea4fac46693e75bc5db0a9b46e0457a3916c5e98d0b91798c5a137dbe92508365193011b5569004fe9a0ef75d73e226068fe826ed2eb9628aa8d00","nonce":"0xa","to":null,"transactionIndex":"0x8","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x3684ae7dfbbe8f075a746bf35c18f4d356f0fe3f8b36150d1d394b744b0d64f8","s":"0x65ab2592621c1f84e80f032b57827e9c4a462c91a253bf962d82ad5058acddbf"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x42d9a64ff889d6d809b0e0b8d2147380e69f07cc931bba7e5e956857a1f24a74","input":"0x3265be11bbdc2d0b62ed551c706a553c383a8376660605baed8d32e89be71912303d74f4a4aebf9563da189c9d329203ab1efe050eba2e1e6f4244e790e2bcef634ae7f82335cca4f035393202443735406d03651a7f23d8d15684607dfb5123703c15bdcf73c4b074ef8c1a2ae5d5630b297f02bf0839297fbdad3532ad6aced6ea91839045adbbaa995ac81ec175387683366d6865aeab5a1cae244a00b3672c8955140862a1ce9d63d2d4b3461671e3a7851fb5d8686faddef58d5204155361e2036bda45f7f808b4841cdf8a98927c850c1247852ff810df7c43735ec6ab45b25afd59a02953f5b04a1f852b5f7c874d390f0e28dc172477b4f9f4bc83d5ceade87719320fb398edbeffef3077f4cc1f2eb7309e14c2bee019b27833be93bf239dcbc861bf63d793bdef9674e0534fe6c558d896684ad7f6beba5d06074a6f6b0e757caf524e155fb43a53b895362ebb62efc0f390459790043f0335055b6ebc37afc27971790bdece822fd327843b0a74ec5e4a862fbbb7cca3c2c944a8ced4a6ff3c9b0312046c18822181cc59e16c88411baeac483414055374a6aba799aa8fa3925b04e2b3f0c0fcb0adb54bb9a97fb91b8540d072b82bf4450c71f602658bdbce963867a0233f5c763309cfa75a16650f03971c2d76497130d77ce731ae1cf3640c98892877bcb452ba31151d3b534a78ea60f5944cbb9223dff39982e2fca1580456587fec201f5f941d720225db2020ba4bc85af4fa135d4101b75eb628540a4075438f328ac4cd2263f17e6f9a71e7418c9e5f29f4418f413158080340077ca7efae6a77bb3e1b9e043ad62ea8ea47ca77df6c3b66112112bd6de16c7c7327c1efd8a0a400603f132f1e3021961c53a175b06a9ad504cf2dff6b82040b1d7c2522c08e24264811b48edecdeadc59cbfd7885c2884be1b00f2d3edcb214364a4a3660de7f75ccff410aec97a28d677e9d7cc1b1eb20f3d838a2f67eca0ad2c18f83705f0e7d864b976671612a69efc46169ba23a4ff4cc8929ceca71bd8b008b9a421fc467ff0adf3e8b4d7b712cc5a9096c5d0a05966bf5dfe0e4e42677c101f38a5ad595672b931c919cfcef0f2b9099bf013277af422896c7d574b7801902980f2e7b52fadd7dcb1e5f77f7d7316b6ba74e2395e005cf61b7579d89758aa392d8470c851ed8dc04dc3ca16b3c6e61d54361a095c4375add08f41772325037e8a48423fc75b0dfd8d4e23f00615650a12f8bac5536b23ef30f5ef21d419dfed66a71408465f6c02e408709d1c841cb5c624fafe4732436bf42069bf1e2a16ef9282fe6347106426df7c1c3f7bd766d0ecdba3618232f2a8895cf36867744bb20d26f2b658743a0b5d69f6f327d9ad6a212bc64067776f381dd4579a3061332b36453d3345708c70ddf50a8ebca1e08d183f03b084b1f662bb6608401c7c1f2d3d34c8330460ac9ce148b04c8b4b9d0e6ad5308c3bb29f9c3f4ffafd","nonce":"0xb","to":null,"transactionIndex":"0x9","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xa5cc300b87b70f6995f9f58f62766e4c941cf89a8899b2e35d5f717f23340dce","s":"0x62defb73ce79415784dfc9ee655aeff22ab9262b4dd4ee76f97f8e0fcd5ae23c"}],"transactionsRoot":"0x72a1709a55d218d846226d7fe3db24c83ef6ce88f130625731a6a28d8ae1147d","uncles":[],"withdrawals":[],"withdrawalsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"} \ No newline at end of file From c83f22385a79e920c491c2bf482f6667a766fc3e Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 17:41:44 +0100 Subject: [PATCH 07/56] feat: trace_decoder/examples/dump.rs --- .gitignore | 2 +- Cargo.lock | 1 + trace_decoder/Cargo.toml | 1 + trace_decoder/examples/dump.rs | 275 +++++++++++++++++++++++++++++++++ trace_decoder/src/lib.rs | 3 +- 5 files changed, 280 insertions(+), 2 deletions(-) create mode 100644 trace_decoder/examples/dump.rs diff --git a/.gitignore b/.gitignore index 3d1dc8c49..b2db01bea 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ *.iml .idea/ .vscode - +/**/*.ignoreme diff --git a/Cargo.lock b/Cargo.lock index fe9988dc2..735d491d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5109,6 +5109,7 @@ dependencies = [ "bytes", "ciborium", "ciborium-io", + "clap", "copyvec", "criterion", "either", diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 7ebfcdb9b..e78a98150 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -43,6 +43,7 @@ zk_evm_common = { workspace = true } [dev-dependencies] alloy = { workspace = true } +clap.workspace = true criterion = { workspace = true } plonky2_maybe_rayon = { workspace = true } pretty_env_logger = { workspace = true } diff --git a/trace_decoder/examples/dump.rs b/trace_decoder/examples/dump.rs new file mode 100644 index 000000000..5238a45a0 --- /dev/null +++ b/trace_decoder/examples/dump.rs @@ -0,0 +1,275 @@ +use std::io; + +#[derive(clap::Parser)] +struct Args { + #[arg(long)] + method: Method, + #[arg(long, default_value_t = 1)] + batch_size: usize, + #[arg(long)] + use_burn_addr: bool, + #[arg(long)] + pretty: bool, +} + +#[derive(clap::ValueEnum, Clone)] +enum Method { + Old, + New, +} + +fn main() -> anyhow::Result<()> { + let Args { + method, + batch_size, + use_burn_addr, + pretty, + } = clap::Parser::parse(); + + let prover::BlockProverInput { + block_trace, + other_data, + } = serde_path_to_error::deserialize(&mut serde_json::Deserializer::from_reader(io::stdin()))?; + + let gis = (match method { + Method::Old => trace_decoder::entrypoint_old as fn(_, _, _, _) -> anyhow::Result>, + Method::New => trace_decoder::entrypoint_new as _, + })(block_trace, other_data, batch_size, use_burn_addr)? + .into_iter() + .map(repr::GenerationInputs::from) + .collect::>(); + + (match pretty { + true => serde_json::to_writer_pretty as fn(_, _) -> _, + false => serde_json::to_writer as _, + })(io::stdout(), &gis)?; + + Ok(()) +} + +mod repr { + use std::{collections::BTreeMap, fmt, iter}; + + use ethereum_types::{Address, U256}; + use evm_arithmetization::{ + generation::TrieInputs, + proof::{BlockHashes, BlockMetadata, TrieRoots}, + }; + use hex::ToHex as _; + use keccak_hash::H256; + use mpt_trie::{ + nibbles::Nibbles, + partial_trie::{HashedPartialTrie, Node}, + }; + use serde::{Serialize, Serializer}; + use stackstack::Stack; + use u4::U4; + + #[derive(Serialize, PartialEq)] + pub struct GenerationInputs { + txn_number: U256, + gas_before: U256, + gas_after: U256, + #[serde(with = "crate::hex::slice")] + txns: Vec>, + withdrawals: Vec<(Address, U256)>, + exit_roots: Vec<(U256, H256)>, + + state: Mpt, + transaction: Mpt, + receipts: Mpt, + storage: BTreeMap, + + checkpoint_root: H256, + state_root: H256, + transaction_root: H256, + receipt_root: H256, + + #[serde(with = "crate::hex::btree_map")] + contract_code: BTreeMap>, + meta: BlockMetadata, + hashes: BlockHashes, + + #[serde(skip_serializing_if = "Option::is_none")] + burn_addr: Option
, + } + + impl From for GenerationInputs { + fn from(value: evm_arithmetization::generation::GenerationInputs) -> Self { + let evm_arithmetization::generation::GenerationInputs { + txn_number_before, + gas_used_before, + gas_used_after, + signed_txns, + withdrawals, + global_exit_roots, + tries: + TrieInputs { + state_trie, + transactions_trie, + receipts_trie, + storage_tries, + }, + trie_roots_after: + TrieRoots { + state_root, + transactions_root, + receipts_root, + }, + checkpoint_state_trie_root, + contract_code, + block_metadata, + block_hashes, + burn_addr, + } = value; + Self { + txn_number: txn_number_before, + gas_before: gas_used_before, + gas_after: gas_used_after, + txns: signed_txns, + withdrawals, + exit_roots: global_exit_roots, + state: Mpt::from_hashed_partial_trie(&state_trie), + transaction: Mpt::from_hashed_partial_trie(&transactions_trie), + receipts: Mpt::from_hashed_partial_trie(&receipts_trie), + storage: storage_tries + .into_iter() + .map(|(k, v)| (k, Mpt::from_hashed_partial_trie(&v))) + .collect(), + state_root, + transaction_root: transactions_root, + receipt_root: receipts_root, + contract_code: contract_code.into_iter().collect(), + meta: block_metadata, + hashes: block_hashes, + checkpoint_root: checkpoint_state_trie_root, + burn_addr, + } + } + } + + #[derive(Serialize, PartialEq)] + struct Mpt(BTreeMap); + + impl Mpt { + pub fn from_hashed_partial_trie(hpt: &HashedPartialTrie) -> Self { + let mut repr = BTreeMap::new(); + visit(Stack::new(), hpt, &mut repr); + Self(repr) + } + } + + #[derive(PartialEq, Eq, PartialOrd, Ord)] + struct MptPath(Vec); + + impl fmt::Display for MptPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self(v) = self; + for u in v { + f.write_fmt(format_args!("{u:x}"))? + } + Ok(()) + } + } + impl Serialize for MptPath { + fn serialize(&self, serializer: S) -> Result { + serializer.collect_str(self) + } + } + + impl FromIterator for MptPath { + fn from_iter>(iter: II) -> Self { + Self(iter.into_iter().collect()) + } + } + + #[derive(PartialEq)] + enum MptNode { + Empty, + Hash(H256), + Value(Vec), + } + + impl fmt::Display for MptNode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MptNode::Empty => f.write_str("empty"), + MptNode::Hash(h) => { + f.write_fmt(format_args!("hash:{}", h.as_bytes().encode_hex::())) + } + MptNode::Value(v) => { + f.write_fmt(format_args!("value:{}", v.encode_hex::())) + } + } + } + } + + impl Serialize for MptNode { + fn serialize(&self, serializer: S) -> Result { + serializer.collect_str(self) + } + } + + fn visit(path: Stack, hpt: &HashedPartialTrie, repr: &mut BTreeMap) { + let key = path.iter().copied().collect(); + match &**hpt { + Node::Empty => { + repr.insert(key, MptNode::Empty); + } + Node::Hash(it) => { + repr.insert(key, MptNode::Hash(*it)); + } + Node::Branch { children, value } => { + for (ix, child) in children.iter().enumerate() { + visit(path.pushed(U4::new(ix as u8).unwrap()), child, repr) + } + if !value.is_empty() { + repr.insert(key, MptNode::Value(value.clone())); + } + } + Node::Extension { nibbles, child } => { + path.with_all(iter_nibbles(*nibbles), |path| visit(*path, child, repr)) + } + Node::Leaf { nibbles, value } => path.with_all(iter_nibbles(*nibbles), |path| { + repr.insert( + path.iter().copied().collect(), + MptNode::Value(value.clone()), + ); + }), + } + } + + fn iter_nibbles(mut nibbles: Nibbles) -> impl Iterator { + iter::from_fn(move || match nibbles.count { + 0 => None, + _ => Some(U4::new(nibbles.pop_next_nibble_back()).unwrap()), + }) + } +} + +mod hex { + pub mod slice { + pub fn serialize( + it: &[impl hex::ToHex], + serializer: S, + ) -> Result { + serializer.collect_seq(it.iter().map(|it| it.encode_hex::())) + } + } + pub mod btree_map { + use std::collections::BTreeMap; + + use serde::{ser::SerializeMap as _, Serialize}; + + pub fn serialize( + it: &BTreeMap, + serializer: S, + ) -> Result { + let mut serializer = serializer.serialize_map(Some(it.len()))?; + for (k, v) in it { + serializer.serialize_entry(k, &v.encode_hex::())?; + } + serializer.end() + } + } +} diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index ac0869271..6eecb6fbe 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -283,7 +283,8 @@ pub struct BlockLevelData { } // pub use entrypoint_old as entrypoint; -pub use imp::entrypoint; +pub use entrypoint_new as entrypoint; +pub use imp::entrypoint as entrypoint_new; mod imp; From 6771d0c1b35726dde834c32bafbee3dee59cb535 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 18:16:39 +0100 Subject: [PATCH 08/56] Revert "chore: trace_decoder test inputs are no longer arrays" This reverts commit 408273a5fff2552b2eeac022c1a964a7214c3d98. --- .../tests/data/witnesses/zero_jerigon/b19807080_main.json | 3 ++- .../data/witnesses/zero_jerigon/b19807080_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b19840104_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b19840104_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b20240052_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b20240052_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b20240058_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b20240058_main_header.json | 2 +- .../tests/data/witnesses/zero_jerigon/b20472570_main.json | 4 ++-- .../data/witnesses/zero_jerigon/b20472570_main_header.json | 3 ++- trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json | 3 ++- .../tests/data/witnesses/zero_jerigon/b28_dev_header.json | 3 ++- trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json | 4 ++-- .../tests/data/witnesses/zero_jerigon/b4_dev_header.json | 2 +- 14 files changed, 23 insertions(+), 19 deletions(-) diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json index ec0f90155..3a09e82d0 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main.json @@ -1,4 +1,4 @@ - +[ { "block_trace": { "trie_pre_images": { @@ -1013,3 +1013,4 @@ "checkpoint_state_trie_root": "0xbbd66174555d27c88e285ff4797de401470d8d2486d15513ab36e491e864bca2" } } +] \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json index 288889c82..74d58e786 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19807080_main_header.json @@ -1 +1 @@ -{"number":"0x12e3b68","hash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","transactions":[{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x485c7c9ae78a17af338eef77267accbf73d3a24be86cceff8ab041ce10388b20","yParity":"0x1","accessList":[],"transactionIndex":"0x0","type":"0x2","nonce":"0x8e","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000071f755898886f79efa73334450f05a824faeae0200000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0x3efde0059a9e20313ee5a466273604b3e79d199a60b2c44e753f5f2fe56eb987","s":"0x40eca86c1d87c685a3024af4a0224dab92758dc1990b8f8ecb6040f88498ab1e","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0x71f755898886f79efa73334450f05a824faeae02","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b832f7b98df73773fee549f702b87332ab605baeab66a725582089dfb8c8716","yParity":"0x1","accessList":[],"transactionIndex":"0x1","type":"0x2","nonce":"0x6a","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000a890e6b83ac95c7de4ffd4549d4cd282b407b49500000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xa884ab9e5c1057e2e741e5ad4c6335f655a0dd248b3a6b7d7d0eb450ac2cff8e","s":"0x7befa7f3480ddc589444e0d4498e0fd68fa765747676bafd9a128c6dcd91d5a1","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0xa890e6b83ac95c7de4ffd4549d4cd282b407b495","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xd119b49569af4d5882efa6c72c84158bc1a9b8ac8f632706ce810f627ab13fb3","yParity":"0x1","accessList":[],"transactionIndex":"0x2","type":"0x2","nonce":"0xa18","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000dee90fc88ef3aceace9a22d2b2921906b724455200000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xd244c53d24ffc3b2fcdfaf692d82593c0bb8cf3369b2a94c91c2c0249c4510a7","s":"0x751ca6879dce7d240443728d6e5756fa78be470b7ebd94cf984a1cb94f9f2c30","chainId":"0x1","v":"0x1","gas":"0x35b60","maxPriorityFeePerGas":"0xb4ad34500","from":"0xdee90fc88ef3aceace9a22d2b2921906b7244552","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x1cd918d39380020","gasPrice":"0xc6ded450f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xc02ea02af1da253b9cf3d1de648c3355211f490cf4b8641b3146e69450870ba6","yParity":"0x0","accessList":[],"transactionIndex":"0x3","type":"0x2","nonce":"0x28b","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000fe6cf59162f319fb2c536f63a6121eb88dc85a3400000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xb66d674b17cb04d44900455636b496131fdae9b8e4c81f790854bda351130e83","s":"0xdb241292520a7c135d381b0fd18788c9490aff4b756d397453a6454da4e0a3c","chainId":"0x1","v":"0x0","gas":"0x35b60","maxPriorityFeePerGas":"0xaa9e48a00","from":"0xfe6cf59162f319fb2c536f63a6121eb88dc85a34","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x102a336dba60000","gasPrice":"0xbccfe8a0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b66220ea1cfac82ed5639293cbb0b5acaa956a348999648aacfc202f5a6451b","yParity":"0x0","accessList":[],"transactionIndex":"0x4","type":"0x2","nonce":"0xba3","input":"0x3d0e3ec50000000000000000000000000000000000000000000000000001d57eaddeea78000000000000000000000000000000000000000000000000023bb9178b0192be00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000c58e4d309c4f5c88afe355c260ee9a1a699ed1dd00000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000008b683c400457ef31f3c27c90acb6ab69304d1b77000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","r":"0xdd70145d23e041328d8242858ca9815cbb03bf408dd7d81e30532932497838fc","s":"0x496bf86926d61a533fa5824c9d21271b8b1597b48014282168a48575f8cf417c","chainId":"0x1","v":"0x0","gas":"0x4dc2f","maxPriorityFeePerGas":"0xb2d05e00","from":"0xc58e4d309c4f5c88afe355c260ee9a1a699ed1dd","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x0","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xa16262586a442817e5766675bd6ec767ebe3815e7ae325248acdcf54de4561aa","yParity":"0x1","accessList":[],"transactionIndex":"0x5","type":"0x2","nonce":"0x162c","input":"0x088890dc000000000000000000000000000000000000000000000000007af53217af31b800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008693ca3483daf299aad023eae75221436d6c11a000000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f1001ad1ee7743e0f6715f50cdaeb1397d5cb4fa","r":"0x2c9a9ab0d7eb2503a5ebbfe1a66c2f08a9170e1da5b14cdb142fce831522a43a","s":"0x360ecd3be1f224118862ddb78787cf31ad7600994b6c7a4a947ae3a071619a8b","chainId":"0x1","v":"0x1","gas":"0x461c6","maxPriorityFeePerGas":"0xb2d05e00","from":"0x8693ca3483daf299aad023eae75221436d6c11a0","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x2c68af0bb140000","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x1d0969550eee06cc9bd992ccceaab28c5762feec4d69cdca3dbc50927263bed9","transactionIndex":"0x6","type":"0x0","nonce":"0x0","input":"0x","r":"0x6b6a8c636721916ee32404201135745eeb2bfad873e662f5a59c331cb6647a95","s":"0x452ae97ab3fb5bd8e4cc7890b28876a662430c40bf643239303e0c86770c96bf","chainId":"0x1","v":"0x26","gas":"0x5208","from":"0x17032783b5f29c8a68e0fafba4db021f248409e4","to":"0xb27b03580c193d324931acb143f6a1f3477e702e","value":"0x1ff118a94dfd000","gasPrice":"0x1a13b8600"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x923e060de69675c90d67472ca7a33e61630f64b92e20224db08055c5cd4eaaf3","yParity":"0x1","accessList":[],"transactionIndex":"0x7","type":"0x2","nonce":"0xbcb0","input":"0xa000000000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f56400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000099f388994000000000000000000000000000000000000000000000000b6ea0676d933c915000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","r":"0x269fa6d550e1ce6f76884a87645bd2a462c303dca06423f2f0638a572109f0f7","s":"0x776dab3e59d703ff24cc45be1b856a73f66facbd0c5d6c41ecc940ca7e02416f","chainId":"0x1","v":"0x1","gas":"0x61a80","maxPriorityFeePerGas":"0x34fd4acd","from":"0x93793bd1f3e35a0efd098c30e486a860a0ef7551","to":"0x9def7cde171841a9f0724124ca0b01a622d749e4","maxFeePerGas":"0x158174adc","value":"0x12e3b68","gasPrice":"0x158174adc"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x71845c70b3ee8a2894f8e5bb833639d1a6a80286eaf2d5b732ecbe8e30ec1346","yParity":"0x1","accessList":[],"transactionIndex":"0x8","type":"0x2","nonce":"0xe5ad7","input":"0x","r":"0xe0c1666544ae41c9fecaba65277c51af8755838a43c6e5bdc15c83970af18461","s":"0x405b701cfa1a3b22fc547c21955d55210f7fdd87b576466a2cf30cb27e9fb442","chainId":"0x1","v":"0x1","gas":"0x6ac1","maxPriorityFeePerGas":"0x0","from":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","to":"0x617c8de5bde54ffbb8d92716cc947858ca38f582","maxFeePerGas":"0x1231a000f","value":"0x6ca54625d8e66f","gasPrice":"0x1231a000f"}],"logsBloom":"0x002000000100000000000000801000044000000000080000800100000401010008008000000000080000084000080000020000000800a0005000000000a0000000000000000000080a000008000000200000100100400000000000008000040000001020020000000000400008000001000000000000041100000010000880000000000000080000004000000000048140000001010008090800004000400000020500000000200000000048000008000000000001000000002008000088000020000002000000000000200000000a00000000000000401000000042000020000050200000000810800010800000000000000000800000400008000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x322e0b5db82824020e3247d491fe8e36688d881392cd63af55f958df0aa95725","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x611a5e88d0ffbe176e4f6409bf229792668d5c96d6e47b519a3d5653fc723973","baseFeePerGas":"0x1231a000f","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11a0834","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96b","validatorIndex":"0x4626c"},{"amount":"0x11a27fc","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96c","validatorIndex":"0x4626d"},{"amount":"0x11b88e3","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96d","validatorIndex":"0x4626e"},{"amount":"0x11be16e","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96e","validatorIndex":"0x4626f"},{"amount":"0x11a1416","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96f","validatorIndex":"0x46270"},{"amount":"0x11a2dc0","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c970","validatorIndex":"0x46271"},{"amount":"0x11a42a8","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c971","validatorIndex":"0x46272"},{"amount":"0x119940e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c972","validatorIndex":"0x46273"},{"amount":"0x1199000","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c973","validatorIndex":"0x46274"},{"amount":"0x11a046e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c974","validatorIndex":"0x46275"},{"amount":"0x119d364","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c975","validatorIndex":"0x46276"},{"amount":"0x3bc7b17","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c976","validatorIndex":"0x46277"},{"amount":"0x1192ee6","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c977","validatorIndex":"0x46278"},{"amount":"0x119bcc9","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c978","validatorIndex":"0x46279"},{"amount":"0x118f663","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c979","validatorIndex":"0x4627a"},{"amount":"0x119b5ce","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c97a","validatorIndex":"0x4627b"}],"excessBlobGas":"0x0","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x121cc2","uncles":[],"parentBeaconBlockRoot":"0xb2fdced42678407cdb560649f70178a2a0e4095543930548bf164b7b936eff36","size":"0xf8b","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x0aaa0d653c3a6ac90de9ad896e60eef01d41c95863411c6b24bd31e59e32fea4","stateRoot":"0xc258b8b986b5003f4a051c625c427e7d93fbdf653669468727bbcc25b1fd1919","mixHash":"0x253d73a8035e2de53f82869fbdd8a700c96604da0485d0a02b05eebc53f615e3","parentHash":"0x27c8003b8d5ed3a0dfb4313cf8e969478176df308cb8ff7590f86323469046e2","blobGasUsed":"0x0","timestamp":"0x663811c7"} \ No newline at end of file +[{"number":"0x12e3b68","hash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","transactions":[{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x485c7c9ae78a17af338eef77267accbf73d3a24be86cceff8ab041ce10388b20","yParity":"0x1","accessList":[],"transactionIndex":"0x0","type":"0x2","nonce":"0x8e","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a000000000000000000000000071f755898886f79efa73334450f05a824faeae0200000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0x3efde0059a9e20313ee5a466273604b3e79d199a60b2c44e753f5f2fe56eb987","s":"0x40eca86c1d87c685a3024af4a0224dab92758dc1990b8f8ecb6040f88498ab1e","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0x71f755898886f79efa73334450f05a824faeae02","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b832f7b98df73773fee549f702b87332ab605baeab66a725582089dfb8c8716","yParity":"0x1","accessList":[],"transactionIndex":"0x1","type":"0x2","nonce":"0x6a","input":"0x088890dc000000000000000000000000000000000000000000000000000011b15df428b300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000a890e6b83ac95c7de4ffd4549d4cd282b407b49500000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xa884ab9e5c1057e2e741e5ad4c6335f655a0dd248b3a6b7d7d0eb450ac2cff8e","s":"0x7befa7f3480ddc589444e0d4498e0fd68fa765747676bafd9a128c6dcd91d5a1","chainId":"0x1","v":"0x1","gas":"0x549a1","maxPriorityFeePerGas":"0xc570bd200","from":"0xa890e6b83ac95c7de4ffd4549d4cd282b407b495","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0xdc778ba13","value":"0x649ff6f7003174","gasPrice":"0xd7a25d20f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xd119b49569af4d5882efa6c72c84158bc1a9b8ac8f632706ce810f627ab13fb3","yParity":"0x1","accessList":[],"transactionIndex":"0x2","type":"0x2","nonce":"0xa18","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000dee90fc88ef3aceace9a22d2b2921906b724455200000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xd244c53d24ffc3b2fcdfaf692d82593c0bb8cf3369b2a94c91c2c0249c4510a7","s":"0x751ca6879dce7d240443728d6e5756fa78be470b7ebd94cf984a1cb94f9f2c30","chainId":"0x1","v":"0x1","gas":"0x35b60","maxPriorityFeePerGas":"0xb4ad34500","from":"0xdee90fc88ef3aceace9a22d2b2921906b7244552","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x1cd918d39380020","gasPrice":"0xc6ded450f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xc02ea02af1da253b9cf3d1de648c3355211f490cf4b8641b3146e69450870ba6","yParity":"0x0","accessList":[],"transactionIndex":"0x3","type":"0x2","nonce":"0x28b","input":"0xfb3bdb41000000000000000000000000000000000000000000000000000708ccaca7c0000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000fe6cf59162f319fb2c536f63a6121eb88dc85a3400000000000000000000000000000000000000000000000000000000663811fc0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000003339474491b13ac638f163d634fbbc722cd27916","r":"0xb66d674b17cb04d44900455636b496131fdae9b8e4c81f790854bda351130e83","s":"0xdb241292520a7c135d381b0fd18788c9490aff4b756d397453a6454da4e0a3c","chainId":"0x1","v":"0x0","gas":"0x35b60","maxPriorityFeePerGas":"0xaa9e48a00","from":"0xfe6cf59162f319fb2c536f63a6121eb88dc85a34","to":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","maxFeePerGas":"0x15c508c700","value":"0x102a336dba60000","gasPrice":"0xbccfe8a0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x6b66220ea1cfac82ed5639293cbb0b5acaa956a348999648aacfc202f5a6451b","yParity":"0x0","accessList":[],"transactionIndex":"0x4","type":"0x2","nonce":"0xba3","input":"0x3d0e3ec50000000000000000000000000000000000000000000000000001d57eaddeea78000000000000000000000000000000000000000000000000023bb9178b0192be00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000c58e4d309c4f5c88afe355c260ee9a1a699ed1dd00000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f00000000000000000000000000000000000000000000000000000000000000020000000000000000000000008b683c400457ef31f3c27c90acb6ab69304d1b77000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","r":"0xdd70145d23e041328d8242858ca9815cbb03bf408dd7d81e30532932497838fc","s":"0x496bf86926d61a533fa5824c9d21271b8b1597b48014282168a48575f8cf417c","chainId":"0x1","v":"0x0","gas":"0x4dc2f","maxPriorityFeePerGas":"0xb2d05e00","from":"0xc58e4d309c4f5c88afe355c260ee9a1a699ed1dd","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x0","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0xa16262586a442817e5766675bd6ec767ebe3815e7ae325248acdcf54de4561aa","yParity":"0x1","accessList":[],"transactionIndex":"0x5","type":"0x2","nonce":"0x162c","input":"0x088890dc000000000000000000000000000000000000000000000000007af53217af31b800000000000000000000000000000000000000000000000000000000000000a00000000000000000000000008693ca3483daf299aad023eae75221436d6c11a000000000000000000000000000000000000000000000000000000000663811c80000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000f1001ad1ee7743e0f6715f50cdaeb1397d5cb4fa","r":"0x2c9a9ab0d7eb2503a5ebbfe1a66c2f08a9170e1da5b14cdb142fce831522a43a","s":"0x360ecd3be1f224118862ddb78787cf31ad7600994b6c7a4a947ae3a071619a8b","chainId":"0x1","v":"0x1","gas":"0x461c6","maxPriorityFeePerGas":"0xb2d05e00","from":"0x8693ca3483daf299aad023eae75221436d6c11a0","to":"0x80a64c6d7f12c47b7c66c5b4e20e72bc1fcd5d9e","maxFeePerGas":"0x2233d4613","value":"0x2c68af0bb140000","gasPrice":"0x1d5ea5e0f"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x1d0969550eee06cc9bd992ccceaab28c5762feec4d69cdca3dbc50927263bed9","transactionIndex":"0x6","type":"0x0","nonce":"0x0","input":"0x","r":"0x6b6a8c636721916ee32404201135745eeb2bfad873e662f5a59c331cb6647a95","s":"0x452ae97ab3fb5bd8e4cc7890b28876a662430c40bf643239303e0c86770c96bf","chainId":"0x1","v":"0x26","gas":"0x5208","from":"0x17032783b5f29c8a68e0fafba4db021f248409e4","to":"0xb27b03580c193d324931acb143f6a1f3477e702e","value":"0x1ff118a94dfd000","gasPrice":"0x1a13b8600"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x923e060de69675c90d67472ca7a33e61630f64b92e20224db08055c5cd4eaaf3","yParity":"0x1","accessList":[],"transactionIndex":"0x7","type":"0x2","nonce":"0xbcb0","input":"0xa000000000000000000000000000000088e6a0c2ddd26feeb64f039a2c41296fcb3f56400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000099f388994000000000000000000000000000000000000000000000000b6ea0676d933c915000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","r":"0x269fa6d550e1ce6f76884a87645bd2a462c303dca06423f2f0638a572109f0f7","s":"0x776dab3e59d703ff24cc45be1b856a73f66facbd0c5d6c41ecc940ca7e02416f","chainId":"0x1","v":"0x1","gas":"0x61a80","maxPriorityFeePerGas":"0x34fd4acd","from":"0x93793bd1f3e35a0efd098c30e486a860a0ef7551","to":"0x9def7cde171841a9f0724124ca0b01a622d749e4","maxFeePerGas":"0x158174adc","value":"0x12e3b68","gasPrice":"0x158174adc"},{"blockHash":"0x0b4c5b498320e5858e7445a5af10658ffee39c9a39de22c81452de5421f63464","blockNumber":"0x12e3b68","hash":"0x71845c70b3ee8a2894f8e5bb833639d1a6a80286eaf2d5b732ecbe8e30ec1346","yParity":"0x1","accessList":[],"transactionIndex":"0x8","type":"0x2","nonce":"0xe5ad7","input":"0x","r":"0xe0c1666544ae41c9fecaba65277c51af8755838a43c6e5bdc15c83970af18461","s":"0x405b701cfa1a3b22fc547c21955d55210f7fdd87b576466a2cf30cb27e9fb442","chainId":"0x1","v":"0x1","gas":"0x6ac1","maxPriorityFeePerGas":"0x0","from":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","to":"0x617c8de5bde54ffbb8d92716cc947858ca38f582","maxFeePerGas":"0x1231a000f","value":"0x6ca54625d8e66f","gasPrice":"0x1231a000f"}],"logsBloom":"0x002000000100000000000000801000044000000000080000800100000401010008008000000000080000084000080000020000000800a0005000000000a0000000000000000000080a000008000000200000100100400000000000008000040000001020020000000000400008000001000000000000041100000010000880000000000000080000004000000000048140000001010008090800004000400000020500000000200000000048000008000000000001000000002008000088000020000002000000000000200000000a00000000000000401000000042000020000050200000000810800010800000000000000000800000400008000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x322e0b5db82824020e3247d491fe8e36688d881392cd63af55f958df0aa95725","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x611a5e88d0ffbe176e4f6409bf229792668d5c96d6e47b519a3d5653fc723973","baseFeePerGas":"0x1231a000f","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11a0834","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96b","validatorIndex":"0x4626c"},{"amount":"0x11a27fc","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96c","validatorIndex":"0x4626d"},{"amount":"0x11b88e3","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96d","validatorIndex":"0x4626e"},{"amount":"0x11be16e","address":"0xc9234d5606e02a0acdb7682fe36adb588cae60d8","index":"0x2a4c96e","validatorIndex":"0x4626f"},{"amount":"0x11a1416","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c96f","validatorIndex":"0x46270"},{"amount":"0x11a2dc0","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c970","validatorIndex":"0x46271"},{"amount":"0x11a42a8","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c971","validatorIndex":"0x46272"},{"amount":"0x119940e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c972","validatorIndex":"0x46273"},{"amount":"0x1199000","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c973","validatorIndex":"0x46274"},{"amount":"0x11a046e","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c974","validatorIndex":"0x46275"},{"amount":"0x119d364","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c975","validatorIndex":"0x46276"},{"amount":"0x3bc7b17","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c976","validatorIndex":"0x46277"},{"amount":"0x1192ee6","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c977","validatorIndex":"0x46278"},{"amount":"0x119bcc9","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c978","validatorIndex":"0x46279"},{"amount":"0x118f663","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c979","validatorIndex":"0x4627a"},{"amount":"0x119b5ce","address":"0xa8c62111e4652b07110a0fc81816303c42632f64","index":"0x2a4c97a","validatorIndex":"0x4627b"}],"excessBlobGas":"0x0","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x121cc2","uncles":[],"parentBeaconBlockRoot":"0xb2fdced42678407cdb560649f70178a2a0e4095543930548bf164b7b936eff36","size":"0xf8b","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x0aaa0d653c3a6ac90de9ad896e60eef01d41c95863411c6b24bd31e59e32fea4","stateRoot":"0xc258b8b986b5003f4a051c625c427e7d93fbdf653669468727bbcc25b1fd1919","mixHash":"0x253d73a8035e2de53f82869fbdd8a700c96604da0485d0a02b05eebc53f615e3","parentHash":"0x27c8003b8d5ed3a0dfb4313cf8e969478176df308cb8ff7590f86323469046e2","blobGasUsed":"0x0","timestamp":"0x663811c7"}] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json index d5d698878..6537bc456 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main.json @@ -1,4 +1,4 @@ -{ +[{ "block_trace": { "trie_pre_images": { "combined": { @@ -363,4 +363,4 @@ }, "checkpoint_state_trie_root": "0x319da7faf76836d1ca1c48e0540a97c0d7f2515b7fd7be7dfb1aef9ed5dd588a" } -} \ No newline at end of file +}] \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json index 59e76e72c..b2fc74151 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b19840104_main_header.json @@ -1 +1 @@ -{"number":"0x12ebc68","hash":"0x3c869591ac4295afc75154eaaf7a8b59a41af3cdcbad9d8c48fb7ef9853f9ec6","transactions":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","extraData":"0xd883010e00846765746888676f312e32322e32856c696e7578","withdrawalsRoot":"0xe4d8d88a7e20aae7598822ee098c466e93c501377e1d302013f9f017944f8733","baseFeePerGas":"0x1aafac7f2","nonce":"0x0000000000000000","miner":"0x0000000000000000000000000000000000000000","withdrawals":[{"amount":"0x119204e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96b","validatorIndex":"0xfa8ea"},{"amount":"0x1193fa3","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96c","validatorIndex":"0xfa8eb"},{"amount":"0x118a669","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96d","validatorIndex":"0xfa8ec"},{"amount":"0x118d295","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96e","validatorIndex":"0xfa8ed"},{"amount":"0x1195db7","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96f","validatorIndex":"0xfa8ee"},{"amount":"0x3c46d9e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd970","validatorIndex":"0xfa8ef"},{"amount":"0x118b8bb","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd971","validatorIndex":"0xfa8f0"},{"amount":"0x11994d6","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd972","validatorIndex":"0xfa8f1"},{"amount":"0x11822b1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd973","validatorIndex":"0xfa8f2"},{"amount":"0x118b828","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd974","validatorIndex":"0xfa8f3"},{"amount":"0x118b7e1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd975","validatorIndex":"0xfa8f4"},{"amount":"0x117492d","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd976","validatorIndex":"0xfa8f5"},{"amount":"0x3c1adb5","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd977","validatorIndex":"0xfa8f6"},{"amount":"0x11713d0","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd978","validatorIndex":"0xfa8f7"},{"amount":"0x1197bef","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd979","validatorIndex":"0xfa8f8"},{"amount":"0x1181b16","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd97a","validatorIndex":"0xfa8f9"}],"excessBlobGas":"0x60000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x0","uncles":[],"parentBeaconBlockRoot":"0x5ab8b5a8f53fb6e010ee24d46334a9ce1051a5ba1691b6383ce8b2a03c10f158","size":"0x4aa","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","stateRoot":"0x101798b8e9f085f2faba1e2749df2916029c6c507f4f388c816ee6f9977a0a98","mixHash":"0x2e5e4c5b459345002e2597c5b8b556f0fb51fd9c6c45f7892eb98cb4de973795","parentHash":"0x290e2c3125591d2f128758525955799fe08eb933dc0e22519810e63a10f0ea69","blobGasUsed":"0x0","timestamp":"0x663e28fb"} +[{"number":"0x12ebc68","hash":"0x3c869591ac4295afc75154eaaf7a8b59a41af3cdcbad9d8c48fb7ef9853f9ec6","transactions":[],"logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","extraData":"0xd883010e00846765746888676f312e32322e32856c696e7578","withdrawalsRoot":"0xe4d8d88a7e20aae7598822ee098c466e93c501377e1d302013f9f017944f8733","baseFeePerGas":"0x1aafac7f2","nonce":"0x0000000000000000","miner":"0x0000000000000000000000000000000000000000","withdrawals":[{"amount":"0x119204e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96b","validatorIndex":"0xfa8ea"},{"amount":"0x1193fa3","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96c","validatorIndex":"0xfa8eb"},{"amount":"0x118a669","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96d","validatorIndex":"0xfa8ec"},{"amount":"0x118d295","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96e","validatorIndex":"0xfa8ed"},{"amount":"0x1195db7","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd96f","validatorIndex":"0xfa8ee"},{"amount":"0x3c46d9e","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd970","validatorIndex":"0xfa8ef"},{"amount":"0x118b8bb","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd971","validatorIndex":"0xfa8f0"},{"amount":"0x11994d6","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd972","validatorIndex":"0xfa8f1"},{"amount":"0x11822b1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd973","validatorIndex":"0xfa8f2"},{"amount":"0x118b828","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd974","validatorIndex":"0xfa8f3"},{"amount":"0x118b7e1","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd975","validatorIndex":"0xfa8f4"},{"amount":"0x117492d","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd976","validatorIndex":"0xfa8f5"},{"amount":"0x3c1adb5","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd977","validatorIndex":"0xfa8f6"},{"amount":"0x11713d0","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd978","validatorIndex":"0xfa8f7"},{"amount":"0x1197bef","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd979","validatorIndex":"0xfa8f8"},{"amount":"0x1181b16","address":"0xf197c6f2ac14d25ee2789a73e4847732c7f16bc9","index":"0x2acd97a","validatorIndex":"0xfa8f9"}],"excessBlobGas":"0x60000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x0","uncles":[],"parentBeaconBlockRoot":"0x5ab8b5a8f53fb6e010ee24d46334a9ce1051a5ba1691b6383ce8b2a03c10f158","size":"0x4aa","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","stateRoot":"0x101798b8e9f085f2faba1e2749df2916029c6c507f4f388c816ee6f9977a0a98","mixHash":"0x2e5e4c5b459345002e2597c5b8b556f0fb51fd9c6c45f7892eb98cb4de973795","parentHash":"0x290e2c3125591d2f128758525955799fe08eb933dc0e22519810e63a10f0ea69","blobGasUsed":"0x0","timestamp":"0x663e28fb"}] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json index 6889f1cce..247fd5df0 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main.json @@ -1,4 +1,4 @@ - +[ { "block_trace": { "trie_pre_images": { @@ -9195,4 +9195,4 @@ "checkpoint_state_trie_root": "0xaeaab1c6af58526a7a36de5210273f9c7ce2dc936293520b2ecb19b1d786976a" } } - +] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json index bd989382c..9e6b54658 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240052_main_header.json @@ -1 +1 @@ -{"number":"0x134d6b4","hash":"0x500c31e728a280af1add4799095e7229d4a4cdfc6c9c73a62434703ffe34045c","transactions":["0x66324d0360eea71d5a5e6d0bc0dbbdf35cbfbc3a3f121d028ad34c11426efdd2","0xe305bf3385425fe0387d926334de3f03150b31233df76fedaef472d635560e78","0xe410fb642fc29d34a9ec92a1ed3cb48748e2ac8fa7cd9c8315fb29656a8fec1a","0x247fa2b38f1fbf6758609e6d5cdc0f9dc899f37735496ecb95bf734eafd360ea","0x9d10a0dd7850ff99c98ec13b3e65905d1242875784b2d5420be80ac2e3f45c4b","0x53d7fddb6491e17eb15ef6d1e8ff3027735905bfcdfa66b3dae56f973fc2576e","0x40c52b14161c3bb6ea8914fc8a7e55852e0a51d36be4a43835015eb9cc330063","0x5df2a9b9eb1d800c76a1c6c90019e0b6dedf71e85764ed80d9cbba1e8e75cc4b","0x0ee9f351711baf9f66d36fda5c4e436b45c4942936d088ac826dddf781f2bdd9","0x74109ee77c85494337ca6db2975e00c9aded34403b64c9189fe22e7bae3bc4e1","0x9c53f84c1993f87c5ddeaea655780c24c9e265644ff89c839564802de661e4d6","0xcd13d2d4292e2a03c099f60e5db2de058459262c5dbe70ac792f533e47e15b09","0x03b719dad83d99a2eb847751faf36d4663a43d936f1c66948b139c6fc82209dc","0x2f417d2c35961dbd7cb522fa0ee06c95aab12b3d6a707ca8f74f97953fa34227","0xc26f561629de18df96ae9c1271912a90e7d67a9b85d99f603b63e87bdfb68e93","0xa4c4e1851441c900b82d8b90808f59535599884ef3363a5f46c05ef309f12c68","0xd3fad4b38903dfc6ff22954674dcccaa232146c3c6b60687dd1fb6bb61b95c46","0xc2f6717a22fd5b1efc93f59751e2467ea872777782e9201160d4af85aa16f91c","0x4baed9c20161fb6ef4315a198386a4c894f146fc278555e3f87c7f6e18d76c06","0xb91012cc7b849eb66779a8706453556467547c41b93394c36503141b4213a508","0xa33cb80d6bd6e5994c35c49250a00c69d49714e9ef343ca18901a4962e95cc5a","0x1fba689d944205912a77de9fcc53f4ea553e58240f09439d9b6b984495ae16b5","0xeaf101fa2a459f6b9812bba88b42dde5357befda42a35b1f5b5651cbd514e9db","0xce1e34de415dc7ba30c2a4d655c3f3e650275c323518ff2a61015d65cdd5a0ec","0x3d87d050821056a3ed8c1a3ada5bdc1dafd6483459f09054f5ec5112c3e2e833","0x60a7e890a6db8b50d93992c461dc16b49f57f6855fc8dfaacb1a525830657ad6","0x143336aadce774b79d069b72eed4d615df1078df98859476982ac00f35dfef3c","0x17e5787cdadfe3c01ae34f23ecab84d90a0fde083d1a5770cb1349b48ea49d45","0xbdb4b34276389846d8e7cba137033a3fabee90c084fbd65c840839fffddc0d2f","0x230eca8906bf58d6017fd8f3057a2c7e05de885b302b5c349c9d587659cc366d","0xbda38f281b0127034ca3d9b3726fe9ac68c800f34990069edfc8c6ab8cfc43ce","0xd58df4c85b7002b5762707b82d29475628319fa5ebd98dfa4e57721c78d5adfd","0xba4ce9b4cd284b96eee2f8db9db065376bbc646656fa04b2d2a623778b24c300","0xd5c2b6ce545a05378dd92582f6e3c77d1aae42cd88a174bce287073697595f8d","0x3c4295faecb8b630259b5ab875e1de2433d0f384d72bd836718d4384d1c7325e","0x46f5f9ef7efca04abc8e45fa48cddb5fc80493ae07ad943af7f10d94df6d5575","0x43244bec21354c3c918afc71ad11ceeeacadc8d9a114de8ee867cfd592dc63ec","0x95da6a534725726a0f4522ad3b5a81f79dd611290136f58506b7eb6c71b6aa6d","0x5a06e4cf4a51e7060d772d3052dd752789d9a344bcccfd3d5642774f8bf21dc5","0xe6dc810bdebe5c422bd9dfa2b444aa848300a9e7caab28cb856c95a40b68182e","0x153b92c7a60749bb79016c97d717c9a1b68e17fc237ad20763d4bfe9eb31443f","0x3c57f44269511d1ebb682f5b4de53f45bc6cb7bbd455cb18d971cc2a5414f4cd","0xfb2f82babaaecfb5190912074f1382706095f5dc04d7b8851b3de2f115a6cd96","0xb930db9657d311ee70e826e1af1595eb34ab0d9fef21599761f8eb6b57289a72","0x26de40a55c59c5d3e10bb86db6f012536cf65fe1599c589c6eeb32b27d9e7a64","0x90faddb5707b8c30beb8efe3b47d4d2b6bb2174088dd5717263e73cd36936f95","0xefa678a2771fbd1534bf85857d20f4b902d6d26e87e7a96af0e1e512c449c76a","0xede6ca6bfe169da516d0b0a17950d6b88f6d97f9a01569fbcf611504a7815f75","0x132a5b1bd116f732dbe91146efbe8f002411fa80d2113c3ad43c60811b50ba33","0x42b01e6112cd30609f68aff8c90e999fa7d07c169a8bbbababe15ee5d38be66f","0xed60c7c83d4831f55fcb573c8d7417fbe9bdd5d449d54daf67fd3d8623f1a297","0x458ebf545d76f78dea87cb03417bc2d299d669223e2b9815bada877a026df63d","0xdf1ce874ef2e43bc1413e05bf0652acae985b6d94f8a9fdd060a70a61ea8e0e1","0xf977ded6ab95ef5a028d10344c960e16838b81837fcb3f3d15128e9c66ace584","0x733cac76207545f35f1c99ee1145b403d31e24da8cde0a70eb3c25515367fc7e","0x5d53e264ba107ae92f4683bc126c5f0c38aff9a6cda1fd1c743a453b4870f4c1","0xc347abe53a5b5020420ab0da3eb05ec67c3bed42ebbe091f2f94f6d9c2fa168a","0x94e61a2fb7550c453a0c7500fa279cabf1fc661ee8c8dedbcb2479d5a8982196","0x945bc4e094a800c26361b627f67616ef4835cec4dba6e58119d68f10e6a1afcf","0x9c4116447040232cb1f5e13059e4ba12c2db501e45f78cf97f60b0db24695b31","0xaf22df09e9921d45535a0f5f80ea607a860d51681e02b9b57e8c53d74cc36310","0x28e6ee2a48b3c780affb3c124d4ce27acec3d40121f4607ecd565c70701c085c","0x95aa1652585dd525dd926368cb936fac87f81625ff6f6eeab1f2288507b61289","0xa5f466f9b62fea39daf0e0fd3c47d783de4aed4dea1d11d93ab0502f3a4489c3","0xf5be04d59b7c36b75ce6d86f02161123f2e5ad02d5f6e8cc7bacd7f2ec1fd206","0x425a10965f389cfc278c7300ac9a27e7891b178fc39991abaac7848f7089d487","0x3be1373318ad87b9957f5b7b4ae602aa19087b4177f3ba255faa19c576a63f7a","0xf250f0ffb6d574b82a1dad285b17835d68779c7cdb59d7f96794fa945fd4feda","0x13d9d1cc11e7f1af51099490be740a996eb7eb4975daa1cec851081c76805e01","0x41f03ef64f0015f1e8ea93f4381407cd12c83581eca09f10d124c12864a24f35","0x4ca92077f33bdc962bd76f59eb1327a096b9330b7e69393c16589c71c61efe1a","0x499d2f13d41a9e444e882891f3105b493112db8c188e650101916a6c00aab571","0x63afc736e099316f08c559498fde320fda3c5175605aee71dc767c41ba00a2a7","0x481ff76b4c9b60212a2cd281bbe79d048c2429e00ff4be2a86ccb87b863165c0","0xb34048c9549de5042db2c0398988724104dbc5e9470088583c2cf6c348b3dd7c","0xba9f94b5b8372d6b431b8735ab4081101aa9b7bda951d912dc722499c598a83f","0xc5a6251e55564b17bf44f7aa6d21cdd20f658d61a8a84a25c04fe4581895d5aa","0x3235c94fcdb5f9ff29cf70efa34af3ec931a3d1694beb027f0fbd5069ff4ec65","0x5f7915e8d005d97fbd262f31ae861e10a3c585a57a0f118ff0789bf045588f99","0x1d6290be9ed40cb5a458c03bb04342b4f14143bc873b3d50c3fbd671f3db7438","0x65866fc1fba54dc4e6bc0e82746757b49869e359726dcabc98cde74d8ce00c63","0x3d515de1807167f4230d8e68393f3d90cd396821bc8dc05282088caa9191e9cc","0x8c2c4d28db1e21b60f29b19a1035a6911e892a1a91609009d38e373279a56243","0x83df9f5987e06e737e6a28e40175e261dc4936e7832b746207f28c87d8373c5a","0x2d7d7fd66d324c4c14d05dd100ebfc5bc9b945b85a4de4a4520decfeb86e531b","0x0a4acb940c53253539d4b3bbcf7752aba3ccf240285f664a4cfbbd72cb192d48","0x193376115ab2d506755b01beeb7b88012559cb78efed68131ee944addff240eb","0x489e003f7d85c8365f378af589c2d83d6a622e85b6fe0ba58e6ea03c62a08e4a","0x8de8197d07d9f2b47a4316871e1836bc0c405b050cc6a5a27dd9faed74ffffb2","0x592578b40c288a1e25e65f6a056da0124db8bc97fe1fc0a904251ee5f87828b9","0xef29e4bc8e60d8fa76eda5f33f961ac1d36f9f13efb6c1c7a58402733f17a9fb","0xa116a77605deec75b2070955445c9d793b05e50f099d4d1497e34eaf87ed5646","0xa15aae1355633ed2ae9283334bf6db5cf5cd76e0134870389ae8ae744a7bb24c","0xaccc10ec12c433e98e3c27d44e5d5f18400fcbe13a8ceed4dd68dfde57c15449","0x6cfb2131e6b7e25e1ac468a503728903690dd5581fc8bad33f1eff4794229a34","0x4ed2e2e41ec55d6a5b42f1672fb89c619183ba003af4474162f5499c1f163498","0xddbf5ffc8adc9379ee0cfc8a7642c88b327c399a85ed1edb8c9b3960ebcbb9ea","0x08d7c8342bab8fdb4e79fc3b7d75616254df38af409d1d9f84657fd3ddcf69f8","0xd4001d19e4225a3a5cbbfe2934d2775105a7d7d8818b7cb98703c33012716110","0x2062cc1d24beecc20057ad331d690508c748e21d3040ffb37b38965966a3d3f0","0xe3836b1fffecb32d2aef998b4d3c0d606ca9ca2b002661a8f184cbe4d15bbf78","0xbf814b35d87c58629568108a5e1176f67453a1eeb324a510d00b927c477182b0","0x769e8a0d5da47949435d6f4d10f0c61c5dad97e492423675fa6db41580c553dd","0xc7e5d496ba456c2e79f504bae6b2ad6759bd16fe24e1322c9ab69ff971cb6040","0xfb2a55d870229c5128aabd6ac21cf4fa02ec0938f507c95267239818ddbbc2eb","0xbacc62ef0a1edd91c4803c5be166926d737bd76bcb129f4a6f57553a09ce535b","0xda567db58bdd46ea35271e1a53d29375b06054c845bba8f4cff3b0493125d12d","0xc31700594d2f23e26a90d4dc5af926b35a64dd7ccdd4049916302426a491b188","0x40e80109207cb7d621545f8f1c5436e2c3997eec7b521c5e0ab8373b05365b64","0x6d24f1451e0477cf59b0d99c18d6bd1d5aef818728886b9be3643fe7ae10701e","0x906d4b0e8f0a3a1b129138e453ead10750ae4cecf517e01b6bb99340bdeedde4","0x44d615725dd6a00816fde0b1767256e8d4a6796a6d1b2d34844d1389763bad4a","0x42182c0aea8452bf6d86618a0b5ba0237882d158eca83591fd2a7e0c4e123d9c","0x22151212da28291a917d43c2420cc5bc3fe8a0379607325cbeba0eb753eee1a9","0x90019486ad21e98d87ab8965de800d56104267dc2416d399d689ea159221bffd","0x64c1844e0cd95031ca18564892dfc038ce8338ee1168ff61b50ea34f9aa1b937","0xf1d5278d5006bb81ce58798252d790ff95503b63947c1000e7a742a8b1e320b0","0x3dcea3438fdf4b53b23d996f5714d4af758ffac6b82a03ac7d153ec850866bd7","0xb357d9022b4ddab68631c1ed393b46ce5b8048a69f98b4f8a1ea0bc86036c88d","0xfb608c5fb250b761fe4c44479ec398cedcc0f19f8196e96912bd3c02bec93557","0x3c30908976f14f75f5d48c0e61f19af6d417544f79424a737902787382dd0966","0x80be3649036b61d382618ba38055e3a6dbad22906928de3e58ceff5448e414c9","0x8d6f918cf7e15bbf0b9bb90f58a6477e050a7be687a1566ee2e34cf71e9683b6","0xaa3663f978d98ec7c3f5db5bcc547c22b55473e072325444be995b49694b68e8","0xf0dfde881f6672c39b92559e62bfb686c1f396c123ad0b078215601cd7833de6","0x100032a9090d3436f4428af12e4ac03aefd95cf8f54d91dafb898553ac65bb76","0x0813eb4603deb99d240bc27fb033d79b750485b255ad5a21718844e68afda6e0","0x564cf32bc2ede84eb22061684320c87877b13805b378ec9cf351b880d94d0e90","0xaace17676be5b8a1d00e4b21cf8de0b31d611a6037d6b6ba427c518c5dee93df","0xabaf2c962dbd67db95c6fed916950ea39ee021ee2ca366dcbae0791c1995eddf","0x55d2836440ac765764d2bc093143f4d33e4c76a67b24b63282129567bdd18891","0x32fbd38f876ee907ab850539e8622734b2b6166bc3c497a63bd9705ab8ff309a","0xe6b3c13b048842c64b4b2285a3d95537bea9932568fe44a14da9d96fe32af38e","0x326a95b803ec456ecf879056c0a062ec867c2b1fe77b5d7543886f744f9fc054","0x76e3b1f93f0c70797f32d34ab16c22aba26897b262bf3b9fea05792c0e44bc99","0xa406ddd554632edbd8fb29bf48239d32379377d9964d63b56a4b58a6342211ae","0xe507f04062a919707c1c3646fd9dafa6466ba9a5b99a45a5f711444074dfdf1f","0x9d8f75b125afb460c73bc48045e8e188e23230c97c10d7c1af65115a9109a3c5","0x1fd09384af3072d7ee6072df6301516d3a116faf3d22dd9c6dc455b3f3928740","0x496962b25aed0d28012906d7a640d01fbab66f4018b462a1ae53a063c0dd3679","0x78063ab277b776b33f80e283670082686a2462fe895c9bb9d330c767c0658f18","0x6d131d2dc122bfb19c76093de5ec81953dd9af621fc7b4585a59ce285a864aca","0xeb51833fadd3b8bfad8a02e89f2e8ecd27d8ff53c7c52ae13c12b4188369d6f6","0x6b8cfc3843f0a4bbe3e386599824431c874d40fd2c175353670fee2e8b81533e","0x7e09208d802733a55e117295f0b57c82e3e5db785a15b739746148e86830e413","0xf0018894e8d2f87813830ebeed5461ecf5281508021664665742dd7e94b15941","0x2142c7fc110bca3accc867ce813dae6b488fed792140796c78785cfe8371c511","0xe6517260872c2d1cffc2bc7f58d3c86645182a272cb6fae9755b7c84f46e12c8","0xe1a71aef34f4be1bcf8bebe2cbae269e8b6e527f6be8f58954346459ad64e54c","0x778a07a701524315fb01cbe4d04e89258ee7cfa6e2b4cccb08ee14d23d83d0bb","0x33907d1183d22ba055b1ed6587a5c1da14824ae516557d1aaaf32990bbe14747","0x6c3bc5aa7785b1d2b87e50aefbaa2d6a567c5604cbda95a48688d71ae46bdece","0x931dfedfe7d7f1376930ff1d99b6a2029b230386b0cf75a39fbac8380fee8e35","0xd0c77c7c70597ce712d58817cfb5b6e97b48de4bd6af393a64a5965701355003","0xe4d21108ca8e6a470dafa942eea205523c296cfefdb49ae53e932dd01ddaf84f","0x0b6b90b3c8786d4a67178cab8c41fb640fe2f7ad63c3e149e12bb22dbfd18012","0xe606244314e4b255a5c6cce60b576c17674dace61c4154c7f9fcd41cc56cf322","0x960ba88a8b1bc543da5124bc09aa57199c17ef37202587dbc8af2a4d90a2e47e","0x839858692b3a211b079ab222e5b8562c6833102a675f0881adc7a8ab4e14cdcc","0x61cfc1d59bd8b930670181f27237f9474eb676cf9d852aa79b5f871c761a2af5","0x56bff44d1fa271202f8d55b54c78c9b75ed53dcb555e9b8f92c4810a270357ba","0xa3aadc8e65bc5430f528f93b0c726b015a2786539fd1f8d850e6920cfde0ea4b","0x12fd47af11eeb08a9115c967c8c409589a3a1d583641e446f54b7535b200bf62","0x5061b45dd10a197ce6d8b21f21075f3bb79e2bbc035fc38c2b4ea715f37be67f","0x84e9a7fefa6122f61a757515ad05f8851f4eef88b11d5612093ec9a206750790","0x9260caf0b005584f7ac5a391df5fe2a2ba270e3e26fa1bc8e522aa1d4c263e7d","0xcd8626836baa047d6459fa00a728097b5b7c740c8800b1630d2c581403fe3905","0x79cd85af2442851aa4fd2295ef741ed935b212e5a155e37aff20a6390b885c14","0x21fe3176027e96bc49a7f7c49e12333c158b663bd03ed64398a2ed3d84c2d094","0x73b5fadcd5aca1a0c30d21823772bdf89512d81336d666dd721abd7e55cf3241","0x8a76f963963517352fff4307ab8026c36777fd47c392622cf0dcaa1e02634b09","0x170c25cc700000097486d3e58a3282108d173d6cd05fb03f4ee338cf3a4e98d7","0x9d44390378e14f9386ef7ac2821d8a1502f242f568528a8776697a455f03443c","0xffcdbfb5ce2e40f33d2ff957faf7f28790a2fd50948b358f430fe3bf9a744442","0xb414778b97281156ca05a5a8620eed70cd7b6eac94cc7194b951b4a43f253c97","0xcf4aeb1257d707c611b02247bbbed867bd4d427cc5c65e4552d2a4842198eff6","0x26dfa7935ba3a3de6ad649e215a48d0602743867d4e7bc1fd55039114ebdbe25","0xa3db4bd9f6c5ab9c0394e592f6e2ad56b0e16ccf7ae5400d2fefba50cf6a13e0","0xd49951086f7c3cc0d78fa7f06241edd0c514ec180bc3dfcf7a6ffd790f6ded4c","0xc1d1fe0cbbd448f65829e2c10783a1461f555f9cc4b41a4ad0b9a7d1a765d9df","0x37c77b747b9efa641342e1bb85f5cc3f4306aec4d7449f7a12d43025c813fa47","0xa052f59e3732d89bee1d7d4490340a42be97c05a3d7b270baae0e715422e481d","0xd03708cd291234da34a99fa6bcf69aca54fbb9b43308b4057959b8534fbcea0f","0x21ccd23bd7f7d79f297d79c23ac3187b7405e1dac52c62bf9210a20bcde6bfd2","0x0ed28691c1b0913319fc7edde29153b7bfadf4ed5c11d75bbeb8a4711a04ab0f","0x08565c5067041f6d8f5f8cad5e39ccfc676d0371b960bd7edc6a631d9fa544c4","0x1f14dd0d18aeb08bd5345c41c31ec54674271c25ec4c442d82598ef1ee99596e","0x7ec78b696485e00fa80211d099c1c947b6a76afa64dcd21ed7fd11352e837bbc","0xdfa91502d2588788465cdafab98f01c934c5516eb043897158905169433773eb","0xf5d6107e5276b246713aa53a7e20a3bbfbaef981f7eda633dbe5402ffc4b1638","0x4fe1ec8d91b3aa59180a0414b33f2c6850e54729c03e22cf26391bee2371ccec","0x9290f637bdf1f5418702e4ddeccab62927659fea210916aff4e322dde9a1965e","0x2093ddc71f77133f222805e75ee536c1363d540bc64896d8854d980556b5eb78","0xe2135122b3adc2aafb5520f31dec24981d9500aa8edf97fdcc3ed03508ddab7f","0xf45b12961b80f82d864e3578f80ac92324b9ef2964ee66a71e58b6241402fff2","0x064a66b3cfe8921f5da142723d4fa2af7b24318305c05f2682ccd9a2904dbe48","0xbd5b0789cb9ba73eb665c8b0a9f8db68fed9ea6e8f965111696820b6e66947c3","0xf1cd611a0e1e5b54885c75d73db9e70aedd3dce765e4faebd2065a47593f39c9","0x17c9a4553d2f689e4da7e8ee5093596ddb3563a03a72fd7ee430b885bbbbc229","0x087120d0240951ec75b3c5c7b637e873ff02f347b97c73c8b2ff3186f3ba5f8d","0x5b0caa9b293799fe9a4ed68a88c74195c3102d3b2cf7b446b89d949b3f80f0c7","0x3f9581b4e3c61fd718c45b2490c8fcdb4e47489ab50a504825830b50bd1419b9","0xd47c0e12e513b6ede8fff4ea4f65aa7fe3ff751e0b16ab1416fb2627ccd81acf","0xf35a605751f0cdc926413a984506d4eab20ae09cd0a5edcc1f505e67dd426c64","0x876a67d7f9ed4e926fafb91272290a01758a9b9acb7af1ad43896c13b381ae69","0xdaff5644cfce09133cb6db783019f4de406f06f8686962e683fdbfd8edb47ee3","0x79f54807878a24229f57f9193ee144e9ad4ddf90f7cd38a70b9d63677f6b37d5","0x98e840f518c6fb10cfc6e2a59e907bb195d6a7abeaec350163d7242b772775aa","0x8b6ec07092cb61afbfeff775a9ebb6d26608e5d30a0039e59713a77874d02988","0x9cd465d2e0fc07c1806b64d34decc57e5426825527a61906413dd2156635c2ab","0x7afff2c624a94881faba70688887524c30539d9aa51060176902fb970da92c85","0xd891cb85ba08a9ceeae640d8dd38c19aebdf42fcb5f36bbee21368ba7975498c","0x513dac3a3f8156c50a837a6eb6c0b4d24aafb40d823905581e97f73a3bc67ae1","0x77cfb9ce0f011db6c1eadc298884fad690c9e92a67e31e5c44ae18cf346d93b1","0xe84a489566ebddce63c7a29c3b39c6b571312f16b01b40b39d8b253d70e2994f","0xbe3664ed0f7b6f45bd46896623d09f0f065a622595e8be9dac57ffc86f48264d","0xcd581e7dd7996363d5e0423f901ddab44e4a74003c7dd2086c3f3f2ae51f80b9","0x702c9f4aec5a17f4033543956e96216ec6ea2614ec6ed28d2cb017b668482d1b","0x82d92d5a9ea7f42b6704a2abc97da2ddd57f9d3ca5996bc8c9e5ee7abfd0c9dc","0x9d8ed0c4005c6114247549dfa93ad39aeabd65011bf8cd24bd904bf5bcbd5932","0x0d88d6d7fcdf2378636b709c13d7292089b1ead9a00f8d42559eb22b9dce2430","0xf29d043407991d3273105cf98898ce206b5222e1070a053f421dd67f76debc51","0xe13a05f255b6ed96309eea1d53672c01b04578ca3dcca4f9b5b157701e853c83","0x5c028819e9553e9241e65e708a97bf8cba9a21264e1bb766799a17fe75bb553a","0x453490ea5195716fcca9adefe393cb5b244ea36317a82f50ecfeaddf3942c6b4","0xa65d52957d4f30dfe1c7ec5b62901603d89ea42beaa4a07efdc10aac94e5b88e","0xcf7209723d41c5cb01b13b63222db5c21b59a5d713d80da55ee70c676c154d26","0xf6887497dc94f67fb82fb4c12716ce481300f7f58304823be885893e62e88444","0x794c1a37c5022eeaf034775994264379ed8df96609a23d8c6f1fa864b57f21c7","0x047cdfec0fcfc9db1fc7a19f82da9c6559ef428ca0348450ca885f1d442f9a02","0x72a9eda4af2f63511dd6c14968d21a54b593164f4059e45f60f8536a7aa7c9c8","0x0cae67e525a278502a93bec1534476561c268f61a10471a2361334f6fc0aa52e","0xc420e00f2fe8fcf4235cd0a1f27bf0501bd93b81d30e2f91335fab7c886c8649","0x2eb6e625ce3508dd5b90f47cb28385465366f1c4612b9ad57a8a305a28c19293"],"logsBloom":"0x5f3d66625185c33fde3dc0faec3998451b0b30bbaec520074f39c1fa8cafaf03887f5d8da0127c580b377b1cec1e0391eb91e3bd8aa4fcba4a91fac873be86e6415bc5eb860b5baa7d5e61acc3f18c2ba62cd0b9716c1ca27c3e5758c92e595656a974739e62f8b3cbf55dd04622ed4d0260f239555085aa8607a594576f3bd15358175086e6f34888e47951bbead0fec12123c7fd5b6e9cf720a07aeafc95397fd69d82fea2ef57431e58c1a8088529bcf8ac9a610dd8806769cffe8c9a83718b5734936e5acfa72044c62203155e4e3ee437864e6c0bbef9bd4d8e85816a8a02752c1e9c410419cdd5d887834f6a9d663a9eba720ee4c2690b281937c71485","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0xe1d506c96b5e7377ab0a6157e6d0c9d65c7a5fa7ed28a9fdaf02595e6889256c","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x4b42fc5bc316b8776e6fa1727c375ab18b2401624615fb71e0c95bd1400ef814","baseFeePerGas":"0x17b285303","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11c0f7f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2b","validatorIndex":"0x15923d"},{"amount":"0x11b3ebc","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2c","validatorIndex":"0x15923e"},{"amount":"0x11be4ab","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2d","validatorIndex":"0x15923f"},{"amount":"0x11bf791","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2e","validatorIndex":"0x159240"},{"amount":"0x11a64ae","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2f","validatorIndex":"0x159241"},{"amount":"0x11b943b","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e30","validatorIndex":"0x159242"},{"amount":"0x11b214e","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e31","validatorIndex":"0x159243"},{"amount":"0x11aee8c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e32","validatorIndex":"0x159244"},{"amount":"0x11adefa","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e33","validatorIndex":"0x159245"},{"amount":"0x11b899f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e34","validatorIndex":"0x159246"},{"amount":"0x11bd948","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e35","validatorIndex":"0x159247"},{"amount":"0x11b96ba","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e36","validatorIndex":"0x159248"},{"amount":"0x11c8e52","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e37","validatorIndex":"0x159249"},{"amount":"0x11ad72c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e38","validatorIndex":"0x15924a"},{"amount":"0x11c2bc8","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e39","validatorIndex":"0x15924b"},{"amount":"0x11ba27c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e3a","validatorIndex":"0x15924c"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0xeef652","uncles":[],"parentBeaconBlockRoot":"0x5515fd3785b9fe785db376b82d43a7349e1407f0ca6e82b05a48da5ae2bef7d0","size":"0x13671","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x71e763ffd2b9a8cb6e043f2acbd02eb1bec8e2370354ba74e6a5c75ae543cffc","stateRoot":"0xc6cf0be4bbea00f4e3492428da4cd4287cceb0f673ed66f6227ee2affca894cf","mixHash":"0x2a7b6019eff4f027dfc004a19822eef8216b63823ba062fe26e3cd5ad11e663a","parentHash":"0xa870f670ae8e85ad097cb45fbe57260ca4f053abafebad9b7d6ae7ba819e08bf","blobGasUsed":"0x0","timestamp":"0x6687daf3"} \ No newline at end of file +[{"number":"0x134d6b4","hash":"0x500c31e728a280af1add4799095e7229d4a4cdfc6c9c73a62434703ffe34045c","transactions":["0x66324d0360eea71d5a5e6d0bc0dbbdf35cbfbc3a3f121d028ad34c11426efdd2","0xe305bf3385425fe0387d926334de3f03150b31233df76fedaef472d635560e78","0xe410fb642fc29d34a9ec92a1ed3cb48748e2ac8fa7cd9c8315fb29656a8fec1a","0x247fa2b38f1fbf6758609e6d5cdc0f9dc899f37735496ecb95bf734eafd360ea","0x9d10a0dd7850ff99c98ec13b3e65905d1242875784b2d5420be80ac2e3f45c4b","0x53d7fddb6491e17eb15ef6d1e8ff3027735905bfcdfa66b3dae56f973fc2576e","0x40c52b14161c3bb6ea8914fc8a7e55852e0a51d36be4a43835015eb9cc330063","0x5df2a9b9eb1d800c76a1c6c90019e0b6dedf71e85764ed80d9cbba1e8e75cc4b","0x0ee9f351711baf9f66d36fda5c4e436b45c4942936d088ac826dddf781f2bdd9","0x74109ee77c85494337ca6db2975e00c9aded34403b64c9189fe22e7bae3bc4e1","0x9c53f84c1993f87c5ddeaea655780c24c9e265644ff89c839564802de661e4d6","0xcd13d2d4292e2a03c099f60e5db2de058459262c5dbe70ac792f533e47e15b09","0x03b719dad83d99a2eb847751faf36d4663a43d936f1c66948b139c6fc82209dc","0x2f417d2c35961dbd7cb522fa0ee06c95aab12b3d6a707ca8f74f97953fa34227","0xc26f561629de18df96ae9c1271912a90e7d67a9b85d99f603b63e87bdfb68e93","0xa4c4e1851441c900b82d8b90808f59535599884ef3363a5f46c05ef309f12c68","0xd3fad4b38903dfc6ff22954674dcccaa232146c3c6b60687dd1fb6bb61b95c46","0xc2f6717a22fd5b1efc93f59751e2467ea872777782e9201160d4af85aa16f91c","0x4baed9c20161fb6ef4315a198386a4c894f146fc278555e3f87c7f6e18d76c06","0xb91012cc7b849eb66779a8706453556467547c41b93394c36503141b4213a508","0xa33cb80d6bd6e5994c35c49250a00c69d49714e9ef343ca18901a4962e95cc5a","0x1fba689d944205912a77de9fcc53f4ea553e58240f09439d9b6b984495ae16b5","0xeaf101fa2a459f6b9812bba88b42dde5357befda42a35b1f5b5651cbd514e9db","0xce1e34de415dc7ba30c2a4d655c3f3e650275c323518ff2a61015d65cdd5a0ec","0x3d87d050821056a3ed8c1a3ada5bdc1dafd6483459f09054f5ec5112c3e2e833","0x60a7e890a6db8b50d93992c461dc16b49f57f6855fc8dfaacb1a525830657ad6","0x143336aadce774b79d069b72eed4d615df1078df98859476982ac00f35dfef3c","0x17e5787cdadfe3c01ae34f23ecab84d90a0fde083d1a5770cb1349b48ea49d45","0xbdb4b34276389846d8e7cba137033a3fabee90c084fbd65c840839fffddc0d2f","0x230eca8906bf58d6017fd8f3057a2c7e05de885b302b5c349c9d587659cc366d","0xbda38f281b0127034ca3d9b3726fe9ac68c800f34990069edfc8c6ab8cfc43ce","0xd58df4c85b7002b5762707b82d29475628319fa5ebd98dfa4e57721c78d5adfd","0xba4ce9b4cd284b96eee2f8db9db065376bbc646656fa04b2d2a623778b24c300","0xd5c2b6ce545a05378dd92582f6e3c77d1aae42cd88a174bce287073697595f8d","0x3c4295faecb8b630259b5ab875e1de2433d0f384d72bd836718d4384d1c7325e","0x46f5f9ef7efca04abc8e45fa48cddb5fc80493ae07ad943af7f10d94df6d5575","0x43244bec21354c3c918afc71ad11ceeeacadc8d9a114de8ee867cfd592dc63ec","0x95da6a534725726a0f4522ad3b5a81f79dd611290136f58506b7eb6c71b6aa6d","0x5a06e4cf4a51e7060d772d3052dd752789d9a344bcccfd3d5642774f8bf21dc5","0xe6dc810bdebe5c422bd9dfa2b444aa848300a9e7caab28cb856c95a40b68182e","0x153b92c7a60749bb79016c97d717c9a1b68e17fc237ad20763d4bfe9eb31443f","0x3c57f44269511d1ebb682f5b4de53f45bc6cb7bbd455cb18d971cc2a5414f4cd","0xfb2f82babaaecfb5190912074f1382706095f5dc04d7b8851b3de2f115a6cd96","0xb930db9657d311ee70e826e1af1595eb34ab0d9fef21599761f8eb6b57289a72","0x26de40a55c59c5d3e10bb86db6f012536cf65fe1599c589c6eeb32b27d9e7a64","0x90faddb5707b8c30beb8efe3b47d4d2b6bb2174088dd5717263e73cd36936f95","0xefa678a2771fbd1534bf85857d20f4b902d6d26e87e7a96af0e1e512c449c76a","0xede6ca6bfe169da516d0b0a17950d6b88f6d97f9a01569fbcf611504a7815f75","0x132a5b1bd116f732dbe91146efbe8f002411fa80d2113c3ad43c60811b50ba33","0x42b01e6112cd30609f68aff8c90e999fa7d07c169a8bbbababe15ee5d38be66f","0xed60c7c83d4831f55fcb573c8d7417fbe9bdd5d449d54daf67fd3d8623f1a297","0x458ebf545d76f78dea87cb03417bc2d299d669223e2b9815bada877a026df63d","0xdf1ce874ef2e43bc1413e05bf0652acae985b6d94f8a9fdd060a70a61ea8e0e1","0xf977ded6ab95ef5a028d10344c960e16838b81837fcb3f3d15128e9c66ace584","0x733cac76207545f35f1c99ee1145b403d31e24da8cde0a70eb3c25515367fc7e","0x5d53e264ba107ae92f4683bc126c5f0c38aff9a6cda1fd1c743a453b4870f4c1","0xc347abe53a5b5020420ab0da3eb05ec67c3bed42ebbe091f2f94f6d9c2fa168a","0x94e61a2fb7550c453a0c7500fa279cabf1fc661ee8c8dedbcb2479d5a8982196","0x945bc4e094a800c26361b627f67616ef4835cec4dba6e58119d68f10e6a1afcf","0x9c4116447040232cb1f5e13059e4ba12c2db501e45f78cf97f60b0db24695b31","0xaf22df09e9921d45535a0f5f80ea607a860d51681e02b9b57e8c53d74cc36310","0x28e6ee2a48b3c780affb3c124d4ce27acec3d40121f4607ecd565c70701c085c","0x95aa1652585dd525dd926368cb936fac87f81625ff6f6eeab1f2288507b61289","0xa5f466f9b62fea39daf0e0fd3c47d783de4aed4dea1d11d93ab0502f3a4489c3","0xf5be04d59b7c36b75ce6d86f02161123f2e5ad02d5f6e8cc7bacd7f2ec1fd206","0x425a10965f389cfc278c7300ac9a27e7891b178fc39991abaac7848f7089d487","0x3be1373318ad87b9957f5b7b4ae602aa19087b4177f3ba255faa19c576a63f7a","0xf250f0ffb6d574b82a1dad285b17835d68779c7cdb59d7f96794fa945fd4feda","0x13d9d1cc11e7f1af51099490be740a996eb7eb4975daa1cec851081c76805e01","0x41f03ef64f0015f1e8ea93f4381407cd12c83581eca09f10d124c12864a24f35","0x4ca92077f33bdc962bd76f59eb1327a096b9330b7e69393c16589c71c61efe1a","0x499d2f13d41a9e444e882891f3105b493112db8c188e650101916a6c00aab571","0x63afc736e099316f08c559498fde320fda3c5175605aee71dc767c41ba00a2a7","0x481ff76b4c9b60212a2cd281bbe79d048c2429e00ff4be2a86ccb87b863165c0","0xb34048c9549de5042db2c0398988724104dbc5e9470088583c2cf6c348b3dd7c","0xba9f94b5b8372d6b431b8735ab4081101aa9b7bda951d912dc722499c598a83f","0xc5a6251e55564b17bf44f7aa6d21cdd20f658d61a8a84a25c04fe4581895d5aa","0x3235c94fcdb5f9ff29cf70efa34af3ec931a3d1694beb027f0fbd5069ff4ec65","0x5f7915e8d005d97fbd262f31ae861e10a3c585a57a0f118ff0789bf045588f99","0x1d6290be9ed40cb5a458c03bb04342b4f14143bc873b3d50c3fbd671f3db7438","0x65866fc1fba54dc4e6bc0e82746757b49869e359726dcabc98cde74d8ce00c63","0x3d515de1807167f4230d8e68393f3d90cd396821bc8dc05282088caa9191e9cc","0x8c2c4d28db1e21b60f29b19a1035a6911e892a1a91609009d38e373279a56243","0x83df9f5987e06e737e6a28e40175e261dc4936e7832b746207f28c87d8373c5a","0x2d7d7fd66d324c4c14d05dd100ebfc5bc9b945b85a4de4a4520decfeb86e531b","0x0a4acb940c53253539d4b3bbcf7752aba3ccf240285f664a4cfbbd72cb192d48","0x193376115ab2d506755b01beeb7b88012559cb78efed68131ee944addff240eb","0x489e003f7d85c8365f378af589c2d83d6a622e85b6fe0ba58e6ea03c62a08e4a","0x8de8197d07d9f2b47a4316871e1836bc0c405b050cc6a5a27dd9faed74ffffb2","0x592578b40c288a1e25e65f6a056da0124db8bc97fe1fc0a904251ee5f87828b9","0xef29e4bc8e60d8fa76eda5f33f961ac1d36f9f13efb6c1c7a58402733f17a9fb","0xa116a77605deec75b2070955445c9d793b05e50f099d4d1497e34eaf87ed5646","0xa15aae1355633ed2ae9283334bf6db5cf5cd76e0134870389ae8ae744a7bb24c","0xaccc10ec12c433e98e3c27d44e5d5f18400fcbe13a8ceed4dd68dfde57c15449","0x6cfb2131e6b7e25e1ac468a503728903690dd5581fc8bad33f1eff4794229a34","0x4ed2e2e41ec55d6a5b42f1672fb89c619183ba003af4474162f5499c1f163498","0xddbf5ffc8adc9379ee0cfc8a7642c88b327c399a85ed1edb8c9b3960ebcbb9ea","0x08d7c8342bab8fdb4e79fc3b7d75616254df38af409d1d9f84657fd3ddcf69f8","0xd4001d19e4225a3a5cbbfe2934d2775105a7d7d8818b7cb98703c33012716110","0x2062cc1d24beecc20057ad331d690508c748e21d3040ffb37b38965966a3d3f0","0xe3836b1fffecb32d2aef998b4d3c0d606ca9ca2b002661a8f184cbe4d15bbf78","0xbf814b35d87c58629568108a5e1176f67453a1eeb324a510d00b927c477182b0","0x769e8a0d5da47949435d6f4d10f0c61c5dad97e492423675fa6db41580c553dd","0xc7e5d496ba456c2e79f504bae6b2ad6759bd16fe24e1322c9ab69ff971cb6040","0xfb2a55d870229c5128aabd6ac21cf4fa02ec0938f507c95267239818ddbbc2eb","0xbacc62ef0a1edd91c4803c5be166926d737bd76bcb129f4a6f57553a09ce535b","0xda567db58bdd46ea35271e1a53d29375b06054c845bba8f4cff3b0493125d12d","0xc31700594d2f23e26a90d4dc5af926b35a64dd7ccdd4049916302426a491b188","0x40e80109207cb7d621545f8f1c5436e2c3997eec7b521c5e0ab8373b05365b64","0x6d24f1451e0477cf59b0d99c18d6bd1d5aef818728886b9be3643fe7ae10701e","0x906d4b0e8f0a3a1b129138e453ead10750ae4cecf517e01b6bb99340bdeedde4","0x44d615725dd6a00816fde0b1767256e8d4a6796a6d1b2d34844d1389763bad4a","0x42182c0aea8452bf6d86618a0b5ba0237882d158eca83591fd2a7e0c4e123d9c","0x22151212da28291a917d43c2420cc5bc3fe8a0379607325cbeba0eb753eee1a9","0x90019486ad21e98d87ab8965de800d56104267dc2416d399d689ea159221bffd","0x64c1844e0cd95031ca18564892dfc038ce8338ee1168ff61b50ea34f9aa1b937","0xf1d5278d5006bb81ce58798252d790ff95503b63947c1000e7a742a8b1e320b0","0x3dcea3438fdf4b53b23d996f5714d4af758ffac6b82a03ac7d153ec850866bd7","0xb357d9022b4ddab68631c1ed393b46ce5b8048a69f98b4f8a1ea0bc86036c88d","0xfb608c5fb250b761fe4c44479ec398cedcc0f19f8196e96912bd3c02bec93557","0x3c30908976f14f75f5d48c0e61f19af6d417544f79424a737902787382dd0966","0x80be3649036b61d382618ba38055e3a6dbad22906928de3e58ceff5448e414c9","0x8d6f918cf7e15bbf0b9bb90f58a6477e050a7be687a1566ee2e34cf71e9683b6","0xaa3663f978d98ec7c3f5db5bcc547c22b55473e072325444be995b49694b68e8","0xf0dfde881f6672c39b92559e62bfb686c1f396c123ad0b078215601cd7833de6","0x100032a9090d3436f4428af12e4ac03aefd95cf8f54d91dafb898553ac65bb76","0x0813eb4603deb99d240bc27fb033d79b750485b255ad5a21718844e68afda6e0","0x564cf32bc2ede84eb22061684320c87877b13805b378ec9cf351b880d94d0e90","0xaace17676be5b8a1d00e4b21cf8de0b31d611a6037d6b6ba427c518c5dee93df","0xabaf2c962dbd67db95c6fed916950ea39ee021ee2ca366dcbae0791c1995eddf","0x55d2836440ac765764d2bc093143f4d33e4c76a67b24b63282129567bdd18891","0x32fbd38f876ee907ab850539e8622734b2b6166bc3c497a63bd9705ab8ff309a","0xe6b3c13b048842c64b4b2285a3d95537bea9932568fe44a14da9d96fe32af38e","0x326a95b803ec456ecf879056c0a062ec867c2b1fe77b5d7543886f744f9fc054","0x76e3b1f93f0c70797f32d34ab16c22aba26897b262bf3b9fea05792c0e44bc99","0xa406ddd554632edbd8fb29bf48239d32379377d9964d63b56a4b58a6342211ae","0xe507f04062a919707c1c3646fd9dafa6466ba9a5b99a45a5f711444074dfdf1f","0x9d8f75b125afb460c73bc48045e8e188e23230c97c10d7c1af65115a9109a3c5","0x1fd09384af3072d7ee6072df6301516d3a116faf3d22dd9c6dc455b3f3928740","0x496962b25aed0d28012906d7a640d01fbab66f4018b462a1ae53a063c0dd3679","0x78063ab277b776b33f80e283670082686a2462fe895c9bb9d330c767c0658f18","0x6d131d2dc122bfb19c76093de5ec81953dd9af621fc7b4585a59ce285a864aca","0xeb51833fadd3b8bfad8a02e89f2e8ecd27d8ff53c7c52ae13c12b4188369d6f6","0x6b8cfc3843f0a4bbe3e386599824431c874d40fd2c175353670fee2e8b81533e","0x7e09208d802733a55e117295f0b57c82e3e5db785a15b739746148e86830e413","0xf0018894e8d2f87813830ebeed5461ecf5281508021664665742dd7e94b15941","0x2142c7fc110bca3accc867ce813dae6b488fed792140796c78785cfe8371c511","0xe6517260872c2d1cffc2bc7f58d3c86645182a272cb6fae9755b7c84f46e12c8","0xe1a71aef34f4be1bcf8bebe2cbae269e8b6e527f6be8f58954346459ad64e54c","0x778a07a701524315fb01cbe4d04e89258ee7cfa6e2b4cccb08ee14d23d83d0bb","0x33907d1183d22ba055b1ed6587a5c1da14824ae516557d1aaaf32990bbe14747","0x6c3bc5aa7785b1d2b87e50aefbaa2d6a567c5604cbda95a48688d71ae46bdece","0x931dfedfe7d7f1376930ff1d99b6a2029b230386b0cf75a39fbac8380fee8e35","0xd0c77c7c70597ce712d58817cfb5b6e97b48de4bd6af393a64a5965701355003","0xe4d21108ca8e6a470dafa942eea205523c296cfefdb49ae53e932dd01ddaf84f","0x0b6b90b3c8786d4a67178cab8c41fb640fe2f7ad63c3e149e12bb22dbfd18012","0xe606244314e4b255a5c6cce60b576c17674dace61c4154c7f9fcd41cc56cf322","0x960ba88a8b1bc543da5124bc09aa57199c17ef37202587dbc8af2a4d90a2e47e","0x839858692b3a211b079ab222e5b8562c6833102a675f0881adc7a8ab4e14cdcc","0x61cfc1d59bd8b930670181f27237f9474eb676cf9d852aa79b5f871c761a2af5","0x56bff44d1fa271202f8d55b54c78c9b75ed53dcb555e9b8f92c4810a270357ba","0xa3aadc8e65bc5430f528f93b0c726b015a2786539fd1f8d850e6920cfde0ea4b","0x12fd47af11eeb08a9115c967c8c409589a3a1d583641e446f54b7535b200bf62","0x5061b45dd10a197ce6d8b21f21075f3bb79e2bbc035fc38c2b4ea715f37be67f","0x84e9a7fefa6122f61a757515ad05f8851f4eef88b11d5612093ec9a206750790","0x9260caf0b005584f7ac5a391df5fe2a2ba270e3e26fa1bc8e522aa1d4c263e7d","0xcd8626836baa047d6459fa00a728097b5b7c740c8800b1630d2c581403fe3905","0x79cd85af2442851aa4fd2295ef741ed935b212e5a155e37aff20a6390b885c14","0x21fe3176027e96bc49a7f7c49e12333c158b663bd03ed64398a2ed3d84c2d094","0x73b5fadcd5aca1a0c30d21823772bdf89512d81336d666dd721abd7e55cf3241","0x8a76f963963517352fff4307ab8026c36777fd47c392622cf0dcaa1e02634b09","0x170c25cc700000097486d3e58a3282108d173d6cd05fb03f4ee338cf3a4e98d7","0x9d44390378e14f9386ef7ac2821d8a1502f242f568528a8776697a455f03443c","0xffcdbfb5ce2e40f33d2ff957faf7f28790a2fd50948b358f430fe3bf9a744442","0xb414778b97281156ca05a5a8620eed70cd7b6eac94cc7194b951b4a43f253c97","0xcf4aeb1257d707c611b02247bbbed867bd4d427cc5c65e4552d2a4842198eff6","0x26dfa7935ba3a3de6ad649e215a48d0602743867d4e7bc1fd55039114ebdbe25","0xa3db4bd9f6c5ab9c0394e592f6e2ad56b0e16ccf7ae5400d2fefba50cf6a13e0","0xd49951086f7c3cc0d78fa7f06241edd0c514ec180bc3dfcf7a6ffd790f6ded4c","0xc1d1fe0cbbd448f65829e2c10783a1461f555f9cc4b41a4ad0b9a7d1a765d9df","0x37c77b747b9efa641342e1bb85f5cc3f4306aec4d7449f7a12d43025c813fa47","0xa052f59e3732d89bee1d7d4490340a42be97c05a3d7b270baae0e715422e481d","0xd03708cd291234da34a99fa6bcf69aca54fbb9b43308b4057959b8534fbcea0f","0x21ccd23bd7f7d79f297d79c23ac3187b7405e1dac52c62bf9210a20bcde6bfd2","0x0ed28691c1b0913319fc7edde29153b7bfadf4ed5c11d75bbeb8a4711a04ab0f","0x08565c5067041f6d8f5f8cad5e39ccfc676d0371b960bd7edc6a631d9fa544c4","0x1f14dd0d18aeb08bd5345c41c31ec54674271c25ec4c442d82598ef1ee99596e","0x7ec78b696485e00fa80211d099c1c947b6a76afa64dcd21ed7fd11352e837bbc","0xdfa91502d2588788465cdafab98f01c934c5516eb043897158905169433773eb","0xf5d6107e5276b246713aa53a7e20a3bbfbaef981f7eda633dbe5402ffc4b1638","0x4fe1ec8d91b3aa59180a0414b33f2c6850e54729c03e22cf26391bee2371ccec","0x9290f637bdf1f5418702e4ddeccab62927659fea210916aff4e322dde9a1965e","0x2093ddc71f77133f222805e75ee536c1363d540bc64896d8854d980556b5eb78","0xe2135122b3adc2aafb5520f31dec24981d9500aa8edf97fdcc3ed03508ddab7f","0xf45b12961b80f82d864e3578f80ac92324b9ef2964ee66a71e58b6241402fff2","0x064a66b3cfe8921f5da142723d4fa2af7b24318305c05f2682ccd9a2904dbe48","0xbd5b0789cb9ba73eb665c8b0a9f8db68fed9ea6e8f965111696820b6e66947c3","0xf1cd611a0e1e5b54885c75d73db9e70aedd3dce765e4faebd2065a47593f39c9","0x17c9a4553d2f689e4da7e8ee5093596ddb3563a03a72fd7ee430b885bbbbc229","0x087120d0240951ec75b3c5c7b637e873ff02f347b97c73c8b2ff3186f3ba5f8d","0x5b0caa9b293799fe9a4ed68a88c74195c3102d3b2cf7b446b89d949b3f80f0c7","0x3f9581b4e3c61fd718c45b2490c8fcdb4e47489ab50a504825830b50bd1419b9","0xd47c0e12e513b6ede8fff4ea4f65aa7fe3ff751e0b16ab1416fb2627ccd81acf","0xf35a605751f0cdc926413a984506d4eab20ae09cd0a5edcc1f505e67dd426c64","0x876a67d7f9ed4e926fafb91272290a01758a9b9acb7af1ad43896c13b381ae69","0xdaff5644cfce09133cb6db783019f4de406f06f8686962e683fdbfd8edb47ee3","0x79f54807878a24229f57f9193ee144e9ad4ddf90f7cd38a70b9d63677f6b37d5","0x98e840f518c6fb10cfc6e2a59e907bb195d6a7abeaec350163d7242b772775aa","0x8b6ec07092cb61afbfeff775a9ebb6d26608e5d30a0039e59713a77874d02988","0x9cd465d2e0fc07c1806b64d34decc57e5426825527a61906413dd2156635c2ab","0x7afff2c624a94881faba70688887524c30539d9aa51060176902fb970da92c85","0xd891cb85ba08a9ceeae640d8dd38c19aebdf42fcb5f36bbee21368ba7975498c","0x513dac3a3f8156c50a837a6eb6c0b4d24aafb40d823905581e97f73a3bc67ae1","0x77cfb9ce0f011db6c1eadc298884fad690c9e92a67e31e5c44ae18cf346d93b1","0xe84a489566ebddce63c7a29c3b39c6b571312f16b01b40b39d8b253d70e2994f","0xbe3664ed0f7b6f45bd46896623d09f0f065a622595e8be9dac57ffc86f48264d","0xcd581e7dd7996363d5e0423f901ddab44e4a74003c7dd2086c3f3f2ae51f80b9","0x702c9f4aec5a17f4033543956e96216ec6ea2614ec6ed28d2cb017b668482d1b","0x82d92d5a9ea7f42b6704a2abc97da2ddd57f9d3ca5996bc8c9e5ee7abfd0c9dc","0x9d8ed0c4005c6114247549dfa93ad39aeabd65011bf8cd24bd904bf5bcbd5932","0x0d88d6d7fcdf2378636b709c13d7292089b1ead9a00f8d42559eb22b9dce2430","0xf29d043407991d3273105cf98898ce206b5222e1070a053f421dd67f76debc51","0xe13a05f255b6ed96309eea1d53672c01b04578ca3dcca4f9b5b157701e853c83","0x5c028819e9553e9241e65e708a97bf8cba9a21264e1bb766799a17fe75bb553a","0x453490ea5195716fcca9adefe393cb5b244ea36317a82f50ecfeaddf3942c6b4","0xa65d52957d4f30dfe1c7ec5b62901603d89ea42beaa4a07efdc10aac94e5b88e","0xcf7209723d41c5cb01b13b63222db5c21b59a5d713d80da55ee70c676c154d26","0xf6887497dc94f67fb82fb4c12716ce481300f7f58304823be885893e62e88444","0x794c1a37c5022eeaf034775994264379ed8df96609a23d8c6f1fa864b57f21c7","0x047cdfec0fcfc9db1fc7a19f82da9c6559ef428ca0348450ca885f1d442f9a02","0x72a9eda4af2f63511dd6c14968d21a54b593164f4059e45f60f8536a7aa7c9c8","0x0cae67e525a278502a93bec1534476561c268f61a10471a2361334f6fc0aa52e","0xc420e00f2fe8fcf4235cd0a1f27bf0501bd93b81d30e2f91335fab7c886c8649","0x2eb6e625ce3508dd5b90f47cb28385465366f1c4612b9ad57a8a305a28c19293"],"logsBloom":"0x5f3d66625185c33fde3dc0faec3998451b0b30bbaec520074f39c1fa8cafaf03887f5d8da0127c580b377b1cec1e0391eb91e3bd8aa4fcba4a91fac873be86e6415bc5eb860b5baa7d5e61acc3f18c2ba62cd0b9716c1ca27c3e5758c92e595656a974739e62f8b3cbf55dd04622ed4d0260f239555085aa8607a594576f3bd15358175086e6f34888e47951bbead0fec12123c7fd5b6e9cf720a07aeafc95397fd69d82fea2ef57431e58c1a8088529bcf8ac9a610dd8806769cffe8c9a83718b5734936e5acfa72044c62203155e4e3ee437864e6c0bbef9bd4d8e85816a8a02752c1e9c410419cdd5d887834f6a9d663a9eba720ee4c2690b281937c71485","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0xe1d506c96b5e7377ab0a6157e6d0c9d65c7a5fa7ed28a9fdaf02595e6889256c","extraData":"0x6265617665726275696c642e6f7267","withdrawalsRoot":"0x4b42fc5bc316b8776e6fa1727c375ab18b2401624615fb71e0c95bd1400ef814","baseFeePerGas":"0x17b285303","nonce":"0x0000000000000000","miner":"0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5","withdrawals":[{"amount":"0x11c0f7f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2b","validatorIndex":"0x15923d"},{"amount":"0x11b3ebc","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2c","validatorIndex":"0x15923e"},{"amount":"0x11be4ab","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2d","validatorIndex":"0x15923f"},{"amount":"0x11bf791","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2e","validatorIndex":"0x159240"},{"amount":"0x11a64ae","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e2f","validatorIndex":"0x159241"},{"amount":"0x11b943b","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e30","validatorIndex":"0x159242"},{"amount":"0x11b214e","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e31","validatorIndex":"0x159243"},{"amount":"0x11aee8c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e32","validatorIndex":"0x159244"},{"amount":"0x11adefa","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e33","validatorIndex":"0x159245"},{"amount":"0x11b899f","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e34","validatorIndex":"0x159246"},{"amount":"0x11bd948","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e35","validatorIndex":"0x159247"},{"amount":"0x11b96ba","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e36","validatorIndex":"0x159248"},{"amount":"0x11c8e52","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e37","validatorIndex":"0x159249"},{"amount":"0x11ad72c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e38","validatorIndex":"0x15924a"},{"amount":"0x11c2bc8","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e39","validatorIndex":"0x15924b"},{"amount":"0x11ba27c","address":"0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f","index":"0x30e7e3a","validatorIndex":"0x15924c"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0xeef652","uncles":[],"parentBeaconBlockRoot":"0x5515fd3785b9fe785db376b82d43a7349e1407f0ca6e82b05a48da5ae2bef7d0","size":"0x13671","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x71e763ffd2b9a8cb6e043f2acbd02eb1bec8e2370354ba74e6a5c75ae543cffc","stateRoot":"0xc6cf0be4bbea00f4e3492428da4cd4287cceb0f673ed66f6227ee2affca894cf","mixHash":"0x2a7b6019eff4f027dfc004a19822eef8216b63823ba062fe26e3cd5ad11e663a","parentHash":"0xa870f670ae8e85ad097cb45fbe57260ca4f053abafebad9b7d6ae7ba819e08bf","blobGasUsed":"0x0","timestamp":"0x6687daf3"}] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json index a912ac113..37f5ba2cb 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main.json @@ -1,4 +1,4 @@ - +[ { "block_trace": { "trie_pre_images": { @@ -10043,4 +10043,4 @@ "checkpoint_state_trie_root": "0xbe6449b0d590db000103d74f27cd54f4eaf3ed103cdc1c50f7db1ec5dbc26bbc" } } - +] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json index 495731756..3c394e779 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20240058_main_header.json @@ -1 +1 @@ -{"number":"0x134d6ba","hash":"0xea53668c4b92ba05c647ea3eeecea693115e775f028b7c1e3bad98afe60c1714","transactions":["0x10baa77ae90bbb5e0807753270a2cd7c1f1e3a49fc75147b9a88ae48266fbaca","0x77d24c7cc1926bdd6abdd67be8702f35b6fe426eca66f2600eadcd25e6bc8703","0xbf27555961012f41458bedada26bdac910f0d312afdb21274e6c0de6cc78ff94","0x3eb53d0c7b5a1549e40221f1862695f577c626480c82993110d020862ef324e1","0x386e5b6d2ce47704cdafd673a76fe8135f3c2056804a52d39c052ce13dcf8613","0x0f89b4d12682ac5743e129f9a047800c6e50776fa3bce1c813cf5c292c3b2b0d","0x3fe7460edb922780ce85a7549c3ac85446a6c694793aa8133e437b5bcf06a378","0x726cc27a5888b23e9a242b7af92d55666afc74f58f18ca0b9a731e3cbe7b6be2","0x54a4c143966f32c7cf6c3b7d4bf527f12cb8083fc6abaf10cc8d5dcd66949973","0x12e2ada283210d0a191c577b305212bb767b4d9f24a715dd078aaf993ed6daeb","0xac75df8c1b2a3baa88a489847bfd0812ad43b3df5306816f3b7fe6b530a0e0b1","0xb80ecd4058cabd710abd7168df90c0c1074955a72017d0576f39587796058b78","0x4b873cba45ca049dc9c54aced8c85484a6f4dc0479349f166f9799aa55731ed0","0xff1f1da5ff35ff6ceddbf8af4836642ad7c432a2dcd05b2d091cabf568fafa91","0x5396249894a92c61ee03437f583df3abeaba49066fdce4d7a424f4106ea47e81","0x31b014a918e48373e058381f25ec70f767525a54e6a45e4d4e4eaa700c55fce1","0xe933e99cfdafcaa300fd1334a99a18eb8ca99ff00647e82246ae1547b154205a","0x3c02338348d916fb192d9ceadb8c291677e5d9f9d8a057fd3451183bf8d1db35","0x1affe87eb0739605fecddd51d2710491cb5274f7a1c556555c8252a2de3b98bc","0x62d8051d4d588fdfca1bbd86d8710e1fcf0c104ac823a501fb75cdadaf387363","0x71a4b962cc272ac70cb55f442013c9b2417541719dde483cd723adf1c97201af","0x3ef1cf8f935b3403bd55c0400f70d0c38ec60f8c1d436dc369d200cf64436377","0xc5b5d3e42f6e190f7e1c3a6c4e3ad8a88a4d0eaf990aecfe8313ecef5e9a9128","0x35b9e8138d24392e5c468f5fb9f045a55dc97df9ee7012869482f8eb76a2ff95","0xebc1b559aff8b1169c6aa9157cdb58f670aa37aa91b975ca5c85006efa0ad2be","0x09fc8f0bde542bc39a48b3ce581ee1e838d3c2f2c190a4f345106e41f5daed9f","0xef49e0da2b7eddadb3c7a965c8f641d70cb7c610f485909151b3c06fa857a518","0x874b826ce0d5650cfa5362f1ceaf74450c717efde705cf70207774438371bde2","0x88d95f46d2b7ac417547ccf0a2bf69ce416613ac8c3368d76cb30ca612264cf4","0xbc681b4df99190ae4cd4dc275d1b904b4818631274540e55bca51281483553d5","0x5b54f41876cb3cbc485b03fd94b52da8890c9b8bf5266d7b8ab975299cdd9b07","0x91d878fc932f13234e2e04f73c4499c6adb7a96113479de34e8d4d6cd582e135","0x2ee8dda8d5a4ab8222d48f608af256ff5b76e321f5e83d4bc226a4ec6473b13b","0x75774b82857238ff577c92b7ec3d2a1ead2c98b5cd71939a913565f1cbbd03e7","0xc3c996a8aa60218995539f3889c715938f367cc954d4440e105060a0d67851da","0xca71b9732bcebd82fd2209076aa065f0503938cd950765fb84e19e1d9adbc603","0xc16c7be2ad78299e0557c554ed69404cd4ba95c2130239eac3d864fd2ee0d89f","0xdc9f750b6b20ddde07d36ec8c54827db2b18ab03372872b7566fca07629e9154","0x2232c45b71c80f53b508f9c45f20c246531e84978aa15968d902716425d4917d","0xc236b6f0458d5647d04c0587fcb443c72a2163fe6b3f18440ad983616374e5b9","0x2720e362091731118f26233c9836bd20585b2c257291029d919ebc6ba65d3735","0xfed2b19d1ccdaf10431b470a0258728cf741095a67675d74f140dc62a7f65cb4","0x00f38dec524f4f63181d6bb93d9ad409396973099e62cbbcd85b323ecee4f428","0x1a0e9585365d26f349cc65d6abeb46e7dc7a1a555d032c89ce1b6453dea9671d","0xe447be5cbfdbfc80884730c315da1cb383977de39b9123cee840688f4c2c28a3","0x2e6e2d10a00d84fd99f566aa1dd99f2a7b18adb71ad9ccd065ea93c46bbca7a2","0x5324cb46e39ac05b71e7133abf896421efc63808efdc482c10f94fcc91c01e5d","0xd98710b2e278015f2708fd350a99720eeaefe5dd63d7cba4da75b19ac641b358","0x80d47003d915faa7f5ce9bbd6f07e0755ae3e0a658ff6e395b283d0172f5bf0d","0x4cb1a391f5b19321d94d27c3d63ce64cdf475ca90010339cc9c0f5e13a5928a3","0x6ddcad7af6f7ff28e831e84e5e80491e7eebe8188f360b0e434cb9fb956b9576","0x24b2e8db688cf6e2e917e9c076c00372d1adb446bcb5965dc275d185cf6aeab7","0x0e0706dd9c73d3bc7e3fdb2b387107538e6346caaba24681343f4aef4a2173ce","0x68e345e1222ff5572f669058f3a7aa6486b0d93f8802a59230c8779752a13333","0x59513960a1ec9b050d5afd5f44573434fecda4063cb5fef74afd49f7cc2c07ec","0xd6b8bc16304f418e5b4d522fa5ed1382fdfb17d120504550d56e98e540a794ec","0xd22a565135512654cb9cdedf4872171f3cdc1ee5e01db63ae9daa29ecec25715","0xc850ac5666def336b01091ab11926a852ade6fa6cf4eb266a198abe570859baf","0xa7725d08276962aee9287c922e07622dd7f2f8e5e52d55a8cf0c10507b0952a2","0xeee01015b80e1b5b2717728d390fa5f44bceedde7a0f5dcfb1f90defeddd5a0a","0x2cf289ba14235df97bd0b1c1d9e010103581edca9dcba2c3e132324edc447ea9","0xf845efbe35808ab9f70af15d1b795285cdd49267fe6fe7d9545d7d93ab1c73fa","0x6d55e82e7c3452eebadd71ceed1b7b354f41f53fc5965a098143ed05750a5003","0x525716fec0f78fcf2282a4d919364d6c07b3741b3a202d5ff91ff27bd0d08def","0x7268d21087c95dbd95da156406b23a11a471945c9755cf7809d3b1b7a2fa55c2","0xb7881dac0a2b3c2a08860dabb2b405d7c1b11cc587c5eefd6392cb060aab3ac8","0x39f6bf42069184a39c1419961fa950d257eb06d0590901aa17b77dd48ffce25f","0x48d03398da8e7d3761ed077731238c0e49bdafdad01882c3502cfacc39e02f71","0xee8b4074d8ad32fa7d35d65d7cf9ad679e0d48cda98a5afef8cc4760dd9b3199","0xe974917ba0cb0ee41f0c4a51a9994cf325275b84de1ff43eee039fcab2c68c2b","0xed565eb3c53274d8454837145a4ac2ae8c04b7141817062c02c3dc65b5b052f0","0x08f8b93e429e9fdc516eff22a5c9d6b65ef97f426cf10355f37b3d34ccb0a98b","0xb005ede15def2e558811dcfded45063fbfdb9353545ea8c25339ff34629ebb2b","0xf5bcbb9071b56246fc1e9e6eed234a4732ac6a47a6ee8855e0864cfd48b6bd1a","0x384c0b9a378a3a45422f2494b945d7f61359bf42c82fa24958d0ee949ad99209","0x8792746825f7744b105c9a60d46aff76064a88e7d3b10f1362605c2bf191e2fb","0x2cddd834594a187bc5c366fc3dd182c18d5500450ecb0afe349062921486bfc6","0x2d50abc7283174efbab8b7581a2b16bd9f1b540fac2377868c5102b659881a2c","0x746be019b3f29ee14030012a22fce027327c933ff03a1a1d47517d6a57965f51","0xe47a41aae99976487b7861d80bb805a79f6f82478e2e518e6179f68ba9b42b31","0x37ee8ef168c13c050174e99e5e3307c8f9f2bd8f7baf2ece14596c39bfeda4c6","0xc607251204ea412f33ca9967b31e742a56c84f37e77a634c8ddc9720202c8ff6","0xd57584bd4f4d8d2758fa56fd98fb00f71780d1b441b5100a28c2720c0f2cf47c","0xe6e64b5de0a9c5a5d0a9f60829187ef8fb1cd1450b3decee82d764c6b4b47e72","0x4840d343f17b6af3491da5b17eb814b4c0861f2f6565f727703f4059aa9e0a31","0x2982540ab35ad428ff6cd55611c3c63c70e6dc4eeb65adb8e4f6daf0629899a5","0x1974aa5c6ae0de183cd630431921bbfed02d242fdc2fcaf61d263d738329895a","0xb63fab5abc247582f6873ad9bb71674e52a0f84ae8964d73c65c5a49a47f4a4b","0x511373f5bf71db16feaf4bfae68ce3af071b6c8e0b0da8b9cc202e83129a9bb9","0xcac4fd8b34138af38dd1fb5643508f37ce7e1ddfe2616c681e0d5c13a594147d","0xb5a5b55502855bd77a6e2b0e05771365bbbd4c30dd552fcfa638d7e896100a1d","0x4b28388c454889248e39ede01790dff88df4c206771fc3f203edccb6589a19b6","0xd31018bdf2c850549e89ad32a74d03ed66a372cff95ba7f386fac51b09f15b31","0xc2357b735a078287707f89b2a129568d9656e34cb6c11f9cd32e02a7d10c9b58","0x62684c02698bdb752d100e3237f5f8baeefa4b2871341a258ac5b6aaf23e8997","0x288cab54801a082ab3f34e79ce775810473ad46716777a19d64a832252db3eca","0x9c03d9019d1581a6fa8fdca0d9729305b111206510b8afeb4d292bfe3bb5011b","0xc117516a08df8a4f910536dd277d65c99c31a28011486ec1ecbdd0ae398b920b","0x9dd43e24e8df009cae824eebe27b8b4197a588896b6af22c4f69aafc57ba0aa2","0x96752d10ceaf86cd13d8d1958be1722d73f48272f9a25acea6c05976a208453f","0xee5490a31c607ba2e7c722095fb3df4e78d8d955a11f51db76a5b19c4d986b15","0x6f75ab1e059f61dd7cb3bc850d9e74a09c079cee4545873c26d01f3b3c35a189","0xa2c022b754d237e61da5a5bf43f0689960ab9cb88b078cac92750293d456658e","0x6c14f1f209b216d853f79549face498b87a7b65e393408181eb953ecb106f685","0xd7fc1912f1d55a0b69844c753949a1382afe642f8c3241c8b9d2dcbc0ee9c8a8","0xa60d1c8ce457390f0b98eef052cc50c8f239e3abedda3141228041b23049c868","0x6604e2160f5dedee6c5649a6fb2099d129a8254984c12e37183654630a5d45a1","0x6586195f7a0a5066849f975cc1046a9d5acf380ca97e10675032fa541b025455","0x0fd528ac75228717c50bf1301c629f031866b41e82645c35863aea79f028cc94","0x4c4686359b8fbd8299f4228d94fda2fbbb8cc517216e88ccccb864d4d8572f20","0xeb448c538c0945da91b490d0a59e05e376bb9a54b417f994f4ede53cb9b9f1b8","0x0c04689b4bbf1a97ecd907316fbd68d8991861683f02bea93193095b7623011d","0xa11ac8f6306c1f17764edfeec331240e0e14fb62741a4a5587ad56ed3e27a9dd","0x5207d8f111587146689fbae84187265753efac48f897301554bf28a0bad35f11","0x7f9fe8a0c25b3a3aebb2338efbcca8507a62bc333ac1acf9aaad9f5eb8d5bac9","0xb66bf9556a9cc63af9e9fae9dbc1161fbbc943ae2beca33b275bdfc12a1272d9","0x4ca39d13b8c40f8160d7332125bcee201d2fe2e98f29e342481a86a97ee23701","0x49e1c6c7a5f72ce8aaf3f71b2fc94bc87b78b3c092a13ba1542e542c415c5b24","0xcc8111473c669a1a23dd48017538b6f2062ba6b20611f94d5d91b540f2b63708","0xc0944eaf281709f025830f99534f4d852563e4f3ade385e170cd85ac6502fc9a","0xc4080487c0e97dcde9a4c4223fb0b654f6e7e617c5444d14692872d165b346aa","0x029b0ac5bb4937aa82f786b559c8f5231e48ad5339026a365a9791be7a782065","0x88bf20195821a0b25565d1a8a2a56836c8880b2dfd385de91610ff374fa63cfa","0xf1ec225976bce5f4fcf1a855e3a6a36d23556d161a0a6b941fad665f2b245d4d","0xa0d3a7ca1d9940db2cb63c0e65bc7e68599c6d995816e1fd337b7b637b2931d2","0xe489a5a7c85280cb7c2064309f6c01cf1e6e0f63e14952587a3d998230d639d8","0x0ff21c69a9f0f7a91ec9f499d2228458a46c3d57d795c5cf0730b858713c0abd","0x03a1540d0095e65d250f5cf0e5f2b136768e00193926ad3971050b48f31a2369","0xd57a95ff6ef9b56207634cddf4d2660cf6149fe12adeea17535d16e95038f23c","0x384f873d81a5d731f80a0707727e78150f455f5371e99d250c4c865438317869","0x39bace2e1faf0b5118a3be2bddfcc51e2f6ebe763b9b9e6af9935ecfc957a7e3","0x9968bf9c49afec7d2e7cf051c768d6449fe6f4c584b251a6ff843c7746b076ec","0xd29a7a5e67eff1e6104ed8984de58da25a23ee5dd759d80fd0021d0e73c3d406","0x758446fd04f04c5c580f8d1b6071e6bff33d67a40726f3859357482afd9f9293","0x02e2cdddf431c1bb4d10cc13c7867d8d5e604b70bdd9100a18c500c34877f05d","0xe0db184b098442ea2c26e76556b3f7af4ffa11c34c1e6ee39b0a882f7557cd26","0x1f609d9dbf86d674f22d93bb0d47688b3cff475680d2ebab953ec36aadad32ab","0xc3d79aabc793ac679261a343cd5702f4c979f534d89d0b4b00b65972545767de","0xbeba1496b81d2bb9c06f1f0c2ea16e59629b8c05d207cc0663afa208f743452d","0x28acf438f77db69fe3d684dec096d74eb4c7b419b3c8d65c6b3373a5706666ab","0x399ea33e26af1af647fa20f03791a5857cb1a7683f906e030777a123d9c50c13","0x1670cec5842c964925f025b07601d22019c2173cf90911ad3bf4435cfc07052e","0xcbbac283d4170c58f4d7f4fae0fc11c4b133d4ed136354e1bea4736b32220f1e","0x440528c529d924386b77527b79a140672796a755fbca8c497c98bc4b9f14cda0","0xdb4b4375f06fcfaccb7e16a8b211caa31e0900e1d1306ee223ea34dddc3dd9c7","0x465cec9a2a565f139190619d6172467161439dfad6953dff7096faf9200c13f8","0x1906c1aa056cfcea858ff1a560442cf8edf73c37c87f10e0acfad9ccfdd7280d","0xcdec80307ec0b778f36627413a637988424750c39a0d7f1d6f1e72a7c8ebc3e0","0xf279eeb6504229de3b3a3238717024503c74d717b2e8bea735b8c1d91245d308","0x6f1352967be840b2651cd967470a9700a2957689331dd425b06f4dd1eabcc2c6","0x98c26320cf118bb7ac0efe52a10d12e5b008d01c79375105b27c33dfa99a3acb","0x57524e0e9f1b36c1c2f1b684b3297d8fbbeb48fa0cfb73d53e86913849efbe3f","0x6ccee1ef3ae9021354557935aff4a2188fc3ff3eac74dd098f199d57be42f0fc","0x77245274cc95e8cca862b656a139b091db748d71e7ba725f9fb62f853ec2286e","0x01d57155d7e2b5769068b5d0ebe2b79c5e935c825c1f9394d31c15cd74eb57ce","0x9b812683207a9e895ed493ef96b3652278026c54cd4c45c45e6a58c4e284affa","0xe1cb09e8b24094426cc94044ae065d2445816f58091ac4c731d6f60a26b030ff","0xd1a39e7787f28514d694b1fdf4138260ec1afd0dc5e8b227f5affbba63202dff","0xde540710a5d8420b7af7d66ab5c7b5a0f7a8ca65bd12ed43a8f2f76583fbb5f4","0x2891945b74450f5272b2ef4a0860631acdcd9f3a43f44024e6b2da2d84cc96e0","0x00f5b59a0065cc39303b9e4795fd7a3146c88872c92daf23b62c1163328ff523","0xc46f39a441deb988f4f5874750b89d02a46ebbfa1b076751668a490a686f7a58","0xa4ec981b6bbf6bea2231428e3750a96a4fd2e88fe392bd7b9bcd128a5acf986e","0x0ce6e946916365e6e183a459e614d8dda6da6f0bff8c27261e763b31ac9c4932","0x6c982987bcb5285b8a2dd9bf5b0ad11fd9d9731ef514018299261626fe3e27b5","0x2e81866d489807990cbdb3ba207ba99fe19586d3c33cbd00c89352bd89477f61","0x357b51b9a081ea8ccc580f4d9d5d0f1aff19c817e8dc2f80dda96fb5ae55abbb","0x4352395fe3596197074b5bfd0525e26e7a9b09226454b1639aa4afca90b67425","0xea31f572d3d12d0ca6119b5d0bb90299de162d69c160248eb88e9b562e10ece6","0xa83eccd8193c8acdec102098d9dfa800bc63ff9e2f0ed4cf657740135b39ffff","0x11c9ea43918e04ee2eb81d7172b095eca1f51f66ac6a801ad9fe8f68521ecda9","0x36cb56905c616f7f25920efbcf8667384bc3ecabe54cd06216e02b1c09fc511d","0xf7b92d4fa89f4eb5e9929a198971bf78c689b3f59b3d8e6c6f19121d3d3e9ef1","0xe2f2e0dfeaf13f4b48e1b77789e3685db85fa8b440eebd7b0df48b14392eb0fb","0x547a5462e235657e9735d1c90745c25fc5ade0a346700b1479f1c4f3f777aa19","0x9efe99afde7352893354505767a3321ab68d03bb7816fcf7d41432e1c58a9bdf","0x1612f38b4d50af9b149bdb909b47f50f1c6e51877f7ce544ae0c0ed0b786b5f1","0x8f75557eb8bc30fe6d73b3bac604fc213544d9d6bc91d657248396f9d84d6248","0xfec7202862e3c9e507337abf1df29c69b79bd3213ec26bdb190e8ab93def24f6","0x9ec3bb4ee77b686018a916c711fecd831e0cf72d7083ab5c603a4844d4542ca2","0x107394bfbd5d863ec343d38f439e1235069f5b9e15e77d98f20ffa0f9efd2db5","0xde07614ec99fea2d583d5c162b71c8f672f542c7a47d3d92245d36faa9d2e2fb","0x757e42e38ec7bdfa62d298bc15f6c3b1b9c8b3fdf807ad202b23ab64638b1e67","0x7b6e2f8903befe1a9a43366163e2210e3504293ba1718f66cfaa8f04eed4f5c7","0x929ab21581ddfedbfa9f391e390ab8f398b6567e614d0c3e51f15c8babd5f24b","0x2b4b05bcd91636475b5afd95f68e1f98d7c57ead038b7352accaea3f00689435","0x6e9922b730896c42c5a769952be52af8f3002c1a441cdbed4e00c23304235549","0xf5a5d30614bc475d65e3eae8c8c46bc874c1b6366d38ae89070906b313e46d89"],"logsBloom":"0xde2f665ae7cb727d5f7fcbc2ffb49173d9bb9a9aabe1790e2e1fb2507f72bff1460745a5a63b6c78e60bfbf2dab7c7c57bc3bb10bbaa6d319bfffc6c11aaebf04e03cffe4c770e7fddccc10bf73cb2ebd68e783985503e34aa53ce4aca6fdeded63b8575c26ed62eb3ddfcfb6ba9bf1b023f36ee32d12728db55cfd5ed0dfef79b49954db57f616c8851f94fafe3c57cc561ffc52d45bdfbf7231e7273f7177feb86504e9fb1f6be7e37d1c4b814ed7f3d91c94838e7cc479ff7fb36b6f940dd4bfcb0e32e6e19b3d90ecebbda1bdfdc76d48266b56b6a73aaa75457c0b2ed8268faae44c127403250ed9fcdaed6b722f37ef75579beacc69093835c636f5419","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x9f07488a43cee51187acfaf324a7675d3810e4f604a591d35788fa456c4a37b1","extraData":"0x546974616e2028746974616e6275696c6465722e78797a29","withdrawalsRoot":"0x28eb7d27ca24bb5ef9da7de28fcdb06838abd26b3b9529e7a5fdb3579c70d0d0","baseFeePerGas":"0x19239e5fb","nonce":"0x0000000000000000","miner":"0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97","withdrawals":[{"amount":"0x11bde51","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8b","validatorIndex":"0x15929d"},{"amount":"0x35d83ec","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8c","validatorIndex":"0x15929e"},{"amount":"0x11c3165","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8d","validatorIndex":"0x15929f"},{"amount":"0x11c27a3","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8e","validatorIndex":"0x1592a0"},{"amount":"0x11b6210","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8f","validatorIndex":"0x1592a1"},{"amount":"0x11b89fe","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e90","validatorIndex":"0x1592a2"},{"amount":"0x11ca1d7","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e91","validatorIndex":"0x1592a3"},{"amount":"0x11bb0ab","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e92","validatorIndex":"0x1592a4"},{"amount":"0x11c576c","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e93","validatorIndex":"0x1592a5"},{"amount":"0x3cfa2f5","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e94","validatorIndex":"0x1592a6"},{"amount":"0x11bb3b5","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e95","validatorIndex":"0x1592a7"},{"amount":"0x11b8745","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e96","validatorIndex":"0x1592a8"},{"amount":"0x11bdc4a","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e97","validatorIndex":"0x1592a9"},{"amount":"0x11b6cb3","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e98","validatorIndex":"0x1592aa"},{"amount":"0x11c29ef","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e99","validatorIndex":"0x1592ab"},{"amount":"0x11bc261","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e9a","validatorIndex":"0x1592ac"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x126b00b","uncles":[],"parentBeaconBlockRoot":"0x32183d6291e5f55aa67377a4a1bd2c2772192fd720d9880ae58df27d41c1d86c","size":"0x1a76f","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x868e868b70c53463e7762a56dc769448c365d2a5e673935eb0d9a8f61afa6bfb","stateRoot":"0x25e32f3be27638d39979675fbf041c089068ac66184b5ffb20c57e244d05711a","mixHash":"0x827b17bfa1d9627edd6397ff66376e31aeed366f9d6b52be8f82d6b81276f44f","parentHash":"0x1d49a3c0bc37f56fcb49f5cc457a65d28b32b4208403aad49371a715ffdc50e5","blobGasUsed":"0x40000","timestamp":"0x6687db3b"} \ No newline at end of file +[{"number":"0x134d6ba","hash":"0xea53668c4b92ba05c647ea3eeecea693115e775f028b7c1e3bad98afe60c1714","transactions":["0x10baa77ae90bbb5e0807753270a2cd7c1f1e3a49fc75147b9a88ae48266fbaca","0x77d24c7cc1926bdd6abdd67be8702f35b6fe426eca66f2600eadcd25e6bc8703","0xbf27555961012f41458bedada26bdac910f0d312afdb21274e6c0de6cc78ff94","0x3eb53d0c7b5a1549e40221f1862695f577c626480c82993110d020862ef324e1","0x386e5b6d2ce47704cdafd673a76fe8135f3c2056804a52d39c052ce13dcf8613","0x0f89b4d12682ac5743e129f9a047800c6e50776fa3bce1c813cf5c292c3b2b0d","0x3fe7460edb922780ce85a7549c3ac85446a6c694793aa8133e437b5bcf06a378","0x726cc27a5888b23e9a242b7af92d55666afc74f58f18ca0b9a731e3cbe7b6be2","0x54a4c143966f32c7cf6c3b7d4bf527f12cb8083fc6abaf10cc8d5dcd66949973","0x12e2ada283210d0a191c577b305212bb767b4d9f24a715dd078aaf993ed6daeb","0xac75df8c1b2a3baa88a489847bfd0812ad43b3df5306816f3b7fe6b530a0e0b1","0xb80ecd4058cabd710abd7168df90c0c1074955a72017d0576f39587796058b78","0x4b873cba45ca049dc9c54aced8c85484a6f4dc0479349f166f9799aa55731ed0","0xff1f1da5ff35ff6ceddbf8af4836642ad7c432a2dcd05b2d091cabf568fafa91","0x5396249894a92c61ee03437f583df3abeaba49066fdce4d7a424f4106ea47e81","0x31b014a918e48373e058381f25ec70f767525a54e6a45e4d4e4eaa700c55fce1","0xe933e99cfdafcaa300fd1334a99a18eb8ca99ff00647e82246ae1547b154205a","0x3c02338348d916fb192d9ceadb8c291677e5d9f9d8a057fd3451183bf8d1db35","0x1affe87eb0739605fecddd51d2710491cb5274f7a1c556555c8252a2de3b98bc","0x62d8051d4d588fdfca1bbd86d8710e1fcf0c104ac823a501fb75cdadaf387363","0x71a4b962cc272ac70cb55f442013c9b2417541719dde483cd723adf1c97201af","0x3ef1cf8f935b3403bd55c0400f70d0c38ec60f8c1d436dc369d200cf64436377","0xc5b5d3e42f6e190f7e1c3a6c4e3ad8a88a4d0eaf990aecfe8313ecef5e9a9128","0x35b9e8138d24392e5c468f5fb9f045a55dc97df9ee7012869482f8eb76a2ff95","0xebc1b559aff8b1169c6aa9157cdb58f670aa37aa91b975ca5c85006efa0ad2be","0x09fc8f0bde542bc39a48b3ce581ee1e838d3c2f2c190a4f345106e41f5daed9f","0xef49e0da2b7eddadb3c7a965c8f641d70cb7c610f485909151b3c06fa857a518","0x874b826ce0d5650cfa5362f1ceaf74450c717efde705cf70207774438371bde2","0x88d95f46d2b7ac417547ccf0a2bf69ce416613ac8c3368d76cb30ca612264cf4","0xbc681b4df99190ae4cd4dc275d1b904b4818631274540e55bca51281483553d5","0x5b54f41876cb3cbc485b03fd94b52da8890c9b8bf5266d7b8ab975299cdd9b07","0x91d878fc932f13234e2e04f73c4499c6adb7a96113479de34e8d4d6cd582e135","0x2ee8dda8d5a4ab8222d48f608af256ff5b76e321f5e83d4bc226a4ec6473b13b","0x75774b82857238ff577c92b7ec3d2a1ead2c98b5cd71939a913565f1cbbd03e7","0xc3c996a8aa60218995539f3889c715938f367cc954d4440e105060a0d67851da","0xca71b9732bcebd82fd2209076aa065f0503938cd950765fb84e19e1d9adbc603","0xc16c7be2ad78299e0557c554ed69404cd4ba95c2130239eac3d864fd2ee0d89f","0xdc9f750b6b20ddde07d36ec8c54827db2b18ab03372872b7566fca07629e9154","0x2232c45b71c80f53b508f9c45f20c246531e84978aa15968d902716425d4917d","0xc236b6f0458d5647d04c0587fcb443c72a2163fe6b3f18440ad983616374e5b9","0x2720e362091731118f26233c9836bd20585b2c257291029d919ebc6ba65d3735","0xfed2b19d1ccdaf10431b470a0258728cf741095a67675d74f140dc62a7f65cb4","0x00f38dec524f4f63181d6bb93d9ad409396973099e62cbbcd85b323ecee4f428","0x1a0e9585365d26f349cc65d6abeb46e7dc7a1a555d032c89ce1b6453dea9671d","0xe447be5cbfdbfc80884730c315da1cb383977de39b9123cee840688f4c2c28a3","0x2e6e2d10a00d84fd99f566aa1dd99f2a7b18adb71ad9ccd065ea93c46bbca7a2","0x5324cb46e39ac05b71e7133abf896421efc63808efdc482c10f94fcc91c01e5d","0xd98710b2e278015f2708fd350a99720eeaefe5dd63d7cba4da75b19ac641b358","0x80d47003d915faa7f5ce9bbd6f07e0755ae3e0a658ff6e395b283d0172f5bf0d","0x4cb1a391f5b19321d94d27c3d63ce64cdf475ca90010339cc9c0f5e13a5928a3","0x6ddcad7af6f7ff28e831e84e5e80491e7eebe8188f360b0e434cb9fb956b9576","0x24b2e8db688cf6e2e917e9c076c00372d1adb446bcb5965dc275d185cf6aeab7","0x0e0706dd9c73d3bc7e3fdb2b387107538e6346caaba24681343f4aef4a2173ce","0x68e345e1222ff5572f669058f3a7aa6486b0d93f8802a59230c8779752a13333","0x59513960a1ec9b050d5afd5f44573434fecda4063cb5fef74afd49f7cc2c07ec","0xd6b8bc16304f418e5b4d522fa5ed1382fdfb17d120504550d56e98e540a794ec","0xd22a565135512654cb9cdedf4872171f3cdc1ee5e01db63ae9daa29ecec25715","0xc850ac5666def336b01091ab11926a852ade6fa6cf4eb266a198abe570859baf","0xa7725d08276962aee9287c922e07622dd7f2f8e5e52d55a8cf0c10507b0952a2","0xeee01015b80e1b5b2717728d390fa5f44bceedde7a0f5dcfb1f90defeddd5a0a","0x2cf289ba14235df97bd0b1c1d9e010103581edca9dcba2c3e132324edc447ea9","0xf845efbe35808ab9f70af15d1b795285cdd49267fe6fe7d9545d7d93ab1c73fa","0x6d55e82e7c3452eebadd71ceed1b7b354f41f53fc5965a098143ed05750a5003","0x525716fec0f78fcf2282a4d919364d6c07b3741b3a202d5ff91ff27bd0d08def","0x7268d21087c95dbd95da156406b23a11a471945c9755cf7809d3b1b7a2fa55c2","0xb7881dac0a2b3c2a08860dabb2b405d7c1b11cc587c5eefd6392cb060aab3ac8","0x39f6bf42069184a39c1419961fa950d257eb06d0590901aa17b77dd48ffce25f","0x48d03398da8e7d3761ed077731238c0e49bdafdad01882c3502cfacc39e02f71","0xee8b4074d8ad32fa7d35d65d7cf9ad679e0d48cda98a5afef8cc4760dd9b3199","0xe974917ba0cb0ee41f0c4a51a9994cf325275b84de1ff43eee039fcab2c68c2b","0xed565eb3c53274d8454837145a4ac2ae8c04b7141817062c02c3dc65b5b052f0","0x08f8b93e429e9fdc516eff22a5c9d6b65ef97f426cf10355f37b3d34ccb0a98b","0xb005ede15def2e558811dcfded45063fbfdb9353545ea8c25339ff34629ebb2b","0xf5bcbb9071b56246fc1e9e6eed234a4732ac6a47a6ee8855e0864cfd48b6bd1a","0x384c0b9a378a3a45422f2494b945d7f61359bf42c82fa24958d0ee949ad99209","0x8792746825f7744b105c9a60d46aff76064a88e7d3b10f1362605c2bf191e2fb","0x2cddd834594a187bc5c366fc3dd182c18d5500450ecb0afe349062921486bfc6","0x2d50abc7283174efbab8b7581a2b16bd9f1b540fac2377868c5102b659881a2c","0x746be019b3f29ee14030012a22fce027327c933ff03a1a1d47517d6a57965f51","0xe47a41aae99976487b7861d80bb805a79f6f82478e2e518e6179f68ba9b42b31","0x37ee8ef168c13c050174e99e5e3307c8f9f2bd8f7baf2ece14596c39bfeda4c6","0xc607251204ea412f33ca9967b31e742a56c84f37e77a634c8ddc9720202c8ff6","0xd57584bd4f4d8d2758fa56fd98fb00f71780d1b441b5100a28c2720c0f2cf47c","0xe6e64b5de0a9c5a5d0a9f60829187ef8fb1cd1450b3decee82d764c6b4b47e72","0x4840d343f17b6af3491da5b17eb814b4c0861f2f6565f727703f4059aa9e0a31","0x2982540ab35ad428ff6cd55611c3c63c70e6dc4eeb65adb8e4f6daf0629899a5","0x1974aa5c6ae0de183cd630431921bbfed02d242fdc2fcaf61d263d738329895a","0xb63fab5abc247582f6873ad9bb71674e52a0f84ae8964d73c65c5a49a47f4a4b","0x511373f5bf71db16feaf4bfae68ce3af071b6c8e0b0da8b9cc202e83129a9bb9","0xcac4fd8b34138af38dd1fb5643508f37ce7e1ddfe2616c681e0d5c13a594147d","0xb5a5b55502855bd77a6e2b0e05771365bbbd4c30dd552fcfa638d7e896100a1d","0x4b28388c454889248e39ede01790dff88df4c206771fc3f203edccb6589a19b6","0xd31018bdf2c850549e89ad32a74d03ed66a372cff95ba7f386fac51b09f15b31","0xc2357b735a078287707f89b2a129568d9656e34cb6c11f9cd32e02a7d10c9b58","0x62684c02698bdb752d100e3237f5f8baeefa4b2871341a258ac5b6aaf23e8997","0x288cab54801a082ab3f34e79ce775810473ad46716777a19d64a832252db3eca","0x9c03d9019d1581a6fa8fdca0d9729305b111206510b8afeb4d292bfe3bb5011b","0xc117516a08df8a4f910536dd277d65c99c31a28011486ec1ecbdd0ae398b920b","0x9dd43e24e8df009cae824eebe27b8b4197a588896b6af22c4f69aafc57ba0aa2","0x96752d10ceaf86cd13d8d1958be1722d73f48272f9a25acea6c05976a208453f","0xee5490a31c607ba2e7c722095fb3df4e78d8d955a11f51db76a5b19c4d986b15","0x6f75ab1e059f61dd7cb3bc850d9e74a09c079cee4545873c26d01f3b3c35a189","0xa2c022b754d237e61da5a5bf43f0689960ab9cb88b078cac92750293d456658e","0x6c14f1f209b216d853f79549face498b87a7b65e393408181eb953ecb106f685","0xd7fc1912f1d55a0b69844c753949a1382afe642f8c3241c8b9d2dcbc0ee9c8a8","0xa60d1c8ce457390f0b98eef052cc50c8f239e3abedda3141228041b23049c868","0x6604e2160f5dedee6c5649a6fb2099d129a8254984c12e37183654630a5d45a1","0x6586195f7a0a5066849f975cc1046a9d5acf380ca97e10675032fa541b025455","0x0fd528ac75228717c50bf1301c629f031866b41e82645c35863aea79f028cc94","0x4c4686359b8fbd8299f4228d94fda2fbbb8cc517216e88ccccb864d4d8572f20","0xeb448c538c0945da91b490d0a59e05e376bb9a54b417f994f4ede53cb9b9f1b8","0x0c04689b4bbf1a97ecd907316fbd68d8991861683f02bea93193095b7623011d","0xa11ac8f6306c1f17764edfeec331240e0e14fb62741a4a5587ad56ed3e27a9dd","0x5207d8f111587146689fbae84187265753efac48f897301554bf28a0bad35f11","0x7f9fe8a0c25b3a3aebb2338efbcca8507a62bc333ac1acf9aaad9f5eb8d5bac9","0xb66bf9556a9cc63af9e9fae9dbc1161fbbc943ae2beca33b275bdfc12a1272d9","0x4ca39d13b8c40f8160d7332125bcee201d2fe2e98f29e342481a86a97ee23701","0x49e1c6c7a5f72ce8aaf3f71b2fc94bc87b78b3c092a13ba1542e542c415c5b24","0xcc8111473c669a1a23dd48017538b6f2062ba6b20611f94d5d91b540f2b63708","0xc0944eaf281709f025830f99534f4d852563e4f3ade385e170cd85ac6502fc9a","0xc4080487c0e97dcde9a4c4223fb0b654f6e7e617c5444d14692872d165b346aa","0x029b0ac5bb4937aa82f786b559c8f5231e48ad5339026a365a9791be7a782065","0x88bf20195821a0b25565d1a8a2a56836c8880b2dfd385de91610ff374fa63cfa","0xf1ec225976bce5f4fcf1a855e3a6a36d23556d161a0a6b941fad665f2b245d4d","0xa0d3a7ca1d9940db2cb63c0e65bc7e68599c6d995816e1fd337b7b637b2931d2","0xe489a5a7c85280cb7c2064309f6c01cf1e6e0f63e14952587a3d998230d639d8","0x0ff21c69a9f0f7a91ec9f499d2228458a46c3d57d795c5cf0730b858713c0abd","0x03a1540d0095e65d250f5cf0e5f2b136768e00193926ad3971050b48f31a2369","0xd57a95ff6ef9b56207634cddf4d2660cf6149fe12adeea17535d16e95038f23c","0x384f873d81a5d731f80a0707727e78150f455f5371e99d250c4c865438317869","0x39bace2e1faf0b5118a3be2bddfcc51e2f6ebe763b9b9e6af9935ecfc957a7e3","0x9968bf9c49afec7d2e7cf051c768d6449fe6f4c584b251a6ff843c7746b076ec","0xd29a7a5e67eff1e6104ed8984de58da25a23ee5dd759d80fd0021d0e73c3d406","0x758446fd04f04c5c580f8d1b6071e6bff33d67a40726f3859357482afd9f9293","0x02e2cdddf431c1bb4d10cc13c7867d8d5e604b70bdd9100a18c500c34877f05d","0xe0db184b098442ea2c26e76556b3f7af4ffa11c34c1e6ee39b0a882f7557cd26","0x1f609d9dbf86d674f22d93bb0d47688b3cff475680d2ebab953ec36aadad32ab","0xc3d79aabc793ac679261a343cd5702f4c979f534d89d0b4b00b65972545767de","0xbeba1496b81d2bb9c06f1f0c2ea16e59629b8c05d207cc0663afa208f743452d","0x28acf438f77db69fe3d684dec096d74eb4c7b419b3c8d65c6b3373a5706666ab","0x399ea33e26af1af647fa20f03791a5857cb1a7683f906e030777a123d9c50c13","0x1670cec5842c964925f025b07601d22019c2173cf90911ad3bf4435cfc07052e","0xcbbac283d4170c58f4d7f4fae0fc11c4b133d4ed136354e1bea4736b32220f1e","0x440528c529d924386b77527b79a140672796a755fbca8c497c98bc4b9f14cda0","0xdb4b4375f06fcfaccb7e16a8b211caa31e0900e1d1306ee223ea34dddc3dd9c7","0x465cec9a2a565f139190619d6172467161439dfad6953dff7096faf9200c13f8","0x1906c1aa056cfcea858ff1a560442cf8edf73c37c87f10e0acfad9ccfdd7280d","0xcdec80307ec0b778f36627413a637988424750c39a0d7f1d6f1e72a7c8ebc3e0","0xf279eeb6504229de3b3a3238717024503c74d717b2e8bea735b8c1d91245d308","0x6f1352967be840b2651cd967470a9700a2957689331dd425b06f4dd1eabcc2c6","0x98c26320cf118bb7ac0efe52a10d12e5b008d01c79375105b27c33dfa99a3acb","0x57524e0e9f1b36c1c2f1b684b3297d8fbbeb48fa0cfb73d53e86913849efbe3f","0x6ccee1ef3ae9021354557935aff4a2188fc3ff3eac74dd098f199d57be42f0fc","0x77245274cc95e8cca862b656a139b091db748d71e7ba725f9fb62f853ec2286e","0x01d57155d7e2b5769068b5d0ebe2b79c5e935c825c1f9394d31c15cd74eb57ce","0x9b812683207a9e895ed493ef96b3652278026c54cd4c45c45e6a58c4e284affa","0xe1cb09e8b24094426cc94044ae065d2445816f58091ac4c731d6f60a26b030ff","0xd1a39e7787f28514d694b1fdf4138260ec1afd0dc5e8b227f5affbba63202dff","0xde540710a5d8420b7af7d66ab5c7b5a0f7a8ca65bd12ed43a8f2f76583fbb5f4","0x2891945b74450f5272b2ef4a0860631acdcd9f3a43f44024e6b2da2d84cc96e0","0x00f5b59a0065cc39303b9e4795fd7a3146c88872c92daf23b62c1163328ff523","0xc46f39a441deb988f4f5874750b89d02a46ebbfa1b076751668a490a686f7a58","0xa4ec981b6bbf6bea2231428e3750a96a4fd2e88fe392bd7b9bcd128a5acf986e","0x0ce6e946916365e6e183a459e614d8dda6da6f0bff8c27261e763b31ac9c4932","0x6c982987bcb5285b8a2dd9bf5b0ad11fd9d9731ef514018299261626fe3e27b5","0x2e81866d489807990cbdb3ba207ba99fe19586d3c33cbd00c89352bd89477f61","0x357b51b9a081ea8ccc580f4d9d5d0f1aff19c817e8dc2f80dda96fb5ae55abbb","0x4352395fe3596197074b5bfd0525e26e7a9b09226454b1639aa4afca90b67425","0xea31f572d3d12d0ca6119b5d0bb90299de162d69c160248eb88e9b562e10ece6","0xa83eccd8193c8acdec102098d9dfa800bc63ff9e2f0ed4cf657740135b39ffff","0x11c9ea43918e04ee2eb81d7172b095eca1f51f66ac6a801ad9fe8f68521ecda9","0x36cb56905c616f7f25920efbcf8667384bc3ecabe54cd06216e02b1c09fc511d","0xf7b92d4fa89f4eb5e9929a198971bf78c689b3f59b3d8e6c6f19121d3d3e9ef1","0xe2f2e0dfeaf13f4b48e1b77789e3685db85fa8b440eebd7b0df48b14392eb0fb","0x547a5462e235657e9735d1c90745c25fc5ade0a346700b1479f1c4f3f777aa19","0x9efe99afde7352893354505767a3321ab68d03bb7816fcf7d41432e1c58a9bdf","0x1612f38b4d50af9b149bdb909b47f50f1c6e51877f7ce544ae0c0ed0b786b5f1","0x8f75557eb8bc30fe6d73b3bac604fc213544d9d6bc91d657248396f9d84d6248","0xfec7202862e3c9e507337abf1df29c69b79bd3213ec26bdb190e8ab93def24f6","0x9ec3bb4ee77b686018a916c711fecd831e0cf72d7083ab5c603a4844d4542ca2","0x107394bfbd5d863ec343d38f439e1235069f5b9e15e77d98f20ffa0f9efd2db5","0xde07614ec99fea2d583d5c162b71c8f672f542c7a47d3d92245d36faa9d2e2fb","0x757e42e38ec7bdfa62d298bc15f6c3b1b9c8b3fdf807ad202b23ab64638b1e67","0x7b6e2f8903befe1a9a43366163e2210e3504293ba1718f66cfaa8f04eed4f5c7","0x929ab21581ddfedbfa9f391e390ab8f398b6567e614d0c3e51f15c8babd5f24b","0x2b4b05bcd91636475b5afd95f68e1f98d7c57ead038b7352accaea3f00689435","0x6e9922b730896c42c5a769952be52af8f3002c1a441cdbed4e00c23304235549","0xf5a5d30614bc475d65e3eae8c8c46bc874c1b6366d38ae89070906b313e46d89"],"logsBloom":"0xde2f665ae7cb727d5f7fcbc2ffb49173d9bb9a9aabe1790e2e1fb2507f72bff1460745a5a63b6c78e60bfbf2dab7c7c57bc3bb10bbaa6d319bfffc6c11aaebf04e03cffe4c770e7fddccc10bf73cb2ebd68e783985503e34aa53ce4aca6fdeded63b8575c26ed62eb3ddfcfb6ba9bf1b023f36ee32d12728db55cfd5ed0dfef79b49954db57f616c8851f94fafe3c57cc561ffc52d45bdfbf7231e7273f7177feb86504e9fb1f6be7e37d1c4b814ed7f3d91c94838e7cc479ff7fb36b6f940dd4bfcb0e32e6e19b3d90ecebbda1bdfdc76d48266b56b6a73aaa75457c0b2ed8268faae44c127403250ed9fcdaed6b722f37ef75579beacc69093835c636f5419","totalDifficulty":"0xc70d815d562d3cfa955","receiptsRoot":"0x9f07488a43cee51187acfaf324a7675d3810e4f604a591d35788fa456c4a37b1","extraData":"0x546974616e2028746974616e6275696c6465722e78797a29","withdrawalsRoot":"0x28eb7d27ca24bb5ef9da7de28fcdb06838abd26b3b9529e7a5fdb3579c70d0d0","baseFeePerGas":"0x19239e5fb","nonce":"0x0000000000000000","miner":"0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97","withdrawals":[{"amount":"0x11bde51","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8b","validatorIndex":"0x15929d"},{"amount":"0x35d83ec","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8c","validatorIndex":"0x15929e"},{"amount":"0x11c3165","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e8d","validatorIndex":"0x15929f"},{"amount":"0x11c27a3","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8e","validatorIndex":"0x1592a0"},{"amount":"0x11b6210","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e8f","validatorIndex":"0x1592a1"},{"amount":"0x11b89fe","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e90","validatorIndex":"0x1592a2"},{"amount":"0x11ca1d7","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e91","validatorIndex":"0x1592a3"},{"amount":"0x11bb0ab","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e92","validatorIndex":"0x1592a4"},{"amount":"0x11c576c","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e93","validatorIndex":"0x1592a5"},{"amount":"0x3cfa2f5","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e94","validatorIndex":"0x1592a6"},{"amount":"0x11bb3b5","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e95","validatorIndex":"0x1592a7"},{"amount":"0x11b8745","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e96","validatorIndex":"0x1592a8"},{"amount":"0x11bdc4a","address":"0xff18544eef6729d9291634493089bdce0f291d50","index":"0x30e7e97","validatorIndex":"0x1592a9"},{"amount":"0x11b6cb3","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e98","validatorIndex":"0x1592aa"},{"amount":"0x11c29ef","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e99","validatorIndex":"0x1592ab"},{"amount":"0x11bc261","address":"0x839d1924ea04ca8c9d45f42fc07d1414f644a2a1","index":"0x30e7e9a","validatorIndex":"0x1592ac"}],"excessBlobGas":"0x9e0000","difficulty":"0x0","gasLimit":"0x1c9c380","gasUsed":"0x126b00b","uncles":[],"parentBeaconBlockRoot":"0x32183d6291e5f55aa67377a4a1bd2c2772192fd720d9880ae58df27d41c1d86c","size":"0x1a76f","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","transactionsRoot":"0x868e868b70c53463e7762a56dc769448c365d2a5e673935eb0d9a8f61afa6bfb","stateRoot":"0x25e32f3be27638d39979675fbf041c089068ac66184b5ffb20c57e244d05711a","mixHash":"0x827b17bfa1d9627edd6397ff66376e31aeed366f9d6b52be8f82d6b81276f44f","parentHash":"0x1d49a3c0bc37f56fcb49f5cc457a65d28b32b4208403aad49371a715ffdc50e5","blobGasUsed":"0x40000","timestamp":"0x6687db3b"}] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json index 25afceede..208deb5bf 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main.json @@ -1,4 +1,4 @@ - +[ { "block_trace": { "trie_pre_images": { @@ -3342,4 +3342,4 @@ "checkpoint_state_trie_root": "0x349c33a12c9ac7fee19b759a1aff095d5d734fda61db4295bc8f783b345f10fd" } } - +] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json index aaf7ac96f..14c6fb8bc 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b20472570_main_header.json @@ -1,4 +1,4 @@ - +[ { "number": "0x13862fa", "hash": "0xd130f124c32962894a74ce0d07fe5b2fe081a2ac5659df122a309a10b87cd2cb", @@ -197,3 +197,4 @@ "blobGasUsed": "0x20000", "timestamp": "0x66b2a627" } +] \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json index 9e263fe02..a51aac3db 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev.json @@ -1,4 +1,4 @@ - +[ { "block_trace": { "trie_pre_images": { @@ -321,3 +321,4 @@ "checkpoint_state_trie_root": "0x106d584f6804109c493182d0bb8ef06380aea582090f4c2927276869a8d1e436" } } +] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json index e1247d601..abf62be05 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b28_dev_header.json @@ -1,4 +1,4 @@ - +[ { "baseFeePerGas": "0x174e475", "blobGasUsed": "0x0", @@ -29,3 +29,4 @@ "withdrawals": [], "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" } +] \ No newline at end of file diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json index 994c1a06b..46ed3e6c9 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev.json @@ -1,4 +1,4 @@ - +[ { "block_trace": { "trie_pre_images": { @@ -469,4 +469,4 @@ "checkpoint_state_trie_root": "0x765b89dc0bbd05503b9074455cb6b1f65f23147cc2f7e7f6cd56b262569ce02e" } } - +] diff --git a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json index 20c3c657e..1aceefbf7 100644 --- a/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json +++ b/trace_decoder/tests/data/witnesses/zero_jerigon/b4_dev_header.json @@ -1 +1 @@ -{"baseFeePerGas":"0x22f4b3ea","blobGasUsed":"0x0","difficulty":"0x0","excessBlobGas":"0x0","extraData":"0x","gasLimit":"0x17ef641","gasUsed":"0x2625a0","hash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","mixHash":"0x147c45372cfe0101a4898b634160af19063e603c11d7c6bf63457e31e8ca81a7","nonce":"0x0000000000000000","number":"0x4","parentBeaconBlockRoot":"0x6ee1f74e9c9bf2a28a7342e4ff7866c37c97ce2a89f95a875f351d786b14d323","parentHash":"0x8ca953b07297729a687b40e05bf17c2c4db4e0f53c3683308b50467724485ae3","receiptsRoot":"0x36832caba1c5339c7a9ff4e63a03149d5b5de5bcee60eaac6d2a21f3a7d88b00","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2b5b","stateRoot":"0x038e7e3c67c9166523c4b2bae746f5d7cf72480af4294bb900f252faf05d04e9","timestamp":"0x66964056","totalDifficulty":"0x1","transactions":[{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x7656fbe97bca00617166f052d7c2bf678249767efe2d58699b437b64979e5122","input":"0x7d877b065e1ddb12872b21f5f4de038b91f077f802d40ae712b1072515259b7302e7a43ef8bdc60dceda1e2cf2c5f6dc5630e87855642dc7bfdd125c15476bfc17bba053f7bbb13b66e4907d00d8e968b6d30283e23c43e883ad1939067ca414f58888d9f32332a3b63473e5e6d6bd31f6914447a4566d1d4afcbd54110b4091903d3a76f94b7dff9f73f28bd04bf374e6dffc49c49e2750211a2a441c641ac30e12f705057ac95cdd9faf3f6b221ee0108fc305e3a33e10900db88f2ea0f0cdef6beb22f898d8de3f8a472e932e9315383a349276338bbc8b7a4ae5b3c5e62dc521cd4ce07fa69a4ced73f51533016f253b6a59d97f8e583b9ac1ede01e4ab64587873f929817340b3663653075c57f0272a1ccd3196e4df246d0f908a33eb6a224444bc1a9f062128aaf7bbbb58c716b0eb64dd0a51162e0bdfd8dd47c18c28ea5e179a03358a31435f4af590a636dc4972fd0fcaa5627e713b1811b53608760d1477eebcf65536a6d57076acfd4f6bfa729892d14ec6c7fa8a9207d9d60bf56c6ad7edd2de9f8223ba4e2bc7df194dd41bc109180a1390ea1a68342b64f05166d325913176a37b05dd46d09604217094a60d555147eff53c583cf904662898844d05a37dc7eff4ab537ac138d066d4bb7af4212925463fdea1cf059126aeaa9794e679b6f38311a9c63196315d1165947116ad759c2f0aa148f30074c214070a74675e3326b11566505c6013297e40f2c8392346ee33e81a26b978a48952b0a754e1347543f6a37d407ed6722ac724a9a507c4916251078d7af4627cb6a0ac24f311a5042798c66cf3904b81381c93c60374912545f7011df013e31a8c7a1cdc2d44372d016431b371a0463d54be2751a3d351d40700e5129404d3f76331c72f6b3255b270f826181b46fec687a29ad18b8226004774b78a4b37c1a5e6a499ae6d8d24b780b56950970132e6f90e28a2cee18a7121d4287a26e6b596d45ed322af4e4bd582e2cbd148852927b522f63d6b0c18033ab44ca81c1a543161615dd31c70070e7eae6bc706a2de10dc395f4c39b632a75671588e91195e604e45f445d3070a0a95436c8b6c5fea9defcc71fa59e3dbc33147abed46c83313a308a746c5689da0699db748fd0f4ab894053e584626b0ff24821fc7fadd2e988894504404463e9e758754273976124a360ddb9a4c11285ac798248659f5868094152748e64b9a3c928123722ec84d417efc8e619a5c4366606607b82307dd8b9bf24f1f7c1f25aa931bcbcfded75bc1e2a575a1f782773768d5adc2d036a4bba4518bc068c47030bc65f6a13252f29b8168fd64957211c6e11b752b1f4144b0ae905d821a935d55a6f6e49c96a8300905615efacebe94ae4bb956c4dd84a0f8b53cd087888d356e160517109f6151359d245488c918847aef5527beca916770bdde14ee846cc22542e62b9db5617db816edf58a373f41a18913344994745739e12fcc980ce06ab4a05999f1fde39c41dfaae47087c1512c75b71cdb23b572730ed055dab87d307f11da0eeae0bc671ba994c3f35718e8f55bb19cc50e03107f33bfb647891f463390300","nonce":"0x2","to":null,"transactionIndex":"0x0","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x283977096b0fa526e636c9ef2a4f988d71354afbb2b9f39200bf2d9939173021","s":"0x3f384055facc74f5d465b3d6600b7973d7a2fd6888f1676dc2836cf1bdb70ad7"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xf5bfe3c2772f0eb210ae36291ac3a1c2612de813db636967017d385ed3f61331","input":"0x6281730779f6d4e88d5c0f26c588e39464798d0e09d6d146ad2d2cf019e5b03f757f5222d42413a1854986a62791201822573bf0b584958116665b8fff83a5aa6d5b677db32c7e35af172e0a6ccb5b6aeb93ea07e199e36fdc647ec500249255bb4dcc8071166debd343ee52ada0f071c81fd4e0153764325b876bc36a46235b798471ca5bbfab1b7437f98e64ae89ec087ca98bb45344142d659b8c16e80a506e72da543eb31bae4fe6a86ee8e4ca6a5914403f5f65c941ef1806b30938903a086d6ca24fe1a7bf3ee5936fac73f6335f1831803550067fa731c9e26a5582dc3792bde1c3d2ba9f5bb03775638cd8ee38fdad626aef958e3f5b65e9c5e215728571b4b3db781f13a5cf5588639944aadf43e4270202175b6854c6b8b248d1e1691161eb025890756dd29827592cb1852236b020e82631eaa6d8d21f9807198259805d3d68f0485ab07e2e6c1ef97b9b0a1781584a676a71a8f6ee7d2f20e2bbd75bdc0fb8bef831515da4787d6c4a12c2ed00fc292387d8c1f284f7926774b3d92895bc7f023d60c93f845571814311568810f5d78742360266ef1f64112b3542724877e14348e0062400379dbed5812312a8eeeb46843d634a1876cf5b49a46c2ba8cd9a3f3b35c13a55645ef3945145361d070938537aba4f5a9135bc16146be05c42421816f5122a6b42489b3cfeac24eb708e6ed0537e5aa9bd41327c7a5eed3741b83b70ba81bd5dd3a6b9cd1d67a0cf7654b5fa4aa05444360965c202effd4c493283455c5548453e747cdc0772d1422b06dfa128e967a9319ad09fbae0d81166ed70237c838f275b4a3b668b12aac2afd6e5733436e0a455e7c67450988a4b20ad0eec20d1eb5b764171b25fc048261ea2cedc8e4da6ee5aa5f11d9f9bf67614363a6226c075905f704fdd3dcb81f1db2dfc697cb45a797938a44471069d4a6976c485eba5a6cb643901d2aa4dec96193d83593684677568b6bea2929090123109123191707d93b413cee3cbd6a88b07e9ca17207e357de30e32f5f8b989a810b3d7b3a24da8f73ab1a35c81450f3c0b9eaacad4611109100100","nonce":"0x3","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0xf7a4dd0b626d2fa57e6e3edc804fecef9b367aafc239ecd8aabcbd917d73fe43","s":"0x6780e0f00ba63a8e9b86888d169319248c186e313516c62bb3ce35a736e93a88"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x21ae9124df7c63aae240083d98b152f1e71bb63b31cd5e8b2927e7fce841c1a1","input":"0x5a6e78adf9e9c860090527daf5786ef962077bf962f7156d7620dc0c8f6cc19a1d9063cffd426fdc040f0f9b3474af111945173d8091157925a03bbe35662a8b5c7e7282a5cf05014ae32e5aaf51c4440d1709811c353b3d306d7d1ca284ae95773ddfda82302667501b01647b20ae9c8770b6065442d3df94925a314b0f7517ea43de1b067112a8cdde51c1be9d622612cff5cd1f5e361a7c3fdfebf14c15967b526de0d94e33b2c7b8ed15e40a7274fbbf49d2acf1106236b710732b6b01ec732c4290df6f262a73b989b21f3e79093637423d6c956af497051acacfb61b73169975ead207fac61be7e1b89410f38392fbe639efe9c0ae4a817d3bb53994df71826e55696aea8dde32418d46215ed66dcf1ad4dd206e149573918e63fdd5e7017185e1fae415d17d0ac36c088f44778d52900812c606c8c65d889a5e280730e2ff0a62c2424922387199ccf61ea3f8e950eae428957f2a6bb6f94e31792a17ed550aa5b128a0ba393263931a2f9f556190704db80be47084996a67b3b9145810fa41f371203334496cc5fa6355cc75e37d271be63e290b1668ac5fc04a6c85db2d928473dae050e5d0478b40656acfcbb32223c1145decce504a639e837b0314730a1ce5670c21ebbc05423e357cf537e345c4109c805c086c51574cd3226261df76c4a4a39a137c8b087db775847b8684b3c20ac384ee4d4225a133d922e0f93a30d1dab2904640076f6b1952877021ff81ec9e94b0e2f6332082816d7c3097b99ea4c163368d6c0e3f8c1948331a497f0e049d679a1527ddde74350fa3a20df460308237e771db53670559375ad1d06833507f57fd63b05727d4e401ef39e13c471149984d98c7f31adf456a1e42e6c8c2a160596502c378d3064a4576e8bbe143996f49f344897194145f1fa60c62cf66df6a8e31157d598c35ad06e7a46408fe2f893a8deda14dfe7ebc56fc0c61368fada78fca4a764496c68976b9067066e678fd4eb3cf9e113a2a36cdfecc7ded22ae3b074b9b8c661e4d212fc6dd3ff8c46c9fab1b2d6eebdfdcede05c0543554a7948d33ead88a2b15c13707534db5fc93d7e9d14b1ce0a418e72898273d45bce6ae6d5c127ec5e8c5f4dddf61c8802e23b34065875862f58a8f8e455464265faba4e70b00c66bda42be441793416d9a0534d3c4c6f85e3eb551a9bd3c8b16437943b9c82d92d10097259afae8b5947a5f82d4b2f16f69405203ed3a0300740611fb0963d3585460260b65a97440a7c334b52e7e538d491be6962a23759e2e37e0e1fb18acece799d633c7b90706501f1784e37d6fb0ae8bbf22ab7bae51761f72e501746483d611ecd3d1d134646a267771b76d614a61d996384e10ee76d19bdead538a3ac820a4f52ede2324859f3","nonce":"0x4","to":null,"transactionIndex":"0x2","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xfbebb228bd4889062bb381b6985560c11673c93decfa7f7f0a92994443e52e46","s":"0x242b17a736b410de42f7f8883cdd68bda91e1fa0c56a2e49497db67f569f4916"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6462b263a2526b1b7b7ab7e13d4d6ab9f60b27fbb8de818fcb13a53b1c0476a6","input":"0x654bd6d64e3263453501652f5d7a6a9f467e021a48e0e2e63d740b7f4e030d0efd24fdf327b78a560bd159686f809555d15d7f3cce1cb5c233ad51eead13a143aecd01cd2848576ee548524b8903af4cb3821775142b0f844092b91738a8e662a8c9a6068bd839941a6e3576364d042af044db4f0cc60711b7aa9cc27c76e27ee6059c7809dcb918d279096edd4e4c74118213ba23f600dec5640ac5021a5b6d7949bd674cd05cd14799ab3f136854491d6e757d8d46c121ead807cac1af9a6d126ec8fd2e39e65bab737d564980a733e2650d0172668895485f0b355062bb37a27bfc5d044379e1fc9779b9d4987ec4c11c4a518be9d2e2becbe15b85e2781684377a9156d3cca334b67190a690ae5260237706bcbdecf9436a2c7ede7f125b1260600cc0384154380a6682b49ed2ecbb7968479553e8408b0a1e1011806ee4b49031b09b89b757ac450382f1453b4544944431629dfc957f07d86177d05403434747a7f98981a18b14929c1e04be6fa90705a08ac133e008326487e2b9afb334792946d3850e77fc5ba555cfe29c5473b2c70d567e139af63170de94611a056cacb0336a3d0912028af7773b047dd4b1b8bde125aba206f0f3b2f131ff1fc5288f1b6c08363500d2bf8bef47906fa7c93bc9e7054e6ff13ce45dd0bd420a774d4f35a1ff1e0b365e96e1b11eaf0b0cc051ef508db86a3135389e72bf4b76e7f5dffaaad9986ca679a47c7b6cd5641c0850421446306e8bb50c49c9e52572b32a8570b83ec336956ab1241aa5c4ec3fcf3d0c2f3a63c79c5a1a3507817400b545f6d3c816fbb03147f8919549bdac32a5081344025f54410602355235301a3d6d4c957cf68ee44c9fbd94df2ec34d6a2988d21e494254446fe655655995a22df0b87ee042745c41c23d8852a0a8848dda3201fe3eb275bc9b51d81ce4dbf4663890507939ca4d2742a0cd39b8f19fd9a320b0cd24623eb9352c1bcd9fbb80015a77ebe3560fa1f378146ae7c52c19b3acf75457c70b6d53e27a6e10749d40687ddbdfe68afc48baa17858406bd160cb79426e7151d3959df5114202727e83bc085148f16d7974f60afe2822ca2dab4701315b7638c4688673be125950aaf4ec2148bee12e591b94a63cc7907bd7b6130b6a2637be408f57ff64e809edb70d5843f95bf0e47268104b74e0a8d3c7a53f04d2740f6ad7275e929e088cba80e210917ef34d9a5f510b34789078d6c3b4505db8179c66790e7b493910d4e0d43c7e44825b848661416e556ad6a6142253354c2c9b4e28f3","nonce":"0x5","to":null,"transactionIndex":"0x3","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x1ce5515735ac68b86acc91f18344f8e74e73ed4071578ba31a8de536e4586c7a","s":"0x38e91803b82cd8b8654be58b313c349a940377f2633ca06a5104e4485db38c39"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6a4df1dc08c2d3aa7e0314a41d90a23a245fde2d225fbf9300d6ff90e9d3f4e8","input":"0x5862cf54ee7b567d587def34aef4eca73807be997b77ee9e8f1aeee284eb4869dad9748fc6dc83bd45f3010e3470f1065cd024d3fc5eae65486893986b78a873372cbe103f6f8632afaccf48b78450d5882152f56d7746020a7ddd255786c2faa44d55dc8d3b11659104c565e6516392c5059da076caba4d6e39ec331759a47988a218d5ff1b757c7c5efa6d42150b7a24cd3de45a1dddf03aa9a62451855579bf538a455c436c2a134a2f9d27b3b8f61a6b6ce169b81cf86e1115b41534733b156f989635db9686b550aefd3c6704db994c9441681003e33ae52bd7587c367bfa5eaa8f9f3bad48515ac3bf2795155655471c054d6559624262ff6f6632a9fc7cfab1e4301c783b524fef241e898b2cee25ea286abd4c9fedff90096d9d2579404649439f82464aa1983e71a770c79b172f37aa1de2e806cc3f15f707a47ca5a62fc6af987c598da291fbef81e5bd90d14691156669df20eadcd96e0273e384d83e195bc105cd433f33bcbd23114a5ece605b5a6a5c6626b98c770803e5a4c93536165d6792c4b5830ad0d4aa5a1c5a1136651cde8a70bf7465217b4460fd8b107cfa9acab56dafa8c4cd4c79e2c5d49b7754ade6eff8884764055805f6271519036558c7b712d4733f719295b1bd2dcbdb070335cd6cd3a3896c59ad4577473ae9acb5eb4a2fdc5f6ac73f94538bfea0cfc801701d2959664e00f07239c530905d047b8c2e6f43cd6b914b00f4129b513062a41df190a4eaa3c2a7eb0d871a926d6651f3391a7f086ead4af9d8b18d801313644564be67a66c7132204bfe57f2bb8da1d712956336d027d516446b0709ab6192da86c9a42a42284a7209f5f9e69eadbf2321e0a38392a77ef8b5c187591704100302726f627c6c08711bd91c261085ebe91d926691c736655c165d8a8c2d3b7dff9c8c532484ab475b434d46152c3c85cf91e70e249a395ad7898839d507a15d5a343b7fb2fd69136c6b1b50eeab706ef825aec6115339134537bf890f6d9b96f27c15ee74d37db6a9f2dac4e0dcf1fc6c4915eb96d63c49eecd77038e6e1206bfb93e2d6f8c82ea9b0d0e4ae117e01aa48b5d553d921d668f4baa8c02d3241d40451570ac90617839f7125487525183d96502390c7787ebac9684e510057870d07cd0e6fd3ee2cb1be4ccfcbd2637343864cb3fc84fc847081b304a7d8cfabf507db1167cba84578f818f321cb9596267cbd5a14aadf5ab61f58b163f3f0a503df3","nonce":"0x6","to":null,"transactionIndex":"0x4","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x501e2d2bd15996cc0eb097306f4f76de2077865f934e459029caabd094c5e578","s":"0x408264ad8649ee95afd43f869be7de87b296b364010aeb18a755fae3dd0a3c49"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xc43c27001eac721ba1d80d27040175725d521d8c7ce5b4f23cc4984952ff6527","input":"0x3a6699e1e7330c28da6f04c0a5ea93bb08f398feb8bcf76b06c47d5cd56ac9b7a09d33778872698a54bcf759f6ec9dea796b71070ceeafb7fd551a7562dba64309a4f0dde67311c854aaf000402a5676d299704e9b47599993a34826f2258904f27ff5d466dc1bf50204c4550b61439b5b620285235b41321d6b4439fca574c375a580ff328e1470c9d189f5491caa3ce96be3328210f927b7336cf46ae82840ee30a127f352a7003b6e47e055070125ff825c42bfde60673b1a3b6e4d6e353fdb998b93fa27cf318ca37018423a0767efaab50662eab61945066c7af69cd44ce8771c51991a996458831a79da2537379d33715d8433659007805988f338ff6412d24a9839bc3a117c86946d3d173aefc5bea29a1859dddfc8e66b08cbab1adadbd45cfeaf6b5542193410926d12059b59bdf54ab4ffdd93f0b2e9800b5b3178dfed60169b04a17365238fdf683d34c3fb2229e770e53d3c6e603982635f435133686856b881186053a6143703135c606b654cb634b4541d6dfee6775dc8ea6ec79fd0fa5d0c724878e34ea1b41bbf781e0907cb7222fd76a4ef1aaedf38b3e9bf7f0942636f920d823043488039385a6f2f01b71bef7f04713058ff70a8ca081c130b8032a368517893b5ab0dc908025b46927f6e8e97bc65e2a6f57bcc0ad8996dd29370da8d7748d50f65a0205df5cba0a2265f307eeea4108c370dfc8b8ba96f3303903933d6cd77221b735a238387bf09a0cb6c1b1832315f788f476a8a5c466423f9868486e88366b60bb331f3920418450f71d9c53bf2a6ce0f8651ccd6837242a438a2a56756e3e86bd181eaea14584608544a7481a83b687c2c2700e6225f57e5c76025da7bc0af2f1554682d3704e733b4a850a87b3af2ca511a0142bb1e09e7e36bb09244def2903aa07ba979735ea71e54051147363b3372bd5007b5b30fc60812d7dcb82f9b729a845875614947927565b8a58d8dcd807e8cc4063d8253728b6385fe15f98e3d34476c692f2d92a0d0f0efeedf0300d046197ad59f80110eb2e8efd3e79c4c8f91766544cfcfbcaaba1c7e7015677c89a9f3393a5072eac9a75380a14044404f5b989b1f397a20564d498147334461ab94f3","nonce":"0x7","to":null,"transactionIndex":"0x5","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xb2c37bb632e39954fbd9f339eb90e3fdd36d7714b7fdd9764a732a1fcb9213bb","s":"0x41e04a31f1b06c053d5d73daeab720564f10b1aef334293322646b358705019e"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd802558258227491da149469648c395dfd9e566d8baadbc0edee4b8a9350dcf7","input":"0x723f63030479b6750c82e768bc239a909d3cea3c5c5c40324507135a0b6d6c6671d356274c8b1fbc2a9d8ff1105a3a6036014320451562fadd213574af6d470e2141e029822e894cc777408dd90ea2a63c1d64701441ae7a916f6e0d10fd3c5a901dd08836d6c08bf71047421b44848680957a28bde7c3fef2d62d99d42079a6a200782ee8df64fe64b3ae835030a369116b0456291187341a7968c6eccfc186e478f3d15a7c52a9e8ecc880118b8e123e4a6dc78dc5897fc7faef850356eee2d7c58e8296404aa26495b08d9bd736920b1c058302a10260bc35553b6fe23560c77257896c3218c53d309217e7779fbe08d2200d896e7cf5264a73ee1ab68b392ef126446bc71a04609973f34ab88c15fbc3197da98d98a095e00f84faa9ae43455b0172b4beb4c32744615f2c7da670f1b7db0a9d5d6911611c3374e65622841c856f03909916f1e17cb4aaff4ae6e19c1a190212095468f4bb6e1fa915ea16c55f61fa08526e5ca93058aea7015c4f8dc1cc0a24aa3162e48d5e767d9fdf4138dfededa980cf45a0404b086fc56ad9e3affd50580317676730bb2d4e27676b1d6fb6cf2e65e73973859b58496c7f5257ec6eb7b88cb247e7b5b5a2cd7d85445831365f73ff856798e47349fffb0b92537d5b2f6396f0da0a60ea721cc98fb04ef8a5a171cdee4123bc01a9f16b5d8492075064dbfc9527bd451d503375f92f94e36303ed18b1d858a1d72c17191b3bab68eaad66f5083b769a9b7b710b5b8a9a1b2c0068550295cb2e165e678477807eea233c8e451b0dee921962b0a7b94a872a40b1181461b1157683d96e898c34505f627c5d6e1c134520476443f229209e59751142b0f45bfbc25aa225a0d0ec8acdd32c453118ed273d45556ef846b9418fd2e93d48b0411a64b362136efe3f4abb98ce57f08ff2085dbf46aa5f143d792f5b1b34162426557265bf21ca655ea91489da715049f2fbb11ca06875fb2b7655c86816fd65b83c4a33df561032303d7773976d1aef53f882f2e157848d5c9340d46de54b15fff6abf3","nonce":"0x8","to":null,"transactionIndex":"0x6","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x4d924fb5f571bce21868b25f94690c57d8fae822964dceb841f56b2228c3d1a2","s":"0x1f5bb6a84fe40b6cd56d5f4f99bafe472c7cebecd996ef0e0d3c78add601e7ef"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd78ed182d5b55254d6584a6f8baf2ff6a7c5ffd5f2c23d3d6b2b00c9b5e7fc07","input":"0x586719e3b335e5a05892455e79e08ce21a9afc02c83e5f768eae9fa00b39a158dd7091c4fa7a6b35364580046435b81b90097f197715cc6892806d41402f9e348f92a4bdd6baea99150349cbea59a2bb9635041154403011536d27ba3a210f1e39251f45b399acae38527bd52d2f458979698118a508d3dd9be2462db4bea525dd26e4d6a6b344757654b0fa84a1048dbb6441ced8bb6efe98493a4022ef0738330750415c04648b8df72298357dfd3d2006b16651c845c06c60a7f0990bdb7aa4cf31a6ae4a4ecbc6b52af04071988cbe72b7c034722389090b53e8facaaf5b79269b6dd4754f1109d9056dd94e2e58f1d4471385c5438cb11216063a9058657fb92e3fd5ff5a7f3e8f0db7c708432c4a9d73a5819af8c164f48ed2609154d895f9e2d463aea10561c8e36d3c0a55ff3302037a017ddeb547d66b945269d12a839b755b8af2ce491d367f1791e601faf06b7a85c1231a27e400a1899c7f49c99e2cf9bff0fa37496f67c65f801a3433347d93b23dd1dcdef91dee790a97e04fee26205bb52bddc2777a82edf2d4b8c58b5f55321166cc5704776063c54302318d383b448f90175f1c0535551a04841106525d74eea2d5f0460832323b3bbf10f62d22d5ba89e2f437437a506f09f7d5f64a5e751cf8e38a5469637d24c9443b88f8af3eaa867654dec790a4105c52f1df1a54511d78b55f439962bffa3041316e3f30c11a100b50278048fa7a7db73838350973e69ce694bca794ecb0c50887f8e7eccad276a086466c29b25d02248a064689199a56ea418580903d70a019acf7013b8c71acca923dfa062494185f63425b9c3f786b59228e4a4da2264f9381532a9934048e28fea3569d2f77ad61628a3f8d316a3c3fb639dc8ce4c740dad66e16048127d881c9f1ad2702f5ea96ca09107a787c6dc491941a810e9aa8f76e77efbfef3dc3b5ea37dac094332f07089250170768625554d6092aa82d744317625ad6fc495364a7c09b2ac53b74b35423a81c4baa75b35e3ee5d33822b6f152201e0a5c7c4f517f47cb1ba9e18c879dd88dea8fa53ee541d2163ab4fede017323f53105151c793f6c302f14785d053d591ee0d2d6e706c2fdb9cee826072f4cf1546e1ea8cc798345123cbe00af96ce94ac4a11765a6449ed7e0edf81c888c9bff074ac439bf598dbfe7fad83661b70142cb03b2164171718c5c739087019b6dc1960dd0cd875db87b3fd1707210379ed6df649fcc52b7ef38093b57105b6dc5960adde984da092cc0c7f99e9f4867471c5d770b67f3189213ddeca75170bb947fa6b68fc9cd8480f213a7774b20cd25d83ab90b3eb4465dc0e88e5c33a659239dbe97d3b712498bd66007b07593b93dd6cc2f2e014df307c9d477d6b368b004b2ac553f5c73e1a70bbf4c9061eafbc64bb339932783a446f2817e422c934754dbb654891dbea919e325a94035afd","nonce":"0x9","to":null,"transactionIndex":"0x7","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x6109e0c44e8f86754478f78ee90f0c3a8d249605655330407342c534bb8fda77","s":"0x3d1cc3c94d2d1b5ec319385ae1dee73c42b87a88800e9484e8ff91d62ebb1940"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x49b652060da03857f56659b1ac638fd132c6b80c7935e655430946c3493b8539","input":"0x7f17bd908166a67abe337de1b827fcc93e6b66bf994e2b9d80c4115880a8d6f0196f2809a0a7e8dbe569eb3f2ff48ac22951762de9b5aaef79ae2385b8da667a578501bbdbb78c42baf0335072f9c5b5cfd1774b78a180169e0a7efde997a52b31054a34440758480569e84779c4a9af1ce56e6f951010423fa1335c314a18774889b6b7f9eb3e198b15478d0c71a8e04d30070b312cd20f76b67c6f65309b0f1d0b77e407cc1d619b538fb7295788bd82100a492033183a7ba7f27908709cefcdece11f88a3c0ad85a3570bbc2591473f302ded85161d493462a2a668020761482e0366f502a93e08d516407b174d49e88f0558de52f828d15ae2a3af2cf0152e4c522cf8992350ca33457725e519df12dc87e0f0b5f8492a616da359baca2bf5091f7c4158461a6b74da6b9d63588b5a6e91e88015700730acdb62d1a948ec56a20bfa860099ae33180a5b4a473877ee13ea235ef70e7300c0a33c9cd3bb41854181774c952e4b93050b6dae8c3eec863075b74076e3904b297f202e328d9e774a935dc1e889c52d97e9904a2dfe890a420461a8f59be3eb2c2c3664f9941b919d5b357f6a47efea60ce84e43f7cff2e016340b2f7320799342da6cbe1b4d7a0f868747e6968ba423780ffb352ec23450a316f250100000000000000000000000000005780171d446e9474fbe92d88273f6f67a31e230a0743511a5c6914c61ef7031bc01321cc05437d810e73a7ef059f110ad8ff161313c4caf5c127033c11b8325715fde7d02b0467c271ba9f257852265e65ce6500d3c0cd3802356edd2f556fc26828cc3f0f364fc94aac491933746886084b89f565be10da4034d54a799ad85d649e09115f6bb061a180be0c83f510062ebd0a5f6d52eee67c06aad2e6e656ad2893a31736330477fe44808094d224ac4569193847ce947eab31145de843d1c115461b1b093347688bc316e54fdfad0dc702477e96b1087a022ae5d329a2c119e4eb3ccd65f0828f4f76382c4a500db9f714bf7e6dba39332866eaf69a0d71522a0f2a8766da60f9f8a4186fd54f34021c562e1778d865f76016c699f1370c8a9acb9654ef137bf146467de8cf50717fd4b7f2c5cb67680f5401cfe4f679bb26d3551814663a2232a3fbd5ee7af0f80df5741e1801c17c93557b2ddcf0da8024cc37c6e745c540066a3f80270928913ffaf223b74a0663625d012d5c654d3d0cabd12c6e4ce68f301251cdb75e93a5c4d73147356743dd7abc434dbfb25b601b5b935b5960147dfb22ad4a7efef3173066d59e8f4604e4c7caae5ef510787adb5f8a1fd1a8168479f19a76bdbcd60c12d1162871225f5b5479551e42f002039c454c47928a7bb525fbc374b6c7a19f3d0f344fb6077dea6d4cb6690cb9356b7ccaa95074ad46519fd18ad0b35a90e21c0c00b19bc581f98f9792423a6ec6e6078d6ea0a3ccd43f366305b685453f4106937ed56b85922c350ba46a747ca7666a11fda7c0a11abe269a097257f0181d212d685b7dd5dc2697fcd88908684dcf09f6e286dacfbb0a01629b432a905c7b0b4d46f35c6a274301fcfa70e0c371eb931f53682111565f5d7b9b3184785a1554a1ee1df94b52d9ecad8bbd118b52a1b8993462f366c54a78963084fa0506cb7ca18ec6675c6fadb89bd7e15f006c229b60176b0b78d5317562c7dc4363761f5940436d321acae8a4ecee4574a56810ee1b5c3e1602023a1c633fa66ec2721272d0ea4fac46693e75bc5db0a9b46e0457a3916c5e98d0b91798c5a137dbe92508365193011b5569004fe9a0ef75d73e226068fe826ed2eb9628aa8d00","nonce":"0xa","to":null,"transactionIndex":"0x8","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x3684ae7dfbbe8f075a746bf35c18f4d356f0fe3f8b36150d1d394b744b0d64f8","s":"0x65ab2592621c1f84e80f032b57827e9c4a462c91a253bf962d82ad5058acddbf"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x42d9a64ff889d6d809b0e0b8d2147380e69f07cc931bba7e5e956857a1f24a74","input":"0x3265be11bbdc2d0b62ed551c706a553c383a8376660605baed8d32e89be71912303d74f4a4aebf9563da189c9d329203ab1efe050eba2e1e6f4244e790e2bcef634ae7f82335cca4f035393202443735406d03651a7f23d8d15684607dfb5123703c15bdcf73c4b074ef8c1a2ae5d5630b297f02bf0839297fbdad3532ad6aced6ea91839045adbbaa995ac81ec175387683366d6865aeab5a1cae244a00b3672c8955140862a1ce9d63d2d4b3461671e3a7851fb5d8686faddef58d5204155361e2036bda45f7f808b4841cdf8a98927c850c1247852ff810df7c43735ec6ab45b25afd59a02953f5b04a1f852b5f7c874d390f0e28dc172477b4f9f4bc83d5ceade87719320fb398edbeffef3077f4cc1f2eb7309e14c2bee019b27833be93bf239dcbc861bf63d793bdef9674e0534fe6c558d896684ad7f6beba5d06074a6f6b0e757caf524e155fb43a53b895362ebb62efc0f390459790043f0335055b6ebc37afc27971790bdece822fd327843b0a74ec5e4a862fbbb7cca3c2c944a8ced4a6ff3c9b0312046c18822181cc59e16c88411baeac483414055374a6aba799aa8fa3925b04e2b3f0c0fcb0adb54bb9a97fb91b8540d072b82bf4450c71f602658bdbce963867a0233f5c763309cfa75a16650f03971c2d76497130d77ce731ae1cf3640c98892877bcb452ba31151d3b534a78ea60f5944cbb9223dff39982e2fca1580456587fec201f5f941d720225db2020ba4bc85af4fa135d4101b75eb628540a4075438f328ac4cd2263f17e6f9a71e7418c9e5f29f4418f413158080340077ca7efae6a77bb3e1b9e043ad62ea8ea47ca77df6c3b66112112bd6de16c7c7327c1efd8a0a400603f132f1e3021961c53a175b06a9ad504cf2dff6b82040b1d7c2522c08e24264811b48edecdeadc59cbfd7885c2884be1b00f2d3edcb214364a4a3660de7f75ccff410aec97a28d677e9d7cc1b1eb20f3d838a2f67eca0ad2c18f83705f0e7d864b976671612a69efc46169ba23a4ff4cc8929ceca71bd8b008b9a421fc467ff0adf3e8b4d7b712cc5a9096c5d0a05966bf5dfe0e4e42677c101f38a5ad595672b931c919cfcef0f2b9099bf013277af422896c7d574b7801902980f2e7b52fadd7dcb1e5f77f7d7316b6ba74e2395e005cf61b7579d89758aa392d8470c851ed8dc04dc3ca16b3c6e61d54361a095c4375add08f41772325037e8a48423fc75b0dfd8d4e23f00615650a12f8bac5536b23ef30f5ef21d419dfed66a71408465f6c02e408709d1c841cb5c624fafe4732436bf42069bf1e2a16ef9282fe6347106426df7c1c3f7bd766d0ecdba3618232f2a8895cf36867744bb20d26f2b658743a0b5d69f6f327d9ad6a212bc64067776f381dd4579a3061332b36453d3345708c70ddf50a8ebca1e08d183f03b084b1f662bb6608401c7c1f2d3d34c8330460ac9ce148b04c8b4b9d0e6ad5308c3bb29f9c3f4ffafd","nonce":"0xb","to":null,"transactionIndex":"0x9","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xa5cc300b87b70f6995f9f58f62766e4c941cf89a8899b2e35d5f717f23340dce","s":"0x62defb73ce79415784dfc9ee655aeff22ab9262b4dd4ee76f97f8e0fcd5ae23c"}],"transactionsRoot":"0x72a1709a55d218d846226d7fe3db24c83ef6ce88f130625731a6a28d8ae1147d","uncles":[],"withdrawals":[],"withdrawalsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"} \ No newline at end of file +[{"baseFeePerGas":"0x22f4b3ea","blobGasUsed":"0x0","difficulty":"0x0","excessBlobGas":"0x0","extraData":"0x","gasLimit":"0x17ef641","gasUsed":"0x2625a0","hash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","mixHash":"0x147c45372cfe0101a4898b634160af19063e603c11d7c6bf63457e31e8ca81a7","nonce":"0x0000000000000000","number":"0x4","parentBeaconBlockRoot":"0x6ee1f74e9c9bf2a28a7342e4ff7866c37c97ce2a89f95a875f351d786b14d323","parentHash":"0x8ca953b07297729a687b40e05bf17c2c4db4e0f53c3683308b50467724485ae3","receiptsRoot":"0x36832caba1c5339c7a9ff4e63a03149d5b5de5bcee60eaac6d2a21f3a7d88b00","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x2b5b","stateRoot":"0x038e7e3c67c9166523c4b2bae746f5d7cf72480af4294bb900f252faf05d04e9","timestamp":"0x66964056","totalDifficulty":"0x1","transactions":[{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x7656fbe97bca00617166f052d7c2bf678249767efe2d58699b437b64979e5122","input":"0x7d877b065e1ddb12872b21f5f4de038b91f077f802d40ae712b1072515259b7302e7a43ef8bdc60dceda1e2cf2c5f6dc5630e87855642dc7bfdd125c15476bfc17bba053f7bbb13b66e4907d00d8e968b6d30283e23c43e883ad1939067ca414f58888d9f32332a3b63473e5e6d6bd31f6914447a4566d1d4afcbd54110b4091903d3a76f94b7dff9f73f28bd04bf374e6dffc49c49e2750211a2a441c641ac30e12f705057ac95cdd9faf3f6b221ee0108fc305e3a33e10900db88f2ea0f0cdef6beb22f898d8de3f8a472e932e9315383a349276338bbc8b7a4ae5b3c5e62dc521cd4ce07fa69a4ced73f51533016f253b6a59d97f8e583b9ac1ede01e4ab64587873f929817340b3663653075c57f0272a1ccd3196e4df246d0f908a33eb6a224444bc1a9f062128aaf7bbbb58c716b0eb64dd0a51162e0bdfd8dd47c18c28ea5e179a03358a31435f4af590a636dc4972fd0fcaa5627e713b1811b53608760d1477eebcf65536a6d57076acfd4f6bfa729892d14ec6c7fa8a9207d9d60bf56c6ad7edd2de9f8223ba4e2bc7df194dd41bc109180a1390ea1a68342b64f05166d325913176a37b05dd46d09604217094a60d555147eff53c583cf904662898844d05a37dc7eff4ab537ac138d066d4bb7af4212925463fdea1cf059126aeaa9794e679b6f38311a9c63196315d1165947116ad759c2f0aa148f30074c214070a74675e3326b11566505c6013297e40f2c8392346ee33e81a26b978a48952b0a754e1347543f6a37d407ed6722ac724a9a507c4916251078d7af4627cb6a0ac24f311a5042798c66cf3904b81381c93c60374912545f7011df013e31a8c7a1cdc2d44372d016431b371a0463d54be2751a3d351d40700e5129404d3f76331c72f6b3255b270f826181b46fec687a29ad18b8226004774b78a4b37c1a5e6a499ae6d8d24b780b56950970132e6f90e28a2cee18a7121d4287a26e6b596d45ed322af4e4bd582e2cbd148852927b522f63d6b0c18033ab44ca81c1a543161615dd31c70070e7eae6bc706a2de10dc395f4c39b632a75671588e91195e604e45f445d3070a0a95436c8b6c5fea9defcc71fa59e3dbc33147abed46c83313a308a746c5689da0699db748fd0f4ab894053e584626b0ff24821fc7fadd2e988894504404463e9e758754273976124a360ddb9a4c11285ac798248659f5868094152748e64b9a3c928123722ec84d417efc8e619a5c4366606607b82307dd8b9bf24f1f7c1f25aa931bcbcfded75bc1e2a575a1f782773768d5adc2d036a4bba4518bc068c47030bc65f6a13252f29b8168fd64957211c6e11b752b1f4144b0ae905d821a935d55a6f6e49c96a8300905615efacebe94ae4bb956c4dd84a0f8b53cd087888d356e160517109f6151359d245488c918847aef5527beca916770bdde14ee846cc22542e62b9db5617db816edf58a373f41a18913344994745739e12fcc980ce06ab4a05999f1fde39c41dfaae47087c1512c75b71cdb23b572730ed055dab87d307f11da0eeae0bc671ba994c3f35718e8f55bb19cc50e03107f33bfb647891f463390300","nonce":"0x2","to":null,"transactionIndex":"0x0","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x283977096b0fa526e636c9ef2a4f988d71354afbb2b9f39200bf2d9939173021","s":"0x3f384055facc74f5d465b3d6600b7973d7a2fd6888f1676dc2836cf1bdb70ad7"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xf5bfe3c2772f0eb210ae36291ac3a1c2612de813db636967017d385ed3f61331","input":"0x6281730779f6d4e88d5c0f26c588e39464798d0e09d6d146ad2d2cf019e5b03f757f5222d42413a1854986a62791201822573bf0b584958116665b8fff83a5aa6d5b677db32c7e35af172e0a6ccb5b6aeb93ea07e199e36fdc647ec500249255bb4dcc8071166debd343ee52ada0f071c81fd4e0153764325b876bc36a46235b798471ca5bbfab1b7437f98e64ae89ec087ca98bb45344142d659b8c16e80a506e72da543eb31bae4fe6a86ee8e4ca6a5914403f5f65c941ef1806b30938903a086d6ca24fe1a7bf3ee5936fac73f6335f1831803550067fa731c9e26a5582dc3792bde1c3d2ba9f5bb03775638cd8ee38fdad626aef958e3f5b65e9c5e215728571b4b3db781f13a5cf5588639944aadf43e4270202175b6854c6b8b248d1e1691161eb025890756dd29827592cb1852236b020e82631eaa6d8d21f9807198259805d3d68f0485ab07e2e6c1ef97b9b0a1781584a676a71a8f6ee7d2f20e2bbd75bdc0fb8bef831515da4787d6c4a12c2ed00fc292387d8c1f284f7926774b3d92895bc7f023d60c93f845571814311568810f5d78742360266ef1f64112b3542724877e14348e0062400379dbed5812312a8eeeb46843d634a1876cf5b49a46c2ba8cd9a3f3b35c13a55645ef3945145361d070938537aba4f5a9135bc16146be05c42421816f5122a6b42489b3cfeac24eb708e6ed0537e5aa9bd41327c7a5eed3741b83b70ba81bd5dd3a6b9cd1d67a0cf7654b5fa4aa05444360965c202effd4c493283455c5548453e747cdc0772d1422b06dfa128e967a9319ad09fbae0d81166ed70237c838f275b4a3b668b12aac2afd6e5733436e0a455e7c67450988a4b20ad0eec20d1eb5b764171b25fc048261ea2cedc8e4da6ee5aa5f11d9f9bf67614363a6226c075905f704fdd3dcb81f1db2dfc697cb45a797938a44471069d4a6976c485eba5a6cb643901d2aa4dec96193d83593684677568b6bea2929090123109123191707d93b413cee3cbd6a88b07e9ca17207e357de30e32f5f8b989a810b3d7b3a24da8f73ab1a35c81450f3c0b9eaacad4611109100100","nonce":"0x3","to":null,"transactionIndex":"0x1","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0xf7a4dd0b626d2fa57e6e3edc804fecef9b367aafc239ecd8aabcbd917d73fe43","s":"0x6780e0f00ba63a8e9b86888d169319248c186e313516c62bb3ce35a736e93a88"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x21ae9124df7c63aae240083d98b152f1e71bb63b31cd5e8b2927e7fce841c1a1","input":"0x5a6e78adf9e9c860090527daf5786ef962077bf962f7156d7620dc0c8f6cc19a1d9063cffd426fdc040f0f9b3474af111945173d8091157925a03bbe35662a8b5c7e7282a5cf05014ae32e5aaf51c4440d1709811c353b3d306d7d1ca284ae95773ddfda82302667501b01647b20ae9c8770b6065442d3df94925a314b0f7517ea43de1b067112a8cdde51c1be9d622612cff5cd1f5e361a7c3fdfebf14c15967b526de0d94e33b2c7b8ed15e40a7274fbbf49d2acf1106236b710732b6b01ec732c4290df6f262a73b989b21f3e79093637423d6c956af497051acacfb61b73169975ead207fac61be7e1b89410f38392fbe639efe9c0ae4a817d3bb53994df71826e55696aea8dde32418d46215ed66dcf1ad4dd206e149573918e63fdd5e7017185e1fae415d17d0ac36c088f44778d52900812c606c8c65d889a5e280730e2ff0a62c2424922387199ccf61ea3f8e950eae428957f2a6bb6f94e31792a17ed550aa5b128a0ba393263931a2f9f556190704db80be47084996a67b3b9145810fa41f371203334496cc5fa6355cc75e37d271be63e290b1668ac5fc04a6c85db2d928473dae050e5d0478b40656acfcbb32223c1145decce504a639e837b0314730a1ce5670c21ebbc05423e357cf537e345c4109c805c086c51574cd3226261df76c4a4a39a137c8b087db775847b8684b3c20ac384ee4d4225a133d922e0f93a30d1dab2904640076f6b1952877021ff81ec9e94b0e2f6332082816d7c3097b99ea4c163368d6c0e3f8c1948331a497f0e049d679a1527ddde74350fa3a20df460308237e771db53670559375ad1d06833507f57fd63b05727d4e401ef39e13c471149984d98c7f31adf456a1e42e6c8c2a160596502c378d3064a4576e8bbe143996f49f344897194145f1fa60c62cf66df6a8e31157d598c35ad06e7a46408fe2f893a8deda14dfe7ebc56fc0c61368fada78fca4a764496c68976b9067066e678fd4eb3cf9e113a2a36cdfecc7ded22ae3b074b9b8c661e4d212fc6dd3ff8c46c9fab1b2d6eebdfdcede05c0543554a7948d33ead88a2b15c13707534db5fc93d7e9d14b1ce0a418e72898273d45bce6ae6d5c127ec5e8c5f4dddf61c8802e23b34065875862f58a8f8e455464265faba4e70b00c66bda42be441793416d9a0534d3c4c6f85e3eb551a9bd3c8b16437943b9c82d92d10097259afae8b5947a5f82d4b2f16f69405203ed3a0300740611fb0963d3585460260b65a97440a7c334b52e7e538d491be6962a23759e2e37e0e1fb18acece799d633c7b90706501f1784e37d6fb0ae8bbf22ab7bae51761f72e501746483d611ecd3d1d134646a267771b76d614a61d996384e10ee76d19bdead538a3ac820a4f52ede2324859f3","nonce":"0x4","to":null,"transactionIndex":"0x2","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xfbebb228bd4889062bb381b6985560c11673c93decfa7f7f0a92994443e52e46","s":"0x242b17a736b410de42f7f8883cdd68bda91e1fa0c56a2e49497db67f569f4916"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6462b263a2526b1b7b7ab7e13d4d6ab9f60b27fbb8de818fcb13a53b1c0476a6","input":"0x654bd6d64e3263453501652f5d7a6a9f467e021a48e0e2e63d740b7f4e030d0efd24fdf327b78a560bd159686f809555d15d7f3cce1cb5c233ad51eead13a143aecd01cd2848576ee548524b8903af4cb3821775142b0f844092b91738a8e662a8c9a6068bd839941a6e3576364d042af044db4f0cc60711b7aa9cc27c76e27ee6059c7809dcb918d279096edd4e4c74118213ba23f600dec5640ac5021a5b6d7949bd674cd05cd14799ab3f136854491d6e757d8d46c121ead807cac1af9a6d126ec8fd2e39e65bab737d564980a733e2650d0172668895485f0b355062bb37a27bfc5d044379e1fc9779b9d4987ec4c11c4a518be9d2e2becbe15b85e2781684377a9156d3cca334b67190a690ae5260237706bcbdecf9436a2c7ede7f125b1260600cc0384154380a6682b49ed2ecbb7968479553e8408b0a1e1011806ee4b49031b09b89b757ac450382f1453b4544944431629dfc957f07d86177d05403434747a7f98981a18b14929c1e04be6fa90705a08ac133e008326487e2b9afb334792946d3850e77fc5ba555cfe29c5473b2c70d567e139af63170de94611a056cacb0336a3d0912028af7773b047dd4b1b8bde125aba206f0f3b2f131ff1fc5288f1b6c08363500d2bf8bef47906fa7c93bc9e7054e6ff13ce45dd0bd420a774d4f35a1ff1e0b365e96e1b11eaf0b0cc051ef508db86a3135389e72bf4b76e7f5dffaaad9986ca679a47c7b6cd5641c0850421446306e8bb50c49c9e52572b32a8570b83ec336956ab1241aa5c4ec3fcf3d0c2f3a63c79c5a1a3507817400b545f6d3c816fbb03147f8919549bdac32a5081344025f54410602355235301a3d6d4c957cf68ee44c9fbd94df2ec34d6a2988d21e494254446fe655655995a22df0b87ee042745c41c23d8852a0a8848dda3201fe3eb275bc9b51d81ce4dbf4663890507939ca4d2742a0cd39b8f19fd9a320b0cd24623eb9352c1bcd9fbb80015a77ebe3560fa1f378146ae7c52c19b3acf75457c70b6d53e27a6e10749d40687ddbdfe68afc48baa17858406bd160cb79426e7151d3959df5114202727e83bc085148f16d7974f60afe2822ca2dab4701315b7638c4688673be125950aaf4ec2148bee12e591b94a63cc7907bd7b6130b6a2637be408f57ff64e809edb70d5843f95bf0e47268104b74e0a8d3c7a53f04d2740f6ad7275e929e088cba80e210917ef34d9a5f510b34789078d6c3b4505db8179c66790e7b493910d4e0d43c7e44825b848661416e556ad6a6142253354c2c9b4e28f3","nonce":"0x5","to":null,"transactionIndex":"0x3","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x1ce5515735ac68b86acc91f18344f8e74e73ed4071578ba31a8de536e4586c7a","s":"0x38e91803b82cd8b8654be58b313c349a940377f2633ca06a5104e4485db38c39"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x6a4df1dc08c2d3aa7e0314a41d90a23a245fde2d225fbf9300d6ff90e9d3f4e8","input":"0x5862cf54ee7b567d587def34aef4eca73807be997b77ee9e8f1aeee284eb4869dad9748fc6dc83bd45f3010e3470f1065cd024d3fc5eae65486893986b78a873372cbe103f6f8632afaccf48b78450d5882152f56d7746020a7ddd255786c2faa44d55dc8d3b11659104c565e6516392c5059da076caba4d6e39ec331759a47988a218d5ff1b757c7c5efa6d42150b7a24cd3de45a1dddf03aa9a62451855579bf538a455c436c2a134a2f9d27b3b8f61a6b6ce169b81cf86e1115b41534733b156f989635db9686b550aefd3c6704db994c9441681003e33ae52bd7587c367bfa5eaa8f9f3bad48515ac3bf2795155655471c054d6559624262ff6f6632a9fc7cfab1e4301c783b524fef241e898b2cee25ea286abd4c9fedff90096d9d2579404649439f82464aa1983e71a770c79b172f37aa1de2e806cc3f15f707a47ca5a62fc6af987c598da291fbef81e5bd90d14691156669df20eadcd96e0273e384d83e195bc105cd433f33bcbd23114a5ece605b5a6a5c6626b98c770803e5a4c93536165d6792c4b5830ad0d4aa5a1c5a1136651cde8a70bf7465217b4460fd8b107cfa9acab56dafa8c4cd4c79e2c5d49b7754ade6eff8884764055805f6271519036558c7b712d4733f719295b1bd2dcbdb070335cd6cd3a3896c59ad4577473ae9acb5eb4a2fdc5f6ac73f94538bfea0cfc801701d2959664e00f07239c530905d047b8c2e6f43cd6b914b00f4129b513062a41df190a4eaa3c2a7eb0d871a926d6651f3391a7f086ead4af9d8b18d801313644564be67a66c7132204bfe57f2bb8da1d712956336d027d516446b0709ab6192da86c9a42a42284a7209f5f9e69eadbf2321e0a38392a77ef8b5c187591704100302726f627c6c08711bd91c261085ebe91d926691c736655c165d8a8c2d3b7dff9c8c532484ab475b434d46152c3c85cf91e70e249a395ad7898839d507a15d5a343b7fb2fd69136c6b1b50eeab706ef825aec6115339134537bf890f6d9b96f27c15ee74d37db6a9f2dac4e0dcf1fc6c4915eb96d63c49eecd77038e6e1206bfb93e2d6f8c82ea9b0d0e4ae117e01aa48b5d553d921d668f4baa8c02d3241d40451570ac90617839f7125487525183d96502390c7787ebac9684e510057870d07cd0e6fd3ee2cb1be4ccfcbd2637343864cb3fc84fc847081b304a7d8cfabf507db1167cba84578f818f321cb9596267cbd5a14aadf5ab61f58b163f3f0a503df3","nonce":"0x6","to":null,"transactionIndex":"0x4","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x501e2d2bd15996cc0eb097306f4f76de2077865f934e459029caabd094c5e578","s":"0x408264ad8649ee95afd43f869be7de87b296b364010aeb18a755fae3dd0a3c49"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xc43c27001eac721ba1d80d27040175725d521d8c7ce5b4f23cc4984952ff6527","input":"0x3a6699e1e7330c28da6f04c0a5ea93bb08f398feb8bcf76b06c47d5cd56ac9b7a09d33778872698a54bcf759f6ec9dea796b71070ceeafb7fd551a7562dba64309a4f0dde67311c854aaf000402a5676d299704e9b47599993a34826f2258904f27ff5d466dc1bf50204c4550b61439b5b620285235b41321d6b4439fca574c375a580ff328e1470c9d189f5491caa3ce96be3328210f927b7336cf46ae82840ee30a127f352a7003b6e47e055070125ff825c42bfde60673b1a3b6e4d6e353fdb998b93fa27cf318ca37018423a0767efaab50662eab61945066c7af69cd44ce8771c51991a996458831a79da2537379d33715d8433659007805988f338ff6412d24a9839bc3a117c86946d3d173aefc5bea29a1859dddfc8e66b08cbab1adadbd45cfeaf6b5542193410926d12059b59bdf54ab4ffdd93f0b2e9800b5b3178dfed60169b04a17365238fdf683d34c3fb2229e770e53d3c6e603982635f435133686856b881186053a6143703135c606b654cb634b4541d6dfee6775dc8ea6ec79fd0fa5d0c724878e34ea1b41bbf781e0907cb7222fd76a4ef1aaedf38b3e9bf7f0942636f920d823043488039385a6f2f01b71bef7f04713058ff70a8ca081c130b8032a368517893b5ab0dc908025b46927f6e8e97bc65e2a6f57bcc0ad8996dd29370da8d7748d50f65a0205df5cba0a2265f307eeea4108c370dfc8b8ba96f3303903933d6cd77221b735a238387bf09a0cb6c1b1832315f788f476a8a5c466423f9868486e88366b60bb331f3920418450f71d9c53bf2a6ce0f8651ccd6837242a438a2a56756e3e86bd181eaea14584608544a7481a83b687c2c2700e6225f57e5c76025da7bc0af2f1554682d3704e733b4a850a87b3af2ca511a0142bb1e09e7e36bb09244def2903aa07ba979735ea71e54051147363b3372bd5007b5b30fc60812d7dcb82f9b729a845875614947927565b8a58d8dcd807e8cc4063d8253728b6385fe15f98e3d34476c692f2d92a0d0f0efeedf0300d046197ad59f80110eb2e8efd3e79c4c8f91766544cfcfbcaaba1c7e7015677c89a9f3393a5072eac9a75380a14044404f5b989b1f397a20564d498147334461ab94f3","nonce":"0x7","to":null,"transactionIndex":"0x5","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xb2c37bb632e39954fbd9f339eb90e3fdd36d7714b7fdd9764a732a1fcb9213bb","s":"0x41e04a31f1b06c053d5d73daeab720564f10b1aef334293322646b358705019e"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd802558258227491da149469648c395dfd9e566d8baadbc0edee4b8a9350dcf7","input":"0x723f63030479b6750c82e768bc239a909d3cea3c5c5c40324507135a0b6d6c6671d356274c8b1fbc2a9d8ff1105a3a6036014320451562fadd213574af6d470e2141e029822e894cc777408dd90ea2a63c1d64701441ae7a916f6e0d10fd3c5a901dd08836d6c08bf71047421b44848680957a28bde7c3fef2d62d99d42079a6a200782ee8df64fe64b3ae835030a369116b0456291187341a7968c6eccfc186e478f3d15a7c52a9e8ecc880118b8e123e4a6dc78dc5897fc7faef850356eee2d7c58e8296404aa26495b08d9bd736920b1c058302a10260bc35553b6fe23560c77257896c3218c53d309217e7779fbe08d2200d896e7cf5264a73ee1ab68b392ef126446bc71a04609973f34ab88c15fbc3197da98d98a095e00f84faa9ae43455b0172b4beb4c32744615f2c7da670f1b7db0a9d5d6911611c3374e65622841c856f03909916f1e17cb4aaff4ae6e19c1a190212095468f4bb6e1fa915ea16c55f61fa08526e5ca93058aea7015c4f8dc1cc0a24aa3162e48d5e767d9fdf4138dfededa980cf45a0404b086fc56ad9e3affd50580317676730bb2d4e27676b1d6fb6cf2e65e73973859b58496c7f5257ec6eb7b88cb247e7b5b5a2cd7d85445831365f73ff856798e47349fffb0b92537d5b2f6396f0da0a60ea721cc98fb04ef8a5a171cdee4123bc01a9f16b5d8492075064dbfc9527bd451d503375f92f94e36303ed18b1d858a1d72c17191b3bab68eaad66f5083b769a9b7b710b5b8a9a1b2c0068550295cb2e165e678477807eea233c8e451b0dee921962b0a7b94a872a40b1181461b1157683d96e898c34505f627c5d6e1c134520476443f229209e59751142b0f45bfbc25aa225a0d0ec8acdd32c453118ed273d45556ef846b9418fd2e93d48b0411a64b362136efe3f4abb98ce57f08ff2085dbf46aa5f143d792f5b1b34162426557265bf21ca655ea91489da715049f2fbb11ca06875fb2b7655c86816fd65b83c4a33df561032303d7773976d1aef53f882f2e157848d5c9340d46de54b15fff6abf3","nonce":"0x8","to":null,"transactionIndex":"0x6","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306c","r":"0x4d924fb5f571bce21868b25f94690c57d8fae822964dceb841f56b2228c3d1a2","s":"0x1f5bb6a84fe40b6cd56d5f4f99bafe472c7cebecd996ef0e0d3c78add601e7ef"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0xd78ed182d5b55254d6584a6f8baf2ff6a7c5ffd5f2c23d3d6b2b00c9b5e7fc07","input":"0x586719e3b335e5a05892455e79e08ce21a9afc02c83e5f768eae9fa00b39a158dd7091c4fa7a6b35364580046435b81b90097f197715cc6892806d41402f9e348f92a4bdd6baea99150349cbea59a2bb9635041154403011536d27ba3a210f1e39251f45b399acae38527bd52d2f458979698118a508d3dd9be2462db4bea525dd26e4d6a6b344757654b0fa84a1048dbb6441ced8bb6efe98493a4022ef0738330750415c04648b8df72298357dfd3d2006b16651c845c06c60a7f0990bdb7aa4cf31a6ae4a4ecbc6b52af04071988cbe72b7c034722389090b53e8facaaf5b79269b6dd4754f1109d9056dd94e2e58f1d4471385c5438cb11216063a9058657fb92e3fd5ff5a7f3e8f0db7c708432c4a9d73a5819af8c164f48ed2609154d895f9e2d463aea10561c8e36d3c0a55ff3302037a017ddeb547d66b945269d12a839b755b8af2ce491d367f1791e601faf06b7a85c1231a27e400a1899c7f49c99e2cf9bff0fa37496f67c65f801a3433347d93b23dd1dcdef91dee790a97e04fee26205bb52bddc2777a82edf2d4b8c58b5f55321166cc5704776063c54302318d383b448f90175f1c0535551a04841106525d74eea2d5f0460832323b3bbf10f62d22d5ba89e2f437437a506f09f7d5f64a5e751cf8e38a5469637d24c9443b88f8af3eaa867654dec790a4105c52f1df1a54511d78b55f439962bffa3041316e3f30c11a100b50278048fa7a7db73838350973e69ce694bca794ecb0c50887f8e7eccad276a086466c29b25d02248a064689199a56ea418580903d70a019acf7013b8c71acca923dfa062494185f63425b9c3f786b59228e4a4da2264f9381532a9934048e28fea3569d2f77ad61628a3f8d316a3c3fb639dc8ce4c740dad66e16048127d881c9f1ad2702f5ea96ca09107a787c6dc491941a810e9aa8f76e77efbfef3dc3b5ea37dac094332f07089250170768625554d6092aa82d744317625ad6fc495364a7c09b2ac53b74b35423a81c4baa75b35e3ee5d33822b6f152201e0a5c7c4f517f47cb1ba9e18c879dd88dea8fa53ee541d2163ab4fede017323f53105151c793f6c302f14785d053d591ee0d2d6e706c2fdb9cee826072f4cf1546e1ea8cc798345123cbe00af96ce94ac4a11765a6449ed7e0edf81c888c9bff074ac439bf598dbfe7fad83661b70142cb03b2164171718c5c739087019b6dc1960dd0cd875db87b3fd1707210379ed6df649fcc52b7ef38093b57105b6dc5960adde984da092cc0c7f99e9f4867471c5d770b67f3189213ddeca75170bb947fa6b68fc9cd8480f213a7774b20cd25d83ab90b3eb4465dc0e88e5c33a659239dbe97d3b712498bd66007b07593b93dd6cc2f2e014df307c9d477d6b368b004b2ac553f5c73e1a70bbf4c9061eafbc64bb339932783a446f2817e422c934754dbb654891dbea919e325a94035afd","nonce":"0x9","to":null,"transactionIndex":"0x7","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x6109e0c44e8f86754478f78ee90f0c3a8d249605655330407342c534bb8fda77","s":"0x3d1cc3c94d2d1b5ec319385ae1dee73c42b87a88800e9484e8ff91d62ebb1940"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x49b652060da03857f56659b1ac638fd132c6b80c7935e655430946c3493b8539","input":"0x7f17bd908166a67abe337de1b827fcc93e6b66bf994e2b9d80c4115880a8d6f0196f2809a0a7e8dbe569eb3f2ff48ac22951762de9b5aaef79ae2385b8da667a578501bbdbb78c42baf0335072f9c5b5cfd1774b78a180169e0a7efde997a52b31054a34440758480569e84779c4a9af1ce56e6f951010423fa1335c314a18774889b6b7f9eb3e198b15478d0c71a8e04d30070b312cd20f76b67c6f65309b0f1d0b77e407cc1d619b538fb7295788bd82100a492033183a7ba7f27908709cefcdece11f88a3c0ad85a3570bbc2591473f302ded85161d493462a2a668020761482e0366f502a93e08d516407b174d49e88f0558de52f828d15ae2a3af2cf0152e4c522cf8992350ca33457725e519df12dc87e0f0b5f8492a616da359baca2bf5091f7c4158461a6b74da6b9d63588b5a6e91e88015700730acdb62d1a948ec56a20bfa860099ae33180a5b4a473877ee13ea235ef70e7300c0a33c9cd3bb41854181774c952e4b93050b6dae8c3eec863075b74076e3904b297f202e328d9e774a935dc1e889c52d97e9904a2dfe890a420461a8f59be3eb2c2c3664f9941b919d5b357f6a47efea60ce84e43f7cff2e016340b2f7320799342da6cbe1b4d7a0f868747e6968ba423780ffb352ec23450a316f250100000000000000000000000000005780171d446e9474fbe92d88273f6f67a31e230a0743511a5c6914c61ef7031bc01321cc05437d810e73a7ef059f110ad8ff161313c4caf5c127033c11b8325715fde7d02b0467c271ba9f257852265e65ce6500d3c0cd3802356edd2f556fc26828cc3f0f364fc94aac491933746886084b89f565be10da4034d54a799ad85d649e09115f6bb061a180be0c83f510062ebd0a5f6d52eee67c06aad2e6e656ad2893a31736330477fe44808094d224ac4569193847ce947eab31145de843d1c115461b1b093347688bc316e54fdfad0dc702477e96b1087a022ae5d329a2c119e4eb3ccd65f0828f4f76382c4a500db9f714bf7e6dba39332866eaf69a0d71522a0f2a8766da60f9f8a4186fd54f34021c562e1778d865f76016c699f1370c8a9acb9654ef137bf146467de8cf50717fd4b7f2c5cb67680f5401cfe4f679bb26d3551814663a2232a3fbd5ee7af0f80df5741e1801c17c93557b2ddcf0da8024cc37c6e745c540066a3f80270928913ffaf223b74a0663625d012d5c654d3d0cabd12c6e4ce68f301251cdb75e93a5c4d73147356743dd7abc434dbfb25b601b5b935b5960147dfb22ad4a7efef3173066d59e8f4604e4c7caae5ef510787adb5f8a1fd1a8168479f19a76bdbcd60c12d1162871225f5b5479551e42f002039c454c47928a7bb525fbc374b6c7a19f3d0f344fb6077dea6d4cb6690cb9356b7ccaa95074ad46519fd18ad0b35a90e21c0c00b19bc581f98f9792423a6ec6e6078d6ea0a3ccd43f366305b685453f4106937ed56b85922c350ba46a747ca7666a11fda7c0a11abe269a097257f0181d212d685b7dd5dc2697fcd88908684dcf09f6e286dacfbb0a01629b432a905c7b0b4d46f35c6a274301fcfa70e0c371eb931f53682111565f5d7b9b3184785a1554a1ee1df94b52d9ecad8bbd118b52a1b8993462f366c54a78963084fa0506cb7ca18ec6675c6fadb89bd7e15f006c229b60176b0b78d5317562c7dc4363761f5940436d321acae8a4ecee4574a56810ee1b5c3e1602023a1c633fa66ec2721272d0ea4fac46693e75bc5db0a9b46e0457a3916c5e98d0b91798c5a137dbe92508365193011b5569004fe9a0ef75d73e226068fe826ed2eb9628aa8d00","nonce":"0xa","to":null,"transactionIndex":"0x8","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0x3684ae7dfbbe8f075a746bf35c18f4d356f0fe3f8b36150d1d394b744b0d64f8","s":"0x65ab2592621c1f84e80f032b57827e9c4a462c91a253bf962d82ad5058acddbf"},{"blockHash":"0x31d9b0b498384b9df66ce8618d5e9ae16bb21f42df5d0501ca774012bf9dc1a3","blockNumber":"0x4","from":"0x8943545177806ed17b9f23f0a21ee5948ecaa776","gas":"0x3d090","gasPrice":"0x4fdc64a6","hash":"0x42d9a64ff889d6d809b0e0b8d2147380e69f07cc931bba7e5e956857a1f24a74","input":"0x3265be11bbdc2d0b62ed551c706a553c383a8376660605baed8d32e89be71912303d74f4a4aebf9563da189c9d329203ab1efe050eba2e1e6f4244e790e2bcef634ae7f82335cca4f035393202443735406d03651a7f23d8d15684607dfb5123703c15bdcf73c4b074ef8c1a2ae5d5630b297f02bf0839297fbdad3532ad6aced6ea91839045adbbaa995ac81ec175387683366d6865aeab5a1cae244a00b3672c8955140862a1ce9d63d2d4b3461671e3a7851fb5d8686faddef58d5204155361e2036bda45f7f808b4841cdf8a98927c850c1247852ff810df7c43735ec6ab45b25afd59a02953f5b04a1f852b5f7c874d390f0e28dc172477b4f9f4bc83d5ceade87719320fb398edbeffef3077f4cc1f2eb7309e14c2bee019b27833be93bf239dcbc861bf63d793bdef9674e0534fe6c558d896684ad7f6beba5d06074a6f6b0e757caf524e155fb43a53b895362ebb62efc0f390459790043f0335055b6ebc37afc27971790bdece822fd327843b0a74ec5e4a862fbbb7cca3c2c944a8ced4a6ff3c9b0312046c18822181cc59e16c88411baeac483414055374a6aba799aa8fa3925b04e2b3f0c0fcb0adb54bb9a97fb91b8540d072b82bf4450c71f602658bdbce963867a0233f5c763309cfa75a16650f03971c2d76497130d77ce731ae1cf3640c98892877bcb452ba31151d3b534a78ea60f5944cbb9223dff39982e2fca1580456587fec201f5f941d720225db2020ba4bc85af4fa135d4101b75eb628540a4075438f328ac4cd2263f17e6f9a71e7418c9e5f29f4418f413158080340077ca7efae6a77bb3e1b9e043ad62ea8ea47ca77df6c3b66112112bd6de16c7c7327c1efd8a0a400603f132f1e3021961c53a175b06a9ad504cf2dff6b82040b1d7c2522c08e24264811b48edecdeadc59cbfd7885c2884be1b00f2d3edcb214364a4a3660de7f75ccff410aec97a28d677e9d7cc1b1eb20f3d838a2f67eca0ad2c18f83705f0e7d864b976671612a69efc46169ba23a4ff4cc8929ceca71bd8b008b9a421fc467ff0adf3e8b4d7b712cc5a9096c5d0a05966bf5dfe0e4e42677c101f38a5ad595672b931c919cfcef0f2b9099bf013277af422896c7d574b7801902980f2e7b52fadd7dcb1e5f77f7d7316b6ba74e2395e005cf61b7579d89758aa392d8470c851ed8dc04dc3ca16b3c6e61d54361a095c4375add08f41772325037e8a48423fc75b0dfd8d4e23f00615650a12f8bac5536b23ef30f5ef21d419dfed66a71408465f6c02e408709d1c841cb5c624fafe4732436bf42069bf1e2a16ef9282fe6347106426df7c1c3f7bd766d0ecdba3618232f2a8895cf36867744bb20d26f2b658743a0b5d69f6f327d9ad6a212bc64067776f381dd4579a3061332b36453d3345708c70ddf50a8ebca1e08d183f03b084b1f662bb6608401c7c1f2d3d34c8330460ac9ce148b04c8b4b9d0e6ad5308c3bb29f9c3f4ffafd","nonce":"0xb","to":null,"transactionIndex":"0x9","value":"0x0","type":"0x0","chainId":"0x301824","v":"0x60306b","r":"0xa5cc300b87b70f6995f9f58f62766e4c941cf89a8899b2e35d5f717f23340dce","s":"0x62defb73ce79415784dfc9ee655aeff22ab9262b4dd4ee76f97f8e0fcd5ae23c"}],"transactionsRoot":"0x72a1709a55d218d846226d7fe3db24c83ef6ce88f130625731a6a28d8ae1147d","uncles":[],"withdrawals":[],"withdrawalsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"}] From 2a6d843c310a2426a7d4852516594f9776ef33e0 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 18:17:01 +0100 Subject: [PATCH 09/56] Revert "refactor: trace_decoder tests do not expect json array in files" This reverts commit 0407031bfca63c182f3cfd6844d4e767703811ee. --- trace_decoder/tests/trace_decoder_tests.rs | 76 ++++++++++++---------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/trace_decoder/tests/trace_decoder_tests.rs b/trace_decoder/tests/trace_decoder_tests.rs index f77e7a901..6db98749f 100644 --- a/trace_decoder/tests/trace_decoder_tests.rs +++ b/trace_decoder/tests/trace_decoder_tests.rs @@ -53,7 +53,7 @@ fn find_witness_data_files(dir: &str) -> anyhow::Result> { .context(format!("Failed to find witness files in dir {dir}")) } -fn read_witness_file(file_path: &Path) -> anyhow::Result { +fn read_witness_file(file_path: &Path) -> anyhow::Result> { let witness = fs::File::open(file_path).context("Unable to read file")?; let mut reader = std::io::BufReader::new(witness); let jd = &mut serde_json::Deserializer::from_reader(&mut reader); @@ -183,35 +183,38 @@ fn test_parsing_decoding_proving(#[case] test_witness_directory: &str) { read_witness_file(&file_path) } }) - .map_ok(|block_prover_input| { - // Run trace decoder, create list of generation inputs - let block_generation_inputs = - decode_generation_inputs(block_prover_input, use_burn_addr)?; - block_generation_inputs - .into_par_iter() - .map(|generation_inputs| { - // For every generation input, simulate execution. - // Execution will be simulated in parallel. - // If system runs out of memory, limit the rayon - // with setting env variable RAYON_NUM_THREADS=. - let timing = TimingTree::new( - &format!( - "simulate zkEVM CPU for block {}, txns {:?}..{:?}.", - generation_inputs.block_metadata.block_number, - generation_inputs.txn_number_before, - generation_inputs.txn_number_before - + generation_inputs.signed_txns.len() - ), - log::Level::Info, - ); - simulate_execution_all_segments::(generation_inputs, 19)?; - timing.filter(Duration::from_millis(100)).print(); - Ok::<(), anyhow::Error>(()) - }) - .collect::, anyhow::Error>>() + .map_ok(|block_prover_inputs| { + block_prover_inputs.into_iter().map(|block_prover_input| { + // Run trace decoder, create list of generation inputs + let block_generation_inputs = + decode_generation_inputs(block_prover_input, use_burn_addr)?; + block_generation_inputs + .into_par_iter() + .map(|generation_inputs| { + // For every generation input, simulate execution. + // Execution will be simulated in parallel. + // If system runs out of memory, limit the rayon + // with setting env variable RAYON_NUM_THREADS=. + let timing = TimingTree::new( + &format!( + "simulate zkEVM CPU for block {}, txns {:?}..{:?}.", + generation_inputs.block_metadata.block_number, + generation_inputs.txn_number_before, + generation_inputs.txn_number_before + + generation_inputs.signed_txns.len() + ), + log::Level::Info, + ); + simulate_execution_all_segments::(generation_inputs, 19)?; + timing.filter(Duration::from_millis(100)).print(); + Ok::<(), anyhow::Error>(()) + }) + .collect::, anyhow::Error>>() + }) }) .flatten_ok() - .collect::>>(); + .map(|it| it?) + .collect::>>(); results.iter().for_each(|it| { if let Err(e) = it { @@ -246,16 +249,19 @@ fn test_generation_inputs_consistency(#[case] test_witness_directory: &str) { header_file_path.display() ))?; let mut header_reader = std::io::BufReader::new(header_file); - let hdr = - serde_json::from_reader::<_, Header>(&mut header_reader).context(format!( - "Failed to deserialize header json file {}", - header_file_path.display() - ))?; + let block_headers = serde_json::from_reader::<_, Vec
>(&mut header_reader) + .context(format!( + "Failed to deserialize header json file {}", + header_file_path.display() + ))?; // Read one json witness file and get list of BlockProverInputs - let bpi = read_witness_file(&file_path)?; - Ok((hdr, bpi)) + let block_prover_inputs = read_witness_file(&file_path)?; + Ok(block_headers + .into_iter() + .zip(block_prover_inputs.into_iter())) } }) + .flatten_ok() .map_ok(|(block_header, block_prover_input)| { let other_block_data = block_prover_input.other_data.clone(); // Run trace decoder, create generation inputs for this block From 322def012d1d1bb9d602e8895b1ffa6acd19ebcf Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 18:26:59 +0100 Subject: [PATCH 10/56] refactor: dump accept multi --- trace_decoder/examples/dump.rs | 62 +++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 13 deletions(-) diff --git a/trace_decoder/examples/dump.rs b/trace_decoder/examples/dump.rs index 5238a45a0..2e517e2e3 100644 --- a/trace_decoder/examples/dump.rs +++ b/trace_decoder/examples/dump.rs @@ -1,5 +1,8 @@ use std::io; +use anyhow::Context; +use itertools::Itertools; + #[derive(clap::Parser)] struct Args { #[arg(long)] @@ -26,27 +29,60 @@ fn main() -> anyhow::Result<()> { pretty, } = clap::Parser::parse(); - let prover::BlockProverInput { - block_trace, - other_data, - } = serde_path_to_error::deserialize(&mut serde_json::Deserializer::from_reader(io::stdin()))?; - - let gis = (match method { - Method::Old => trace_decoder::entrypoint_old as fn(_, _, _, _) -> anyhow::Result>, + let entrypoint = match method { + Method::Old => trace_decoder::entrypoint_old as fn(_, _, _, _) -> anyhow::Result<_>, Method::New => trace_decoder::entrypoint_new as _, - })(block_trace, other_data, batch_size, use_burn_addr)? - .into_iter() - .map(repr::GenerationInputs::from) - .collect::>(); + }; - (match pretty { + let out = Input::into_iter(serde_path_to_error::deserialize( + &mut serde_json::Deserializer::from_reader(io::stdin()), + )?) + .enumerate() + .map( + |( + ix, + prover::BlockProverInput { + block_trace, + other_data, + }, + )| { + entrypoint(block_trace, other_data, batch_size, use_burn_addr) + .context(format!("couldn't prove input at {ix}")) + }, + ) + .map_ok(|it| { + Vec::into_iter(it) + .map(repr::GenerationInputs::from) + .collect::>() + }) + .collect::, _>>()?; + + let printer = match pretty { true => serde_json::to_writer_pretty as fn(_, _) -> _, false => serde_json::to_writer as _, - })(io::stdout(), &gis)?; + }; + + printer(io::stdout(), &out)?; Ok(()) } +#[derive(serde::Deserialize)] +#[serde(untagged)] +enum Input { + One(T), + Many(Vec), +} + +impl Input { + fn into_iter(self) -> impl Iterator { + match self { + Input::One(it) => vec![it].into_iter(), + Input::Many(it) => it.into_iter(), + } + } +} + mod repr { use std::{collections::BTreeMap, fmt, iter}; From fd2e90d919da5779ddb4b561b6bcb04a8644da6d Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 2 Sep 2024 21:27:17 +0100 Subject: [PATCH 11/56] add --quiet --- trace_decoder/examples/dump.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/trace_decoder/examples/dump.rs b/trace_decoder/examples/dump.rs index 2e517e2e3..dfa416585 100644 --- a/trace_decoder/examples/dump.rs +++ b/trace_decoder/examples/dump.rs @@ -13,6 +13,8 @@ struct Args { use_burn_addr: bool, #[arg(long)] pretty: bool, + #[arg(long)] + quiet: bool, } #[derive(clap::ValueEnum, Clone)] @@ -27,6 +29,7 @@ fn main() -> anyhow::Result<()> { batch_size, use_burn_addr, pretty, + quiet, } = clap::Parser::parse(); let entrypoint = match method { @@ -57,12 +60,14 @@ fn main() -> anyhow::Result<()> { }) .collect::, _>>()?; - let printer = match pretty { - true => serde_json::to_writer_pretty as fn(_, _) -> _, - false => serde_json::to_writer as _, - }; + if !quiet { + let printer = match pretty { + true => serde_json::to_writer_pretty as fn(_, _) -> _, + false => serde_json::to_writer as _, + }; - printer(io::stdout(), &out)?; + printer(io::stdout(), &out)?; + } Ok(()) } From 81907a9f97aa8a875f47887501191b28eb623612 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 3 Sep 2024 16:57:46 +0100 Subject: [PATCH 12/56] fix: remove unaccessed storage tries --- trace_decoder/src/imp.rs | 6 ++++++ trace_decoder/src/processed_block_trace.rs | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index def975931..8ee5e6f5a 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -456,6 +456,12 @@ fn middle( .transaction .trim_to(batch_first_txn_ix..curr_txn_ix)?; + let keep = storage_masks + .keys() + .map(keccak_hash::keccak) + .collect::>(); + before.storage.retain(|haddr, _| keep.contains(haddr)); + for (addr, mask) in storage_masks { if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { it.trim_to(mask)? diff --git a/trace_decoder/src/processed_block_trace.rs b/trace_decoder/src/processed_block_trace.rs index 7be1fb297..8027acb60 100644 --- a/trace_decoder/src/processed_block_trace.rs +++ b/trace_decoder/src/processed_block_trace.rs @@ -48,9 +48,11 @@ pub(crate) struct Hash2Code { impl Hash2Code { pub fn new() -> Self { - Self { + let mut this = Self { inner: HashMap::new(), - } + }; + this.insert(vec![]); + this } pub fn get(&mut self, hash: H256) -> anyhow::Result> { match self.inner.get(&hash) { From e05f3d0d3320fb3a2beb520a161a0e3db7ebcd16 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 3 Sep 2024 16:58:48 +0100 Subject: [PATCH 13/56] test: ab --- Cargo.lock | 23 ++ trace_decoder/Cargo.toml | 1 + trace_decoder/tests/ab.rs | 507 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 531 insertions(+) create mode 100644 trace_decoder/tests/ab.rs diff --git a/Cargo.lock b/Cargo.lock index 735d491d2..1d206ace7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1747,6 +1747,12 @@ dependencies = [ "cipher", ] +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.9.0" @@ -3721,6 +3727,16 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "pretty_env_logger" version = "0.5.0" @@ -5125,6 +5141,7 @@ dependencies = [ "nunny", "plonky2", "plonky2_maybe_rayon 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "pretty_assertions", "pretty_env_logger", "prover", "rlp", @@ -5788,6 +5805,12 @@ dependencies = [ "time", ] +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + [[package]] name = "zero_bin_common" version = "0.1.0" diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index e78a98150..56d38ac9b 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -46,6 +46,7 @@ alloy = { workspace = true } clap.workspace = true criterion = { workspace = true } plonky2_maybe_rayon = { workspace = true } +pretty_assertions = "1.4.0" pretty_env_logger = { workspace = true } prover = { workspace = true } rstest = "0.21.0" diff --git a/trace_decoder/tests/ab.rs b/trace_decoder/tests/ab.rs new file mode 100644 index 000000000..cc2b99acc --- /dev/null +++ b/trace_decoder/tests/ab.rs @@ -0,0 +1,507 @@ +use std::collections::{BTreeMap, BTreeSet, HashMap}; + +use alloy::{ + consensus::{Account, Eip658Value, Receipt, ReceiptWithBloom}, + primitives::{address, b256, Address, Bloom, FixedBytes, Log, B256}, +}; +use alloy_compat::Compat as _; +use evm_arithmetization::proof::{BlockHashes, BlockMetadata}; +use keccak_hash::H256; +use key::TrieKey; +use mpt_trie::{ + nibbles::Nibbles, + partial_trie::{HashedPartialTrie, PartialTrie as _}, +}; +use trace_decoder::{ + BlockLevelData, BlockTrace, BlockTraceTriePreImages, OtherBlockData, + SeparateStorageTriesPreImage, SeparateTriePreImage, SeparateTriePreImages, TxnInfo, TxnMeta, + TxnTrace, +}; + +const ALICE: Address = address!("00000000000000000000000000000000000a11ce"); +const BOB: Address = address!("0000000000000000000000000000000000000b0b"); +const CHARLIE: Address = address!("000000000000000000000000000000000c44271e"); +const BEACON: Address = address!("000f3df6d732807ef1319fb7b8bb8522d0beac02"); + +#[test] +fn character_hashes() { + t( + ALICE, + b256!("98934450b0a9aefe4c16aba331967de160f1b92f655dbf45675997ac0ef2bcf3"), + ); + t( + BOB, + b256!("3034df95d8f0ea7db7ab950e22fc977fa82ae80174df73ee1c75c24246b96df3"), + ); + t( + CHARLIE, + b256!("82c4b3e30ae93f236e06c03afe07f4c69f1aa9d4bac5bb3f4731810828003f97"), + ); + t( + BEACON, + b256!("37d65eaa92c6bc4c13a5ec45527f0c18ea8932588728769ec7aecfe6d9f32e42"), + ); + + #[track_caller] + fn t(address: Address, expected: B256) { + assert_eq!(keccak_hash::keccak(address).compat(), expected) + } +} + +#[test] +fn empty2() { + do_test( + [(BEACON, acct()), (ALICE, acct())], + [], + [(BEACON, hpt())], + [], + [ + txn([], [], rcpt(true, 0, []), 0), + txn([], [], rcpt(true, 0, []), 0), + ], + obd(), + ) +} +#[test] +fn pad1() { + do_test( + [(BEACON, acct()), (ALICE, acct())], + [], + [(BEACON, hpt())], + [], + [txn([], [], rcpt(true, 0, []), 0)], + obd(), + ) +} + +#[test] +#[ignore] +fn pad2() { + do_test([(BEACON, acct())], [], [(BEACON, hpt())], [], [], obd()); +} + +fn rcpt(success: bool, gas: u128, logs: impl Into>) -> ReceiptWithBloom { + ReceiptWithBloom { + receipt: Receipt { + status: Eip658Value::Eip658(success), + cumulative_gas_used: gas, + logs: logs.into(), + }, + logs_bloom: Bloom(FixedBytes::default()), + } +} + +fn txn( + traces: impl Into>, + byte_code: impl Into>, + receipt: impl Into, + gas: u64, +) -> TxnInfo { + TxnInfo { + traces: traces + .into() + .into_iter() + .map(|(k, v)| (k.compat(), v)) + .collect(), + meta: TxnMeta { + byte_code: byte_code.into(), + new_receipt_trie_node_byte: alloy::rlp::encode(receipt.into()), + gas_used: gas, + }, + } +} + +fn hpt() -> HashedPartialTrie { + HashedPartialTrie::default() +} + +fn obd() -> OtherBlockData { + OtherBlockData { + b_data: BlockLevelData { + b_meta: BlockMetadata::default(), + b_hashes: BlockHashes { + prev_hashes: Vec::::default(), + cur_hash: H256::default(), + }, + withdrawals: Vec::<(ethereum_types::Address, ethereum_types::U256)>::default(), + }, + checkpoint_state_trie_root: H256::default(), + } +} + +fn acct() -> Account { + Account { + storage_root: HashedPartialTrie::default().hash().compat(), + ..Default::default() + } +} + +fn do_test( + state: impl Into>, + deferred_state: impl Into>, + storage: impl Into>, + code_db: impl Into>>, + txn_info: impl Into>, + obd: impl Into, +) { + let obd = obd.into(); + let bt = BlockTrace { + trie_pre_images: BlockTraceTriePreImages::Separate(SeparateTriePreImages { + state: SeparateTriePreImage::Direct({ + let mut hpt = HashedPartialTrie::default(); + for (k, v) in state.into() { + hpt.insert( + Nibbles::from_h256_be(keccak_hash::keccak(k)), + alloy::rlp::encode(v), + ) + .unwrap() + } + for (k, h) in deferred_state.into() { + hpt.insert(k.into_nibbles(), h.compat()).unwrap() + } + hpt + }), + storage: SeparateStorageTriesPreImage::MultipleTries( + storage + .into() + .into_iter() + .map(|(k, v)| (keccak_hash::keccak(k), SeparateTriePreImage::Direct(v))) + .collect(), + ), + }), + code_db: code_db.into(), + txn_info: txn_info.into(), + }; + + eprintln!("generate reference..."); + let mut reference = trace_decoder::entrypoint_old(bt.clone(), obd.clone(), 1, false) + .expect("couldn't generate reference"); + eprintln!("generate subject..."); + let subject = + trace_decoder::entrypoint_new(bt, obd, 1, false).expect("couldn't generate subject"); + + for gi in &mut reference { + gi.contract_code.insert(keccak_hash::keccak([]), vec![]); + } + + pretty_assertions::assert_str_eq!( + str_repr(reference), + str_repr(subject), + "reference (left) != (right) subject" + ); + + #[track_caller] + fn str_repr(src: Vec) -> String { + serde_json::to_string_pretty( + &src.into_iter() + .map(repr::GenerationInputs::from) + .collect::>(), + ) + .expect("unable to serialize") + } +} + +mod key { + use copyvec::CopyVec; + use u4::U4; + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] + pub struct TrieKey(CopyVec); + + impl TrieKey { + pub const fn new() -> Self { + Self(CopyVec::new()) + } + pub fn into_nibbles(self) -> mpt_trie::nibbles::Nibbles { + let mut theirs = mpt_trie::nibbles::Nibbles::new(); + let Self(ours) = self; + for nibble in ours { + theirs.push_nibble_back(nibble as _) + } + theirs + } + } + + impl std::str::FromStr for TrieKey { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let mut nibbles = CopyVec::new(); + for char in s.chars() { + nibbles.try_push(U4::from_str_radix(char.encode_utf8(&mut [0; 4]), 16)?)? + } + Ok(Self(nibbles)) + } + } + + const fn assert_trie_key(s: &str) { + let is_hex = alloy::hex::const_check_raw(s.as_bytes()); + assert!(is_hex, "string must be hex characters only"); + assert!(s.len() <= 64, "too many characters in string"); + } + + macro_rules! key { + () => { + TrieKey::new() + }; + ($lit:literal) => {{ + const { assert_trie_key($lit) }; + $lit.parse::().unwrap() + }}; + } + pub(crate) use key; +} + +mod repr { + use std::{collections::BTreeMap, fmt, iter}; + + use ::hex::ToHex as _; + use ethereum_types::{Address, U256}; + use evm_arithmetization::{ + generation::TrieInputs, + proof::{BlockHashes, BlockMetadata, TrieRoots}, + }; + use keccak_hash::H256; + use mpt_trie::{ + nibbles::Nibbles, + partial_trie::{HashedPartialTrie, Node}, + }; + use serde::{Serialize, Serializer}; + use stackstack::Stack; + use u4::U4; + + #[derive(Serialize, PartialEq)] + pub struct GenerationInputs { + #[serde(skip_serializing_if = "is_default")] + txn_number: U256, + #[serde(skip_serializing_if = "is_default")] + gas_before: U256, + #[serde(skip_serializing_if = "is_default")] + gas_after: U256, + #[serde(with = "hex::slice", skip_serializing_if = "is_default")] + txns: Vec>, + #[serde(skip_serializing_if = "is_default")] + withdrawals: Vec<(Address, U256)>, + #[serde(skip_serializing_if = "is_default")] + exit_roots: Vec<(U256, H256)>, + + #[serde(skip_serializing_if = "is_default")] + state: Mpt, + #[serde(skip_serializing_if = "is_default")] + transaction: Mpt, + #[serde(skip_serializing_if = "is_default")] + receipts: Mpt, + #[serde(skip_serializing_if = "is_default")] + storage: BTreeMap, + + #[serde(skip_serializing_if = "is_default")] + checkpoint_root: H256, + state_root: H256, + transaction_root: H256, + receipt_root: H256, + + #[serde(with = "hex::btree_map", skip_serializing_if = "is_default")] + contract_code: BTreeMap>, + #[serde(skip_serializing_if = "is_default")] + meta: BlockMetadata, + #[serde(skip_serializing_if = "hashes_is_empty")] + hashes: BlockHashes, + + #[serde(skip_serializing_if = "Option::is_none")] + burn_addr: Option
, + } + + fn is_default(it: &T) -> bool { + *it == T::default() + } + fn hashes_is_empty(it: &BlockHashes) -> bool { + *it == BlockHashes { + prev_hashes: vec![], + cur_hash: H256::zero(), + } + } + + impl From for GenerationInputs { + fn from(value: evm_arithmetization::generation::GenerationInputs) -> Self { + let evm_arithmetization::generation::GenerationInputs { + txn_number_before, + gas_used_before, + gas_used_after, + signed_txns, + withdrawals, + global_exit_roots, + tries: + TrieInputs { + state_trie, + transactions_trie, + receipts_trie, + storage_tries, + }, + trie_roots_after: + TrieRoots { + state_root, + transactions_root, + receipts_root, + }, + checkpoint_state_trie_root, + contract_code, + block_metadata, + block_hashes, + burn_addr, + } = value; + Self { + txn_number: txn_number_before, + gas_before: gas_used_before, + gas_after: gas_used_after, + txns: signed_txns, + withdrawals, + exit_roots: global_exit_roots, + state: Mpt::from_hashed_partial_trie(&state_trie), + transaction: Mpt::from_hashed_partial_trie(&transactions_trie), + receipts: Mpt::from_hashed_partial_trie(&receipts_trie), + storage: storage_tries + .into_iter() + .map(|(k, v)| (k, Mpt::from_hashed_partial_trie(&v))) + .collect(), + state_root, + transaction_root: transactions_root, + receipt_root: receipts_root, + contract_code: contract_code.into_iter().collect(), + meta: block_metadata, + hashes: block_hashes, + checkpoint_root: checkpoint_state_trie_root, + burn_addr, + } + } + } + + #[derive(Serialize, PartialEq)] + struct Mpt(BTreeMap); + + impl Mpt { + pub fn from_hashed_partial_trie(hpt: &HashedPartialTrie) -> Self { + let mut repr = BTreeMap::new(); + visit(Stack::new(), hpt, &mut repr); + Self(repr) + } + } + + impl Default for Mpt { + fn default() -> Self { + Self::from_hashed_partial_trie(&HashedPartialTrie::default()) + } + } + + #[derive(PartialEq, Eq, PartialOrd, Ord)] + struct MptPath(Vec); + + impl fmt::Display for MptPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self(v) = self; + for u in v { + f.write_fmt(format_args!("{u:x}"))? + } + Ok(()) + } + } + impl Serialize for MptPath { + fn serialize(&self, serializer: S) -> Result { + serializer.collect_str(self) + } + } + + impl FromIterator for MptPath { + fn from_iter>(iter: II) -> Self { + Self(iter.into_iter().collect()) + } + } + + #[derive(PartialEq)] + enum MptNode { + Empty, + Hash(H256), + Value(Vec), + } + + impl fmt::Display for MptNode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MptNode::Empty => f.write_str("empty"), + MptNode::Hash(h) => { + f.write_fmt(format_args!("hash:{}", h.as_bytes().encode_hex::())) + } + MptNode::Value(v) => { + f.write_fmt(format_args!("value:{}", v.encode_hex::())) + } + } + } + } + + impl Serialize for MptNode { + fn serialize(&self, serializer: S) -> Result { + serializer.collect_str(self) + } + } + + fn visit(path: Stack, hpt: &HashedPartialTrie, repr: &mut BTreeMap) { + let key = path.iter().copied().collect(); + match &**hpt { + Node::Empty => { + repr.insert(key, MptNode::Empty); + } + Node::Hash(it) => { + repr.insert(key, MptNode::Hash(*it)); + } + Node::Branch { children, value } => { + for (ix, child) in children.iter().enumerate() { + visit(path.pushed(U4::new(ix as u8).unwrap()), child, repr) + } + if !value.is_empty() { + repr.insert(key, MptNode::Value(value.clone())); + } + } + Node::Extension { nibbles, child } => { + path.with_all(iter_nibbles(*nibbles), |path| visit(*path, child, repr)) + } + Node::Leaf { nibbles, value } => path.with_all(iter_nibbles(*nibbles), |path| { + repr.insert( + path.iter().copied().collect(), + MptNode::Value(value.clone()), + ); + }), + } + } + + fn iter_nibbles(mut nibbles: Nibbles) -> impl Iterator { + iter::from_fn(move || match nibbles.count { + 0 => None, + _ => Some(U4::new(nibbles.pop_next_nibble_back()).unwrap()), + }) + } + + mod hex { + pub mod slice { + pub fn serialize( + it: &[impl hex::ToHex], + serializer: S, + ) -> Result { + serializer.collect_seq(it.iter().map(|it| it.encode_hex::())) + } + } + pub mod btree_map { + use std::collections::BTreeMap; + + use serde::{ser::SerializeMap as _, Serialize}; + + pub fn serialize( + it: &BTreeMap, + serializer: S, + ) -> Result { + let mut serializer = serializer.serialize_map(Some(it.len()))?; + for (k, v) in it { + serializer.serialize_entry(k, &v.encode_hex::())?; + } + serializer.end() + } + } + } +} From 4511b807414366f21ee71996f1f0ff1261d8aa65 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Tue, 3 Sep 2024 17:03:05 +0100 Subject: [PATCH 14/56] test: break out common --- trace_decoder/tests/ab.rs | 410 +----------------------------- trace_decoder/tests/common/mod.rs | 399 +++++++++++++++++++++++++++++ 2 files changed, 409 insertions(+), 400 deletions(-) create mode 100644 trace_decoder/tests/common/mod.rs diff --git a/trace_decoder/tests/ab.rs b/trace_decoder/tests/ab.rs index cc2b99acc..bcfe78092 100644 --- a/trace_decoder/tests/ab.rs +++ b/trace_decoder/tests/ab.rs @@ -1,53 +1,24 @@ +//! Test that the new implementation produces the same results as the old. + +mod common; + use std::collections::{BTreeMap, BTreeSet, HashMap}; use alloy::{ - consensus::{Account, Eip658Value, Receipt, ReceiptWithBloom}, - primitives::{address, b256, Address, Bloom, FixedBytes, Log, B256}, + consensus::Account, + primitives::{Address, B256}, }; use alloy_compat::Compat as _; -use evm_arithmetization::proof::{BlockHashes, BlockMetadata}; -use keccak_hash::H256; -use key::TrieKey; +use common::{acct, hpt, key::TrieKey, obd, rcpt, txn, ALICE, BEACON}; use mpt_trie::{ nibbles::Nibbles, partial_trie::{HashedPartialTrie, PartialTrie as _}, }; use trace_decoder::{ - BlockLevelData, BlockTrace, BlockTraceTriePreImages, OtherBlockData, - SeparateStorageTriesPreImage, SeparateTriePreImage, SeparateTriePreImages, TxnInfo, TxnMeta, - TxnTrace, + BlockTrace, BlockTraceTriePreImages, OtherBlockData, SeparateStorageTriesPreImage, + SeparateTriePreImage, SeparateTriePreImages, TxnInfo, }; -const ALICE: Address = address!("00000000000000000000000000000000000a11ce"); -const BOB: Address = address!("0000000000000000000000000000000000000b0b"); -const CHARLIE: Address = address!("000000000000000000000000000000000c44271e"); -const BEACON: Address = address!("000f3df6d732807ef1319fb7b8bb8522d0beac02"); - -#[test] -fn character_hashes() { - t( - ALICE, - b256!("98934450b0a9aefe4c16aba331967de160f1b92f655dbf45675997ac0ef2bcf3"), - ); - t( - BOB, - b256!("3034df95d8f0ea7db7ab950e22fc977fa82ae80174df73ee1c75c24246b96df3"), - ); - t( - CHARLIE, - b256!("82c4b3e30ae93f236e06c03afe07f4c69f1aa9d4bac5bb3f4731810828003f97"), - ); - t( - BEACON, - b256!("37d65eaa92c6bc4c13a5ec45527f0c18ea8932588728769ec7aecfe6d9f32e42"), - ); - - #[track_caller] - fn t(address: Address, expected: B256) { - assert_eq!(keccak_hash::keccak(address).compat(), expected) - } -} - #[test] fn empty2() { do_test( @@ -80,62 +51,6 @@ fn pad2() { do_test([(BEACON, acct())], [], [(BEACON, hpt())], [], [], obd()); } -fn rcpt(success: bool, gas: u128, logs: impl Into>) -> ReceiptWithBloom { - ReceiptWithBloom { - receipt: Receipt { - status: Eip658Value::Eip658(success), - cumulative_gas_used: gas, - logs: logs.into(), - }, - logs_bloom: Bloom(FixedBytes::default()), - } -} - -fn txn( - traces: impl Into>, - byte_code: impl Into>, - receipt: impl Into, - gas: u64, -) -> TxnInfo { - TxnInfo { - traces: traces - .into() - .into_iter() - .map(|(k, v)| (k.compat(), v)) - .collect(), - meta: TxnMeta { - byte_code: byte_code.into(), - new_receipt_trie_node_byte: alloy::rlp::encode(receipt.into()), - gas_used: gas, - }, - } -} - -fn hpt() -> HashedPartialTrie { - HashedPartialTrie::default() -} - -fn obd() -> OtherBlockData { - OtherBlockData { - b_data: BlockLevelData { - b_meta: BlockMetadata::default(), - b_hashes: BlockHashes { - prev_hashes: Vec::::default(), - cur_hash: H256::default(), - }, - withdrawals: Vec::<(ethereum_types::Address, ethereum_types::U256)>::default(), - }, - checkpoint_state_trie_root: H256::default(), - } -} - -fn acct() -> Account { - Account { - storage_root: HashedPartialTrie::default().hash().compat(), - ..Default::default() - } -} - fn do_test( state: impl Into>, deferred_state: impl Into>, @@ -194,314 +109,9 @@ fn do_test( fn str_repr(src: Vec) -> String { serde_json::to_string_pretty( &src.into_iter() - .map(repr::GenerationInputs::from) + .map(common::repr::GenerationInputs::from) .collect::>(), ) .expect("unable to serialize") } } - -mod key { - use copyvec::CopyVec; - use u4::U4; - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct TrieKey(CopyVec); - - impl TrieKey { - pub const fn new() -> Self { - Self(CopyVec::new()) - } - pub fn into_nibbles(self) -> mpt_trie::nibbles::Nibbles { - let mut theirs = mpt_trie::nibbles::Nibbles::new(); - let Self(ours) = self; - for nibble in ours { - theirs.push_nibble_back(nibble as _) - } - theirs - } - } - - impl std::str::FromStr for TrieKey { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let mut nibbles = CopyVec::new(); - for char in s.chars() { - nibbles.try_push(U4::from_str_radix(char.encode_utf8(&mut [0; 4]), 16)?)? - } - Ok(Self(nibbles)) - } - } - - const fn assert_trie_key(s: &str) { - let is_hex = alloy::hex::const_check_raw(s.as_bytes()); - assert!(is_hex, "string must be hex characters only"); - assert!(s.len() <= 64, "too many characters in string"); - } - - macro_rules! key { - () => { - TrieKey::new() - }; - ($lit:literal) => {{ - const { assert_trie_key($lit) }; - $lit.parse::().unwrap() - }}; - } - pub(crate) use key; -} - -mod repr { - use std::{collections::BTreeMap, fmt, iter}; - - use ::hex::ToHex as _; - use ethereum_types::{Address, U256}; - use evm_arithmetization::{ - generation::TrieInputs, - proof::{BlockHashes, BlockMetadata, TrieRoots}, - }; - use keccak_hash::H256; - use mpt_trie::{ - nibbles::Nibbles, - partial_trie::{HashedPartialTrie, Node}, - }; - use serde::{Serialize, Serializer}; - use stackstack::Stack; - use u4::U4; - - #[derive(Serialize, PartialEq)] - pub struct GenerationInputs { - #[serde(skip_serializing_if = "is_default")] - txn_number: U256, - #[serde(skip_serializing_if = "is_default")] - gas_before: U256, - #[serde(skip_serializing_if = "is_default")] - gas_after: U256, - #[serde(with = "hex::slice", skip_serializing_if = "is_default")] - txns: Vec>, - #[serde(skip_serializing_if = "is_default")] - withdrawals: Vec<(Address, U256)>, - #[serde(skip_serializing_if = "is_default")] - exit_roots: Vec<(U256, H256)>, - - #[serde(skip_serializing_if = "is_default")] - state: Mpt, - #[serde(skip_serializing_if = "is_default")] - transaction: Mpt, - #[serde(skip_serializing_if = "is_default")] - receipts: Mpt, - #[serde(skip_serializing_if = "is_default")] - storage: BTreeMap, - - #[serde(skip_serializing_if = "is_default")] - checkpoint_root: H256, - state_root: H256, - transaction_root: H256, - receipt_root: H256, - - #[serde(with = "hex::btree_map", skip_serializing_if = "is_default")] - contract_code: BTreeMap>, - #[serde(skip_serializing_if = "is_default")] - meta: BlockMetadata, - #[serde(skip_serializing_if = "hashes_is_empty")] - hashes: BlockHashes, - - #[serde(skip_serializing_if = "Option::is_none")] - burn_addr: Option
, - } - - fn is_default(it: &T) -> bool { - *it == T::default() - } - fn hashes_is_empty(it: &BlockHashes) -> bool { - *it == BlockHashes { - prev_hashes: vec![], - cur_hash: H256::zero(), - } - } - - impl From for GenerationInputs { - fn from(value: evm_arithmetization::generation::GenerationInputs) -> Self { - let evm_arithmetization::generation::GenerationInputs { - txn_number_before, - gas_used_before, - gas_used_after, - signed_txns, - withdrawals, - global_exit_roots, - tries: - TrieInputs { - state_trie, - transactions_trie, - receipts_trie, - storage_tries, - }, - trie_roots_after: - TrieRoots { - state_root, - transactions_root, - receipts_root, - }, - checkpoint_state_trie_root, - contract_code, - block_metadata, - block_hashes, - burn_addr, - } = value; - Self { - txn_number: txn_number_before, - gas_before: gas_used_before, - gas_after: gas_used_after, - txns: signed_txns, - withdrawals, - exit_roots: global_exit_roots, - state: Mpt::from_hashed_partial_trie(&state_trie), - transaction: Mpt::from_hashed_partial_trie(&transactions_trie), - receipts: Mpt::from_hashed_partial_trie(&receipts_trie), - storage: storage_tries - .into_iter() - .map(|(k, v)| (k, Mpt::from_hashed_partial_trie(&v))) - .collect(), - state_root, - transaction_root: transactions_root, - receipt_root: receipts_root, - contract_code: contract_code.into_iter().collect(), - meta: block_metadata, - hashes: block_hashes, - checkpoint_root: checkpoint_state_trie_root, - burn_addr, - } - } - } - - #[derive(Serialize, PartialEq)] - struct Mpt(BTreeMap); - - impl Mpt { - pub fn from_hashed_partial_trie(hpt: &HashedPartialTrie) -> Self { - let mut repr = BTreeMap::new(); - visit(Stack::new(), hpt, &mut repr); - Self(repr) - } - } - - impl Default for Mpt { - fn default() -> Self { - Self::from_hashed_partial_trie(&HashedPartialTrie::default()) - } - } - - #[derive(PartialEq, Eq, PartialOrd, Ord)] - struct MptPath(Vec); - - impl fmt::Display for MptPath { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self(v) = self; - for u in v { - f.write_fmt(format_args!("{u:x}"))? - } - Ok(()) - } - } - impl Serialize for MptPath { - fn serialize(&self, serializer: S) -> Result { - serializer.collect_str(self) - } - } - - impl FromIterator for MptPath { - fn from_iter>(iter: II) -> Self { - Self(iter.into_iter().collect()) - } - } - - #[derive(PartialEq)] - enum MptNode { - Empty, - Hash(H256), - Value(Vec), - } - - impl fmt::Display for MptNode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - MptNode::Empty => f.write_str("empty"), - MptNode::Hash(h) => { - f.write_fmt(format_args!("hash:{}", h.as_bytes().encode_hex::())) - } - MptNode::Value(v) => { - f.write_fmt(format_args!("value:{}", v.encode_hex::())) - } - } - } - } - - impl Serialize for MptNode { - fn serialize(&self, serializer: S) -> Result { - serializer.collect_str(self) - } - } - - fn visit(path: Stack, hpt: &HashedPartialTrie, repr: &mut BTreeMap) { - let key = path.iter().copied().collect(); - match &**hpt { - Node::Empty => { - repr.insert(key, MptNode::Empty); - } - Node::Hash(it) => { - repr.insert(key, MptNode::Hash(*it)); - } - Node::Branch { children, value } => { - for (ix, child) in children.iter().enumerate() { - visit(path.pushed(U4::new(ix as u8).unwrap()), child, repr) - } - if !value.is_empty() { - repr.insert(key, MptNode::Value(value.clone())); - } - } - Node::Extension { nibbles, child } => { - path.with_all(iter_nibbles(*nibbles), |path| visit(*path, child, repr)) - } - Node::Leaf { nibbles, value } => path.with_all(iter_nibbles(*nibbles), |path| { - repr.insert( - path.iter().copied().collect(), - MptNode::Value(value.clone()), - ); - }), - } - } - - fn iter_nibbles(mut nibbles: Nibbles) -> impl Iterator { - iter::from_fn(move || match nibbles.count { - 0 => None, - _ => Some(U4::new(nibbles.pop_next_nibble_back()).unwrap()), - }) - } - - mod hex { - pub mod slice { - pub fn serialize( - it: &[impl hex::ToHex], - serializer: S, - ) -> Result { - serializer.collect_seq(it.iter().map(|it| it.encode_hex::())) - } - } - pub mod btree_map { - use std::collections::BTreeMap; - - use serde::{ser::SerializeMap as _, Serialize}; - - pub fn serialize( - it: &BTreeMap, - serializer: S, - ) -> Result { - let mut serializer = serializer.serialize_map(Some(it.len()))?; - for (k, v) in it { - serializer.serialize_entry(k, &v.encode_hex::())?; - } - serializer.end() - } - } - } -} diff --git a/trace_decoder/tests/common/mod.rs b/trace_decoder/tests/common/mod.rs new file mode 100644 index 000000000..0ec5e0b19 --- /dev/null +++ b/trace_decoder/tests/common/mod.rs @@ -0,0 +1,399 @@ +use std::collections::BTreeMap; + +use alloy::{ + consensus::{Account, Eip658Value, Receipt, ReceiptWithBloom}, + primitives::{Address, Bloom, FixedBytes, Log}, +}; +use alloy_compat::Compat as _; +use evm_arithmetization::proof::{BlockHashes, BlockMetadata}; +use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie as _}; +use trace_decoder::{BlockLevelData, OtherBlockData, TxnInfo, TxnMeta, TxnTrace}; + +pub fn rcpt(success: bool, gas: u128, logs: impl Into>) -> ReceiptWithBloom { + ReceiptWithBloom { + receipt: Receipt { + status: Eip658Value::Eip658(success), + cumulative_gas_used: gas, + logs: logs.into(), + }, + logs_bloom: Bloom(FixedBytes::default()), + } +} + +pub fn txn( + traces: impl Into>, + byte_code: impl Into>, + receipt: impl Into, + gas: u64, +) -> TxnInfo { + TxnInfo { + traces: traces + .into() + .into_iter() + .map(|(k, v)| (k.compat(), v)) + .collect(), + meta: TxnMeta { + byte_code: byte_code.into(), + new_receipt_trie_node_byte: alloy::rlp::encode(receipt.into()), + gas_used: gas, + }, + } +} + +pub fn hpt() -> HashedPartialTrie { + HashedPartialTrie::default() +} + +pub fn obd() -> OtherBlockData { + OtherBlockData { + b_data: BlockLevelData { + b_meta: BlockMetadata::default(), + b_hashes: BlockHashes { + prev_hashes: Default::default(), + cur_hash: Default::default(), + }, + withdrawals: Vec::<(ethereum_types::Address, ethereum_types::U256)>::default(), + }, + checkpoint_state_trie_root: Default::default(), + } +} + +pub fn acct() -> Account { + Account { + storage_root: HashedPartialTrie::default().hash().compat(), + ..Default::default() + } +} + +/// Store the address next to the hash for reference when e.g debugging tries +macro_rules! characters { + ($($name:ident = $addr:literal ($hash:literal);)*) => { + $( + pub const $name: alloy::primitives::Address = alloy::primitives::address!($addr); + )* + + mod test_character_hashes { + use alloy_compat::Compat as _; + $( + #[test] + #[allow(non_snake_case)] + fn $name() { + assert_eq!(keccak_hash::keccak(super::$name).compat(), alloy::primitives::b256!($hash)) + } + )* + } + }; +} + +// Well known addresses for use in tests +characters! { + ALICE = "00000000000000000000000000000000000a11ce" ("98934450b0a9aefe4c16aba331967de160f1b92f655dbf45675997ac0ef2bcf3"); + BOB = "0000000000000000000000000000000000000b0b" ("3034df95d8f0ea7db7ab950e22fc977fa82ae80174df73ee1c75c24246b96df3"); + CHARLIE = "000000000000000000000000000000000c44271e" ("82c4b3e30ae93f236e06c03afe07f4c69f1aa9d4bac5bb3f4731810828003f97"); + BEACON = "000f3df6d732807ef1319fb7b8bb8522d0beac02" ("37d65eaa92c6bc4c13a5ec45527f0c18ea8932588728769ec7aecfe6d9f32e42"); +} + +pub mod key { + use copyvec::CopyVec; + use u4::U4; + #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] + pub struct TrieKey(CopyVec); + + impl TrieKey { + pub const fn new() -> Self { + Self(CopyVec::new()) + } + pub fn into_nibbles(self) -> mpt_trie::nibbles::Nibbles { + let mut theirs = mpt_trie::nibbles::Nibbles::new(); + let Self(ours) = self; + for nibble in ours { + theirs.push_nibble_back(nibble as _) + } + theirs + } + } + + impl std::str::FromStr for TrieKey { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + let mut nibbles = CopyVec::new(); + for char in s.chars() { + nibbles.try_push(U4::from_str_radix(char.encode_utf8(&mut [0; 4]), 16)?)? + } + Ok(Self(nibbles)) + } + } + + const fn assert_trie_key(s: &str) { + let is_hex = alloy::hex::const_check_raw(s.as_bytes()); + assert!(is_hex, "string must be hex characters only"); + assert!(s.len() <= 64, "too many characters in string"); + } + + macro_rules! key { + () => { + TrieKey::new() + }; + ($lit:literal) => {{ + const { assert_trie_key($lit) }; + $lit.parse::().unwrap() + }}; + } + pub(crate) use key; +} + +pub mod repr { + use std::{collections::BTreeMap, fmt, iter}; + + use ::hex::ToHex as _; + use ethereum_types::{Address, U256}; + use evm_arithmetization::{ + generation::TrieInputs, + proof::{BlockHashes, BlockMetadata, TrieRoots}, + }; + use keccak_hash::H256; + use mpt_trie::{ + nibbles::Nibbles, + partial_trie::{HashedPartialTrie, Node}, + }; + use serde::{Serialize, Serializer}; + use stackstack::Stack; + use u4::U4; + + #[derive(Serialize, PartialEq)] + pub struct GenerationInputs { + #[serde(skip_serializing_if = "is_default")] + txn_number: U256, + #[serde(skip_serializing_if = "is_default")] + gas_before: U256, + #[serde(skip_serializing_if = "is_default")] + gas_after: U256, + #[serde(with = "hex::slice", skip_serializing_if = "is_default")] + txns: Vec>, + #[serde(skip_serializing_if = "is_default")] + withdrawals: Vec<(Address, U256)>, + #[serde(skip_serializing_if = "is_default")] + exit_roots: Vec<(U256, H256)>, + + #[serde(skip_serializing_if = "is_default")] + state: Mpt, + #[serde(skip_serializing_if = "is_default")] + transaction: Mpt, + #[serde(skip_serializing_if = "is_default")] + receipts: Mpt, + #[serde(skip_serializing_if = "is_default")] + storage: BTreeMap, + + #[serde(skip_serializing_if = "is_default")] + checkpoint_root: H256, + state_root: H256, + transaction_root: H256, + receipt_root: H256, + + #[serde(with = "hex::btree_map", skip_serializing_if = "is_default")] + contract_code: BTreeMap>, + #[serde(skip_serializing_if = "is_default")] + meta: BlockMetadata, + #[serde(skip_serializing_if = "hashes_is_empty")] + hashes: BlockHashes, + + #[serde(skip_serializing_if = "Option::is_none")] + burn_addr: Option
, + } + + fn is_default(it: &T) -> bool { + *it == T::default() + } + fn hashes_is_empty(it: &BlockHashes) -> bool { + *it == BlockHashes { + prev_hashes: vec![], + cur_hash: H256::zero(), + } + } + + impl From for GenerationInputs { + fn from(value: evm_arithmetization::generation::GenerationInputs) -> Self { + let evm_arithmetization::generation::GenerationInputs { + txn_number_before, + gas_used_before, + gas_used_after, + signed_txns, + withdrawals, + global_exit_roots, + tries: + TrieInputs { + state_trie, + transactions_trie, + receipts_trie, + storage_tries, + }, + trie_roots_after: + TrieRoots { + state_root, + transactions_root, + receipts_root, + }, + checkpoint_state_trie_root, + contract_code, + block_metadata, + block_hashes, + burn_addr, + } = value; + Self { + txn_number: txn_number_before, + gas_before: gas_used_before, + gas_after: gas_used_after, + txns: signed_txns, + withdrawals, + exit_roots: global_exit_roots, + state: Mpt::from_hashed_partial_trie(&state_trie), + transaction: Mpt::from_hashed_partial_trie(&transactions_trie), + receipts: Mpt::from_hashed_partial_trie(&receipts_trie), + storage: storage_tries + .into_iter() + .map(|(k, v)| (k, Mpt::from_hashed_partial_trie(&v))) + .collect(), + state_root, + transaction_root: transactions_root, + receipt_root: receipts_root, + contract_code: contract_code.into_iter().collect(), + meta: block_metadata, + hashes: block_hashes, + checkpoint_root: checkpoint_state_trie_root, + burn_addr, + } + } + } + + #[derive(Serialize, PartialEq)] + struct Mpt(BTreeMap); + + impl Mpt { + pub fn from_hashed_partial_trie(hpt: &HashedPartialTrie) -> Self { + let mut repr = BTreeMap::new(); + visit(Stack::new(), hpt, &mut repr); + Self(repr) + } + } + + impl Default for Mpt { + fn default() -> Self { + Self::from_hashed_partial_trie(&HashedPartialTrie::default()) + } + } + + #[derive(PartialEq, Eq, PartialOrd, Ord)] + struct MptPath(Vec); + + impl fmt::Display for MptPath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let Self(v) = self; + for u in v { + f.write_fmt(format_args!("{u:x}"))? + } + Ok(()) + } + } + impl Serialize for MptPath { + fn serialize(&self, serializer: S) -> Result { + serializer.collect_str(self) + } + } + + impl FromIterator for MptPath { + fn from_iter>(iter: II) -> Self { + Self(iter.into_iter().collect()) + } + } + + #[derive(PartialEq)] + enum MptNode { + Empty, + Hash(H256), + Value(Vec), + } + + impl fmt::Display for MptNode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MptNode::Empty => f.write_str("empty"), + MptNode::Hash(h) => { + f.write_fmt(format_args!("hash:{}", h.as_bytes().encode_hex::())) + } + MptNode::Value(v) => { + f.write_fmt(format_args!("value:{}", v.encode_hex::())) + } + } + } + } + + impl Serialize for MptNode { + fn serialize(&self, serializer: S) -> Result { + serializer.collect_str(self) + } + } + + fn visit(path: Stack, hpt: &HashedPartialTrie, repr: &mut BTreeMap) { + let key = path.iter().copied().collect(); + match &**hpt { + Node::Empty => { + repr.insert(key, MptNode::Empty); + } + Node::Hash(it) => { + repr.insert(key, MptNode::Hash(*it)); + } + Node::Branch { children, value } => { + for (ix, child) in children.iter().enumerate() { + visit(path.pushed(U4::new(ix as u8).unwrap()), child, repr) + } + if !value.is_empty() { + repr.insert(key, MptNode::Value(value.clone())); + } + } + Node::Extension { nibbles, child } => { + path.with_all(iter_nibbles(*nibbles), |path| visit(*path, child, repr)) + } + Node::Leaf { nibbles, value } => path.with_all(iter_nibbles(*nibbles), |path| { + repr.insert( + path.iter().copied().collect(), + MptNode::Value(value.clone()), + ); + }), + } + } + + fn iter_nibbles(mut nibbles: Nibbles) -> impl Iterator { + iter::from_fn(move || match nibbles.count { + 0 => None, + _ => Some(U4::new(nibbles.pop_next_nibble_back()).unwrap()), + }) + } + + mod hex { + pub mod slice { + pub fn serialize( + it: &[impl hex::ToHex], + serializer: S, + ) -> Result { + serializer.collect_seq(it.iter().map(|it| it.encode_hex::())) + } + } + pub mod btree_map { + use std::collections::BTreeMap; + + use serde::{ser::SerializeMap as _, Serialize}; + + pub fn serialize( + it: &BTreeMap, + serializer: S, + ) -> Result { + let mut serializer = serializer.serialize_map(Some(it.len()))?; + for (k, v) in it { + serializer.serialize_entry(k, &v.encode_hex::())?; + } + serializer.end() + } + } + } +} From 3546b42a6cc5b836401e0f5176734424f9f982d4 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 13:18:03 +0100 Subject: [PATCH 15/56] test: a/b --- trace_decoder/tests/ab.rs | 199 +++++++++++++++++++++++++++++- trace_decoder/tests/common/mod.rs | 63 ++++++++-- 2 files changed, 248 insertions(+), 14 deletions(-) diff --git a/trace_decoder/tests/ab.rs b/trace_decoder/tests/ab.rs index bcfe78092..f36c5c353 100644 --- a/trace_decoder/tests/ab.rs +++ b/trace_decoder/tests/ab.rs @@ -9,14 +9,15 @@ use alloy::{ primitives::{Address, B256}, }; use alloy_compat::Compat as _; -use common::{acct, hpt, key::TrieKey, obd, rcpt, txn, ALICE, BEACON}; +use common::{acct, hpt, key::TrieKey, obd, pos, rcpt, stg, txn, ALICE, BEACON}; +use ethereum_types::U256; use mpt_trie::{ nibbles::Nibbles, partial_trie::{HashedPartialTrie, PartialTrie as _}, }; use trace_decoder::{ BlockTrace, BlockTraceTriePreImages, OtherBlockData, SeparateStorageTriesPreImage, - SeparateTriePreImage, SeparateTriePreImages, TxnInfo, + SeparateTriePreImage, SeparateTriePreImages, TxnInfo, TxnTrace, }; #[test] @@ -46,11 +47,199 @@ fn pad1() { } #[test] -#[ignore] +#[should_panic = "TODO(0xaatif): fix"] fn pad2() { do_test([(BEACON, acct())], [], [(BEACON, hpt())], [], [], obd()); } +#[test] +fn alice_changes_balance() { + do_test( + [(BEACON, acct()), (ALICE, acct())], + [], + // TODO(0xaatif): if alice is missing from the storage: + // - subject gives her a Node::Hash($EMPTY_TRIE_HASH). + // - reference gives her a Node::Empty. + // neither error. + [(BEACON, hpt()), (ALICE, hpt())], + [], + [ + txn( + [( + ALICE, + TxnTrace { + storage_read: [].into(), + ..Default::default() + }, + )], + [], + rcpt(true, 0, []), + 0, + ), + txn([], [], rcpt(true, 0, []), 0), + ], + obd(), + ) +} + +#[test] +fn alice_changes_nonce() { + do_test( + [(BEACON, acct()), (ALICE, acct())], + [], + [(BEACON, hpt()), (ALICE, hpt())], + [], + [ + txn( + [( + ALICE, + TxnTrace { + nonce: Some(U256::from(1)), + ..Default::default() + }, + )], + [], + rcpt(true, 0, []), + 0, + ), + txn([], [], rcpt(true, 0, []), 0), + ], + obd(), + ) +} + +#[test] +fn alice_reads_existing() { + let alice_stg = stg( + [ + (pos(ALICE, 0), b"zero".into()), + (pos(ALICE, 1), b"one".into()), + (pos(ALICE, 2), b"two".into()), + ], + [], + ); + do_test( + [ + (BEACON, acct()), + ( + ALICE, + Account { + storage_root: alice_stg.hash().compat(), + ..Default::default() + }, + ), + ], + [], + [(BEACON, hpt()), (ALICE, alice_stg)], + [], + [ + txn( + [( + ALICE, + TxnTrace { + storage_read: [pos(ALICE, 1)].into(), + ..Default::default() + }, + )], + [], + rcpt(true, 0, []), + 0, + ), + txn([], [], rcpt(true, 0, []), 0), + ], + obd(), + ) +} + +#[test] +fn alice_reads_absent() { + do_test( + [(BEACON, acct()), (ALICE, acct())], + [], + [(BEACON, hpt()), (ALICE, hpt())], + [], + [ + txn( + [( + ALICE, + TxnTrace { + storage_read: [pos(ALICE, 0)].into(), + ..Default::default() + }, + )], + [], + rcpt(true, 0, []), + 0, + ), + txn([], [], rcpt(true, 0, []), 0), + ], + obd(), + ) +} + +#[test] +fn alice_writes() { + do_test( + [(BEACON, acct()), (ALICE, acct())], + [], + [(BEACON, hpt()), (ALICE, hpt())], + [], + [ + txn( + [( + ALICE, + TxnTrace { + storage_written: [(pos(ALICE, 0), 42.into())].into(), + ..Default::default() + }, + )], + [], + rcpt(true, 0, []), + 0, + ), + txn([], [], rcpt(true, 0, []), 0), + ], + obd(), + ) +} + +#[test] +fn alice_writes_then_reads() { + do_test( + [(BEACON, acct()), (ALICE, acct())], + [], + [(BEACON, hpt()), (ALICE, hpt())], + [], + [ + txn( + [( + ALICE, + TxnTrace { + storage_written: [(pos(ALICE, 0), 42.into())].into(), + ..Default::default() + }, + )], + [], + rcpt(true, 0, []), + 0, + ), + txn( + [( + ALICE, + TxnTrace { + storage_read: [pos(ALICE, 0)].into(), + ..Default::default() + }, + )], + [], + rcpt(true, 0, []), + 0, + ), + ], + obd(), + ) +} + fn do_test( state: impl Into>, deferred_state: impl Into>, @@ -99,11 +288,13 @@ fn do_test( gi.contract_code.insert(keccak_hash::keccak([]), vec![]); } + let reference = str_repr(reference); pretty_assertions::assert_str_eq!( - str_repr(reference), + reference, str_repr(subject), "reference (left) != (right) subject" ); + println!("{reference}"); #[track_caller] fn str_repr(src: Vec) -> String { diff --git a/trace_decoder/tests/common/mod.rs b/trace_decoder/tests/common/mod.rs index 0ec5e0b19..9c7d3d222 100644 --- a/trace_decoder/tests/common/mod.rs +++ b/trace_decoder/tests/common/mod.rs @@ -2,10 +2,13 @@ use std::collections::BTreeMap; use alloy::{ consensus::{Account, Eip658Value, Receipt, ReceiptWithBloom}, - primitives::{Address, Bloom, FixedBytes, Log}, + primitives::{Address, Bloom, FixedBytes, Log, B256}, }; use alloy_compat::Compat as _; use evm_arithmetization::proof::{BlockHashes, BlockMetadata}; +pub use keccak_hash::keccak as k; +use keccak_hash::H256; +use key::TrieKey; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie as _}; use trace_decoder::{BlockLevelData, OtherBlockData, TxnInfo, TxnMeta, TxnTrace}; @@ -65,6 +68,38 @@ pub fn acct() -> Account { } } +pub fn stg( + full: impl IntoIterator)>, + deferred: impl IntoIterator, +) -> HashedPartialTrie { + let mut hpt = hpt(); + for (k, v) in full { + hpt.insert(TrieKey::from_hash(k).into_nibbles(), v).unwrap() + } + for (k, h) in deferred { + hpt.insert(k.into_nibbles(), h.compat()).unwrap() + } + hpt +} + +pub fn pos(addr: Address, slot_ix: u64) -> H256 { + let address_left_padded = alloy::primitives::B256::left_padding_from(&**addr); + let slot_ix_left_padded = alloy::primitives::U256::from(slot_ix).to_be_bytes::<32>(); + let concat = { + let mut storage = [0; 64]; + for (ix, byte) in address_left_padded + .0 + .into_iter() + .chain(slot_ix_left_padded) + .enumerate() + { + storage[ix] = byte + } + storage + }; + k(concat) +} + /// Store the address next to the hash for reference when e.g debugging tries macro_rules! characters { ($($name:ident = $addr:literal ($hash:literal);)*) => { @@ -93,11 +128,13 @@ characters! { BEACON = "000f3df6d732807ef1319fb7b8bb8522d0beac02" ("37d65eaa92c6bc4c13a5ec45527f0c18ea8932588728769ec7aecfe6d9f32e42"); } +#[allow(unused)] pub mod key { use copyvec::CopyVec; - use u4::U4; + use keccak_hash::H256; + use u4::{AsNibbles, U4}; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct TrieKey(CopyVec); + pub struct TrieKey(pub CopyVec); impl TrieKey { pub const fn new() -> Self { @@ -111,6 +148,13 @@ pub mod key { } theirs } + pub(super) fn from_hash(h: H256) -> Self { + let mut v = CopyVec::new(); + for u4 in AsNibbles(h.0) { + v.push(u4) + } + Self(v) + } } impl std::str::FromStr for TrieKey { @@ -125,18 +169,17 @@ pub mod key { } } - const fn assert_trie_key(s: &str) { - let is_hex = alloy::hex::const_check_raw(s.as_bytes()); - assert!(is_hex, "string must be hex characters only"); - assert!(s.len() <= 64, "too many characters in string"); - } - macro_rules! key { () => { TrieKey::new() }; ($lit:literal) => {{ - const { assert_trie_key($lit) }; + const { + let s = $lit; + let is_hex = alloy::hex::const_check_raw(s.as_bytes()); + assert!(is_hex, "string must be hex characters only"); + assert!(s.len() <= 64, "too many characters in string"); + }; $lit.parse::().unwrap() }}; } From d11a3659c0bde8fc5606c7b35f52ccdda3eb746d Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 13:33:58 +0100 Subject: [PATCH 16/56] fix: imp::batch --- trace_decoder/src/imp.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 8ee5e6f5a..b764c315d 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -186,7 +186,7 @@ fn start( /// Break `txns` into batches of length `hint`, prioritising creating at least /// two batches. fn batch(mut txns: Vec, hint: usize) -> Vec> { - let hint = cmp::min(hint, 1); + let hint = cmp::max(hint, 1); let n_batches = txns.iter().chunks(hint).into_iter().count(); match (txns.len(), n_batches) { // enough @@ -210,6 +210,27 @@ fn batch(mut txns: Vec, hint: usize) -> Vec> { } } +#[test] +fn test_batch() { + #[track_caller] + fn do_test(n: usize, hint: usize, exp: impl IntoIterator) { + itertools::assert_equal( + exp, + batch(vec![TxnInfo::default(); n], hint) + .iter() + .map(Vec::len), + ) + } + + do_test(0, 0, [1, 1]); // pad2 + do_test(1, 0, [1, 1]); // pad1 + do_test(2, 0, [1, 1]); // exact + do_test(3, 0, [1, 1, 1]); + do_test(3, 1, [1, 1, 1]); + do_test(3, 2, [2, 1]); // leftover after hint + do_test(3, 3, [1, 2]); // big hint +} + #[derive(Debug)] struct Batch { pub first_txn_ix: usize, From 69ed607f72b8c59193a32695455c57ed9200a158 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 14:33:19 +0100 Subject: [PATCH 17/56] fix: storage shenanigans --- trace_decoder/src/imp.rs | 22 ++++++++++------------ trace_decoder/tests/ab.rs | 3 ++- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index b764c315d..286be61fd 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -372,6 +372,15 @@ fn middle( } // if txn failed, don't commit changes to trie }; + let trim_storage = storage_masks.entry(addr).or_default(); + + trim_storage.extend( + storage_written + .keys() + .chain(&storage_read) + .map(|it| TrieKey::from_hash(keccak_hash::keccak(it))), + ); + if commit { acct.balance = balance.unwrap_or(acct.balance); acct.nonce = nonce.unwrap_or(acct.nonce); @@ -391,18 +400,7 @@ fn middle( .transpose()? .unwrap_or(acct.code_hash); - let trim_storage = storage_masks.entry(addr).or_default(); - - trim_storage.extend( - storage_written - .keys() - .chain(&storage_read) - .map(|it| TrieKey::from_hash(keccak_hash::keccak(it))), - ); - - let storage_trie_change = !storage_written.is_empty(); - - if storage_trie_change { + if !storage_written.is_empty() { let storage = match born { true => storage.entry(keccak_hash::keccak(addr)).or_default(), false => storage diff --git a/trace_decoder/tests/ab.rs b/trace_decoder/tests/ab.rs index f36c5c353..78c8bc770 100644 --- a/trace_decoder/tests/ab.rs +++ b/trace_decoder/tests/ab.rs @@ -47,7 +47,7 @@ fn pad1() { } #[test] -#[should_panic = "TODO(0xaatif): fix"] +#[should_panic] // TODO(0xaatif): fix fn pad2() { do_test([(BEACON, acct())], [], [(BEACON, hpt())], [], [], obd()); } @@ -240,6 +240,7 @@ fn alice_writes_then_reads() { ) } +#[track_caller] fn do_test( state: impl Into>, deferred_state: impl Into>, From 69249b0eeb56a24187b28381bd5213486d967837 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 14:43:34 +0100 Subject: [PATCH 18/56] refactor(ci): separate build for tests --- .github/workflows/ci.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f23f911bd..2966f4c8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,9 +44,14 @@ jobs: RUST_BACKTRACE: 1 test_trace_decoder: - name: Test trace_decoder + name: test trace_decoder runs-on: zero-ci timeout-minutes: 30 + env: + RUST_LOG: info + CARGO_INCREMENTAL: 1 + RUST_BACKTRACE: 1 + if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" steps: - name: Checkout sources @@ -60,12 +65,11 @@ jobs: with: cache-on-failure: true - - name: Test in trace_decoder subdirectory + - name: build # build separately so test logs are actually nice + run: cargo build --tests --manifest-path trace_decoder/Cargo.toml + + - name: test run: cargo test --release --manifest-path trace_decoder/Cargo.toml -- --nocapture - env: - RUST_LOG: info - CARGO_INCREMENTAL: 1 - RUST_BACKTRACE: 1 test_proof_gen: name: Test proof_gen @@ -132,7 +136,7 @@ jobs: - name: Set up rust cache uses: Swatinem/rust-cache@v2 with: - cache-on-failure: true + cache-on-failure: true - name: Test in zero_bin subdirectory run: | From 42b5d68f5ed3eaf22fef526b8c53b85d2f791644 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 14:43:58 +0100 Subject: [PATCH 19/56] refactor(ci): refactor conditions --- .github/workflows/ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2966f4c8c..5af8dd057 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: name: Test mpt_trie runs-on: ubuntu-latest timeout-minutes: 30 - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') }} steps: - name: Checkout sources uses: actions/checkout@v4 @@ -52,7 +52,7 @@ jobs: CARGO_INCREMENTAL: 1 RUST_BACKTRACE: 1 - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') }} steps: - name: Checkout sources uses: actions/checkout@v4 @@ -75,7 +75,7 @@ jobs: name: Test proof_gen runs-on: ubuntu-latest timeout-minutes: 30 - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') }} steps: - name: Checkout sources uses: actions/checkout@v4 @@ -100,7 +100,7 @@ jobs: name: Test evm_arithmetization runs-on: ubuntu-latest timeout-minutes: 30 - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') }} steps: - name: Checkout sources uses: actions/checkout@v4 @@ -125,7 +125,7 @@ jobs: name: Test zero_bin runs-on: ubuntu-latest timeout-minutes: 30 - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') }} steps: - name: Checkout sources uses: actions/checkout@v4 @@ -158,7 +158,7 @@ jobs: name: Test zk_evm_proc_macro runs-on: ubuntu-latest timeout-minutes: 30 - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') }} steps: - name: Checkout sources uses: actions/checkout@v4 @@ -222,7 +222,7 @@ jobs: name: Rustdoc, Formatting and Clippy runs-on: ubuntu-latest timeout-minutes: 10 - if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')" + if: ${{ ! contains(toJSON(github.event.commits.*.message), '[skip-ci]') }} steps: - name: Checkout sources uses: actions/checkout@v4 From 085e97f00bb34e8ca8c70beed57e475a3bbbdaf5 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 15:07:13 +0100 Subject: [PATCH 20/56] chore: change CI names --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5af8dd057..969ea7cd3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,7 +180,7 @@ jobs: RUST_BACKTRACE: 1 simple_proof_regular: - name: Execute bash script to generate and verify a proof for a small block. + name: prove_stdio (small - b19807080) runs-on: zero-ci steps: @@ -193,7 +193,7 @@ jobs: ./prove_stdio.sh artifacts/witness_b19807080.json simple_proof_witness_only: - name: Execute bash script to generate the proof witness for a small block. + name: prove_stdio test_only (small - b19807080) runs-on: zero-ci steps: @@ -206,7 +206,7 @@ jobs: ./prove_stdio.sh artifacts/witness_b19807080.json test_only multi_blocks_proof_regular: - name: Execute bash script to generate and verify a proof for multiple blocks using parallel proving. + name: prove_stdio (wide - b3_b6) runs-on: zero-ci steps: From ece25d3ac668346e3a28bb4615f8175bac132ca9 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 15:08:48 +0100 Subject: [PATCH 21/56] chore: cargo run --quiet in stdio.sh --- zero_bin/tools/prove_stdio.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zero_bin/tools/prove_stdio.sh b/zero_bin/tools/prove_stdio.sh index d37f84bf9..85afbbb21 100755 --- a/zero_bin/tools/prove_stdio.sh +++ b/zero_bin/tools/prove_stdio.sh @@ -91,7 +91,7 @@ fi # proof. This is useful for quickly testing decoding and all of the # other non-proving code. if [[ $TEST_ONLY == "test_only" ]]; then - cargo run --release --bin leader -- --test-only --runtime in-memory --load-strategy on-demand --block-batch-size $BLOCK_BATCH_SIZE --proof-output-dir $PROOF_OUTPUT_DIR stdio < $INPUT_FILE &> $TEST_OUT_PATH + cargo run --quiet --release --bin leader -- --test-only --runtime in-memory --load-strategy on-demand --block-batch-size $BLOCK_BATCH_SIZE --proof-output-dir $PROOF_OUTPUT_DIR stdio < $INPUT_FILE &> $TEST_OUT_PATH if grep -q 'All proof witnesses have been generated successfully.' $TEST_OUT_PATH; then echo -e "\n\nSuccess - Note this was just a test, not a proof" rm $TEST_OUT_PATH From 13304bbd5727dcfd2f87223fac239787d853b2d4 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 16:27:57 +0100 Subject: [PATCH 22/56] fix: special case empty txn_info --- trace_decoder/src/imp.rs | 39 ++++++++++++++++++++++++++++----------- trace_decoder/tests/ab.rs | 1 - 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 286be61fd..44bed43a8 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -61,15 +61,32 @@ pub fn entrypoint( *amt = eth_to_gwei(*amt) } - let batches = middle( - state, - storage, - batch(txn_info, batch_size), - &mut code, - b_meta.block_timestamp, - b_meta.parent_beacon_block_root, - withdrawals, - )?; + // TODO(0xaatif): I hate this + let batches = match txn_info.is_empty() { + true => { + let mut batches = middle( + state, + storage, + vec![vec![TxnInfo::default()]], + &mut code, + b_meta.block_timestamp, + b_meta.parent_beacon_block_root, + withdrawals, + )?; + assert_eq!(batches.len(), 1); + batches.push(batches[0].clone()); + batches + } + false => middle( + state, + storage, + batch(txn_info, batch_size), + &mut code, + b_meta.block_timestamp, + b_meta.parent_beacon_block_root, + withdrawals, + )?, + }; let mut running_gas_used = 0; Ok(batches @@ -231,7 +248,7 @@ fn test_batch() { do_test(3, 3, [1, 2]); // big hint } -#[derive(Debug)] +#[derive(Debug, Clone)] struct Batch { pub first_txn_ix: usize, pub gas_used: u64, @@ -249,7 +266,7 @@ struct Batch { /// [`evm_arithmetization::generation::TrieInputs`], /// generic over state trie representation. -#[derive(Debug)] +#[derive(Debug, Clone)] struct IntraBlockTries { pub state: StateTrieT, pub storage: BTreeMap, diff --git a/trace_decoder/tests/ab.rs b/trace_decoder/tests/ab.rs index 78c8bc770..831e77224 100644 --- a/trace_decoder/tests/ab.rs +++ b/trace_decoder/tests/ab.rs @@ -47,7 +47,6 @@ fn pad1() { } #[test] -#[should_panic] // TODO(0xaatif): fix fn pad2() { do_test([(BEACON, acct())], [], [(BEACON, hpt())], [], [], obd()); } From 1dbc67acf6f00156171b936568d0b557c235bec9 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Wed, 4 Sep 2024 16:40:12 +0100 Subject: [PATCH 23/56] Revert "fix: special case empty txn_info" This reverts commit 13304bbd5727dcfd2f87223fac239787d853b2d4. --- trace_decoder/src/imp.rs | 39 +++++++++++---------------------------- trace_decoder/tests/ab.rs | 1 + 2 files changed, 12 insertions(+), 28 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 44bed43a8..286be61fd 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -61,32 +61,15 @@ pub fn entrypoint( *amt = eth_to_gwei(*amt) } - // TODO(0xaatif): I hate this - let batches = match txn_info.is_empty() { - true => { - let mut batches = middle( - state, - storage, - vec![vec![TxnInfo::default()]], - &mut code, - b_meta.block_timestamp, - b_meta.parent_beacon_block_root, - withdrawals, - )?; - assert_eq!(batches.len(), 1); - batches.push(batches[0].clone()); - batches - } - false => middle( - state, - storage, - batch(txn_info, batch_size), - &mut code, - b_meta.block_timestamp, - b_meta.parent_beacon_block_root, - withdrawals, - )?, - }; + let batches = middle( + state, + storage, + batch(txn_info, batch_size), + &mut code, + b_meta.block_timestamp, + b_meta.parent_beacon_block_root, + withdrawals, + )?; let mut running_gas_used = 0; Ok(batches @@ -248,7 +231,7 @@ fn test_batch() { do_test(3, 3, [1, 2]); // big hint } -#[derive(Debug, Clone)] +#[derive(Debug)] struct Batch { pub first_txn_ix: usize, pub gas_used: u64, @@ -266,7 +249,7 @@ struct Batch { /// [`evm_arithmetization::generation::TrieInputs`], /// generic over state trie representation. -#[derive(Debug, Clone)] +#[derive(Debug)] struct IntraBlockTries { pub state: StateTrieT, pub storage: BTreeMap, diff --git a/trace_decoder/tests/ab.rs b/trace_decoder/tests/ab.rs index 831e77224..78c8bc770 100644 --- a/trace_decoder/tests/ab.rs +++ b/trace_decoder/tests/ab.rs @@ -47,6 +47,7 @@ fn pad1() { } #[test] +#[should_panic] // TODO(0xaatif): fix fn pad2() { do_test([(BEACON, acct())], [], [(BEACON, hpt())], [], [], obd()); } From ac673daeba4c77cee2bc19d1761b537038979e52 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Thu, 5 Sep 2024 10:21:30 +0100 Subject: [PATCH 24/56] fix?: special case dummy batch --- trace_decoder/src/imp.rs | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 286be61fd..638077239 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -319,6 +319,8 @@ fn middle( )?; } + let is_dummy = batch.iter().all(|it| it.meta.byte_code.is_empty()); + for TxnInfo { traces, meta: @@ -469,22 +471,24 @@ fn middle( false => vec![], }, before: { - before.state.trim_to(state_mask)?; - before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; - before - .transaction - .trim_to(batch_first_txn_ix..curr_txn_ix)?; - - let keep = storage_masks - .keys() - .map(keccak_hash::keccak) - .collect::>(); - before.storage.retain(|haddr, _| keep.contains(haddr)); - - for (addr, mask) in storage_masks { - if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { - it.trim_to(mask)? - } // TODO(0xaatif): why is this fallible? + if !is_dummy { + before.state.trim_to(state_mask)?; + before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; + before + .transaction + .trim_to(batch_first_txn_ix..curr_txn_ix)?; + + let keep = storage_masks + .keys() + .map(keccak_hash::keccak) + .collect::>(); + before.storage.retain(|haddr, _| keep.contains(haddr)); + + for (addr, mask) in storage_masks { + if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { + it.trim_to(mask)? + } // TODO(0xaatif): why is this fallible? + } } before }, From 5be5357f8757028776a1a19a7f9e099d4ca58293 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Thu, 5 Sep 2024 11:54:44 +0100 Subject: [PATCH 25/56] Revert "fix?: special case dummy batch" This reverts commit ac673daeba4c77cee2bc19d1761b537038979e52. --- trace_decoder/src/imp.rs | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 638077239..286be61fd 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -319,8 +319,6 @@ fn middle( )?; } - let is_dummy = batch.iter().all(|it| it.meta.byte_code.is_empty()); - for TxnInfo { traces, meta: @@ -471,24 +469,22 @@ fn middle( false => vec![], }, before: { - if !is_dummy { - before.state.trim_to(state_mask)?; - before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; - before - .transaction - .trim_to(batch_first_txn_ix..curr_txn_ix)?; - - let keep = storage_masks - .keys() - .map(keccak_hash::keccak) - .collect::>(); - before.storage.retain(|haddr, _| keep.contains(haddr)); - - for (addr, mask) in storage_masks { - if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { - it.trim_to(mask)? - } // TODO(0xaatif): why is this fallible? - } + before.state.trim_to(state_mask)?; + before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; + before + .transaction + .trim_to(batch_first_txn_ix..curr_txn_ix)?; + + let keep = storage_masks + .keys() + .map(keccak_hash::keccak) + .collect::>(); + before.storage.retain(|haddr, _| keep.contains(haddr)); + + for (addr, mask) in storage_masks { + if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { + it.trim_to(mask)? + } // TODO(0xaatif): why is this fallible? } before }, From 592aa3ade7856bff15e4ff5497f0454c033ababe Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Thu, 5 Sep 2024 13:20:32 +0100 Subject: [PATCH 26/56] try: do not run cancun hook on dummy txns --- trace_decoder/src/decoding.rs | 4 ++-- trace_decoder/src/imp.rs | 42 +++++++++++++++++++--------------- trace_decoder/src/typed_mpt.rs | 12 +++++----- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/trace_decoder/src/decoding.rs b/trace_decoder/src/decoding.rs index ebb293b2c..ca141ed20 100644 --- a/trace_decoder/src/decoding.rs +++ b/trace_decoder/src/decoding.rs @@ -256,7 +256,7 @@ fn create_minimal_partial_tries_needed_by_txn( delta_application_out: TrieDeltaApplicationOutput, ) -> anyhow::Result { let mut state_trie = curr_block_tries.state.clone(); - state_trie.trim_to( + state_trie.mask( nodes_used_by_txn .state_accesses .iter() @@ -457,7 +457,7 @@ fn add_withdrawals_to_txns( if last_inputs.signed_txns.is_empty() { let mut state_trie = final_trie_state.state.clone(); - state_trie.trim_to( + state_trie.mask( // This is a dummy payload, hence it does not contain yet // state accesses to the withdrawal addresses. withdrawals diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 286be61fd..2d471e7d9 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -185,7 +185,10 @@ fn start( /// Break `txns` into batches of length `hint`, prioritising creating at least /// two batches. -fn batch(mut txns: Vec, hint: usize) -> Vec> { +/// +/// [`None`] represents a dummy transaction. +fn batch(txns: Vec, hint: usize) -> Vec>> { + let mut txns = txns.into_iter().map(Some).collect::>(); let hint = cmp::max(hint, 1); let n_batches = txns.iter().chunks(hint).into_iter().count(); match (txns.len(), n_batches) { @@ -204,7 +207,7 @@ fn batch(mut txns: Vec, hint: usize) -> Vec> { // add padding (0 | 1, _) => txns .into_iter() - .pad_using(2, |_ix| TxnInfo::default()) + .pad_using(2, |_ix| None) .map(|it| vec![it]) .collect(), } @@ -262,7 +265,9 @@ fn middle( mut state_trie: StateTrieT, // storage at the beginning of the block mut storage: BTreeMap, - batches: Vec>, + // None represents a dummy txn + // All vecs must be non-empty. + batches: Vec>>, code: &mut Hash2Code, block_timestamp: U256, parent_beacon_block_root: H256, @@ -290,6 +295,7 @@ fn middle( let mut curr_txn_ix = 0; let len_txns = batches.iter().flatten().count(); + for batch in batches { let batch_first_txn_ix = curr_txn_ix; // GOTCHA: if there are no transactions in this batch let mut batch_gas_used = 0; @@ -308,7 +314,7 @@ fn middle( let mut storage_masks = BTreeMap::<_, BTreeSet>::new(); let mut state_mask = BTreeSet::new(); - if curr_txn_ix == 0 { + if curr_txn_ix == 0 && batch[0].is_some() { cancun_hook( block_timestamp, &mut storage, @@ -327,7 +333,7 @@ fn middle( new_receipt_trie_node_byte, gas_used: txn_gas_used, }, - } in batch + } in batch.into_iter().flatten() { if let Ok(nonempty) = nunny::Vec::new(txn_byte_code) { batch_byte_code.push(nonempty.clone()); @@ -372,9 +378,9 @@ fn middle( } // if txn failed, don't commit changes to trie }; - let trim_storage = storage_masks.entry(addr).or_default(); + let storage_mask = storage_masks.entry(addr).or_default(); - trim_storage.extend( + storage_mask.extend( storage_written .keys() .chain(&storage_read) @@ -412,7 +418,7 @@ fn middle( let slot = TrieKey::from_hash(keccak_hash::keccak(k)); match v.is_zero() { // this is actually a delete - true => trim_storage.extend(storage.reporting_remove(slot)?), + true => storage_mask.extend(storage.reporting_remove(slot)?), false => { storage.insert(slot, rlp::encode(&v).to_vec())?; } @@ -469,11 +475,9 @@ fn middle( false => vec![], }, before: { - before.state.trim_to(state_mask)?; - before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; - before - .transaction - .trim_to(batch_first_txn_ix..curr_txn_ix)?; + before.state.mask(state_mask)?; + before.receipt.mask(batch_first_txn_ix..curr_txn_ix)?; + before.transaction.mask(batch_first_txn_ix..curr_txn_ix)?; let keep = storage_masks .keys() @@ -483,7 +487,7 @@ fn middle( for (addr, mask) in storage_masks { if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { - it.trim_to(mask)? + it.mask(mask)? } // TODO(0xaatif): why is this fallible? } before @@ -502,7 +506,7 @@ fn middle( fn cancun_hook( block_timestamp: U256, storage: &mut BTreeMap, - trim_storage: &mut BTreeMap>, + storage_masks: &mut BTreeMap>, parent_beacon_block_root: H256, trim_state: &mut BTreeSet, state_trie: &mut StateTrieT, @@ -513,7 +517,7 @@ fn cancun_hook( let beacon_storage = storage .get_mut(&keccak_hash::keccak(BEACON_ROOTS_CONTRACT_ADDRESS)) .context("missing beacon contract storage trie")?; - let beacon_trim = trim_storage + let storage_mask = storage_masks .entry(BEACON_ROOTS_CONTRACT_ADDRESS) .or_default(); for (ix, u) in [ @@ -526,13 +530,13 @@ fn cancun_hook( let mut h = [0; 32]; ix.to_big_endian(&mut h); let slot = TrieKey::from_hash(keccak_hash::keccak(H256::from_slice(&h))); - beacon_trim.insert(slot); + storage_mask.insert(slot); match u.is_zero() { - true => beacon_trim.extend(beacon_storage.reporting_remove(slot)?), + true => storage_mask.extend(beacon_storage.reporting_remove(slot)?), false => { beacon_storage.insert(slot, alloy::rlp::encode(u.compat()))?; - beacon_trim.insert(slot); + storage_mask.insert(slot); } } } diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index c26991da3..9d81663bc 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -205,7 +205,7 @@ impl TransactionTrie { &self.untyped } /// Defer (hash) parts of the trie that aren't in `txn_ixs`. - pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, txn_ixs @@ -250,7 +250,7 @@ impl ReceiptTrie { &self.untyped } /// Defer (hash) parts of the trie that aren't in `txn_ixs`. - pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, txn_ixs @@ -277,7 +277,7 @@ pub trait StateTrie { fn get_by_address(&self, address: Address) -> Option; fn reporting_remove(&mut self, address: Address) -> anyhow::Result>; fn contains_address(&self, address: Address) -> bool; - fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; + fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; fn iter(&self) -> impl Iterator + '_; fn root(&self) -> H256; } @@ -344,7 +344,7 @@ impl StateTrie for StateMpt { .as_hashed_partial_trie() .contains(TrieKey::from_address(address).into_nibbles()) } - fn trim_to(&mut self, addresses: impl IntoIterator) -> anyhow::Result<()> { + fn mask(&mut self, addresses: impl IntoIterator) -> anyhow::Result<()> { let inner = mpt_trie::trie_subsets::create_trie_subset( self.typed.as_hashed_partial_trie(), addresses.into_iter().map(TrieKey::into_nibbles), @@ -401,7 +401,7 @@ impl StateTrie for StateSmt { fn contains_address(&self, address: Address) -> bool { self.address2state.contains_key(&address) } - fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()> { + fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()> { let _ = address; Ok(()) } @@ -455,7 +455,7 @@ impl StorageTrie { &mut self.untyped } /// Defer (hash) the parts of the trie that aren't in `paths`. - pub fn trim_to(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { + pub fn mask(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, paths.into_iter().map(TrieKey::into_nibbles), From 211bcbfe1ff44cb8a302fe12ebee574968281c80 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Thu, 5 Sep 2024 13:33:30 +0100 Subject: [PATCH 27/56] Revert "try: do not run cancun hook on dummy txns" This reverts commit 592aa3ade7856bff15e4ff5497f0454c033ababe. --- trace_decoder/src/decoding.rs | 4 ++-- trace_decoder/src/imp.rs | 42 +++++++++++++++------------------- trace_decoder/src/typed_mpt.rs | 12 +++++----- 3 files changed, 27 insertions(+), 31 deletions(-) diff --git a/trace_decoder/src/decoding.rs b/trace_decoder/src/decoding.rs index ca141ed20..ebb293b2c 100644 --- a/trace_decoder/src/decoding.rs +++ b/trace_decoder/src/decoding.rs @@ -256,7 +256,7 @@ fn create_minimal_partial_tries_needed_by_txn( delta_application_out: TrieDeltaApplicationOutput, ) -> anyhow::Result { let mut state_trie = curr_block_tries.state.clone(); - state_trie.mask( + state_trie.trim_to( nodes_used_by_txn .state_accesses .iter() @@ -457,7 +457,7 @@ fn add_withdrawals_to_txns( if last_inputs.signed_txns.is_empty() { let mut state_trie = final_trie_state.state.clone(); - state_trie.mask( + state_trie.trim_to( // This is a dummy payload, hence it does not contain yet // state accesses to the withdrawal addresses. withdrawals diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 2d471e7d9..286be61fd 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -185,10 +185,7 @@ fn start( /// Break `txns` into batches of length `hint`, prioritising creating at least /// two batches. -/// -/// [`None`] represents a dummy transaction. -fn batch(txns: Vec, hint: usize) -> Vec>> { - let mut txns = txns.into_iter().map(Some).collect::>(); +fn batch(mut txns: Vec, hint: usize) -> Vec> { let hint = cmp::max(hint, 1); let n_batches = txns.iter().chunks(hint).into_iter().count(); match (txns.len(), n_batches) { @@ -207,7 +204,7 @@ fn batch(txns: Vec, hint: usize) -> Vec>> { // add padding (0 | 1, _) => txns .into_iter() - .pad_using(2, |_ix| None) + .pad_using(2, |_ix| TxnInfo::default()) .map(|it| vec![it]) .collect(), } @@ -265,9 +262,7 @@ fn middle( mut state_trie: StateTrieT, // storage at the beginning of the block mut storage: BTreeMap, - // None represents a dummy txn - // All vecs must be non-empty. - batches: Vec>>, + batches: Vec>, code: &mut Hash2Code, block_timestamp: U256, parent_beacon_block_root: H256, @@ -295,7 +290,6 @@ fn middle( let mut curr_txn_ix = 0; let len_txns = batches.iter().flatten().count(); - for batch in batches { let batch_first_txn_ix = curr_txn_ix; // GOTCHA: if there are no transactions in this batch let mut batch_gas_used = 0; @@ -314,7 +308,7 @@ fn middle( let mut storage_masks = BTreeMap::<_, BTreeSet>::new(); let mut state_mask = BTreeSet::new(); - if curr_txn_ix == 0 && batch[0].is_some() { + if curr_txn_ix == 0 { cancun_hook( block_timestamp, &mut storage, @@ -333,7 +327,7 @@ fn middle( new_receipt_trie_node_byte, gas_used: txn_gas_used, }, - } in batch.into_iter().flatten() + } in batch { if let Ok(nonempty) = nunny::Vec::new(txn_byte_code) { batch_byte_code.push(nonempty.clone()); @@ -378,9 +372,9 @@ fn middle( } // if txn failed, don't commit changes to trie }; - let storage_mask = storage_masks.entry(addr).or_default(); + let trim_storage = storage_masks.entry(addr).or_default(); - storage_mask.extend( + trim_storage.extend( storage_written .keys() .chain(&storage_read) @@ -418,7 +412,7 @@ fn middle( let slot = TrieKey::from_hash(keccak_hash::keccak(k)); match v.is_zero() { // this is actually a delete - true => storage_mask.extend(storage.reporting_remove(slot)?), + true => trim_storage.extend(storage.reporting_remove(slot)?), false => { storage.insert(slot, rlp::encode(&v).to_vec())?; } @@ -475,9 +469,11 @@ fn middle( false => vec![], }, before: { - before.state.mask(state_mask)?; - before.receipt.mask(batch_first_txn_ix..curr_txn_ix)?; - before.transaction.mask(batch_first_txn_ix..curr_txn_ix)?; + before.state.trim_to(state_mask)?; + before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; + before + .transaction + .trim_to(batch_first_txn_ix..curr_txn_ix)?; let keep = storage_masks .keys() @@ -487,7 +483,7 @@ fn middle( for (addr, mask) in storage_masks { if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { - it.mask(mask)? + it.trim_to(mask)? } // TODO(0xaatif): why is this fallible? } before @@ -506,7 +502,7 @@ fn middle( fn cancun_hook( block_timestamp: U256, storage: &mut BTreeMap, - storage_masks: &mut BTreeMap>, + trim_storage: &mut BTreeMap>, parent_beacon_block_root: H256, trim_state: &mut BTreeSet, state_trie: &mut StateTrieT, @@ -517,7 +513,7 @@ fn cancun_hook( let beacon_storage = storage .get_mut(&keccak_hash::keccak(BEACON_ROOTS_CONTRACT_ADDRESS)) .context("missing beacon contract storage trie")?; - let storage_mask = storage_masks + let beacon_trim = trim_storage .entry(BEACON_ROOTS_CONTRACT_ADDRESS) .or_default(); for (ix, u) in [ @@ -530,13 +526,13 @@ fn cancun_hook( let mut h = [0; 32]; ix.to_big_endian(&mut h); let slot = TrieKey::from_hash(keccak_hash::keccak(H256::from_slice(&h))); - storage_mask.insert(slot); + beacon_trim.insert(slot); match u.is_zero() { - true => storage_mask.extend(beacon_storage.reporting_remove(slot)?), + true => beacon_trim.extend(beacon_storage.reporting_remove(slot)?), false => { beacon_storage.insert(slot, alloy::rlp::encode(u.compat()))?; - storage_mask.insert(slot); + beacon_trim.insert(slot); } } } diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index 9d81663bc..c26991da3 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -205,7 +205,7 @@ impl TransactionTrie { &self.untyped } /// Defer (hash) parts of the trie that aren't in `txn_ixs`. - pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, txn_ixs @@ -250,7 +250,7 @@ impl ReceiptTrie { &self.untyped } /// Defer (hash) parts of the trie that aren't in `txn_ixs`. - pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, txn_ixs @@ -277,7 +277,7 @@ pub trait StateTrie { fn get_by_address(&self, address: Address) -> Option; fn reporting_remove(&mut self, address: Address) -> anyhow::Result>; fn contains_address(&self, address: Address) -> bool; - fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; + fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; fn iter(&self) -> impl Iterator + '_; fn root(&self) -> H256; } @@ -344,7 +344,7 @@ impl StateTrie for StateMpt { .as_hashed_partial_trie() .contains(TrieKey::from_address(address).into_nibbles()) } - fn mask(&mut self, addresses: impl IntoIterator) -> anyhow::Result<()> { + fn trim_to(&mut self, addresses: impl IntoIterator) -> anyhow::Result<()> { let inner = mpt_trie::trie_subsets::create_trie_subset( self.typed.as_hashed_partial_trie(), addresses.into_iter().map(TrieKey::into_nibbles), @@ -401,7 +401,7 @@ impl StateTrie for StateSmt { fn contains_address(&self, address: Address) -> bool { self.address2state.contains_key(&address) } - fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()> { + fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()> { let _ = address; Ok(()) } @@ -455,7 +455,7 @@ impl StorageTrie { &mut self.untyped } /// Defer (hash) the parts of the trie that aren't in `paths`. - pub fn mask(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { + pub fn trim_to(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, paths.into_iter().map(TrieKey::into_nibbles), From 50108d98f5785d4247ce18bfeec62bb2c126889e Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Thu, 5 Sep 2024 15:35:23 +0100 Subject: [PATCH 28/56] fix: do not increment txn numbers for dummy txns --- trace_decoder/src/imp.rs | 44 ++++++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 286be61fd..90eb2192f 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -185,8 +185,12 @@ fn start( /// Break `txns` into batches of length `hint`, prioritising creating at least /// two batches. -fn batch(mut txns: Vec, hint: usize) -> Vec> { +/// +/// [`None`] represents a dummy transaction that should not increment the +/// transaction index. +fn batch(txns: Vec, hint: usize) -> Vec>> { let hint = cmp::max(hint, 1); + let mut txns = txns.into_iter().map(Some).collect::>(); let n_batches = txns.iter().chunks(hint).into_iter().count(); match (txns.len(), n_batches) { // enough @@ -204,7 +208,7 @@ fn batch(mut txns: Vec, hint: usize) -> Vec> { // add padding (0 | 1, _) => txns .into_iter() - .pad_using(2, |_ix| TxnInfo::default()) + .pad_using(2, |_ix| None) .map(|it| vec![it]) .collect(), } @@ -262,7 +266,9 @@ fn middle( mut state_trie: StateTrieT, // storage at the beginning of the block mut storage: BTreeMap, - batches: Vec>, + // None represents a dummy transaction that should not increment the transaction index + // all batches SHOULD not be empty + batches: Vec>>, code: &mut Hash2Code, block_timestamp: U256, parent_beacon_block_root: H256, @@ -319,17 +325,18 @@ fn middle( )?; } - for TxnInfo { - traces, - meta: - TxnMeta { - byte_code: txn_byte_code, - new_receipt_trie_node_byte, - gas_used: txn_gas_used, - }, - } in batch - { - if let Ok(nonempty) = nunny::Vec::new(txn_byte_code) { + for txn in batch { + let increment_txn_ix = txn.is_some(); + let TxnInfo { + traces, + meta: + TxnMeta { + byte_code, + new_receipt_trie_node_byte, + gas_used: txn_gas_used, + }, + } = txn.unwrap_or_default(); + if let Ok(nonempty) = nunny::Vec::new(byte_code) { batch_byte_code.push(nonempty.clone()); transaction_trie.insert(curr_txn_ix, nonempty.into())?; receipt_trie.insert( @@ -355,6 +362,11 @@ fn middle( .into_iter() .map(|(addr, trc)| (addr, trc == TxnTrace::default(), trc)) { + // - created and failed + // - access the state trie, no change to storage trie + // - created and self destructed + // - access the state trie + // - empty trace requires the account to be present in the state trie let (mut acct, born) = state_trie .get_by_address(addr) .map(|acct| (acct, false)) @@ -442,7 +454,9 @@ fn middle( } } - curr_txn_ix += 1; + if increment_txn_ix { + curr_txn_ix += 1; + } } // txn in batch out.push(Batch { From 2a7ac0613bf4c5bd482a45ea35bb7aa845a543e6 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Thu, 5 Sep 2024 15:54:10 +0100 Subject: [PATCH 29/56] Revert "chore: change CI names" This reverts commit 085e97f00bb34e8ca8c70beed57e475a3bbbdaf5. --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 969ea7cd3..5af8dd057 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -180,7 +180,7 @@ jobs: RUST_BACKTRACE: 1 simple_proof_regular: - name: prove_stdio (small - b19807080) + name: Execute bash script to generate and verify a proof for a small block. runs-on: zero-ci steps: @@ -193,7 +193,7 @@ jobs: ./prove_stdio.sh artifacts/witness_b19807080.json simple_proof_witness_only: - name: prove_stdio test_only (small - b19807080) + name: Execute bash script to generate the proof witness for a small block. runs-on: zero-ci steps: @@ -206,7 +206,7 @@ jobs: ./prove_stdio.sh artifacts/witness_b19807080.json test_only multi_blocks_proof_regular: - name: prove_stdio (wide - b3_b6) + name: Execute bash script to generate and verify a proof for multiple blocks using parallel proving. runs-on: zero-ci steps: From 2a50ca1d943d599b0ee1a559a72414b381291ea1 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Thu, 5 Sep 2024 15:55:48 +0100 Subject: [PATCH 30/56] run: rm trace_decoder/tests/common/mod.rs trace_decoder/tests/ab.rs --- trace_decoder/tests/ab.rs | 309 --------------------- trace_decoder/tests/common/mod.rs | 442 ------------------------------ 2 files changed, 751 deletions(-) delete mode 100644 trace_decoder/tests/ab.rs delete mode 100644 trace_decoder/tests/common/mod.rs diff --git a/trace_decoder/tests/ab.rs b/trace_decoder/tests/ab.rs deleted file mode 100644 index 78c8bc770..000000000 --- a/trace_decoder/tests/ab.rs +++ /dev/null @@ -1,309 +0,0 @@ -//! Test that the new implementation produces the same results as the old. - -mod common; - -use std::collections::{BTreeMap, BTreeSet, HashMap}; - -use alloy::{ - consensus::Account, - primitives::{Address, B256}, -}; -use alloy_compat::Compat as _; -use common::{acct, hpt, key::TrieKey, obd, pos, rcpt, stg, txn, ALICE, BEACON}; -use ethereum_types::U256; -use mpt_trie::{ - nibbles::Nibbles, - partial_trie::{HashedPartialTrie, PartialTrie as _}, -}; -use trace_decoder::{ - BlockTrace, BlockTraceTriePreImages, OtherBlockData, SeparateStorageTriesPreImage, - SeparateTriePreImage, SeparateTriePreImages, TxnInfo, TxnTrace, -}; - -#[test] -fn empty2() { - do_test( - [(BEACON, acct()), (ALICE, acct())], - [], - [(BEACON, hpt())], - [], - [ - txn([], [], rcpt(true, 0, []), 0), - txn([], [], rcpt(true, 0, []), 0), - ], - obd(), - ) -} -#[test] -fn pad1() { - do_test( - [(BEACON, acct()), (ALICE, acct())], - [], - [(BEACON, hpt())], - [], - [txn([], [], rcpt(true, 0, []), 0)], - obd(), - ) -} - -#[test] -#[should_panic] // TODO(0xaatif): fix -fn pad2() { - do_test([(BEACON, acct())], [], [(BEACON, hpt())], [], [], obd()); -} - -#[test] -fn alice_changes_balance() { - do_test( - [(BEACON, acct()), (ALICE, acct())], - [], - // TODO(0xaatif): if alice is missing from the storage: - // - subject gives her a Node::Hash($EMPTY_TRIE_HASH). - // - reference gives her a Node::Empty. - // neither error. - [(BEACON, hpt()), (ALICE, hpt())], - [], - [ - txn( - [( - ALICE, - TxnTrace { - storage_read: [].into(), - ..Default::default() - }, - )], - [], - rcpt(true, 0, []), - 0, - ), - txn([], [], rcpt(true, 0, []), 0), - ], - obd(), - ) -} - -#[test] -fn alice_changes_nonce() { - do_test( - [(BEACON, acct()), (ALICE, acct())], - [], - [(BEACON, hpt()), (ALICE, hpt())], - [], - [ - txn( - [( - ALICE, - TxnTrace { - nonce: Some(U256::from(1)), - ..Default::default() - }, - )], - [], - rcpt(true, 0, []), - 0, - ), - txn([], [], rcpt(true, 0, []), 0), - ], - obd(), - ) -} - -#[test] -fn alice_reads_existing() { - let alice_stg = stg( - [ - (pos(ALICE, 0), b"zero".into()), - (pos(ALICE, 1), b"one".into()), - (pos(ALICE, 2), b"two".into()), - ], - [], - ); - do_test( - [ - (BEACON, acct()), - ( - ALICE, - Account { - storage_root: alice_stg.hash().compat(), - ..Default::default() - }, - ), - ], - [], - [(BEACON, hpt()), (ALICE, alice_stg)], - [], - [ - txn( - [( - ALICE, - TxnTrace { - storage_read: [pos(ALICE, 1)].into(), - ..Default::default() - }, - )], - [], - rcpt(true, 0, []), - 0, - ), - txn([], [], rcpt(true, 0, []), 0), - ], - obd(), - ) -} - -#[test] -fn alice_reads_absent() { - do_test( - [(BEACON, acct()), (ALICE, acct())], - [], - [(BEACON, hpt()), (ALICE, hpt())], - [], - [ - txn( - [( - ALICE, - TxnTrace { - storage_read: [pos(ALICE, 0)].into(), - ..Default::default() - }, - )], - [], - rcpt(true, 0, []), - 0, - ), - txn([], [], rcpt(true, 0, []), 0), - ], - obd(), - ) -} - -#[test] -fn alice_writes() { - do_test( - [(BEACON, acct()), (ALICE, acct())], - [], - [(BEACON, hpt()), (ALICE, hpt())], - [], - [ - txn( - [( - ALICE, - TxnTrace { - storage_written: [(pos(ALICE, 0), 42.into())].into(), - ..Default::default() - }, - )], - [], - rcpt(true, 0, []), - 0, - ), - txn([], [], rcpt(true, 0, []), 0), - ], - obd(), - ) -} - -#[test] -fn alice_writes_then_reads() { - do_test( - [(BEACON, acct()), (ALICE, acct())], - [], - [(BEACON, hpt()), (ALICE, hpt())], - [], - [ - txn( - [( - ALICE, - TxnTrace { - storage_written: [(pos(ALICE, 0), 42.into())].into(), - ..Default::default() - }, - )], - [], - rcpt(true, 0, []), - 0, - ), - txn( - [( - ALICE, - TxnTrace { - storage_read: [pos(ALICE, 0)].into(), - ..Default::default() - }, - )], - [], - rcpt(true, 0, []), - 0, - ), - ], - obd(), - ) -} - -#[track_caller] -fn do_test( - state: impl Into>, - deferred_state: impl Into>, - storage: impl Into>, - code_db: impl Into>>, - txn_info: impl Into>, - obd: impl Into, -) { - let obd = obd.into(); - let bt = BlockTrace { - trie_pre_images: BlockTraceTriePreImages::Separate(SeparateTriePreImages { - state: SeparateTriePreImage::Direct({ - let mut hpt = HashedPartialTrie::default(); - for (k, v) in state.into() { - hpt.insert( - Nibbles::from_h256_be(keccak_hash::keccak(k)), - alloy::rlp::encode(v), - ) - .unwrap() - } - for (k, h) in deferred_state.into() { - hpt.insert(k.into_nibbles(), h.compat()).unwrap() - } - hpt - }), - storage: SeparateStorageTriesPreImage::MultipleTries( - storage - .into() - .into_iter() - .map(|(k, v)| (keccak_hash::keccak(k), SeparateTriePreImage::Direct(v))) - .collect(), - ), - }), - code_db: code_db.into(), - txn_info: txn_info.into(), - }; - - eprintln!("generate reference..."); - let mut reference = trace_decoder::entrypoint_old(bt.clone(), obd.clone(), 1, false) - .expect("couldn't generate reference"); - eprintln!("generate subject..."); - let subject = - trace_decoder::entrypoint_new(bt, obd, 1, false).expect("couldn't generate subject"); - - for gi in &mut reference { - gi.contract_code.insert(keccak_hash::keccak([]), vec![]); - } - - let reference = str_repr(reference); - pretty_assertions::assert_str_eq!( - reference, - str_repr(subject), - "reference (left) != (right) subject" - ); - println!("{reference}"); - - #[track_caller] - fn str_repr(src: Vec) -> String { - serde_json::to_string_pretty( - &src.into_iter() - .map(common::repr::GenerationInputs::from) - .collect::>(), - ) - .expect("unable to serialize") - } -} diff --git a/trace_decoder/tests/common/mod.rs b/trace_decoder/tests/common/mod.rs deleted file mode 100644 index 9c7d3d222..000000000 --- a/trace_decoder/tests/common/mod.rs +++ /dev/null @@ -1,442 +0,0 @@ -use std::collections::BTreeMap; - -use alloy::{ - consensus::{Account, Eip658Value, Receipt, ReceiptWithBloom}, - primitives::{Address, Bloom, FixedBytes, Log, B256}, -}; -use alloy_compat::Compat as _; -use evm_arithmetization::proof::{BlockHashes, BlockMetadata}; -pub use keccak_hash::keccak as k; -use keccak_hash::H256; -use key::TrieKey; -use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie as _}; -use trace_decoder::{BlockLevelData, OtherBlockData, TxnInfo, TxnMeta, TxnTrace}; - -pub fn rcpt(success: bool, gas: u128, logs: impl Into>) -> ReceiptWithBloom { - ReceiptWithBloom { - receipt: Receipt { - status: Eip658Value::Eip658(success), - cumulative_gas_used: gas, - logs: logs.into(), - }, - logs_bloom: Bloom(FixedBytes::default()), - } -} - -pub fn txn( - traces: impl Into>, - byte_code: impl Into>, - receipt: impl Into, - gas: u64, -) -> TxnInfo { - TxnInfo { - traces: traces - .into() - .into_iter() - .map(|(k, v)| (k.compat(), v)) - .collect(), - meta: TxnMeta { - byte_code: byte_code.into(), - new_receipt_trie_node_byte: alloy::rlp::encode(receipt.into()), - gas_used: gas, - }, - } -} - -pub fn hpt() -> HashedPartialTrie { - HashedPartialTrie::default() -} - -pub fn obd() -> OtherBlockData { - OtherBlockData { - b_data: BlockLevelData { - b_meta: BlockMetadata::default(), - b_hashes: BlockHashes { - prev_hashes: Default::default(), - cur_hash: Default::default(), - }, - withdrawals: Vec::<(ethereum_types::Address, ethereum_types::U256)>::default(), - }, - checkpoint_state_trie_root: Default::default(), - } -} - -pub fn acct() -> Account { - Account { - storage_root: HashedPartialTrie::default().hash().compat(), - ..Default::default() - } -} - -pub fn stg( - full: impl IntoIterator)>, - deferred: impl IntoIterator, -) -> HashedPartialTrie { - let mut hpt = hpt(); - for (k, v) in full { - hpt.insert(TrieKey::from_hash(k).into_nibbles(), v).unwrap() - } - for (k, h) in deferred { - hpt.insert(k.into_nibbles(), h.compat()).unwrap() - } - hpt -} - -pub fn pos(addr: Address, slot_ix: u64) -> H256 { - let address_left_padded = alloy::primitives::B256::left_padding_from(&**addr); - let slot_ix_left_padded = alloy::primitives::U256::from(slot_ix).to_be_bytes::<32>(); - let concat = { - let mut storage = [0; 64]; - for (ix, byte) in address_left_padded - .0 - .into_iter() - .chain(slot_ix_left_padded) - .enumerate() - { - storage[ix] = byte - } - storage - }; - k(concat) -} - -/// Store the address next to the hash for reference when e.g debugging tries -macro_rules! characters { - ($($name:ident = $addr:literal ($hash:literal);)*) => { - $( - pub const $name: alloy::primitives::Address = alloy::primitives::address!($addr); - )* - - mod test_character_hashes { - use alloy_compat::Compat as _; - $( - #[test] - #[allow(non_snake_case)] - fn $name() { - assert_eq!(keccak_hash::keccak(super::$name).compat(), alloy::primitives::b256!($hash)) - } - )* - } - }; -} - -// Well known addresses for use in tests -characters! { - ALICE = "00000000000000000000000000000000000a11ce" ("98934450b0a9aefe4c16aba331967de160f1b92f655dbf45675997ac0ef2bcf3"); - BOB = "0000000000000000000000000000000000000b0b" ("3034df95d8f0ea7db7ab950e22fc977fa82ae80174df73ee1c75c24246b96df3"); - CHARLIE = "000000000000000000000000000000000c44271e" ("82c4b3e30ae93f236e06c03afe07f4c69f1aa9d4bac5bb3f4731810828003f97"); - BEACON = "000f3df6d732807ef1319fb7b8bb8522d0beac02" ("37d65eaa92c6bc4c13a5ec45527f0c18ea8932588728769ec7aecfe6d9f32e42"); -} - -#[allow(unused)] -pub mod key { - use copyvec::CopyVec; - use keccak_hash::H256; - use u4::{AsNibbles, U4}; - #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] - pub struct TrieKey(pub CopyVec); - - impl TrieKey { - pub const fn new() -> Self { - Self(CopyVec::new()) - } - pub fn into_nibbles(self) -> mpt_trie::nibbles::Nibbles { - let mut theirs = mpt_trie::nibbles::Nibbles::new(); - let Self(ours) = self; - for nibble in ours { - theirs.push_nibble_back(nibble as _) - } - theirs - } - pub(super) fn from_hash(h: H256) -> Self { - let mut v = CopyVec::new(); - for u4 in AsNibbles(h.0) { - v.push(u4) - } - Self(v) - } - } - - impl std::str::FromStr for TrieKey { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - let mut nibbles = CopyVec::new(); - for char in s.chars() { - nibbles.try_push(U4::from_str_radix(char.encode_utf8(&mut [0; 4]), 16)?)? - } - Ok(Self(nibbles)) - } - } - - macro_rules! key { - () => { - TrieKey::new() - }; - ($lit:literal) => {{ - const { - let s = $lit; - let is_hex = alloy::hex::const_check_raw(s.as_bytes()); - assert!(is_hex, "string must be hex characters only"); - assert!(s.len() <= 64, "too many characters in string"); - }; - $lit.parse::().unwrap() - }}; - } - pub(crate) use key; -} - -pub mod repr { - use std::{collections::BTreeMap, fmt, iter}; - - use ::hex::ToHex as _; - use ethereum_types::{Address, U256}; - use evm_arithmetization::{ - generation::TrieInputs, - proof::{BlockHashes, BlockMetadata, TrieRoots}, - }; - use keccak_hash::H256; - use mpt_trie::{ - nibbles::Nibbles, - partial_trie::{HashedPartialTrie, Node}, - }; - use serde::{Serialize, Serializer}; - use stackstack::Stack; - use u4::U4; - - #[derive(Serialize, PartialEq)] - pub struct GenerationInputs { - #[serde(skip_serializing_if = "is_default")] - txn_number: U256, - #[serde(skip_serializing_if = "is_default")] - gas_before: U256, - #[serde(skip_serializing_if = "is_default")] - gas_after: U256, - #[serde(with = "hex::slice", skip_serializing_if = "is_default")] - txns: Vec>, - #[serde(skip_serializing_if = "is_default")] - withdrawals: Vec<(Address, U256)>, - #[serde(skip_serializing_if = "is_default")] - exit_roots: Vec<(U256, H256)>, - - #[serde(skip_serializing_if = "is_default")] - state: Mpt, - #[serde(skip_serializing_if = "is_default")] - transaction: Mpt, - #[serde(skip_serializing_if = "is_default")] - receipts: Mpt, - #[serde(skip_serializing_if = "is_default")] - storage: BTreeMap, - - #[serde(skip_serializing_if = "is_default")] - checkpoint_root: H256, - state_root: H256, - transaction_root: H256, - receipt_root: H256, - - #[serde(with = "hex::btree_map", skip_serializing_if = "is_default")] - contract_code: BTreeMap>, - #[serde(skip_serializing_if = "is_default")] - meta: BlockMetadata, - #[serde(skip_serializing_if = "hashes_is_empty")] - hashes: BlockHashes, - - #[serde(skip_serializing_if = "Option::is_none")] - burn_addr: Option
, - } - - fn is_default(it: &T) -> bool { - *it == T::default() - } - fn hashes_is_empty(it: &BlockHashes) -> bool { - *it == BlockHashes { - prev_hashes: vec![], - cur_hash: H256::zero(), - } - } - - impl From for GenerationInputs { - fn from(value: evm_arithmetization::generation::GenerationInputs) -> Self { - let evm_arithmetization::generation::GenerationInputs { - txn_number_before, - gas_used_before, - gas_used_after, - signed_txns, - withdrawals, - global_exit_roots, - tries: - TrieInputs { - state_trie, - transactions_trie, - receipts_trie, - storage_tries, - }, - trie_roots_after: - TrieRoots { - state_root, - transactions_root, - receipts_root, - }, - checkpoint_state_trie_root, - contract_code, - block_metadata, - block_hashes, - burn_addr, - } = value; - Self { - txn_number: txn_number_before, - gas_before: gas_used_before, - gas_after: gas_used_after, - txns: signed_txns, - withdrawals, - exit_roots: global_exit_roots, - state: Mpt::from_hashed_partial_trie(&state_trie), - transaction: Mpt::from_hashed_partial_trie(&transactions_trie), - receipts: Mpt::from_hashed_partial_trie(&receipts_trie), - storage: storage_tries - .into_iter() - .map(|(k, v)| (k, Mpt::from_hashed_partial_trie(&v))) - .collect(), - state_root, - transaction_root: transactions_root, - receipt_root: receipts_root, - contract_code: contract_code.into_iter().collect(), - meta: block_metadata, - hashes: block_hashes, - checkpoint_root: checkpoint_state_trie_root, - burn_addr, - } - } - } - - #[derive(Serialize, PartialEq)] - struct Mpt(BTreeMap); - - impl Mpt { - pub fn from_hashed_partial_trie(hpt: &HashedPartialTrie) -> Self { - let mut repr = BTreeMap::new(); - visit(Stack::new(), hpt, &mut repr); - Self(repr) - } - } - - impl Default for Mpt { - fn default() -> Self { - Self::from_hashed_partial_trie(&HashedPartialTrie::default()) - } - } - - #[derive(PartialEq, Eq, PartialOrd, Ord)] - struct MptPath(Vec); - - impl fmt::Display for MptPath { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self(v) = self; - for u in v { - f.write_fmt(format_args!("{u:x}"))? - } - Ok(()) - } - } - impl Serialize for MptPath { - fn serialize(&self, serializer: S) -> Result { - serializer.collect_str(self) - } - } - - impl FromIterator for MptPath { - fn from_iter>(iter: II) -> Self { - Self(iter.into_iter().collect()) - } - } - - #[derive(PartialEq)] - enum MptNode { - Empty, - Hash(H256), - Value(Vec), - } - - impl fmt::Display for MptNode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - MptNode::Empty => f.write_str("empty"), - MptNode::Hash(h) => { - f.write_fmt(format_args!("hash:{}", h.as_bytes().encode_hex::())) - } - MptNode::Value(v) => { - f.write_fmt(format_args!("value:{}", v.encode_hex::())) - } - } - } - } - - impl Serialize for MptNode { - fn serialize(&self, serializer: S) -> Result { - serializer.collect_str(self) - } - } - - fn visit(path: Stack, hpt: &HashedPartialTrie, repr: &mut BTreeMap) { - let key = path.iter().copied().collect(); - match &**hpt { - Node::Empty => { - repr.insert(key, MptNode::Empty); - } - Node::Hash(it) => { - repr.insert(key, MptNode::Hash(*it)); - } - Node::Branch { children, value } => { - for (ix, child) in children.iter().enumerate() { - visit(path.pushed(U4::new(ix as u8).unwrap()), child, repr) - } - if !value.is_empty() { - repr.insert(key, MptNode::Value(value.clone())); - } - } - Node::Extension { nibbles, child } => { - path.with_all(iter_nibbles(*nibbles), |path| visit(*path, child, repr)) - } - Node::Leaf { nibbles, value } => path.with_all(iter_nibbles(*nibbles), |path| { - repr.insert( - path.iter().copied().collect(), - MptNode::Value(value.clone()), - ); - }), - } - } - - fn iter_nibbles(mut nibbles: Nibbles) -> impl Iterator { - iter::from_fn(move || match nibbles.count { - 0 => None, - _ => Some(U4::new(nibbles.pop_next_nibble_back()).unwrap()), - }) - } - - mod hex { - pub mod slice { - pub fn serialize( - it: &[impl hex::ToHex], - serializer: S, - ) -> Result { - serializer.collect_seq(it.iter().map(|it| it.encode_hex::())) - } - } - pub mod btree_map { - use std::collections::BTreeMap; - - use serde::{ser::SerializeMap as _, Serialize}; - - pub fn serialize( - it: &BTreeMap, - serializer: S, - ) -> Result { - let mut serializer = serializer.serialize_map(Some(it.len()))?; - for (k, v) in it { - serializer.serialize_entry(k, &v.encode_hex::())?; - } - serializer.end() - } - } - } -} From 325b27f995f5bc56fea258c638923ad8f6db8357 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 00:13:09 +0100 Subject: [PATCH 31/56] fix: withdrawals on empty txns --- Cargo.lock | 1 + trace_decoder/Cargo.toml | 1 + trace_decoder/examples/dump.rs | 2 +- trace_decoder/src/imp.rs | 8 +++++--- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 621516fde..df8b769bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5149,6 +5149,7 @@ dependencies = [ "camino", "ciborium", "ciborium-io", + "clap", "copyvec", "criterion", "either", diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 3b67e51fa..79400e5a9 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -46,6 +46,7 @@ alloy = { workspace = true } alloy-compat = "0.1.0" assert2 = "0.3.15" camino = "1.1.9" +clap.workspace = true criterion = { workspace = true } glob = "0.3.1" libtest-mimic = "0.7.3" diff --git a/trace_decoder/examples/dump.rs b/trace_decoder/examples/dump.rs index dfa416585..70743d346 100644 --- a/trace_decoder/examples/dump.rs +++ b/trace_decoder/examples/dump.rs @@ -50,7 +50,7 @@ fn main() -> anyhow::Result<()> { }, )| { entrypoint(block_trace, other_data, batch_size, use_burn_addr) - .context(format!("couldn't prove input at {ix}")) + .context(format!("couldn't decode input at {ix}")) }, ) .map_ok(|it| { diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 90eb2192f..27ba8de65 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -294,8 +294,9 @@ fn middle( let mut out = vec![]; - let mut curr_txn_ix = 0; - let len_txns = batches.iter().flatten().count(); + let mut curr_txn_ix = 0; // incremented for non-dummy transactions + let mut loop_ix = 0; // always incremented + let loop_len = batches.iter().flatten().count(); for batch in batches { let batch_first_txn_ix = curr_txn_ix; // GOTCHA: if there are no transactions in this batch let mut batch_gas_used = 0; @@ -457,6 +458,7 @@ fn middle( if increment_txn_ix { curr_txn_ix += 1; } + loop_ix += 1; } // txn in batch out.push(Batch { @@ -464,7 +466,7 @@ fn middle( gas_used: batch_gas_used, contract_code: batch_contract_code, byte_code: batch_byte_code, - withdrawals: match curr_txn_ix == len_txns { + withdrawals: match loop_ix == loop_len { true => { for (addr, amt) in &withdrawals { state_mask.insert(TrieKey::from_address(*addr)); From 08620629d9a0a7ba27fe739934c68523a3f6998c Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 00:18:43 +0100 Subject: [PATCH 32/56] chore: trace_decoder::iface --- trace_decoder/src/iface.rs | 185 +++++++++++++++++++++++++++++++++++ trace_decoder/src/lib.rs | 191 ++----------------------------------- 2 files changed, 193 insertions(+), 183 deletions(-) create mode 100644 trace_decoder/src/iface.rs diff --git a/trace_decoder/src/iface.rs b/trace_decoder/src/iface.rs new file mode 100644 index 000000000..47d273239 --- /dev/null +++ b/trace_decoder/src/iface.rs @@ -0,0 +1,185 @@ +//! Public types for this crate. +//! +//! These are all in one place because they're about to be refactored away. + +use std::collections::{BTreeMap, BTreeSet, HashMap}; + +use ethereum_types::{Address, U256}; +use evm_arithmetization::proof::{BlockHashes, BlockMetadata}; +use keccak_hash::H256; +use mpt_trie::partial_trie::HashedPartialTrie; +use serde::{Deserialize, Serialize}; + +/// Core payload needed to generate proof for a block. +/// Additional data retrievable from the blockchain node (using standard ETH RPC +/// API) may be needed for proof generation. +/// +/// The trie preimages are the hashed partial tries at the +/// start of the block. A [TxnInfo] contains all the transaction data +/// necessary to generate an IR. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct BlockTrace { + /// The state and storage trie pre-images (i.e. the tries before + /// the execution of the current block) in multiple possible formats. + pub trie_pre_images: BlockTraceTriePreImages, + + /// A collection of contract code. + /// This will be accessed by its hash internally. + #[serde(default)] + pub code_db: BTreeSet>, + + /// Traces and other info per transaction. The index of the transaction + /// within the block corresponds to the slot in this vec. + pub txn_info: Vec, +} + +/// Minimal hashed out tries needed by all txns in the block. +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum BlockTraceTriePreImages { + /// The trie pre-image with separate state/storage tries. + Separate(SeparateTriePreImages), + /// The trie pre-image with combined state/storage tries. + Combined(CombinedPreImages), +} + +/// State/Storage trie pre-images that are separate. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct SeparateTriePreImages { + /// State trie. + pub state: SeparateTriePreImage, + /// Storage trie. + pub storage: SeparateStorageTriesPreImage, +} + +/// A trie pre-image where state & storage are separate. +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum SeparateTriePreImage { + /// Storage or state trie format that can be processed as is, as it + /// corresponds to the internal format. + Direct(HashedPartialTrie), +} + +/// A trie pre-image where both state & storage are combined into one payload. +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub struct CombinedPreImages { + /// Compact combined state and storage tries. + #[serde(with = "crate::hex")] + pub compact: Vec, +} + +/// A trie pre-image where state and storage are separate. +#[derive(Clone, Debug, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum SeparateStorageTriesPreImage { + /// Each storage trie is sent over in a hashmap with the hashed account + /// address as a key. + MultipleTries(HashMap), +} + +/// Info specific to txns in the block. +#[derive(Clone, Debug, Deserialize, Serialize, Default)] +pub struct TxnInfo { + /// Trace data for the txn. This is used by the protocol to: + /// - Mutate it's own trie state between txns to arrive at the correct trie + /// state for the start of each txn. + /// - Create minimal partial tries needed for proof gen based on what state + /// the txn accesses. (eg. What trie nodes are accessed). + pub traces: BTreeMap, + + /// Data that is specific to the txn as a whole. + pub meta: TxnMeta, +} + +/// Structure holding metadata for one transaction. +#[derive(Clone, Debug, Deserialize, Serialize, Default)] +pub struct TxnMeta { + /// Txn byte code. This is also the raw RLP bytestring inserted into the txn + /// trie by this txn. Note that the key is not included and this is only + /// the rlped value of the node! + #[serde(with = "crate::hex")] + pub byte_code: Vec, + + /// Rlped bytes of the new receipt value inserted into the receipt trie by + /// this txn. Note that the key is not included and this is only the rlped + /// value of the node! + #[serde(with = "crate::hex")] + pub new_receipt_trie_node_byte: Vec, + + /// Gas used by this txn (Note: not cumulative gas used). + pub gas_used: u64, +} + +/// A "trace" specific to an account for a txn. +/// +/// Specifically, since we can not execute the txn before proof generation, we +/// rely on a separate EVM to run the txn and supply this data for us. +#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] +pub struct TxnTrace { + /// If the balance changed, then the new balance will appear here. Will be + /// `None` if no change. + #[serde(skip_serializing_if = "Option::is_none")] + pub balance: Option, + + /// If the nonce changed, then the new nonce will appear here. Will be + /// `None` if no change. + #[serde(skip_serializing_if = "Option::is_none")] + pub nonce: Option, + + /// [hash](hash)([Address]) of storages read by the + /// transaction. + #[serde(default, skip_serializing_if = "BTreeSet::is_empty")] + pub storage_read: BTreeSet, + + /// [hash](hash)([Address]) of storages written by the + /// transaction, with their new value. + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] + pub storage_written: BTreeMap, + + /// Contract code that this account has accessed or created + #[serde(skip_serializing_if = "Option::is_none")] + pub code_usage: Option, + + /// True if the account got self-destructed at the end of this txn. + #[serde(default, skip_serializing_if = "is_false")] + pub self_destructed: bool, +} + +fn is_false(b: &bool) -> bool { + !b +} + +/// Contract code access type. Used by txn traces. +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +#[serde(rename_all = "snake_case")] +pub enum ContractCodeUsage { + /// Contract was read. + Read(H256), + + /// Contract was created (and these are the bytes). Note that this new + /// contract code will not appear in the [`BlockTrace`] map. + Write(#[serde(with = "crate::hex")] Vec), +} + +/// Other data that is needed for proof gen. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct OtherBlockData { + /// Data that is specific to the block. + pub b_data: BlockLevelData, + /// State trie root hash at the checkpoint. + pub checkpoint_state_trie_root: H256, +} + +/// Data that is specific to a block and is constant for all txns in a given +/// block. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct BlockLevelData { + /// All block data excluding block hashes and withdrawals. + pub b_meta: BlockMetadata, + /// Block hashes: the previous 256 block hashes and the current block hash. + pub b_hashes: BlockHashes, + /// Block withdrawal addresses and values. + pub withdrawals: Vec<(Address, U256)>, +} diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index 6eecb6fbe..0adef3915 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -82,6 +82,10 @@ /// code. const _DEVELOPER_DOCS: () = (); +mod iface; + +pub use iface::*; + /// Defines the main functions used to generate the IR. mod decoding; /// Defines functions that processes a [BlockTrace] so that it is easier to turn @@ -96,196 +100,17 @@ mod type2; mod typed_mpt; mod wire; -use std::collections::{BTreeMap, BTreeSet, HashMap}; +use std::collections::HashMap; -use ethereum_types::{Address, U256}; -use evm_arithmetization::proof::{BlockHashes, BlockMetadata}; +pub use entrypoint_new as entrypoint; use evm_arithmetization::GenerationInputs; +pub use imp::entrypoint as entrypoint_new; use keccak_hash::keccak as hash; use keccak_hash::H256; -use mpt_trie::partial_trie::{HashedPartialTrie, OnOrphanedHashNode}; +use mpt_trie::partial_trie::OnOrphanedHashNode; use processed_block_trace::ProcessedTxnBatchInfo; -use serde::{Deserialize, Serialize}; use typed_mpt::{StateMpt, StateTrie as _, StorageTrie, TrieKey}; -/// Core payload needed to generate proof for a block. -/// Additional data retrievable from the blockchain node (using standard ETH RPC -/// API) may be needed for proof generation. -/// -/// The trie preimages are the hashed partial tries at the -/// start of the block. A [TxnInfo] contains all the transaction data -/// necessary to generate an IR. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct BlockTrace { - /// The state and storage trie pre-images (i.e. the tries before - /// the execution of the current block) in multiple possible formats. - pub trie_pre_images: BlockTraceTriePreImages, - - /// A collection of contract code. - /// This will be accessed by its hash internally. - #[serde(default)] - pub code_db: BTreeSet>, - - /// Traces and other info per transaction. The index of the transaction - /// within the block corresponds to the slot in this vec. - pub txn_info: Vec, -} - -/// Minimal hashed out tries needed by all txns in the block. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -pub enum BlockTraceTriePreImages { - /// The trie pre-image with separate state/storage tries. - Separate(SeparateTriePreImages), - /// The trie pre-image with combined state/storage tries. - Combined(CombinedPreImages), -} - -/// State/Storage trie pre-images that are separate. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct SeparateTriePreImages { - /// State trie. - pub state: SeparateTriePreImage, - /// Storage trie. - pub storage: SeparateStorageTriesPreImage, -} - -/// A trie pre-image where state & storage are separate. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -pub enum SeparateTriePreImage { - /// Storage or state trie format that can be processed as is, as it - /// corresponds to the internal format. - Direct(HashedPartialTrie), -} - -/// A trie pre-image where both state & storage are combined into one payload. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -pub struct CombinedPreImages { - /// Compact combined state and storage tries. - #[serde(with = "crate::hex")] - pub compact: Vec, -} - -/// A trie pre-image where state and storage are separate. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(rename_all = "snake_case")] -pub enum SeparateStorageTriesPreImage { - /// Each storage trie is sent over in a hashmap with the hashed account - /// address as a key. - MultipleTries(HashMap), -} - -/// Info specific to txns in the block. -#[derive(Clone, Debug, Deserialize, Serialize, Default)] -pub struct TxnInfo { - /// Trace data for the txn. This is used by the protocol to: - /// - Mutate it's own trie state between txns to arrive at the correct trie - /// state for the start of each txn. - /// - Create minimal partial tries needed for proof gen based on what state - /// the txn accesses. (eg. What trie nodes are accessed). - pub traces: BTreeMap, - - /// Data that is specific to the txn as a whole. - pub meta: TxnMeta, -} - -/// Structure holding metadata for one transaction. -#[derive(Clone, Debug, Deserialize, Serialize, Default)] -pub struct TxnMeta { - /// Txn byte code. This is also the raw RLP bytestring inserted into the txn - /// trie by this txn. Note that the key is not included and this is only - /// the rlped value of the node! - #[serde(with = "crate::hex")] - pub byte_code: Vec, - - /// Rlped bytes of the new receipt value inserted into the receipt trie by - /// this txn. Note that the key is not included and this is only the rlped - /// value of the node! - #[serde(with = "crate::hex")] - pub new_receipt_trie_node_byte: Vec, - - /// Gas used by this txn (Note: not cumulative gas used). - pub gas_used: u64, -} - -/// A "trace" specific to an account for a txn. -/// -/// Specifically, since we can not execute the txn before proof generation, we -/// rely on a separate EVM to run the txn and supply this data for us. -#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialEq)] -pub struct TxnTrace { - /// If the balance changed, then the new balance will appear here. Will be - /// `None` if no change. - #[serde(skip_serializing_if = "Option::is_none")] - pub balance: Option, - - /// If the nonce changed, then the new nonce will appear here. Will be - /// `None` if no change. - #[serde(skip_serializing_if = "Option::is_none")] - pub nonce: Option, - - /// [hash](hash)([Address]) of storages read by the - /// transaction. - #[serde(default, skip_serializing_if = "BTreeSet::is_empty")] - pub storage_read: BTreeSet, - - /// [hash](hash)([Address]) of storages written by the - /// transaction, with their new value. - #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub storage_written: BTreeMap, - - /// Contract code that this account has accessed or created - #[serde(skip_serializing_if = "Option::is_none")] - pub code_usage: Option, - - /// True if the account got self-destructed at the end of this txn. - #[serde(default, skip_serializing_if = "is_false")] - pub self_destructed: bool, -} - -fn is_false(b: &bool) -> bool { - !b -} - -/// Contract code access type. Used by txn traces. -#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] -#[serde(rename_all = "snake_case")] -pub enum ContractCodeUsage { - /// Contract was read. - Read(H256), - - /// Contract was created (and these are the bytes). Note that this new - /// contract code will not appear in the [`BlockTrace`] map. - Write(#[serde(with = "crate::hex")] Vec), -} - -/// Other data that is needed for proof gen. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct OtherBlockData { - /// Data that is specific to the block. - pub b_data: BlockLevelData, - /// State trie root hash at the checkpoint. - pub checkpoint_state_trie_root: H256, -} - -/// Data that is specific to a block and is constant for all txns in a given -/// block. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct BlockLevelData { - /// All block data excluding block hashes and withdrawals. - pub b_meta: BlockMetadata, - /// Block hashes: the previous 256 block hashes and the current block hash. - pub b_hashes: BlockHashes, - /// Block withdrawal addresses and values. - pub withdrawals: Vec<(Address, U256)>, -} - -// pub use entrypoint_old as entrypoint; -pub use entrypoint_new as entrypoint; -pub use imp::entrypoint as entrypoint_new; - mod imp; /// TODO(0xaatif): From 432e223f8a450e8a1928fba2b2ef3fab2150fa43 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 00:32:29 +0100 Subject: [PATCH 33/56] refactor: remove old impl --- trace_decoder/examples/dump.rs | 316 --------- trace_decoder/src/decoding.rs | 710 --------------------- trace_decoder/src/iface.rs | 2 +- trace_decoder/src/imp.rs | 64 +- trace_decoder/src/lib.rs | 206 +----- trace_decoder/src/processed_block_trace.rs | 304 --------- trace_decoder/src/type1.rs | 4 +- trace_decoder/src/typed_mpt.rs | 62 +- 8 files changed, 114 insertions(+), 1554 deletions(-) delete mode 100644 trace_decoder/examples/dump.rs delete mode 100644 trace_decoder/src/decoding.rs delete mode 100644 trace_decoder/src/processed_block_trace.rs diff --git a/trace_decoder/examples/dump.rs b/trace_decoder/examples/dump.rs deleted file mode 100644 index 70743d346..000000000 --- a/trace_decoder/examples/dump.rs +++ /dev/null @@ -1,316 +0,0 @@ -use std::io; - -use anyhow::Context; -use itertools::Itertools; - -#[derive(clap::Parser)] -struct Args { - #[arg(long)] - method: Method, - #[arg(long, default_value_t = 1)] - batch_size: usize, - #[arg(long)] - use_burn_addr: bool, - #[arg(long)] - pretty: bool, - #[arg(long)] - quiet: bool, -} - -#[derive(clap::ValueEnum, Clone)] -enum Method { - Old, - New, -} - -fn main() -> anyhow::Result<()> { - let Args { - method, - batch_size, - use_burn_addr, - pretty, - quiet, - } = clap::Parser::parse(); - - let entrypoint = match method { - Method::Old => trace_decoder::entrypoint_old as fn(_, _, _, _) -> anyhow::Result<_>, - Method::New => trace_decoder::entrypoint_new as _, - }; - - let out = Input::into_iter(serde_path_to_error::deserialize( - &mut serde_json::Deserializer::from_reader(io::stdin()), - )?) - .enumerate() - .map( - |( - ix, - prover::BlockProverInput { - block_trace, - other_data, - }, - )| { - entrypoint(block_trace, other_data, batch_size, use_burn_addr) - .context(format!("couldn't decode input at {ix}")) - }, - ) - .map_ok(|it| { - Vec::into_iter(it) - .map(repr::GenerationInputs::from) - .collect::>() - }) - .collect::, _>>()?; - - if !quiet { - let printer = match pretty { - true => serde_json::to_writer_pretty as fn(_, _) -> _, - false => serde_json::to_writer as _, - }; - - printer(io::stdout(), &out)?; - } - - Ok(()) -} - -#[derive(serde::Deserialize)] -#[serde(untagged)] -enum Input { - One(T), - Many(Vec), -} - -impl Input { - fn into_iter(self) -> impl Iterator { - match self { - Input::One(it) => vec![it].into_iter(), - Input::Many(it) => it.into_iter(), - } - } -} - -mod repr { - use std::{collections::BTreeMap, fmt, iter}; - - use ethereum_types::{Address, U256}; - use evm_arithmetization::{ - generation::TrieInputs, - proof::{BlockHashes, BlockMetadata, TrieRoots}, - }; - use hex::ToHex as _; - use keccak_hash::H256; - use mpt_trie::{ - nibbles::Nibbles, - partial_trie::{HashedPartialTrie, Node}, - }; - use serde::{Serialize, Serializer}; - use stackstack::Stack; - use u4::U4; - - #[derive(Serialize, PartialEq)] - pub struct GenerationInputs { - txn_number: U256, - gas_before: U256, - gas_after: U256, - #[serde(with = "crate::hex::slice")] - txns: Vec>, - withdrawals: Vec<(Address, U256)>, - exit_roots: Vec<(U256, H256)>, - - state: Mpt, - transaction: Mpt, - receipts: Mpt, - storage: BTreeMap, - - checkpoint_root: H256, - state_root: H256, - transaction_root: H256, - receipt_root: H256, - - #[serde(with = "crate::hex::btree_map")] - contract_code: BTreeMap>, - meta: BlockMetadata, - hashes: BlockHashes, - - #[serde(skip_serializing_if = "Option::is_none")] - burn_addr: Option
, - } - - impl From for GenerationInputs { - fn from(value: evm_arithmetization::generation::GenerationInputs) -> Self { - let evm_arithmetization::generation::GenerationInputs { - txn_number_before, - gas_used_before, - gas_used_after, - signed_txns, - withdrawals, - global_exit_roots, - tries: - TrieInputs { - state_trie, - transactions_trie, - receipts_trie, - storage_tries, - }, - trie_roots_after: - TrieRoots { - state_root, - transactions_root, - receipts_root, - }, - checkpoint_state_trie_root, - contract_code, - block_metadata, - block_hashes, - burn_addr, - } = value; - Self { - txn_number: txn_number_before, - gas_before: gas_used_before, - gas_after: gas_used_after, - txns: signed_txns, - withdrawals, - exit_roots: global_exit_roots, - state: Mpt::from_hashed_partial_trie(&state_trie), - transaction: Mpt::from_hashed_partial_trie(&transactions_trie), - receipts: Mpt::from_hashed_partial_trie(&receipts_trie), - storage: storage_tries - .into_iter() - .map(|(k, v)| (k, Mpt::from_hashed_partial_trie(&v))) - .collect(), - state_root, - transaction_root: transactions_root, - receipt_root: receipts_root, - contract_code: contract_code.into_iter().collect(), - meta: block_metadata, - hashes: block_hashes, - checkpoint_root: checkpoint_state_trie_root, - burn_addr, - } - } - } - - #[derive(Serialize, PartialEq)] - struct Mpt(BTreeMap); - - impl Mpt { - pub fn from_hashed_partial_trie(hpt: &HashedPartialTrie) -> Self { - let mut repr = BTreeMap::new(); - visit(Stack::new(), hpt, &mut repr); - Self(repr) - } - } - - #[derive(PartialEq, Eq, PartialOrd, Ord)] - struct MptPath(Vec); - - impl fmt::Display for MptPath { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self(v) = self; - for u in v { - f.write_fmt(format_args!("{u:x}"))? - } - Ok(()) - } - } - impl Serialize for MptPath { - fn serialize(&self, serializer: S) -> Result { - serializer.collect_str(self) - } - } - - impl FromIterator for MptPath { - fn from_iter>(iter: II) -> Self { - Self(iter.into_iter().collect()) - } - } - - #[derive(PartialEq)] - enum MptNode { - Empty, - Hash(H256), - Value(Vec), - } - - impl fmt::Display for MptNode { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - MptNode::Empty => f.write_str("empty"), - MptNode::Hash(h) => { - f.write_fmt(format_args!("hash:{}", h.as_bytes().encode_hex::())) - } - MptNode::Value(v) => { - f.write_fmt(format_args!("value:{}", v.encode_hex::())) - } - } - } - } - - impl Serialize for MptNode { - fn serialize(&self, serializer: S) -> Result { - serializer.collect_str(self) - } - } - - fn visit(path: Stack, hpt: &HashedPartialTrie, repr: &mut BTreeMap) { - let key = path.iter().copied().collect(); - match &**hpt { - Node::Empty => { - repr.insert(key, MptNode::Empty); - } - Node::Hash(it) => { - repr.insert(key, MptNode::Hash(*it)); - } - Node::Branch { children, value } => { - for (ix, child) in children.iter().enumerate() { - visit(path.pushed(U4::new(ix as u8).unwrap()), child, repr) - } - if !value.is_empty() { - repr.insert(key, MptNode::Value(value.clone())); - } - } - Node::Extension { nibbles, child } => { - path.with_all(iter_nibbles(*nibbles), |path| visit(*path, child, repr)) - } - Node::Leaf { nibbles, value } => path.with_all(iter_nibbles(*nibbles), |path| { - repr.insert( - path.iter().copied().collect(), - MptNode::Value(value.clone()), - ); - }), - } - } - - fn iter_nibbles(mut nibbles: Nibbles) -> impl Iterator { - iter::from_fn(move || match nibbles.count { - 0 => None, - _ => Some(U4::new(nibbles.pop_next_nibble_back()).unwrap()), - }) - } -} - -mod hex { - pub mod slice { - pub fn serialize( - it: &[impl hex::ToHex], - serializer: S, - ) -> Result { - serializer.collect_seq(it.iter().map(|it| it.encode_hex::())) - } - } - pub mod btree_map { - use std::collections::BTreeMap; - - use serde::{ser::SerializeMap as _, Serialize}; - - pub fn serialize( - it: &BTreeMap, - serializer: S, - ) -> Result { - let mut serializer = serializer.serialize_map(Some(it.len()))?; - for (k, v) in it { - serializer.serialize_entry(k, &v.encode_hex::())?; - } - serializer.end() - } - } -} diff --git a/trace_decoder/src/decoding.rs b/trace_decoder/src/decoding.rs deleted file mode 100644 index ebb293b2c..000000000 --- a/trace_decoder/src/decoding.rs +++ /dev/null @@ -1,710 +0,0 @@ -use std::{cmp::min, collections::HashMap, ops::Range}; - -use anyhow::{anyhow, Context as _}; -use ethereum_types::H160; -use ethereum_types::{Address, BigEndianHash, H256, U256, U512}; -use evm_arithmetization::{ - generation::{ - mpt::{decode_receipt, AccountRlp}, - GenerationInputs, TrieInputs, - }, - proof::{BlockMetadata, ExtraBlockData, TrieRoots}, - testing_utils::{ - BEACON_ROOTS_CONTRACT_ADDRESS, BEACON_ROOTS_CONTRACT_ADDRESS_HASHED, HISTORY_BUFFER_LENGTH, - }, -}; -use mpt_trie::{ - nibbles::Nibbles, - partial_trie::{HashedPartialTrie, PartialTrie as _}, - special_query::path_for_query, - trie_ops::TrieOpError, - utils::{IntoTrieKey as _, TriePath}, -}; - -use crate::{ - hash, - processed_block_trace::{ - NodesUsedByTxnBatch, ProcessedBlockTrace, ProcessedTxnBatchInfo, StateWrite, TxnMetaState, - }, - typed_mpt::{ReceiptTrie, StateTrie, StorageTrie, TransactionTrie, TrieKey}, - OtherBlockData, PartialTriePreImages, TryIntoExt as TryIntoBounds, -}; - -/// The current state of all tries as we process txn deltas. These are mutated -/// after every txn we process in the trace. -#[derive(Clone, Debug, Default)] -struct PartialTrieState { - state: StateTrieT, - storage: HashMap, - txn: TransactionTrie, - receipt: ReceiptTrie, -} - -/// Additional information discovered during delta application. -#[derive(Debug, Default)] -struct TrieDeltaApplicationOutput { - // During delta application, if a delete occurs, we may have to make sure additional nodes - // that are not accessed by the txn remain unhashed. - additional_state_trie_paths_to_not_hash: Vec, - additional_storage_trie_paths_to_not_hash: HashMap>, -} - -pub fn into_txn_proof_gen_ir( - ProcessedBlockTrace { - tries: PartialTriePreImages { state, storage }, - txn_info, - withdrawals, - }: ProcessedBlockTrace, - other_data: OtherBlockData, - use_burn_addr: bool, - batch_size: usize, -) -> anyhow::Result> { - let mut curr_block_tries = PartialTrieState { - state: state.clone(), - storage: storage.iter().map(|(k, v)| (*k, v.clone())).collect(), - ..Default::default() - }; - - let mut extra_data = ExtraBlockData { - checkpoint_state_trie_root: other_data.checkpoint_state_trie_root, - txn_number_before: U256::zero(), - txn_number_after: U256::zero(), - gas_used_before: U256::zero(), - gas_used_after: U256::zero(), - }; - - let num_txs = txn_info - .iter() - .map(|tx_info| tx_info.meta.len()) - .sum::(); - - let mut txn_gen_inputs = txn_info - .into_iter() - .enumerate() - .map(|(txn_idx, txn_info)| { - let txn_range = - min(txn_idx * batch_size, num_txs)..min(txn_idx * batch_size + batch_size, num_txs); - let is_initial_payload = txn_range.start == 0; - - process_txn_info( - txn_range.clone(), - is_initial_payload, - txn_info, - &mut curr_block_tries, - &mut extra_data, - &other_data, - use_burn_addr, - ) - .context(format!( - "at transaction range {}..{}", - txn_range.start, txn_range.end - )) - }) - .collect::>>() - .context(format!( - "at block num {} with chain id {}", - other_data.b_data.b_meta.block_number, other_data.b_data.b_meta.block_chain_id - ))?; - - if !withdrawals.is_empty() { - add_withdrawals_to_txns(&mut txn_gen_inputs, &mut curr_block_tries, withdrawals)?; - } - - Ok(txn_gen_inputs) -} - -/// Cancun HF specific: At the start of a block, prior txn execution, we -/// need to update the storage of the beacon block root contract. -// See . -fn update_beacon_block_root_contract_storage( - trie_state: &mut PartialTrieState, - delta_out: &mut TrieDeltaApplicationOutput, - nodes_used: &mut NodesUsedByTxnBatch, - block_data: &BlockMetadata, -) -> anyhow::Result<()> { - const HISTORY_BUFFER_LENGTH_MOD: U256 = U256([HISTORY_BUFFER_LENGTH.1, 0, 0, 0]); - - let timestamp_idx = block_data.block_timestamp % HISTORY_BUFFER_LENGTH_MOD; - let timestamp = rlp::encode(&block_data.block_timestamp).to_vec(); - - let root_idx = timestamp_idx + HISTORY_BUFFER_LENGTH_MOD; - let calldata = rlp::encode(&U256::from_big_endian( - &block_data.parent_beacon_block_root.0, - )) - .to_vec(); - - let storage_trie = trie_state - .storage - .get_mut(&BEACON_ROOTS_CONTRACT_ADDRESS_HASHED) - .context(format!( - "missing account storage trie for address {:x}", - BEACON_ROOTS_CONTRACT_ADDRESS - ))?; - - let slots_nibbles = nodes_used - .storage_accesses - .entry(BEACON_ROOTS_CONTRACT_ADDRESS_HASHED) - .or_default(); - - for (ix, val) in [(timestamp_idx, timestamp), (root_idx, calldata)] { - // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 - // document this - let slot = TrieKey::from_nibbles(Nibbles::from_h256_be(hash( - Nibbles::from_h256_be(H256::from_uint(&ix)).bytes_be(), - ))); - - slots_nibbles.push(slot); - - // If we are writing a zero, then we actually need to perform a delete. - match val == ZERO_STORAGE_SLOT_VAL_RLPED { - false => { - storage_trie.insert(slot, val.clone()).context(format!( - "at slot {:?} with value {}", - slot, - U512::from_big_endian(val.as_slice()) - ))?; - - delta_out - .additional_storage_trie_paths_to_not_hash - .entry(BEACON_ROOTS_CONTRACT_ADDRESS_HASHED) - .or_default() - .push(slot); - } - true => { - if let Ok(Some(remaining_slot_key)) = - delete_node_and_report_remaining_key_if_branch_collapsed( - storage_trie.as_mut_hashed_partial_trie_unchecked(), - &slot, - ) - { - delta_out - .additional_storage_trie_paths_to_not_hash - .entry(BEACON_ROOTS_CONTRACT_ADDRESS_HASHED) - .or_default() - .push(remaining_slot_key); - } - } - } - } - - delta_out - .additional_state_trie_paths_to_not_hash - .push(TrieKey::from_hash(BEACON_ROOTS_CONTRACT_ADDRESS_HASHED)); - let mut account = trie_state - .state - .get_by_address(BEACON_ROOTS_CONTRACT_ADDRESS) - .context(format!( - "missing account storage trie for address {:x}", - BEACON_ROOTS_CONTRACT_ADDRESS - ))?; - - account.storage_root = storage_trie.root(); - - trie_state - .state - .insert_by_address(BEACON_ROOTS_CONTRACT_ADDRESS, account) - // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 - // Add an entry API - .expect("insert must succeed with the same key as a successful `get`"); - - Ok(()) -} - -fn update_txn_and_receipt_tries( - trie_state: &mut PartialTrieState, - meta: &TxnMetaState, - txn_idx: usize, -) -> anyhow::Result<()> { - if let Some(bytes) = &meta.txn_bytes { - trie_state.txn.insert(txn_idx, bytes.clone())?; - trie_state - .receipt - .insert(txn_idx, meta.receipt_node_bytes.clone())?; - } // else it's just a dummy - Ok(()) -} - -/// If the account does not have a storage trie or does but is not -/// accessed by any txns, then we still need to manually create an entry for -/// them. -fn init_any_needed_empty_storage_tries<'a>( - storage_tries: &mut HashMap, - accounts_with_storage: impl Iterator, - accts_with_unaccessed_storage: &HashMap, -) { - for h_addr in accounts_with_storage { - if !storage_tries.contains_key(h_addr) { - let trie = accts_with_unaccessed_storage - .get(h_addr) - .map(|s_root| { - let mut it = StorageTrie::default(); - it.insert_hash(TrieKey::default(), *s_root) - .expect("empty trie insert cannot fail"); - it - }) - .unwrap_or_default(); - - storage_tries.insert(*h_addr, trie); - }; - } -} - -fn create_minimal_partial_tries_needed_by_txn( - curr_block_tries: &PartialTrieState>, - nodes_used_by_txn: &NodesUsedByTxnBatch, - txn_range: Range, - delta_application_out: TrieDeltaApplicationOutput, -) -> anyhow::Result { - let mut state_trie = curr_block_tries.state.clone(); - state_trie.trim_to( - nodes_used_by_txn - .state_accesses - .iter() - .map(|it| TrieKey::from_address(*it)) - .chain(delta_application_out.additional_state_trie_paths_to_not_hash), - )?; - - let txn_keys = txn_range.map(TrieKey::from_txn_ix); - - let transactions_trie = create_trie_subset_wrapped( - curr_block_tries.txn.as_hashed_partial_trie(), - txn_keys.clone(), - TrieType::Txn, - )?; - - let receipts_trie = create_trie_subset_wrapped( - curr_block_tries.receipt.as_hashed_partial_trie(), - txn_keys, - TrieType::Receipt, - )?; - - let storage_tries = create_minimal_storage_partial_tries( - &curr_block_tries.storage, - &nodes_used_by_txn.storage_accesses, - &delta_application_out.additional_storage_trie_paths_to_not_hash, - )?; - - Ok(TrieInputs { - state_trie: state_trie.try_into()?, - transactions_trie, - receipts_trie, - storage_tries, - }) -} - -fn apply_deltas_to_trie_state( - trie_state: &mut PartialTrieState, - deltas: &NodesUsedByTxnBatch, - meta: &[TxnMetaState], -) -> anyhow::Result { - let mut out = TrieDeltaApplicationOutput::default(); - - for (hashed_acc_addr, storage_writes) in deltas.storage_writes.iter() { - let storage_trie = trie_state - .storage - .get_mut(hashed_acc_addr) - .context(format!( - "missing account storage trie {:x}", - hashed_acc_addr - ))?; - - for (key, val) in storage_writes { - let slot = TrieKey::from_hash(hash(key.into_nibbles().bytes_be())); - // If we are writing a zero, then we actually need to perform a delete. - match val == &ZERO_STORAGE_SLOT_VAL_RLPED { - false => { - storage_trie.insert(slot, val.clone()).context(format!( - "at slot {:?} with value {}", - slot, - U512::from_big_endian(val.as_slice()) - ))?; - } - true => { - if let Some(remaining_slot_key) = - delete_node_and_report_remaining_key_if_branch_collapsed( - storage_trie.as_mut_hashed_partial_trie_unchecked(), - &slot, - )? - { - out.additional_storage_trie_paths_to_not_hash - .entry(*hashed_acc_addr) - .or_default() - .push(remaining_slot_key); - } - } - }; - } - } - - for (addr, state_write) in &deltas.state_writes { - // If the account was created, then it will not exist in the trie yet. - let is_created = !trie_state.state.contains_address(*addr); - let mut account = trie_state.state.get_by_address(*addr).unwrap_or_default(); - - state_write.apply_writes_to_state_node(&mut account, &hash(addr), &trie_state.storage)?; - - trie_state.state.insert_by_address(*addr, account)?; - - if is_created { - // If the account did not exist prior this transaction, we - // need to make sure the transaction didn't revert. - - // We will check the status of the last receipt that attempted to create the - // account in this batch. - let last_creation_receipt = &meta - .iter() - .rev() - .find(|tx| tx.created_accounts.contains(addr)) - .expect("We should have found a matching transaction") - .receipt_node_bytes; - - let (_, _, receipt) = decode_receipt(last_creation_receipt) - .map_err(|_| anyhow!("couldn't RLP-decode receipt node bytes"))?; - - if !receipt.status { - // The transaction failed, hence any created account should be removed. - if let Some(remaining_account_key) = trie_state.state.reporting_remove(*addr)? { - out.additional_state_trie_paths_to_not_hash - .push(remaining_account_key); - trie_state.storage.remove(&hash(addr)); - continue; - } - } - } - } - - // Remove any accounts that self-destructed. - for addr in deltas.self_destructed_accounts.iter() { - trie_state.storage.remove(&hash(addr)); - - if let Some(remaining_account_key) = trie_state.state.reporting_remove(*addr)? { - out.additional_state_trie_paths_to_not_hash - .push(remaining_account_key); - } - } - - Ok(out) -} - -fn get_trie_trace(trie: &HashedPartialTrie, k: &Nibbles) -> TriePath { - path_for_query(trie, *k, true).collect() -} - -/// If a branch collapse occurred after a delete, then we must ensure that -/// the other single child that remains also is not hashed when passed into -/// plonky2. Returns the key to the remaining child if a collapse occurred. -pub fn delete_node_and_report_remaining_key_if_branch_collapsed( - trie: &mut HashedPartialTrie, - key: &TrieKey, -) -> Result, TrieOpError> { - let key = key.into_nibbles(); - let old_trace = get_trie_trace(trie, &key); - trie.delete(key)?; - let new_trace = get_trie_trace(trie, &key); - Ok( - node_deletion_resulted_in_a_branch_collapse(&old_trace, &new_trace) - .map(TrieKey::from_nibbles), - ) -} - -/// Comparing the path of the deleted key before and after the deletion, -/// determine if the deletion resulted in a branch collapsing into a leaf or -/// extension node, and return the path to the remaining child if this -/// occurred. -fn node_deletion_resulted_in_a_branch_collapse( - old_path: &TriePath, - new_path: &TriePath, -) -> Option { - // Collapse requires at least 2 nodes. - if old_path.0.len() < 2 { - return None; - } - - // If the node path length decreased after the delete, then a collapse occurred. - // As an aside, note that while it's true that the branch could have collapsed - // into an extension node with multiple nodes below it, the query logic will - // always stop at most one node after the keys diverge, which guarantees that - // the new trie path will always be shorter if a collapse occurred. - let branch_collapse_occurred = old_path.0.len() > new_path.0.len(); - - // Now we need to determine the key of the only remaining node after the - // collapse. - branch_collapse_occurred.then(|| new_path.iter().into_key()) -} - -/// The withdrawals are always in the final ir payload. -fn add_withdrawals_to_txns( - txn_ir: &mut [GenerationInputs], - final_trie_state: &mut PartialTrieState< - impl StateTrie + Clone + TryIntoBounds, - >, - mut withdrawals: Vec<(Address, U256)>, -) -> anyhow::Result<()> { - // Scale withdrawals amounts. - for (_addr, amt) in withdrawals.iter_mut() { - *amt = eth_to_gwei(*amt) - } - - let withdrawals_with_hashed_addrs_iter = || { - withdrawals - .iter() - .map(|(addr, v)| (*addr, hash(addr.as_bytes()), *v)) - }; - - let last_inputs = txn_ir - .last_mut() - .expect("We cannot have an empty list of payloads."); - - if last_inputs.signed_txns.is_empty() { - let mut state_trie = final_trie_state.state.clone(); - state_trie.trim_to( - // This is a dummy payload, hence it does not contain yet - // state accesses to the withdrawal addresses. - withdrawals - .iter() - .map(|(addr, _)| *addr) - .chain(match last_inputs.txn_number_before == 0.into() { - // We need to include the beacon roots contract as this payload is at the - // start of the block execution. - true => Some(BEACON_ROOTS_CONTRACT_ADDRESS), - false => None, - }) - .map(TrieKey::from_address), - )?; - last_inputs.tries.state_trie = state_trie.try_into()?; - } - - update_trie_state_from_withdrawals( - withdrawals_with_hashed_addrs_iter(), - &mut final_trie_state.state, - )?; - - last_inputs.withdrawals = withdrawals; - last_inputs.trie_roots_after.state_root = final_trie_state.state.clone().try_into()?.hash(); - - Ok(()) -} - -/// Withdrawals update balances in the account trie, so we need to update -/// our local trie state. -fn update_trie_state_from_withdrawals<'a>( - withdrawals: impl IntoIterator + 'a, - state: &mut impl StateTrie, -) -> anyhow::Result<()> { - for (addr, h_addr, amt) in withdrawals { - let mut acc_data = state.get_by_address(addr).context(format!( - "No account present at {addr:x} (hashed: {h_addr:x}) to withdraw {amt} Gwei from!" - ))?; - - acc_data.balance += amt; - - state - .insert_by_address(addr, acc_data) - // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 - // Add an entry API - .expect("insert must succeed with the same key as a successful `get`"); - } - - Ok(()) -} - -/// Processes a single transaction in the trace. -fn process_txn_info( - txn_range: Range, - is_initial_payload: bool, - txn_info: ProcessedTxnBatchInfo, - curr_block_tries: &mut PartialTrieState< - impl StateTrie + Clone + TryIntoBounds, - >, - extra_data: &mut ExtraBlockData, - other_data: &OtherBlockData, - use_burn_target: bool, -) -> anyhow::Result { - log::trace!( - "Generating proof IR for txn {} through {}...", - txn_range.start, - txn_range.end - 1 - ); - - init_any_needed_empty_storage_tries( - &mut curr_block_tries.storage, - txn_info.nodes_used_by_txn.storage_accesses.keys(), - &txn_info.nodes_used_by_txn.accts_with_unaccessed_storage, - ); - - // For each non-dummy txn, we increment `txn_number_after` and - // update `gas_used_after` accordingly. - extra_data.txn_number_after += txn_info.meta.len().into(); - extra_data.gas_used_after += txn_info.meta.iter().map(|i| i.gas_used).sum::().into(); - - // Because we need to run delta application before creating the minimal - // sub-tries (we need to detect if deletes collapsed any branches), we need to - // do this clone every iteration. - let tries_at_start_of_txn = curr_block_tries.clone(); - - for (i, meta) in txn_info.meta.iter().enumerate() { - update_txn_and_receipt_tries( - curr_block_tries, - meta, - extra_data.txn_number_before.as_usize() + i, - )?; - } - - let mut delta_out = apply_deltas_to_trie_state( - curr_block_tries, - &txn_info.nodes_used_by_txn, - &txn_info.meta, - )?; - - let nodes_used_by_txn = if is_initial_payload { - let mut nodes_used = txn_info.nodes_used_by_txn; - update_beacon_block_root_contract_storage( - curr_block_tries, - &mut delta_out, - &mut nodes_used, - &other_data.b_data.b_meta, - )?; - - nodes_used - } else { - txn_info.nodes_used_by_txn - }; - - let tries = create_minimal_partial_tries_needed_by_txn( - &tries_at_start_of_txn, - &nodes_used_by_txn, - txn_range, - delta_out, - )?; - - let burn_addr = match use_burn_target { - // TODO: https://github.com/0xPolygonZero/zk_evm/issues/565 - // Retrieve the actual burn address from `cdk-erigon`. - true => Some(H160::zero()), - false => None, - }; - let gen_inputs = GenerationInputs { - txn_number_before: extra_data.txn_number_before, - burn_addr, - gas_used_before: extra_data.gas_used_before, - gas_used_after: extra_data.gas_used_after, - signed_txns: txn_info - .meta - .iter() - .filter_map(|t| t.txn_bytes.clone()) - .collect::>(), - withdrawals: Vec::default(), /* Only ever set in a dummy txn at the end of - * the block (see `[add_withdrawals_to_txns]` - * for more info). */ - tries, - trie_roots_after: TrieRoots { - state_root: curr_block_tries.state.clone().try_into()?.hash(), - transactions_root: curr_block_tries.txn.root(), - receipts_root: curr_block_tries.receipt.root(), - }, - checkpoint_state_trie_root: extra_data.checkpoint_state_trie_root, - contract_code: txn_info - .contract_code_accessed - .into_iter() - .map(|code| (hash(&code), code)) - .collect(), - block_metadata: other_data.b_data.b_meta.clone(), - block_hashes: other_data.b_data.b_hashes.clone(), - global_exit_roots: vec![], - }; - - // After processing a transaction, we update the remaining accumulators - // for the next transaction. - extra_data.txn_number_before = extra_data.txn_number_after; - extra_data.gas_used_before = extra_data.gas_used_after; - - Ok(gen_inputs) -} - -impl StateWrite { - fn apply_writes_to_state_node( - &self, - state_node: &mut AccountRlp, - h_addr: &H256, - acc_storage_tries: &HashMap, - ) -> anyhow::Result<()> { - let storage_root_hash_change = match self.storage_trie_change { - false => None, - true => { - let storage_trie = acc_storage_tries - .get(h_addr) - .context(format!("missing account storage trie {:x}", h_addr))?; - - Some(storage_trie.root()) - } - }; - - state_node.balance = self.balance.unwrap_or(state_node.balance); - state_node.nonce = self.nonce.unwrap_or(state_node.nonce); - state_node.storage_root = storage_root_hash_change.unwrap_or(state_node.storage_root); - state_node.code_hash = self.code_hash.unwrap_or(state_node.code_hash); - - Ok(()) - } -} - -// TODO!!!: We really need to be appending the empty storage tries to the base -// trie somewhere else! This is a big hack! -fn create_minimal_storage_partial_tries<'a>( - storage_tries: &HashMap, - accesses_per_account: impl IntoIterator)>, - additional_storage_trie_paths_to_not_hash: &HashMap>, -) -> anyhow::Result> { - accesses_per_account - .into_iter() - .map(|(h_addr, mem_accesses)| { - // Guaranteed to exist due to calling `init_any_needed_empty_storage_tries` - // earlier on. - let base_storage_trie = &storage_tries[h_addr]; - - let storage_slots_to_not_hash = mem_accesses.iter().cloned().chain( - additional_storage_trie_paths_to_not_hash - .get(h_addr) - .into_iter() - .flat_map(|slots| slots.iter().cloned()), - ); - - let partial_storage_trie = create_trie_subset_wrapped( - base_storage_trie.as_hashed_partial_trie(), - storage_slots_to_not_hash, - TrieType::Storage, - )?; - - Ok((*h_addr, partial_storage_trie)) - }) - .collect() -} - -fn create_trie_subset_wrapped( - trie: &HashedPartialTrie, - accesses: impl IntoIterator, - trie_type: TrieType, -) -> anyhow::Result { - mpt_trie::trie_subsets::create_trie_subset( - trie, - accesses.into_iter().map(TrieKey::into_nibbles), - ) - .context(format!("missing keys when creating {}", trie_type)) -} - -pub fn eth_to_gwei(eth: U256) -> U256 { - // 1 ether = 10^9 gwei. - eth * U256::from(10).pow(9.into()) -} - -// This is just `rlp(0)`. -const ZERO_STORAGE_SLOT_VAL_RLPED: [u8; 1] = [128]; - -/// Aid for error context. -#[derive(Debug, strum::Display)] -#[allow(missing_docs)] -enum TrieType { - Storage, - Receipt, - Txn, -} diff --git a/trace_decoder/src/iface.rs b/trace_decoder/src/iface.rs index 47d273239..faff3a8a9 100644 --- a/trace_decoder/src/iface.rs +++ b/trace_decoder/src/iface.rs @@ -1,6 +1,6 @@ //! Public types for this crate. //! -//! These are all in one place because they're about to be refactored away. +//! These are all in one place because they're about to be heavily refactored. use std::collections::{BTreeMap, BTreeSet, HashMap}; diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 27ba8de65..fc72d3288 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -1,12 +1,12 @@ use std::{ cmp, - collections::{BTreeMap, BTreeSet}, + collections::{BTreeMap, BTreeSet, HashMap}, mem, ops::Range, }; use alloy_compat::Compat as _; -use anyhow::{anyhow, ensure, Context as _}; +use anyhow::{anyhow, bail, ensure, Context as _}; use ethereum_types::{Address, U256}; use evm_arithmetization::{ generation::{mpt::AccountRlp, TrieInputs}, @@ -20,8 +20,6 @@ use mpt_trie::partial_trie::PartialTrie as _; use nunny::NonEmpty; use crate::{ - decoding::eth_to_gwei, - processed_block_trace::{map_receipt_bytes, Hash2Code}, typed_mpt::{ReceiptTrie, StateMpt, StateTrie, StorageTrie, TransactionTrie, TrieKey}, BlockLevelData, BlockTrace, BlockTraceTriePreImages, CombinedPreImages, ContractCodeUsage, OtherBlockData, SeparateStorageTriesPreImage, SeparateTriePreImage, SeparateTriePreImages, @@ -567,3 +565,61 @@ fn cancun_hook( // TODO(0xaatif): is this _meant_ to exclude the final member? const PRECOMPILE_ADDRESS_RANGE: Range = U256([1, 0, 0, 0])..U256([10, 0, 0, 0]); + +fn eth_to_gwei(eth: U256) -> U256 { + // 1 ether = 10^9 gwei. + eth * U256::from(10).pow(9.into()) +} + +fn map_receipt_bytes(bytes: Vec) -> anyhow::Result> { + match rlp::decode::(&bytes) { + Ok(_) => Ok(bytes), + Err(_) => { + rlp::decode(&bytes).context("couldn't decode receipt as a legacy receipt or raw bytes") + } + } +} + +/// Code hash mappings that we have constructed from parsing the block +/// trace. +/// If there are any txns that create contracts, then they will also +/// get added here as we process the deltas. +struct Hash2Code { + /// Key must always be [`hash`] of value. + inner: HashMap>, +} + +impl Hash2Code { + pub fn new() -> Self { + let mut this = Self { + inner: HashMap::new(), + }; + this.insert(vec![]); + this + } + pub fn get(&mut self, hash: H256) -> anyhow::Result> { + match self.inner.get(&hash) { + Some(code) => Ok(code.clone()), + None => bail!("no code for hash {}", hash), + } + } + pub fn insert(&mut self, code: Vec) { + self.inner.insert(keccak_hash::keccak(&code), code); + } +} + +impl Extend> for Hash2Code { + fn extend>>(&mut self, iter: II) { + for it in iter { + self.insert(it) + } + } +} + +impl FromIterator> for Hash2Code { + fn from_iter>>(iter: II) -> Self { + let mut this = Self::new(); + this.extend(iter); + this + } +} diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index 0adef3915..31d3219a5 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -86,11 +86,6 @@ mod iface; pub use iface::*; -/// Defines the main functions used to generate the IR. -mod decoding; -/// Defines functions that processes a [BlockTrace] so that it is easier to turn -/// the block transactions into IRs. -mod processed_block_trace; mod type1; // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 // add backend/prod support for type 2 @@ -100,192 +95,10 @@ mod type2; mod typed_mpt; mod wire; -use std::collections::HashMap; - -pub use entrypoint_new as entrypoint; -use evm_arithmetization::GenerationInputs; -pub use imp::entrypoint as entrypoint_new; -use keccak_hash::keccak as hash; -use keccak_hash::H256; -use mpt_trie::partial_trie::OnOrphanedHashNode; -use processed_block_trace::ProcessedTxnBatchInfo; -use typed_mpt::{StateMpt, StateTrie as _, StorageTrie, TrieKey}; +pub use imp::entrypoint; mod imp; -/// TODO(0xaatif): -/// document this once we have the API finalized -pub fn entrypoint_old( - trace: BlockTrace, - other: OtherBlockData, - mut batch_size: usize, - use_burn_addr: bool, -) -> anyhow::Result> { - use anyhow::Context as _; - use mpt_trie::partial_trie::PartialTrie as _; - - use crate::processed_block_trace::{ - Hash2Code, ProcessedBlockTrace, ProcessedBlockTracePreImages, - }; - use crate::PartialTriePreImages; - use crate::{ - BlockTraceTriePreImages, CombinedPreImages, SeparateStorageTriesPreImage, - SeparateTriePreImage, SeparateTriePreImages, - }; - - let BlockTrace { - trie_pre_images, - code_db, - txn_info, - } = trace; - - let pre_images = match trie_pre_images { - BlockTraceTriePreImages::Separate(SeparateTriePreImages { - state: SeparateTriePreImage::Direct(state), - storage: SeparateStorageTriesPreImage::MultipleTries(storage), - }) => ProcessedBlockTracePreImages { - tries: PartialTriePreImages { - state: state.items().try_fold( - StateMpt::new(OnOrphanedHashNode::Reject), - |mut acc, (nibbles, hash_or_val)| { - let path = TrieKey::from_nibbles(nibbles); - match hash_or_val { - mpt_trie::trie_ops::ValOrHash::Val(bytes) => { - #[expect(deprecated)] // this is MPT specific - acc.insert_by_hashed_address( - path.into_hash() - .context("invalid path length in direct state trie")?, - rlp::decode(&bytes) - .context("invalid AccountRlp in direct state trie")?, - )?; - } - mpt_trie::trie_ops::ValOrHash::Hash(h) => { - acc.insert_hash_by_key(path, h)?; - } - }; - anyhow::Ok(acc) - }, - )?, - storage: storage - .into_iter() - .map(|(k, SeparateTriePreImage::Direct(v))| { - v.items() - .try_fold( - StorageTrie::new(OnOrphanedHashNode::Reject), - |mut acc, (nibbles, hash_or_val)| { - let path = TrieKey::from_nibbles(nibbles); - match hash_or_val { - mpt_trie::trie_ops::ValOrHash::Val(value) => { - acc.insert(path, value)?; - } - mpt_trie::trie_ops::ValOrHash::Hash(h) => { - acc.insert_hash(path, h)?; - } - }; - anyhow::Ok(acc) - }, - ) - .map(|v| (k, v)) - }) - .collect::>()?, - }, - extra_code_hash_mappings: None, - }, - BlockTraceTriePreImages::Combined(CombinedPreImages { compact }) => { - let instructions = - wire::parse(&compact).context("couldn't parse instructions from binary format")?; - let type1::Frontend { - state, - code, - storage, - } = type1::frontend(instructions)?; - ProcessedBlockTracePreImages { - tries: PartialTriePreImages { - state, - storage: storage.into_iter().collect(), - }, - extra_code_hash_mappings: match code.is_empty() { - true => None, - false => Some( - code.into_iter() - .map(|it| (crate::hash(&it), it.into_vec())) - .collect(), - ), - }, - } - } - }; - - let all_accounts_in_pre_images = pre_images.tries.state.iter().collect::>(); - - // Note we discard any user-provided hashes. - let mut hash2code = code_db - .into_iter() - .chain( - pre_images - .extra_code_hash_mappings - .unwrap_or_default() - .into_values(), - ) - .collect::(); - - // Make sure the batch size is smaller than the total number of transactions, - // or we would need to generate dummy proofs for the aggregation layers. - if batch_size > txn_info.len() { - batch_size = txn_info.len() / 2 + 1; - } - - let last_tx_idx = txn_info.len().saturating_sub(1) / batch_size; - - let mut txn_info = txn_info - .chunks(batch_size) - .enumerate() - .map(|(i, t)| { - let extra_state_accesses = if last_tx_idx == i { - // If this is the last transaction, we mark the withdrawal addresses - // as accessed in the state trie. - other - .b_data - .withdrawals - .iter() - .map(|(addr, _)| *addr) - .collect::>() - } else { - Vec::new() - }; - - TxnInfo::into_processed_txn_info( - t, - &pre_images.tries, - &all_accounts_in_pre_images, - &extra_state_accesses, - &mut hash2code, - ) - }) - .collect::, _>>()?; - - while txn_info.len() < 2 { - txn_info.push(ProcessedTxnBatchInfo::default()); - } - - decoding::into_txn_proof_gen_ir( - ProcessedBlockTrace { - tries: pre_images.tries, - txn_info, - withdrawals: other.b_data.withdrawals.clone(), - }, - other, - use_burn_addr, - batch_size, - ) -} - -#[derive(Debug, Default)] -struct PartialTriePreImages { - pub state: StateMpt, - pub storage: HashMap, -} - /// Like `#[serde(with = "hex")`, but tolerates and emits leading `0x` prefixes mod hex { use serde::{de::Error as _, Deserialize as _, Deserializer, Serializer}; @@ -312,23 +125,6 @@ mod hex { } } -trait TryIntoExt { - type Error: std::error::Error + Send + Sync + 'static; - fn try_into(self) -> Result; -} - -impl TryIntoExt for ThisT -where - ThisT: TryInto, - E: std::error::Error + Send + Sync + 'static, -{ - type Error = ThisT::Error; - - fn try_into(self) -> Result { - TryInto::try_into(self) - } -} - #[cfg(test)] #[derive(serde::Deserialize)] struct Case { diff --git a/trace_decoder/src/processed_block_trace.rs b/trace_decoder/src/processed_block_trace.rs deleted file mode 100644 index 8027acb60..000000000 --- a/trace_decoder/src/processed_block_trace.rs +++ /dev/null @@ -1,304 +0,0 @@ -use std::collections::{BTreeSet, HashMap, HashSet}; - -use anyhow::{bail, Context as _}; -use ethereum_types::{Address, H256, U256}; -use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; -use itertools::Itertools; -use zk_evm_common::EMPTY_TRIE_HASH; - -use crate::typed_mpt::{StateTrie as _, TrieKey}; -use crate::PartialTriePreImages; -use crate::{hash, TxnTrace}; -use crate::{ContractCodeUsage, TxnInfo}; - -const FIRST_PRECOMPILE_ADDRESS: U256 = U256([1, 0, 0, 0]); -const LAST_PRECOMPILE_ADDRESS: U256 = U256([10, 0, 0, 0]); - -/// A processed block trace, ready to be used to generate prover input payloads. -#[derive(Debug)] -pub(crate) struct ProcessedBlockTrace { - pub tries: PartialTriePreImages, - pub txn_info: Vec, - pub withdrawals: Vec<(Address, U256)>, -} - -#[derive(Debug)] -pub(crate) struct ProcessedBlockTracePreImages { - pub tries: PartialTriePreImages, - pub extra_code_hash_mappings: Option>>, -} - -/// A processed transaction batch, containing all information necessary to -/// reproduce the state transition incurred by its set of transactions. -#[derive(Debug, Default)] -pub(crate) struct ProcessedTxnBatchInfo { - pub nodes_used_by_txn: NodesUsedByTxnBatch, - pub contract_code_accessed: HashSet>, - pub meta: Vec, -} - -/// Code hash mappings that we have constructed from parsing the block -/// trace. -/// If there are any txns that create contracts, then they will also -/// get added here as we process the deltas. -pub(crate) struct Hash2Code { - /// Key must always be [`hash`] of value. - inner: HashMap>, -} - -impl Hash2Code { - pub fn new() -> Self { - let mut this = Self { - inner: HashMap::new(), - }; - this.insert(vec![]); - this - } - pub fn get(&mut self, hash: H256) -> anyhow::Result> { - match self.inner.get(&hash) { - Some(code) => Ok(code.clone()), - None => bail!("no code for hash {}", hash), - } - } - pub fn insert(&mut self, code: Vec) { - self.inner.insert(hash(&code), code); - } -} - -impl Extend> for Hash2Code { - fn extend>>(&mut self, iter: II) { - for it in iter { - self.insert(it) - } - } -} - -impl FromIterator> for Hash2Code { - fn from_iter>>(iter: II) -> Self { - let mut this = Self::new(); - this.extend(iter); - this - } -} - -impl TxnInfo { - pub(crate) fn into_processed_txn_info( - tx_infos: &[Self], - tries: &PartialTriePreImages, - all_accounts_in_pre_image: &[(H256, AccountRlp)], - extra_state_accesses: &[Address], - hash2code: &mut Hash2Code, - ) -> anyhow::Result { - let mut nodes_used_by_txn = NodesUsedByTxnBatch::default(); - let mut contract_code_accessed = HashSet::from([vec![]]); // we always "access" empty code - let mut meta = Vec::with_capacity(tx_infos.len()); - - let all_accounts: BTreeSet = - all_accounts_in_pre_image.iter().map(|(h, _)| *h).collect(); - - for txn in tx_infos { - let mut created_accounts = BTreeSet::new(); - - for ( - addr, - TxnTrace { - balance, - nonce, - storage_read, - storage_written, - code_usage, - self_destructed, - }, - ) in &txn.traces - { - // record storage changes - let storage_written = storage_written.clone(); - - let storage_read_keys = storage_read.clone().into_iter(); - - let storage_written_keys = storage_written.keys(); - let storage_access_keys = storage_read_keys.chain(storage_written_keys.copied()); - - if let Some(storage) = nodes_used_by_txn.storage_accesses.get_mut(&hash(addr)) { - storage.extend( - storage_access_keys - .map(|H256(bytes)| TrieKey::from_hash(hash(bytes))) - .collect_vec(), - ) - } else { - nodes_used_by_txn.storage_accesses.insert( - hash(addr), - storage_access_keys - .map(|H256(bytes)| TrieKey::from_hash(hash(bytes))) - .collect(), - ); - }; - - // record state changes - let state_write = StateWrite { - balance: *balance, - nonce: *nonce, - storage_trie_change: !storage_written.is_empty(), - code_hash: code_usage.as_ref().map(|it| match it { - ContractCodeUsage::Read(hash) => *hash, - ContractCodeUsage::Write(bytes) => hash(bytes), - }), - }; - - if state_write != StateWrite::default() { - // a write occurred - - // Account creations are flagged to handle reverts. - if !all_accounts.contains(&hash(addr)) { - created_accounts.insert(*addr); - } - - // Some edge case may see a contract creation followed by a `SELFDESTRUCT`, with - // then a follow-up transaction within the same batch updating the state of the - // account. If that happens, we should not delete the account after processing - // this batch. - nodes_used_by_txn.self_destructed_accounts.remove(addr); - - if let Some(existing_state_write) = nodes_used_by_txn.state_writes.get_mut(addr) - { - // The entry already exists, so we update only the relevant fields. - if state_write.balance.is_some() { - existing_state_write.balance = state_write.balance; - } - if state_write.nonce.is_some() { - existing_state_write.nonce = state_write.nonce; - } - if state_write.storage_trie_change { - existing_state_write.storage_trie_change = - state_write.storage_trie_change; - } - if state_write.code_hash.is_some() { - existing_state_write.code_hash = state_write.code_hash; - } - } else { - nodes_used_by_txn.state_writes.insert(*addr, state_write); - } - } - - for (k, v) in storage_written.into_iter() { - if let Some(storage) = nodes_used_by_txn.storage_writes.get_mut(&hash(addr)) { - storage.insert(TrieKey::from_hash(k), rlp::encode(&v).to_vec()); - } else { - nodes_used_by_txn.storage_writes.insert( - hash(addr), - HashMap::from_iter([(TrieKey::from_hash(k), rlp::encode(&v).to_vec())]), - ); - } - } - - let is_precompile = (FIRST_PRECOMPILE_ADDRESS..LAST_PRECOMPILE_ADDRESS) - .contains(&U256::from_big_endian(&addr.0)); - - // Trie witnesses will only include accessed precompile accounts as hash - // nodes if the transaction calling them reverted. If this is the case, we - // shouldn't include them in this transaction's `state_accesses` to allow the - // decoder to build a minimal state trie without hitting any hash node. - if !is_precompile || tries.state.get_by_address(*addr).is_some() { - nodes_used_by_txn.state_accesses.insert(*addr); - } - - match code_usage { - Some(ContractCodeUsage::Read(hash)) => { - contract_code_accessed.insert(hash2code.get(*hash)?); - } - Some(ContractCodeUsage::Write(code)) => { - contract_code_accessed.insert(code.clone()); - hash2code.insert(code.to_vec()); - } - None => {} - } - - if *self_destructed { - nodes_used_by_txn.self_destructed_accounts.insert(*addr); - } - } - - for &addr in extra_state_accesses { - nodes_used_by_txn.state_accesses.insert(addr); - } - - let accounts_with_storage_accesses = nodes_used_by_txn - .storage_accesses - .iter() - .filter(|(_, slots)| !slots.is_empty()) - .map(|(addr, _)| *addr) - .collect::>(); - - let all_accounts_with_non_empty_storage = all_accounts_in_pre_image - .iter() - .filter(|(_, data)| data.storage_root != EMPTY_TRIE_HASH); - - let accounts_with_storage_but_no_storage_accesses = all_accounts_with_non_empty_storage - .filter(|&(addr, _data)| !accounts_with_storage_accesses.contains(addr)) - .map(|(addr, data)| (*addr, data.storage_root)); - - nodes_used_by_txn - .accts_with_unaccessed_storage - .extend(accounts_with_storage_but_no_storage_accesses); - - meta.push(TxnMetaState { - txn_bytes: match txn.meta.byte_code.is_empty() { - false => Some(txn.meta.byte_code.clone()), - true => None, - }, - receipt_node_bytes: map_receipt_bytes(txn.meta.new_receipt_trie_node_byte.clone())?, - gas_used: txn.meta.gas_used, - created_accounts, - }); - } - - Ok(ProcessedTxnBatchInfo { - nodes_used_by_txn, - contract_code_accessed, - meta, - }) - } -} - -pub fn map_receipt_bytes(bytes: Vec) -> anyhow::Result> { - match rlp::decode::(&bytes) { - Ok(_) => Ok(bytes), - Err(_) => { - rlp::decode(&bytes).context("couldn't decode receipt as a legacy receipt or raw bytes") - } - } -} - -/// A collection of all the state and storage accesses performed by a batch of -/// transaction. -/// -/// Note that "*_accesses" fields include writes. -#[derive(Debug, Default)] -pub(crate) struct NodesUsedByTxnBatch { - pub state_accesses: HashSet
, - pub state_writes: HashMap, - - pub storage_accesses: HashMap>, - pub storage_writes: HashMap>>, - - /// Hashed address -> storage root. - pub accts_with_unaccessed_storage: HashMap, - pub self_destructed_accounts: HashSet
, -} - -#[derive(Debug, Default, PartialEq)] -pub(crate) struct StateWrite { - pub balance: Option, - pub nonce: Option, - pub storage_trie_change: bool, - pub code_hash: Option, -} - -#[derive(Debug, Default)] -pub(crate) struct TxnMetaState { - /// [`None`] if this is a dummy transaction inserted for padding. - pub txn_bytes: Option>, - pub receipt_node_bytes: Vec, - pub gas_used: u64, - pub created_accounts: BTreeSet
, -} diff --git a/trace_decoder/src/type1.rs b/trace_decoder/src/type1.rs index 019a75c95..aeea0dbb6 100644 --- a/trace_decoder/src/type1.rs +++ b/trace_decoder/src/type1.rs @@ -97,11 +97,11 @@ fn visit( match code { Some(Either::Left(Hash { raw_hash })) => raw_hash.into(), Some(Either::Right(Code { code })) => { - let hash = crate::hash(&code); + let hash = keccak_hash::keccak(&code); frontend.code.insert(code); hash } - None => crate::hash([]), + None => keccak_hash::keccak([]), } }, }; diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index c26991da3..1170509bf 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -319,7 +319,7 @@ impl StateTrie for StateMpt { account: AccountRlp, ) -> anyhow::Result> { #[expect(deprecated)] - self.insert_by_hashed_address(crate::hash(address), account) + self.insert_by_hashed_address(keccak_hash::keccak(address), account) } /// Insert a deferred part of the trie fn insert_hash_by_key(&mut self, key: TrieKey, hash: H256) -> anyhow::Result<()> { @@ -332,11 +332,9 @@ impl StateTrie for StateMpt { /// Delete the account at `address`, returning any remaining branch on /// collapse fn reporting_remove(&mut self, address: Address) -> anyhow::Result> { - Ok( - crate::decoding::delete_node_and_report_remaining_key_if_branch_collapsed( - self.typed.as_mut_hashed_partial_trie_unchecked(), - &TrieKey::from_address(address), - )?, + delete_node_and_report_remaining_key_if_branch_collapsed( + self.typed.as_mut_hashed_partial_trie_unchecked(), + TrieKey::from_address(address), ) } fn contains_address(&self, address: Address) -> bool { @@ -444,12 +442,7 @@ impl StorageTrie { &self.untyped } pub fn reporting_remove(&mut self, key: TrieKey) -> anyhow::Result> { - Ok( - crate::decoding::delete_node_and_report_remaining_key_if_branch_collapsed( - &mut self.untyped, - &key, - )?, - ) + delete_node_and_report_remaining_key_if_branch_collapsed(&mut self.untyped, key) } pub fn as_mut_hashed_partial_trie_unchecked(&mut self) -> &mut HashedPartialTrie { &mut self.untyped @@ -469,3 +462,48 @@ impl From for HashedPartialTrie { value.untyped } } + +/// If a branch collapse occurred after a delete, then we must ensure that +/// the other single child that remains also is not hashed when passed into +/// plonky2. Returns the key to the remaining child if a collapse occurred. +fn delete_node_and_report_remaining_key_if_branch_collapsed( + trie: &mut HashedPartialTrie, + key: TrieKey, +) -> anyhow::Result> { + let old_trace = get_trie_trace(trie, key); + trie.delete(key.into_nibbles())?; + let new_trace = get_trie_trace(trie, key); + Ok( + node_deletion_resulted_in_a_branch_collapse(&old_trace, &new_trace) + .map(TrieKey::from_nibbles), + ) +} + +fn get_trie_trace(trie: &HashedPartialTrie, k: TrieKey) -> mpt_trie::utils::TriePath { + mpt_trie::special_query::path_for_query(trie, k.into_nibbles(), true).collect() +} + +/// Comparing the path of the deleted key before and after the deletion, +/// determine if the deletion resulted in a branch collapsing into a leaf or +/// extension node, and return the path to the remaining child if this +/// occurred. +fn node_deletion_resulted_in_a_branch_collapse( + old_path: &mpt_trie::utils::TriePath, + new_path: &mpt_trie::utils::TriePath, +) -> Option { + // Collapse requires at least 2 nodes. + if old_path.0.len() < 2 { + return None; + } + + // If the node path length decreased after the delete, then a collapse occurred. + // As an aside, note that while it's true that the branch could have collapsed + // into an extension node with multiple nodes below it, the query logic will + // always stop at most one node after the keys diverge, which guarantees that + // the new trie path will always be shorter if a collapse occurred. + let branch_collapse_occurred = old_path.0.len() > new_path.0.len(); + + // Now we need to determine the key of the only remaining node after the + // collapse. + branch_collapse_occurred.then(|| mpt_trie::utils::IntoTrieKey::into_key(new_path.iter())) +} From aa0f425ba8a55d848e097e55434f19a369ee94a3 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 00:33:03 +0100 Subject: [PATCH 34/56] chore: rename ci --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5af8dd057..030d3c1a0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,7 @@ jobs: RUST_BACKTRACE: 1 test_trace_decoder: - name: test trace_decoder + name: Test trace_decoder runs-on: zero-ci timeout-minutes: 30 env: From 6cc97ad352618c9287458bdbad478c661ba435e4 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 00:35:36 +0100 Subject: [PATCH 35/56] refactor: trim_to -> mask --- trace_decoder/src/imp.rs | 10 ++++------ trace_decoder/src/typed_mpt.rs | 12 ++++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index fc72d3288..e897d64f4 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -483,11 +483,9 @@ fn middle( false => vec![], }, before: { - before.state.trim_to(state_mask)?; - before.receipt.trim_to(batch_first_txn_ix..curr_txn_ix)?; - before - .transaction - .trim_to(batch_first_txn_ix..curr_txn_ix)?; + before.state.mask(state_mask)?; + before.receipt.mask(batch_first_txn_ix..curr_txn_ix)?; + before.transaction.mask(batch_first_txn_ix..curr_txn_ix)?; let keep = storage_masks .keys() @@ -497,7 +495,7 @@ fn middle( for (addr, mask) in storage_masks { if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { - it.trim_to(mask)? + it.mask(mask)? } // TODO(0xaatif): why is this fallible? } before diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index 1170509bf..722e9bfc2 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -205,7 +205,7 @@ impl TransactionTrie { &self.untyped } /// Defer (hash) parts of the trie that aren't in `txn_ixs`. - pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, txn_ixs @@ -250,7 +250,7 @@ impl ReceiptTrie { &self.untyped } /// Defer (hash) parts of the trie that aren't in `txn_ixs`. - pub fn trim_to(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { + pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, txn_ixs @@ -277,7 +277,7 @@ pub trait StateTrie { fn get_by_address(&self, address: Address) -> Option; fn reporting_remove(&mut self, address: Address) -> anyhow::Result>; fn contains_address(&self, address: Address) -> bool; - fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; + fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; fn iter(&self) -> impl Iterator + '_; fn root(&self) -> H256; } @@ -342,7 +342,7 @@ impl StateTrie for StateMpt { .as_hashed_partial_trie() .contains(TrieKey::from_address(address).into_nibbles()) } - fn trim_to(&mut self, addresses: impl IntoIterator) -> anyhow::Result<()> { + fn mask(&mut self, addresses: impl IntoIterator) -> anyhow::Result<()> { let inner = mpt_trie::trie_subsets::create_trie_subset( self.typed.as_hashed_partial_trie(), addresses.into_iter().map(TrieKey::into_nibbles), @@ -399,7 +399,7 @@ impl StateTrie for StateSmt { fn contains_address(&self, address: Address) -> bool { self.address2state.contains_key(&address) } - fn trim_to(&mut self, address: impl IntoIterator) -> anyhow::Result<()> { + fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()> { let _ = address; Ok(()) } @@ -448,7 +448,7 @@ impl StorageTrie { &mut self.untyped } /// Defer (hash) the parts of the trie that aren't in `paths`. - pub fn trim_to(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { + pub fn mask(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, paths.into_iter().map(TrieKey::into_nibbles), From 457c5f2a96918b23cc39cd7227c831f9425d1d7e Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 01:23:50 +0100 Subject: [PATCH 36/56] doc: librar --- trace_decoder/src/imp.rs | 23 +++++--- trace_decoder/src/lib.rs | 102 ++++++++++++--------------------- trace_decoder/src/typed_mpt.rs | 3 - trace_decoder/src/wire.rs | 4 +- 4 files changed, 55 insertions(+), 77 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index e897d64f4..709614432 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -30,17 +30,15 @@ use crate::{ pub fn entrypoint( trace: BlockTrace, other: OtherBlockData, - batch_size: usize, + batch_size_hint: usize, use_burn_addr: bool, ) -> anyhow::Result> { - ensure!(batch_size != 0); - let BlockTrace { trie_pre_images, code_db, txn_info, } = trace; - let (state, storage, mut code) = start(trie_pre_images)?; + let (state, storage, mut code) = convert(trie_pre_images)?; code.extend(code_db); let OtherBlockData { @@ -53,7 +51,8 @@ pub fn entrypoint( checkpoint_state_trie_root, } = other; - // TODO(0xaatif): docs for the RPC field say this is gwei already... + // TODO(0xaatif): docs for the RPC field say this is gwei already: + // https://docs.rs/alloy/0.3.1/alloy/eips/eip4895/struct.Withdrawal.html#structfield.amount // in any case, this shouldn't be our problem. for (_, amt) in &mut withdrawals { *amt = eth_to_gwei(*amt) @@ -62,7 +61,7 @@ pub fn entrypoint( let batches = middle( state, storage, - batch(txn_info, batch_size), + batch(txn_info, batch_size_hint), &mut code, b_meta.block_timestamp, b_meta.parent_beacon_block_root, @@ -117,7 +116,13 @@ pub fn entrypoint( .collect()) } -fn start( +/// The user has either provided us with a [`serde`]-ed +/// [`HashedPartialTrie`](mpt_trie::partial_trie::HashedPartialTrie), +/// or a [`wire`](crate::wire)-encoded representation of one. +/// +/// Turn either of those into our [`typed_mpt`](crate::typed_mpt) +/// representations. +fn convert( pre_images: BlockTraceTriePreImages, ) -> anyhow::Result<(StateMpt, BTreeMap, Hash2Code)> { Ok(match pre_images { @@ -259,6 +264,10 @@ struct IntraBlockTries { pub receipt: ReceiptTrie, } +/// We have detailed trace information +/// +/// - `state_trie` is the state at the beginning of the block. +/// - `storage` are the storage tries at the beginning of the block. fn middle( // state at the beginning of the block mut state_trie: StateTrieT, diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index 31d3219a5..a14c6c57f 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -1,85 +1,57 @@ -//!
-//! This library is undergoing major refactoring as part of (#275)(https://github.com/0xPolygonZero/zk_evm/issues/275). -//! Consider all TODOs to be tracked under that issue. -//!
+//! An _Ethereum Node_[^1] executes _transactions_ in _blocks_. //! -//! Your neighborhood zk-ready [ethereum](https://github.com/0xPolygonZero/erigon) -//! [node](https://github.com/0xPolygonHermez/cdk-erigon/) emits binary "witnesses"[^1]. +//! Execution mutates two key data structures: +//! - [The state trie](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/#state-trie). +//! - [The storage tries](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-trie/#storage-trie). //! -//! But [`plonky2`], your prover, wants [`GenerationInputs`]. +//! Ethereum nodes expose information about the transactions over RPC, e.g: +//! - [The specific changes to the storage tries](TxnTrace::storage_written). +//! - [Changes to account balance in the state trie](TxnTrace::balance). //! -//! This library helps you get there. +//! The tries and the transactions can be proved to be correct using a +//! zero-knowledge prover like [`evm_arithmetization`], +//! an Ethereum-y frontend for [`plonky2`]. //! -//! [^1]: A witness is an attestation of the state of the world, which can be -//! proven by a prover. +//! **Prover perfomance is a high priority.** //! -//! # Non-Goals -//! - Performance - this won't be the bottleneck in any proving system. -//! - Robustness - malicious or malformed input may crash this library. +//! The aformentioned trie structures may have subtries _deferred_. +//! That is, any node (and its children!) may be replaced by its hash, +//! while maintaining provability of its contents: +//! ```text +//! A A +//! / \ / \ +//! B C -> H C +//! / \ \ \ +//! D E F F +//! ``` +//! (where `H` is the hash of the `D/B\E` subtrie). //! -//! TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 -//! refactor all the docs below +//! The principle concern of this library is to step through the transactions, +//! and reproduce the tries that the Ethereum node does, +//! **while deferring all possible subtries to minimise prover load**, +//! since prover performance is sensitive to the size of the trie. //! -//! It might not be obvious why we need traces for each txn in order to generate -//! proofs. While it's true that we could just run all the txns of a block in an -//! EVM to generate the traces ourselves, there are a few major downsides: -//! - The client is likely a full node and already has to run the txns in an EVM -//! anyways. -//! - We want this protocol to be as agnostic as possible to the underlying -//! chain that we're generating proofs for, and running our own EVM would -//! likely cause us to loose this genericness. +//! [^1]: In our stack, this is (a fork of erigon)[https://github.com/0xPolygonZero/erigon], +//! which exposes more information over RPC. //! -//! While it's also true that we run our own zk-EVM (plonky2) to generate -//! proofs, it's critical that we are able to generate txn proofs in parallel. -//! Since generating proofs with plonky2 is very slow, this would force us to -//! sequentialize the entire proof generation process. So in the end, it's ideal -//! if we can get this information sent to us instead. -//! -//! This library generates an Intermediary Representation (IR) of -//! a block's transactions, given a [BlockTrace] and some additional -//! data represented by [OtherBlockData]. -//! -//! It first preprocesses the [BlockTrace] to provide transaction, -//! withdrawals and tries data that can be directly used to generate an IR. -//! For each transaction, this library extracts the -//! necessary data from the processed transaction information to -//! return the IR. -//! -//! The IR is used to generate root proofs, then aggregation proofs and finally -//! block proofs. Because aggregation proofs require at least two entries, we -//! pad the vector of IRs thanks to additional dummy payload intermediary -//! representations whenever necessary. -//! -//! ### [Withdrawals](https://ethereum.org/staking/withdrawals) and Padding -//! -//! Withdrawals are all proven together in a dummy payload. A dummy payload -//! corresponds to the IR of a proof with no transaction. They must, however, be -//! proven last. The padding is therefore carried out as follows: If there are -//! no transactions in the block, we add two dummy transactions. The withdrawals -//! -- if any -- are added to the second dummy transaction. If there is only one -//! transaction in the block, we add one dummy transaction. If -//! there are withdrawals, the dummy transaction is at the end. Otherwise, it is -//! added at the start. If there are two or more transactions: -//! - if there are no withdrawals, no dummy transactions are added -//! - if there are withdrawals, one dummy transaction is added at the end, with -//! all the withdrawals in it. +//! # Non-goals +//! - Peformance - this will never be the bottleneck in any proving stack. +//! - Robustness - this library depends on other libraries that are not robust, +//! so may panic at any time. #![deny(rustdoc::broken_intra_doc_links)] #![warn(missing_debug_implementations)] #![warn(missing_docs)] -/// The broad overview is as follows: +/// Over RPC, ethereum nodes expose their tries as a series of binary +/// [`wire::Instruction`]s in a node-dependant format. /// -/// 1. Ethereum nodes emit a bunch of binary [`wire::Instruction`]s, which are -/// parsed in [`wire`]. -/// 2. They are passed to one of two "frontends", depending on the node +/// These are parsed into the relevant trie depending on the node: /// - [`type2`], which contains an [`smt_trie`]. /// - [`type1`], which contains an [`mpt_trie`]. -/// 3. The frontend ([`type1::Frontend`] or [`type2::Frontend`]) is passed to -/// the "backend", which lowers to [`evm_arithmetization::GenerationInputs`]. /// -/// Deviations from the specification are signalled with `BUG(spec)` in the -/// code. +/// After getting the tries, +/// we can continue to do the main work of "executing" the transactions. const _DEVELOPER_DOCS: () = (); mod iface; diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index 722e9bfc2..bc615d9ce 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -9,9 +9,6 @@ use evm_arithmetization::generation::mpt::AccountRlp; use mpt_trie::partial_trie::{HashedPartialTrie, Node, OnOrphanedHashNode, PartialTrie as _}; use u4::{AsNibbles, U4}; -/// Map where keys are [up to 64 nibbles](TrieKey), -/// and values are [`rlp::Encodable`]/[`rlp::Decodable`]. -/// /// See . /// /// Portions of the trie may be deferred: see [`Self::insert_hash`]. diff --git a/trace_decoder/src/wire.rs b/trace_decoder/src/wire.rs index 355d30827..6f56f1e44 100644 --- a/trace_decoder/src/wire.rs +++ b/trace_decoder/src/wire.rs @@ -4,7 +4,7 @@ //! //! Fortunately, their opcodes don't conflict, so we can have a single //! [`Instruction`] type, with shared parsing logic in this module, and bail on -//! unsupported instructions later on in the frontend. +//! unsupported instructions later on. //! //! This is fine because we don't care about failing fast when parsing. @@ -68,7 +68,7 @@ pub enum Instruction { AccountLeaf { key: NonEmpty>, nonce: Option, - /// BUG(spec): see decode site [`account_leaf`]. + /// BUG(spec): see parse site [`account_leaf`]. balance: Option, has_code: bool, has_storage: bool, From 5f6cea8d80543b5b468fc26035ba6e33edc9521d Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 03:54:09 +0100 Subject: [PATCH 37/56] refactor: tweak variable names --- trace_decoder/src/imp.rs | 87 +++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 41 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 709614432..1e9eac9b0 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -2,9 +2,9 @@ use std::{ cmp, collections::{BTreeMap, BTreeSet, HashMap}, mem, - ops::Range, }; +use alloy::primitives::address; use alloy_compat::Compat as _; use anyhow::{anyhow, bail, ensure, Context as _}; use ethereum_types::{Address, U256}; @@ -30,15 +30,17 @@ use crate::{ pub fn entrypoint( trace: BlockTrace, other: OtherBlockData, - batch_size_hint: usize, + batch_size: usize, use_burn_addr: bool, ) -> anyhow::Result> { + ensure!(batch_size != 0); + let BlockTrace { trie_pre_images, code_db, txn_info, } = trace; - let (state, storage, mut code) = convert(trie_pre_images)?; + let (state, storage, mut code) = start(trie_pre_images)?; code.extend(code_db); let OtherBlockData { @@ -61,7 +63,7 @@ pub fn entrypoint( let batches = middle( state, storage, - batch(txn_info, batch_size_hint), + batch(txn_info, batch_size), &mut code, b_meta.block_timestamp, b_meta.parent_beacon_block_root, @@ -122,7 +124,7 @@ pub fn entrypoint( /// /// Turn either of those into our [`typed_mpt`](crate::typed_mpt) /// representations. -fn convert( +fn start( pre_images: BlockTraceTriePreImages, ) -> anyhow::Result<(StateMpt, BTreeMap, Hash2Code)> { Ok(match pre_images { @@ -264,26 +266,24 @@ struct IntraBlockTries { pub receipt: ReceiptTrie, } -/// We have detailed trace information -/// -/// - `state_trie` is the state at the beginning of the block. -/// - `storage` are the storage tries at the beginning of the block. +/// Does the main work mentioned in the [module documentation](mod@self). fn middle( // state at the beginning of the block mut state_trie: StateTrieT, // storage at the beginning of the block - mut storage: BTreeMap, + mut storage_tries: BTreeMap, // None represents a dummy transaction that should not increment the transaction index // all batches SHOULD not be empty batches: Vec>>, code: &mut Hash2Code, block_timestamp: U256, parent_beacon_block_root: H256, + // added to final batch mut withdrawals: Vec<(Address, U256)>, ) -> anyhow::Result>> { // Initialise the storage tries. for (haddr, acct) in state_trie.iter() { - let storage = storage.entry(haddr).or_insert({ + let storage = storage_tries.entry(haddr).or_insert({ let mut it = StorageTrie::default(); it.insert_hash(TrieKey::default(), acct.storage_root) .expect("empty trie insert cannot fail"); @@ -301,11 +301,11 @@ fn middle( let mut out = vec![]; - let mut curr_txn_ix = 0; // incremented for non-dummy transactions + let mut txn_ix = 0; // incremented for non-dummy transactions let mut loop_ix = 0; // always incremented let loop_len = batches.iter().flatten().count(); for batch in batches { - let batch_first_txn_ix = curr_txn_ix; // GOTCHA: if there are no transactions in this batch + let batch_first_txn_ix = txn_ix; // GOTCHA: if there are no transactions in this batch let mut batch_gas_used = 0; let mut batch_byte_code = vec![]; let mut batch_contract_code = BTreeSet::from([vec![]]); // always include empty code @@ -314,18 +314,19 @@ fn middle( state: state_trie.clone(), transaction: transaction_trie.clone(), receipt: receipt_trie.clone(), - storage: storage.clone(), + storage: storage_tries.clone(), }; + // We want to trim the TrieInputs above, // but won't know the bounds until after the loop below, // so store that information here. let mut storage_masks = BTreeMap::<_, BTreeSet>::new(); let mut state_mask = BTreeSet::new(); - if curr_txn_ix == 0 { + if txn_ix == 0 { cancun_hook( block_timestamp, - &mut storage, + &mut storage_tries, &mut storage_masks, parent_beacon_block_root, &mut state_mask, @@ -334,7 +335,7 @@ fn middle( } for txn in batch { - let increment_txn_ix = txn.is_some(); + let do_increment_txn_ix = txn.is_some(); let TxnInfo { traces, meta: @@ -344,11 +345,12 @@ fn middle( gas_used: txn_gas_used, }, } = txn.unwrap_or_default(); + if let Ok(nonempty) = nunny::Vec::new(byte_code) { batch_byte_code.push(nonempty.clone()); - transaction_trie.insert(curr_txn_ix, nonempty.into())?; + transaction_trie.insert(txn_ix, nonempty.into())?; receipt_trie.insert( - curr_txn_ix, + txn_ix, map_receipt_bytes(new_receipt_trie_node_byte.clone())?, )?; } @@ -357,7 +359,7 @@ fn middle( for ( addr, - empty, + just_access, TxnTrace { balance, nonce, @@ -366,10 +368,14 @@ fn middle( code_usage, self_destructed, }, - ) in traces - .into_iter() - .map(|(addr, trc)| (addr, trc == TxnTrace::default(), trc)) - { + ) in traces.into_iter().map(|(addr, trc)| { + ( + addr, + // This is our fork of Erigon's way of letting us know + trc == TxnTrace::default(), + trc, + ) + }) { // - created and failed // - access the state trie, no change to storage trie // - created and self destructed @@ -380,15 +386,15 @@ fn middle( .map(|acct| (acct, false)) .unwrap_or((AccountRlp::default(), true)); - let commit = match born { - false => !empty, + let do_writes = match born { + false => !just_access, true => { let (_, _, receipt) = evm_arithmetization::generation::mpt::decode_receipt( &map_receipt_bytes(new_receipt_trie_node_byte.clone())?, ) .map_err(|e| anyhow!("{e:?}")) .context("couldn't decode receipt")?; - receipt.status && !empty + receipt.status && !just_access } // if txn failed, don't commit changes to trie }; @@ -401,7 +407,7 @@ fn middle( .map(|it| TrieKey::from_hash(keccak_hash::keccak(it))), ); - if commit { + if do_writes { acct.balance = balance.unwrap_or(acct.balance); acct.nonce = nonce.unwrap_or(acct.nonce); acct.code_hash = code_usage @@ -422,8 +428,8 @@ fn middle( if !storage_written.is_empty() { let storage = match born { - true => storage.entry(keccak_hash::keccak(addr)).or_default(), - false => storage + true => storage_tries.entry(keccak_hash::keccak(addr)).or_default(), + false => storage_tries .get_mut(&keccak_hash::keccak(addr)) .context(format!("missing storage trie for address {addr:x}"))?, }; @@ -445,25 +451,27 @@ fn middle( } if self_destructed { - storage.remove(&keccak_hash::keccak(addr)); + storage_tries.remove(&keccak_hash::keccak(addr)); state_mask.extend(state_trie.reporting_remove(addr)?) } - let is_precompile = - PRECOMPILE_ADDRESS_RANGE.contains(&U256::from_big_endian(addr.as_bytes())); + let precompiled_addresses = address!("0000000000000000000000000000000000000001") + ..address!("000000000000000000000000000000000000000a"); // Trie witnesses will only include accessed precompile accounts as hash // nodes if the transaction calling them reverted. If this is the case, we // shouldn't include them in this transaction's `state_accesses` to allow the // decoder to build a minimal state trie without hitting any hash node. - if !is_precompile || state_trie.get_by_address(addr).is_some() { + if !precompiled_addresses.contains(&addr.compat()) + || state_trie.get_by_address(addr).is_some() + { state_mask.insert(TrieKey::from_address(addr)); } } - if increment_txn_ix { - curr_txn_ix += 1; + if do_increment_txn_ix { + txn_ix += 1; } loop_ix += 1; } // txn in batch @@ -493,8 +501,8 @@ fn middle( }, before: { before.state.mask(state_mask)?; - before.receipt.mask(batch_first_txn_ix..curr_txn_ix)?; - before.transaction.mask(batch_first_txn_ix..curr_txn_ix)?; + before.receipt.mask(batch_first_txn_ix..txn_ix)?; + before.transaction.mask(batch_first_txn_ix..txn_ix)?; let keep = storage_masks .keys() @@ -570,9 +578,6 @@ fn cancun_hook( Ok(()) } -// TODO(0xaatif): is this _meant_ to exclude the final member? -const PRECOMPILE_ADDRESS_RANGE: Range = U256([1, 0, 0, 0])..U256([10, 0, 0, 0]); - fn eth_to_gwei(eth: U256) -> U256 { // 1 ether = 10^9 gwei. eth * U256::from(10).pow(9.into()) From f94f7f50a3f3af0476f7b1bc84f1096a3c36b5ec Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 04:13:39 +0100 Subject: [PATCH 38/56] chore: tweaks --- trace_decoder/src/imp.rs | 52 +++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 1e9eac9b0..f71c79d51 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -376,27 +376,36 @@ fn middle( trc, ) }) { - // - created and failed - // - access the state trie, no change to storage trie - // - created and self destructed - // - access the state trie - // - empty trace requires the account to be present in the state trie + let (_, _, receipt) = evm_arithmetization::generation::mpt::decode_receipt( + &map_receipt_bytes(new_receipt_trie_node_byte.clone())?, + ) + .map_err(|e| anyhow!("{e:?}")) + .context("couldn't decode receipt")?; + let (mut acct, born) = state_trie .get_by_address(addr) .map(|acct| (acct, false)) .unwrap_or((AccountRlp::default(), true)); - let do_writes = match born { - false => !just_access, - true => { - let (_, _, receipt) = evm_arithmetization::generation::mpt::decode_receipt( - &map_receipt_bytes(new_receipt_trie_node_byte.clone())?, - ) - .map_err(|e| anyhow!("{e:?}")) - .context("couldn't decode receipt")?; - receipt.status && !just_access - } // if txn failed, don't commit changes to trie - }; + if born || just_access { + state_trie + .clone() + .insert_by_address(addr, acct) + .context(format!( + "couldn't reach state of {} address {addr:x}", + match born { + true => "created", + false => "accessed", + } + ))?; + } + + let do_writes = !just_access + && match born { + // if txn failed, don't commit changes to trie + true => receipt.status, + false => true, + }; let trim_storage = storage_masks.entry(addr).or_default(); @@ -458,14 +467,9 @@ fn middle( let precompiled_addresses = address!("0000000000000000000000000000000000000001") ..address!("000000000000000000000000000000000000000a"); - // Trie witnesses will only include accessed precompile accounts as hash - // nodes if the transaction calling them reverted. If this is the case, we - // shouldn't include them in this transaction's `state_accesses` to allow the - // decoder to build a minimal state trie without hitting any hash node. - - if !precompiled_addresses.contains(&addr.compat()) - || state_trie.get_by_address(addr).is_some() - { + if !precompiled_addresses.contains(&addr.compat()) { + // TODO(0xaatif): this looks like an optimization, + // but if it's omitted, the tests fail... state_mask.insert(TrieKey::from_address(addr)); } } From 11e0cc49452e438b515ea39e797b78463b247cd9 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 04:14:49 +0100 Subject: [PATCH 39/56] refactor: remove dead StateTrie::contains_address --- trace_decoder/src/typed_mpt.rs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index bc615d9ce..60fbba943 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -273,7 +273,6 @@ pub trait StateTrie { fn insert_hash_by_key(&mut self, key: TrieKey, hash: H256) -> anyhow::Result<()>; fn get_by_address(&self, address: Address) -> Option; fn reporting_remove(&mut self, address: Address) -> anyhow::Result>; - fn contains_address(&self, address: Address) -> bool; fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()>; fn iter(&self) -> impl Iterator + '_; fn root(&self) -> H256; @@ -334,11 +333,6 @@ impl StateTrie for StateMpt { TrieKey::from_address(address), ) } - fn contains_address(&self, address: Address) -> bool { - self.typed - .as_hashed_partial_trie() - .contains(TrieKey::from_address(address).into_nibbles()) - } fn mask(&mut self, addresses: impl IntoIterator) -> anyhow::Result<()> { let inner = mpt_trie::trie_subsets::create_trie_subset( self.typed.as_hashed_partial_trie(), @@ -393,9 +387,6 @@ impl StateTrie for StateSmt { self.address2state.remove(&address); Ok(None) } - fn contains_address(&self, address: Address) -> bool { - self.address2state.contains_key(&address) - } fn mask(&mut self, address: impl IntoIterator) -> anyhow::Result<()> { let _ = address; Ok(()) From 3f3fb37aeedb571b499a673b8b133e71c9f94d83 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 04:19:51 +0100 Subject: [PATCH 40/56] chore: comment --- trace_decoder/src/imp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index f71c79d51..6247ee1f8 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -517,7 +517,7 @@ fn middle( for (addr, mask) in storage_masks { if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { it.mask(mask)? - } // TODO(0xaatif): why is this fallible? + } // else self_destructed } before }, From fd128b056030ccdfca948552b1fafe76eb5e128d Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 04:33:31 +0100 Subject: [PATCH 41/56] fix: broken links --- trace_decoder/src/iface.rs | 4 ++-- trace_decoder/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/trace_decoder/src/iface.rs b/trace_decoder/src/iface.rs index faff3a8a9..3d86e3564 100644 --- a/trace_decoder/src/iface.rs +++ b/trace_decoder/src/iface.rs @@ -128,12 +128,12 @@ pub struct TxnTrace { #[serde(skip_serializing_if = "Option::is_none")] pub nonce: Option, - /// [hash](hash)([Address]) of storages read by the + /// [hash](keccak_hash)([Address]) of storages read by the /// transaction. #[serde(default, skip_serializing_if = "BTreeSet::is_empty")] pub storage_read: BTreeSet, - /// [hash](hash)([Address]) of storages written by the + /// [hash](keccak_hash)([Address]) of storages written by the /// transaction, with their new value. #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub storage_written: BTreeMap, diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index a14c6c57f..d02d94cc3 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -31,7 +31,7 @@ //! **while deferring all possible subtries to minimise prover load**, //! since prover performance is sensitive to the size of the trie. //! -//! [^1]: In our stack, this is (a fork of erigon)[https://github.com/0xPolygonZero/erigon], +//! [^1]: In our stack, this is [a fork of erigon](https://github.com/0xPolygonZero/erigon), //! which exposes more information over RPC. //! //! # Non-goals From 92fa7963d67312e430c5502e89b5bea52b962efd Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 14:18:42 +0100 Subject: [PATCH 42/56] run: rm trace_decoder/src/imp_pass.rs --- trace_decoder/src/imp_pass.rs | 637 ---------------------------------- 1 file changed, 637 deletions(-) delete mode 100644 trace_decoder/src/imp_pass.rs diff --git a/trace_decoder/src/imp_pass.rs b/trace_decoder/src/imp_pass.rs deleted file mode 100644 index 1e9eac9b0..000000000 --- a/trace_decoder/src/imp_pass.rs +++ /dev/null @@ -1,637 +0,0 @@ -use std::{ - cmp, - collections::{BTreeMap, BTreeSet, HashMap}, - mem, -}; - -use alloy::primitives::address; -use alloy_compat::Compat as _; -use anyhow::{anyhow, bail, ensure, Context as _}; -use ethereum_types::{Address, U256}; -use evm_arithmetization::{ - generation::{mpt::AccountRlp, TrieInputs}, - proof::TrieRoots, - testing_utils::{BEACON_ROOTS_CONTRACT_ADDRESS, HISTORY_BUFFER_LENGTH_VALUE}, - GenerationInputs, -}; -use itertools::Itertools as _; -use keccak_hash::H256; -use mpt_trie::partial_trie::PartialTrie as _; -use nunny::NonEmpty; - -use crate::{ - typed_mpt::{ReceiptTrie, StateMpt, StateTrie, StorageTrie, TransactionTrie, TrieKey}, - BlockLevelData, BlockTrace, BlockTraceTriePreImages, CombinedPreImages, ContractCodeUsage, - OtherBlockData, SeparateStorageTriesPreImage, SeparateTriePreImage, SeparateTriePreImages, - TxnInfo, TxnMeta, TxnTrace, -}; - -/// TODO(0xaatif): doc -pub fn entrypoint( - trace: BlockTrace, - other: OtherBlockData, - batch_size: usize, - use_burn_addr: bool, -) -> anyhow::Result> { - ensure!(batch_size != 0); - - let BlockTrace { - trie_pre_images, - code_db, - txn_info, - } = trace; - let (state, storage, mut code) = start(trie_pre_images)?; - code.extend(code_db); - - let OtherBlockData { - b_data: - BlockLevelData { - b_meta, - b_hashes, - mut withdrawals, - }, - checkpoint_state_trie_root, - } = other; - - // TODO(0xaatif): docs for the RPC field say this is gwei already: - // https://docs.rs/alloy/0.3.1/alloy/eips/eip4895/struct.Withdrawal.html#structfield.amount - // in any case, this shouldn't be our problem. - for (_, amt) in &mut withdrawals { - *amt = eth_to_gwei(*amt) - } - - let batches = middle( - state, - storage, - batch(txn_info, batch_size), - &mut code, - b_meta.block_timestamp, - b_meta.parent_beacon_block_root, - withdrawals, - )?; - - let mut running_gas_used = 0; - Ok(batches - .into_iter() - .map( - |Batch { - first_txn_ix, - gas_used, - contract_code, - byte_code, - before: - IntraBlockTries { - state, - storage, - transaction, - receipt, - }, - after, - withdrawals, - }| GenerationInputs { - txn_number_before: first_txn_ix.into(), - gas_used_before: running_gas_used.into(), - gas_used_after: { - running_gas_used += gas_used; - running_gas_used.into() - }, - signed_txns: byte_code.into_iter().map(Into::into).collect(), - withdrawals, - global_exit_roots: vec![], - tries: TrieInputs { - state_trie: state.into(), - transactions_trie: transaction.into(), - receipts_trie: receipt.into(), - storage_tries: storage.into_iter().map(|(k, v)| (k, v.into())).collect(), - }, - trie_roots_after: after, - checkpoint_state_trie_root, - contract_code: contract_code - .into_iter() - .map(|it| (keccak_hash::keccak(&it), it)) - .collect(), - block_metadata: b_meta.clone(), - block_hashes: b_hashes.clone(), - burn_addr: use_burn_addr.then_some(Address::zero()), - }, - ) - .collect()) -} - -/// The user has either provided us with a [`serde`]-ed -/// [`HashedPartialTrie`](mpt_trie::partial_trie::HashedPartialTrie), -/// or a [`wire`](crate::wire)-encoded representation of one. -/// -/// Turn either of those into our [`typed_mpt`](crate::typed_mpt) -/// representations. -fn start( - pre_images: BlockTraceTriePreImages, -) -> anyhow::Result<(StateMpt, BTreeMap, Hash2Code)> { - Ok(match pre_images { - // TODO(0xaatif): refactor our convoluted input types - BlockTraceTriePreImages::Separate(SeparateTriePreImages { - state: SeparateTriePreImage::Direct(state), - storage: SeparateStorageTriesPreImage::MultipleTries(storage), - }) => { - let state = state.items().try_fold( - StateMpt::default(), - |mut acc, (nibbles, hash_or_val)| { - let path = TrieKey::from_nibbles(nibbles); - match hash_or_val { - mpt_trie::trie_ops::ValOrHash::Val(bytes) => { - #[expect(deprecated)] // this is MPT specific - acc.insert_by_hashed_address( - path.into_hash() - .context("invalid path length in direct state trie")?, - rlp::decode(&bytes) - .context("invalid AccountRlp in direct state trie")?, - )?; - } - mpt_trie::trie_ops::ValOrHash::Hash(h) => { - acc.insert_hash_by_key(path, h)?; - } - }; - anyhow::Ok(acc) - }, - )?; - let storage = storage - .into_iter() - .map(|(k, SeparateTriePreImage::Direct(v))| { - v.items() - .try_fold(StorageTrie::default(), |mut acc, (nibbles, hash_or_val)| { - let path = TrieKey::from_nibbles(nibbles); - match hash_or_val { - mpt_trie::trie_ops::ValOrHash::Val(value) => { - acc.insert(path, value)?; - } - mpt_trie::trie_ops::ValOrHash::Hash(h) => { - acc.insert_hash(path, h)?; - } - }; - anyhow::Ok(acc) - }) - .map(|v| (k, v)) - }) - .collect::>()?; - (state, storage, Hash2Code::new()) - } - BlockTraceTriePreImages::Combined(CombinedPreImages { compact }) => { - let instructions = crate::wire::parse(&compact) - .context("couldn't parse instructions from binary format")?; - let crate::type1::Frontend { - state, - storage, - code, - } = crate::type1::frontend(instructions)?; - (state, storage, code.into_iter().map(Into::into).collect()) - } - }) -} - -/// Break `txns` into batches of length `hint`, prioritising creating at least -/// two batches. -/// -/// [`None`] represents a dummy transaction that should not increment the -/// transaction index. -fn batch(txns: Vec, hint: usize) -> Vec>> { - let hint = cmp::max(hint, 1); - let mut txns = txns.into_iter().map(Some).collect::>(); - let n_batches = txns.iter().chunks(hint).into_iter().count(); - match (txns.len(), n_batches) { - // enough - (_, 2..) => txns - .into_iter() - .chunks(hint) - .into_iter() - .map(FromIterator::from_iter) - .collect(), - // not enough batches at `hint`, but enough real transactions - (2.., ..2) => { - let second = txns.split_off(txns.len() / 2); - vec![txns, second] - } - // add padding - (0 | 1, _) => txns - .into_iter() - .pad_using(2, |_ix| None) - .map(|it| vec![it]) - .collect(), - } -} - -#[test] -fn test_batch() { - #[track_caller] - fn do_test(n: usize, hint: usize, exp: impl IntoIterator) { - itertools::assert_equal( - exp, - batch(vec![TxnInfo::default(); n], hint) - .iter() - .map(Vec::len), - ) - } - - do_test(0, 0, [1, 1]); // pad2 - do_test(1, 0, [1, 1]); // pad1 - do_test(2, 0, [1, 1]); // exact - do_test(3, 0, [1, 1, 1]); - do_test(3, 1, [1, 1, 1]); - do_test(3, 2, [2, 1]); // leftover after hint - do_test(3, 3, [1, 2]); // big hint -} - -#[derive(Debug)] -struct Batch { - pub first_txn_ix: usize, - pub gas_used: u64, - /// See [`GenerationInputs::contract_code`]. - pub contract_code: BTreeSet>, - /// For each transaction in batch, in order. - pub byte_code: Vec>>, - - pub before: IntraBlockTries, - pub after: TrieRoots, - - /// Empty for all but the final batch - pub withdrawals: Vec<(Address, U256)>, -} - -/// [`evm_arithmetization::generation::TrieInputs`], -/// generic over state trie representation. -#[derive(Debug)] -struct IntraBlockTries { - pub state: StateTrieT, - pub storage: BTreeMap, - pub transaction: TransactionTrie, - pub receipt: ReceiptTrie, -} - -/// Does the main work mentioned in the [module documentation](mod@self). -fn middle( - // state at the beginning of the block - mut state_trie: StateTrieT, - // storage at the beginning of the block - mut storage_tries: BTreeMap, - // None represents a dummy transaction that should not increment the transaction index - // all batches SHOULD not be empty - batches: Vec>>, - code: &mut Hash2Code, - block_timestamp: U256, - parent_beacon_block_root: H256, - // added to final batch - mut withdrawals: Vec<(Address, U256)>, -) -> anyhow::Result>> { - // Initialise the storage tries. - for (haddr, acct) in state_trie.iter() { - let storage = storage_tries.entry(haddr).or_insert({ - let mut it = StorageTrie::default(); - it.insert_hash(TrieKey::default(), acct.storage_root) - .expect("empty trie insert cannot fail"); - it - }); - ensure!( - storage.root() == acct.storage_root, - "inconsistent initial storage for hashed address {haddr:x}" - ) - } - - // These are the per-block tries. - let mut transaction_trie = TransactionTrie::new(); - let mut receipt_trie = ReceiptTrie::new(); - - let mut out = vec![]; - - let mut txn_ix = 0; // incremented for non-dummy transactions - let mut loop_ix = 0; // always incremented - let loop_len = batches.iter().flatten().count(); - for batch in batches { - let batch_first_txn_ix = txn_ix; // GOTCHA: if there are no transactions in this batch - let mut batch_gas_used = 0; - let mut batch_byte_code = vec![]; - let mut batch_contract_code = BTreeSet::from([vec![]]); // always include empty code - - let mut before = IntraBlockTries { - state: state_trie.clone(), - transaction: transaction_trie.clone(), - receipt: receipt_trie.clone(), - storage: storage_tries.clone(), - }; - - // We want to trim the TrieInputs above, - // but won't know the bounds until after the loop below, - // so store that information here. - let mut storage_masks = BTreeMap::<_, BTreeSet>::new(); - let mut state_mask = BTreeSet::new(); - - if txn_ix == 0 { - cancun_hook( - block_timestamp, - &mut storage_tries, - &mut storage_masks, - parent_beacon_block_root, - &mut state_mask, - &mut state_trie, - )?; - } - - for txn in batch { - let do_increment_txn_ix = txn.is_some(); - let TxnInfo { - traces, - meta: - TxnMeta { - byte_code, - new_receipt_trie_node_byte, - gas_used: txn_gas_used, - }, - } = txn.unwrap_or_default(); - - if let Ok(nonempty) = nunny::Vec::new(byte_code) { - batch_byte_code.push(nonempty.clone()); - transaction_trie.insert(txn_ix, nonempty.into())?; - receipt_trie.insert( - txn_ix, - map_receipt_bytes(new_receipt_trie_node_byte.clone())?, - )?; - } - - batch_gas_used += txn_gas_used; - - for ( - addr, - just_access, - TxnTrace { - balance, - nonce, - storage_read, - storage_written, - code_usage, - self_destructed, - }, - ) in traces.into_iter().map(|(addr, trc)| { - ( - addr, - // This is our fork of Erigon's way of letting us know - trc == TxnTrace::default(), - trc, - ) - }) { - // - created and failed - // - access the state trie, no change to storage trie - // - created and self destructed - // - access the state trie - // - empty trace requires the account to be present in the state trie - let (mut acct, born) = state_trie - .get_by_address(addr) - .map(|acct| (acct, false)) - .unwrap_or((AccountRlp::default(), true)); - - let do_writes = match born { - false => !just_access, - true => { - let (_, _, receipt) = evm_arithmetization::generation::mpt::decode_receipt( - &map_receipt_bytes(new_receipt_trie_node_byte.clone())?, - ) - .map_err(|e| anyhow!("{e:?}")) - .context("couldn't decode receipt")?; - receipt.status && !just_access - } // if txn failed, don't commit changes to trie - }; - - let trim_storage = storage_masks.entry(addr).or_default(); - - trim_storage.extend( - storage_written - .keys() - .chain(&storage_read) - .map(|it| TrieKey::from_hash(keccak_hash::keccak(it))), - ); - - if do_writes { - acct.balance = balance.unwrap_or(acct.balance); - acct.nonce = nonce.unwrap_or(acct.nonce); - acct.code_hash = code_usage - .map(|it| match it { - ContractCodeUsage::Read(hash) => { - batch_contract_code.insert(code.get(hash)?); - anyhow::Ok(hash) - } - ContractCodeUsage::Write(bytes) => { - code.insert(bytes.clone()); - let hash = keccak_hash::keccak(&bytes); - batch_contract_code.insert(bytes); - Ok(hash) - } - }) - .transpose()? - .unwrap_or(acct.code_hash); - - if !storage_written.is_empty() { - let storage = match born { - true => storage_tries.entry(keccak_hash::keccak(addr)).or_default(), - false => storage_tries - .get_mut(&keccak_hash::keccak(addr)) - .context(format!("missing storage trie for address {addr:x}"))?, - }; - - for (k, v) in storage_written { - let slot = TrieKey::from_hash(keccak_hash::keccak(k)); - match v.is_zero() { - // this is actually a delete - true => trim_storage.extend(storage.reporting_remove(slot)?), - false => { - storage.insert(slot, rlp::encode(&v).to_vec())?; - } - } - } - acct.storage_root = storage.root(); - } - - state_trie.insert_by_address(addr, acct)?; - } - - if self_destructed { - storage_tries.remove(&keccak_hash::keccak(addr)); - state_mask.extend(state_trie.reporting_remove(addr)?) - } - - let precompiled_addresses = address!("0000000000000000000000000000000000000001") - ..address!("000000000000000000000000000000000000000a"); - - // Trie witnesses will only include accessed precompile accounts as hash - // nodes if the transaction calling them reverted. If this is the case, we - // shouldn't include them in this transaction's `state_accesses` to allow the - // decoder to build a minimal state trie without hitting any hash node. - - if !precompiled_addresses.contains(&addr.compat()) - || state_trie.get_by_address(addr).is_some() - { - state_mask.insert(TrieKey::from_address(addr)); - } - } - - if do_increment_txn_ix { - txn_ix += 1; - } - loop_ix += 1; - } // txn in batch - - out.push(Batch { - first_txn_ix: batch_first_txn_ix, - gas_used: batch_gas_used, - contract_code: batch_contract_code, - byte_code: batch_byte_code, - withdrawals: match loop_ix == loop_len { - true => { - for (addr, amt) in &withdrawals { - state_mask.insert(TrieKey::from_address(*addr)); - let mut acct = state_trie - .get_by_address(*addr) - .context("missing address for withdrawal")?; - acct.balance += *amt; - state_trie - .insert_by_address(*addr, acct) - // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 - // Add an entry API - .expect("insert must succeed with the same key as a successful `get`"); - } - mem::take(&mut withdrawals) - } - false => vec![], - }, - before: { - before.state.mask(state_mask)?; - before.receipt.mask(batch_first_txn_ix..txn_ix)?; - before.transaction.mask(batch_first_txn_ix..txn_ix)?; - - let keep = storage_masks - .keys() - .map(keccak_hash::keccak) - .collect::>(); - before.storage.retain(|haddr, _| keep.contains(haddr)); - - for (addr, mask) in storage_masks { - if let Some(it) = before.storage.get_mut(&keccak_hash::keccak(addr)) { - it.mask(mask)? - } // TODO(0xaatif): why is this fallible? - } - before - }, - after: TrieRoots { - state_root: state_trie.root(), - transactions_root: transaction_trie.root(), - receipts_root: receipt_trie.root(), - }, - }); - } // batch in batches - - Ok(out) -} - -fn cancun_hook( - block_timestamp: U256, - storage: &mut BTreeMap, - trim_storage: &mut BTreeMap>, - parent_beacon_block_root: H256, - trim_state: &mut BTreeSet, - state_trie: &mut StateTrieT, -) -> anyhow::Result<()> { - let history_buffer_length = U256::from(HISTORY_BUFFER_LENGTH_VALUE); - let history_timestamp = block_timestamp % history_buffer_length; - let history_timestamp_next = history_timestamp + history_buffer_length; - let beacon_storage = storage - .get_mut(&keccak_hash::keccak(BEACON_ROOTS_CONTRACT_ADDRESS)) - .context("missing beacon contract storage trie")?; - let beacon_trim = trim_storage - .entry(BEACON_ROOTS_CONTRACT_ADDRESS) - .or_default(); - for (ix, u) in [ - (history_timestamp, block_timestamp), - ( - history_timestamp_next, - U256::from_big_endian(parent_beacon_block_root.as_bytes()), - ), - ] { - let mut h = [0; 32]; - ix.to_big_endian(&mut h); - let slot = TrieKey::from_hash(keccak_hash::keccak(H256::from_slice(&h))); - beacon_trim.insert(slot); - - match u.is_zero() { - true => beacon_trim.extend(beacon_storage.reporting_remove(slot)?), - false => { - beacon_storage.insert(slot, alloy::rlp::encode(u.compat()))?; - beacon_trim.insert(slot); - } - } - } - trim_state.insert(TrieKey::from_address(BEACON_ROOTS_CONTRACT_ADDRESS)); - let mut beacon_acct = state_trie - .get_by_address(BEACON_ROOTS_CONTRACT_ADDRESS) - .context("missing beacon contract address")?; - beacon_acct.storage_root = beacon_storage.root(); - state_trie - .insert_by_address(BEACON_ROOTS_CONTRACT_ADDRESS, beacon_acct) - // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 - // Add an entry API - .expect("insert must succeed with the same key as a successful `get`"); - Ok(()) -} - -fn eth_to_gwei(eth: U256) -> U256 { - // 1 ether = 10^9 gwei. - eth * U256::from(10).pow(9.into()) -} - -fn map_receipt_bytes(bytes: Vec) -> anyhow::Result> { - match rlp::decode::(&bytes) { - Ok(_) => Ok(bytes), - Err(_) => { - rlp::decode(&bytes).context("couldn't decode receipt as a legacy receipt or raw bytes") - } - } -} - -/// Code hash mappings that we have constructed from parsing the block -/// trace. -/// If there are any txns that create contracts, then they will also -/// get added here as we process the deltas. -struct Hash2Code { - /// Key must always be [`hash`] of value. - inner: HashMap>, -} - -impl Hash2Code { - pub fn new() -> Self { - let mut this = Self { - inner: HashMap::new(), - }; - this.insert(vec![]); - this - } - pub fn get(&mut self, hash: H256) -> anyhow::Result> { - match self.inner.get(&hash) { - Some(code) => Ok(code.clone()), - None => bail!("no code for hash {}", hash), - } - } - pub fn insert(&mut self, code: Vec) { - self.inner.insert(keccak_hash::keccak(&code), code); - } -} - -impl Extend> for Hash2Code { - fn extend>>(&mut self, iter: II) { - for it in iter { - self.insert(it) - } - } -} - -impl FromIterator> for Hash2Code { - fn from_iter>>(iter: II) -> Self { - let mut this = Self::new(); - this.extend(iter); - this - } -} From a1efa561eccdf79ee533ff04518b9e18de98a177 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:06:45 +0100 Subject: [PATCH 43/56] chore: dep fmt --- trace_decoder/Cargo.toml | 8 ++++---- zero_bin/leader/Cargo.toml | 8 ++++++-- zero_bin/prover/Cargo.toml | 4 ++-- zero_bin/rpc/Cargo.toml | 4 ++-- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 79400e5a9..41779d5cc 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -10,9 +10,9 @@ homepage.workspace = true keywords.workspace = true [dependencies] -alloy.workspace = true +alloy = { workspace = true } alloy-compat = "0.1.0" -anyhow.workspace = true +anyhow = { workspace = true } bitflags = { workspace = true } bitvec = { workspace = true } bytes = { workspace = true } @@ -25,7 +25,7 @@ ethereum-types = { workspace = true } evm_arithmetization = { workspace = true } hex = { workspace = true } hex-literal = { workspace = true } -itertools.workspace = true +itertools = { workspace = true } keccak-hash = { workspace = true } log = { workspace = true } mpt_trie = { workspace = true } @@ -46,7 +46,7 @@ alloy = { workspace = true } alloy-compat = "0.1.0" assert2 = "0.3.15" camino = "1.1.9" -clap.workspace = true +clap = { workspace = true } criterion = { workspace = true } glob = "0.3.1" libtest-mimic = "0.7.3" diff --git a/zero_bin/leader/Cargo.toml b/zero_bin/leader/Cargo.toml index 1f70f96a2..d3d7dff05 100644 --- a/zero_bin/leader/Cargo.toml +++ b/zero_bin/leader/Cargo.toml @@ -22,7 +22,7 @@ proof_gen = { workspace = true } serde_json = { workspace = true } serde_path_to_error = { workspace = true } futures = { workspace = true } -alloy.workspace = true +alloy = { workspace = true } axum = { workspace = true } toml = { workspace = true } @@ -35,7 +35,11 @@ zero_bin_common = { workspace = true } [features] default = [] -cdk_erigon = ["prover/cdk_erigon", "evm_arithmetization/cdk_erigon", "rpc/cdk_erigon"] +cdk_erigon = [ + "prover/cdk_erigon", + "evm_arithmetization/cdk_erigon", + "rpc/cdk_erigon", +] [build-dependencies] cargo_metadata = { workspace = true } diff --git a/zero_bin/prover/Cargo.toml b/zero_bin/prover/Cargo.toml index 6295f65b4..57838d9de 100644 --- a/zero_bin/prover/Cargo.toml +++ b/zero_bin/prover/Cargo.toml @@ -9,9 +9,9 @@ keywords.workspace = true categories.workspace = true [dependencies] -alloy.workspace = true +alloy = { workspace = true } anyhow = { workspace = true } -clap = {workspace = true, features = ["derive", "string"] } +clap = { workspace = true, features = ["derive", "string"] } evm_arithmetization = { workspace = true } futures = { workspace = true } num-traits = { workspace = true } diff --git a/zero_bin/rpc/Cargo.toml b/zero_bin/rpc/Cargo.toml index 046461569..28008f0d1 100644 --- a/zero_bin/rpc/Cargo.toml +++ b/zero_bin/rpc/Cargo.toml @@ -11,7 +11,7 @@ build = "../common/build.rs" [dependencies] __compat_primitive_types = { workspace = true } -alloy.workspace = true +alloy = { workspace = true } anyhow = { workspace = true } clap = { workspace = true } evm_arithmetization = { workspace = true } @@ -39,4 +39,4 @@ vergen = { workspace = true } anyhow = { workspace = true } [features] -cdk_erigon = [] \ No newline at end of file +cdk_erigon = [] From ff1dd67661bfae606ef2c7f3bb4ba7f86fd8538f Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:07:23 +0100 Subject: [PATCH 44/56] doc: cancun hook --- trace_decoder/src/imp.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/imp.rs index 6247ee1f8..cc72d33a2 100644 --- a/trace_decoder/src/imp.rs +++ b/trace_decoder/src/imp.rs @@ -532,6 +532,11 @@ fn middle( Ok(out) } +/// Updates the storage of the beacon block root contract, +/// according to +/// +/// This is cancun-specific, and runs at the start of the block, +/// before any transactions (as per the EIP). fn cancun_hook( block_timestamp: U256, storage: &mut BTreeMap, From ff0b9d76e3874caf73fc5e49379c6ffc53c48c63 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:08:29 +0100 Subject: [PATCH 45/56] chore: iface -> interface --- trace_decoder/src/{iface.rs => interface.rs} | 0 trace_decoder/src/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename trace_decoder/src/{iface.rs => interface.rs} (100%) diff --git a/trace_decoder/src/iface.rs b/trace_decoder/src/interface.rs similarity index 100% rename from trace_decoder/src/iface.rs rename to trace_decoder/src/interface.rs diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index d02d94cc3..f2f7858c5 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -54,9 +54,9 @@ /// we can continue to do the main work of "executing" the transactions. const _DEVELOPER_DOCS: () = (); -mod iface; +mod interface; -pub use iface::*; +pub use interface::*; mod type1; // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 From a34c3e16a7ca5f6c80fc0cbb83a6bdcaa2330ffa Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:09:52 +0100 Subject: [PATCH 46/56] chore: doc rf --- trace_decoder/src/interface.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trace_decoder/src/interface.rs b/trace_decoder/src/interface.rs index 3d86e3564..5f406580a 100644 --- a/trace_decoder/src/interface.rs +++ b/trace_decoder/src/interface.rs @@ -1,6 +1,6 @@ //! Public types for this crate. //! -//! These are all in one place because they're about to be heavily refactored. +//! These are all in one place because they're about to be heavily refactored in [#401](https://github.com/0xPolygonZero/zk_evm/issues/401). use std::collections::{BTreeMap, BTreeSet, HashMap}; From ecb69d24c21ace9b285f2ccec717e68937fad694 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:11:58 +0100 Subject: [PATCH 47/56] chore: doc --- trace_decoder/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index f2f7858c5..78cf573da 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -8,9 +8,8 @@ //! - [The specific changes to the storage tries](TxnTrace::storage_written). //! - [Changes to account balance in the state trie](TxnTrace::balance). //! -//! The tries and the transactions can be proved to be correct using a -//! zero-knowledge prover like [`evm_arithmetization`], -//! an Ethereum-y frontend for [`plonky2`]. +//! The state execution correctness is then asserted by the zkEVM prover in +//! [`evm_arithmetization`], relying on `starky` and [`plonky2`]. //! //! **Prover perfomance is a high priority.** //! From 42111c6ff2a384a79625d62bc0a91eea67adfcdf Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:12:20 +0100 Subject: [PATCH 48/56] chore: imp -> core --- trace_decoder/src/{imp.rs => core.rs} | 0 trace_decoder/src/lib.rs | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename trace_decoder/src/{imp.rs => core.rs} (100%) diff --git a/trace_decoder/src/imp.rs b/trace_decoder/src/core.rs similarity index 100% rename from trace_decoder/src/imp.rs rename to trace_decoder/src/core.rs diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index 78cf573da..e463068f8 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -66,9 +66,9 @@ mod type2; mod typed_mpt; mod wire; -pub use imp::entrypoint; +pub use core::entrypoint; -mod imp; +mod core; /// Like `#[serde(with = "hex")`, but tolerates and emits leading `0x` prefixes mod hex { From c8f7e77eb5877c6220c691212ce867ce0236e683 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:13:39 +0100 Subject: [PATCH 49/56] chore: `batch_size_hint` --- trace_decoder/src/core.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/trace_decoder/src/core.rs b/trace_decoder/src/core.rs index cc72d33a2..65f9ce61d 100644 --- a/trace_decoder/src/core.rs +++ b/trace_decoder/src/core.rs @@ -30,10 +30,10 @@ use crate::{ pub fn entrypoint( trace: BlockTrace, other: OtherBlockData, - batch_size: usize, + batch_size_hint: usize, use_burn_addr: bool, ) -> anyhow::Result> { - ensure!(batch_size != 0); + ensure!(batch_size_hint != 0); let BlockTrace { trie_pre_images, @@ -63,7 +63,7 @@ pub fn entrypoint( let batches = middle( state, storage, - batch(txn_info, batch_size), + batch(txn_info, batch_size_hint), &mut code, b_meta.block_timestamp, b_meta.parent_beacon_block_root, @@ -188,13 +188,13 @@ fn start( }) } -/// Break `txns` into batches of length `hint`, prioritising creating at least -/// two batches. +/// Break `txns` into batches of length `batch_size_hint`, prioritising creating +/// at least two batches. /// /// [`None`] represents a dummy transaction that should not increment the /// transaction index. -fn batch(txns: Vec, hint: usize) -> Vec>> { - let hint = cmp::max(hint, 1); +fn batch(txns: Vec, batch_size_hint: usize) -> Vec>> { + let hint = cmp::max(batch_size_hint, 1); let mut txns = txns.into_iter().map(Some).collect::>(); let n_batches = txns.iter().chunks(hint).into_iter().count(); match (txns.len(), n_batches) { From c5bbe6b936567b05bfb4cadcc909d09608d4564d Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Fri, 6 Sep 2024 18:16:00 +0100 Subject: [PATCH 50/56] chore: just_access --- trace_decoder/src/core.rs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/trace_decoder/src/core.rs b/trace_decoder/src/core.rs index 65f9ce61d..33096e099 100644 --- a/trace_decoder/src/core.rs +++ b/trace_decoder/src/core.rs @@ -368,14 +368,10 @@ fn middle( code_usage, self_destructed, }, - ) in traces.into_iter().map(|(addr, trc)| { - ( - addr, - // This is our fork of Erigon's way of letting us know - trc == TxnTrace::default(), - trc, - ) - }) { + ) in traces + .into_iter() + .map(|(addr, trc)| (addr, trc == TxnTrace::default(), trc)) + { let (_, _, receipt) = evm_arithmetization::generation::mpt::decode_receipt( &map_receipt_bytes(new_receipt_trie_node_byte.clone())?, ) From 8639067795b490011326fd5a7a7525fe3e976565 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 9 Sep 2024 13:03:13 +0100 Subject: [PATCH 51/56] review: markups --- trace_decoder/src/core.rs | 4 ++-- trace_decoder/src/lib.rs | 11 ++++++----- trace_decoder/src/typed_mpt.rs | 14 +++++++------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/trace_decoder/src/core.rs b/trace_decoder/src/core.rs index 05f92c354..1f65e00a1 100644 --- a/trace_decoder/src/core.rs +++ b/trace_decoder/src/core.rs @@ -324,7 +324,7 @@ fn middle( let mut state_mask = BTreeSet::new(); if txn_ix == 0 { - cancun_hook( + do_beacon_hook( block_timestamp, &mut storage_tries, &mut storage_masks, @@ -533,7 +533,7 @@ fn middle( /// /// This is cancun-specific, and runs at the start of the block, /// before any transactions (as per the EIP). -fn cancun_hook( +fn do_beacon_hook( block_timestamp: U256, storage: &mut BTreeMap, trim_storage: &mut BTreeMap>, diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index e463068f8..88636d877 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -13,7 +13,7 @@ //! //! **Prover perfomance is a high priority.** //! -//! The aformentioned trie structures may have subtries _deferred_. +//! The aformentioned trie structures may have subtries _indirected_. //! That is, any node (and its children!) may be replaced by its hash, //! while maintaining provability of its contents: //! ```text @@ -26,15 +26,16 @@ //! (where `H` is the hash of the `D/B\E` subtrie). //! //! The principle concern of this library is to step through the transactions, -//! and reproduce the tries that the Ethereum node does, -//! **while deferring all possible subtries to minimise prover load**, -//! since prover performance is sensitive to the size of the trie. +//! and reproduce the _intermediate tries_, +//! while indirecting all possible subtries to minimise prover load +//! (since prover performance is sensitive to the size of the trie). +//! The prover can therefore prove each batch of transactions independently. //! //! [^1]: In our stack, this is [a fork of erigon](https://github.com/0xPolygonZero/erigon), //! which exposes more information over RPC. //! //! # Non-goals -//! - Peformance - this will never be the bottleneck in any proving stack. +//! - Performance - this will never be the bottleneck in any proving stack. //! - Robustness - this library depends on other libraries that are not robust, //! so may panic at any time. diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index a2d233915..81f8bcf93 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -11,7 +11,7 @@ use u4::{AsNibbles, U4}; /// See . /// -/// Portions of the trie may be deferred: see [`Self::insert_hash`]. +/// Portions of the trie may be indirected: see [`Self::insert_hash`]. #[derive(Debug, Clone, PartialEq, Eq)] struct TypedMpt { inner: HashedPartialTrie, @@ -201,7 +201,7 @@ impl TransactionTrie { pub const fn as_hashed_partial_trie(&self) -> &mpt_trie::partial_trie::HashedPartialTrie { &self.untyped } - /// Defer (hash) parts of the trie that aren't in `txn_ixs`. + /// Indirect (hash) parts of the trie that aren't in `txn_ixs`. pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, @@ -246,7 +246,7 @@ impl ReceiptTrie { pub const fn as_hashed_partial_trie(&self) -> &mpt_trie::partial_trie::HashedPartialTrie { &self.untyped } - /// Defer (hash) parts of the trie that aren't in `txn_ixs`. + /// Indirect (hash) parts of the trie that aren't in `txn_ixs`. pub fn mask(&mut self, txn_ixs: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, @@ -322,7 +322,7 @@ impl StateTrie for StateMpt { #[expect(deprecated)] self.insert_by_hashed_address(keccak_hash::keccak(address), account) } - /// Insert a deferred part of the trie + /// Insert an indirected part of the trie fn insert_hash_by_key(&mut self, key: TrieKey, hash: H256) -> anyhow::Result<()> { self.typed.insert_hash(key, hash) } @@ -370,7 +370,7 @@ impl From for HashedPartialTrie { pub struct StateSmt { address2state: BTreeMap, - deferred: BTreeMap, + indirected: BTreeMap, } impl StateTrie for StateSmt { @@ -382,7 +382,7 @@ impl StateTrie for StateSmt { Ok(self.address2state.insert(address, account)) } fn insert_hash_by_key(&mut self, key: TrieKey, hash: H256) -> anyhow::Result<()> { - self.deferred.insert(key, hash); + self.indirected.insert(key, hash); Ok(()) } fn get_by_address(&self, address: Address) -> Option { @@ -440,7 +440,7 @@ impl StorageTrie { pub fn as_mut_hashed_partial_trie_unchecked(&mut self) -> &mut HashedPartialTrie { &mut self.untyped } - /// Defer (hash) the parts of the trie that aren't in `paths`. + /// Indirect (hash) the parts of the trie that aren't in `paths`. pub fn mask(&mut self, paths: impl IntoIterator) -> anyhow::Result<()> { self.untyped = mpt_trie::trie_subsets::create_trie_subset( &self.untyped, From ab5c74e2e28ace66582bd7c39840e8e607a7b733 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 9 Sep 2024 13:30:39 +0100 Subject: [PATCH 52/56] refactor: NamedConstant --- Cargo.lock | 1 + .../src/cpu/kernel/constants/mod.rs | 18 +++++++++---- evm_arithmetization/src/testing_utils.rs | 4 +-- trace_decoder/src/core.rs | 7 +++-- zero_bin/rpc/Cargo.toml | 1 + zero_bin/rpc/src/native/state.rs | 27 ++++++++++--------- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaf81c99e..735f80c4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4194,6 +4194,7 @@ name = "rpc" version = "0.1.0" dependencies = [ "alloy", + "alloy-compat", "anyhow", "cargo_metadata", "clap", diff --git a/evm_arithmetization/src/cpu/kernel/constants/mod.rs b/evm_arithmetization/src/cpu/kernel/constants/mod.rs index 451f36b1d..348c5b2c6 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/mod.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/mod.rs @@ -18,6 +18,13 @@ pub(crate) mod journal_entry; pub(crate) mod trie_type; pub(crate) mod txn_fields; +/// A named constant. +/// Prefer this over `(name, value)` tuples. +pub struct Named<'a, T> { + pub name: &'a str, + pub value: T, +} + /// Constants that are accessible to our kernel assembly code. pub(crate) fn evm_constants() -> HashMap { let mut c = HashMap::new(); @@ -71,8 +78,8 @@ pub(crate) fn evm_constants() -> HashMap { U256::from_big_endian(&cancun_constants::BEACON_ROOTS_CONTRACT_STATE_KEY.1), ); c.insert( - cancun_constants::HISTORY_BUFFER_LENGTH.0.into(), - cancun_constants::HISTORY_BUFFER_LENGTH.1.into(), + cancun_constants::HISTORY_BUFFER_LENGTH.name.into(), + cancun_constants::HISTORY_BUFFER_LENGTH.value, ); c.insert( @@ -424,9 +431,10 @@ pub mod cancun_constants { // Beacon constants /////////////////// - pub const HISTORY_BUFFER_LENGTH_VALUE: u64 = 8191; - pub const HISTORY_BUFFER_LENGTH: (&str, u64) = - ("HISTORY_BUFFER_LENGTH", HISTORY_BUFFER_LENGTH_VALUE); + pub const HISTORY_BUFFER_LENGTH: Named = Named { + name: "HISTORY_BUFFER_LENGTH", + value: U256([8191, 0, 0, 0]), + }; pub const BEACON_ROOTS_CONTRACT_ADDRESS: Address = H160(hex!("000F3df6D732807Ef1319fB7B8bB8522d0Beac02")); diff --git a/evm_arithmetization/src/testing_utils.rs b/evm_arithmetization/src/testing_utils.rs index 4152da5b6..d8556916b 100644 --- a/evm_arithmetization/src/testing_utils.rs +++ b/evm_arithmetization/src/testing_utils.rs @@ -64,8 +64,8 @@ pub fn update_beacon_roots_account_storage( timestamp: U256, parent_root: H256, ) -> anyhow::Result<()> { - let timestamp_idx = timestamp % HISTORY_BUFFER_LENGTH.1; - let root_idx = timestamp_idx + HISTORY_BUFFER_LENGTH.1; + let timestamp_idx = timestamp % HISTORY_BUFFER_LENGTH.value; + let root_idx = timestamp_idx + HISTORY_BUFFER_LENGTH.value; insert_storage(storage_trie, timestamp_idx, timestamp)?; insert_storage(storage_trie, root_idx, h2u(parent_root)) diff --git a/trace_decoder/src/core.rs b/trace_decoder/src/core.rs index 1f65e00a1..a8ac252d7 100644 --- a/trace_decoder/src/core.rs +++ b/trace_decoder/src/core.rs @@ -11,7 +11,7 @@ use ethereum_types::{Address, U256}; use evm_arithmetization::{ generation::{mpt::AccountRlp, TrieInputs}, proof::TrieRoots, - testing_utils::{BEACON_ROOTS_CONTRACT_ADDRESS, HISTORY_BUFFER_LENGTH_VALUE}, + testing_utils::{BEACON_ROOTS_CONTRACT_ADDRESS, HISTORY_BUFFER_LENGTH}, GenerationInputs, }; use itertools::Itertools as _; @@ -541,9 +541,8 @@ fn do_beacon_hook( trim_state: &mut BTreeSet, state_trie: &mut StateTrieT, ) -> anyhow::Result<()> { - let history_buffer_length = U256::from(HISTORY_BUFFER_LENGTH_VALUE); - let history_timestamp = block_timestamp % history_buffer_length; - let history_timestamp_next = history_timestamp + history_buffer_length; + let history_timestamp = block_timestamp % HISTORY_BUFFER_LENGTH.value; + let history_timestamp_next = history_timestamp + HISTORY_BUFFER_LENGTH.value; let beacon_storage = storage .get_mut(&keccak_hash::keccak(BEACON_ROOTS_CONTRACT_ADDRESS)) .context("missing beacon contract storage trie")?; diff --git a/zero_bin/rpc/Cargo.toml b/zero_bin/rpc/Cargo.toml index c9403bdb5..d91b15755 100644 --- a/zero_bin/rpc/Cargo.toml +++ b/zero_bin/rpc/Cargo.toml @@ -12,6 +12,7 @@ build = "../common/build.rs" [dependencies] __compat_primitive_types = { workspace = true } alloy = { workspace = true } +alloy-compat = "0.1.0" anyhow = { workspace = true } clap = { workspace = true } futures = { workspace = true } diff --git a/zero_bin/rpc/src/native/state.rs b/zero_bin/rpc/src/native/state.rs index b46eabc9d..24c7b1214 100644 --- a/zero_bin/rpc/src/native/state.rs +++ b/zero_bin/rpc/src/native/state.rs @@ -1,12 +1,14 @@ use std::collections::{HashMap, HashSet}; use std::sync::Arc; +use alloy::primitives::Bytes; use alloy::{ primitives::{keccak256, Address, StorageKey, B256, U256}, providers::Provider, rpc::types::eth::{Block, BlockTransactionsKind, EIP1186AccountProofResponse}, transports::Transport, }; +use alloy_compat::Compat; use anyhow::Context as _; use evm_arithmetization::testing_utils::{BEACON_ROOTS_CONTRACT_STATE_KEY, HISTORY_BUFFER_LENGTH}; use futures::future::{try_join, try_join_all}; @@ -17,8 +19,6 @@ use trace_decoder::{ }; use zero_bin_common::provider::CachedProvider; -use crate::Compat; - /// Processes the state witness for the given block. pub async fn process_state_witness( cached_provider: Arc>, @@ -93,13 +93,12 @@ fn insert_beacon_roots_update( state_access: &mut HashMap>, block: &Block, ) -> anyhow::Result<()> { - let timestamp = block.header.timestamp; - - const MODULUS: u64 = HISTORY_BUFFER_LENGTH.1; + let timestamp = U256::from(block.header.timestamp); - let keys = HashSet::from_iter([ - U256::from(timestamp % MODULUS).into(), // timestamp_idx - U256::from((timestamp % MODULUS) + MODULUS).into(), // root_idx + let chunk = HISTORY_BUFFER_LENGTH.value.compat(); + let keys = HashSet::from([ + (timestamp % chunk).into(), // timestamp_idx + ((timestamp % chunk) + chunk).into(), // root_idx ]); state_access.insert(BEACON_ROOTS_CONTRACT_STATE_KEY.1.into(), keys); @@ -128,7 +127,7 @@ where // Insert account proofs for (address, proof) in account_proofs.into_iter() { - state.insert_proof(proof.account_proof.compat()); + state.insert_proof(conv_vec_bytes(proof.account_proof)); let storage_mpt = storage_proofs @@ -138,17 +137,17 @@ where Default::default(), )); for proof in proof.storage_proof { - storage_mpt.insert_proof(proof.proof.compat()); + storage_mpt.insert_proof(conv_vec_bytes(proof.proof)); } } // Insert short node variants from next proofs for (address, proof) in next_account_proofs.into_iter() { - state.insert_short_node_variants_from_proof(proof.account_proof.compat()); + state.insert_short_node_variants_from_proof(conv_vec_bytes(proof.account_proof)); if let Some(storage_mpt) = storage_proofs.get_mut(&keccak256(address)) { for proof in proof.storage_proof { - storage_mpt.insert_short_node_variants_from_proof(proof.proof.compat()); + storage_mpt.insert_short_node_variants_from_proof(conv_vec_bytes(proof.proof)); } } } @@ -156,6 +155,10 @@ where Ok((state, storage_proofs)) } +fn conv_vec_bytes(bytes: Vec) -> Vec> { + bytes.into_iter().map(|bytes| bytes.to_vec()).collect() +} + /// Fetches the proof data for the given accounts and associated storage keys. async fn fetch_proof_data( accounts_state: HashMap>, From 66bf870a8c82220ce74841f85612d242dcdcd5b1 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 9 Sep 2024 15:49:58 +0100 Subject: [PATCH 53/56] mark: 0xaatif/discuss-trie-mask From cfe6d42da834ebcb6ddc21ecdd1ac18c2625df2f Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 9 Sep 2024 15:51:22 +0100 Subject: [PATCH 54/56] chore: shim --- trace_decoder/src/core.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/trace_decoder/src/core.rs b/trace_decoder/src/core.rs index a8ac252d7..666ea5caf 100644 --- a/trace_decoder/src/core.rs +++ b/trace_decoder/src/core.rs @@ -466,7 +466,10 @@ fn middle( if !precompiled_addresses.contains(&addr.compat()) { // TODO(0xaatif): this looks like an optimization, // but if it's omitted, the tests fail... - state_mask.insert(TrieKey::from_address(addr)); + if std::env::var_os("SKIP_MASK_PRECOMPILED").is_some_and(|it| it == "true") { + } else { + state_mask.insert(TrieKey::from_address(addr)); + } } } From befc4ba3f2e0838d0765aa6d6f23a4cd028a0c31 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 9 Sep 2024 18:44:30 +0100 Subject: [PATCH 55/56] prove: mpt library is not robust either :) --- Cargo.lock | 62 ++++++++++++++++++++++++++ trace_decoder/Cargo.toml | 15 +++---- trace_decoder/src/typed_mpt.rs | 79 ++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 735f80c4c..6e83cdd32 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1426,6 +1426,9 @@ name = "copyvec" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8aba112395a3627b61476b950f4c015964642a1d32a44112ad97c4a781dab81f" +dependencies = [ + "quickcheck", +] [[package]] name = "core-foundation" @@ -1714,6 +1717,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-quickcheck-arbitrary" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697d85c38ac8f4dad3129d38d0d40060a98fd2557bfaf0bc8c071ecfce884ce5" +dependencies = [ + "proc-macro2", + "quote", + "structmeta", + "syn 2.0.77", +] + [[package]] name = "derive_builder" version = "0.20.1" @@ -1925,6 +1940,16 @@ dependencies = [ "regex", ] +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" version = "0.10.2" @@ -3937,6 +3962,17 @@ version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" +[[package]] +name = "quickcheck" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "env_logger 0.8.4", + "log", + "rand", +] + [[package]] name = "quote" version = "1.0.37" @@ -4756,6 +4792,29 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "structmeta" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ad9e09554f0456d67a69c1584c9798ba733a5b50349a6c0d0948710523922d" +dependencies = [ + "proc-macro2", + "quote", + "structmeta-derive", + "syn 2.0.77", +] + +[[package]] +name = "structmeta-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + [[package]] name = "strum" version = "0.26.3" @@ -5176,6 +5235,7 @@ dependencies = [ "pretty_assertions", "pretty_env_logger", "prover", + "quickcheck", "rlp", "serde", "serde_json", @@ -5284,6 +5344,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "390884f06a6f4eee34a2082a3eb17844cf3605a69f033f79bf0e6f460279112c" dependencies = [ "const-default", + "derive-quickcheck-arbitrary", + "quickcheck", "serde", ] diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index b8f07eff8..bcb980852 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -18,7 +18,7 @@ bitvec = { workspace = true } bytes = { workspace = true } ciborium = { workspace = true } ciborium-io = { workspace = true } -copyvec = "0.2.0" +copyvec = { version = "0.2.0", features = ["quickcheck"] } either = { workspace = true } enum-as-inner = { workspace = true } ethereum-types = { workspace = true } @@ -34,7 +34,7 @@ serde = { workspace = true } stackstack = "0.3.0" strum = { version = "0.26.3", features = ["derive"] } thiserror = { workspace = true } -u4 = { workspace = true } +u4 = { workspace = true, features = ["quickcheck"] } winnow = { workspace = true } # Local dependencies @@ -56,20 +56,15 @@ plonky2_maybe_rayon = { workspace = true } pretty_assertions = "1.4.0" pretty_env_logger = { workspace = true } prover = { workspace = true } +quickcheck = "1.0.3" serde_json = { workspace = true } serde_path_to_error = { workspace = true } [features] default = ["eth_mainnet"] -eth_mainnet = [ - "evm_arithmetization/eth_mainnet", - "prover/eth_mainnet", -] -cdk_erigon = [ - "evm_arithmetization/cdk_erigon", - "prover/cdk_erigon", -] +eth_mainnet = ["evm_arithmetization/eth_mainnet", "prover/eth_mainnet"] +cdk_erigon = ["evm_arithmetization/cdk_erigon", "prover/cdk_erigon"] [[bench]] name = "block_processing" diff --git a/trace_decoder/src/typed_mpt.rs b/trace_decoder/src/typed_mpt.rs index 81f8bcf93..9c0d4110f 100644 --- a/trace_decoder/src/typed_mpt.rs +++ b/trace_decoder/src/typed_mpt.rs @@ -500,3 +500,82 @@ fn node_deletion_resulted_in_a_branch_collapse( // collapse. branch_collapse_occurred.then(|| mpt_trie::utils::IntoTrieKey::into_key(new_path.iter())) } + +#[cfg(test)] +mod tests { + use std::array; + + use itertools::Itertools as _; + use quickcheck::Arbitrary; + + use super::*; + + quickcheck::quickcheck! { + fn quickcheck( + kvs: Vec<(TrieKey, Vec)>, + mask_kvs: Vec<(TrieKey, Vec)>, + khs: Vec<(TrieKey, ArbitraryHash)> + ) -> () { + do_quickcheck(kvs, mask_kvs, khs) + } + } + + fn do_quickcheck( + kvs: Vec<(TrieKey, Vec)>, + mask_kvs: Vec<(TrieKey, Vec)>, + khs: Vec<(TrieKey, ArbitraryHash)>, + ) { + let mut mpt = HashedPartialTrie::default(); + let mask = mask_kvs + .iter() + .map(|(k, _)| k.into_nibbles()) + .collect::>(); + for (k, v) in kvs.into_iter().chain(mask_kvs) { + let _ = mpt.insert(k.into_nibbles(), v); + } + for (k, ArbitraryHash(h)) in khs { + let _ = mpt.insert(k.into_nibbles(), h); + } + let root = mpt.hash(); + if let Ok(sub) = mpt_trie::trie_subsets::create_trie_subset(&mpt, mask) { + assert_eq!(sub.hash(), root) + } + } + + impl Arbitrary for TrieKey { + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + Self(Arbitrary::arbitrary(g)) + } + + fn shrink(&self) -> Box> { + let Self(comps) = *self; + Box::new(comps.shrink().map(Self)) + } + } + + #[derive(Debug, Clone, Copy)] + struct ArbitraryHash(H256); + impl ArbitraryHash { + pub fn new((a, b, c, d): (u64, u64, u64, u64)) -> Self { + let mut iter = [a, b, c, d].into_iter().flat_map(u64::to_ne_bytes); + let h = H256(array::from_fn(|_| iter.next().unwrap())); + assert_eq!(iter.count(), 0); + Self(h) + } + } + impl Arbitrary for ArbitraryHash { + fn arbitrary(g: &mut quickcheck::Gen) -> Self { + Self::new(Arbitrary::arbitrary(g)) + } + + fn shrink(&self) -> Box> { + let Self(H256(bytes)) = self; + let (a, b, c, d) = bytes + .chunks_exact(8) + .map(|it| u64::from_ne_bytes(it.try_into().unwrap())) + .collect_tuple() + .unwrap(); + Box::new((a, b, c, d).shrink().map(Self::new)) + } + } +} From d263e91f87f62e5379f6d5590a84e803c732b406 Mon Sep 17 00:00:00 2001 From: 0xaatif Date: Mon, 9 Sep 2024 19:05:48 +0100 Subject: [PATCH 56/56] wip: check-subsets --- trace_decoder/Cargo.toml | 4 ++++ trace_decoder/src/lib.rs | 2 ++ trace_decoder/tests/check-subsets.rs | 32 ++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 trace_decoder/tests/check-subsets.rs diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index bcb980852..b56d229e6 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -77,3 +77,7 @@ harness = false [[test]] name = "simulate-execution" harness = false + +[[test]] +name = "check-subsets" +harness = false diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index 88636d877..4a0bdf7b4 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -57,6 +57,8 @@ const _DEVELOPER_DOCS: () = (); mod interface; pub use interface::*; +pub use type1::frontend; +pub use wire::parse; mod type1; // TODO(0xaatif): https://github.com/0xPolygonZero/zk_evm/issues/275 diff --git a/trace_decoder/tests/check-subsets.rs b/trace_decoder/tests/check-subsets.rs new file mode 100644 index 000000000..694a7df40 --- /dev/null +++ b/trace_decoder/tests/check-subsets.rs @@ -0,0 +1,32 @@ +use common::{cases, Case}; +use itertools::Itertools; +use mpt_trie::partial_trie::PartialTrie; +use trace_decoder::{BlockTraceTriePreImages, CombinedPreImages}; + +mod common; + +fn main() -> anyhow::Result<()> { + for Case { name, trace, .. } in cases().unwrap() { + let BlockTraceTriePreImages::Combined(CombinedPreImages { compact }) = + trace.trie_pre_images + else { + panic!() + }; + let whole = trace_decoder::frontend(trace_decoder::parse(&compact).unwrap()) + .unwrap() + .state + .as_hashed_partial_trie() + .clone(); + let all_keys = whole.keys().collect::>(); + let len = all_keys.len(); + for n in 0..len { + println!("{name}\t{n}\t{len}"); + for comb in all_keys.iter().copied().combinations(n) { + if let Ok(sub) = mpt_trie::trie_subsets::create_trie_subset(&whole, comb.clone()) { + assert_eq!(sub.hash(), whole.hash(), "{comb:?}") + } + } + } + } + Ok(()) +}