diff --git a/Cargo.lock b/Cargo.lock index a899fd802..87a3bd9d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5804,6 +5804,7 @@ dependencies = [ "primitive-types 0.12.2", "proof_gen", "regex", + "rlp", "ruint", "serde", "serde_json", diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 0f9046e71..dfc19f13a 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -240,8 +240,8 @@ impl GenerationInputs { #[derive(Clone, Debug, Deserialize, Serialize)] pub struct DebugTrieOutputs { pub state_trie: HashedPartialTrie, - pub transactions_trie: HashedPartialTrie, - pub receipts_trie: HashedPartialTrie, + pub transaction_trie: HashedPartialTrie, + pub receipt_trie: HashedPartialTrie, } /// Wrapper around the error that happened in the simulation @@ -676,7 +676,7 @@ pub(crate) fn collect_debug_tries( Ok(DebugTrieOutputs { state_trie, - transactions_trie, - receipts_trie, + transaction_trie: transactions_trie, + receipt_trie: receipts_trie, }) } diff --git a/mpt_trie/src/debug_tools/diff.rs b/mpt_trie/src/debug_tools/diff.rs index 12775b445..880984290 100644 --- a/mpt_trie/src/debug_tools/diff.rs +++ b/mpt_trie/src/debug_tools/diff.rs @@ -136,13 +136,15 @@ impl Display for DiffPoint { /// Meta information for a node in a trie. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct NodeInfo { - key: Nibbles, - + /// Mpt trie node key. + pub key: Nibbles, /// The direct value associated with the node (only applicable to `Leaf` & /// `Branch` nodes). - value: Option>, - node_type: TrieNodeType, - hash: H256, + pub value: Option>, + /// Type of this node. + pub node_type: TrieNodeType, + /// Node hash. + pub hash: H256, } impl Display for NodeInfo { diff --git a/trace_decoder/src/core.rs b/trace_decoder/src/core.rs index 1ce4687fe..41e356bb7 100644 --- a/trace_decoder/src/core.rs +++ b/trace_decoder/src/core.rs @@ -430,7 +430,7 @@ fn middle( // >>>>>>>>>>> DEBUG: Introduce error in the trie diff simulation let addressdebug = "0x".to_string() + &hex::encode(addr.0); if addressdebug.eq("0x71f755898886f79efa73334450f05a824faeae02") { - println!(">>>>>>>> I have found address and making a change txn index {txn_ix} address {addressdebug}!"); + println!(">>>>>>>> I have found address and making a change txn index {txn_ix} address {addressdebug} making a balance from {} to {}!", acct.balance, acct.balance+U256::from(1)); acct.balance += U256::from(1); } //******************************************************************* diff --git a/zero/Cargo.toml b/zero/Cargo.toml index da1058daa..c605f4b12 100644 --- a/zero/Cargo.toml +++ b/zero/Cargo.toml @@ -30,6 +30,7 @@ paladin-core = { workspace = true } plonky2 = { workspace = true } plonky2_maybe_rayon = { workspace = true } regex = "1.5.4" +rlp = {workspace = true} ruint = { workspace = true, features = ["num-traits", "primitive-types"] } serde = { workspace = true } serde_json = { workspace = true } diff --git a/zero/src/bin/trie_diff.rs b/zero/src/bin/trie_diff.rs index 0d5c0c202..358d955da 100644 --- a/zero/src/bin/trie_diff.rs +++ b/zero/src/bin/trie_diff.rs @@ -5,6 +5,7 @@ use std::sync::Arc; use anyhow::Result; use clap::{Parser, ValueHint}; +use evm_arithmetization::generation::DebugTrieOutputs; use futures::{future, TryStreamExt}; use paladin::directive::{Directive, IndexedStream}; use paladin::runtime::Runtime; @@ -106,9 +107,29 @@ async fn main() -> Result<()> { info!("Performing trie diff..."); zero::trie_diff::compare_tries( &block_prover_input, - &observer.data[prover_tries.batch_index], + batch_index, + &DebugTrieOutputs { + state_trie: observer.data[prover_tries.batch_index] + .tries + .state + .as_hashed_partial_trie() + .clone(), + transaction_trie: observer.data[prover_tries.batch_index] + .tries + .transaction + .clone() + .into(), + receipt_trie: observer.data[prover_tries.batch_index] + .tries + .receipt + .clone() + .into(), + }, &prover_tries.tries, )?; + + info!("Trie comparison finished"); + return Ok(()); } else { error!( "Failed to extract block and batch numbers from error message: {}", diff --git a/zero/src/trie_diff/mod.rs b/zero/src/trie_diff/mod.rs index bcae9df31..18ba2c115 100644 --- a/zero/src/trie_diff/mod.rs +++ b/zero/src/trie_diff/mod.rs @@ -1,14 +1,111 @@ +use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use evm_arithmetization::generation::DebugTrieOutputs; -use trace_decoder::observer::TriesObserverElement; +use mpt_trie::debug_tools::diff::create_diff_between_tries; +use mpt_trie::utils::TrieNodeType; use tracing::info; use crate::prover::BlockProverInput; -pub fn compare_tries( - _block_prover_input: &BlockProverInput, - _left: &TriesObserverElement, - _right: &DebugTrieOutputs, +pub fn compare_tries( + block_prover_input: &BlockProverInput, + batch_index: usize, + left: &DebugTrieOutputs, + right: &DebugTrieOutputs, ) -> anyhow::Result<()> { - info!("Here I am comparing tries..."); + let block_number = block_prover_input + .other_data + .b_data + .b_meta + .block_number + .as_u64(); + let state_trie_diff = create_diff_between_tries(&left.state_trie, &right.state_trie); + if let Some(ref state_trie_diff_point) = state_trie_diff.latest_diff_res { + if state_trie_diff_point.a_info.node_type == TrieNodeType::Leaf { + if let Some(ref td_account_value) = state_trie_diff_point.a_info.value { + let td_account_data = rlp::decode::(td_account_value)?; + info!("Trace decoder state trie block {block_number} batch {batch_index} output account address hash: {} account data: {:#?}", + state_trie_diff_point.a_info.key, td_account_data); + } else { + info!("Trace decoder state trie block {block_number} batch {batch_index}, skip account printout as diff is not at the leaf node level."); + } + } + if state_trie_diff_point.b_info.node_type == TrieNodeType::Leaf { + if let Some(ref prover_account_value) = state_trie_diff_point.b_info.value { + let prover_account_data = rlp::decode::(prover_account_value)?; + info!("Prover state trie block {block_number} batch {batch_index} account address hash: {} account data: {:#?}", + state_trie_diff_point.b_info.key, prover_account_data); + } else { + info!("Prover state trie block {block_number} batch {batch_index}, skip account printout as diff is not at the leaf node level."); + } + } + + info!( + "State trie block {block_number} batch {batch_index} diff: {:#?}", + state_trie_diff_point + ); + } else { + info!("State trie for block {block_number} batch {batch_index} matches."); + } + + let transaction_trie_diff = + create_diff_between_tries(&left.transaction_trie, &right.transaction_trie); + if let Some(ref transaction_trie_diff_point) = transaction_trie_diff.latest_diff_res { + if transaction_trie_diff_point.a_info.node_type == TrieNodeType::Leaf { + let tx_index = + rlp::decode::(transaction_trie_diff_point.a_info.key.as_byte_slice())?; + info!("Trace decoder transaction trie block {block_number} batch {batch_index} transaction index {tx_index} rlp bytecode: {:?}", + transaction_trie_diff_point.a_info.value.as_ref().map(hex::encode)); + } else { + info!("Trace decoder transaction trie block {block_number} batch {batch_index}, skip tx printout as diff is not at the leaf node level."); + } + if transaction_trie_diff_point.b_info.node_type == TrieNodeType::Leaf { + let tx_index = + rlp::decode::(transaction_trie_diff_point.b_info.key.as_byte_slice())?; + info!("Prover transaction trie block {block_number} batch {batch_index} transaction index {tx_index} rlp bytecode: {:?}", + transaction_trie_diff_point.b_info.value.as_ref().map(hex::encode)); + } else { + info!("Prover transaction trie block {block_number} batch {batch_index}, skip tx printout as diff is not at the leaf node level."); + } + + info!( + "Transactions trie block {block_number} batch {batch_index} diff: {:#?}", + transaction_trie_diff_point + ); + } else { + info!("Transaction trie for block {block_number} batch {batch_index} matches."); + } + + let receipt_trie_diff = create_diff_between_tries(&left.receipt_trie, &right.receipt_trie); + if let Some(ref receipt_trie_diff_point) = receipt_trie_diff.latest_diff_res { + if receipt_trie_diff_point.a_info.node_type == TrieNodeType::Leaf { + if let Some(ref td_receipt_value) = receipt_trie_diff_point.a_info.value { + let tx_index = + rlp::decode::(receipt_trie_diff_point.a_info.key.as_byte_slice())?; + let td_receipt_data = rlp::decode::(td_receipt_value)?; + info!("Trace decoder receipt trie block {block_number} batch {batch_index} output tx index: {tx_index} receipt data: {:#?}", td_receipt_data); + } else { + info!("Trace decoder receipt trie block {block_number} batch {batch_index}, skip printout as diff is not at the leaf node level."); + } + } + + if receipt_trie_diff_point.b_info.node_type == TrieNodeType::Leaf { + if let Some(ref prover_receipt_value) = receipt_trie_diff_point.b_info.value { + let tx_index = + rlp::decode::(receipt_trie_diff_point.b_info.key.as_byte_slice())?; + let prover_receipt_data = rlp::decode::(prover_receipt_value)?; + info!("Prover receipt trie block {block_number} batch {batch_index} output tx index: {tx_index} receipt data: {:#?}", prover_receipt_data); + } else { + info!("Prover receipt trie block {block_number} batch {batch_index}, skip receipt printout as diff is not at the leaf node level."); + } + } + + println!( + "Receipt trie block {block_number} batch {batch_index} diff: {:#?}", + receipt_trie_diff + ); + } else { + println!("Receipt trie block {block_number} batch {batch_index} matches."); + } + Ok(()) }