diff --git a/evm/src/generation/mpt.rs b/evm/src/generation/mpt.rs index 8860024f..23e35694 100644 --- a/evm/src/generation/mpt.rs +++ b/evm/src/generation/mpt.rs @@ -66,6 +66,33 @@ pub(crate) fn all_mpt_prover_inputs_reversed(trie_inputs: &TrieInputs) -> Vec Vec { + let payload_info = PayloadInfo::from(rlp).unwrap(); + let decoded_receipt: LegacyReceiptRlp = rlp::decode(rlp).unwrap(); + let mut parsed_receipt = Vec::new(); + + parsed_receipt.push(payload_info.value_len.into()); // payload_len of the entire receipt + parsed_receipt.push((decoded_receipt.status as u8).into()); + parsed_receipt.push(decoded_receipt.cum_gas_used); + parsed_receipt.extend(decoded_receipt.bloom.iter().map(|byte| U256::from(*byte))); + let encoded_logs = rlp::encode_list(&decoded_receipt.logs); + let logs_payload_info = PayloadInfo::from(&encoded_logs).unwrap(); + parsed_receipt.push(logs_payload_info.value_len.into()); // payload_len of all the logs + parsed_receipt.push(decoded_receipt.logs.len().into()); + + for log in decoded_receipt.logs { + let encoded_log = rlp::encode(&log); + let log_payload_info = PayloadInfo::from(&encoded_log).unwrap(); + parsed_receipt.push(log_payload_info.value_len.into()); // payload of one log + parsed_receipt.push(U256::from_big_endian(&log.address.to_fixed_bytes())); + parsed_receipt.push(log.topics.len().into()); + parsed_receipt.extend(log.topics.iter().map(|topic| U256::from(topic.as_bytes()))); + parsed_receipt.push(log.data.len().into()); + parsed_receipt.extend(log.data.iter().map(|byte| U256::from(*byte))); + } + + parsed_receipt +} /// Generate prover inputs for the initial MPT data, in the format expected by `mpt/load.asm`. pub(crate) fn all_mpt_prover_inputs(trie_inputs: &TrieInputs) -> Vec { let mut prover_inputs = vec![]; @@ -90,33 +117,11 @@ pub(crate) fn all_mpt_prover_inputs(trie_inputs: &TrieInputs) -> Vec { rlp::decode_list(rlp) }); - mpt_prover_inputs(&trie_inputs.receipts_trie, &mut prover_inputs, &|rlp| { - let payload_info = PayloadInfo::from(rlp).unwrap(); - let decoded_receipt: LegacyReceiptRlp = rlp::decode(rlp).unwrap(); - let mut parsed_receipt = Vec::new(); - - parsed_receipt.push(payload_info.value_len.into()); // payload_len of the entire receipt - parsed_receipt.push((decoded_receipt.status as u8).into()); - parsed_receipt.push(decoded_receipt.cum_gas_used); - parsed_receipt.extend(decoded_receipt.bloom.iter().map(|byte| U256::from(*byte))); - let encoded_logs = rlp::encode_list(&decoded_receipt.logs); - let logs_payload_info = PayloadInfo::from(&encoded_logs).unwrap(); - parsed_receipt.push(logs_payload_info.value_len.into()); // payload_len of all the logs - parsed_receipt.push(decoded_receipt.logs.len().into()); - - for log in decoded_receipt.logs { - let encoded_log = rlp::encode(&log); - let log_payload_info = PayloadInfo::from(&encoded_log).unwrap(); - parsed_receipt.push(log_payload_info.value_len.into()); // payload of one log - parsed_receipt.push(U256::from_big_endian(&log.address.to_fixed_bytes())); - parsed_receipt.push(log.topics.len().into()); - parsed_receipt.extend(log.topics.iter().map(|topic| U256::from(topic.as_bytes()))); - parsed_receipt.push(log.data.len().into()); - parsed_receipt.extend(log.data.iter().map(|byte| U256::from(*byte))); - } - - parsed_receipt - }); + mpt_prover_inputs( + &trie_inputs.receipts_trie, + &mut prover_inputs, + &parse_receipts, + ); // Temporary! The actual number of transactions in the trie cannot be known if the trie // contains hash nodes. diff --git a/evm/tests/add11_yml.rs b/evm/tests/add11_yml.rs index 6ed5d155..e0b6f104 100644 --- a/evm/tests/add11_yml.rs +++ b/evm/tests/add11_yml.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::str::FromStr; use std::time::Duration; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; @@ -12,7 +13,7 @@ use plonky2::plonk::config::KeccakGoldilocksConfig; use plonky2::util::timing::TimingTree; use plonky2_evm::all_stark::AllStark; use plonky2_evm::config::StarkConfig; -use plonky2_evm::generation::mpt::AccountRlp; +use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::proof::{BlockMetadata, TrieRoots}; use plonky2_evm::prover::prove; @@ -124,10 +125,22 @@ fn add11_yml() -> anyhow::Result<()> { expected_state_trie_after.insert(to_nibbles, rlp::encode(&to_account_after).to_vec()); expected_state_trie_after }; + + let receipt_0 = LegacyReceiptRlp { + status: true, + cum_gas_used: 0xa868u64.into(), + bloom: vec![0; 256].into(), + logs: vec![], + }; + let mut receipts_trie = HashedPartialTrie::from(Node::Empty); + receipts_trie.insert( + Nibbles::from_str("0x80").unwrap(), + rlp::encode(&receipt_0).to_vec(), + ); let trie_roots_after = TrieRoots { state_root: expected_state_trie_after.hash(), transactions_root: tries_before.transactions_trie.hash(), // TODO: Fix this when we have transactions trie. - receipts_root: tries_before.receipts_trie.hash(), // TODO: Fix this when we have receipts trie. + receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { signed_txns: vec![txn.to_vec()], diff --git a/evm/tests/log_opcode.rs b/evm/tests/log_opcode.rs index 160e0960..8219e4ed 100644 --- a/evm/tests/log_opcode.rs +++ b/evm/tests/log_opcode.rs @@ -111,7 +111,7 @@ fn test_log_opcodes() -> anyhow::Result<()> { logs: vec![log_0], }; - // Insert the first receipt into the initial receipt trie. + // Insert the first receipt into the initial receipt trie. The initial receipts trie has an initial node with a random nibble. let mut receipts_trie = HashedPartialTrie::from(Node::Empty); receipts_trie.insert( Nibbles::from_str("0x1337").unwrap(), diff --git a/evm/tests/simple_transfer.rs b/evm/tests/simple_transfer.rs index 1666d2f9..5bf95f58 100644 --- a/evm/tests/simple_transfer.rs +++ b/evm/tests/simple_transfer.rs @@ -1,4 +1,5 @@ use std::collections::HashMap; +use std::str::FromStr; use std::time::Duration; use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; @@ -12,7 +13,7 @@ use plonky2::plonk::config::KeccakGoldilocksConfig; use plonky2::util::timing::TimingTree; use plonky2_evm::all_stark::AllStark; use plonky2_evm::config::StarkConfig; -use plonky2_evm::generation::mpt::AccountRlp; +use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use plonky2_evm::generation::{GenerationInputs, TrieInputs}; use plonky2_evm::proof::{BlockMetadata, TrieRoots}; use plonky2_evm::prover::prove; @@ -110,10 +111,23 @@ fn test_simple_transfer() -> anyhow::Result<()> { } .into() }; + + let receipt_0 = LegacyReceiptRlp { + status: true, + cum_gas_used: 21032.into(), + bloom: vec![0; 256].into(), + logs: vec![], + }; + let mut receipts_trie = HashedPartialTrie::from(Node::Empty); + receipts_trie.insert( + Nibbles::from_str("0x80").unwrap(), + rlp::encode(&receipt_0).to_vec(), + ); + let trie_roots_after = TrieRoots { state_root: expected_state_trie_after.hash(), transactions_root: tries_before.transactions_trie.hash(), // TODO: Fix this when we have transactions trie. - receipts_root: tries_before.receipts_trie.hash(), // TODO: Fix this when we have receipts trie. + receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { signed_txns: vec![txn.to_vec()],