From 954d1a77c6fa9068ec14fc25e4d0b3b8a63558fb Mon Sep 17 00:00:00 2001 From: Robin Salen <30937548+Nashtare@users.noreply.github.com> Date: Thu, 9 Nov 2023 09:34:12 -0500 Subject: [PATCH] Remove logic for multiple txns at once (#1341) * Have prover take only a single txn at most * Update comment * Apply review --- evm/src/cpu/kernel/asm/core/process_txn.asm | 8 +- evm/src/cpu/kernel/asm/main.asm | 14 +- evm/src/generation/mod.rs | 5 +- evm/src/generation/prover_input.rs | 12 +- evm/src/generation/rlp.rs | 14 +- evm/src/generation/state.rs | 8 +- evm/tests/add11_yml.rs | 2 +- evm/tests/basic_smart_contract.rs | 2 +- evm/tests/empty_txn_list.rs | 2 +- evm/tests/erc20.rs | 2 +- evm/tests/log_opcode.rs | 184 +-------------- evm/tests/many_transactions.rs | 247 -------------------- evm/tests/self_balance_gas_cost.rs | 2 +- evm/tests/selfdestruct.rs | 2 +- evm/tests/simple_transfer.rs | 2 +- evm/tests/withdrawals.rs | 2 +- 16 files changed, 36 insertions(+), 472 deletions(-) delete mode 100644 evm/tests/many_transactions.rs diff --git a/evm/src/cpu/kernel/asm/core/process_txn.asm b/evm/src/cpu/kernel/asm/core/process_txn.asm index 95a36831b4..3e7e35db70 100644 --- a/evm/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm/src/cpu/kernel/asm/core/process_txn.asm @@ -452,22 +452,22 @@ global invalid_txn: POP %mload_txn_field(@TXN_FIELD_GAS_LIMIT) PUSH 0 - %jump(txn_loop_after) + %jump(txn_after) global invalid_txn_1: %pop2 %mload_txn_field(@TXN_FIELD_GAS_LIMIT) PUSH 0 - %jump(txn_loop_after) + %jump(txn_after) global invalid_txn_2: %pop3 %mload_txn_field(@TXN_FIELD_GAS_LIMIT) PUSH 0 - %jump(txn_loop_after) + %jump(txn_after) global invalid_txn_3: %pop4 %mload_txn_field(@TXN_FIELD_GAS_LIMIT) PUSH 0 - %jump(txn_loop_after) + %jump(txn_after) diff --git a/evm/src/cpu/kernel/asm/main.asm b/evm/src/cpu/kernel/asm/main.asm index abdc183617..7a6f12279f 100644 --- a/evm/src/cpu/kernel/asm/main.asm +++ b/evm/src/cpu/kernel/asm/main.asm @@ -14,7 +14,7 @@ global hash_initial_tries: %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE) %assert_eq %mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE) %assert_eq -global start_txns: +global start_txn: // stack: (empty) // The special case of an empty trie (i.e. for the first transaction) // is handled outside of the kernel. @@ -29,24 +29,22 @@ global start_txns: SWAP2 // stack: init_gas_used, txn_counter, num_nibbles, txn_nb -txn_loop: - // If the prover has no more txns for us to process, halt. - PROVER_INPUT(end_of_txns) + // If the prover has no txn for us to process, halt. + PROVER_INPUT(no_txn) %jumpi(execute_withdrawals) - // Call route_txn. When we return, continue the txn loop. - PUSH txn_loop_after + // Call route_txn. When we return, we will process the txn receipt. + PUSH txn_after // stack: retdest, prev_gas_used, txn_counter, num_nibbles, txn_nb DUP4 DUP4 %increment_bounded_rlp %stack (next_txn_counter, next_num_nibbles, retdest, prev_gas_used, txn_counter, num_nibbles) -> (txn_counter, num_nibbles, retdest, prev_gas_used, txn_counter, num_nibbles, next_txn_counter, next_num_nibbles) %jump(route_txn) -global txn_loop_after: +global txn_after: // stack: success, leftover_gas, cur_cum_gas, prev_txn_counter, prev_num_nibbles, txn_counter, num_nibbles, txn_nb %process_receipt // stack: new_cum_gas, txn_counter, num_nibbles, txn_nb SWAP3 %increment SWAP3 - %jump(txn_loop) global execute_withdrawals: // stack: cum_gas, txn_counter, num_nibbles, txn_nb diff --git a/evm/src/generation/mod.rs b/evm/src/generation/mod.rs index 4751d92116..0deba3a274 100644 --- a/evm/src/generation/mod.rs +++ b/evm/src/generation/mod.rs @@ -46,7 +46,8 @@ pub struct GenerationInputs { pub gas_used_after: U256, pub block_bloom_after: [U256; 8], - pub signed_txns: Vec>, + // A None would yield an empty proof, otherwise this contains the encoding of a transaction. + pub signed_txn: Option>, // Withdrawal pairs `(addr, amount)`. At the end of the txs, `amount` is added to `addr`'s balance. See EIP-4895. pub withdrawals: Vec<(Address, U256)>, pub tries: TrieInputs, @@ -122,7 +123,7 @@ fn apply_metadata_and_tries_memops, const D: usize> (GlobalMetadata::TxnNumberBefore, inputs.txn_number_before), ( GlobalMetadata::TxnNumberAfter, - inputs.txn_number_before + inputs.signed_txns.len(), + inputs.txn_number_before + if inputs.signed_txn.is_some() { 1 } else { 0 }, ), ( GlobalMetadata::StateTrieRootDigestBefore, diff --git a/evm/src/generation/prover_input.rs b/evm/src/generation/prover_input.rs index 63277c44b8..6699a12dec 100644 --- a/evm/src/generation/prover_input.rs +++ b/evm/src/generation/prover_input.rs @@ -35,7 +35,7 @@ impl From> for ProverInputFn { impl GenerationState { pub(crate) fn prover_input(&mut self, input_fn: &ProverInputFn) -> Result { match input_fn.0[0].as_str() { - "end_of_txns" => self.run_end_of_txns(), + "no_txn" => self.no_txn(), "ff" => self.run_ff(input_fn), "sf" => self.run_sf(input_fn), "ffe" => self.run_ffe(input_fn), @@ -49,14 +49,8 @@ impl GenerationState { } } - fn run_end_of_txns(&mut self) -> Result { - let end = self.next_txn_index == self.inputs.signed_txns.len(); - if end { - Ok(U256::one()) - } else { - self.next_txn_index += 1; - Ok(U256::zero()) - } + fn no_txn(&mut self) -> Result { + Ok(U256::from(self.inputs.signed_txn.is_none() as u8)) } /// Finite field operations. diff --git a/evm/src/generation/rlp.rs b/evm/src/generation/rlp.rs index f28272a27b..6a6b4b13c1 100644 --- a/evm/src/generation/rlp.rs +++ b/evm/src/generation/rlp.rs @@ -1,18 +1,16 @@ use ethereum_types::U256; -pub(crate) fn all_rlp_prover_inputs_reversed(signed_txns: &[Vec]) -> Vec { - let mut inputs = all_rlp_prover_inputs(signed_txns); +pub(crate) fn all_rlp_prover_inputs_reversed(signed_txn: &[u8]) -> Vec { + let mut inputs = all_rlp_prover_inputs(signed_txn); inputs.reverse(); inputs } -fn all_rlp_prover_inputs(signed_txns: &[Vec]) -> Vec { +fn all_rlp_prover_inputs(signed_txn: &[u8]) -> Vec { let mut prover_inputs = vec![]; - for txn in signed_txns { - prover_inputs.push(txn.len().into()); - for &byte in txn { - prover_inputs.push(byte.into()); - } + prover_inputs.push(signed_txn.len().into()); + for &byte in signed_txn { + prover_inputs.push(byte.into()); } prover_inputs } diff --git a/evm/src/generation/state.rs b/evm/src/generation/state.rs index fa0c171bf3..506738ba72 100644 --- a/evm/src/generation/state.rs +++ b/evm/src/generation/state.rs @@ -29,8 +29,6 @@ pub(crate) struct GenerationState { pub(crate) memory: MemoryState, pub(crate) traces: Traces, - pub(crate) next_txn_index: usize, - /// Prover inputs containing MPT data, in reverse order so that the next input can be obtained /// via `pop()`. pub(crate) mpt_prover_inputs: Vec, @@ -54,7 +52,7 @@ pub(crate) struct GenerationState { impl GenerationState { pub(crate) fn new(inputs: GenerationInputs, kernel_code: &[u8]) -> Result { - log::debug!("Input signed_txns: {:?}", &inputs.signed_txns); + log::debug!("Input signed_txn: {:?}", &inputs.signed_txn); log::debug!("Input state_trie: {:?}", &inputs.tries.state_trie); log::debug!( "Input transactions_trie: {:?}", @@ -64,7 +62,8 @@ impl GenerationState { log::debug!("Input storage_tries: {:?}", &inputs.tries.storage_tries); log::debug!("Input contract_code: {:?}", &inputs.contract_code); let mpt_prover_inputs = all_mpt_prover_inputs_reversed(&inputs.tries)?; - let rlp_prover_inputs = all_rlp_prover_inputs_reversed(&inputs.signed_txns); + let rlp_prover_inputs = + all_rlp_prover_inputs_reversed(inputs.signed_txn.as_ref().unwrap_or(&vec![])); let withdrawal_prover_inputs = all_withdrawals_prover_inputs_reversed(&inputs.withdrawals); let bignum_modmul_result_limbs = Vec::new(); @@ -73,7 +72,6 @@ impl GenerationState { registers: Default::default(), memory: MemoryState::new(kernel_code), traces: Traces::default(), - next_txn_index: 0, mpt_prover_inputs, rlp_prover_inputs, withdrawal_prover_inputs, diff --git a/evm/tests/add11_yml.rs b/evm/tests/add11_yml.rs index 0a0224332e..1523943ff4 100644 --- a/evm/tests/add11_yml.rs +++ b/evm/tests/add11_yml.rs @@ -151,7 +151,7 @@ fn add11_yml() -> anyhow::Result<()> { receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, diff --git a/evm/tests/basic_smart_contract.rs b/evm/tests/basic_smart_contract.rs index 0615a26c70..6f73f9356f 100644 --- a/evm/tests/basic_smart_contract.rs +++ b/evm/tests/basic_smart_contract.rs @@ -183,7 +183,7 @@ fn test_basic_smart_contract() -> anyhow::Result<()> { receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, diff --git a/evm/tests/empty_txn_list.rs b/evm/tests/empty_txn_list.rs index 0f2082a2ef..3072b48b0d 100644 --- a/evm/tests/empty_txn_list.rs +++ b/evm/tests/empty_txn_list.rs @@ -48,7 +48,7 @@ fn test_empty_txn_list() -> anyhow::Result<()> { receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { - signed_txns: vec![], + signed_txn: None, withdrawals: vec![], tries: TrieInputs { state_trie, diff --git a/evm/tests/erc20.rs b/evm/tests/erc20.rs index 21951bc932..435919c198 100644 --- a/evm/tests/erc20.rs +++ b/evm/tests/erc20.rs @@ -159,7 +159,7 @@ fn test_erc20() -> anyhow::Result<()> { receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, diff --git a/evm/tests/log_opcode.rs b/evm/tests/log_opcode.rs index d4a18679ac..fdb12dfbb4 100644 --- a/evm/tests/log_opcode.rs +++ b/evm/tests/log_opcode.rs @@ -229,7 +229,7 @@ fn test_log_opcodes() -> anyhow::Result<()> { .unwrap(), ]; let inputs = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, @@ -437,7 +437,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> { }; let inputs_first = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after: tries_after, @@ -582,7 +582,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> { U256::from_dec_str("2722259584404615024560450425766186844160").unwrap(), ]; let inputs = GenerationInputs { - signed_txns: vec![txn_2.to_vec()], + signed_txn: Some(txn_2.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, @@ -753,184 +753,6 @@ fn test_txn_and_receipt_trie_hash() -> anyhow::Result<()> { Ok(()) } -#[test] -#[ignore] // Too slow to run on CI. -fn test_two_txn() -> anyhow::Result<()> { - init_logger(); - - let all_stark = AllStark::::default(); - let config = StarkConfig::standard_fast_config(); - - let beneficiary = hex!("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"); - let sender = hex!("af1276cbb260bb13deddb4209ae99ae6e497f446"); - // Private key: DCDFF53B4F013DBCDC717F89FE3BF4D8B10512AAE282B48E01D7530470382701 - let to = hex!("095e7baea6a6c7c4c2dfeb977efac326af552d87"); - - let beneficiary_state_key = keccak(beneficiary); - let sender_state_key = keccak(sender); - let to_hashed = keccak(to); - - let beneficiary_nibbles = Nibbles::from_bytes_be(beneficiary_state_key.as_bytes()).unwrap(); - let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap(); - let to_nibbles = Nibbles::from_bytes_be(to_hashed.as_bytes()).unwrap(); - - // Set accounts before the transaction. - let beneficiary_account_before = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - - let sender_balance_before = 50000000000000000u64; - let sender_account_before = AccountRlp { - balance: sender_balance_before.into(), - ..AccountRlp::default() - }; - let to_account_before = AccountRlp { - ..AccountRlp::default() - }; - - // Initialize the state trie with three accounts. - let mut state_trie_before = HashedPartialTrie::from(Node::Empty); - state_trie_before.insert( - beneficiary_nibbles, - rlp::encode(&beneficiary_account_before).to_vec(), - ); - state_trie_before.insert(sender_nibbles, rlp::encode(&sender_account_before).to_vec()); - state_trie_before.insert(to_nibbles, rlp::encode(&to_account_before).to_vec()); - - let tries_before = TrieInputs { - state_trie: state_trie_before, - transactions_trie: Node::Empty.into(), - receipts_trie: Node::Empty.into(), - storage_tries: vec![(to_hashed, Node::Empty.into())], - }; - - // Prove two simple transfers. - let gas_price = 10; - let txn_value = 0x11c37937e08000u64; - let txn_0 = hex!("f866800a82520894095e7baea6a6c7c4c2dfeb977efac326af552d878711c37937e080008026a01fcd0ce88ac7600698a771f206df24b70e67981b6f107bd7c1c24ea94f113bcba00d87cc5c7afc2988e4ff200b5a0c7016b0d5498bbc692065ca983fcbbfe02555"); - let txn_1 = hex!("f866010a82520894095e7baea6a6c7c4c2dfeb977efac326af552d878711c37937e080008026a0d8123f5f537bd3a67283f67eb136f7accdfc4ef012cfbfd3fb1d0ac7fd01b96fa004666d9feef90a1eb568570374dd19977d4da231b289d769e6f95105c06fd672"); - - let block_metadata = BlockMetadata { - block_beneficiary: Address::from(beneficiary), - block_timestamp: 0x03e8.into(), - block_number: 1.into(), - block_difficulty: 0x020000.into(), - block_random: H256::from_uint(&0x020000.into()), - block_gaslimit: 0xffffffffu32.into(), - block_chain_id: 1.into(), - block_base_fee: 0xa.into(), - block_gas_used: 0.into(), - block_bloom: [0.into(); 8], - }; - - let mut contract_code = HashMap::new(); - contract_code.insert(keccak(vec![]), vec![]); - - // Update accounts - let beneficiary_account_after = AccountRlp { - nonce: 1.into(), - ..AccountRlp::default() - }; - - let sender_balance_after = sender_balance_before - gas_price * 21000 * 2 - txn_value * 2; - let sender_account_after = AccountRlp { - balance: sender_balance_after.into(), - nonce: 2.into(), - ..AccountRlp::default() - }; - let to_account_after = AccountRlp { - balance: (2 * txn_value).into(), - ..AccountRlp::default() - }; - - // Update the state trie. - let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty); - expected_state_trie_after.insert( - beneficiary_nibbles, - rlp::encode(&beneficiary_account_after).to_vec(), - ); - expected_state_trie_after.insert(sender_nibbles, rlp::encode(&sender_account_after).to_vec()); - expected_state_trie_after.insert(to_nibbles, rlp::encode(&to_account_after).to_vec()); - - // Compute new receipt trie. - let mut receipts_trie = HashedPartialTrie::from(Node::Empty); - - let receipt_0 = LegacyReceiptRlp { - status: true, - cum_gas_used: 21000u64.into(), - bloom: [0x00; 256].to_vec().into(), - logs: vec![], - }; - - let receipt_1 = LegacyReceiptRlp { - status: true, - cum_gas_used: 42000u64.into(), - bloom: [0x00; 256].to_vec().into(), - logs: vec![], - }; - - receipts_trie.insert( - Nibbles::from_str("0x80").unwrap(), - rlp::encode(&receipt_0).to_vec(), - ); - - receipts_trie.insert( - Nibbles::from_str("0x01").unwrap(), - rlp::encode(&receipt_1).to_vec(), - ); - - let mut transactions_trie: HashedPartialTrie = Node::Leaf { - nibbles: Nibbles::from_str("0x80").unwrap(), - value: txn_0.to_vec(), - } - .into(); - - transactions_trie.insert(Nibbles::from_str("0x01").unwrap(), txn_1.to_vec()); - - let trie_roots_after = TrieRoots { - state_root: expected_state_trie_after.hash(), - transactions_root: transactions_trie.hash(), - receipts_root: receipts_trie.hash(), - }; - let inputs = GenerationInputs { - signed_txns: vec![txn_0.to_vec(), txn_1.to_vec()], - withdrawals: vec![], - tries: tries_before, - trie_roots_after, - contract_code, - genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(), - block_metadata, - txn_number_before: 0.into(), - gas_used_before: 0.into(), - gas_used_after: 42000u64.into(), - block_bloom_before: [0.into(); 8], - block_bloom_after: [0.into(); 8], - block_hashes: BlockHashes { - prev_hashes: vec![H256::default(); 256], - cur_hash: H256::default(), - }, - addresses: vec![], - }; - - let mut timing = TimingTree::new("prove", log::Level::Debug); - let proof = prove::(&all_stark, &config, inputs, &mut timing)?; - timing.filter(Duration::from_millis(100)).print(); - - // Assert trie roots. - assert_eq!( - proof.public_values.trie_roots_after.state_root, - expected_state_trie_after.hash() - ); - - assert_eq!( - proof.public_values.trie_roots_after.receipts_root, - receipts_trie.hash() - ); - - verify_proof(&all_stark, proof, &config) -} - fn init_logger() { let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); } diff --git a/evm/tests/many_transactions.rs b/evm/tests/many_transactions.rs deleted file mode 100644 index 837c77e320..0000000000 --- a/evm/tests/many_transactions.rs +++ /dev/null @@ -1,247 +0,0 @@ -#![allow(clippy::upper_case_acronyms)] - -use std::collections::HashMap; -use std::str::FromStr; -use std::time::Duration; - -use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; -use eth_trie_utils::nibbles::Nibbles; -use eth_trie_utils::partial_trie::{HashedPartialTrie, PartialTrie}; -use ethereum_types::{Address, H256, U256}; -use hex_literal::hex; -use keccak_hash::keccak; -use plonky2::field::goldilocks_field::GoldilocksField; -use plonky2::plonk::config::KeccakGoldilocksConfig; -use plonky2::util::timing::TimingTree; -use plonky2_evm::all_stark::AllStark; -use plonky2_evm::config::StarkConfig; -use plonky2_evm::cpu::kernel::opcodes::{get_opcode, get_push_opcode}; -use plonky2_evm::generation::mpt::{AccountRlp, LegacyReceiptRlp}; -use plonky2_evm::generation::{GenerationInputs, TrieInputs}; -use plonky2_evm::proof::{BlockHashes, BlockMetadata, TrieRoots}; -use plonky2_evm::prover::prove; -use plonky2_evm::verifier::verify_proof; -use plonky2_evm::Node; - -type F = GoldilocksField; -const D: usize = 2; -type C = KeccakGoldilocksConfig; - -/// Test the validity of four transactions, where only the first one is valid and the other three abort. -#[test] -fn test_four_transactions() -> anyhow::Result<()> { - init_logger(); - - let all_stark = AllStark::::default(); - let config = StarkConfig::standard_fast_config(); - - let beneficiary = hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); - let sender = hex!("2c7536e3605d9c16a7a3d7b1898e529396a65c23"); - let to = hex!("a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0"); - - let beneficiary_state_key = keccak(beneficiary); - let sender_state_key = keccak(sender); - let to_state_key = keccak(to); - - let beneficiary_nibbles = Nibbles::from_bytes_be(beneficiary_state_key.as_bytes()).unwrap(); - let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap(); - let to_nibbles = Nibbles::from_bytes_be(to_state_key.as_bytes()).unwrap(); - - let push1 = get_push_opcode(1); - let add = get_opcode("ADD"); - let stop = get_opcode("STOP"); - let code = [push1, 3, push1, 4, add, stop]; - let code_gas = 3 + 3 + 3; - let code_hash = keccak(code); - - let beneficiary_account_before = AccountRlp::default(); - let sender_account_before = AccountRlp { - nonce: 5.into(), - - balance: eth_to_wei(100_000.into()), - - ..AccountRlp::default() - }; - let to_account_before = AccountRlp { - code_hash, - ..AccountRlp::default() - }; - - let state_trie_before = { - let mut children = core::array::from_fn(|_| Node::Empty.into()); - children[sender_nibbles.get_nibble(0) as usize] = Node::Leaf { - nibbles: sender_nibbles.truncate_n_nibbles_front(1), - - value: rlp::encode(&sender_account_before).to_vec(), - } - .into(); - children[to_nibbles.get_nibble(0) as usize] = Node::Leaf { - nibbles: to_nibbles.truncate_n_nibbles_front(1), - - value: rlp::encode(&to_account_before).to_vec(), - } - .into(); - Node::Branch { - children, - value: vec![], - } - } - .into(); - - let tries_before = TrieInputs { - state_trie: state_trie_before, - transactions_trie: Node::Empty.into(), - receipts_trie: Node::Empty.into(), - storage_tries: vec![], - }; - - // Generated using a little py-evm script. - let txn1 = hex!("f861050a8255f094a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0648242421ba02c89eb757d9deeb1f5b3859a9d4d679951ef610ac47ad4608dc142beb1b7e313a05af7e9fbab825455d36c36c7f4cfcafbeafa9a77bdff936b52afb36d4fe4bcdd"); - let txn2 = hex!("f863800a83061a8094095e7baea6a6c7c4c2dfeb977efac326af552d87830186a0801ba0ffb600e63115a7362e7811894a91d8ba4330e526f22121c994c4692035dfdfd5a06198379fcac8de3dbfac48b165df4bf88e2088f294b61efb9a65fe2281c76e16"); - let txn3 = hex!("f861800a8405f5e10094100000000000000000000000000000000000000080801ba07e09e26678ed4fac08a249ebe8ed680bf9051a5e14ad223e4b2b9d26e0208f37a05f6e3f188e3e6eab7d7d3b6568f5eac7d687b08d307d3154ccd8c87b4630509b"); - let txn4 = hex!("f866800a82520894095e7baea6a6c7c4c2dfeb977efac326af552d878711c37937e080008026a01fcd0ce88ac7600698a771f206df24b70e67981b6f107bd7c1c24ea94f113bcba00d87cc5c7afc2988e4ff200b5a0c7016b0d5498bbc692065ca983fcbbfe02555"); - - let txdata_gas = 2 * 16; - let gas_used = 21_000 + code_gas + txdata_gas; - - let value = U256::from(100u32); - - let block_metadata = BlockMetadata { - block_beneficiary: Address::from(beneficiary), - block_timestamp: 0x03e8.into(), - block_number: 1.into(), - block_difficulty: 0x020000.into(), - block_gaslimit: 0x445566u64.into(), - block_chain_id: 1.into(), - block_gas_used: gas_used.into(), - ..BlockMetadata::default() - }; - - let mut contract_code = HashMap::new(); - contract_code.insert(keccak(vec![]), vec![]); - contract_code.insert(code_hash, code.to_vec()); - - // Update trie roots after the 4 transactions. - // State trie. - let expected_state_trie_after: HashedPartialTrie = { - let beneficiary_account_after = AccountRlp { - balance: beneficiary_account_before.balance + gas_used * 10, - ..beneficiary_account_before - }; - let sender_account_after = AccountRlp { - balance: sender_account_before.balance - value - gas_used * 10, - nonce: sender_account_before.nonce + 1, - ..sender_account_before - }; - let to_account_after = AccountRlp { - balance: to_account_before.balance + value, - ..to_account_before - }; - - let mut children = core::array::from_fn(|_| Node::Empty.into()); - children[beneficiary_nibbles.get_nibble(0) as usize] = Node::Leaf { - nibbles: beneficiary_nibbles.truncate_n_nibbles_front(1), - - value: rlp::encode(&beneficiary_account_after).to_vec(), - } - .into(); - children[sender_nibbles.get_nibble(0) as usize] = Node::Leaf { - nibbles: sender_nibbles.truncate_n_nibbles_front(1), - - value: rlp::encode(&sender_account_after).to_vec(), - } - .into(); - children[to_nibbles.get_nibble(0) as usize] = Node::Leaf { - nibbles: to_nibbles.truncate_n_nibbles_front(1), - - value: rlp::encode(&to_account_after).to_vec(), - } - .into(); - Node::Branch { - children, - value: vec![], - } - } - .into(); - - // Transactions trie. - let mut transactions_trie: HashedPartialTrie = Node::Leaf { - nibbles: Nibbles::from_str("0x80").unwrap(), - value: txn1.to_vec(), - } - .into(); - transactions_trie.insert(Nibbles::from_str("0x01").unwrap(), txn2.to_vec()); - transactions_trie.insert(Nibbles::from_str("0x02").unwrap(), txn3.to_vec()); - transactions_trie.insert(Nibbles::from_str("0x03").unwrap(), txn4.to_vec()); - - // Receipts trie. - let mut receipts_trie = HashedPartialTrie::from(Node::Empty); - let receipt_0 = LegacyReceiptRlp { - status: true, - cum_gas_used: gas_used.into(), - bloom: [0x00; 256].to_vec().into(), - logs: vec![], - }; - let receipt_1 = LegacyReceiptRlp { - status: false, - cum_gas_used: gas_used.into(), - bloom: [0x00; 256].to_vec().into(), - logs: vec![], - }; - receipts_trie.insert( - Nibbles::from_str("0x80").unwrap(), - rlp::encode(&receipt_0).to_vec(), - ); - receipts_trie.insert( - Nibbles::from_str("0x01").unwrap(), - rlp::encode(&receipt_1).to_vec(), - ); - receipts_trie.insert( - Nibbles::from_str("0x02").unwrap(), - rlp::encode(&receipt_1).to_vec(), - ); - receipts_trie.insert( - Nibbles::from_str("0x03").unwrap(), - rlp::encode(&receipt_1).to_vec(), - ); - - let trie_roots_after = TrieRoots { - state_root: expected_state_trie_after.hash(), - transactions_root: transactions_trie.hash(), - receipts_root: receipts_trie.hash(), - }; - let inputs = GenerationInputs { - signed_txns: vec![txn1.to_vec(), txn2.to_vec(), txn3.to_vec(), txn4.to_vec()], - withdrawals: vec![], - tries: tries_before, - trie_roots_after, - genesis_state_trie_root: HashedPartialTrie::from(Node::Empty).hash(), - contract_code, - block_metadata, - addresses: vec![], - block_bloom_before: [0.into(); 8], - gas_used_before: 0.into(), - gas_used_after: gas_used.into(), - txn_number_before: 0.into(), - block_bloom_after: [0.into(); 8], - block_hashes: BlockHashes { - prev_hashes: vec![H256::default(); 256], - cur_hash: H256::default(), - }, - }; - - let mut timing = TimingTree::new("prove", log::Level::Debug); - let proof = prove::(&all_stark, &config, inputs, &mut timing)?; - timing.filter(Duration::from_millis(100)).print(); - - verify_proof(&all_stark, proof, &config) -} - -fn eth_to_wei(eth: U256) -> U256 { - // 1 ether = 10^18 wei. - eth * U256::from(10).pow(18.into()) -} - -fn init_logger() { - let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); -} diff --git a/evm/tests/self_balance_gas_cost.rs b/evm/tests/self_balance_gas_cost.rs index bd8bf838b7..59912bc937 100644 --- a/evm/tests/self_balance_gas_cost.rs +++ b/evm/tests/self_balance_gas_cost.rs @@ -170,7 +170,7 @@ fn self_balance_gas_cost() -> anyhow::Result<()> { receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, diff --git a/evm/tests/selfdestruct.rs b/evm/tests/selfdestruct.rs index 2f9ab4f4d4..4d76701244 100644 --- a/evm/tests/selfdestruct.rs +++ b/evm/tests/selfdestruct.rs @@ -122,7 +122,7 @@ fn test_selfdestruct() -> anyhow::Result<()> { receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, diff --git a/evm/tests/simple_transfer.rs b/evm/tests/simple_transfer.rs index 9902616fe0..d013dc76a8 100644 --- a/evm/tests/simple_transfer.rs +++ b/evm/tests/simple_transfer.rs @@ -138,7 +138,7 @@ fn test_simple_transfer() -> anyhow::Result<()> { receipts_root: receipts_trie.hash(), }; let inputs = GenerationInputs { - signed_txns: vec![txn.to_vec()], + signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, trie_roots_after, diff --git a/evm/tests/withdrawals.rs b/evm/tests/withdrawals.rs index d5b7ba1b9f..737335b362 100644 --- a/evm/tests/withdrawals.rs +++ b/evm/tests/withdrawals.rs @@ -63,7 +63,7 @@ fn test_withdrawals() -> anyhow::Result<()> { }; let inputs = GenerationInputs { - signed_txns: vec![], + signed_txn: None, withdrawals, tries: TrieInputs { state_trie: state_trie_before,