From a50e2dbf88dc067fb1a67f469d83820855cc70af Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 3 May 2024 10:32:35 +0200 Subject: [PATCH 001/118] [WIP] add account to linked list --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm new file mode 100644 index 000000000..b37c41304 --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -0,0 +1,166 @@ +/// Access lists for addresses and storage keys. +/// The access list is stored in a sorted linked list in SEGMENT_ACCESSED_ADDRESSES for addresses and +/// SEGMENT_ACCESSED_STORAGE_KEYS segment for storage keys. The length of +/// the segments is stored in the global metadata. +/// Both arrays are stored in the kernel memory (context=0). +/// Searching and inserting is done by guessing the predecessor in the list. +/// If the address/storage key isn't found in the array, it is inserted at the end. + +// Initialize an empty linked list (@U256_MAX)⮌ +// which is written as [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST +// The stire values at the respective positions are: +// - 0: The account key +// - 1: A ptr to the payload (the account values) +// - 2: A counter indicating if the number of times this address have been accessed. +// - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. +global init_accounts_linked_list: + // stack: (empty) + + // Initialize SEGMENT_ACCOUNTS_LINKED_LIST + // Store @U256_MAX at the beggining of the segment + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST // ctx == virt == 0 + DUP1 + PUSH @U256_MAX + MSTORE_GENERAL + // Store @SEGMENT_ACCOUNTS_LINKED_LIST at address 2 + %add_const(3) + DUP1 + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + MSTORE_GENERAL + + // Store the segment scaled length + %increment + %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) + JUMP + +%macro init_accounts_linked_list + PUSH %%after + %jump(init_account_linked_list) +%%after: +%endmacro + +%macro insert_account + %stack (addr, ptr) -> (addr, ptr, %%after) + %jump(insert_account) +%%after: + // stack: cold_access +%endmacro + +%macro insert_account_no_return + %insert_account + POP +%endmacro + +// Multiply the ptr at the top of the stack by 4 +// and abort if 4*ptr - SEGMENT_ACCOUNTS_LINKED_LIST >= @GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN +// In this way ptr must be poiting to the begining of a node. +%macro get_valid_account_ptr + // stack: ptr + %mul_const(4) + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + DUP2 + SUB + %assert_lt_const(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) + // stack: 2*ptr +%endmacro + +/// Inserts the account addr and payload otr into the linked list if it is not already present. +/// `value` should be the current storage value at the slot `(addr, key)`. +/// Return `0, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present +/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +global insert_account: + // stack: addr, payload_ptr, retdest + PROVER_INPUT(linked_lists::insert_account) + // stack: pred_ptr/4, addr, payload_ptr, retdest + %get_valid_account_ptr + // stack: pred_ptr, addr, payload_ptr, retdest + DUP1 + MLOAD_GENERAL + DUP1 + // stack: pred_addr, pred_addr, pred_ptr, addr, payload_ptr, retdest + DUP4 GT + DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) + ADD // OR + // If the predesessor is strictly smaller or the predecessor is the special + // node with key @U256_MAX (and hence we're inserting a new minimum), then + // we need to insert a new node. + %jumpi(insert_new_account) + // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. + DUP3 + %assert_eq + // stack: pred_ptr, addr, payload_ptr, retdest + + // stack: pred_ptr, addr, payload_ptr, retdest + // Check that this is not a deleted node + DUP1 + %add_const(3) + MLOAD_GENERAL + %jump_neq_const(@U256_MAX, account_found) + // The storage key is not in the list. + PANIC +account_found: + // The address was already in the list + // stack: pred_ptr, addr, payload_ptr, retdest + // Load the access counter + DUP1 + %increment + MLOAD_GENERAL + // stack: orig_payload_ptr, pred_ptr, addr, payload_ptr, retdest + SWAP1 + %add_const(2) + DUP1 + MLOAD_GENERAL + %increment + // stack: access_ctr, access_ctr_ptr, orig_payload_ptr, addr, payload_ptr, retdest + SWAP1 + DUP2 + // stack: access_ctr, access_ctr_ptr, access_ctr, orig_payload_ptr, addr, payload_ptr, retdest + MSTORE_GENERAL + // stack: access_ctr, orig_payload_ptr, addr, payload_ptr, retdest + // If access_ctr == 1 then this it's a cold access + %eq_const(0) + %stack (cold_access, orig_payload_ptr, addr, payload_ptr) -> (retdest, cold_access, orig_payload_ptr) + JUMP + + +/// Remove the storage key and its value from the access list. +/// Panics if the key is not in the list. +global remove_account: + // stack: addr, key, retdest + PROVER_INPUT(access_lists::remove_account) + // stack: pred_ptr/4, addr, key, retdest + %get_valid_storage_ptr + // stack: pred_ptr, addr, key, retdest + %add_const(3) + // stack: next_ptr_ptr, addr, key, retdest + DUP1 + MLOAD_GENERAL + // stack: next_ptr, next_ptr_ptr, addr, key, retdest + DUP1 + %increment + MLOAD_GENERAL + // stack: next_key, next_ptr, next_ptr_ptr, addr, key, retdest + DUP5 + EQ + DUP2 + MLOAD_GENERAL + // stack: next_addr, next_key == key, next_ptr, next_ptr_ptr, addr, key, retdest + DUP5 + EQ + MUL // AND + // stack: next_addr == addr AND next_key == key, next_ptr, next_ptr_ptr, addr, key, retdest + %assert_nonzero + // stack: next_ptr, next_ptr_ptr, addr, key, retdest + %add_const(3) + // stack: next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + DUP1 + MLOAD_GENERAL + // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + SWAP1 + PUSH @U256_MAX + MSTORE_GENERAL + // stack: next_next_ptr, next_ptr_ptr, addr, key, retdest + MSTORE_GENERAL + %pop2 + JUMP \ No newline at end of file From 52dc55d407c1040d0893cda049ee8e3e3c9d904f Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 3 May 2024 17:14:29 +0200 Subject: [PATCH 002/118] Add account linked list and some unit tests --- .../src/cpu/kernel/aggregator.rs | 1 + .../src/cpu/kernel/asm/mpt/linked_list.asm | 115 +++++--- .../src/cpu/kernel/asm/util/assertions.asm | 6 +- .../cpu/kernel/constants/global_metadata.rs | 8 +- .../src/cpu/kernel/tests/mpt/linked_list.rs | 278 ++++++++++++++++++ .../src/cpu/kernel/tests/mpt/mod.rs | 1 + .../src/generation/prover_input.rs | 55 +++- evm_arithmetization/src/memory/segments.rs | 7 +- 8 files changed, 431 insertions(+), 40 deletions(-) create mode 100644 evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs diff --git a/evm_arithmetization/src/cpu/kernel/aggregator.rs b/evm_arithmetization/src/cpu/kernel/aggregator.rs index 637655255..8c5439cf1 100644 --- a/evm_arithmetization/src/cpu/kernel/aggregator.rs +++ b/evm_arithmetization/src/cpu/kernel/aggregator.rs @@ -122,6 +122,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/mpt/insert/insert_extension.asm"), include_str!("asm/mpt/insert/insert_leaf.asm"), include_str!("asm/mpt/insert/insert_trie_specific.asm"), + include_str!("asm/mpt/linked_list.asm"), include_str!("asm/mpt/read.asm"), include_str!("asm/mpt/storage/storage_read.asm"), include_str!("asm/mpt/storage/storage_write.asm"), diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index b37c41304..5b07ffc61 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -51,17 +51,20 @@ global init_accounts_linked_list: POP %endmacro -// Multiply the ptr at the top of the stack by 4 -// and abort if 4*ptr - SEGMENT_ACCOUNTS_LINKED_LIST >= @GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN -// In this way ptr must be poiting to the begining of a node. +// Multiply the value at the top of the stack, denoted by ptr/4, by 4 +// and abort if ptr/4 >= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN]/4 +// In this way 4*ptr/4 must be pointing to the beginning of a node. +// TODO: Maybe we should check here if the node have been deleted. %macro get_valid_account_ptr - // stack: ptr + // stack: ptr/4 + DUP1 + %mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) + // By construction, both @SEGMENT_ACCESSED_STORAGE_KEYS and the unscaled list len + // must be multiples of 4 + %div_const(4) + // stack: @SEGMENT_ACCESSED_STORAGE_KEYS/4 + accessed_strg_keys_len/4, ptr/4, ptr/4 + %assert_gt %mul_const(4) - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - DUP2 - SUB - %assert_lt_const(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) - // stack: 2*ptr %endmacro /// Inserts the account addr and payload otr into the linked list if it is not already present. @@ -70,7 +73,7 @@ global init_accounts_linked_list: /// and this is the first access, or `0, original_ptr` if it was already present and accessed. global insert_account: // stack: addr, payload_ptr, retdest - PROVER_INPUT(linked_lists::insert_account) + PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr, payload_ptr, retdest %get_valid_account_ptr // stack: pred_ptr, addr, payload_ptr, retdest @@ -120,47 +123,93 @@ account_found: // stack: access_ctr, orig_payload_ptr, addr, payload_ptr, retdest // If access_ctr == 1 then this it's a cold access %eq_const(0) - %stack (cold_access, orig_payload_ptr, addr, payload_ptr) -> (retdest, cold_access, orig_payload_ptr) + %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP +insert_new_account: + // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + POP + // get the value of the next address + %add_const(3) + // stack: next_ptr_ptr, addr, payload_ptr, retdest + %mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) + DUP2 + MLOAD_GENERAL + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, payload_ptr, retdest + // Check that this is not a deleted node + DUP1 + %eq_const(@U256_MAX) + %assert_zero + DUP1 + MLOAD_GENERAL + // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, payload_ptr, retdest + DUP5 + // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). + // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. + %assert_lt + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, payload_ptr, retdest + SWAP2 + DUP2 + // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, payload_ptr, retdest + MSTORE_GENERAL + // stack: new_ptr, next_ptr, addr, payload_ptr, retdest + DUP1 + DUP4 + MSTORE_GENERAL + // stack: new_ptr, next_ptr, addr, payload_ptr, retdest + %increment + DUP1 + DUP4 + MSTORE_GENERAL + // stack: new_ptr + 1, next_ptr, addr, payload_ptr, retdest + %increment + DUP1 + PUSH 0 + MSTORE_GENERAL + %increment + DUP1 + // stack: new_next_ptr, new_next_ptr, next_ptr, addr, payload_ptr, retdest + SWAP2 + MSTORE_GENERAL + // stack: new_next_ptr, addr, payload_ptr, retdest + %increment + %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) + // stack: addr, payload_ptr, retdest + // TODO: Don't for get to %journal_add_account_loaded + %pop2 + PUSH 1 + SWAP1 + JUMP /// Remove the storage key and its value from the access list. /// Panics if the key is not in the list. global remove_account: - // stack: addr, key, retdest - PROVER_INPUT(access_lists::remove_account) - // stack: pred_ptr/4, addr, key, retdest - %get_valid_storage_ptr - // stack: pred_ptr, addr, key, retdest + // stack: addr, retdest + PROVER_INPUT(linked_list::remove_account) + // stack: pred_ptr/4, addr, retdest + %get_valid_account_ptr + // stack: pred_ptr, addr, retdest %add_const(3) - // stack: next_ptr_ptr, addr, key, retdest + // stack: next_ptr_ptr, addr, retdest DUP1 MLOAD_GENERAL - // stack: next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_ptr, next_ptr_ptr, addr, retdest DUP1 %increment MLOAD_GENERAL - // stack: next_key, next_ptr, next_ptr_ptr, addr, key, retdest - DUP5 - EQ - DUP2 - MLOAD_GENERAL - // stack: next_addr, next_key == key, next_ptr, next_ptr_ptr, addr, key, retdest - DUP5 - EQ - MUL // AND - // stack: next_addr == addr AND next_key == key, next_ptr, next_ptr_ptr, addr, key, retdest - %assert_nonzero - // stack: next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_addr, next_ptr, next_ptr_ptr, addr, retdest + DUP4 + %assert_eq + // stack: next_ptr, next_ptr_ptr, addr, retdest %add_const(3) // stack: next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest DUP1 MLOAD_GENERAL - // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, retdest SWAP1 PUSH @U256_MAX MSTORE_GENERAL - // stack: next_next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_next_ptr, next_ptr_ptr, addr, retdest MSTORE_GENERAL - %pop2 + POP JUMP \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/util/assertions.asm b/evm_arithmetization/src/cpu/kernel/asm/util/assertions.asm index dc73721b3..229e7b6de 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/util/assertions.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/util/assertions.asm @@ -56,10 +56,8 @@ global panic: %endmacro %macro assert_gt - // %assert_zero is cheaper than %assert_nonzero, so we will leverage the - // fact that (x > y) == !(x <= y). - LE - %assert_zero + GT + %assert_nonzero %endmacro %macro assert_gt(ret) diff --git a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs index 4baa18f48..f3f46e220 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs @@ -94,10 +94,14 @@ pub(crate) enum GlobalMetadata { KernelHash, KernelLen, + + /// Then address of the next available address in + /// Segment::AccountsLinkedList + AccountsLinkedListLen, } impl GlobalMetadata { - pub(crate) const COUNT: usize = 47; + pub(crate) const COUNT: usize = 48; /// Unscales this virtual offset by their respective `Segment` value. pub(crate) const fn unscale(&self) -> usize { @@ -153,6 +157,7 @@ impl GlobalMetadata { Self::TxnNumberAfter, Self::KernelHash, Self::KernelLen, + Self::AccountsLinkedListLen, ] } @@ -206,6 +211,7 @@ impl GlobalMetadata { Self::TxnNumberAfter => "GLOBAL_METADATA_TXN_NUMBER_AFTER", Self::KernelHash => "GLOBAL_METADATA_KERNEL_HASH", Self::KernelLen => "GLOBAL_METADATA_KERNEL_LEN", + Self::AccountsLinkedListLen => "GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN", } } } diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs new file mode 100644 index 000000000..b69f8e541 --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -0,0 +1,278 @@ +use std::collections::HashSet; + +use anyhow::Result; +use env_logger::try_init_from_env; +use env_logger::Env; +use env_logger::DEFAULT_FILTER_ENV; +use ethereum_types::{Address, H160, U256}; +use plonky2::field::goldilocks_field::GoldilocksField as F; +use rand::{thread_rng, Rng}; + +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::constants::global_metadata::GlobalMetadata::{ + AccessedAddressesLen, AccessedStorageKeysLen, +}; +use crate::cpu::kernel::interpreter::Interpreter; +use crate::memory::segments::Segment::{self, AccessedAddresses, AccessedStorageKeys}; +use crate::witness::memory::MemoryAddress; + +fn init_logger() { + let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); +} + +#[test] +fn test_init_linked_lists() -> Result<()> { + init_logger(); + let init_label = KERNEL.global_labels["init_accounts_linked_list"]; + + // Check the initial state of the linked list in the kernel. + let initial_stack = vec![0xdeadbeefu32.into()]; + let mut interpreter = Interpreter::::new(init_label, initial_stack); + interpreter.run()?; + + assert!(interpreter.stack().is_empty()); + + let acc_addr_list: Vec = (0..4) + .map(|i| { + interpreter + .generation_state + .memory + .get_with_init(MemoryAddress::new(0, Segment::AccountsLinkedList, i)) + }) + .collect(); + assert_eq!( + vec![ + U256::MAX, + U256::zero(), + U256::zero(), + (Segment::AccountsLinkedList as usize).into(), + ], + acc_addr_list + ); + + Ok(()) +} + +#[test] +fn test_list_iterator() -> Result<()> { + init_logger(); + let init_label = KERNEL.global_labels["init_accounts_linked_list"]; + + let initial_stack = vec![0xdeadbeefu32.into()]; + let mut interpreter = Interpreter::::new(init_label, initial_stack); + interpreter.run()?; + + // test the list iterator + let mut list = interpreter + .generation_state + .get_accounts_linked_list() + .expect("Since we called init_access_lists there must be a list"); + + let Some((pos_0, next_val_0, _)) = list.next() else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(pos_0, 0); + assert_eq!(next_val_0, U256::MAX); + let Some((pos_0, _, _)) = list.next() else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(pos_0, 0); + Ok(()) +} + +#[test] +fn test_insert_account() -> Result<()> { + init_logger(); + let init_label = KERNEL.global_labels["init_accounts_linked_list"]; + + // Test for address already in list. + let initial_stack = vec![0xdeadbeefu32.into()]; + let mut interpreter = Interpreter::::new(init_label, initial_stack); + interpreter.run()?; + + let insert_accessed_addresses = KERNEL.global_labels["insert_account"]; + + let retaddr = 0xdeadbeefu32.into(); + let mut rng = thread_rng(); + let address: H160 = rng.gen(); + let payload_otr = U256::one(); + + assert!(address != H160::zero(), "Cosmic luck or bad RNG?"); + + interpreter.push(retaddr); + interpreter.push(U256::from(address.0.as_slice())); + interpreter.generation_state.registers.program_counter = insert_accessed_addresses; + + interpreter.run()?; + assert_eq!(interpreter.stack(), &[U256::one()]); + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(AccessedAddressesLen as usize)).unwrap(), + ), + U256::from(Segment::AccessedAddresses as usize + 4) + ); + + Ok(()) +} + +// #[test] +// fn test_insert_accessed_addresses() -> Result<()> { +// let init_access_lists = KERNEL.global_labels["init_access_lists"]; + +// // Test for address already in list. +// let initial_stack = vec![0xdeadbeefu32.into()]; +// let mut interpreter = Interpreter::::new(init_access_lists, +// initial_stack); interpreter.run()?; + +// let insert_accessed_addresses = +// KERNEL.global_labels["insert_accessed_addresses"]; + +// let retaddr = 0xdeadbeefu32.into(); +// let mut rng = thread_rng(); +// let n = 10; +// let addresses = (0..n) +// .map(|_| rng.gen::
()) +// .collect::>() +// .into_iter() +// .collect::>(); +// let addr_not_in_list = rng.gen::
(); +// assert!( +// !addresses.contains(&addr_not_in_list), +// "Cosmic luck or bad RNG?" +// ); + +// let offset = Segment::AccessedAddresses as usize; +// for i in 0..n { +// let addr = U256::from(addresses[i].0.as_slice()); +// interpreter.push(0xdeadbeefu32.into()); +// interpreter.push(addr); +// interpreter.generation_state.registers.program_counter = +// insert_accessed_addresses; interpreter.run()?; +// assert_eq!(interpreter.pop().unwrap(), U256::one()); +// } + +// for i in 0..n { +// // Test for address already in list. +// let addr_in_list = addresses[i]; +// interpreter.push(retaddr); +// interpreter.push(U256::from(addr_in_list.0.as_slice())); +// interpreter.generation_state.registers.program_counter = +// insert_accessed_addresses; interpreter.run()?; +// assert_eq!(interpreter.pop().unwrap(), U256::zero()); +// assert_eq!( +// interpreter.generation_state.memory.get_with_init( +// MemoryAddress::new_bundle(U256::from(AccessedAddressesLen as +// usize)).unwrap(), ), +// U256::from(offset + 2 * (n + 1)) +// ); +// } + +// // Test for address not in list. +// interpreter.push(retaddr); +// interpreter.push(U256::from(addr_not_in_list.0.as_slice())); +// interpreter.generation_state.registers.program_counter = +// insert_accessed_addresses; + +// interpreter.run()?; +// assert_eq!(interpreter.stack(), &[U256::one()]); +// assert_eq!( +// interpreter.generation_state.memory.get_with_init( +// MemoryAddress::new_bundle(U256::from(AccessedAddressesLen as +// usize)).unwrap(), ), +// U256::from(offset + 2 * (n + 2)) +// ); +// assert_eq!( +// interpreter +// .generation_state +// .memory +// .get_with_init(MemoryAddress::new(0, AccessedAddresses, 2 * (n + +// 1)),), U256::from(addr_not_in_list.0.as_slice()) +// ); + +// Ok(()) +// } + +// #[test] +// fn test_insert_accessed_storage_keys() -> Result<()> { +// let init_access_lists = KERNEL.global_labels["init_access_lists"]; + +// // Test for address already in list. +// let initial_stack = vec![0xdeadbeefu32.into()]; +// let mut interpreter = Interpreter::::new(init_access_lists, +// initial_stack); interpreter.run()?; + +// let insert_accessed_storage_keys = +// KERNEL.global_labels["insert_accessed_storage_keys"]; + +// let retaddr = 0xdeadbeefu32.into(); +// let mut rng = thread_rng(); +// let n = 10; +// let storage_keys = (0..n) +// .map(|_| (rng.gen::
(), U256(rng.gen()))) +// .collect::>() +// .into_iter() +// .collect::>(); +// let storage_key_not_in_list = (rng.gen::
(), U256(rng.gen())); +// assert!( +// !storage_keys.contains(&storage_key_not_in_list), +// "Cosmic luck or bad RNG?" +// ); + +// let offset = Segment::AccessedStorageKeys as usize; +// for i in 0..n { +// let addr = U256::from(storage_keys[i].0 .0.as_slice()); +// let key = storage_keys[i].1; +// interpreter.push(retaddr); +// interpreter.push(key); +// interpreter.push(addr); +// interpreter.generation_state.registers.program_counter = +// insert_accessed_storage_keys; interpreter.run()?; +// assert_eq!(interpreter.pop().unwrap(), U256::one()); +// interpreter.pop().expect("Stack shouldn't be empty"); // Pop the +// value_ptr. } + +// for i in 0..10 { +// // Test for storage key already in list. +// let (addr, key) = storage_keys[i]; +// interpreter.push(retaddr); +// interpreter.push(key); +// interpreter.push(U256::from(addr.0.as_slice())); +// interpreter.generation_state.registers.program_counter = +// insert_accessed_storage_keys; interpreter.run()?; +// assert_eq!(interpreter.pop().unwrap(), U256::zero()); +// interpreter.pop().expect("Stack shouldn't be empty"); // Pop the +// value_ptr. assert_eq!( +// interpreter.generation_state.memory.get_with_init( +// MemoryAddress::new_bundle(U256::from(AccessedStorageKeysLen +// as usize)).unwrap(), ), +// U256::from(offset + 4 * (n + 1)) +// ); +// } + +// // Test for storage key not in list. +// interpreter.push(retaddr); +// interpreter.push(storage_key_not_in_list.1); +// interpreter.push(U256::from(storage_key_not_in_list.0 .0.as_slice())); +// interpreter.generation_state.registers.program_counter = +// insert_accessed_storage_keys; + +// interpreter.run()?; +// assert_eq!(interpreter.stack()[1], U256::one()); +// assert_eq!( +// interpreter.generation_state.memory.get_with_init( +// MemoryAddress::new_bundle(U256::from(AccessedStorageKeysLen as +// usize)).unwrap(), ), +// U256::from(offset + 4 * (n + 2)) +// ); +// assert_eq!( +// interpreter +// .generation_state +// .memory +// .get_with_init(MemoryAddress::new(0, AccessedStorageKeys, 4 * (n +// + 1)),), U256::from(storage_key_not_in_list.0 .0.as_slice()) ); +// assert_eq!( interpreter .generation_state .memory +// .get_with_init(MemoryAddress::new(0, AccessedStorageKeys, 4 * (n +// + 1) + 1),), storage_key_not_in_list.1 ); + +// Ok(()) +// } diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs index 84f64bb7b..403887c4f 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs @@ -9,6 +9,7 @@ mod delete; mod hash; mod hex_prefix; mod insert; +mod linked_list; mod load; mod read; diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 002fc1d4a..64570e109 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -55,6 +55,7 @@ impl GenerationState { "num_bits" => self.run_num_bits(), "jumpdest_table" => self.run_jumpdest_table(input_fn), "access_lists" => self.run_access_lists(input_fn), + "linked_list" => self.run_linked_list(input_fn), _ => Err(ProgramError::ProverInputError(InvalidFunction)), } } @@ -262,6 +263,16 @@ impl GenerationState { } } + /// Generates either the next used jump address or the proof for the last + /// jump address. + fn run_linked_list(&mut self, input_fn: &ProverInputFn) -> Result { + match input_fn.0[1].as_str() { + "insert_account" => self.run_next_insert_account(), + "remove_account" => self.run_next_remove_account(), + _ => Err(ProgramError::ProverInputError(InvalidInput)), + } + } + /// Returns the next used jump address. fn run_next_jumpdest_table_address(&mut self) -> Result { let context = u256_to_usize(stack_peek(self, 0)? >> CONTEXT_SCALING_FACTOR)?; @@ -378,6 +389,33 @@ impl GenerationState { } Ok((Segment::AccessedStorageKeys as usize).into()) } + + /// Returns a pointer to an element in the list whose value is such that + /// `value <= addr < next_value` and `addr` is the top of the stack. + fn run_next_insert_account(&mut self) -> Result { + let addr = stack_peek(self, 0)?; + for (curr_ptr, next_addr, _) in self.get_accounts_linked_list()? { + if next_addr > addr { + // In order to avoid pointers to the next ptr, we use the fact + // that valid pointers and Segment::AccessedAddresses are always even + return Ok(((Segment::AccountsLinkedList as usize + curr_ptr) / 4usize).into()); + } + } + Ok((Segment::AccessedAddresses as usize).into()) + } + + /// Returns a pointer to an element in the list whose value is such that + /// `value < addr == next_value` and addr is the top of the stack. + /// If the element is not in the list loops forever + fn run_next_remove_account(&mut self) -> Result { + let addr = stack_peek(self, 0)?; + for (curr_ptr, next_addr, _) in self.get_accounts_linked_list()? { + if next_addr == addr { + return Ok(((Segment::AccountsLinkedList as usize + curr_ptr) / 2usize).into()); + } + } + Ok((Segment::AccessedAddresses as usize).into()) + } } impl GenerationState { @@ -463,6 +501,20 @@ impl GenerationState { ) } + pub(crate) fn get_accounts_linked_list(&self) -> Result { + // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next + // available virtual address in the segment. In order to get the length + // we need to substract `Segment::AccountsLinkedList` as usize. + let acc_list_len = + u256_to_usize(self.get_global_metadata(GlobalMetadata::AccountsLinkedListLen))? + - Segment::AccountsLinkedList as usize; + AccList::from_mem_and_segment( + &self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content + [..acc_list_len], + Segment::AccountsLinkedList, + ) + } + fn get_global_metadata(&self, data: GlobalMetadata) -> U256 { self.memory.get_with_init(MemoryAddress::new( 0, @@ -606,6 +658,7 @@ impl<'a> AccList<'a> { node_size: match segment { Segment::AccessedAddresses => 2, Segment::AccessedStorageKeys => 4, + Segment::AccountsLinkedList => 4, _ => return Err(ProgramError::ProverInputError(InvalidInput)), }, offset: segment as usize, @@ -631,7 +684,7 @@ impl<'a> Iterator for AccList<'a> { U256::zero(), )) } else { - // storage_keys + // storage_keys or accounts linked list Some(( old_pos, self.access_list_mem[self.pos].unwrap_or_default(), diff --git a/evm_arithmetization/src/memory/segments.rs b/evm_arithmetization/src/memory/segments.rs index 407fa0977..13ab0fd84 100644 --- a/evm_arithmetization/src/memory/segments.rs +++ b/evm_arithmetization/src/memory/segments.rs @@ -73,10 +73,12 @@ pub(crate) enum Segment { ContextCheckpoints = 32 << SEGMENT_SCALING_FACTOR, /// List of 256 previous block hashes. BlockHashes = 33 << SEGMENT_SCALING_FACTOR, + /// List of accounts in the state trie, + AccountsLinkedList = 34 << SEGMENT_SCALING_FACTOR, } impl Segment { - pub(crate) const COUNT: usize = 34; + pub(crate) const COUNT: usize = 35; /// Unscales this segment by `SEGMENT_SCALING_FACTOR`. pub(crate) const fn unscale(&self) -> usize { @@ -119,6 +121,7 @@ impl Segment { Self::TouchedAddresses, Self::ContextCheckpoints, Self::BlockHashes, + Self::AccountsLinkedList, ] } @@ -159,6 +162,7 @@ impl Segment { Segment::TouchedAddresses => "SEGMENT_TOUCHED_ADDRESSES", Segment::ContextCheckpoints => "SEGMENT_CONTEXT_CHECKPOINTS", Segment::BlockHashes => "SEGMENT_BLOCK_HASHES", + Segment::AccountsLinkedList => "SEGMENT_ACCOUNTS_LINKED_LIST", } } @@ -198,6 +202,7 @@ impl Segment { Segment::TouchedAddresses => 256, Segment::ContextCheckpoints => 256, Segment::BlockHashes => 256, + Segment::AccountsLinkedList => 256, } } } From d242757bb351a88133c94cb05388c7e0584f1452 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Mon, 6 May 2024 14:25:52 +0200 Subject: [PATCH 003/118] Modify tests for insetions and fix bugs --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 37 ++- .../src/cpu/kernel/tests/core/access_lists.rs | 4 +- .../src/cpu/kernel/tests/mpt/linked_list.rs | 224 +++++++++++------- .../src/generation/prover_input.rs | 16 +- 4 files changed, 176 insertions(+), 105 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 5b07ffc61..b4aeb83d5 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -67,15 +67,17 @@ global init_accounts_linked_list: %mul_const(4) %endmacro -/// Inserts the account addr and payload otr into the linked list if it is not already present. +/// Inserts the account addr and payload pinter into the linked list if it is not already present. /// `value` should be the current storage value at the slot `(addr, key)`. -/// Return `0, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present +/// Return `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. global insert_account: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr, payload_ptr, retdest +global debug_ptr_div_4: %get_valid_account_ptr +global debug_ptr: // stack: pred_ptr, addr, payload_ptr, retdest DUP1 MLOAD_GENERAL @@ -87,6 +89,7 @@ global insert_account: // If the predesessor is strictly smaller or the predecessor is the special // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. +global debug_before_jumpi: %jumpi(insert_new_account) // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. @@ -102,30 +105,36 @@ global insert_account: %jump_neq_const(@U256_MAX, account_found) // The storage key is not in the list. PANIC + +global debug_account_found: account_found: // The address was already in the list // stack: pred_ptr, addr, payload_ptr, retdest // Load the access counter - DUP1 %increment + DUP1 MLOAD_GENERAL - // stack: orig_payload_ptr, pred_ptr, addr, payload_ptr, retdest + // stack: orig_payload_ptr, pred_ptr + 1, addr, payload_ptr, retdest SWAP1 - %add_const(2) + %increment DUP1 +global debug_before_load_ctr: MLOAD_GENERAL +global debug_after_load_ctr: %increment - // stack: access_ctr, access_ctr_ptr, orig_payload_ptr, addr, payload_ptr, retdest + // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, payload_ptr, retdest SWAP1 DUP2 - // stack: access_ctr, access_ctr_ptr, access_ctr, orig_payload_ptr, addr, payload_ptr, retdest + // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest +global debug_before_store_ctr: MSTORE_GENERAL - // stack: access_ctr, orig_payload_ptr, addr, payload_ptr, retdest + // stack: access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest // If access_ctr == 1 then this it's a cold access - %eq_const(0) + %eq_const(1) %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP +global debug_insert_new_account: insert_new_account: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest POP @@ -155,11 +164,13 @@ insert_new_account: // stack: new_ptr, next_ptr, addr, payload_ptr, retdest DUP1 DUP4 +global debug_store_addr: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, payload_ptr, retdest %increment DUP1 - DUP4 + DUP5 +global debug_store_ptr: MSTORE_GENERAL // stack: new_ptr + 1, next_ptr, addr, payload_ptr, retdest %increment @@ -176,9 +187,11 @@ insert_new_account: %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) // stack: addr, payload_ptr, retdest // TODO: Don't for get to %journal_add_account_loaded - %pop2 - PUSH 1 + POP + PUSH 0 SWAP1 + SWAP2 +global debug_before_jump: JUMP /// Remove the storage key and its value from the access list. diff --git a/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs b/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs index 4b3aae8cc..95a666200 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs @@ -73,12 +73,12 @@ fn test_list_iterator() -> Result<()> { .get_addresses_access_list() .expect("Since we called init_access_lists there must be a list"); - let Some((pos_0, next_val_0, _)) = list.next() else { + let Some((pos_0, next_val_0, _, _)) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); assert_eq!(next_val_0, U256::MAX); - let Some((pos_0, _, _)) = list.next() else { + let Some((pos_0, _, _, _)) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index b69f8e541..b6d2d4a19 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -5,13 +5,12 @@ use env_logger::try_init_from_env; use env_logger::Env; use env_logger::DEFAULT_FILTER_ENV; use ethereum_types::{Address, H160, U256}; +use num::traits::ToBytes; use plonky2::field::goldilocks_field::GoldilocksField as F; use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::KERNEL; -use crate::cpu::kernel::constants::global_metadata::GlobalMetadata::{ - AccessedAddressesLen, AccessedStorageKeysLen, -}; +use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; use crate::memory::segments::Segment::{self, AccessedAddresses, AccessedStorageKeys}; use crate::witness::memory::MemoryAddress; @@ -68,15 +67,20 @@ fn test_list_iterator() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some((pos_0, next_val_0, _)) = list.next() else { + let Some((pos_0, addr, ptr, ctr)) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); - assert_eq!(next_val_0, U256::MAX); - let Some((pos_0, _, _)) = list.next() else { + assert_eq!(addr, U256::MAX); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); + let Some((pos_0, addr, ptr, ctr)) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); + assert_eq!(addr, U256::MAX); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); Ok(()) } @@ -90,107 +94,159 @@ fn test_insert_account() -> Result<()> { let mut interpreter = Interpreter::::new(init_label, initial_stack); interpreter.run()?; - let insert_accessed_addresses = KERNEL.global_labels["insert_account"]; + let insert_account_label = KERNEL.global_labels["insert_account"]; let retaddr = 0xdeadbeefu32.into(); let mut rng = thread_rng(); let address: H160 = rng.gen(); - let payload_otr = U256::one(); + let payload_ptr = U256::from(5); assert!(address != H160::zero(), "Cosmic luck or bad RNG?"); interpreter.push(retaddr); + interpreter.push(payload_ptr); interpreter.push(U256::from(address.0.as_slice())); - interpreter.generation_state.registers.program_counter = insert_accessed_addresses; + interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!(interpreter.stack(), &[U256::one()]); - assert_eq!( - interpreter.generation_state.memory.get_with_init( - MemoryAddress::new_bundle(U256::from(AccessedAddressesLen as usize)).unwrap(), - ), - U256::from(Segment::AccessedAddresses as usize + 4) - ); + assert_eq!(interpreter.stack(), &[payload_ptr, U256::one()]); + + let mut list = interpreter + .generation_state + .get_accounts_linked_list() + .expect("Since we called init_access_lists there must be a list"); + + let Some((old_pos, addr, ptr, ctr)) = list.next() else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(old_pos, 0); + assert_eq!(addr, U256::from(address.0.as_slice())); + assert_eq!(ptr, payload_ptr); + assert_eq!(ctr, U256::zero()); + let Some((old_pos, addr, ptr, ctr)) = list.next() else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(old_pos, 4); + assert_eq!(addr, U256::MAX); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); Ok(()) } -// #[test] -// fn test_insert_accessed_addresses() -> Result<()> { -// let init_access_lists = KERNEL.global_labels["init_access_lists"]; +#[test] +fn test_insert_accounts() -> Result<()> { + init_logger(); -// // Test for address already in list. -// let initial_stack = vec![0xdeadbeefu32.into()]; -// let mut interpreter = Interpreter::::new(init_access_lists, -// initial_stack); interpreter.run()?; + let init_label = KERNEL.global_labels["init_accounts_linked_list"]; -// let insert_accessed_addresses = -// KERNEL.global_labels["insert_accessed_addresses"]; + // Test for address already in list. + let initial_stack = vec![0xdeadbeefu32.into()]; + let mut interpreter = Interpreter::::new(init_label, initial_stack); + interpreter.run()?; -// let retaddr = 0xdeadbeefu32.into(); -// let mut rng = thread_rng(); -// let n = 10; -// let addresses = (0..n) -// .map(|_| rng.gen::
()) -// .collect::>() -// .into_iter() -// .collect::>(); -// let addr_not_in_list = rng.gen::
(); -// assert!( -// !addresses.contains(&addr_not_in_list), -// "Cosmic luck or bad RNG?" -// ); + let insert_account_label = KERNEL.global_labels["insert_account"]; -// let offset = Segment::AccessedAddresses as usize; -// for i in 0..n { -// let addr = U256::from(addresses[i].0.as_slice()); -// interpreter.push(0xdeadbeefu32.into()); -// interpreter.push(addr); -// interpreter.generation_state.registers.program_counter = -// insert_accessed_addresses; interpreter.run()?; -// assert_eq!(interpreter.pop().unwrap(), U256::one()); -// } + let retaddr = 0xdeadbeefu32.into(); + let mut rng = thread_rng(); + let n = 10; + let addresses = (0..n) + // .map(|_| rng.gen::
()) + .map(|i| Address::from_low_u64_be(i as u64 + 5)) + .collect::>() + .into_iter() + .collect::>(); + // let addr_not_in_list = rng.gen::
(); + let addr_not_in_list = Address::from_low_u64_be(4); + assert!( + !addresses.contains(&addr_not_in_list), + "Cosmic luck or bad RNG?" + ); + log::debug!( + "addresses = {:?}", + addresses + .iter() + .map(|x| U256::from(x.0.as_slice())) + .collect::>() + ); + let offset = Segment::AccountsLinkedList as usize; + for i in 0..n { + let addr = U256::from(addresses[i as usize].0.as_slice()); + interpreter.push(0xdeadbeefu32.into()); + interpreter.push(addr + 1); // ptr = addr + 1 for the sake of the test + interpreter.push(addr); + interpreter.generation_state.registers.program_counter = insert_account_label; + log::debug!("inserting addr={:?} and ptr={:?}", addr, addr + 1); + interpreter.run()?; + log::debug!("we are at {i}"); + assert_eq!(interpreter.pop().unwrap(), U256::zero()); + assert_eq!(interpreter.pop().unwrap(), addr + 1); + // The counter must be 0 + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(offset + 4 * (i + 1) + 2)).unwrap(), + ), + U256::zero() + ); + } + + // The next free address in Segment::AccounLinkedList must be offset + (n + + // 1)*4. + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(GlobalMetadata::AccountsLinkedListLen as usize)) + .unwrap(), + ), + U256::from(offset + (n + 1) * 4) + ); -// for i in 0..n { -// // Test for address already in list. -// let addr_in_list = addresses[i]; -// interpreter.push(retaddr); -// interpreter.push(U256::from(addr_in_list.0.as_slice())); -// interpreter.generation_state.registers.program_counter = -// insert_accessed_addresses; interpreter.run()?; -// assert_eq!(interpreter.pop().unwrap(), U256::zero()); -// assert_eq!( -// interpreter.generation_state.memory.get_with_init( -// MemoryAddress::new_bundle(U256::from(AccessedAddressesLen as -// usize)).unwrap(), ), -// U256::from(offset + 2 * (n + 1)) -// ); -// } + for i in 0..n { + // Test for address already in list. + let addr_in_list = U256::from(addresses[i as usize].0.as_slice()); + interpreter.push(retaddr); + interpreter.push(U256::zero()); + interpreter.push(addr_in_list); + interpreter.generation_state.registers.program_counter = insert_account_label; + log::debug!( + "inserting addr={:?} and ptr={:?}", + addr_in_list, + addr_in_list + 1 + ); + interpreter.run()?; + log::debug!("we are at {i}"); + assert_eq!(interpreter.pop().unwrap(), U256::one()); + assert_eq!(interpreter.pop().unwrap(), addr_in_list + 1); + // The counter must be one now + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(offset + 4 * (i + 1) + 2)).unwrap(), + ), + U256::one() + ); + } + + // Test for address not in list. -// // Test for address not in list. -// interpreter.push(retaddr); -// interpreter.push(U256::from(addr_not_in_list.0.as_slice())); -// interpreter.generation_state.registers.program_counter = -// insert_accessed_addresses; + interpreter.push(retaddr); + interpreter.push(U256::from(3)); + interpreter.push(U256::from(addr_not_in_list.0.as_slice())); + interpreter.generation_state.registers.program_counter = insert_account_label; -// interpreter.run()?; -// assert_eq!(interpreter.stack(), &[U256::one()]); -// assert_eq!( -// interpreter.generation_state.memory.get_with_init( -// MemoryAddress::new_bundle(U256::from(AccessedAddressesLen as -// usize)).unwrap(), ), -// U256::from(offset + 2 * (n + 2)) -// ); -// assert_eq!( -// interpreter -// .generation_state -// .memory -// .get_with_init(MemoryAddress::new(0, AccessedAddresses, 2 * (n + -// 1)),), U256::from(addr_not_in_list.0.as_slice()) -// ); + interpreter.run()?; + assert_eq!(interpreter.stack(), &[U256::from(3), U256::zero()]); -// Ok(()) -// } + // The next free address in Segment::AccounLinkedList must be offset + (n + + // 2)*4. + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(GlobalMetadata::AccountsLinkedListLen as usize)) + .unwrap(), + ), + U256::from(offset + (n + 2) * 4) + ); + + Ok(()) +} // #[test] // fn test_insert_accessed_storage_keys() -> Result<()> { diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 64570e109..f15a257ba 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -339,7 +339,7 @@ impl GenerationState { /// `value <= addr < next_value` and `addr` is the top of the stack. fn run_next_addresses_insert(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _) in self.get_addresses_access_list()? { + for (curr_ptr, next_addr, _, _) in self.get_addresses_access_list()? { if next_addr > addr { // In order to avoid pointers to the next ptr, we use the fact // that valid pointers and Segment::AccessedAddresses are always even @@ -354,7 +354,7 @@ impl GenerationState { /// If the element is not in the list returns loops forever fn run_next_addresses_remove(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _) in self.get_addresses_access_list()? { + for (curr_ptr, next_addr, _, _) in self.get_addresses_access_list()? { if next_addr == addr { return Ok(((Segment::AccessedAddresses as usize + curr_ptr) / 2usize).into()); } @@ -367,7 +367,7 @@ impl GenerationState { fn run_next_storage_insert(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - for (curr_ptr, next_addr, next_key) in self.get_storage_keys_access_list()? { + for (curr_ptr, next_addr, next_key, _) in self.get_storage_keys_access_list()? { if next_addr > addr || (next_addr == addr && next_key > key) { // In order to avoid pointers to the key, value or next ptr, we use the fact // that valid pointers and Segment::AccessedAddresses are always multiples of 4 @@ -382,7 +382,7 @@ impl GenerationState { fn run_next_storage_remove(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - for (curr_ptr, next_addr, next_key) in self.get_storage_keys_access_list()? { + for (curr_ptr, next_addr, next_key, _) in self.get_storage_keys_access_list()? { if (next_addr == addr && next_key == key) || next_addr == U256::MAX { return Ok(((Segment::AccessedStorageKeys as usize + curr_ptr) / 4usize).into()); } @@ -394,7 +394,7 @@ impl GenerationState { /// `value <= addr < next_value` and `addr` is the top of the stack. fn run_next_insert_account(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _) in self.get_accounts_linked_list()? { + for (curr_ptr, next_addr, _, _) in self.get_accounts_linked_list()? { if next_addr > addr { // In order to avoid pointers to the next ptr, we use the fact // that valid pointers and Segment::AccessedAddresses are always even @@ -409,7 +409,7 @@ impl GenerationState { /// If the element is not in the list loops forever fn run_next_remove_account(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _) in self.get_accounts_linked_list()? { + for (curr_ptr, next_addr, _, _) in self.get_accounts_linked_list()? { if next_addr == addr { return Ok(((Segment::AccountsLinkedList as usize + curr_ptr) / 2usize).into()); } @@ -668,7 +668,7 @@ impl<'a> AccList<'a> { } impl<'a> Iterator for AccList<'a> { - type Item = (usize, U256, U256); + type Item = (usize, U256, U256, U256); fn next(&mut self) -> Option { if let Ok(new_pos) = @@ -682,6 +682,7 @@ impl<'a> Iterator for AccList<'a> { old_pos, self.access_list_mem[self.pos].unwrap_or_default(), U256::zero(), + U256::zero(), )) } else { // storage_keys or accounts linked list @@ -689,6 +690,7 @@ impl<'a> Iterator for AccList<'a> { old_pos, self.access_list_mem[self.pos].unwrap_or_default(), self.access_list_mem[self.pos + 1].unwrap_or_default(), + self.access_list_mem[self.pos + 2].unwrap_or_default(), )) } } else { From 4558a38602a3ee47ae886915427e895a8d4156cd Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Mon, 6 May 2024 17:55:15 +0200 Subject: [PATCH 004/118] Fix deletion test --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 3 +- .../src/cpu/kernel/tests/mpt/linked_list.rs | 195 ++++++++---------- .../src/generation/prover_input.rs | 2 +- 3 files changed, 85 insertions(+), 115 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index b4aeb83d5..64d16a35d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -200,7 +200,9 @@ global remove_account: // stack: addr, retdest PROVER_INPUT(linked_list::remove_account) // stack: pred_ptr/4, addr, retdest +global debug_before_del_ptr: %get_valid_account_ptr +global debug_after_del_ptr: // stack: pred_ptr, addr, retdest %add_const(3) // stack: next_ptr_ptr, addr, retdest @@ -208,7 +210,6 @@ global remove_account: MLOAD_GENERAL // stack: next_ptr, next_ptr_ptr, addr, retdest DUP1 - %increment MLOAD_GENERAL // stack: next_addr, next_ptr, next_ptr_ptr, addr, retdest DUP4 diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index b6d2d4a19..2291e7bb7 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -5,8 +5,10 @@ use env_logger::try_init_from_env; use env_logger::Env; use env_logger::DEFAULT_FILTER_ENV; use ethereum_types::{Address, H160, U256}; +use itertools::Itertools; use num::traits::ToBytes; use plonky2::field::goldilocks_field::GoldilocksField as F; +use plonky2_maybe_rayon::rayon::iter; use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::KERNEL; @@ -109,7 +111,7 @@ fn test_insert_account() -> Result<()> { interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!(interpreter.stack(), &[payload_ptr, U256::one()]); + assert_eq!(interpreter.stack(), &[payload_ptr, U256::zero()]); let mut list = interpreter .generation_state @@ -135,7 +137,7 @@ fn test_insert_account() -> Result<()> { } #[test] -fn test_insert_accounts() -> Result<()> { +fn test_insert_and_delete_accounts() -> Result<()> { init_logger(); let init_label = KERNEL.global_labels["init_accounts_linked_list"]; @@ -150,37 +152,37 @@ fn test_insert_accounts() -> Result<()> { let retaddr = 0xdeadbeefu32.into(); let mut rng = thread_rng(); let n = 10; - let addresses = (0..n) + let mut addresses = (0..n) // .map(|_| rng.gen::
()) .map(|i| Address::from_low_u64_be(i as u64 + 5)) .collect::>() .into_iter() .collect::>(); + let delta_ptr = 100; // let addr_not_in_list = rng.gen::
(); let addr_not_in_list = Address::from_low_u64_be(4); assert!( !addresses.contains(&addr_not_in_list), "Cosmic luck or bad RNG?" ); - log::debug!( - "addresses = {:?}", - addresses - .iter() - .map(|x| U256::from(x.0.as_slice())) - .collect::>() - ); + let offset = Segment::AccountsLinkedList as usize; + // Insert all addresses for i in 0..n { let addr = U256::from(addresses[i as usize].0.as_slice()); interpreter.push(0xdeadbeefu32.into()); - interpreter.push(addr + 1); // ptr = addr + 1 for the sake of the test + interpreter.push(addr + delta_ptr); // ptr = addr + delta_ptr for the sake of the test interpreter.push(addr); interpreter.generation_state.registers.program_counter = insert_account_label; - log::debug!("inserting addr={:?} and ptr={:?}", addr, addr + 1); interpreter.run()?; - log::debug!("we are at {i}"); - assert_eq!(interpreter.pop().unwrap(), U256::zero()); - assert_eq!(interpreter.pop().unwrap(), addr + 1); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::zero() + ); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + addr + delta_ptr + ); // The counter must be 0 assert_eq!( interpreter.generation_state.memory.get_with_init( @@ -200,22 +202,22 @@ fn test_insert_accounts() -> Result<()> { U256::from(offset + (n + 1) * 4) ); + // Test for address already in list. for i in 0..n { - // Test for address already in list. let addr_in_list = U256::from(addresses[i as usize].0.as_slice()); interpreter.push(retaddr); interpreter.push(U256::zero()); interpreter.push(addr_in_list); interpreter.generation_state.registers.program_counter = insert_account_label; - log::debug!( - "inserting addr={:?} and ptr={:?}", - addr_in_list, - addr_in_list + 1 - ); interpreter.run()?; - log::debug!("we are at {i}"); - assert_eq!(interpreter.pop().unwrap(), U256::one()); - assert_eq!(interpreter.pop().unwrap(), addr_in_list + 1); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::one() + ); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + addr_in_list + delta_ptr + ); // The counter must be one now assert_eq!( interpreter.generation_state.memory.get_with_init( @@ -225,15 +227,24 @@ fn test_insert_accounts() -> Result<()> { ); } - // Test for address not in list. - + // Test for address not in the list. interpreter.push(retaddr); - interpreter.push(U256::from(3)); + interpreter.push(U256::from(addr_not_in_list.0.as_slice()) + delta_ptr); interpreter.push(U256::from(addr_not_in_list.0.as_slice())); interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!(interpreter.stack(), &[U256::from(3), U256::zero()]); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::zero() + ); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::from(addr_not_in_list.0.as_slice()) + delta_ptr + ); + + // Now the list of accounts have address 4 + addresses.push(addr_not_in_list); // The next free address in Segment::AccounLinkedList must be offset + (n + // 2)*4. @@ -245,90 +256,48 @@ fn test_insert_accounts() -> Result<()> { U256::from(offset + (n + 2) * 4) ); + // Remove all even nodes + let delete_account_label = KERNEL.global_labels["remove_account"]; + + let mut new_addresses = vec![]; + + for (i, j) in (0..n).tuples() { + // Test for address already in list. + let addr_in_list = U256::from(addresses[i as usize].0.as_slice()); + interpreter.push(retaddr); + interpreter.push(addr_in_list); + interpreter.generation_state.registers.program_counter = delete_account_label; + interpreter.run()?; + assert!(interpreter.stack().is_empty()); + // we add the non deleted addres to new_addresses + new_addresses.push(addresses[j]); + } + // the last address is not removed + new_addresses.push(*addresses.last().unwrap()); + + // We need to sort the list in order to properly compare with + // the linked list the interpreter's memory + new_addresses.sort(); + + let mut list = interpreter + .generation_state + .get_accounts_linked_list() + .expect("Since we called init_access_lists there must be a list"); + + for (i, (_, addr, ptr, ctr)) in list.enumerate() { + if addr == U256::MAX { + // + assert_eq!(addr, U256::MAX); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); + break; + } + let addr_in_list = U256::from(new_addresses[i].0.as_slice()); + assert_eq!(addr, addr_in_list); + assert_eq!(ptr, addr + delta_ptr); + // ctr is 0 for the lowest address because is never accessed + assert_eq!(ctr, if i == 0 { U256::zero() } else { U256::one() }); + } + Ok(()) } - -// #[test] -// fn test_insert_accessed_storage_keys() -> Result<()> { -// let init_access_lists = KERNEL.global_labels["init_access_lists"]; - -// // Test for address already in list. -// let initial_stack = vec![0xdeadbeefu32.into()]; -// let mut interpreter = Interpreter::::new(init_access_lists, -// initial_stack); interpreter.run()?; - -// let insert_accessed_storage_keys = -// KERNEL.global_labels["insert_accessed_storage_keys"]; - -// let retaddr = 0xdeadbeefu32.into(); -// let mut rng = thread_rng(); -// let n = 10; -// let storage_keys = (0..n) -// .map(|_| (rng.gen::
(), U256(rng.gen()))) -// .collect::>() -// .into_iter() -// .collect::>(); -// let storage_key_not_in_list = (rng.gen::
(), U256(rng.gen())); -// assert!( -// !storage_keys.contains(&storage_key_not_in_list), -// "Cosmic luck or bad RNG?" -// ); - -// let offset = Segment::AccessedStorageKeys as usize; -// for i in 0..n { -// let addr = U256::from(storage_keys[i].0 .0.as_slice()); -// let key = storage_keys[i].1; -// interpreter.push(retaddr); -// interpreter.push(key); -// interpreter.push(addr); -// interpreter.generation_state.registers.program_counter = -// insert_accessed_storage_keys; interpreter.run()?; -// assert_eq!(interpreter.pop().unwrap(), U256::one()); -// interpreter.pop().expect("Stack shouldn't be empty"); // Pop the -// value_ptr. } - -// for i in 0..10 { -// // Test for storage key already in list. -// let (addr, key) = storage_keys[i]; -// interpreter.push(retaddr); -// interpreter.push(key); -// interpreter.push(U256::from(addr.0.as_slice())); -// interpreter.generation_state.registers.program_counter = -// insert_accessed_storage_keys; interpreter.run()?; -// assert_eq!(interpreter.pop().unwrap(), U256::zero()); -// interpreter.pop().expect("Stack shouldn't be empty"); // Pop the -// value_ptr. assert_eq!( -// interpreter.generation_state.memory.get_with_init( -// MemoryAddress::new_bundle(U256::from(AccessedStorageKeysLen -// as usize)).unwrap(), ), -// U256::from(offset + 4 * (n + 1)) -// ); -// } - -// // Test for storage key not in list. -// interpreter.push(retaddr); -// interpreter.push(storage_key_not_in_list.1); -// interpreter.push(U256::from(storage_key_not_in_list.0 .0.as_slice())); -// interpreter.generation_state.registers.program_counter = -// insert_accessed_storage_keys; - -// interpreter.run()?; -// assert_eq!(interpreter.stack()[1], U256::one()); -// assert_eq!( -// interpreter.generation_state.memory.get_with_init( -// MemoryAddress::new_bundle(U256::from(AccessedStorageKeysLen as -// usize)).unwrap(), ), -// U256::from(offset + 4 * (n + 2)) -// ); -// assert_eq!( -// interpreter -// .generation_state -// .memory -// .get_with_init(MemoryAddress::new(0, AccessedStorageKeys, 4 * (n -// + 1)),), U256::from(storage_key_not_in_list.0 .0.as_slice()) ); -// assert_eq!( interpreter .generation_state .memory -// .get_with_init(MemoryAddress::new(0, AccessedStorageKeys, 4 * (n -// + 1) + 1),), storage_key_not_in_list.1 ); - -// Ok(()) -// } diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index f15a257ba..38f8e89c7 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -411,7 +411,7 @@ impl GenerationState { let addr = stack_peek(self, 0)?; for (curr_ptr, next_addr, _, _) in self.get_accounts_linked_list()? { if next_addr == addr { - return Ok(((Segment::AccountsLinkedList as usize + curr_ptr) / 2usize).into()); + return Ok(((Segment::AccountsLinkedList as usize + curr_ptr) / 4usize).into()); } } Ok((Segment::AccessedAddresses as usize).into()) From c369aa54459b10ff601208e88e78479ec128a495 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Tue, 7 May 2024 17:34:42 +0200 Subject: [PATCH 005/118] [WIP] Getting trie data without leaves --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 7 +++- .../src/generation/prover_input.rs | 32 +++++++++---------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 64d16a35d..eef89e7bf 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -226,4 +226,9 @@ global debug_after_del_ptr: // stack: next_next_ptr, next_ptr_ptr, addr, retdest MSTORE_GENERAL POP - JUMP \ No newline at end of file + JUMP + +// Polulates the state MPT with the nodes in the list plus non-deterministically guessed +// hased nodes. +global account_linked_list_to_state_trie: + \ No newline at end of file diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 38f8e89c7..39a8fb737 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -487,28 +487,28 @@ impl GenerationState { } } - pub(crate) fn get_addresses_access_list(&self) -> Result { + pub(crate) fn get_addresses_access_list(&self) -> Result { // `GlobalMetadata::AccessedAddressesLen` stores the value of the next available // virtual address in the segment. In order to get the length we need // to substract `Segment::AccessedAddresses` as usize. let acc_addr_len = u256_to_usize(self.get_global_metadata(GlobalMetadata::AccessedAddressesLen))? - Segment::AccessedAddresses as usize; - AccList::from_mem_and_segment( + LinkedList::from_mem_and_segment( &self.memory.contexts[0].segments[Segment::AccessedAddresses.unscale()].content [..acc_addr_len], Segment::AccessedAddresses, ) } - pub(crate) fn get_accounts_linked_list(&self) -> Result { + pub(crate) fn get_accounts_linked_list(&self) -> Result { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next // available virtual address in the segment. In order to get the length // we need to substract `Segment::AccountsLinkedList` as usize. let acc_list_len = u256_to_usize(self.get_global_metadata(GlobalMetadata::AccountsLinkedListLen))? - Segment::AccountsLinkedList as usize; - AccList::from_mem_and_segment( + LinkedList::from_mem_and_segment( &self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content [..acc_list_len], Segment::AccountsLinkedList, @@ -523,7 +523,7 @@ impl GenerationState { )) } - pub(crate) fn get_storage_keys_access_list(&self) -> Result { + pub(crate) fn get_storage_keys_access_list(&self) -> Result { // GlobalMetadata::AccessedStorageKeysLen stores the value of the next available // virtual address in the segment. In order to get the length we need // to substract Segment::AccessedStorageKeys as usize @@ -534,7 +534,7 @@ impl GenerationState { GlobalMetadata::AccessedStorageKeysLen.unscale(), )) - Segment::AccessedStorageKeys as usize, )?; - AccList::from_mem_and_segment( + LinkedList::from_mem_and_segment( &self.memory.contexts[0].segments[Segment::AccessedStorageKeys.unscale()].content [..acc_storage_len], Segment::AccessedStorageKeys, @@ -638,14 +638,14 @@ impl<'a> Iterator for CodeIterator<'a> { // In this representation, the values of nodes are stored in the range // `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - // 1]` holds the address of the next node, where i = node_size * j. -pub(crate) struct AccList<'a> { - access_list_mem: &'a [Option], +pub(crate) struct LinkedList<'a> { + linked_list_mem: &'a [Option], node_size: usize, offset: usize, pos: usize, } -impl<'a> AccList<'a> { +impl<'a> LinkedList<'a> { const fn from_mem_and_segment( access_list_mem: &'a [Option], segment: Segment, @@ -654,7 +654,7 @@ impl<'a> AccList<'a> { return Err(ProgramError::ProverInputError(InvalidInput)); } Ok(Self { - access_list_mem, + linked_list_mem: access_list_mem, node_size: match segment { Segment::AccessedAddresses => 2, Segment::AccessedStorageKeys => 4, @@ -667,12 +667,12 @@ impl<'a> AccList<'a> { } } -impl<'a> Iterator for AccList<'a> { +impl<'a> Iterator for LinkedList<'a> { type Item = (usize, U256, U256, U256); fn next(&mut self) -> Option { if let Ok(new_pos) = - u256_to_usize(self.access_list_mem[self.pos + self.node_size - 1].unwrap_or_default()) + u256_to_usize(self.linked_list_mem[self.pos + self.node_size - 1].unwrap_or_default()) { let old_pos = self.pos; self.pos = new_pos - self.offset; @@ -680,7 +680,7 @@ impl<'a> Iterator for AccList<'a> { // addresses Some(( old_pos, - self.access_list_mem[self.pos].unwrap_or_default(), + self.linked_list_mem[self.pos].unwrap_or_default(), U256::zero(), U256::zero(), )) @@ -688,9 +688,9 @@ impl<'a> Iterator for AccList<'a> { // storage_keys or accounts linked list Some(( old_pos, - self.access_list_mem[self.pos].unwrap_or_default(), - self.access_list_mem[self.pos + 1].unwrap_or_default(), - self.access_list_mem[self.pos + 2].unwrap_or_default(), + self.linked_list_mem[self.pos].unwrap_or_default(), + self.linked_list_mem[self.pos + 1].unwrap_or_default(), + self.linked_list_mem[self.pos + 2].unwrap_or_default(), )) } } else { From ecf0e8630d5990e8eea6234a3b23c106edd36107 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Wed, 22 May 2024 16:13:28 +0200 Subject: [PATCH 006/118] [WIP] changes during the flights --- .../src/cpu/kernel/tests/core/access_lists.rs | 4 +- .../src/cpu/kernel/tests/mpt/linked_list.rs | 83 ++++++- evm_arithmetization/src/generation/mod.rs | 1 + evm_arithmetization/src/generation/mpt.rs | 216 ++++++++++++++++++ .../src/generation/prover_input.rs | 176 +++++--------- evm_arithmetization/src/generation/state.rs | 1 + 6 files changed, 354 insertions(+), 127 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs b/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs index 95a666200..ce2b40bc4 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs @@ -73,12 +73,12 @@ fn test_list_iterator() -> Result<()> { .get_addresses_access_list() .expect("Since we called init_access_lists there must be a list"); - let Some((pos_0, next_val_0, _, _)) = list.next() else { + let Some((pos_0, [next_val_0, _])) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); assert_eq!(next_val_0, U256::MAX); - let Some((pos_0, _, _, _)) = list.next() else { + let Some((pos_0, _)) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 2291e7bb7..ef4ec9438 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -15,8 +15,70 @@ use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; use crate::memory::segments::Segment::{self, AccessedAddresses, AccessedStorageKeys}; +use crate::util::u256_to_usize; +use crate::witness::errors::ProgramError; +use crate::witness::errors::ProverInputError::InvalidInput; use crate::witness::memory::MemoryAddress; +// A linked list implemented using a vector `access_list_mem`. +// In this representation, the values of nodes are stored in the range +// `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - +// 1]` holds the address of the next node, where i = node_size * j. +pub(crate) struct LinkedList<'a, const N: usize> { + linked_list_mem: &'a mut Vec>, + offset: usize, + pos: usize, +} + +impl<'a, const N: usize> LinkedList<'a, N> { + fn from_mem_and_segment( + access_list_mem: &'a mut Vec>, + segment: Segment, + ) -> Result { + if access_list_mem.is_empty() { + return Err(ProgramError::ProverInputError(InvalidInput)); + } + Ok(Self { + linked_list_mem: access_list_mem, + offset: segment as usize, + pos: 0, + }) + } + + /// Returns the index of a node whose value is less or equal than `val` + fn predecessor(self, val: U256) -> Option { + for (curr_ptr, node) in self { + if node[0] > val { + return Some(curr_ptr); + } + } + None + } + + fn insert(&mut self, node: &[Option; N]) -> Result<(), ProgramError> { + self.linked_list_mem.extend_from_slice(node); + Ok(()) + } +} + +impl<'a, const N: usize> Iterator for LinkedList<'a, N> { + type Item = (usize, [U256; N]); + + fn next(&mut self) -> Option { + if let Ok(new_pos) = + u256_to_usize(self.linked_list_mem[self.pos + N - 1].unwrap_or_default()) + { + let old_pos = self.pos; + self.pos = new_pos - self.offset; + Some(( + old_pos, + std::array::from_fn(|i| self.linked_list_mem[self.pos + i].unwrap_or_default()), + )) + } else { + None + } + } +} fn init_logger() { let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } @@ -69,20 +131,22 @@ fn test_list_iterator() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some((pos_0, addr, ptr, ctr)) = list.next() else { + let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); - let Some((pos_0, addr, ptr, ctr)) = list.next() else { + assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); + let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); + assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); Ok(()) } @@ -118,21 +182,28 @@ fn test_insert_account() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some((old_pos, addr, ptr, ctr)) = list.next() else { + let Some((old_pos, [addr, ptr, ctr, scaled_next_pos])) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(old_pos, 0); assert_eq!(addr, U256::from(address.0.as_slice())); assert_eq!(ptr, payload_ptr); assert_eq!(ctr, U256::zero()); - let Some((old_pos, addr, ptr, ctr)) = list.next() else { + assert_eq!( + scaled_next_pos, + (Segment::AccountsLinkedList as usize).into() + ); + let Some((old_pos, [addr, ptr, ctr, scaled_new_pos])) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(old_pos, 4); assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); - + assert_eq!( + scaled_new_pos, + (Segment::AccountsLinkedList as usize + 4).into() + ); Ok(()) } @@ -284,7 +355,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - for (i, (_, addr, ptr, ctr)) in list.enumerate() { + for (i, (_, [addr, ptr, ctr, _])) in list.enumerate() { if addr == U256::MAX { // assert_eq!(addr, U256::MAX); diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 84da8ceb2..58d8adad9 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -28,6 +28,7 @@ use crate::proof::{BlockHashes, BlockMetadata, ExtraBlockData, PublicValues, Tri use crate::util::{h2u, u256_to_usize}; use crate::witness::memory::{MemoryAddress, MemoryChannel}; +pub(crate) mod linked_list; pub mod mpt; pub(crate) mod prover_input; pub(crate) mod rlp; diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index cb91f06c9..fd06850ec 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -30,6 +30,17 @@ pub struct TrieRootPtrs { pub receipt_root_ptr: usize, } +pub struct StateAndStorageLeaves { + pub state_leaves: Vec, + pub storage_leaves: Vec, +} + +pub struct TxnAndReceiptTries { + pub txn_root_ptr: usize, + pub receipt_root_ptr: usize, + pub trie_data: Vec, +} + impl Default for AccountRlp { fn default() -> Self { Self { @@ -308,6 +319,143 @@ fn load_state_trie( } } +// pub enum NodePtr { +// Inner(usize), +// Leaf(usize), +// } + +fn get_state_and_storage_leaves( + trie: &HashedPartialTrie, + key: Nibbles, + state_leaves: &mut Vec, + storage_leaves: &mut Vec, + storage_tries_by_state_key: &HashMap, +) -> Result<(), ProgramError> { + match trie.deref() { + Node::Branch { children, value } => { + if !value.is_empty() { + return Err(ProgramError::ProverInputError( + ProverInputError::InvalidMptInput, + )); + } + + for (i, child) in children.iter().enumerate() { + let extended_key = key.merge_nibbles(&Nibbles { + count: 1, + packed: i.into(), + }); + + get_state_and_storage_leaves( + child, + extended_key, + state_leaves, + storage_leaves, + storage_tries_by_state_key, + )?; + } + + Ok(()) + } + Node::Extension { nibbles, child } => { + let extended_key = key.merge_nibbles(nibbles); + let child_ptr = get_state_and_storage_leaves( + child, + extended_key, + state_leaves, + storage_leaves, + storage_tries_by_state_key, + )?; + + Ok(()) + } + Node::Leaf { nibbles, value } => { + let account: AccountRlp = rlp::decode(value).map_err(|_| ProgramError::InvalidRlp)?; + let AccountRlp { + nonce, + balance, + storage_root, + code_hash, + } = account; + + let storage_hash_only = HashedPartialTrie::new(Node::Hash(storage_root)); + let merged_key = key.merge_nibbles(nibbles); + let storage_trie: &HashedPartialTrie = storage_tries_by_state_key + .get(&merged_key) + .copied() + .unwrap_or(&storage_hash_only); + + assert_eq!( + storage_trie.hash(), + storage_root, + "In TrieInputs, an account's storage_root didn't match the +associated storage trie hash" + ); + + state_leaves.push(nibbles.count.into()); + state_leaves.push( + nibbles + .try_into() + .map_err(|_| ProgramError::IntegerTooLarge)?, + ); + // Set `value_ptr_ptr`. + state_leaves.push((state_leaves.len() + 1).into()); + + state_leaves.push(nonce); + state_leaves.push(balance); + // The Storage pointer is only written in the trie + state_leaves.push(code_hash.into_uint()); + let storage_ptr = + get_storage_leaves(storage_trie, storage_leaves, &parse_storage_value)?; + + Ok(()) + } + _ => Ok(()), + } +} + +pub(crate) fn get_storage_leaves( + trie: &HashedPartialTrie, + storage_leaves: &mut Vec, + parse_value: &F, +) -> Result<(), ProgramError> +where + F: Fn(&[u8]) -> Result, ProgramError>, +{ + match trie.deref() { + Node::Branch { children, value } => { + // Now, load all children and update their pointers. + for (i, child) in children.iter().enumerate() { + let child_ptr = get_storage_leaves(child, storage_leaves, parse_value)?; + } + + Ok(()) + } + + Node::Extension { nibbles, child } => { + get_storage_leaves(child, storage_leaves, parse_value)?; + + Ok(()) + } + Node::Leaf { nibbles, value } => { + storage_leaves.push(nibbles.count.into()); + storage_leaves.push( + nibbles + .try_into() + .map_err(|_| ProgramError::IntegerTooLarge)?, + ); + + // Set `value_ptr_ptr`. + storage_leaves.push((storage_leaves.len() + 1).into()); + + let leaf = parse_value(value)?; + storage_leaves.extend(leaf); + + Ok(()) + } + _ => Ok(()), + } +} + pub(crate) fn load_all_mpts( trie_inputs: &TrieInputs, ) -> Result<(TrieRootPtrs, Vec), ProgramError> { @@ -346,6 +494,74 @@ pub(crate) fn load_all_mpts( Ok((trie_root_ptrs, trie_data)) } +pub(crate) fn load_linked_lists_txn_and_receipt_mpt( + trie_inputs: &TrieInputs, +) -> Result<(StateAndStorageLeaves, TxnAndReceiptTries), ProgramError> { + let mut state_leaves = vec![U256::zero()]; + let mut storage_leaves = vec![U256::zero()]; + let mut trie_data = vec![U256::zero()]; + + let storage_tries_by_state_key = trie_inputs + .storage_tries + .iter() + .map(|(hashed_address, storage_trie)| { + let key = Nibbles::from_bytes_be(hashed_address.as_bytes()) + .expect("An H256 is 32 bytes long"); + (key, storage_trie) + }) + .collect(); + + let txn_root_ptr = load_mpt(&trie_inputs.transactions_trie, &mut trie_data, &|rlp| { + let mut parsed_txn = vec![U256::from(rlp.len())]; + parsed_txn.extend(rlp.iter().copied().map(U256::from)); + Ok(parsed_txn) + })?; + + let receipt_root_ptr = load_mpt(&trie_inputs.receipts_trie, &mut trie_data, &parse_receipts)?; + + get_state_and_storage_leaves( + &trie_inputs.state_trie, + empty_nibbles(), + &mut state_leaves, + &mut storage_leaves, + &storage_tries_by_state_key, + ); + + Ok(( + StateAndStorageLeaves { + state_leaves, + storage_leaves, + }, + TxnAndReceiptTries { + txn_root_ptr, + receipt_root_ptr, + trie_data, + }, + )) +} + +pub(crate) fn load_state_mpt( + trie_inputs: &TrieInputs, + trie_data: &mut Vec, +) -> Result { + let storage_tries_by_state_key = trie_inputs + .storage_tries + .iter() + .map(|(hashed_address, storage_trie)| { + let key = Nibbles::from_bytes_be(hashed_address.as_bytes()) + .expect("An H256 is 32 bytes long"); + (key, storage_trie) + }) + .collect(); + + load_state_trie( + &trie_inputs.state_trie, + empty_nibbles(), + trie_data, + &storage_tries_by_state_key, + ) +} + pub mod transaction_testing { use super::*; diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 39a8fb737..74eac16dc 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -9,6 +9,7 @@ use num_bigint::BigUint; use plonky2::field::types::Field; use serde::{Deserialize, Serialize}; +use super::linked_list::LinkedList; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::simulate_cpu_and_get_user_jumps; @@ -33,6 +34,10 @@ use crate::witness::util::{current_context_peek, stack_peek}; #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)] pub struct ProverInputFn(Vec); +pub const ADRESSSES_ACCESS_LIST_LEN: usize = 2; +pub const STORAGE_KEYS_ACCESS_LIST_LEN: usize = 4; +pub const ACCOUNTS_LINKED_LIST_LEN: usize = 4; + impl From> for ProverInputFn { fn from(v: Vec) -> Self { Self(v) @@ -339,14 +344,14 @@ impl GenerationState { /// `value <= addr < next_value` and `addr` is the top of the stack. fn run_next_addresses_insert(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _, _) in self.get_addresses_access_list()? { - if next_addr > addr { - // In order to avoid pointers to the next ptr, we use the fact - // that valid pointers and Segment::AccessedAddresses are always even - return Ok(((Segment::AccessedAddresses as usize + curr_ptr) / 2usize).into()); - } + if let Some(ptr) = self + .get_addresses_access_list()? + .predecessor(|node| node[0] > addr) + { + Ok(((Segment::AccessedAddresses as usize + ptr) / 2usize).into()) + } else { + Ok((Segment::AccessedAddresses as usize).into()) } - Ok((Segment::AccessedAddresses as usize).into()) } /// Returns a pointer to an element in the list whose value is such that @@ -354,7 +359,7 @@ impl GenerationState { /// If the element is not in the list returns loops forever fn run_next_addresses_remove(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _, _) in self.get_addresses_access_list()? { + for (curr_ptr, [next_addr, _]) in self.get_addresses_access_list()? { if next_addr == addr { return Ok(((Segment::AccessedAddresses as usize + curr_ptr) / 2usize).into()); } @@ -367,14 +372,14 @@ impl GenerationState { fn run_next_storage_insert(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - for (curr_ptr, next_addr, next_key, _) in self.get_storage_keys_access_list()? { - if next_addr > addr || (next_addr == addr && next_key > key) { - // In order to avoid pointers to the key, value or next ptr, we use the fact - // that valid pointers and Segment::AccessedAddresses are always multiples of 4 - return Ok(((Segment::AccessedStorageKeys as usize + curr_ptr) / 4usize).into()); - } + if let Some(ptr) = self + .get_storage_keys_access_list()? + .predecessor(|node| node[0] > addr || (node[0] == addr && node[1] > key)) + { + Ok(((Segment::AccessedStorageKeys as usize + ptr) / 4usize).into()) + } else { + Ok((Segment::AccessedAddresses as usize).into()) } - Ok((Segment::AccessedAddresses as usize).into()) } /// Returns a pointer to the predecessor of the top of the stack in the @@ -382,26 +387,28 @@ impl GenerationState { fn run_next_storage_remove(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - for (curr_ptr, next_addr, next_key, _) in self.get_storage_keys_access_list()? { - if (next_addr == addr && next_key == key) || next_addr == U256::MAX { - return Ok(((Segment::AccessedStorageKeys as usize + curr_ptr) / 4usize).into()); - } + if let Some(ptr) = self + .get_storage_keys_access_list()? + .predecessor(|node| (node[0] == addr && node[1] == key) || node[0] == U256::MAX) + { + Ok(((Segment::AccessedStorageKeys as usize + ptr) / 4usize).into()) + } else { + Ok((Segment::AccessedStorageKeys as usize).into()) } - Ok((Segment::AccessedStorageKeys as usize).into()) } /// Returns a pointer to an element in the list whose value is such that /// `value <= addr < next_value` and `addr` is the top of the stack. fn run_next_insert_account(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _, _) in self.get_accounts_linked_list()? { - if next_addr > addr { - // In order to avoid pointers to the next ptr, we use the fact - // that valid pointers and Segment::AccessedAddresses are always even - return Ok(((Segment::AccountsLinkedList as usize + curr_ptr) / 4usize).into()); - } + if let Some(pred) = self + .get_accounts_linked_list()? + .predecessor(|node| node[0] > addr) + { + Ok(((Segment::AccountsLinkedList as usize + pred) / 4usize).into()) + } else { + Ok((Segment::AccountsLinkedList as usize).into()) } - Ok((Segment::AccessedAddresses as usize).into()) } /// Returns a pointer to an element in the list whose value is such that @@ -409,12 +416,14 @@ impl GenerationState { /// If the element is not in the list loops forever fn run_next_remove_account(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, next_addr, _, _) in self.get_accounts_linked_list()? { - if next_addr == addr { - return Ok(((Segment::AccountsLinkedList as usize + curr_ptr) / 4usize).into()); - } + if let Some(ptr) = self + .get_accounts_linked_list()? + .predecessor(|node| node[0] == addr) + { + Ok(((Segment::AccountsLinkedList as usize + ptr) / 4usize).into()) + } else { + Ok((Segment::AccessedAddresses as usize).into()) } - Ok((Segment::AccessedAddresses as usize).into()) } } @@ -487,30 +496,30 @@ impl GenerationState { } } - pub(crate) fn get_addresses_access_list(&self) -> Result { + pub(crate) fn get_addresses_access_list( + &mut self, + ) -> Result, ProgramError> { // `GlobalMetadata::AccessedAddressesLen` stores the value of the next available // virtual address in the segment. In order to get the length we need // to substract `Segment::AccessedAddresses` as usize. - let acc_addr_len = - u256_to_usize(self.get_global_metadata(GlobalMetadata::AccessedAddressesLen))? - - Segment::AccessedAddresses as usize; + let mem_len = self.memory.contexts[0].segments[Segment::AccessedAddresses.unscale()] + .content + .len(); LinkedList::from_mem_and_segment( - &self.memory.contexts[0].segments[Segment::AccessedAddresses.unscale()].content - [..acc_addr_len], + &mut self.memory.contexts[0].segments[Segment::AccessedAddresses.unscale()].content, + mem_len, Segment::AccessedAddresses, ) } - pub(crate) fn get_accounts_linked_list(&self) -> Result { + pub(crate) fn get_accounts_linked_list( + &mut self, + ) -> Result, ProgramError> { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next // available virtual address in the segment. In order to get the length // we need to substract `Segment::AccountsLinkedList` as usize. - let acc_list_len = - u256_to_usize(self.get_global_metadata(GlobalMetadata::AccountsLinkedListLen))? - - Segment::AccountsLinkedList as usize; LinkedList::from_mem_and_segment( - &self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content - [..acc_list_len], + &mut self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content, Segment::AccountsLinkedList, ) } @@ -523,20 +532,14 @@ impl GenerationState { )) } - pub(crate) fn get_storage_keys_access_list(&self) -> Result { + pub(crate) fn get_storage_keys_access_list( + &mut self, + ) -> Result, ProgramError> { // GlobalMetadata::AccessedStorageKeysLen stores the value of the next available // virtual address in the segment. In order to get the length we need // to substract Segment::AccessedStorageKeys as usize - let acc_storage_len = u256_to_usize( - self.memory.get_with_init(MemoryAddress::new( - 0, - Segment::GlobalMetadata, - GlobalMetadata::AccessedStorageKeysLen.unscale(), - )) - Segment::AccessedStorageKeys as usize, - )?; LinkedList::from_mem_and_segment( - &self.memory.contexts[0].segments[Segment::AccessedStorageKeys.unscale()].content - [..acc_storage_len], + &mut self.memory.contexts[0].segments[Segment::AccessedStorageKeys.unscale()].content, Segment::AccessedStorageKeys, ) } @@ -634,71 +637,6 @@ impl<'a> Iterator for CodeIterator<'a> { } } -// Iterates over a linked list implemented using a vector `access_list_mem`. -// In this representation, the values of nodes are stored in the range -// `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - -// 1]` holds the address of the next node, where i = node_size * j. -pub(crate) struct LinkedList<'a> { - linked_list_mem: &'a [Option], - node_size: usize, - offset: usize, - pos: usize, -} - -impl<'a> LinkedList<'a> { - const fn from_mem_and_segment( - access_list_mem: &'a [Option], - segment: Segment, - ) -> Result { - if access_list_mem.is_empty() { - return Err(ProgramError::ProverInputError(InvalidInput)); - } - Ok(Self { - linked_list_mem: access_list_mem, - node_size: match segment { - Segment::AccessedAddresses => 2, - Segment::AccessedStorageKeys => 4, - Segment::AccountsLinkedList => 4, - _ => return Err(ProgramError::ProverInputError(InvalidInput)), - }, - offset: segment as usize, - pos: 0, - }) - } -} - -impl<'a> Iterator for LinkedList<'a> { - type Item = (usize, U256, U256, U256); - - fn next(&mut self) -> Option { - if let Ok(new_pos) = - u256_to_usize(self.linked_list_mem[self.pos + self.node_size - 1].unwrap_or_default()) - { - let old_pos = self.pos; - self.pos = new_pos - self.offset; - if self.node_size == 2 { - // addresses - Some(( - old_pos, - self.linked_list_mem[self.pos].unwrap_or_default(), - U256::zero(), - U256::zero(), - )) - } else { - // storage_keys or accounts linked list - Some(( - old_pos, - self.linked_list_mem[self.pos].unwrap_or_default(), - self.linked_list_mem[self.pos + 1].unwrap_or_default(), - self.linked_list_mem[self.pos + 2].unwrap_or_default(), - )) - } - } else { - None - } - } -} - enum EvmField { Bls381Base, Bls381Scalar, diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index 6e08c5391..bf04fd587 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -320,6 +320,7 @@ impl GenerationState { trie_roots_ptrs } + pub(crate) fn new(inputs: GenerationInputs, kernel_code: &[u8]) -> Result { let rlp_prover_inputs = all_rlp_prover_inputs_reversed(inputs.clone().signed_txn.as_ref().unwrap_or(&vec![])); From 65773d8cda0698289f0ee6fd727f5cf4bf8092c5 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 24 May 2024 11:21:21 +0200 Subject: [PATCH 007/118] Fix storage ll error --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 303 +++++++++++++-- .../cpu/kernel/constants/global_metadata.rs | 9 +- .../src/cpu/kernel/tests/mpt/linked_list.rs | 362 ++++++++++++++---- evm_arithmetization/src/generation/mpt.rs | 32 +- .../src/generation/prover_input.rs | 111 ++++-- evm_arithmetization/src/generation/state.rs | 35 ++ evm_arithmetization/src/memory/segments.rs | 7 +- 7 files changed, 724 insertions(+), 135 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index eef89e7bf..b70899e88 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -6,14 +6,22 @@ /// Searching and inserting is done by guessing the predecessor in the list. /// If the address/storage key isn't found in the array, it is inserted at the end. -// Initialize an empty linked list (@U256_MAX)⮌ +// Initialize an empty account linked list (@U256_MAX)⮌ // which is written as [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST -// The stire values at the respective positions are: +// The values at the respective positions are: // - 0: The account key // - 1: A ptr to the payload (the account values) -// - 2: A counter indicating if the number of times this address have been accessed. +// - 2: A counter indicating the number of times this address have been accessed. // - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. -global init_accounts_linked_list: +// Initialize also an empty storage linked list (@U256_MAX)⮌ +// which is written as [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST +// The values at the respective positions are: +// - 0: The account key +// - 1: The key +// - 2: A ptr to the payload (the account values) +// - 3: A counter indicating the number of times this slot have been accessed. +// - 4: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. +global init_linked_lists: // stack: (empty) // Initialize SEGMENT_ACCOUNTS_LINKED_LIST @@ -31,11 +39,27 @@ global init_accounts_linked_list: // Store the segment scaled length %increment %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) + + // Initialize SEGMENT_STORAGE_LINKED_LIST + // Store @U256_MAX at the beggining of the segment + PUSH @SEGMENT_STORAGE_LINKED_LIST // ctx == virt == 0 + DUP1 + PUSH @U256_MAX + MSTORE_GENERAL + // Store @SEGMENT_ACCOUNTS_LINKED_LIST at address 2 + %add_const(4) + DUP1 + PUSH @SEGMENT_STORAGE_LINKED_LIST + MSTORE_GENERAL + + // Store the segment scaled length + %increment + %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) JUMP -%macro init_accounts_linked_list +%macro init_linked_lists PUSH %%after - %jump(init_account_linked_list) + %jump(init_account_linked_lists) %%after: %endmacro @@ -67,17 +91,14 @@ global init_accounts_linked_list: %mul_const(4) %endmacro -/// Inserts the account addr and payload pinter into the linked list if it is not already present. -/// `value` should be the current storage value at the slot `(addr, key)`. -/// Return `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present +/// Inserts the account addr and payload pointer into the linked list if it is not already present. +/// Return `1, payload_ptr` if the account was inserted, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. global insert_account: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr, payload_ptr, retdest -global debug_ptr_div_4: %get_valid_account_ptr -global debug_ptr: // stack: pred_ptr, addr, payload_ptr, retdest DUP1 MLOAD_GENERAL @@ -89,7 +110,6 @@ global debug_ptr: // If the predesessor is strictly smaller or the predecessor is the special // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. -global debug_before_jumpi: %jumpi(insert_new_account) // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. @@ -106,11 +126,10 @@ global debug_before_jumpi: // The storage key is not in the list. PANIC -global debug_account_found: account_found: // The address was already in the list // stack: pred_ptr, addr, payload_ptr, retdest - // Load the access counter + // Load the the payload pointer and access counter %increment DUP1 MLOAD_GENERAL @@ -118,15 +137,12 @@ account_found: SWAP1 %increment DUP1 -global debug_before_load_ctr: MLOAD_GENERAL -global debug_after_load_ctr: %increment // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, payload_ptr, retdest SWAP1 DUP2 // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest -global debug_before_store_ctr: MSTORE_GENERAL // stack: access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest // If access_ctr == 1 then this it's a cold access @@ -134,7 +150,6 @@ global debug_before_store_ctr: %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP -global debug_insert_new_account: insert_new_account: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest POP @@ -164,13 +179,11 @@ insert_new_account: // stack: new_ptr, next_ptr, addr, payload_ptr, retdest DUP1 DUP4 -global debug_store_addr: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, payload_ptr, retdest %increment DUP1 DUP5 -global debug_store_ptr: MSTORE_GENERAL // stack: new_ptr + 1, next_ptr, addr, payload_ptr, retdest %increment @@ -191,7 +204,6 @@ global debug_store_ptr: PUSH 0 SWAP1 SWAP2 -global debug_before_jump: JUMP /// Remove the storage key and its value from the access list. @@ -200,9 +212,7 @@ global remove_account: // stack: addr, retdest PROVER_INPUT(linked_list::remove_account) // stack: pred_ptr/4, addr, retdest -global debug_before_del_ptr: %get_valid_account_ptr -global debug_after_del_ptr: // stack: pred_ptr, addr, retdest %add_const(3) // stack: next_ptr_ptr, addr, retdest @@ -228,7 +238,248 @@ global debug_after_del_ptr: POP JUMP -// Polulates the state MPT with the nodes in the list plus non-deterministically guessed -// hased nodes. -global account_linked_list_to_state_trie: + +// +// +// STORAGE linked list +// +// + +%macro insert_slot + %stack (addr, key, ptr) -> (addr, key, ptr, %%after) + %jump(insert_slot) +%%after: + // stack: cold_access +%endmacro + +%macro insert_slot_no_return + %insert_account + POP +%endmacro + +// Multiply the value at the top of the stack, denoted by ptr/5, by 5 +// and abort if ptr/5 >= (mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN] - @SEGMENT_STORAGE_LINKED_LIST)/5 +// In this way @SEGMENT_STORAGE_LINKED_LIST + 5*ptr/5 must be pointing to the beginning of a node. +// TODO: Maybe we should check here if the node have been deleted. +%macro get_valid_slot_ptr + // stack: ptr/5 + DUP1 + %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) + %sub_const(@SEGMENT_STORAGE_LINKED_LIST) + // By construction, the unscaled list len + // must be multiple of 5 + %div_const(5) + // stack: accessed_strg_keys_len/5, ptr/5, ptr/5 + %assert_gt + %mul_const(5) + %add_const(@SEGMENT_STORAGE_LINKED_LIST) +%endmacro + +/// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present. +/// Return `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present +/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +global insert_slot: + // stack: addr, payload_ptr, retdest + PROVER_INPUT(linked_list::insert_slot) + // stack: pred_ptr/5, addr, key, payload_ptr, retdest + %get_valid_slot_ptr + + // stack: pred_ptr, addr, key, payload_ptr, retdest + DUP1 + MLOAD_GENERAL + DUP1 + // stack: pred_addr, pred_addr, pred_ptr, addr, key, payload_ptr, retdest + DUP4 + GT + DUP3 %eq_const(@SEGMENT_STORAGE_LINKED_LIST) + ADD // OR + // If the predesessor is strictly smaller or the predecessor is the special + // node with key @U256_MAX (and hence we're inserting a new minimum), then + // we need to insert a new node. + %jumpi(insert_new_slot) + // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. + DUP3 + %assert_eq + // stack: pred_ptr, addr, key, payload_ptr, retdest + DUP1 + %increment + MLOAD_GENERAL + // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + DUP1 DUP5 + GT + %jumpi(insert_new_slot) + // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + DUP4 + // We know that key <= pred_key. It must hold that pred_key == key. + %assert_eq + // stack: pred_ptr, addr, key, payload_ptr, retdest + + // stack: pred_ptr, addr, key, payload_ptr, retdest + // Check that this is not a deleted node + DUP1 + %add_const(4) + MLOAD_GENERAL + %jump_neq_const(@U256_MAX, slot_found) + // The storage key is not in the list. + PANIC + +slot_found: + // The slot was already in the list + // stack: pred_ptr, addr, key, payload_ptr, retdest + // Load the the payload pointer and access counter + %add_const(2) + DUP1 + MLOAD_GENERAL + // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest + SWAP1 + %increment + DUP1 + MLOAD_GENERAL + %increment + // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, key, payload_ptr, retdest + SWAP1 + DUP2 + // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest + MSTORE_GENERAL + // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest + // If access_ctr == 1 then this it's a cold access + %eq_const(1) + %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + JUMP + +global debug_insert_new_slot: +insert_new_slot: + // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + POP + // get the value of the next address + %add_const(4) + // stack: next_ptr_ptr, addr, key, payload_ptr, retdest + %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) + DUP2 + MLOAD_GENERAL +global debug_next_ptr: + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // Check that this is not a deleted node + DUP1 + %eq_const(@U256_MAX) + %assert_zero + DUP1 + MLOAD_GENERAL +global debug_next_addr: + // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + DUP1 + DUP6 + // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). + // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. +global debug_before_lt: + LT + %jumpi(next_node_ok) + // If addr <= next_addr, then it addr must be equal to next_addr + // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + DUP5 + %assert_eq +global debug_after_assert_eq: + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + DUP1 + %increment + MLOAD_GENERAL + // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + DUP6 + // The next key must be strictly larger + %assert_lt +global debug_next_node_ok: +next_node_ok: + // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + POP + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + SWAP2 + DUP2 + // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, key, payload_ptr, retdest + MSTORE_GENERAL + // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest + // Write the address in the new node + DUP1 + DUP4 + MSTORE_GENERAL + // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest + // Write the key in the new node + %increment + DUP1 + DUP5 + MSTORE_GENERAL + // stack: new_ptr + 1, next_ptr, addr, key, payload_ptr, retdest + // Store payload_ptr + %increment + DUP1 + DUP6 + MSTORE_GENERAL + + // stack: new_ptr + 2, next_ptr, addr, key, payload_ptr, retdest + // Store the counter + %increment + DUP1 + PUSH 0 + MSTORE_GENERAL + // stack: new_ptr + 3, next_ptr, addr, key, payload_ptr, retdest + %increment + DUP1 + // stack: new_next_ptr, new_next_ptr, next_ptr, addr, key, payload_ptr, retdest + SWAP2 + MSTORE_GENERAL + // stack: new_next_ptr, addr, key, payload_ptr, retdest + %increment + %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) + // stack: addr, key, payload_ptr, retdest + // TODO: Don't for get to %journal_add_storage_loaded!!! + %pop2 + PUSH 0 + SWAP1 + SWAP2 + JUMP + +/// Remove the storage key and its value from the list. +/// Panics if the key is not in the list. +global remove_slot: + // stack: addr, key, retdest + PROVER_INPUT(linked_list::remove_slot) + // stack: pred_ptr/5, addr, key, retdest +global debug_before_valid_storage_ptr: + %get_valid_slot_ptr +global debug_after_valid_storage_ptr: + // stack: pred_ptr, addr, key, retdest + %add_const(4) + // stack: next_ptr_ptr, addr, key, retdest + DUP1 + MLOAD_GENERAL + // stack: next_ptr, next_ptr_ptr, addr, key, retdest + DUP1 + MLOAD_GENERAL + // stack: next_addr, next_ptr, next_ptr_ptr, addr, key, retdest + DUP4 +global debug_before_assert_eq: + %assert_eq + // stack: next_ptr, next_ptr_ptr, addr, key, retdest + DUP1 + %increment + MLOAD_GENERAL + // stack: next_key, next_ptr, next_ptr_ptr, addr, key, retdest + DUP5 +global debug_before_assert_eq_2: + %assert_eq + // stack: next_ptr, next_ptr_ptr, addr, key, retdest + %add_const(4) + // stack: next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + DUP1 + MLOAD_GENERAL + // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + // Mark the next node as deleted + SWAP1 + PUSH @U256_MAX + MSTORE_GENERAL + // stack: next_next_ptr, next_ptr_ptr, addr, key, retdest + MSTORE_GENERAL + %pop2 + JUMP + \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs index f3f46e220..24eeed49b 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs @@ -95,13 +95,16 @@ pub(crate) enum GlobalMetadata { KernelHash, KernelLen, - /// Then address of the next available address in + /// The address of the next available address in /// Segment::AccountsLinkedList AccountsLinkedListLen, + // The address of the next available address in + /// Segment::StorageLinkedList + StorageLinkedListLen, } impl GlobalMetadata { - pub(crate) const COUNT: usize = 48; + pub(crate) const COUNT: usize = 49; /// Unscales this virtual offset by their respective `Segment` value. pub(crate) const fn unscale(&self) -> usize { @@ -158,6 +161,7 @@ impl GlobalMetadata { Self::KernelHash, Self::KernelLen, Self::AccountsLinkedListLen, + Self::StorageLinkedListLen, ] } @@ -212,6 +216,7 @@ impl GlobalMetadata { Self::KernelHash => "GLOBAL_METADATA_KERNEL_HASH", Self::KernelLen => "GLOBAL_METADATA_KERNEL_LEN", Self::AccountsLinkedListLen => "GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN", + Self::StorageLinkedListLen => "GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN", } } } diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index ef4ec9438..8319e402b 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -20,65 +20,6 @@ use crate::witness::errors::ProgramError; use crate::witness::errors::ProverInputError::InvalidInput; use crate::witness::memory::MemoryAddress; -// A linked list implemented using a vector `access_list_mem`. -// In this representation, the values of nodes are stored in the range -// `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - -// 1]` holds the address of the next node, where i = node_size * j. -pub(crate) struct LinkedList<'a, const N: usize> { - linked_list_mem: &'a mut Vec>, - offset: usize, - pos: usize, -} - -impl<'a, const N: usize> LinkedList<'a, N> { - fn from_mem_and_segment( - access_list_mem: &'a mut Vec>, - segment: Segment, - ) -> Result { - if access_list_mem.is_empty() { - return Err(ProgramError::ProverInputError(InvalidInput)); - } - Ok(Self { - linked_list_mem: access_list_mem, - offset: segment as usize, - pos: 0, - }) - } - - /// Returns the index of a node whose value is less or equal than `val` - fn predecessor(self, val: U256) -> Option { - for (curr_ptr, node) in self { - if node[0] > val { - return Some(curr_ptr); - } - } - None - } - - fn insert(&mut self, node: &[Option; N]) -> Result<(), ProgramError> { - self.linked_list_mem.extend_from_slice(node); - Ok(()) - } -} - -impl<'a, const N: usize> Iterator for LinkedList<'a, N> { - type Item = (usize, [U256; N]); - - fn next(&mut self) -> Option { - if let Ok(new_pos) = - u256_to_usize(self.linked_list_mem[self.pos + N - 1].unwrap_or_default()) - { - let old_pos = self.pos; - self.pos = new_pos - self.offset; - Some(( - old_pos, - std::array::from_fn(|i| self.linked_list_mem[self.pos + i].unwrap_or_default()), - )) - } else { - None - } - } -} fn init_logger() { let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "debug")); } @@ -86,7 +27,7 @@ fn init_logger() { #[test] fn test_init_linked_lists() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_accounts_linked_list"]; + let init_label = KERNEL.global_labels["init_linked_lists"]; // Check the initial state of the linked list in the kernel. let initial_stack = vec![0xdeadbeefu32.into()]; @@ -95,6 +36,7 @@ fn test_init_linked_lists() -> Result<()> { assert!(interpreter.stack().is_empty()); + // Check the initial accounts linked list let acc_addr_list: Vec = (0..4) .map(|i| { interpreter @@ -113,25 +55,45 @@ fn test_init_linked_lists() -> Result<()> { acc_addr_list ); + // Check the inital storage linked list + let acc_addr_list: Vec = (0..5) + .map(|i| { + interpreter + .generation_state + .memory + .get_with_init(MemoryAddress::new(0, Segment::StorageLinkedList, i)) + }) + .collect(); + assert_eq!( + vec![ + U256::MAX, + U256::zero(), + U256::zero(), + U256::zero(), + (Segment::StorageLinkedList as usize).into(), + ], + acc_addr_list + ); + Ok(()) } #[test] fn test_list_iterator() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_accounts_linked_list"]; + let init_label = KERNEL.global_labels["init_linked_lists"]; let initial_stack = vec![0xdeadbeefu32.into()]; let mut interpreter = Interpreter::::new(init_label, initial_stack); interpreter.run()?; // test the list iterator - let mut list = interpreter + let mut accounts_list = interpreter .generation_state .get_accounts_linked_list() - .expect("Since we called init_access_lists there must be a list"); + .expect("Since we called init_access_lists there must be an accounts list"); - let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = list.next() else { + let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); @@ -139,7 +101,7 @@ fn test_list_iterator() -> Result<()> { assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); - let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = list.next() else { + let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(pos_0, 0); @@ -147,13 +109,36 @@ fn test_list_iterator() -> Result<()> { assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); + + let mut storage_list = interpreter + .generation_state + .get_storage_linked_list() + .expect("Since we called init_access_lists there must be a storage list"); + let Some((pos_0, [addr, key, ptr, ctr, scaled_pos_1])) = storage_list.next() else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(pos_0, 0); + assert_eq!(addr, U256::MAX); + assert_eq!(key, U256::zero()); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); + assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); + let Some((pos_0, [addr, key, ptr, ctr, scaled_pos_1])) = storage_list.next() else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(pos_0, 0); + assert_eq!(addr, U256::MAX); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); + assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); + Ok(()) } #[test] fn test_insert_account() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_accounts_linked_list"]; + let init_label = KERNEL.global_labels["init_linked_lists"]; // Test for address already in list. let initial_stack = vec![0xdeadbeefu32.into()]; @@ -207,11 +192,74 @@ fn test_insert_account() -> Result<()> { Ok(()) } +#[test] +fn test_insert_storage() -> Result<()> { + init_logger(); + let init_label = KERNEL.global_labels["init_linked_lists"]; + + // Test for address already in list. + let initial_stack = vec![0xdeadbeefu32.into()]; + let mut interpreter = Interpreter::::new(init_label, initial_stack); + interpreter.run()?; + + let insert_account_label = KERNEL.global_labels["insert_slot"]; + + let retaddr = 0xdeadbeefu32.into(); + let mut rng = thread_rng(); + let address: H160 = rng.gen(); + let key: H160 = rng.gen(); + let payload_ptr = U256::from(5); + + assert!(address != H160::zero(), "Cosmic luck or bad RNG?"); + + interpreter.push(retaddr); + interpreter.push(payload_ptr); + interpreter.push(U256::from(key.0.as_slice())); + interpreter.push(U256::from(address.0.as_slice())); + interpreter.generation_state.registers.program_counter = insert_account_label; + + interpreter.run()?; + assert_eq!(interpreter.stack(), &[payload_ptr, U256::zero()]); + + let mut list = interpreter + .generation_state + .get_storage_linked_list() + .expect("Since we called init_access_lists there must be a list"); + + let Some((old_pos, [inserted_addr, inserted_key, ptr, ctr, scaled_next_pos])) = list.next() + else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(old_pos, 0); + assert_eq!(inserted_addr, U256::from(address.0.as_slice())); + assert_eq!(inserted_key, U256::from(key.0.as_slice())); + assert_eq!(ptr, payload_ptr); + assert_eq!(ctr, U256::zero()); + assert_eq!( + scaled_next_pos, + (Segment::StorageLinkedList as usize).into() + ); + let Some((old_pos, [inserted_addr, inserted_key, ptr, ctr, scaled_new_pos])) = list.next() + else { + return Err(anyhow::Error::msg("Couldn't get value")); + }; + assert_eq!(old_pos, 5); + assert_eq!(inserted_addr, U256::MAX); + assert_eq!(inserted_key, U256::zero()); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); + assert_eq!( + scaled_new_pos, + (Segment::StorageLinkedList as usize + 5).into() + ); + Ok(()) +} + #[test] fn test_insert_and_delete_accounts() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_accounts_linked_list"]; + let init_label = KERNEL.global_labels["init_linked_lists"]; // Test for address already in list. let initial_stack = vec![0xdeadbeefu32.into()]; @@ -372,3 +420,183 @@ fn test_insert_and_delete_accounts() -> Result<()> { Ok(()) } + +#[test] +fn test_insert_and_delete_storage() -> Result<()> { + init_logger(); + + let init_label = KERNEL.global_labels["init_linked_lists"]; + + // Test for address already in list. + let initial_stack = vec![0xdeadbeefu32.into()]; + let mut interpreter = Interpreter::::new(init_label, initial_stack); + interpreter.run()?; + + let insert_slot_label = KERNEL.global_labels["insert_slot"]; + + let retaddr = 0xdeadbeefu32.into(); + let mut rng = thread_rng(); + let n = 10; + let mut addresses_and_keys = (0..n) + // .map(|_| rng.gen::
()) + .map(|i| { + [ + Address::from_low_u64_be(i as u64 + 5), + H160::from_low_u64_be(i as u64 + 6), + ] + }) + .collect::>() + .into_iter() + .collect::>(); + let delta_ptr = 100; + // let addr_not_in_list = rng.gen::
(); + let addr_not_in_list = Address::from_low_u64_be(4); + let key_not_in_list = H160::from_low_u64_be(5); + assert!( + !addresses_and_keys.contains(&[addr_not_in_list, key_not_in_list]), + "Cosmic luck or bad RNG?" + ); + + let offset = Segment::StorageLinkedList as usize; + // Insert all addresses, key pairs + for i in 0..n { + let [addr, key] = addresses_and_keys[i as usize].map(|x| U256::from(x.0.as_slice())); + interpreter.push(0xdeadbeefu32.into()); + interpreter.push(addr + delta_ptr); // ptr = addr + delta_ptr for the sake of the test + interpreter.push(key); + interpreter.push(addr); + interpreter.generation_state.registers.program_counter = insert_slot_label; + interpreter.run()?; + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::zero() + ); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + addr + delta_ptr + ); + // The counter must be 0 + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(offset + 5 * (i + 1) + 3)).unwrap(), + ), + U256::zero() + ); + } + + // The next free node in Segment::StorageLinkedList must be at offset + (n + + // 1)*5. + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(GlobalMetadata::StorageLinkedListLen as usize)) + .unwrap(), + ), + U256::from(offset + (n + 1) * 5) + ); + + // Test for address already in list. + for i in 0..n { + let [addr_in_list, key_in_list] = + addresses_and_keys[i as usize].map(|x| U256::from(x.0.as_slice())); + interpreter.push(retaddr); + interpreter.push(U256::zero()); + interpreter.push(key_in_list); + interpreter.push(addr_in_list); + interpreter.generation_state.registers.program_counter = insert_slot_label; + interpreter.run()?; + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::one() + ); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + addr_in_list + delta_ptr + ); + // The counter must be one now + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(offset + 5 * (i + 1) + 3)).unwrap(), + ), + U256::one() + ); + } + + // Test for address not in the list. + interpreter.push(retaddr); + interpreter.push(U256::from(addr_not_in_list.0.as_slice()) + delta_ptr); + interpreter.push(U256::from(key_not_in_list.0.as_slice())); + interpreter.push(U256::from(addr_not_in_list.0.as_slice())); + interpreter.generation_state.registers.program_counter = insert_slot_label; + + interpreter.run()?; + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::zero() + ); + assert_eq!( + interpreter.pop().expect("The stack can't be empty"), + U256::from(addr_not_in_list.0.as_slice()) + delta_ptr + ); + + // Now the list of accounts have [4, 5] + addresses_and_keys.push([addr_not_in_list, key_not_in_list]); + + // The next free node in Segment::AccounLinkedList must be at offset + (n + + // 2)*5. + assert_eq!( + interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(GlobalMetadata::StorageLinkedListLen as usize)) + .unwrap(), + ), + U256::from(offset + (n + 2) * 5) + ); + + // Remove all even nodes + let remove_slot_label = KERNEL.global_labels["remove_slot"]; + + let mut new_addresses = vec![]; + + for (i, j) in (0..n).tuples() { + // Test for [address, ke] already in list. + let [addr_in_list, key_in_list] = + addresses_and_keys[i as usize].map(|x| U256::from(x.0.as_slice())); + interpreter.push(retaddr); + interpreter.push(key_in_list); + interpreter.push(addr_in_list); + interpreter.generation_state.registers.program_counter = remove_slot_label; + interpreter.run()?; + assert!(interpreter.stack().is_empty()); + // we add the non deleted addres to new_addresses + new_addresses.push(addresses_and_keys[j]); + } + // the last address is not removed + new_addresses.push(*addresses_and_keys.last().unwrap()); + + // We need to sort the list in order to properly compare with + // the linked list the interpreter's memory + new_addresses.sort(); + + let mut list = interpreter + .generation_state + .get_storage_linked_list() + .expect("Since we called init_access_lists there must be a list"); + + for (i, (_, [addr, key, ptr, ctr, _])) in list.enumerate() { + if addr == U256::MAX { + // + assert_eq!(addr, U256::MAX); + assert_eq!(key, U256::zero()); + assert_eq!(ptr, U256::zero()); + assert_eq!(ctr, U256::zero()); + break; + } + let [addr_in_list, key_in_list] = new_addresses[i].map(|x| U256::from(x.0.as_slice())); + assert_eq!(addr, addr_in_list); + assert_eq!(key, key_in_list); + assert_eq!(ptr, addr + delta_ptr); + // ctr is 0 for the lowest address because is never accessed + assert_eq!(ctr, if i == 0 { U256::zero() } else { U256::one() }); + } + + Ok(()) +} diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index fd06850ec..b5abfcab7 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -329,6 +329,7 @@ fn get_state_and_storage_leaves( key: Nibbles, state_leaves: &mut Vec, storage_leaves: &mut Vec, + trie_data: &mut Vec, storage_tries_by_state_key: &HashMap, ) -> Result<(), ProgramError> { match trie.deref() { @@ -350,6 +351,7 @@ fn get_state_and_storage_leaves( extended_key, state_leaves, storage_leaves, + trie_data, storage_tries_by_state_key, )?; } @@ -363,6 +365,7 @@ fn get_state_and_storage_leaves( extended_key, state_leaves, storage_leaves, + trie_data, storage_tries_by_state_key, )?; @@ -398,14 +401,19 @@ associated storage trie hash" .map_err(|_| ProgramError::IntegerTooLarge)?, ); // Set `value_ptr_ptr`. - state_leaves.push((state_leaves.len() + 1).into()); + state_leaves.push((trie_data.len()).into()); - state_leaves.push(nonce); - state_leaves.push(balance); + trie_data.push(nonce); + trie_data.push(balance); // The Storage pointer is only written in the trie - state_leaves.push(code_hash.into_uint()); - let storage_ptr = - get_storage_leaves(storage_trie, storage_leaves, &parse_storage_value)?; + trie_data.push(0.into()); + trie_data.push(code_hash.into_uint()); + get_storage_leaves( + storage_trie, + storage_leaves, + trie_data, + &parse_storage_value, + )?; Ok(()) } @@ -416,6 +424,7 @@ associated storage trie hash" pub(crate) fn get_storage_leaves( trie: &HashedPartialTrie, storage_leaves: &mut Vec, + trie_data: &mut Vec, parse_value: &F, ) -> Result<(), ProgramError> where @@ -425,14 +434,14 @@ where Node::Branch { children, value } => { // Now, load all children and update their pointers. for (i, child) in children.iter().enumerate() { - let child_ptr = get_storage_leaves(child, storage_leaves, parse_value)?; + let child_ptr = get_storage_leaves(child, storage_leaves, trie_data, parse_value)?; } Ok(()) } Node::Extension { nibbles, child } => { - get_storage_leaves(child, storage_leaves, parse_value)?; + get_storage_leaves(child, storage_leaves, trie_data, parse_value)?; Ok(()) } @@ -445,10 +454,10 @@ where ); // Set `value_ptr_ptr`. - storage_leaves.push((storage_leaves.len() + 1).into()); + storage_leaves.push((storage_leaves.len()).into()); let leaf = parse_value(value)?; - storage_leaves.extend(leaf); + trie_data.extend(leaf); Ok(()) } @@ -494,7 +503,7 @@ pub(crate) fn load_all_mpts( Ok((trie_root_ptrs, trie_data)) } -pub(crate) fn load_linked_lists_txn_and_receipt_mpt( +pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( trie_inputs: &TrieInputs, ) -> Result<(StateAndStorageLeaves, TxnAndReceiptTries), ProgramError> { let mut state_leaves = vec![U256::zero()]; @@ -524,6 +533,7 @@ pub(crate) fn load_linked_lists_txn_and_receipt_mpt( empty_nibbles(), &mut state_leaves, &mut storage_leaves, + &mut trie_data, &storage_tries_by_state_key, ); diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 74eac16dc..993340cd2 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -36,7 +36,8 @@ pub struct ProverInputFn(Vec); pub const ADRESSSES_ACCESS_LIST_LEN: usize = 2; pub const STORAGE_KEYS_ACCESS_LIST_LEN: usize = 4; -pub const ACCOUNTS_LINKED_LIST_LEN: usize = 4; +pub const ACCOUNTS_LINKED_LIST_NODE_SIZE: usize = 4; +pub const STORAGE_LINKED_LIST_NODE_SIZE: usize = 5; impl From> for ProverInputFn { fn from(v: Vec) -> Self { @@ -274,6 +275,8 @@ impl GenerationState { match input_fn.0[1].as_str() { "insert_account" => self.run_next_insert_account(), "remove_account" => self.run_next_remove_account(), + "insert_slot" => self.run_next_insert_slot(), + "remove_slot" => self.run_next_remove_slot(), _ => Err(ProgramError::ProverInputError(InvalidInput)), } } @@ -344,9 +347,9 @@ impl GenerationState { /// `value <= addr < next_value` and `addr` is the top of the stack. fn run_next_addresses_insert(&mut self) -> Result { let addr = stack_peek(self, 0)?; - if let Some(ptr) = self + if let Some((ptr, _)) = self .get_addresses_access_list()? - .predecessor(|node| node[0] > addr) + .find(|&(_, node)| node[0] > addr) { Ok(((Segment::AccessedAddresses as usize + ptr) / 2usize).into()) } else { @@ -359,12 +362,14 @@ impl GenerationState { /// If the element is not in the list returns loops forever fn run_next_addresses_remove(&mut self) -> Result { let addr = stack_peek(self, 0)?; - for (curr_ptr, [next_addr, _]) in self.get_addresses_access_list()? { - if next_addr == addr { - return Ok(((Segment::AccessedAddresses as usize + curr_ptr) / 2usize).into()); - } + if let Some((ptr, _)) = self + .get_addresses_access_list()? + .find(|(_, node)| node[0] == addr) + { + Ok(((Segment::AccessedAddresses as usize + ptr) / 2usize).into()) + } else { + Ok((Segment::AccessedAddresses as usize).into()) } - Ok((Segment::AccessedAddresses as usize).into()) } /// Returns a pointer to the predecessor of the top of the stack in the @@ -372,13 +377,13 @@ impl GenerationState { fn run_next_storage_insert(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - if let Some(ptr) = self + if let Some((ptr, _)) = self .get_storage_keys_access_list()? - .predecessor(|node| node[0] > addr || (node[0] == addr && node[1] > key)) + .find(|(_, node)| node[0] > addr || (node[0] == addr && node[1] > key)) { Ok(((Segment::AccessedStorageKeys as usize + ptr) / 4usize).into()) } else { - Ok((Segment::AccessedAddresses as usize).into()) + Ok((Segment::AccessedStorageKeys as usize).into()) } } @@ -387,9 +392,9 @@ impl GenerationState { fn run_next_storage_remove(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - if let Some(ptr) = self + if let Some((ptr, _)) = self .get_storage_keys_access_list()? - .predecessor(|node| (node[0] == addr && node[1] == key) || node[0] == U256::MAX) + .find(|(_, node)| (node[0] == addr && node[1] == key) || node[0] == U256::MAX) { Ok(((Segment::AccessedStorageKeys as usize + ptr) / 4usize).into()) } else { @@ -397,32 +402,71 @@ impl GenerationState { } } - /// Returns a pointer to an element in the list whose value is such that - /// `value <= addr < next_value` and `addr` is the top of the stack. + /// Returns a pointer to an node in the list such that + /// `node[0] <= addr < next_node[0]` and `addr` is the top of the stack. fn run_next_insert_account(&mut self) -> Result { let addr = stack_peek(self, 0)?; - if let Some(pred) = self + if let Some((ptr, _)) = self .get_accounts_linked_list()? - .predecessor(|node| node[0] > addr) + .find(|(_, node)| node[0] > addr) { - Ok(((Segment::AccountsLinkedList as usize + pred) / 4usize).into()) + Ok( + ((Segment::AccountsLinkedList as usize + ptr) / ACCOUNTS_LINKED_LIST_NODE_SIZE) + .into(), + ) } else { Ok((Segment::AccountsLinkedList as usize).into()) } } - /// Returns a pointer to an element in the list whose value is such that - /// `value < addr == next_value` and addr is the top of the stack. + /// Returns an unscaled pointer to an element in the list such that + /// `node[0] <= addr < next_node[0]`, or node[0] == addr and `node[1] <= + /// key < next_node[1]`, where `addr` and `key` are the elements at top + /// of the stack. + fn run_next_insert_slot(&mut self) -> Result { + let addr = stack_peek(self, 0)?; + let key = stack_peek(self, 1)?; + log::debug!("Looking for addr = {:?} and key = {:?}", addr, key); + if let Some((ptr, _)) = self.get_storage_linked_list()?.find(|(_, node)| { + log::debug!("searching in node = {:?}", node); + node[0] > addr || (node[0] == addr && node[1] > key) + }) { + log::debug!("found"); + Ok((ptr / STORAGE_LINKED_LIST_NODE_SIZE).into()) + } else { + Ok(0.into()) + } + } + + /// Returns a pointer to an element in the list such that + /// `node[0] < addr == next_node[0]` and addr is the top of the stack. /// If the element is not in the list loops forever fn run_next_remove_account(&mut self) -> Result { let addr = stack_peek(self, 0)?; - if let Some(ptr) = self + if let Some((ptr, _)) = self .get_accounts_linked_list()? - .predecessor(|node| node[0] == addr) + .find(|(_, node)| node[0] == addr) { - Ok(((Segment::AccountsLinkedList as usize + ptr) / 4usize).into()) + Ok((ptr / ACCOUNTS_LINKED_LIST_NODE_SIZE).into()) } else { - Ok((Segment::AccessedAddresses as usize).into()) + Ok(0.into()) + } + } + + /// Returns a pointer to an element in the list such that + /// `node[0] <= addr == next_node[0]` and `node[1] < key == next_node[1] `, + /// and `addr, key` are the elements at the top of the stack. + /// If the element is not in the list loops forever + fn run_next_remove_slot(&mut self) -> Result { + let addr = stack_peek(self, 0)?; + let key = stack_peek(self, 1)?; + if let Some((ptr, _)) = self + .get_storage_linked_list()? + .find(|(_, node)| node[0] == addr && node[1] == key) + { + Ok((ptr / STORAGE_LINKED_LIST_NODE_SIZE).into()) + } else { + Ok(0.into()) } } } @@ -507,23 +551,34 @@ impl GenerationState { .len(); LinkedList::from_mem_and_segment( &mut self.memory.contexts[0].segments[Segment::AccessedAddresses.unscale()].content, - mem_len, Segment::AccessedAddresses, ) } pub(crate) fn get_accounts_linked_list( - &mut self, - ) -> Result, ProgramError> { + &self, + ) -> Result, ProgramError> { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next // available virtual address in the segment. In order to get the length // we need to substract `Segment::AccountsLinkedList` as usize. LinkedList::from_mem_and_segment( - &mut self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content, + &self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content, Segment::AccountsLinkedList, ) } + pub(crate) fn get_storage_linked_list( + &self, + ) -> Result, ProgramError> { + // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next + // available virtual address in the segment. In order to get the length + // we need to substract `Segment::AccountsLinkedList` as usize. + LinkedList::from_mem_and_segment( + &self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()].content, + Segment::StorageLinkedList, + ) + } + fn get_global_metadata(&self, data: GlobalMetadata) -> U256 { self.memory.get_with_init(MemoryAddress::new( 0, diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index bf04fd587..e65895c9b 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -14,6 +14,9 @@ use crate::byte_packing::byte_packing_stark::BytePackingOp; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::stack::MAX_USER_STACK_SIZE; +use crate::generation::mpt::{ + load_linked_lists_and_txn_and_receipt_mpts, StateAndStorageLeaves, TxnAndReceiptTries, +}; use crate::generation::rlp::all_rlp_prover_inputs_reversed; use crate::generation::CpuColumnsView; use crate::generation::GenerationInputs; @@ -321,6 +324,38 @@ impl GenerationState { trie_roots_ptrs } + fn preinitialize_linked_list_and_txn_and_receipt_mpts( + &mut self, + trie_inputs: &TrieInputs, + ) -> TrieRootPtrs { + let ( + StateAndStorageLeaves { + state_leaves, + storage_leaves, + }, + TxnAndReceiptTries { + txn_root_ptr, + receipt_root_ptr, + trie_data, + }, + ) = load_linked_lists_and_txn_and_receipt_mpts(trie_inputs) + .expect("Invalid MPT data for preinitialization"); + + self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content = + state_leaves.iter().map(|&val| Some(val)).collect(); + self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()].content = + storage_leaves.iter().map(|&val| Some(val)).collect(); + self.memory.contexts[0].segments[Segment::TrieData.unscale()].content = + trie_data.iter().map(|&val| Some(val)).collect(); + + TrieRootPtrs { + // TODO: Perhaps is safer to make state_root_ptr an Option + state_root_ptr: 0, + txn_root_ptr, + receipt_root_ptr, + } + } + pub(crate) fn new(inputs: GenerationInputs, kernel_code: &[u8]) -> Result { let rlp_prover_inputs = all_rlp_prover_inputs_reversed(inputs.clone().signed_txn.as_ref().unwrap_or(&vec![])); diff --git a/evm_arithmetization/src/memory/segments.rs b/evm_arithmetization/src/memory/segments.rs index 13ab0fd84..3ab321ff3 100644 --- a/evm_arithmetization/src/memory/segments.rs +++ b/evm_arithmetization/src/memory/segments.rs @@ -75,10 +75,12 @@ pub(crate) enum Segment { BlockHashes = 33 << SEGMENT_SCALING_FACTOR, /// List of accounts in the state trie, AccountsLinkedList = 34 << SEGMENT_SCALING_FACTOR, + /// List of storage slots of all the accounts in state trie, + StorageLinkedList = 35 << SEGMENT_SCALING_FACTOR, } impl Segment { - pub(crate) const COUNT: usize = 35; + pub(crate) const COUNT: usize = 36; /// Unscales this segment by `SEGMENT_SCALING_FACTOR`. pub(crate) const fn unscale(&self) -> usize { @@ -122,6 +124,7 @@ impl Segment { Self::ContextCheckpoints, Self::BlockHashes, Self::AccountsLinkedList, + Self::StorageLinkedList, ] } @@ -163,6 +166,7 @@ impl Segment { Segment::ContextCheckpoints => "SEGMENT_CONTEXT_CHECKPOINTS", Segment::BlockHashes => "SEGMENT_BLOCK_HASHES", Segment::AccountsLinkedList => "SEGMENT_ACCOUNTS_LINKED_LIST", + Segment::StorageLinkedList => "SEGMENT_STORAGE_LINKED_LIST", } } @@ -203,6 +207,7 @@ impl Segment { Segment::ContextCheckpoints => 256, Segment::BlockHashes => 256, Segment::AccountsLinkedList => 256, + Segment::StorageLinkedList => 256, } } } From c9e3b4feb145ce5012fac3a69ac1c6636416d6b0 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 24 May 2024 11:29:02 +0200 Subject: [PATCH 008/118] Add missing file --- .../src/generation/linked_list.rs | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 evm_arithmetization/src/generation/linked_list.rs diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs new file mode 100644 index 000000000..f229fc526 --- /dev/null +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -0,0 +1,112 @@ +use std::collections::HashSet; + +use anyhow::Result; +use env_logger::try_init_from_env; +use env_logger::Env; +use env_logger::DEFAULT_FILTER_ENV; +use ethereum_types::{Address, H160, U256}; +use itertools::Itertools; +use num::traits::ToBytes; +use plonky2::field::goldilocks_field::GoldilocksField as F; +use plonky2_maybe_rayon::rayon::iter; +use rand::{thread_rng, Rng}; + +use crate::cpu::kernel::aggregator::KERNEL; +use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; +use crate::cpu::kernel::interpreter::Interpreter; +use crate::memory::segments::Segment::{self, AccessedAddresses, AccessedStorageKeys}; +use crate::util::u256_to_usize; +use crate::witness::errors::ProgramError; +use crate::witness::errors::ProverInputError; +use crate::witness::errors::ProverInputError::InvalidInput; +use crate::witness::memory::MemoryAddress; + +// A linked list implemented using a vector `access_list_mem`. +// In this representation, the values of nodes are stored in the range +// `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - +// 1]` holds the address of the next node, where i = node_size * j. +pub(crate) struct LinkedList<'a, const N: usize> { + mem: &'a [Option], + mem_len: usize, + offset: usize, + pos: usize, +} + +impl<'a, const N: usize> LinkedList<'a, N> { + pub fn from_mem_and_segment( + mem: &'a [Option], + segment: Segment, + ) -> Result { + Self::from_mem_len_and_segment(mem, mem.len(), segment) + } + + pub fn from_mem_len_and_segment( + mem: &'a [Option], + mem_len: usize, + segment: Segment, + ) -> Result { + if mem.is_empty() { + return Err(ProgramError::ProverInputError(InvalidInput)); + } + let mem_len = mem.len(); + Ok(Self { + mem, + mem_len, + offset: segment as usize, + pos: 0, + }) + } + + /// Returns the index of the smallest node such that its sucessor satisfy + /// `predicate` + pub fn predecessor(self, predicate: F) -> Option + where + F: Fn(&[U256; N]) -> bool, + { + for (prev_ptr, node) in self { + if predicate(&node) { + return Some(prev_ptr); + } + } + None + } + + // fn insert(&mut self, new_node: &[Option; N]) -> Result<(), + // ProgramError> { if let Some((ptr, node)) = + // self.find(|(prev_ptr, other_node)| other_node[0] > + // new_node[0].unwrap_or_default()) { + // let scaled_new_ptr = self.offset + self.mem.len(); + // // TODO: We don't want to use the next pointer in new_node. Ideally, + // we would // like to define new_node as &[Option; N - 1]. + // However that // would require const_generic_expr. + // self.mem[self.mem_len..self.mem_len + N - + // 1].clone_from_slice(&new_node[0..N - 1]); let prev_node = &mut + // self.mem[ptr..ptr + N]; let scaled_prev_next_ptr = prev_node[N - + // 1]; prev_node[N - 1] = Some(scaled_new_ptr.into()); + // self.mem[self.mem_len + N - 1] = scaled_prev_next_ptr; + // Ok(()) + // } else { + // // TODO: Is this the right error? + // Err(ProgramError::ProverInputError( + // ProverInputError::InvalidInput, + // )) + // } + // } +} + +impl<'a, const N: usize> Iterator for LinkedList<'a, N> { + type Item = (usize, [U256; N]); + + fn next(&mut self) -> Option { + if let Ok(new_pos) = u256_to_usize(self.mem[self.pos + N - 1].unwrap_or_default()) { + let old_pos = self.pos; + self.pos = new_pos - self.offset; + Some(( + old_pos, + std::array::from_fn(|i| self.mem[self.pos + i].unwrap_or_default()), + )) + } else { + None + } + } +} From ba87c79324ac68b427e916e5b8fcd29fb25b9e9e Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 24 May 2024 18:50:14 +0200 Subject: [PATCH 009/118] [WIP] checking consistency between linked list and state trie --- .../src/cpu/kernel/asm/account_code.asm | 21 +++++ .../src/cpu/kernel/asm/main.asm | 2 +- .../src/cpu/kernel/asm/mpt/linked_list.asm | 21 ++--- .../src/generation/linked_list.rs | 57 +++++------ evm_arithmetization/src/generation/mod.rs | 26 +++++ evm_arithmetization/src/generation/mpt.rs | 94 +++++++++++-------- .../src/generation/prover_input.rs | 18 +++- evm_arithmetization/src/generation/state.rs | 44 ++++----- 8 files changed, 174 insertions(+), 109 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/account_code.asm b/evm_arithmetization/src/cpu/kernel/asm/account_code.asm index 2654bedc7..bb1ccfef5 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/account_code.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/account_code.asm @@ -24,7 +24,28 @@ extcodehash_dead: global extcodehash: // stack: address, retdest + + //TEST linked list + DUP1 + %read_accounts_linked_list + // stack: ll_addr, address, retdest +global debug_ll_addr: + %add_const(3) + %mload_trie_data + // stack: ll_code_hash, address, retdest + SWAP1 %mpt_read_state_trie + DUP1 + %add_const(3) + %mload_trie_data + // stack: code_hash, account_ptr, ll_code_hash, retdest + SWAP1 SWAP2 + // stack: ll_code_hash, code_hash, account_ptr, retdest +global debug_before_eq_code_hash: + %assert_eq + // END TEST linked list + + // stack: account_ptr, retdest DUP1 ISZERO %jumpi(retzero) %add_const(3) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index bcb49ecce..79c88f4ee 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -37,7 +37,7 @@ global hash_initial_tries: // We initialize the segment length with 1 because the segment contains // the null pointer `0` when the tries are empty. PUSH 1 - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) %assert_eq + %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_len %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_len diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index b70899e88..1df6c7a1f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -98,7 +98,9 @@ global insert_account: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr, payload_ptr, retdest +global debug_got_ptr: %get_valid_account_ptr +global debug_valid_ptr: // stack: pred_ptr, addr, payload_ptr, retdest DUP1 MLOAD_GENERAL @@ -348,7 +350,6 @@ slot_found: %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP -global debug_insert_new_slot: insert_new_slot: // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest POP @@ -358,7 +359,6 @@ insert_new_slot: %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 MLOAD_GENERAL -global debug_next_ptr: // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest // Check that this is not a deleted node DUP1 @@ -366,20 +366,17 @@ global debug_next_ptr: %assert_zero DUP1 MLOAD_GENERAL -global debug_next_addr: // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 DUP6 // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. -global debug_before_lt: LT %jumpi(next_node_ok) // If addr <= next_addr, then it addr must be equal to next_addr // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP5 %assert_eq -global debug_after_assert_eq: // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 %increment @@ -388,7 +385,6 @@ global debug_after_assert_eq: DUP6 // The next key must be strictly larger %assert_lt -global debug_next_node_ok: next_node_ok: // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest POP @@ -444,9 +440,7 @@ global remove_slot: // stack: addr, key, retdest PROVER_INPUT(linked_list::remove_slot) // stack: pred_ptr/5, addr, key, retdest -global debug_before_valid_storage_ptr: %get_valid_slot_ptr -global debug_after_valid_storage_ptr: // stack: pred_ptr, addr, key, retdest %add_const(4) // stack: next_ptr_ptr, addr, key, retdest @@ -457,7 +451,6 @@ global debug_after_valid_storage_ptr: MLOAD_GENERAL // stack: next_addr, next_ptr, next_ptr_ptr, addr, key, retdest DUP4 -global debug_before_assert_eq: %assert_eq // stack: next_ptr, next_ptr_ptr, addr, key, retdest DUP1 @@ -465,7 +458,6 @@ global debug_before_assert_eq: MLOAD_GENERAL // stack: next_key, next_ptr, next_ptr_ptr, addr, key, retdest DUP5 -global debug_before_assert_eq_2: %assert_eq // stack: next_ptr, next_ptr_ptr, addr, key, retdest %add_const(4) @@ -482,4 +474,11 @@ global debug_before_assert_eq_2: %pop2 JUMP - \ No newline at end of file +%macro read_accounts_linked_list + %stack (addr) -> (addr, 0, %%after) + %addr_to_state_key + %jump(insert_account) +%%after: + // stack: cold_access, account_ptr + POP +%endmacro \ No newline at end of file diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index f229fc526..b835ff3e0 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -1,4 +1,5 @@ use std::collections::HashSet; +use std::fmt; use anyhow::Result; use env_logger::try_init_from_env; @@ -25,6 +26,7 @@ use crate::witness::memory::MemoryAddress; // In this representation, the values of nodes are stored in the range // `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - // 1]` holds the address of the next node, where i = node_size * j. +#[derive(Clone)] pub(crate) struct LinkedList<'a, const N: usize> { mem: &'a [Option], mem_len: usize, @@ -32,6 +34,18 @@ pub(crate) struct LinkedList<'a, const N: usize> { pos: usize, } +pub(crate) fn empty_list_mem(segment: Segment) -> [U256; N] { + std::array::from_fn(|i| { + if i == 0 { + U256::MAX + } else if i == N - 1 { + (segment as usize).into() + } else { + U256::zero() + } + }) +} + impl<'a, const N: usize> LinkedList<'a, N> { pub fn from_mem_and_segment( mem: &'a [Option], @@ -56,42 +70,21 @@ impl<'a, const N: usize> LinkedList<'a, N> { pos: 0, }) } +} - /// Returns the index of the smallest node such that its sucessor satisfy - /// `predicate` - pub fn predecessor(self, predicate: F) -> Option - where - F: Fn(&[U256; N]) -> bool, - { - for (prev_ptr, node) in self { - if predicate(&node) { - return Some(prev_ptr); +impl<'a, const N: usize> fmt::Debug for LinkedList<'a, N> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + writeln!(f, "Linked List {{"); + let cloned_list = self.clone(); + for (_, node) in cloned_list { + if node[0] == U256::MAX { + writeln!(f, "{:?}", node); + break; } + writeln!(f, "{:?} ->", node); } - None + write!(f, "}}") } - - // fn insert(&mut self, new_node: &[Option; N]) -> Result<(), - // ProgramError> { if let Some((ptr, node)) = - // self.find(|(prev_ptr, other_node)| other_node[0] > - // new_node[0].unwrap_or_default()) { - // let scaled_new_ptr = self.offset + self.mem.len(); - // // TODO: We don't want to use the next pointer in new_node. Ideally, - // we would // like to define new_node as &[Option; N - 1]. - // However that // would require const_generic_expr. - // self.mem[self.mem_len..self.mem_len + N - - // 1].clone_from_slice(&new_node[0..N - 1]); let prev_node = &mut - // self.mem[ptr..ptr + N]; let scaled_prev_next_ptr = prev_node[N - - // 1]; prev_node[N - 1] = Some(scaled_new_ptr.into()); - // self.mem[self.mem_len + N - 1] = scaled_prev_next_ptr; - // Ok(()) - // } else { - // // TODO: Is this the right error? - // Err(ProgramError::ProverInputError( - // ProverInputError::InvalidInput, - // )) - // } - // } } impl<'a, const N: usize> Iterator for LinkedList<'a, N> { diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 58d8adad9..c2d36d14b 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -162,6 +162,22 @@ fn apply_metadata_and_tries_memops, const D: usize> ), (GlobalMetadata::KernelHash, h2u(KERNEL.code_hash)), (GlobalMetadata::KernelLen, KERNEL.code.len().into()), + ( + GlobalMetadata::AccountsLinkedListLen, + (Segment::AccountsLinkedList as usize + + state.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] + .content + .len()) + .into(), + ), + ( + GlobalMetadata::StorageLinkedListLen, + (Segment::StorageLinkedList as usize + + state.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] + .content + .len()) + .into(), + ), ]; let channel = MemoryChannel::GeneralPurpose(0); @@ -226,10 +242,20 @@ pub fn generate_traces, const D: usize>( debug_inputs(&inputs); let mut state = GenerationState::::new(inputs.clone(), &KERNEL.code) .map_err(|err| anyhow!("Failed to parse all the initial prover inputs: {:?}", err))?; + log::debug!( + "trie data[..59] = {:?}", + state.memory.contexts[0].segments[Segment::TrieData.unscale()].content[..59].to_vec() + ); apply_metadata_and_tries_memops(&mut state, &inputs); + log::debug!( + "trie data[..59] = {:?}", + state.memory.contexts[0].segments[Segment::TrieData.unscale()].content[..59].to_vec() + ); + let cpu_res = timed!(timing, "simulate CPU", simulate_cpu(&mut state)); + if cpu_res.is_err() { let _ = output_debug_tries(&state); diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index b5abfcab7..563c67a03 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -9,8 +9,11 @@ use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; use rlp::{Decodable, DecoderError, Encodable, PayloadInfo, Rlp, RlpStream}; use rlp_derive::{RlpDecodable, RlpEncodable}; +use super::linked_list::empty_list_mem; +use super::prover_input::{ACCOUNTS_LINKED_LIST_NODE_SIZE, STORAGE_LINKED_LIST_NODE_SIZE}; use crate::cpu::kernel::constants::trie_type::PartialTrieType; use crate::generation::TrieInputs; +use crate::memory::segments::Segment; use crate::util::h2u; use crate::witness::errors::{ProgramError, ProverInputError}; use crate::Node; @@ -25,22 +28,11 @@ pub struct AccountRlp { #[derive(Clone, Debug)] pub struct TrieRootPtrs { - pub state_root_ptr: usize, + pub state_root_ptr: Option, pub txn_root_ptr: usize, pub receipt_root_ptr: usize, } -pub struct StateAndStorageLeaves { - pub state_leaves: Vec, - pub storage_leaves: Vec, -} - -pub struct TxnAndReceiptTries { - pub txn_root_ptr: usize, - pub receipt_root_ptr: usize, - pub trie_data: Vec, -} - impl Default for AccountRlp { fn default() -> Self { Self { @@ -319,11 +311,6 @@ fn load_state_trie( } } -// pub enum NodePtr { -// Inner(usize), -// Leaf(usize), -// } - fn get_state_and_storage_leaves( trie: &HashedPartialTrie, key: Nibbles, @@ -394,21 +381,35 @@ fn get_state_and_storage_leaves( associated storage trie hash" ); - state_leaves.push(nibbles.count.into()); - state_leaves.push( - nibbles - .try_into() - .map_err(|_| ProgramError::IntegerTooLarge)?, - ); + // The last leaf must point to the new one + let len = state_leaves.len(); + state_leaves[len - 1] = + U256::from(Segment::AccountsLinkedList as usize + state_leaves.len()); + // The nibbles are the address? + let address = nibbles + .try_into() + .map_err(|_| ProgramError::IntegerTooLarge)?; + state_leaves.push(address); // Set `value_ptr_ptr`. state_leaves.push((trie_data.len()).into()); + // Set counter + state_leaves.push(0.into()); + // Set the next node as the inital node + state_leaves.push((Segment::AccountsLinkedList as usize).into()); + // Push the payload in the trie data trie_data.push(nonce); trie_data.push(balance); // The Storage pointer is only written in the trie trie_data.push(0.into()); + log::debug!( + "code_hash = {:?} written at position = {:?}", + code_hash.into_uint(), + trie_data.len() + ); trie_data.push(code_hash.into_uint()); get_storage_leaves( + address, storage_trie, storage_leaves, trie_data, @@ -422,6 +423,7 @@ associated storage trie hash" } pub(crate) fn get_storage_leaves( + address: U256, trie: &HashedPartialTrie, storage_leaves: &mut Vec, trie_data: &mut Vec, @@ -434,27 +436,37 @@ where Node::Branch { children, value } => { // Now, load all children and update their pointers. for (i, child) in children.iter().enumerate() { - let child_ptr = get_storage_leaves(child, storage_leaves, trie_data, parse_value)?; + let child_ptr = + get_storage_leaves(address, child, storage_leaves, trie_data, parse_value)?; } Ok(()) } Node::Extension { nibbles, child } => { - get_storage_leaves(child, storage_leaves, trie_data, parse_value)?; + get_storage_leaves(address, child, storage_leaves, trie_data, parse_value)?; Ok(()) } Node::Leaf { nibbles, value } => { - storage_leaves.push(nibbles.count.into()); + // The last leaf must point to the new one + let len = storage_leaves.len(); + storage_leaves[len - 1] = + U256::from(Segment::StorageLinkedList as usize + storage_leaves.len()); + // Write the address + storage_leaves.push(address); + // Write the key storage_leaves.push( nibbles .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?, ); - - // Set `value_ptr_ptr`. - storage_leaves.push((storage_leaves.len()).into()); + // Write `value_ptr_ptr`. + storage_leaves.push((trie_data.len()).into()); + // Write the counter + storage_leaves.push(0.into()); + // Set the next node as the inital node + storage_leaves.push((Segment::StorageLinkedList as usize).into()); let leaf = parse_value(value)?; trie_data.extend(leaf); @@ -495,7 +507,7 @@ pub(crate) fn load_all_mpts( let receipt_root_ptr = load_mpt(&trie_inputs.receipts_trie, &mut trie_data, &parse_receipts)?; let trie_root_ptrs = TrieRootPtrs { - state_root_ptr, + state_root_ptr: Some(state_root_ptr), txn_root_ptr, receipt_root_ptr, }; @@ -505,9 +517,11 @@ pub(crate) fn load_all_mpts( pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( trie_inputs: &TrieInputs, -) -> Result<(StateAndStorageLeaves, TxnAndReceiptTries), ProgramError> { - let mut state_leaves = vec![U256::zero()]; - let mut storage_leaves = vec![U256::zero()]; +) -> Result<(TrieRootPtrs, Vec, Vec, Vec), ProgramError> { + let mut state_leaves = + empty_list_mem::(Segment::AccountsLinkedList).to_vec(); + let mut storage_leaves = + empty_list_mem::(Segment::StorageLinkedList).to_vec(); let mut trie_data = vec![U256::zero()]; let storage_tries_by_state_key = trie_inputs @@ -520,6 +534,9 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( }) .collect(); + // TODO: Remove after checking correctness of linked lists + let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; + let txn_root_ptr = load_mpt(&trie_inputs.transactions_trie, &mut trie_data, &|rlp| { let mut parsed_txn = vec![U256::from(rlp.len())]; parsed_txn.extend(rlp.iter().copied().map(U256::from)); @@ -538,15 +555,14 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( ); Ok(( - StateAndStorageLeaves { - state_leaves, - storage_leaves, - }, - TxnAndReceiptTries { + TrieRootPtrs { + state_root_ptr: Some(state_root_ptr), txn_root_ptr, receipt_root_ptr, - trie_data, }, + state_leaves, + storage_leaves, + trie_data, )) } diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 993340cd2..ad6d3aa41 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -73,7 +73,11 @@ impl GenerationState { fn run_trie_ptr(&mut self, input_fn: &ProverInputFn) -> Result { let trie = input_fn.0[1].as_str(); match trie { - "state" => Ok(U256::from(self.trie_root_ptrs.state_root_ptr)), + "state" => self + .trie_root_ptrs + .state_root_ptr + .ok_or(ProgramError::ProverInputError(InvalidInput)) + .map(U256::from), "txn" => Ok(U256::from(self.trie_root_ptrs.txn_root_ptr)), "receipt" => Ok(U256::from(self.trie_root_ptrs.receipt_root_ptr)), _ => Err(ProgramError::ProverInputError(InvalidInput)), @@ -406,10 +410,22 @@ impl GenerationState { /// `node[0] <= addr < next_node[0]` and `addr` is the top of the stack. fn run_next_insert_account(&mut self) -> Result { let addr = stack_peek(self, 0)?; + log::debug!( + "accounts linked list = {:?}", + self.get_accounts_linked_list() + ); + log::debug!( + "trie data[58] = {:?}", + self.memory.contexts[0].segments[Segment::TrieData.unscale()].content[55..60].to_vec(), + ); if let Some((ptr, _)) = self .get_accounts_linked_list()? .find(|(_, node)| node[0] > addr) { + log::debug!( + "found ptr = {:?}", + Segment::AccountsLinkedList as usize + ptr + ); Ok( ((Segment::AccountsLinkedList as usize + ptr) / ACCOUNTS_LINKED_LIST_NODE_SIZE) .into(), diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index e65895c9b..ec724a7e3 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -14,9 +14,7 @@ use crate::byte_packing::byte_packing_stark::BytePackingOp; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::stack::MAX_USER_STACK_SIZE; -use crate::generation::mpt::{ - load_linked_lists_and_txn_and_receipt_mpts, StateAndStorageLeaves, TxnAndReceiptTries, -}; +use crate::generation::mpt::load_linked_lists_and_txn_and_receipt_mpts; use crate::generation::rlp::all_rlp_prover_inputs_reversed; use crate::generation::CpuColumnsView; use crate::generation::GenerationInputs; @@ -152,6 +150,15 @@ pub(crate) trait State { let halt_offsets = self.get_halt_offsets(); loop { + // TODO: remove! + + log::debug!( + "chupalla = {:?}", + self.get_generation_state().memory.contexts[0].segments + [Segment::TrieData.unscale()] + .content[58] + ); + let registers = self.get_registers(); let pc = registers.program_counter; @@ -324,22 +331,13 @@ impl GenerationState { trie_roots_ptrs } - fn preinitialize_linked_list_and_txn_and_receipt_mpts( + fn preinitialize_linked_lists_and_txn_and_receipt_mpts( &mut self, trie_inputs: &TrieInputs, ) -> TrieRootPtrs { - let ( - StateAndStorageLeaves { - state_leaves, - storage_leaves, - }, - TxnAndReceiptTries { - txn_root_ptr, - receipt_root_ptr, - trie_data, - }, - ) = load_linked_lists_and_txn_and_receipt_mpts(trie_inputs) - .expect("Invalid MPT data for preinitialization"); + let (trie_roots_ptrs, state_leaves, storage_leaves, trie_data) = + load_linked_lists_and_txn_and_receipt_mpts(trie_inputs) + .expect("Invalid MPT data for preinitialization"); self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content = state_leaves.iter().map(|&val| Some(val)).collect(); @@ -348,12 +346,7 @@ impl GenerationState { self.memory.contexts[0].segments[Segment::TrieData.unscale()].content = trie_data.iter().map(|&val| Some(val)).collect(); - TrieRootPtrs { - // TODO: Perhaps is safer to make state_root_ptr an Option - state_root_ptr: 0, - txn_root_ptr, - receipt_root_ptr, - } + trie_roots_ptrs } pub(crate) fn new(inputs: GenerationInputs, kernel_code: &[u8]) -> Result { @@ -372,13 +365,14 @@ impl GenerationState { state_key_to_address: HashMap::new(), bignum_modmul_result_limbs, trie_root_ptrs: TrieRootPtrs { - state_root_ptr: 0, + state_root_ptr: Some(0), txn_root_ptr: 0, receipt_root_ptr: 0, }, jumpdest_table: None, }; - let trie_root_ptrs = state.preinitialize_mpts(&inputs.tries); + let trie_root_ptrs = + state.preinitialize_linked_lists_and_txn_and_receipt_mpts(&inputs.tries); state.trie_root_ptrs = trie_root_ptrs; Ok(state) @@ -459,7 +453,7 @@ impl GenerationState { bignum_modmul_result_limbs: self.bignum_modmul_result_limbs.clone(), withdrawal_prover_inputs: self.withdrawal_prover_inputs.clone(), trie_root_ptrs: TrieRootPtrs { - state_root_ptr: 0, + state_root_ptr: Some(0), txn_root_ptr: 0, receipt_root_ptr: 0, }, From 6fc8c22865874abfac0ac86a2a16098a1789a0ac Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Mon, 27 May 2024 16:48:06 +0200 Subject: [PATCH 010/118] [WIP] addr 0x798c6047767c10f653ca157a7f66a592a1d6ca550cae352912be0b0745336afd not found in linked list --- .../src/cpu/kernel/asm/account_code.asm | 1 + .../src/cpu/kernel/asm/core/process_txn.asm | 3 +++ .../src/cpu/kernel/asm/core/transfer.asm | 1 + .../src/cpu/kernel/asm/main.asm | 9 +++++---- .../src/cpu/kernel/asm/mpt/read.asm | 1 + .../cpu/kernel/asm/transactions/router.asm | 1 + evm_arithmetization/src/generation/mod.rs | 9 ++++++++- evm_arithmetization/src/generation/mpt.rs | 5 +++++ evm_arithmetization/src/generation/state.rs | 19 +++++++++++++------ 9 files changed, 38 insertions(+), 11 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/account_code.asm b/evm_arithmetization/src/cpu/kernel/asm/account_code.asm index bb1ccfef5..23a87176c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/account_code.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/account_code.asm @@ -33,6 +33,7 @@ global debug_ll_addr: %add_const(3) %mload_trie_data // stack: ll_code_hash, address, retdest +global debug_addr_from_ll: SWAP1 %mpt_read_state_trie DUP1 diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm index 860edf592..ff21a0865 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm @@ -71,6 +71,7 @@ global buy_gas: // stack: gas_cost, retdest %mload_txn_field(@TXN_FIELD_ORIGIN) // stack: sender_addr, gas_cost, retdest +global debug_sera_aca: %deduct_eth // stack: deduct_eth_status, retdest %jumpi(panic) @@ -103,6 +104,7 @@ global warm_coinbase: global process_based_on_type: %is_contract_creation +global debug_is_contract_creation: %jumpi(process_contract_creation_txn) %jump(process_message_txn) @@ -225,6 +227,7 @@ global process_message_txn: // stack: retdest %mload_txn_field(@TXN_FIELD_VALUE) %mload_txn_field(@TXN_FIELD_TO) +global debug_es_esta_la_addr_maldita: DUP1 %insert_accessed_addresses_no_return %mload_txn_field(@TXN_FIELD_ORIGIN) // stack: from, to, amount, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm index 0517cf3a8..9a3ec0643 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm @@ -5,6 +5,7 @@ global transfer_eth: // stack: from, to, amount, retdest %stack (from, to, amount, retdest) -> (from, amount, to, amount, retdest) +global debug_o_sera_aca: %deduct_eth // stack: deduct_eth_status, to, amount, retdest %jumpi(transfer_eth_failure) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 79c88f4ee..ff60a6777 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -34,16 +34,17 @@ global main: global hash_initial_tries: // We compute the length of the trie data segment in `mpt_hash` so that we // can check the value provided by the prover. - // We initialize the segment length with 1 because the segment contains - // the null pointer `0` when the tries are empty. - PUSH 1 - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) %assert_eq + // The trie data segment is already written by the linked lists + %mload_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) + %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_len %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_len %mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_full_len +global debug_before_the_55: %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) +global debug_after_the_55: global start_txn: // stack: (empty) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 4a57dd4db..74ac30a16 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -5,6 +5,7 @@ global mpt_read_state_trie: // stack: addr, retdest %addr_to_state_key // stack: key, retdest +global debug_mpt_read_state_trie_state_key: PUSH 64 // num_nibbles %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // node_ptr // stack: node_ptr, num_nibbles, key, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm index 10506d328..d277075a5 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm @@ -40,6 +40,7 @@ global update_txn_trie: // stack: txn_rlp_len, txn_counter, num_nibbles, retdest // Copy the transaction rlp to the trie data segment. %get_trie_data_size +global debug_get_trie_data_size: // stack: value_ptr, txn_rlp_len, txn_counter, num_nibbles, retdest SWAP1 // First we write txn rlp length diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index c2d36d14b..86e92d4e6 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -178,6 +178,13 @@ fn apply_metadata_and_tries_memops, const D: usize> .len()) .into(), ), + ( + GlobalMetadata::TrieDataSize, + state.memory.contexts[0].segments[Segment::TrieData.unscale()] + .content + .len() + .into(), + ), ]; let channel = MemoryChannel::GeneralPurpose(0); @@ -223,7 +230,7 @@ fn apply_metadata_and_tries_memops, const D: usize> pub(crate) fn debug_inputs(inputs: &GenerationInputs) { log::debug!("Input signed_txn: {:?}", &inputs.signed_txn); - log::debug!("Input state_trie: {:?}", &inputs.tries.state_trie); + log::debug!("Input state_trie: {:#?}", &inputs.tries.state_trie); log::debug!( "Input transactions_trie: {:?}", &inputs.tries.transactions_trie diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index 563c67a03..cf1e27bde 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -537,6 +537,11 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( // TODO: Remove after checking correctness of linked lists let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; + log::debug!( + "trie_data size after loading state_mpt = {:?}", + trie_data.len() + ); + let txn_root_ptr = load_mpt(&trie_inputs.transactions_trie, &mut trie_data, &|rlp| { let mut parsed_txn = vec![U256::from(rlp.len())]; parsed_txn.extend(rlp.iter().copied().map(U256::from)); diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index ec724a7e3..eef2f4cea 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -13,6 +13,7 @@ use super::TrieInputs; use crate::byte_packing::byte_packing_stark::BytePackingOp; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; +use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::stack::MAX_USER_STACK_SIZE; use crate::generation::mpt::load_linked_lists_and_txn_and_receipt_mpts; use crate::generation::rlp::all_rlp_prover_inputs_reversed; @@ -152,12 +153,18 @@ pub(crate) trait State { loop { // TODO: remove! - log::debug!( - "chupalla = {:?}", - self.get_generation_state().memory.contexts[0].segments - [Segment::TrieData.unscale()] - .content[58] - ); + // log::debug!( + // "content[1] = {:?}, content[58] = {:?} \n trie_data_size = {:?}", + // self.get_generation_state().memory.contexts[0].segments + // [Segment::TrieData.unscale()] + // .content[1], + // self.get_generation_state().memory.contexts[0].segments + // [Segment::TrieData.unscale()] + // .content[58], + // self.get_generation_state().memory.contexts[0].segments + // [Segment::GlobalMetadata.unscale()] + // .get(GlobalMetadata::TrieDataSize.unscale()) + // ); let registers = self.get_registers(); let pc = registers.program_counter; From 31a850fd6541fabaa1226793ee42e21ff97948f5 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Mon, 27 May 2024 18:49:44 +0200 Subject: [PATCH 011/118] [WIP] add missing nibbles to key --- .../src/cpu/kernel/asm/core/transfer.asm | 1 + .../src/cpu/kernel/tests/account_code.rs | 2 +- evm_arithmetization/src/generation/mpt.rs | 2 +- evm_arithmetization/src/generation/state.rs | 14 ++++++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm index 9a3ec0643..a80c5fbf1 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm @@ -67,6 +67,7 @@ global add_eth: // stack: addr, amount, retdest DUP1 %insert_touched_addresses DUP1 %mpt_read_state_trie +global debug_leyendo_account: // stack: account_ptr, addr, amount, retdest DUP1 ISZERO %jumpi(add_eth_new_account) // If the account pointer is null, we need to create the account. %add_const(1) diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index 5ad2d8485..150b6ad0a 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -40,7 +40,7 @@ pub(crate) fn initialize_mpts( MemoryAddress::new_bundle((GlobalMetadata::TrieDataSize as usize).into()).unwrap(); let to_set = [ - (state_addr, trie_root_ptrs.state_root_ptr.into()), + (state_addr, trie_root_ptrs.state_root_ptr.unwrap().into()), (txn_addr, trie_root_ptrs.txn_root_ptr.into()), (receipts_addr, trie_root_ptrs.receipt_root_ptr.into()), (len_addr, trie_data.len().into()), diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index cf1e27bde..c2ed9266b 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -386,7 +386,7 @@ associated storage trie hash" state_leaves[len - 1] = U256::from(Segment::AccountsLinkedList as usize + state_leaves.len()); // The nibbles are the address? - let address = nibbles + let address = merged_key .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?; state_leaves.push(address); diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index eef2f4cea..e350ed6b8 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -6,6 +6,7 @@ use ethereum_types::{Address, BigEndianHash, H160, H256, U256}; use itertools::Itertools; use keccak_hash::keccak; use log::Level; +use mpt_trie::partial_trie::HashedPartialTrie; use plonky2::field::types::Field; use super::mpt::{load_all_mpts, TrieRootPtrs}; @@ -17,6 +18,7 @@ use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::stack::MAX_USER_STACK_SIZE; use crate::generation::mpt::load_linked_lists_and_txn_and_receipt_mpts; use crate::generation::rlp::all_rlp_prover_inputs_reversed; +use crate::generation::trie_extractor::get_state_trie; use crate::generation::CpuColumnsView; use crate::generation::GenerationInputs; use crate::keccak_sponge::columns::KECCAK_WIDTH_BYTES; @@ -153,6 +155,18 @@ pub(crate) trait State { loop { // TODO: remove! + // log::debug!( + // "state_trie = {:?}", + // get_state_trie::( + // &self.get_generation_state().memory, + // self.get_generation_state().memory.contexts[0].segments + // [Segment::GlobalMetadata.unscale()] + // .get(GlobalMetadata::StateTrieRoot.unscale()) + // .try_into() + // .unwrap() + // ) + // ); + // log::debug!( // "content[1] = {:?}, content[58] = {:?} \n trie_data_size = {:?}", // self.get_generation_state().memory.contexts[0].segments From d1df4c514abfbece1abd1b9e774d66969fa48ef6 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Tue, 28 May 2024 12:23:52 +0200 Subject: [PATCH 012/118] Fix accounts insertions --- .../src/cpu/kernel/asm/account_code.asm | 22 ------- .../src/cpu/kernel/asm/core/process_txn.asm | 3 - .../src/cpu/kernel/asm/core/transfer.asm | 3 +- .../src/cpu/kernel/asm/main.asm | 3 +- .../asm/mpt/insert/insert_trie_specific.asm | 4 ++ .../src/cpu/kernel/asm/mpt/linked_list.asm | 62 +++++++++++++++++-- .../src/cpu/kernel/asm/mpt/read.asm | 45 ++++++++++++-- .../cpu/kernel/asm/transactions/router.asm | 1 - evm_arithmetization/src/generation/mod.rs | 11 +--- evm_arithmetization/src/generation/mpt.rs | 52 ++++++++++++---- .../src/generation/prover_input.rs | 37 ++++++----- evm_arithmetization/src/generation/state.rs | 27 -------- 12 files changed, 167 insertions(+), 103 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/account_code.asm b/evm_arithmetization/src/cpu/kernel/asm/account_code.asm index 23a87176c..2654bedc7 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/account_code.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/account_code.asm @@ -24,29 +24,7 @@ extcodehash_dead: global extcodehash: // stack: address, retdest - - //TEST linked list - DUP1 - %read_accounts_linked_list - // stack: ll_addr, address, retdest -global debug_ll_addr: - %add_const(3) - %mload_trie_data - // stack: ll_code_hash, address, retdest -global debug_addr_from_ll: - SWAP1 %mpt_read_state_trie - DUP1 - %add_const(3) - %mload_trie_data - // stack: code_hash, account_ptr, ll_code_hash, retdest - SWAP1 SWAP2 - // stack: ll_code_hash, code_hash, account_ptr, retdest -global debug_before_eq_code_hash: - %assert_eq - // END TEST linked list - - // stack: account_ptr, retdest DUP1 ISZERO %jumpi(retzero) %add_const(3) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm index ff21a0865..860edf592 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm @@ -71,7 +71,6 @@ global buy_gas: // stack: gas_cost, retdest %mload_txn_field(@TXN_FIELD_ORIGIN) // stack: sender_addr, gas_cost, retdest -global debug_sera_aca: %deduct_eth // stack: deduct_eth_status, retdest %jumpi(panic) @@ -104,7 +103,6 @@ global warm_coinbase: global process_based_on_type: %is_contract_creation -global debug_is_contract_creation: %jumpi(process_contract_creation_txn) %jump(process_message_txn) @@ -227,7 +225,6 @@ global process_message_txn: // stack: retdest %mload_txn_field(@TXN_FIELD_VALUE) %mload_txn_field(@TXN_FIELD_TO) -global debug_es_esta_la_addr_maldita: DUP1 %insert_accessed_addresses_no_return %mload_txn_field(@TXN_FIELD_ORIGIN) // stack: from, to, amount, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm index a80c5fbf1..0d0b7b754 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm @@ -5,7 +5,6 @@ global transfer_eth: // stack: from, to, amount, retdest %stack (from, to, amount, retdest) -> (from, amount, to, amount, retdest) -global debug_o_sera_aca: %deduct_eth // stack: deduct_eth_status, to, amount, retdest %jumpi(transfer_eth_failure) @@ -67,7 +66,7 @@ global add_eth: // stack: addr, amount, retdest DUP1 %insert_touched_addresses DUP1 %mpt_read_state_trie -global debug_leyendo_account: +global debug_is_not_arriving_here: // stack: account_ptr, addr, amount, retdest DUP1 ISZERO %jumpi(add_eth_new_account) // If the account pointer is null, we need to create the account. %add_const(1) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index ff60a6777..1449834a0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -42,9 +42,8 @@ global hash_initial_tries: // stack: trie_data_len %mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_full_len -global debug_before_the_55: + %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) -global debug_after_the_55: global start_txn: // stack: (empty) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm index 71f78ec5b..5508d6dc2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm @@ -6,6 +6,10 @@ // TODO: Have this take an address and do %mpt_insert_state_trie? To match mpt_read_state_trie. global mpt_insert_state_trie: // stack: key, value_ptr, retdest + DUP2 DUP2 +global debug_before_insert_account_no_return: + %insert_account_no_return +global debug_account_inserted: %stack (key, value_ptr) -> (key, value_ptr, mpt_insert_state_trie_save) PUSH 64 // num_nibbles diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 1df6c7a1f..df8b6f6a5 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -72,7 +72,7 @@ global init_linked_lists: %macro insert_account_no_return %insert_account - POP + %pop2 %endmacro // Multiply the value at the top of the stack, denoted by ptr/4, by 4 @@ -98,9 +98,7 @@ global insert_account: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr, payload_ptr, retdest -global debug_got_ptr: %get_valid_account_ptr -global debug_valid_ptr: // stack: pred_ptr, addr, payload_ptr, retdest DUP1 MLOAD_GENERAL @@ -208,6 +206,62 @@ insert_new_account: SWAP2 JUMP +%macro search_account + %stack (addr, ptr) -> (addr, ptr, %%after) + %jump(search_account) +%%after: + // stack: cold_access +%endmacro + +%macro search_account_no_return + %search_account + %pop2 +%endmacro + + +/// Search the account addr and payload pointer into the linked list. +/// Return `1, payload_ptr` if the account was inserted, `1, original_ptr` if it was already present +/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +global search_account: + // stack: addr, payload_ptr, retdest + PROVER_INPUT(linked_list::insert_account) + // stack: pred_ptr/4, addr, payload_ptr, retdest + %get_valid_account_ptr + // stack: pred_ptr, addr, payload_ptr, retdest + DUP1 + MLOAD_GENERAL + DUP1 + // stack: pred_addr, pred_addr, pred_ptr, addr, payload_ptr, retdest + DUP4 GT + DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) + ADD // OR + // If the predesessor is strictly smaller or the predecessor is the special + // node with key @U256_MAX (and hence we're inserting a new minimum), then + // we need to insert a new node. + %jumpi(account_not_found) + // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. + DUP3 + %assert_eq + // stack: pred_ptr, addr, payload_ptr, retdest + + // stack: pred_ptr, addr, payload_ptr, retdest + // Check that this is not a deleted node + DUP1 + %add_const(3) + MLOAD_GENERAL + %jump_neq_const(@U256_MAX, account_found) + // The storage key is not in the list. + PANIC + +account_not_found: + // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + %pop3 + SWAP1 + PUSH 1 + SWAP1 + JUMP + /// Remove the storage key and its value from the access list. /// Panics if the key is not in the list. global remove_account: @@ -477,7 +531,7 @@ global remove_slot: %macro read_accounts_linked_list %stack (addr) -> (addr, 0, %%after) %addr_to_state_key - %jump(insert_account) + %jump(search_account) %%after: // stack: cold_access, account_ptr POP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 74ac30a16..677e2899b 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -1,20 +1,57 @@ +global mpt_read_state_trie_test: + // stack: addr, retdest + // stack: address, retdest + + //TEST linked list + DUP1 + %read_accounts_linked_list + // stack: ll_addr, address, retdest +global debug_ll_addr: + %add_const(3) +global debug_before_read_tre_data: + %mload_trie_data +global debug_ll_code_hash: + // stack: ll_code_hash, address, retdest + SWAP1 + %mpt_read_state_trie_original + DUP1 + %add_const(3) + %mload_trie_data + // stack: code_hash, account_ptr, ll_code_hash, retdest + SWAP1 SWAP2 + // stack: ll_code_hash, code_hash, account_ptr, retdest +global debug_before_eq_hashes: + %assert_eq + // END TEST linked list + SWAP1 + JUMP + + + +// Convenience macro to call mpt_read_state_trie and return where we left off. +%macro mpt_read_state_trie + %stack (addr) -> (addr, %%after) + %jump(mpt_read_state_trie_test) +%%after: +%endmacro + + // Given an address, return a pointer to the associated account data, which // consists of four words (nonce, balance, storage_root, code_hash), in the // state trie. Returns null if the address is not found. -global mpt_read_state_trie: +global mpt_read_state_trie_original: // stack: addr, retdest %addr_to_state_key // stack: key, retdest -global debug_mpt_read_state_trie_state_key: PUSH 64 // num_nibbles %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // node_ptr // stack: node_ptr, num_nibbles, key, retdest %jump(mpt_read) // Convenience macro to call mpt_read_state_trie and return where we left off. -%macro mpt_read_state_trie +%macro mpt_read_state_trie_original %stack (addr) -> (addr, %%after) - %jump(mpt_read_state_trie) + %jump(mpt_read_state_trie_original) %%after: %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm index d277075a5..10506d328 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/router.asm @@ -40,7 +40,6 @@ global update_txn_trie: // stack: txn_rlp_len, txn_counter, num_nibbles, retdest // Copy the transaction rlp to the trie data segment. %get_trie_data_size -global debug_get_trie_data_size: // stack: value_ptr, txn_rlp_len, txn_counter, num_nibbles, retdest SWAP1 // First we write txn rlp length diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 86e92d4e6..3613a75fa 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -230,7 +230,7 @@ fn apply_metadata_and_tries_memops, const D: usize> pub(crate) fn debug_inputs(inputs: &GenerationInputs) { log::debug!("Input signed_txn: {:?}", &inputs.signed_txn); - log::debug!("Input state_trie: {:#?}", &inputs.tries.state_trie); + log::debug!("Input state_trie: {:?}", &inputs.tries.state_trie); log::debug!( "Input transactions_trie: {:?}", &inputs.tries.transactions_trie @@ -249,18 +249,9 @@ pub fn generate_traces, const D: usize>( debug_inputs(&inputs); let mut state = GenerationState::::new(inputs.clone(), &KERNEL.code) .map_err(|err| anyhow!("Failed to parse all the initial prover inputs: {:?}", err))?; - log::debug!( - "trie data[..59] = {:?}", - state.memory.contexts[0].segments[Segment::TrieData.unscale()].content[..59].to_vec() - ); apply_metadata_and_tries_memops(&mut state, &inputs); - log::debug!( - "trie data[..59] = {:?}", - state.memory.contexts[0].segments[Segment::TrieData.unscale()].content[..59].to_vec() - ); - let cpu_res = timed!(timing, "simulate CPU", simulate_cpu(&mut state)); if cpu_res.is_err() { diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index c2ed9266b..7bba03423 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -399,17 +399,28 @@ associated storage trie hash" // Push the payload in the trie data trie_data.push(nonce); + log::debug!( + "added nonce = {:?} to trie_data at pos = {:?}", + trie_data[trie_data.len() - 1], + trie_data.len() - 1 + ); trie_data.push(balance); + log::debug!( + "added balance = {:?} to trie_data at pos = {:?}", + trie_data[trie_data.len() - 1], + trie_data.len() - 1 + ); // The Storage pointer is only written in the trie trie_data.push(0.into()); + trie_data.push(code_hash.into_uint()); log::debug!( - "code_hash = {:?} written at position = {:?}", - code_hash.into_uint(), - trie_data.len() + "added code_hash = {:?} to trie_data at pos = {:?}", + trie_data[trie_data.len() - 1], + trie_data.len() - 1 ); - trie_data.push(code_hash.into_uint()); get_storage_leaves( address, + empty_nibbles(), storage_trie, storage_leaves, trie_data, @@ -424,6 +435,7 @@ associated storage trie hash" pub(crate) fn get_storage_leaves( address: U256, + key: Nibbles, trie: &HashedPartialTrie, storage_leaves: &mut Vec, trie_data: &mut Vec, @@ -436,28 +448,47 @@ where Node::Branch { children, value } => { // Now, load all children and update their pointers. for (i, child) in children.iter().enumerate() { - let child_ptr = - get_storage_leaves(address, child, storage_leaves, trie_data, parse_value)?; + let extended_key = key.merge_nibbles(&Nibbles { + count: 1, + packed: i.into(), + }); + let child_ptr = get_storage_leaves( + address, + extended_key, + child, + storage_leaves, + trie_data, + parse_value, + )?; } Ok(()) } Node::Extension { nibbles, child } => { - get_storage_leaves(address, child, storage_leaves, trie_data, parse_value)?; + let extended_key = key.merge_nibbles(nibbles); + get_storage_leaves( + address, + extended_key, + child, + storage_leaves, + trie_data, + parse_value, + )?; Ok(()) } Node::Leaf { nibbles, value } => { // The last leaf must point to the new one let len = storage_leaves.len(); + let merged_key = key.merge_nibbles(nibbles); storage_leaves[len - 1] = U256::from(Segment::StorageLinkedList as usize + storage_leaves.len()); // Write the address storage_leaves.push(address); // Write the key storage_leaves.push( - nibbles + merged_key .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?, ); @@ -537,11 +568,6 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( // TODO: Remove after checking correctness of linked lists let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; - log::debug!( - "trie_data size after loading state_mpt = {:?}", - trie_data.len() - ); - let txn_root_ptr = load_mpt(&trie_inputs.transactions_trie, &mut trie_data, &|rlp| { let mut parsed_txn = vec![U256::from(rlp.len())]; parsed_txn.extend(rlp.iter().copied().map(U256::from)); diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index ad6d3aa41..7af89c30d 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -414,18 +414,27 @@ impl GenerationState { "accounts linked list = {:?}", self.get_accounts_linked_list() ); - log::debug!( - "trie data[58] = {:?}", - self.memory.contexts[0].segments[Segment::TrieData.unscale()].content[55..60].to_vec(), - ); - if let Some((ptr, _)) = self + if let Some((ptr, node)) = self .get_accounts_linked_list()? .find(|(_, node)| node[0] > addr) { - log::debug!( - "found ptr = {:?}", - Segment::AccountsLinkedList as usize + ptr - ); + { + let mut next_ptr: usize = node[3].try_into().unwrap(); + next_ptr -= Segment::AccountsLinkedList as usize; + let index: usize = self.memory.contexts[0].segments + [Segment::AccountsLinkedList.unscale()] + .content[next_ptr + 1] + .unwrap() + .try_into() + .unwrap(); + log::debug!( + "account found = {:?} at ptr = {:?}", + self.memory.contexts[0].segments[Segment::TrieData.unscale()].content + [index..index + 4] + .to_vec(), + index + ); + } Ok( ((Segment::AccountsLinkedList as usize + ptr) / ACCOUNTS_LINKED_LIST_NODE_SIZE) .into(), @@ -442,12 +451,10 @@ impl GenerationState { fn run_next_insert_slot(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - log::debug!("Looking for addr = {:?} and key = {:?}", addr, key); - if let Some((ptr, _)) = self.get_storage_linked_list()?.find(|(_, node)| { - log::debug!("searching in node = {:?}", node); - node[0] > addr || (node[0] == addr && node[1] > key) - }) { - log::debug!("found"); + if let Some((ptr, _)) = self + .get_storage_linked_list()? + .find(|(_, node)| node[0] > addr || (node[0] == addr && node[1] > key)) + { Ok((ptr / STORAGE_LINKED_LIST_NODE_SIZE).into()) } else { Ok(0.into()) diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index e350ed6b8..5833219da 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -153,33 +153,6 @@ pub(crate) trait State { let halt_offsets = self.get_halt_offsets(); loop { - // TODO: remove! - - // log::debug!( - // "state_trie = {:?}", - // get_state_trie::( - // &self.get_generation_state().memory, - // self.get_generation_state().memory.contexts[0].segments - // [Segment::GlobalMetadata.unscale()] - // .get(GlobalMetadata::StateTrieRoot.unscale()) - // .try_into() - // .unwrap() - // ) - // ); - - // log::debug!( - // "content[1] = {:?}, content[58] = {:?} \n trie_data_size = {:?}", - // self.get_generation_state().memory.contexts[0].segments - // [Segment::TrieData.unscale()] - // .content[1], - // self.get_generation_state().memory.contexts[0].segments - // [Segment::TrieData.unscale()] - // .content[58], - // self.get_generation_state().memory.contexts[0].segments - // [Segment::GlobalMetadata.unscale()] - // .get(GlobalMetadata::TrieDataSize.unscale()) - // ); - let registers = self.get_registers(); let pc = registers.program_counter; From 768962910d6dd45a33a42dd66ff05765af868383 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Tue, 28 May 2024 17:16:16 +0200 Subject: [PATCH 013/118] Check storage reads --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 14 ++++++++++- .../kernel/asm/mpt/storage/storage_read.asm | 25 ++++++++++++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index df8b6f6a5..9e6e05f37 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -310,7 +310,7 @@ global remove_account: %macro insert_slot_no_return %insert_account - POP + %pop2 %endmacro // Multiply the value at the top of the stack, denoted by ptr/5, by 5 @@ -535,4 +535,16 @@ global remove_slot: %%after: // stack: cold_access, account_ptr POP +%endmacro + +%macro read_storage_linked_list + // stack: slot + %slot_to_storage_key + %address + %addr_to_state_key + %stack (addr, key) -> (addr, key, 0, %%after) + %jump(insert_slot) +%%after: + // stack: cold_access, slot_ptr + POP %endmacro \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index db9fe4222..c48b2a9aa 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -5,7 +5,17 @@ %endmacro global sload_current: - %stack (slot) -> (slot, after_storage_read) + + // TEST STORAGE linked list + DUP1 + %read_storage_linked_list + %mload_trie_data + %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) + + // %stack (slot) -> (slot, after_storage_read) + + + %slot_to_storage_key // stack: storage_key, after_storage_read PUSH 64 // storage_key has 64 nibbles @@ -14,18 +24,27 @@ global sload_current: %jump(mpt_read) global after_storage_read: - // stack: value_ptr, retdest + // stack: value_ptr, ll_value, retdest DUP1 %jumpi(storage_key_exists) // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. - %stack (value_ptr, retdest) -> (retdest, 0) + + %stack (value_ptr, ll_value, retdest) -> (retdest, 0) + //%stack (value_ptr, retdest) -> (retdest, 0) + JUMP global storage_key_exists: // stack: value_ptr, retdest + // actually: value_ptr, ll_value, retdest %mload_trie_data // stack: value, retdest + // atually: value, ll_value, retdest + DUP2 +global debug_ll_storage_ok: + %assert_eq + SWAP1 JUMP From 29b79b16a11f523a65f7d406478f304597582ba5 Mon Sep 17 00:00:00 2001 From: Hamy Ratoanina Date: Wed, 29 May 2024 04:07:25 -0400 Subject: [PATCH 014/118] Add segments to preinitialization --- evm_arithmetization/src/memory/columns.rs | 5 +- .../src/memory/memory_stark.rs | 53 ++++++++++++++++--- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/evm_arithmetization/src/memory/columns.rs b/evm_arithmetization/src/memory/columns.rs index 28fc7943f..9c46d61cb 100644 --- a/evm_arithmetization/src/memory/columns.rs +++ b/evm_arithmetization/src/memory/columns.rs @@ -40,8 +40,11 @@ pub(crate) const VIRTUAL_FIRST_CHANGE: usize = SEGMENT_FIRST_CHANGE + 1; // Contains `next_segment * addr_changed * next_is_read`. pub(crate) const INITIALIZE_AUX: usize = VIRTUAL_FIRST_CHANGE + 1; +// Used to allow pre-initialization of some context 0 segments. +pub(crate) const PREINITIALIZED_SEGMENTS: usize = INITIALIZE_AUX + 1; + // We use a range check to enforce the ordering. -pub(crate) const RANGE_CHECK: usize = INITIALIZE_AUX + 1; +pub(crate) const RANGE_CHECK: usize = PREINITIALIZED_SEGMENTS + 1; /// The counter column (used for the range check) starts from 0 and increments. pub(crate) const COUNTER: usize = RANGE_CHECK + 1; /// The frequencies column used in logUp. diff --git a/evm_arithmetization/src/memory/memory_stark.rs b/evm_arithmetization/src/memory/memory_stark.rs index f788024fd..bec3471e9 100644 --- a/evm_arithmetization/src/memory/memory_stark.rs +++ b/evm_arithmetization/src/memory/memory_stark.rs @@ -17,6 +17,7 @@ use starky::evaluation_frame::StarkEvaluationFrame; use starky::lookup::{Column, Filter, Lookup}; use starky::stark::Stark; +use super::columns::PREINITIALIZED_SEGMENTS; use super::segments::Segment; use crate::all_stark::EvmStarkFrame; use crate::memory::columns::{ @@ -130,6 +131,11 @@ pub(crate) fn generate_first_change_flags_and_rc( let address_changed = row[CONTEXT_FIRST_CHANGE] + row[SEGMENT_FIRST_CHANGE] + row[VIRTUAL_FIRST_CHANGE]; row[INITIALIZE_AUX] = next_segment * address_changed * next_is_read; + + row[PREINITIALIZED_SEGMENTS] = (next_segment + - F::from_canonical_usize(Segment::TrieData.unscale())) + * (next_segment - F::from_canonical_usize(Segment::AccountsLinkedList.unscale())) + * (next_segment - F::from_canonical_usize(Segment::StorageLinkedList.unscale())) } } @@ -369,6 +375,18 @@ impl, const D: usize> Stark for MemoryStark, const D: usize> Stark for MemoryStark, const D: usize> Stark for MemoryStark, const D: usize> Stark for MemoryStark Date: Wed, 29 May 2024 13:14:53 +0200 Subject: [PATCH 015/118] [WIP] Unreasonable offset --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 22 ++++++++++++++++--- .../kernel/asm/mpt/storage/storage_read.asm | 1 + .../kernel/asm/mpt/storage/storage_write.asm | 13 +++++++++++ .../src/generation/prover_input.rs | 1 + 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 9e6e05f37..e05ae1ce0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -339,10 +339,13 @@ global insert_slot: PROVER_INPUT(linked_list::insert_slot) // stack: pred_ptr/5, addr, key, payload_ptr, retdest %get_valid_slot_ptr +global debug_the_ptr: // stack: pred_ptr, addr, key, payload_ptr, retdest DUP1 +global debug_before_mload: MLOAD_GENERAL +global debug_after_mload: DUP1 // stack: pred_addr, pred_addr, pred_ptr, addr, key, payload_ptr, retdest DUP4 @@ -353,10 +356,12 @@ global insert_slot: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(insert_new_slot) +global debug_after_first_jumpi: // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq +global debug_after_assert_eq: // stack: pred_ptr, addr, key, payload_ptr, retdest DUP1 %increment @@ -364,6 +369,7 @@ global insert_slot: // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest DUP1 DUP5 GT +global before_jumpi: %jumpi(insert_new_slot) // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest DUP4 @@ -404,14 +410,17 @@ slot_found: %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP +global debug_insert_new_slot: insert_new_slot: - // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest POP // get the value of the next address %add_const(4) +global debug_next_ptr_ptr: // stack: next_ptr_ptr, addr, key, payload_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 +global debug_mload_1: MLOAD_GENERAL // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest // Check that this is not a deleted node @@ -419,6 +428,7 @@ insert_new_slot: %eq_const(@U256_MAX) %assert_zero DUP1 + global debug_mload_2: MLOAD_GENERAL // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 @@ -434,29 +444,35 @@ insert_new_slot: // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 %increment +global debug_mload_3: MLOAD_GENERAL // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest - DUP6 + DUP1 // This is added just to have the correct stack in next_node_ok + DUP7 // The next key must be strictly larger %assert_lt next_node_ok: - // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_addr or next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest POP // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest SWAP2 DUP2 // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, key, payload_ptr, retdest +global debug_mstore_1: MSTORE_GENERAL +global debug_after_mstore_1: // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the address in the new node DUP1 DUP4 +global debug_mload_5: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the key in the new node %increment DUP1 DUP5 +global debug_mload_6: MSTORE_GENERAL // stack: new_ptr + 1, next_ptr, addr, key, payload_ptr, retdest // Store payload_ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index c48b2a9aa..e7be723f0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -8,6 +8,7 @@ global sload_current: // TEST STORAGE linked list DUP1 +global debug_the_slot: %read_storage_linked_list %mload_trie_data %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index 22c5d29de..676cb0e8c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -119,8 +119,21 @@ sstore_after_refund: %append_to_trie_data // stack: slot, value_ptr, kexit_info + // TEST storage write + // TEST STORAGE linked list + DUP2 + DUP2 + %slot_to_storage_key + %address + %addr_to_state_key + %insert_slot_no_return + + // Next, call mpt_insert on the current account's storage root. %stack (slot, value_ptr) -> (slot, value_ptr, after_storage_insert) + + + %slot_to_storage_key // stack: storage_key, value_ptr, after_storage_insert, kexit_info PUSH 64 // storage_key has 64 nibbles diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 7af89c30d..0720365ab 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -451,6 +451,7 @@ impl GenerationState { fn run_next_insert_slot(&mut self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; + log::debug!("storage linked list = {:?}", self.get_storage_linked_list()); if let Some((ptr, _)) = self .get_storage_linked_list()? .find(|(_, node)| node[0] > addr || (node[0] == addr && node[1] > key)) From 796087b701b96af1011dd03671ed778fe1ab9970 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Wed, 29 May 2024 17:43:17 +0200 Subject: [PATCH 016/118] [WIP] Erc721 error --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 76 +++++++++++++++++-- .../kernel/asm/mpt/storage/storage_read.asm | 29 ++++--- .../kernel/asm/mpt/storage/storage_write.asm | 8 ++ 3 files changed, 97 insertions(+), 16 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index e05ae1ce0..c054d2889 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -219,8 +219,8 @@ insert_new_account: %endmacro -/// Search the account addr and payload pointer into the linked list. -/// Return `1, payload_ptr` if the account was inserted, `1, original_ptr` if it was already present +/// Search the account addr andin the linked list. +/// Return `1, payload_ptr` if the account was not found, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. global search_account: // stack: addr, payload_ptr, retdest @@ -335,7 +335,7 @@ global remove_account: /// Return `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. global insert_slot: - // stack: addr, payload_ptr, retdest + // stack: addr, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) // stack: pred_ptr/5, addr, key, payload_ptr, retdest %get_valid_slot_ptr @@ -504,8 +504,70 @@ global debug_mload_6: SWAP2 JUMP +/// Search the pair (addres, storage_key) in the storage the linked list. +/// Returns `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present +/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +// TODO: Not sure if this is correct, bc if a value is not found we need to return 0 but keep track of it for +// having the right cold_access +global search_slot: + // stack: addr, payload_ptr, retdest + PROVER_INPUT(linked_list::insert_slot) + // stack: pred_ptr/5, addr, key, payload_ptr, retdest + %get_valid_slot_ptr + + // stack: pred_ptr, addr, key, payload_ptr, retdest + DUP1 + MLOAD_GENERAL + DUP1 + // stack: pred_addr, pred_addr, pred_ptr, addr, key, payload_ptr, retdest + DUP4 + GT + DUP3 %eq_const(@SEGMENT_STORAGE_LINKED_LIST) + ADD // OR + // If the predesessor is strictly smaller or the predecessor is the special + // node with key @U256_MAX (and hence we're inserting a new minimum), then + // the slot was not found + %jumpi(slot_not_found) + // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. + DUP3 + %assert_eq + // stack: pred_ptr, addr, key, payload_ptr, retdest + DUP1 + %increment + MLOAD_GENERAL + // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + DUP1 DUP5 + GT + %jumpi(slot_not_found) + // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + DUP4 + // We know that key <= pred_key. It must hold that pred_key == key. + %assert_eq + // stack: pred_ptr, addr, key, payload_ptr, retdest + + // stack: pred_ptr, addr, key, payload_ptr, retdest + // Check that this is not a deleted node + DUP1 + %add_const(4) + MLOAD_GENERAL + %jump_neq_const(@U256_MAX, slot_found) + // The storage key is not in the list. + PANIC + +slot_not_found: +// stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest + %pop4 + SWAP1 + PUSH 1 + SWAP1 +global debug_before_jump: + JUMP + + /// Remove the storage key and its value from the list. /// Panics if the key is not in the list. + global remove_slot: // stack: addr, key, retdest PROVER_INPUT(linked_list::remove_slot) @@ -544,6 +606,10 @@ global remove_slot: %pop2 JUMP +/// Search the account addr and payload pointer into the linked list. +/// Return `1, payload_ptr` if the account was inserted, `1, original_ptr` if it was already present +/// and this is the first access, or `0, original_ptr` if it was already present and accessed. + %macro read_accounts_linked_list %stack (addr) -> (addr, 0, %%after) %addr_to_state_key @@ -559,8 +625,8 @@ global remove_slot: %address %addr_to_state_key %stack (addr, key) -> (addr, key, 0, %%after) - %jump(insert_slot) + %jump(search_slot) %%after: - // stack: cold_access, slot_ptr + // stack: cold_access, value_ptr, slot_ptr POP %endmacro \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index e7be723f0..8055ef634 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -7,13 +7,16 @@ global sload_current: // TEST STORAGE linked list - DUP1 -global debug_the_slot: - %read_storage_linked_list - %mload_trie_data - %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) +// DUP1 +//global debug_the_slot: +// %read_storage_linked_list +//global debug_after_read_linked_list: +// %mload_trie_data +//global debug_read_val: +// %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) +//global debug_stack_after_debug_read_val: - // %stack (slot) -> (slot, after_storage_read) + %stack (slot) -> (slot, after_storage_read) @@ -31,8 +34,10 @@ global after_storage_read: // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. - %stack (value_ptr, ll_value, retdest) -> (retdest, 0) - //%stack (value_ptr, retdest) -> (retdest, 0) +global debug_donde_que_salta: + // This is the replacement + // %stack (value_ptr, ll_value, retdest) -> (retdest, 0) + %stack (value_ptr, retdest) -> (retdest, 0) JUMP @@ -42,9 +47,11 @@ global storage_key_exists: %mload_trie_data // stack: value, retdest // atually: value, ll_value, retdest - DUP2 -global debug_ll_storage_ok: - %assert_eq + + + // DUP2 +//global debug_ll_storage_ok: + // %assert_eq SWAP1 JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index 676cb0e8c..633c0c328 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -7,7 +7,9 @@ global sys_sstore: %check_static DUP1 %leftover_gas %le_const(@GAS_CALLSTIPEND) %jumpi(fault_exception) %stack (kexit_info, slot, value) -> (slot, kexit_info, slot, value) +global before_sload_current: %sload_current +global after_sload_current: %address %stack (addr, current_value, kexit_info, slot, value) -> (addr, slot, current_value, kexit_info, slot, value) %insert_accessed_storage_keys @@ -17,9 +19,11 @@ global sys_sstore: MLOAD_GENERAL // stack: original_value, current_value, kexit_info, slot, value PUSH 0 +global debug_a: // stack: gas, original_value, current_value, kexit_info, slot, value %jump(sstore_after_cold_access_check) +global debug_sstore_cold_access: sstore_cold_access: // stack: value_ptr, current_value, kexit_info, slot, value DUP2 MSTORE_GENERAL @@ -28,6 +32,7 @@ sstore_cold_access: PUSH @GAS_COLDSLOAD // stack: gas, original_value, current_value, kexit_info, slot, value +global debug_sstore_after_cold_access_check: sstore_after_cold_access_check: // Check for warm access. %stack (gas, original_value, current_value, kexit_info, slot, value) -> @@ -46,14 +51,17 @@ sstore_after_cold_access_check: DUP2 ISZERO ISZERO %mul_const(@GAS_SRESET) ADD %jump(sstore_charge_gas) +global debug_sstore_warm: sstore_warm: // stack: gas, original_value, current_value, kexit_info, slot, value) %add_const(@GAS_WARMACCESS) +global debug_sstore_charge_gas: sstore_charge_gas: %stack (gas, original_value, current_value, kexit_info, slot, value) -> (gas, kexit_info, current_value, value, original_value, slot) %charge_gas +global debug_sstore_refund: sstore_refund: %stack (kexit_info, current_value, value, original_value, slot) -> (current_value, value, current_value, value, original_value, slot, kexit_info) EQ %jumpi(sstore_no_refund) From 566ccb51f10622caae66f0646b89eb46a7f09fc0 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Wed, 29 May 2024 17:47:46 +0200 Subject: [PATCH 017/118] [WIP] uncomment ll reads --- .../kernel/asm/mpt/storage/storage_read.asm | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index 8055ef634..1e6759027 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -7,16 +7,16 @@ global sload_current: // TEST STORAGE linked list -// DUP1 -//global debug_the_slot: -// %read_storage_linked_list -//global debug_after_read_linked_list: -// %mload_trie_data -//global debug_read_val: -// %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) -//global debug_stack_after_debug_read_val: + DUP1 +global debug_the_slot: + %read_storage_linked_list +global debug_after_read_linked_list: + %mload_trie_data +global debug_read_val: + %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) +global debug_stack_after_debug_read_val: - %stack (slot) -> (slot, after_storage_read) + // %stack (slot) -> (slot, after_storage_read) @@ -35,9 +35,8 @@ global after_storage_read: // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. global debug_donde_que_salta: - // This is the replacement - // %stack (value_ptr, ll_value, retdest) -> (retdest, 0) - %stack (value_ptr, retdest) -> (retdest, 0) + %stack (value_ptr, ll_value, retdest) -> (retdest, 0) + //%stack (value_ptr, retdest) -> (retdest, 0) JUMP @@ -47,11 +46,9 @@ global storage_key_exists: %mload_trie_data // stack: value, retdest // atually: value, ll_value, retdest - - - // DUP2 -//global debug_ll_storage_ok: - // %assert_eq + DUP2 +global debug_ll_storage_ok: + %assert_eq SWAP1 JUMP From 12e63ea3aacd803647d177aa19719670e2c6f540 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Thu, 30 May 2024 16:23:29 +0200 Subject: [PATCH 018/118] [WIP] Fixing iterator --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 2 +- .../src/cpu/kernel/tests/core/access_lists.rs | 7 +- .../src/cpu/kernel/tests/mpt/linked_list.rs | 35 ++--- .../src/generation/linked_list.rs | 16 +-- .../src/generation/prover_input.rs | 128 +++++++++--------- 5 files changed, 90 insertions(+), 98 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index c054d2889..3c04bdbe2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -204,6 +204,7 @@ insert_new_account: PUSH 0 SWAP1 SWAP2 +global debug_before_jump: JUMP %macro search_account @@ -561,7 +562,6 @@ slot_not_found: SWAP1 PUSH 1 SWAP1 -global debug_before_jump: JUMP diff --git a/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs b/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs index ce2b40bc4..9623ed9e1 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/core/access_lists.rs @@ -73,15 +73,14 @@ fn test_list_iterator() -> Result<()> { .get_addresses_access_list() .expect("Since we called init_access_lists there must be a list"); - let Some((pos_0, [next_val_0, _])) = list.next() else { + let Some([next_val_0, _]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(pos_0, 0); assert_eq!(next_val_0, U256::MAX); - let Some((pos_0, _)) = list.next() else { + let Some([_, pos_0]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(pos_0, 0); + assert_eq!(pos_0, U256::from(Segment::AccessedAddresses as usize)); Ok(()) } diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 8319e402b..28296eef8 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -93,18 +93,16 @@ fn test_list_iterator() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be an accounts list"); - let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = accounts_list.next() else { + let Some([addr, ptr, ctr, scaled_pos_1]) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(pos_0, 0); assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); - let Some((pos_0, [addr, ptr, ctr, scaled_pos_1])) = accounts_list.next() else { + let Some([addr, ptr, ctr, scaled_pos_1]) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(pos_0, 0); assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); @@ -114,23 +112,21 @@ fn test_list_iterator() -> Result<()> { .generation_state .get_storage_linked_list() .expect("Since we called init_access_lists there must be a storage list"); - let Some((pos_0, [addr, key, ptr, ctr, scaled_pos_1])) = storage_list.next() else { + let Some([addr, key, ptr, ctr, scaled_pos_1]) = storage_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(pos_0, 0); assert_eq!(addr, U256::MAX); assert_eq!(key, U256::zero()); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); - assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); - let Some((pos_0, [addr, key, ptr, ctr, scaled_pos_1])) = storage_list.next() else { + assert_eq!(scaled_pos_1, (Segment::StorageLinkedList as usize).into()); + let Some([addr, key, ptr, ctr, scaled_pos_1]) = storage_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(pos_0, 0); assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); - assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); + assert_eq!(scaled_pos_1, (Segment::StorageLinkedList as usize).into()); Ok(()) } @@ -167,10 +163,9 @@ fn test_insert_account() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some((old_pos, [addr, ptr, ctr, scaled_next_pos])) = list.next() else { + let Some([addr, ptr, ctr, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(old_pos, 0); assert_eq!(addr, U256::from(address.0.as_slice())); assert_eq!(ptr, payload_ptr); assert_eq!(ctr, U256::zero()); @@ -178,10 +173,9 @@ fn test_insert_account() -> Result<()> { scaled_next_pos, (Segment::AccountsLinkedList as usize).into() ); - let Some((old_pos, [addr, ptr, ctr, scaled_new_pos])) = list.next() else { + let Some([addr, ptr, ctr, scaled_new_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(old_pos, 4); assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); @@ -226,11 +220,9 @@ fn test_insert_storage() -> Result<()> { .get_storage_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some((old_pos, [inserted_addr, inserted_key, ptr, ctr, scaled_next_pos])) = list.next() - else { + let Some([inserted_addr, inserted_key, ptr, ctr, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(old_pos, 0); assert_eq!(inserted_addr, U256::from(address.0.as_slice())); assert_eq!(inserted_key, U256::from(key.0.as_slice())); assert_eq!(ptr, payload_ptr); @@ -239,11 +231,9 @@ fn test_insert_storage() -> Result<()> { scaled_next_pos, (Segment::StorageLinkedList as usize).into() ); - let Some((old_pos, [inserted_addr, inserted_key, ptr, ctr, scaled_new_pos])) = list.next() - else { + let Some([inserted_addr, inserted_key, ptr, ctr, scaled_new_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; - assert_eq!(old_pos, 5); assert_eq!(inserted_addr, U256::MAX); assert_eq!(inserted_key, U256::zero()); assert_eq!(ptr, U256::zero()); @@ -288,6 +278,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { let offset = Segment::AccountsLinkedList as usize; // Insert all addresses for i in 0..n { + log::debug!("checking {i}-th insertion"); let addr = U256::from(addresses[i as usize].0.as_slice()); interpreter.push(0xdeadbeefu32.into()); interpreter.push(addr + delta_ptr); // ptr = addr + delta_ptr for the sake of the test @@ -403,7 +394,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - for (i, (_, [addr, ptr, ctr, _])) in list.enumerate() { + for (i, [addr, ptr, ctr, _]) in list.enumerate() { if addr == U256::MAX { // assert_eq!(addr, U256::MAX); @@ -581,7 +572,7 @@ fn test_insert_and_delete_storage() -> Result<()> { .get_storage_linked_list() .expect("Since we called init_access_lists there must be a list"); - for (i, (_, [addr, key, ptr, ctr, _])) in list.enumerate() { + for (i, [addr, key, ptr, ctr, _]) in list.enumerate() { if addr == U256::MAX { // assert_eq!(addr, U256::MAX); diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index b835ff3e0..115cdc90e 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -76,9 +76,9 @@ impl<'a, const N: usize> fmt::Debug for LinkedList<'a, N> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "Linked List {{"); let cloned_list = self.clone(); - for (_, node) in cloned_list { + for node in cloned_list { if node[0] == U256::MAX { - writeln!(f, "{:?}", node); + writeln!(f, "Node: {:?}", node); break; } writeln!(f, "{:?} ->", node); @@ -88,16 +88,16 @@ impl<'a, const N: usize> fmt::Debug for LinkedList<'a, N> { } impl<'a, const N: usize> Iterator for LinkedList<'a, N> { - type Item = (usize, [U256; N]); + type Item = [U256; N]; fn next(&mut self) -> Option { + // The first node is always the special node, so we skip it in the first + // iteration. if let Ok(new_pos) = u256_to_usize(self.mem[self.pos + N - 1].unwrap_or_default()) { - let old_pos = self.pos; self.pos = new_pos - self.offset; - Some(( - old_pos, - std::array::from_fn(|i| self.mem[self.pos + i].unwrap_or_default()), - )) + Some(std::array::from_fn(|i| { + self.mem[self.pos + i].unwrap_or_default() + })) } else { None } diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 0720365ab..3166c51a9 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -336,7 +336,7 @@ impl GenerationState { /// Returns a non-jumpdest proof for the address on the top of the stack. A /// non-jumpdest proof is the closest address to the address on the top of /// the stack, if the closses address is >= 32, or zero otherwise. - fn run_next_non_jumpdest_proof(&mut self) -> Result { + fn run_next_non_jumpdest_proof(&self) -> Result { let code = self.get_current_code()?; let address = u256_to_usize(stack_peek(self, 0)?)?; let closest_opcode_addr = get_closest_opcode_address(&code, address); @@ -349,13 +349,15 @@ impl GenerationState { /// Returns a pointer to an element in the list whose value is such that /// `value <= addr < next_value` and `addr` is the top of the stack. - fn run_next_addresses_insert(&mut self) -> Result { + fn run_next_addresses_insert(&self) -> Result { let addr = stack_peek(self, 0)?; - if let Some((ptr, _)) = self + if let Some((([_, ptr], _), _)) = self .get_addresses_access_list()? - .find(|&(_, node)| node[0] > addr) + .zip(self.get_addresses_access_list()?.skip(1)) + .zip(self.get_addresses_access_list()?.skip(2)) + .find(|&((_, [prev_addr, _]), [next_addr, _])| prev_addr <= addr && addr < next_addr) { - Ok(((Segment::AccessedAddresses as usize + ptr) / 2usize).into()) + Ok(ptr / U256::from(2)) } else { Ok((Segment::AccessedAddresses as usize).into()) } @@ -364,13 +366,14 @@ impl GenerationState { /// Returns a pointer to an element in the list whose value is such that /// `value < addr == next_value` and addr is the top of the stack. /// If the element is not in the list returns loops forever - fn run_next_addresses_remove(&mut self) -> Result { + fn run_next_addresses_remove(&self) -> Result { let addr = stack_peek(self, 0)?; - if let Some((ptr, _)) = self + if let Some(([_, ptr], _)) = self .get_addresses_access_list()? - .find(|(_, node)| node[0] == addr) + .zip(self.get_addresses_access_list()?.skip(1)) + .find(|&(_, [next_addr, _])| next_addr == addr) { - Ok(((Segment::AccessedAddresses as usize + ptr) / 2usize).into()) + Ok(ptr / U256::from(2)) } else { Ok((Segment::AccessedAddresses as usize).into()) } @@ -378,14 +381,21 @@ impl GenerationState { /// Returns a pointer to the predecessor of the top of the stack in the /// accessed storage keys list. - fn run_next_storage_insert(&mut self) -> Result { + fn run_next_storage_insert(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - if let Some((ptr, _)) = self + if let Some((([.., ptr], _), _)) = self .get_storage_keys_access_list()? - .find(|(_, node)| node[0] > addr || (node[0] == addr && node[1] > key)) + .zip(self.get_storage_keys_access_list()?.skip(1)) + .zip(self.get_storage_keys_access_list()?.skip(2)) + .find( + |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { + (prev_addr <= addr && addr < next_addr) + || (next_addr == addr && prev_key <= key && key < next_key) + }, + ) { - Ok(((Segment::AccessedStorageKeys as usize + ptr) / 4usize).into()) + Ok(ptr / U256::from(4)) } else { Ok((Segment::AccessedStorageKeys as usize).into()) } @@ -393,14 +403,15 @@ impl GenerationState { /// Returns a pointer to the predecessor of the top of the stack in the /// accessed storage keys list. - fn run_next_storage_remove(&mut self) -> Result { + fn run_next_storage_remove(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - if let Some((ptr, _)) = self + if let Some(([.., ptr], _)) = self .get_storage_keys_access_list()? - .find(|(_, node)| (node[0] == addr && node[1] == key) || node[0] == U256::MAX) + .zip(self.get_storage_keys_access_list()?.skip(1)) + .find(|&(_, [next_addr, next_key, ..])| (next_addr == addr && next_key == key)) { - Ok(((Segment::AccessedStorageKeys as usize + ptr) / 4usize).into()) + Ok(ptr / U256::from(4)) } else { Ok((Segment::AccessedStorageKeys as usize).into()) } @@ -408,37 +419,20 @@ impl GenerationState { /// Returns a pointer to an node in the list such that /// `node[0] <= addr < next_node[0]` and `addr` is the top of the stack. - fn run_next_insert_account(&mut self) -> Result { + fn run_next_insert_account(&self) -> Result { let addr = stack_peek(self, 0)?; log::debug!( "accounts linked list = {:?}", self.get_accounts_linked_list() ); - if let Some((ptr, node)) = self + if let Some((([.., pred_ptr], [node_addr, ..]), _)) = self .get_accounts_linked_list()? - .find(|(_, node)| node[0] > addr) + .zip(self.get_accounts_linked_list()?.skip(1)) + .zip(self.get_accounts_linked_list()?.skip(2)) + .find(|&((_, [prev_addr, ..]), [next_addr, ..])| prev_addr <= addr && addr < next_addr) { - { - let mut next_ptr: usize = node[3].try_into().unwrap(); - next_ptr -= Segment::AccountsLinkedList as usize; - let index: usize = self.memory.contexts[0].segments - [Segment::AccountsLinkedList.unscale()] - .content[next_ptr + 1] - .unwrap() - .try_into() - .unwrap(); - log::debug!( - "account found = {:?} at ptr = {:?}", - self.memory.contexts[0].segments[Segment::TrieData.unscale()].content - [index..index + 4] - .to_vec(), - index - ); - } - Ok( - ((Segment::AccountsLinkedList as usize + ptr) / ACCOUNTS_LINKED_LIST_NODE_SIZE) - .into(), - ) + log::debug!("account found = {:?} at ptr = {:?}", node_addr, pred_ptr); + Ok(pred_ptr / U256::from(ACCOUNTS_LINKED_LIST_NODE_SIZE)) } else { Ok((Segment::AccountsLinkedList as usize).into()) } @@ -448,49 +442,57 @@ impl GenerationState { /// `node[0] <= addr < next_node[0]`, or node[0] == addr and `node[1] <= /// key < next_node[1]`, where `addr` and `key` are the elements at top /// of the stack. - fn run_next_insert_slot(&mut self) -> Result { + fn run_next_insert_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; log::debug!("storage linked list = {:?}", self.get_storage_linked_list()); - if let Some((ptr, _)) = self + if let Some((([.., pred_ptr], _), _)) = self .get_storage_linked_list()? - .find(|(_, node)| node[0] > addr || (node[0] == addr && node[1] > key)) + .zip(self.get_storage_linked_list()?.skip(1)) + .zip(self.get_storage_linked_list()?.skip(2)) + .find( + |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { + (prev_addr <= addr && addr < next_addr) || (next_addr == addr && next_key > key) + }, + ) { - Ok((ptr / STORAGE_LINKED_LIST_NODE_SIZE).into()) + Ok(pred_ptr / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) } else { - Ok(0.into()) + Ok((Segment::StorageLinkedList as usize).into()) } } - /// Returns a pointer to an element in the list such that - /// `node[0] < addr == next_node[0]` and addr is the top of the stack. + /// Returns a pointer `ptr`` to a node of the form [next_addr, ..] in the + /// list such that `next_addr = addr` and addr is the top of the stack. /// If the element is not in the list loops forever - fn run_next_remove_account(&mut self) -> Result { + fn run_next_remove_account(&self) -> Result { let addr = stack_peek(self, 0)?; - if let Some((ptr, _)) = self + if let Some(([.., ptr], _)) = self .get_accounts_linked_list()? - .find(|(_, node)| node[0] == addr) + .zip(self.get_accounts_linked_list()?.skip(1)) + .find(|&(_, [next_node_addr, ..])| next_node_addr == addr) { Ok((ptr / ACCOUNTS_LINKED_LIST_NODE_SIZE).into()) } else { - Ok(0.into()) + Ok((Segment::AccountsLinkedList as usize).into()) } } - /// Returns a pointer to an element in the list such that - /// `node[0] <= addr == next_node[0]` and `node[1] < key == next_node[1] `, + /// Returns a pointer `ptr`to an a node = [next_addr, next_key] in the list + /// such that `next_addr == addr` and `next_key == key `, /// and `addr, key` are the elements at the top of the stack. /// If the element is not in the list loops forever - fn run_next_remove_slot(&mut self) -> Result { + fn run_next_remove_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - if let Some((ptr, _)) = self + if let Some(([.., ptr], _)) = self .get_storage_linked_list()? - .find(|(_, node)| node[0] == addr && node[1] == key) + .zip(self.get_storage_linked_list()?.skip(1)) + .find(|&(_, [next_addr, next_key, ..])| next_addr == addr && next_key == key) { - Ok((ptr / STORAGE_LINKED_LIST_NODE_SIZE).into()) + Ok(ptr / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) } else { - Ok(0.into()) + Ok((Segment::StorageLinkedList as usize).into()) } } } @@ -565,7 +567,7 @@ impl GenerationState { } pub(crate) fn get_addresses_access_list( - &mut self, + &self, ) -> Result, ProgramError> { // `GlobalMetadata::AccessedAddressesLen` stores the value of the next available // virtual address in the segment. In order to get the length we need @@ -574,7 +576,7 @@ impl GenerationState { .content .len(); LinkedList::from_mem_and_segment( - &mut self.memory.contexts[0].segments[Segment::AccessedAddresses.unscale()].content, + &self.memory.contexts[0].segments[Segment::AccessedAddresses.unscale()].content, Segment::AccessedAddresses, ) } @@ -612,13 +614,13 @@ impl GenerationState { } pub(crate) fn get_storage_keys_access_list( - &mut self, + &self, ) -> Result, ProgramError> { // GlobalMetadata::AccessedStorageKeysLen stores the value of the next available // virtual address in the segment. In order to get the length we need // to substract Segment::AccessedStorageKeys as usize LinkedList::from_mem_and_segment( - &mut self.memory.contexts[0].segments[Segment::AccessedStorageKeys.unscale()].content, + &self.memory.contexts[0].segments[Segment::AccessedStorageKeys.unscale()].content, Segment::AccessedStorageKeys, ) } From c1f47dd008d57131bc348f9b7a6aaecef6e48d58 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 31 May 2024 11:16:27 +0200 Subject: [PATCH 019/118] Fix unit tests --- .../src/cpu/kernel/tests/mpt/linked_list.rs | 5 +- .../src/generation/linked_list.rs | 2 +- .../src/generation/prover_input.rs | 50 +++++++++++++++---- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 28296eef8..d3637a7bb 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -315,6 +315,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { // Test for address already in list. for i in 0..n { let addr_in_list = U256::from(addresses[i as usize].0.as_slice()); + log::debug!("checking already in the list {i}-th"); interpreter.push(retaddr); interpreter.push(U256::zero()); interpreter.push(addr_in_list); @@ -372,8 +373,9 @@ fn test_insert_and_delete_accounts() -> Result<()> { let mut new_addresses = vec![]; for (i, j) in (0..n).tuples() { - // Test for address already in list. + // Remove addressese already in list. let addr_in_list = U256::from(addresses[i as usize].0.as_slice()); + log::debug!("Removing {i}-th addr = {:?}", addr_in_list); interpreter.push(retaddr); interpreter.push(addr_in_list); interpreter.generation_state.registers.program_counter = delete_account_label; @@ -396,7 +398,6 @@ fn test_insert_and_delete_accounts() -> Result<()> { for (i, [addr, ptr, ctr, _]) in list.enumerate() { if addr == U256::MAX { - // assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); assert_eq!(ctr, U256::zero()); diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index 115cdc90e..6e8cfb00b 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -78,7 +78,7 @@ impl<'a, const N: usize> fmt::Debug for LinkedList<'a, N> { let cloned_list = self.clone(); for node in cloned_list { if node[0] == U256::MAX { - writeln!(f, "Node: {:?}", node); + writeln!(f, "{:?}", node); break; } writeln!(f, "{:?} ->", node); diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 3166c51a9..b56b17b9a 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -355,7 +355,9 @@ impl GenerationState { .get_addresses_access_list()? .zip(self.get_addresses_access_list()?.skip(1)) .zip(self.get_addresses_access_list()?.skip(2)) - .find(|&((_, [prev_addr, _]), [next_addr, _])| prev_addr <= addr && addr < next_addr) + .find(|&((_, [prev_addr, _]), [next_addr, _])| { + (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr + }) { Ok(ptr / U256::from(2)) } else { @@ -390,8 +392,14 @@ impl GenerationState { .zip(self.get_storage_keys_access_list()?.skip(2)) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - (prev_addr <= addr && addr < next_addr) - || (next_addr == addr && prev_key <= key && key < next_key) + let next_addr_is_larger = + (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr; + let between_same_addr = prev_addr == addr && addr == next_addr; + let new_smallest_key = + (prev_addr < addr || prev_addr == U256::MAX) && addr == next_addr; + next_addr_is_larger + || (between_same_addr && prev_key <= key && key < next_key) + || (new_smallest_key && key < next_key) }, ) { @@ -408,7 +416,7 @@ impl GenerationState { let key = stack_peek(self, 1)?; if let Some(([.., ptr], _)) = self .get_storage_keys_access_list()? - .zip(self.get_storage_keys_access_list()?.skip(1)) + .zip(self.get_storage_keys_access_list()?.skip(2)) .find(|&(_, [next_addr, next_key, ..])| (next_addr == addr && next_key == key)) { Ok(ptr / U256::from(4)) @@ -429,7 +437,9 @@ impl GenerationState { .get_accounts_linked_list()? .zip(self.get_accounts_linked_list()?.skip(1)) .zip(self.get_accounts_linked_list()?.skip(2)) - .find(|&((_, [prev_addr, ..]), [next_addr, ..])| prev_addr <= addr && addr < next_addr) + .find(|&((_, [prev_addr, ..]), [next_addr, ..])| { + (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr + }) { log::debug!("account found = {:?} at ptr = {:?}", node_addr, pred_ptr); Ok(pred_ptr / U256::from(ACCOUNTS_LINKED_LIST_NODE_SIZE)) @@ -452,13 +462,21 @@ impl GenerationState { .zip(self.get_storage_linked_list()?.skip(2)) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - (prev_addr <= addr && addr < next_addr) || (next_addr == addr && next_key > key) + let next_addr_is_larger = + (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr; + let between_same_addr = prev_addr == addr && addr == next_addr; + let new_smallest_key = + (prev_addr < addr || prev_addr == U256::MAX) && addr == next_addr; + next_addr_is_larger + || (between_same_addr && prev_key <= key && key < next_key) + || (new_smallest_key && key < next_key) }, ) { - Ok(pred_ptr / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) + Ok((pred_ptr - U256::from(Segment::StorageLinkedList as usize)) + / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) } else { - Ok((Segment::StorageLinkedList as usize).into()) + Ok(U256::zero()) } } @@ -469,9 +487,18 @@ impl GenerationState { let addr = stack_peek(self, 0)?; if let Some(([.., ptr], _)) = self .get_accounts_linked_list()? - .zip(self.get_accounts_linked_list()?.skip(1)) + .zip(self.get_accounts_linked_list()?.skip(2)) .find(|&(_, [next_node_addr, ..])| next_node_addr == addr) { + log::debug!( + "storage linked list = {:?}", + self.get_accounts_linked_list() + ); + log::debug!( + "deleting account with addr = {:?} and ptr = {:?}", + addr, + ptr + ); Ok((ptr / ACCOUNTS_LINKED_LIST_NODE_SIZE).into()) } else { Ok((Segment::AccountsLinkedList as usize).into()) @@ -487,10 +514,11 @@ impl GenerationState { let key = stack_peek(self, 1)?; if let Some(([.., ptr], _)) = self .get_storage_linked_list()? - .zip(self.get_storage_linked_list()?.skip(1)) + .zip(self.get_storage_linked_list()?.skip(2)) .find(|&(_, [next_addr, next_key, ..])| next_addr == addr && next_key == key) { - Ok(ptr / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) + Ok((ptr - U256::from(Segment::StorageLinkedList as usize)) + / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) } else { Ok((Segment::StorageLinkedList as usize).into()) } From 9a9323df8ae8fed3fa4fafd183c80a43e3a8c069 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 31 May 2024 15:42:33 +0200 Subject: [PATCH 020/118] Fix erc721 error --- .../src/cpu/kernel/asm/core/access_lists.asm | 6 ++ .../src/generation/prover_input.rs | 56 +++++++++++++------ 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm index 5d0512a12..a500db8be 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm @@ -234,6 +234,7 @@ global insert_accessed_storage_keys: DUP4 GT DUP3 %eq_const(@SEGMENT_ACCESSED_STORAGE_KEYS) ADD // OR +global debug_before_jumpi1: %jumpi(insert_storage_key) // stack: pred_addr, pred_ptr, addr, key, retdest // We know that addr <= pred_addr. It must hold that pred_addr == addr. @@ -247,11 +248,14 @@ global insert_accessed_storage_keys: DUP1 DUP5 GT // stack: key > pred_key, pred_key, pred_ptr, addr, key, retdest +global debug_before_jumpi2: %jumpi(insert_storage_key) // stack: pred_key, pred_ptr, addr, key, retdest DUP4 // We know that key <= pred_key. It must hold that pred_key == key. +global debug_before_son_eaugles: %assert_eq +global debug_lo_son: // stack: pred_ptr, addr, key, retdest // Check that this is not a deleted node DUP1 @@ -260,6 +264,8 @@ global insert_accessed_storage_keys: %jump_neq_const(@U256_MAX, storage_key_found) // The storage key is not in the list. PANIC + +global debug_key_found: storage_key_found: // The address was already in the list // stack: pred_ptr, addr, key, retdest diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index b56b17b9a..cd28f5a68 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -386,23 +386,37 @@ impl GenerationState { fn run_next_storage_insert(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; + log::debug!( + "storage access list = {:?}", + self.get_storage_keys_access_list() + ); + log::debug!("linda no?"); if let Some((([.., ptr], _), _)) = self .get_storage_keys_access_list()? .zip(self.get_storage_keys_access_list()?.skip(1)) .zip(self.get_storage_keys_access_list()?.skip(2)) + .inspect( + |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { + log::debug!("radical"); + let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) + || (prev_addr == addr && prev_key <= key); + let next_is_strictly_larger = + next_addr > key || (next_addr == addr && next_key > key); + log::debug!("addr = {:?}, prev_addr = {:?}, prev_key = {:?}, next_addr = {:?}, next_key = {:?}, prev_is_less_or_equal = {:?}, next_is_strictly_larger = {:?}", + addr, prev_addr, prev_key, next_addr, next_key, prev_is_less_or_equal, next_is_strictly_larger); + } + ) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - let next_addr_is_larger = - (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr; - let between_same_addr = prev_addr == addr && addr == next_addr; - let new_smallest_key = - (prev_addr < addr || prev_addr == U256::MAX) && addr == next_addr; - next_addr_is_larger - || (between_same_addr && prev_key <= key && key < next_key) - || (new_smallest_key && key < next_key) - }, + let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) + || (prev_addr == addr && prev_key <= key); + let next_is_strictly_larger = + next_addr > addr || (next_addr == addr && next_key > key); + prev_is_less_or_equal && next_is_strictly_larger + } ) { + log::debug!("ptr = {:?} found", ptr); Ok(ptr / U256::from(4)) } else { Ok((Segment::AccessedStorageKeys as usize).into()) @@ -460,16 +474,24 @@ impl GenerationState { .get_storage_linked_list()? .zip(self.get_storage_linked_list()?.skip(1)) .zip(self.get_storage_linked_list()?.skip(2)) + .inspect( + |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { + log::debug!("radical"); + let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) + || (prev_addr == addr && prev_key <= key); + let next_is_strictly_larger = + next_addr > addr || (next_addr == addr && next_key > key); + log::debug!("addr = {:?}, key = {:?}, prev_addr = {:?}, prev_key = {:?}, next_addr = {:?}, next_key = {:?}, prev_is_less_or_equal = {:?}, next_is_strictly_larger = {:?}", + addr, key, prev_addr, prev_key, next_addr, next_key, prev_is_less_or_equal, next_is_strictly_larger); + } + ) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - let next_addr_is_larger = - (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr; - let between_same_addr = prev_addr == addr && addr == next_addr; - let new_smallest_key = - (prev_addr < addr || prev_addr == U256::MAX) && addr == next_addr; - next_addr_is_larger - || (between_same_addr && prev_key <= key && key < next_key) - || (new_smallest_key && key < next_key) + let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) + || (prev_addr == addr && prev_key <= key); + let next_is_strictly_larger = + next_addr > addr || (next_addr == addr && next_key > key); + prev_is_less_or_equal && next_is_strictly_larger }, ) { From 6c93057f2e87cb9ee0624df08b26c7a41ddc799e Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Fri, 31 May 2024 15:58:29 +0200 Subject: [PATCH 021/118] mend --- .../src/cpu/kernel/asm/mpt/linked_list.asm | 2 +- .../src/cpu/kernel/asm/mpt/storage/storage_write.asm | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 3c04bdbe2..0b6f6c0b2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -310,7 +310,7 @@ global remove_account: %endmacro %macro insert_slot_no_return - %insert_account + %insert_slot %pop2 %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index 633c0c328..b7aa3b5af 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -7,9 +7,7 @@ global sys_sstore: %check_static DUP1 %leftover_gas %le_const(@GAS_CALLSTIPEND) %jumpi(fault_exception) %stack (kexit_info, slot, value) -> (slot, kexit_info, slot, value) -global before_sload_current: %sload_current -global after_sload_current: %address %stack (addr, current_value, kexit_info, slot, value) -> (addr, slot, current_value, kexit_info, slot, value) %insert_accessed_storage_keys @@ -19,11 +17,9 @@ global after_sload_current: MLOAD_GENERAL // stack: original_value, current_value, kexit_info, slot, value PUSH 0 -global debug_a: // stack: gas, original_value, current_value, kexit_info, slot, value %jump(sstore_after_cold_access_check) -global debug_sstore_cold_access: sstore_cold_access: // stack: value_ptr, current_value, kexit_info, slot, value DUP2 MSTORE_GENERAL @@ -32,7 +28,6 @@ sstore_cold_access: PUSH @GAS_COLDSLOAD // stack: gas, original_value, current_value, kexit_info, slot, value -global debug_sstore_after_cold_access_check: sstore_after_cold_access_check: // Check for warm access. %stack (gas, original_value, current_value, kexit_info, slot, value) -> @@ -51,17 +46,14 @@ sstore_after_cold_access_check: DUP2 ISZERO ISZERO %mul_const(@GAS_SRESET) ADD %jump(sstore_charge_gas) -global debug_sstore_warm: sstore_warm: // stack: gas, original_value, current_value, kexit_info, slot, value) %add_const(@GAS_WARMACCESS) -global debug_sstore_charge_gas: sstore_charge_gas: %stack (gas, original_value, current_value, kexit_info, slot, value) -> (gas, kexit_info, current_value, value, original_value, slot) %charge_gas -global debug_sstore_refund: sstore_refund: %stack (kexit_info, current_value, value, original_value, slot) -> (current_value, value, current_value, value, original_value, slot, kexit_info) EQ %jumpi(sstore_no_refund) @@ -136,12 +128,8 @@ sstore_after_refund: %addr_to_state_key %insert_slot_no_return - // Next, call mpt_insert on the current account's storage root. %stack (slot, value_ptr) -> (slot, value_ptr, after_storage_insert) - - - %slot_to_storage_key // stack: storage_key, value_ptr, after_storage_insert, kexit_info PUSH 64 // storage_key has 64 nibbles From 48d1cfe0f4ae28e364ac47ec1d495967ac1665e5 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Fri, 31 May 2024 17:41:21 +0200 Subject: [PATCH 022/118] Remove debug info --- .../src/cpu/kernel/asm/core/access_lists.asm | 5 --- .../src/cpu/kernel/asm/core/transfer.asm | 1 - .../asm/mpt/insert/insert_trie_specific.asm | 2 - .../src/cpu/kernel/asm/mpt/linked_list.asm | 16 ------- .../src/cpu/kernel/asm/mpt/read.asm | 6 +-- .../kernel/asm/mpt/storage/storage_read.asm | 13 +++--- evm_arithmetization/src/generation/mpt.rs | 6 +-- .../src/generation/prover_input.rs | 43 ------------------- 8 files changed, 11 insertions(+), 81 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm index a500db8be..b88502baf 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm @@ -234,7 +234,6 @@ global insert_accessed_storage_keys: DUP4 GT DUP3 %eq_const(@SEGMENT_ACCESSED_STORAGE_KEYS) ADD // OR -global debug_before_jumpi1: %jumpi(insert_storage_key) // stack: pred_addr, pred_ptr, addr, key, retdest // We know that addr <= pred_addr. It must hold that pred_addr == addr. @@ -248,14 +247,11 @@ global debug_before_jumpi1: DUP1 DUP5 GT // stack: key > pred_key, pred_key, pred_ptr, addr, key, retdest -global debug_before_jumpi2: %jumpi(insert_storage_key) // stack: pred_key, pred_ptr, addr, key, retdest DUP4 // We know that key <= pred_key. It must hold that pred_key == key. -global debug_before_son_eaugles: %assert_eq -global debug_lo_son: // stack: pred_ptr, addr, key, retdest // Check that this is not a deleted node DUP1 @@ -265,7 +261,6 @@ global debug_lo_son: // The storage key is not in the list. PANIC -global debug_key_found: storage_key_found: // The address was already in the list // stack: pred_ptr, addr, key, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm index 0d0b7b754..0517cf3a8 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm @@ -66,7 +66,6 @@ global add_eth: // stack: addr, amount, retdest DUP1 %insert_touched_addresses DUP1 %mpt_read_state_trie -global debug_is_not_arriving_here: // stack: account_ptr, addr, amount, retdest DUP1 ISZERO %jumpi(add_eth_new_account) // If the account pointer is null, we need to create the account. %add_const(1) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm index 5508d6dc2..8d84e6774 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm @@ -7,9 +7,7 @@ global mpt_insert_state_trie: // stack: key, value_ptr, retdest DUP2 DUP2 -global debug_before_insert_account_no_return: %insert_account_no_return -global debug_account_inserted: %stack (key, value_ptr) -> (key, value_ptr, mpt_insert_state_trie_save) PUSH 64 // num_nibbles diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 0b6f6c0b2..505201cf9 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -204,7 +204,6 @@ insert_new_account: PUSH 0 SWAP1 SWAP2 -global debug_before_jump: JUMP %macro search_account @@ -340,13 +339,10 @@ global insert_slot: PROVER_INPUT(linked_list::insert_slot) // stack: pred_ptr/5, addr, key, payload_ptr, retdest %get_valid_slot_ptr -global debug_the_ptr: // stack: pred_ptr, addr, key, payload_ptr, retdest DUP1 -global debug_before_mload: MLOAD_GENERAL -global debug_after_mload: DUP1 // stack: pred_addr, pred_addr, pred_ptr, addr, key, payload_ptr, retdest DUP4 @@ -357,12 +353,10 @@ global debug_after_mload: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(insert_new_slot) -global debug_after_first_jumpi: // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq -global debug_after_assert_eq: // stack: pred_ptr, addr, key, payload_ptr, retdest DUP1 %increment @@ -410,18 +404,14 @@ slot_found: %eq_const(1) %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP - -global debug_insert_new_slot: insert_new_slot: // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest POP // get the value of the next address %add_const(4) -global debug_next_ptr_ptr: // stack: next_ptr_ptr, addr, key, payload_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 -global debug_mload_1: MLOAD_GENERAL // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest // Check that this is not a deleted node @@ -429,7 +419,6 @@ global debug_mload_1: %eq_const(@U256_MAX) %assert_zero DUP1 - global debug_mload_2: MLOAD_GENERAL // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 @@ -445,7 +434,6 @@ global debug_mload_1: // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 %increment -global debug_mload_3: MLOAD_GENERAL // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 // This is added just to have the correct stack in next_node_ok @@ -459,21 +447,17 @@ next_node_ok: SWAP2 DUP2 // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, key, payload_ptr, retdest -global debug_mstore_1: MSTORE_GENERAL -global debug_after_mstore_1: // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the address in the new node DUP1 DUP4 -global debug_mload_5: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the key in the new node %increment DUP1 DUP5 -global debug_mload_6: MSTORE_GENERAL // stack: new_ptr + 1, next_ptr, addr, key, payload_ptr, retdest // Store payload_ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 677e2899b..7ba7ca224 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -1,3 +1,4 @@ +// TODO: Use only linked lists global mpt_read_state_trie_test: // stack: addr, retdest // stack: address, retdest @@ -6,11 +7,8 @@ global mpt_read_state_trie_test: DUP1 %read_accounts_linked_list // stack: ll_addr, address, retdest -global debug_ll_addr: %add_const(3) -global debug_before_read_tre_data: %mload_trie_data -global debug_ll_code_hash: // stack: ll_code_hash, address, retdest SWAP1 %mpt_read_state_trie_original @@ -20,7 +18,7 @@ global debug_ll_code_hash: // stack: code_hash, account_ptr, ll_code_hash, retdest SWAP1 SWAP2 // stack: ll_code_hash, code_hash, account_ptr, retdest -global debug_before_eq_hashes: +global debug_at_least_the_code_hash_is_the_same: %assert_eq // END TEST linked list SWAP1 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index 1e6759027..bc8598087 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -6,15 +6,12 @@ global sload_current: + // TODO: Use only the linked list // TEST STORAGE linked list DUP1 -global debug_the_slot: %read_storage_linked_list -global debug_after_read_linked_list: %mload_trie_data -global debug_read_val: %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) -global debug_stack_after_debug_read_val: // %stack (slot) -> (slot, after_storage_read) @@ -34,8 +31,10 @@ global after_storage_read: // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. -global debug_donde_que_salta: - %stack (value_ptr, ll_value, retdest) -> (retdest, 0) + POP +global debug_the_storage_value_is_zero: + %assert_zero + %stack (retdest) -> (retdest, 0) //%stack (value_ptr, retdest) -> (retdest, 0) JUMP @@ -47,7 +46,7 @@ global storage_key_exists: // stack: value, retdest // atually: value, ll_value, retdest DUP2 -global debug_ll_storage_ok: +global debug_the_storage_value_is_the_same: %assert_eq SWAP1 diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index 7bba03423..b0cacd583 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -565,9 +565,6 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( }) .collect(); - // TODO: Remove after checking correctness of linked lists - let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; - let txn_root_ptr = load_mpt(&trie_inputs.transactions_trie, &mut trie_data, &|rlp| { let mut parsed_txn = vec![U256::from(rlp.len())]; parsed_txn.extend(rlp.iter().copied().map(U256::from)); @@ -585,6 +582,9 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( &storage_tries_by_state_key, ); + // TODO: Remove after checking correctness of linked lists + let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; + Ok(( TrieRootPtrs { state_root_ptr: Some(state_root_ptr), diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index cd28f5a68..42efe0e11 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -386,26 +386,10 @@ impl GenerationState { fn run_next_storage_insert(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - log::debug!( - "storage access list = {:?}", - self.get_storage_keys_access_list() - ); - log::debug!("linda no?"); if let Some((([.., ptr], _), _)) = self .get_storage_keys_access_list()? .zip(self.get_storage_keys_access_list()?.skip(1)) .zip(self.get_storage_keys_access_list()?.skip(2)) - .inspect( - |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - log::debug!("radical"); - let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) - || (prev_addr == addr && prev_key <= key); - let next_is_strictly_larger = - next_addr > key || (next_addr == addr && next_key > key); - log::debug!("addr = {:?}, prev_addr = {:?}, prev_key = {:?}, next_addr = {:?}, next_key = {:?}, prev_is_less_or_equal = {:?}, next_is_strictly_larger = {:?}", - addr, prev_addr, prev_key, next_addr, next_key, prev_is_less_or_equal, next_is_strictly_larger); - } - ) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) @@ -416,7 +400,6 @@ impl GenerationState { } ) { - log::debug!("ptr = {:?} found", ptr); Ok(ptr / U256::from(4)) } else { Ok((Segment::AccessedStorageKeys as usize).into()) @@ -443,10 +426,6 @@ impl GenerationState { /// `node[0] <= addr < next_node[0]` and `addr` is the top of the stack. fn run_next_insert_account(&self) -> Result { let addr = stack_peek(self, 0)?; - log::debug!( - "accounts linked list = {:?}", - self.get_accounts_linked_list() - ); if let Some((([.., pred_ptr], [node_addr, ..]), _)) = self .get_accounts_linked_list()? .zip(self.get_accounts_linked_list()?.skip(1)) @@ -455,7 +434,6 @@ impl GenerationState { (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr }) { - log::debug!("account found = {:?} at ptr = {:?}", node_addr, pred_ptr); Ok(pred_ptr / U256::from(ACCOUNTS_LINKED_LIST_NODE_SIZE)) } else { Ok((Segment::AccountsLinkedList as usize).into()) @@ -469,22 +447,10 @@ impl GenerationState { fn run_next_insert_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - log::debug!("storage linked list = {:?}", self.get_storage_linked_list()); if let Some((([.., pred_ptr], _), _)) = self .get_storage_linked_list()? .zip(self.get_storage_linked_list()?.skip(1)) .zip(self.get_storage_linked_list()?.skip(2)) - .inspect( - |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - log::debug!("radical"); - let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) - || (prev_addr == addr && prev_key <= key); - let next_is_strictly_larger = - next_addr > addr || (next_addr == addr && next_key > key); - log::debug!("addr = {:?}, key = {:?}, prev_addr = {:?}, prev_key = {:?}, next_addr = {:?}, next_key = {:?}, prev_is_less_or_equal = {:?}, next_is_strictly_larger = {:?}", - addr, key, prev_addr, prev_key, next_addr, next_key, prev_is_less_or_equal, next_is_strictly_larger); - } - ) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) @@ -512,15 +478,6 @@ impl GenerationState { .zip(self.get_accounts_linked_list()?.skip(2)) .find(|&(_, [next_node_addr, ..])| next_node_addr == addr) { - log::debug!( - "storage linked list = {:?}", - self.get_accounts_linked_list() - ); - log::debug!( - "deleting account with addr = {:?} and ptr = {:?}", - addr, - ptr - ); Ok((ptr / ACCOUNTS_LINKED_LIST_NODE_SIZE).into()) } else { Ok((Segment::AccountsLinkedList as usize).into()) From c938cad9b4eeda34a844a1bc5d4a60ba1a887541 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Fri, 31 May 2024 17:51:14 +0200 Subject: [PATCH 023/118] mend --- .../src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm index 8d84e6774..5784c6b3b 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm @@ -6,8 +6,10 @@ // TODO: Have this take an address and do %mpt_insert_state_trie? To match mpt_read_state_trie. global mpt_insert_state_trie: // stack: key, value_ptr, retdest + // TODO: Use only the account linked list DUP2 DUP2 %insert_account_no_return + %stack (key, value_ptr) -> (key, value_ptr, mpt_insert_state_trie_save) PUSH 64 // num_nibbles From dba0967ccb39919ec6a6603a76963a789c7f0a22 Mon Sep 17 00:00:00 2001 From: 4l0n50 Date: Mon, 3 Jun 2024 16:32:29 +0200 Subject: [PATCH 024/118] [WIP] hashing --- evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm | 2 +- evm_arithmetization/src/generation/mpt.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 0b6f6c0b2..5e8313d75 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -629,4 +629,4 @@ global remove_slot: %%after: // stack: cold_access, value_ptr, slot_ptr POP -%endmacro \ No newline at end of file +%endmacro diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index 7bba03423..f1d9638d9 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -391,7 +391,7 @@ associated storage trie hash" .map_err(|_| ProgramError::IntegerTooLarge)?; state_leaves.push(address); // Set `value_ptr_ptr`. - state_leaves.push((trie_data.len()).into()); + state_leaves.push(trie_data.len().into()); // Set counter state_leaves.push(0.into()); // Set the next node as the inital node From 8a386f9d720f0675d22af80649a68859a6dfe56f Mon Sep 17 00:00:00 2001 From: Hamy Ratoanina Date: Mon, 3 Jun 2024 15:25:15 -0400 Subject: [PATCH 025/118] Provide constants non-deterministically --- .../src/cpu/kernel/asm/main.asm | 9 ++++++++ evm_arithmetization/src/generation/mod.rs | 23 ------------------- .../src/generation/prover_input.rs | 15 ++++++++++++ 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 1449834a0..7d1181753 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -22,6 +22,15 @@ global main: // Encode constant nodes %initialize_rlp_segment + + // Initialize linked list and trie data constants. + // TODO: Validate them. + PROVER_INPUT(linked_list::accounts_linked_list_len) + %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) + PROVER_INPUT(linked_list::storage_linked_list_len) + %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) + PROVER_INPUT(trie_ptr::trie_data_size) + %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) // Initialize the state, transaction and receipt trie root pointers. PROVER_INPUT(trie_ptr::state) diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 3613a75fa..efb15775c 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -162,29 +162,6 @@ fn apply_metadata_and_tries_memops, const D: usize> ), (GlobalMetadata::KernelHash, h2u(KERNEL.code_hash)), (GlobalMetadata::KernelLen, KERNEL.code.len().into()), - ( - GlobalMetadata::AccountsLinkedListLen, - (Segment::AccountsLinkedList as usize - + state.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] - .content - .len()) - .into(), - ), - ( - GlobalMetadata::StorageLinkedListLen, - (Segment::StorageLinkedList as usize - + state.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] - .content - .len()) - .into(), - ), - ( - GlobalMetadata::TrieDataSize, - state.memory.contexts[0].segments[Segment::TrieData.unscale()] - .content - .len() - .into(), - ), ]; let channel = MemoryChannel::GeneralPurpose(0); diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index cd28f5a68..abef54439 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -80,6 +80,11 @@ impl GenerationState { .map(U256::from), "txn" => Ok(U256::from(self.trie_root_ptrs.txn_root_ptr)), "receipt" => Ok(U256::from(self.trie_root_ptrs.receipt_root_ptr)), + "trie_data_size" => Ok(U256::from( + self.memory.contexts[0].segments[Segment::TrieData.unscale()] + .content + .len(), + )), _ => Err(ProgramError::ProverInputError(InvalidInput)), } } @@ -281,6 +286,16 @@ impl GenerationState { "remove_account" => self.run_next_remove_account(), "insert_slot" => self.run_next_insert_slot(), "remove_slot" => self.run_next_remove_slot(), + "accounts_linked_list_len" => Ok((Segment::AccountsLinkedList as usize + + self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] + .content + .len()) + .into()), + "storage_linked_list_len" => Ok((Segment::StorageLinkedList as usize + + self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] + .content + .len()) + .into()), _ => Err(ProgramError::ProverInputError(InvalidInput)), } } From 5deb97d5a004e254b22dc79421c0b072c9e76e32 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 4 Jun 2024 11:40:02 +0800 Subject: [PATCH 026/118] Update journaling --- .../kernel/asm/journal/account_created.asm | 2 +- .../kernel/asm/journal/account_destroyed.asm | 33 +++++++++++++++++-- .../cpu/kernel/asm/journal/account_loaded.asm | 1 + .../cpu/kernel/asm/journal/code_change.asm | 4 ++- .../cpu/kernel/asm/journal/nonce_change.asm | 4 ++- .../src/cpu/kernel/asm/mpt/linked_list.asm | 7 +++- 6 files changed, 45 insertions(+), 6 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm index 4748d5cbc..2360dafb4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm @@ -9,5 +9,5 @@ global revert_account_created: POP %journal_load_1 // stack: address, retdest - %delete_account + %remove_account JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index 3806a891d..6ff1127d0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -4,14 +4,14 @@ %journal_add_3(@JOURNAL_ENTRY_ACCOUNT_DESTROYED) %endmacro -global revert_account_destroyed: +global revert_account_destroyed_original: // stack: entry_type, ptr, retdest POP %journal_load_3 // stack: address, target, prev_balance, retdest PUSH revert_account_destroyed_contd DUP2 %jump(remove_selfdestruct_list) -revert_account_destroyed_contd: +revert_account_destroyed_contd_original: // stack: address, target, prev_balance, retdest SWAP1 // Remove `prev_balance` from `target`'s balance. @@ -30,3 +30,32 @@ revert_account_destroyed_contd: %mstore_trie_data JUMP +global revert_account_destroyed: + // stack: entry_type, ptr, retdest + POP + %journal_load_3 + // stack: address, target, prev_balance, retdest + PUSH revert_account_destroyed_contd DUP2 + %jump(remove_selfdestruct_list) +revert_account_destroyed_contd: + // stack: address: target, prev_balance, retdest + SWAP1 + // Remove `prev_balance` from `target`'s balance. + // stack: target, address, prev_balance, retdest + %search_account + // stack: target_found, target_payload_ptr, address, prev_balance, retdest + // The target should have been accessed before + %assert_zero %add_const(1) + // stack: target_balance_ptr, address, prev_balance, retdest + DUP3 DUP2 %mload_trie_data + // stack: target_balance, prev_balance, target_balance_ptr, address, prev_balance, retdest + SUB SWAP1 %mstore_trie_data + // stack: address, prev_balance, retdest + %search_account + // stack: address_found, account_payload, prev_balance, retdest + %assert_zero + %increment + // stack: account_balance_payload, prev_balance, retdest + %mstore_trie_data + JUMP + diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm index d7da0a788..4d3bb473c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm @@ -11,6 +11,7 @@ global revert_account_loaded: POP %journal_load_1 // stack: address, retdest + // TODO: remove 1 from the counter in the linked_lists. DUP1 %eq_const(@RIP160) %jumpi(ripemd) %jump(remove_accessed_addresses) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm index 5bb637c72..3c43f66d4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm @@ -9,7 +9,9 @@ global revert_code_change: POP %journal_load_2 // stack: address, prev_codehash, retdest - %mpt_read_state_trie + %search_account + // stack: address_found, account_ptr, prev_codehash, retdest + %assert_zero // stack: account_ptr, prev_codehash, retdest %add_const(3) // stack: codehash_ptr, prev_codehash, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm index 3ab8f1367..14cf8ce76 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm @@ -9,7 +9,9 @@ global revert_nonce_change: POP %journal_load_2 // stack: address, prev_nonce, retdest - %mpt_read_state_trie + %search_account + // stack: found_address, payload_ptr, prev_nonce, retdest + %assert_zero // The address should already be present. // stack: nonce_ptr, prev_nonce retdest %mstore_trie_data // stack: retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 0b6f6c0b2..6764a5bef 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -220,7 +220,7 @@ global debug_before_jump: %endmacro -/// Search the account addr andin the linked list. +/// Search the account addr in the linked list. /// Return `1, payload_ptr` if the account was not found, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. global search_account: @@ -295,6 +295,11 @@ global remove_account: POP JUMP +%macro remove_account + %stack (addr) -> (addr, %%after) + %jump(remove_account) +%%after: +%endmacro // // From fbb216b238e32ca6969a9406765c1c9ad8416362 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 4 Jun 2024 15:26:21 +0800 Subject: [PATCH 027/118] Update search_account and read_accounts_linked_lists --- .../kernel/asm/journal/account_destroyed.asm | 8 +++--- .../cpu/kernel/asm/journal/code_change.asm | 4 +-- .../cpu/kernel/asm/journal/nonce_change.asm | 4 +-- .../src/cpu/kernel/asm/mpt/linked_list.asm | 26 +++++++++++-------- .../src/cpu/kernel/asm/mpt/read.asm | 3 ++- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index 6ff1127d0..e784fd6b9 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -42,18 +42,18 @@ revert_account_destroyed_contd: SWAP1 // Remove `prev_balance` from `target`'s balance. // stack: target, address, prev_balance, retdest - %search_account + %read_accounts_linked_list // stack: target_found, target_payload_ptr, address, prev_balance, retdest // The target should have been accessed before - %assert_zero %add_const(1) + %assert_eq_const(1) %add_const(1) // stack: target_balance_ptr, address, prev_balance, retdest DUP3 DUP2 %mload_trie_data // stack: target_balance, prev_balance, target_balance_ptr, address, prev_balance, retdest SUB SWAP1 %mstore_trie_data // stack: address, prev_balance, retdest - %search_account + %read_accounts_linked_list // stack: address_found, account_payload, prev_balance, retdest - %assert_zero + %assert_eq_const(1) %increment // stack: account_balance_payload, prev_balance, retdest %mstore_trie_data diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm index 3c43f66d4..5e902dc6a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm @@ -9,9 +9,9 @@ global revert_code_change: POP %journal_load_2 // stack: address, prev_codehash, retdest - %search_account + %read_accounts_linked_list // stack: address_found, account_ptr, prev_codehash, retdest - %assert_zero + %assert_eq_const(1) // stack: account_ptr, prev_codehash, retdest %add_const(3) // stack: codehash_ptr, prev_codehash, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm index 14cf8ce76..8ac1eee9e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm @@ -9,9 +9,9 @@ global revert_nonce_change: POP %journal_load_2 // stack: address, prev_nonce, retdest - %search_account + %read_accounts_linked_list // stack: found_address, payload_ptr, prev_nonce, retdest - %assert_zero // The address should already be present. + %assert_eq_const(1) // The address should already be present. // stack: nonce_ptr, prev_nonce retdest %mstore_trie_data // stack: retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 6764a5bef..6b79965a9 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -147,7 +147,7 @@ account_found: // stack: access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest // If access_ctr == 1 then this it's a cold access %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, 1, cold_access, orig_payload_ptr) JUMP insert_new_account: @@ -216,13 +216,15 @@ global debug_before_jump: %macro search_account_no_return %search_account - %pop2 + %pop3 %endmacro /// Search the account addr in the linked list. -/// Return `1, payload_ptr` if the account was not found, `1, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +/// Returns (account_found, cold_access, payload_ptr) where: +/// - `account_found` indicates whether the account was already in the linked list, +/// - `cold_access` indicates whether the current access is a cold access (so whether the account was ever accessed before) +/// - `payload_ptr` is a pointer to the account's payload. global search_account: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) @@ -246,7 +248,6 @@ global search_account: %assert_eq // stack: pred_ptr, addr, payload_ptr, retdest - // stack: pred_ptr, addr, payload_ptr, retdest // Check that this is not a deleted node DUP1 %add_const(3) @@ -258,9 +259,8 @@ global search_account: account_not_found: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest %pop3 - SWAP1 - PUSH 1 - SWAP1 + %stack (payload_ptr, retdest) -> (retdest, 0, 1, payload_ptr) + // stack: retdest, account_found, cold_access, payload_ptr, retdest JUMP /// Remove the storage key and its value from the access list. @@ -620,8 +620,8 @@ global remove_slot: %addr_to_state_key %jump(search_account) %%after: - // stack: cold_access, account_ptr - POP + // stack: address_found, cold_access, account_ptr + SWAP1 POP %endmacro %macro read_storage_linked_list @@ -634,4 +634,8 @@ global remove_slot: %%after: // stack: cold_access, value_ptr, slot_ptr POP -%endmacro \ No newline at end of file +%endmacro + +/// Search the account addr and payload pointer into the linked list. +/// Return `1, payload_ptr` if the account was inserted, `0, original_ptr` if it was already present +/// and this is the first access, or `0, original_ptr` if it was already present and accessed. \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 677e2899b..ad9b563c8 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -5,7 +5,8 @@ global mpt_read_state_trie_test: //TEST linked list DUP1 %read_accounts_linked_list - // stack: ll_addr, address, retdest + // stack: addr_found, ll_addr, address, retdest + POP global debug_ll_addr: %add_const(3) global debug_before_read_tre_data: From 8c3ac792afbb6b0d03af31fd2cf373ef09a072f6 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Tue, 4 Jun 2024 12:02:06 +0200 Subject: [PATCH 028/118] Constraint state and storage leaves --- .../asm/mpt/hash/hash_trie_specific.asm | 4 - .../asm/mpt/{ => linked_list}/linked_list.asm | 0 .../kernel/asm/mpt/linked_list/set_leaves.asm | 137 ++++++++++++++++++ 3 files changed, 137 insertions(+), 4 deletions(-) rename evm_arithmetization/src/cpu/kernel/asm/mpt/{ => linked_list}/linked_list.asm (100%) create mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm index cd07c01fd..b9bed9ae2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm @@ -101,10 +101,6 @@ global encode_account: DUP3 %add_const(2) %mload_trie_data // storage_root_ptr = value[2] // stack: storage_root_ptr, cur_len, rlp_pos_5, value_ptr, cur_len, retdest - - PUSH debug_after_hash_storage_trie - POP - // Hash storage trie. %mpt_hash_storage_trie // stack: storage_root_digest, new_len, rlp_pos_5, value_ptr, cur_len, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm similarity index 100% rename from evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm rename to evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm new file mode 100644 index 000000000..2066cefa8 --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm @@ -0,0 +1,137 @@ +// Set the trie with root at `node_ptr` leaves +// payloads pointers to mem[payload_ptr_ptr] + step*i, for +// for i =0..n_leaves. This is used to constraint that the +// initial state and account tries payload pointers are exactly +// those of the inital accounts and linked lists +// Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest +// Post stack: account_ptr_ptr, storage_ptr_ptr +global mpt_set_payload: + // stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + DUP1 %mload_trie_data + // stack: node_type, node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // Increment node_ptr, so it points to the node payload instead of its type. + SWAP1 %increment SWAP1 + // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + + DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(skip) + DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_branch) + DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) + DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) + +skip: + // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %stack (node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) + JUMP + +// Pre stack: node_ptr, account_ptr_ptr, retdest +// Post stack: storage_ptr_ptr +global mpt_set_storage_payload: + // stack: node_ptr, storage_ptr_ptr, retdest + DUP1 %mload_trie_data + // stack: node_type, node_ptr, storage_ptr_ptr, retdest + // Increment node_ptr, so it points to the node payload instead of its type. + SWAP1 %increment SWAP1 + // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest + + DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(storage_skip) + DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_storage_branch) + DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) + DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_storage_leaf) + +storage_skip: + // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest + %stack (node_type, node_payload_ptr, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) + JUMP + +global set_payload_branch: + // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + POP + + // Call encode_or_hash_node on each child + %rep 16 + %stack + (node_payload_ptr, account_ptr_ptr, storage_ptr_ptr) -> + (node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_mpt_set_payload, node_payload_ptr) + // stack: node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %mload_trie_data + // stack: child_i_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_encode, node_payload_ptr, retdest + %jump(mpt_set_payload) + %%after_mpt_set_payload: + // stack: account_ptr_ptr', storage_ptr_ptr', node_payload_ptr, retdest + SWAP1 + SWAP2 + %increment + %endrep + // stack: node_payload_ptr', account_ptr_ptr', storage_ptr_ptr', retdest + %stack (node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) + JUMP + +global set_payload_storage_branch: + // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest + POP + + // Call encode_or_hash_node on each child + %rep 16 + %stack + (node_payload_ptr, storage_ptr_ptr) -> + (node_payload_ptr, storage_ptr_ptr, %%after_mpt_set_payload, node_payload_ptr) + // stack: node_payload_ptr, storage_ptr_ptr, retdest + %mload_trie_data + // stack: child_i_ptr, storage_ptr_ptr, %%after_encode, node_payload_ptr, retdest + %jump(mpt_set_payload) + %%after_mpt_set_payload: + // stack: storage_ptr_ptr', node_payload_ptr, retdest + SWAP1 + %increment + %endrep + // stack: node_payload_ptr', storage_ptr_ptr', retdest + %stack (node_payload_ptr, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) + JUMP + +set_payload_extension: + // stack: node_type, node_payload_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest + POP + // stack: node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %add_const(2) %mload_trie_data + // stack: child_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest + %jump(mpt_set_payload) + +set_payload_leaf: + // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + POP + // stack: node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + DUP1 %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. + MLOAD_GENERAL + // stack value_ptr, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %add_const(2) %mload_trie_data // storage_root_ptr = value[2] + // stack storage_root_ptr, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %stack + (storage_root_ptr, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr) -> + (storage_root_ptr, storage_ptr_ptr, after_set_storage_payload, node_payload_ptr, account_ptr_ptr) + %jump(mpt_set_storage_payload) +after_set_storage_payload: + // stack: storage_ptr_ptr', node_payload_ptr, account_ptr_ptr, retdest + SWAP2 SWAP1 + + %add_const(2) + DUP2 + MSTORE_GENERAL + // stack: account_ptr_ptr, storage_ptr_ptr', retdest + %add_const(5) // The next pointer is at distance 4 + // stack: payload_ptr_ptr', storage_ptr_ptr', retdest + SWAP1 + SWAP2 + JUMP + +set_payload_storage_leaf: + // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest + POP + // stack: node_payload_ptr, storage_ptr_ptr, retdest + %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. + DUP2 + MSTORE_GENERAL + // stack: storage_ptr_ptr, retdest + %add_const(5) // The next pointer is at distance 5 + // stack: storage_ptr_ptr', retdest + SWAP1 + JUMP \ No newline at end of file From 1232b9af12119422ba020da1e62ca25ce7c45ada Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 4 Jun 2024 19:35:12 +0800 Subject: [PATCH 029/118] Update slot and account search methods in linked_lists and update revert_storage_change --- .../cpu/kernel/asm/journal/storage_change.asm | 27 +++++++++++++++++-- .../src/cpu/kernel/asm/mpt/linked_list.asm | 23 +++++++++++----- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm index 752674d1e..e162db2b4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm @@ -4,7 +4,7 @@ %journal_add_3(@JOURNAL_ENTRY_STORAGE_CHANGE) %endmacro -global revert_storage_change: +global revert_storage_change_original: // stack: entry_type, ptr, retdest POP %journal_load_3 @@ -27,7 +27,21 @@ global revert_storage_change: (storage_root_ptr, num_nibbles, storage_key, prev_value_ptr, new_storage_root, address, retdest) %jump(mpt_insert) -delete: +global revert_storage_change: + // stack: entry_type, ptr, retdest + POP + %journal_load_3 + // stack: address, slot, prev_value, retdest + DUP3 ISZERO %jumpi(delete) + // stack: address, slot, prev_value, retdest + %read_slot_linked_list + // stack: storage_found, cold_access, value_ptr, prev_value, retdest + %assert_eq_const(1) POP + // stack: value_ptr, prev_value, retdest + %mstore_trie_data + JUMP + +delete_original: // stack: address, slot, prev_value, retdest SWAP2 POP %stack (slot, address, retdest) -> (slot, new_storage_root, address, retdest) @@ -44,6 +58,15 @@ delete: // stack: storage_root_ptr, 64, storage_key, new_storage_root, address, retdest %jump(mpt_delete) +delete: + // stack: address, slot, prev_value, retdest + SWAP2 POP + // stack: slot, address, retdest + %slot_to_storage_key + SWAP1 %addr_to_state_key + // stack: addr_key, slot_key, retdest + %jump(remove_slot) + new_storage_root: // stack: new_storage_root_ptr, address, retdest DUP2 %mpt_read_state_trie diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 6b79965a9..b982527b0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -226,6 +226,7 @@ global debug_before_jump: /// - `cold_access` indicates whether the current access is a cold access (so whether the account was ever accessed before) /// - `payload_ptr` is a pointer to the account's payload. global search_account: + // addr is the key here // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr, payload_ptr, retdest @@ -413,7 +414,7 @@ slot_found: // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest // If access_ctr == 1 then this it's a cold access %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, 1, cold_access, orig_payload_ptr) JUMP global debug_insert_new_slot: @@ -516,7 +517,7 @@ global debug_mload_6: // TODO: Not sure if this is correct, bc if a value is not found we need to return 0 but keep track of it for // having the right cold_access global search_slot: - // stack: addr, payload_ptr, retdest + // stack: addr, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) // stack: pred_ptr/5, addr, key, payload_ptr, retdest %get_valid_slot_ptr @@ -564,9 +565,7 @@ global search_slot: slot_not_found: // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest %pop4 - SWAP1 - PUSH 1 - SWAP1 + %stack (payload_ptr, retdest) -> (retdest, 0, 1, payload_ptr) JUMP @@ -632,8 +631,18 @@ global remove_slot: %stack (addr, key) -> (addr, key, 0, %%after) %jump(search_slot) %%after: - // stack: cold_access, value_ptr, slot_ptr - POP + // stack: storage_found, cold_access, value_ptr, slot_ptr + SWAP1 POP +%endmacro + +%macro read_slot_linked_list + // stack: address, slot + %addr_to_state_key + SWAP1 %slot_to_storage_key + %stack (slot_key, addr_key) -> (addr_key, slot_key, 0 %%after) + %jump(search_slot) +%%after: + // stack: storage_found, cold_access, value_ptr, slot_ptr %endmacro /// Search the account addr and payload pointer into the linked list. From 5d43ff4d6e6f7b3b83c2b4794295074fde766d69 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Wed, 5 Jun 2024 09:46:00 +0800 Subject: [PATCH 030/118] Fix asm --- evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index b982527b0..467a5b718 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -639,12 +639,8 @@ global remove_slot: // stack: address, slot %addr_to_state_key SWAP1 %slot_to_storage_key - %stack (slot_key, addr_key) -> (addr_key, slot_key, 0 %%after) + %stack (slot_key, addr_key) -> (addr_key, slot_key, 0, %%after) %jump(search_slot) %%after: // stack: storage_found, cold_access, value_ptr, slot_ptr %endmacro - -/// Search the account addr and payload pointer into the linked list. -/// Return `1, payload_ptr` if the account was inserted, `0, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. \ No newline at end of file From bd1215d39c1ee1ec168d57fe6a3916ab6a92cb0a Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 7 Jun 2024 10:10:38 +0800 Subject: [PATCH 031/118] Some fixes and debugging --- .../RevertOpcodeReturn_d5g0v0_Shanghai.json | 1665 +++++++++++ ...recompiledTouch_nonce_d0g0v0_Shanghai.json | 2597 +++++++++++++++++ ...hToEmptyAccountRevert_d0g0v0_Shanghai.json | 919 ++++++ .../src/cpu/kernel/asm/mpt/linked_list.asm | 2 +- .../kernel/asm/mpt/storage/storage_read.asm | 1 + .../src/cpu/kernel/interpreter.rs | 14 +- .../src/cpu/kernel/tests/account_code.rs | 6 + .../src/cpu/kernel/tests/add11.rs | 7 + evm_arithmetization/tests/add11_yml.rs | 5 +- 9 files changed, 5211 insertions(+), 5 deletions(-) create mode 100644 evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json create mode 100644 evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json create mode 100644 evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json diff --git a/evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json b/evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json new file mode 100644 index 000000000..42e20cd82 --- /dev/null +++ b/evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json @@ -0,0 +1,1665 @@ +{ + "txn_number_before": "0x0", + "gas_used_before": "0x0", + "gas_used_after": "0xc47f", + "signed_txn": [ + 248, + 128, + 128, + 10, + 131, + 12, + 53, + 0, + 148, + 160, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 128, + 160, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 166, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 27, + 160, + 97, + 145, + 39, + 137, + 40, + 226, + 6, + 123, + 99, + 190, + 156, + 203, + 125, + 224, + 240, + 146, + 148, + 148, + 14, + 215, + 23, + 249, + 230, + 222, + 139, + 224, + 1, + 119, + 92, + 87, + 205, + 42, + 160, + 70, + 2, + 193, + 98, + 140, + 130, + 135, + 18, + 187, + 237, + 75, + 2, + 254, + 199, + 39, + 29, + 79, + 99, + 15, + 183, + 49, + 48, + 182, + 174, + 14, + 49, + 207, + 204, + 24, + 110, + 143, + 67 + ], + "withdrawals": [], + "tries": { + "state_trie": { + "node": { + "Branch": { + "children": [ + { + "node": { + "Branch": { + "children": [ + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b" + }, + "value": [ + 248, + 73, + 128, + 133, + 232, + 212, + 165, + 16, + 0, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x75f0b26f88f770e01663ec33a25e55811909f7bd5dab82adfd887cbc08f20a" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 46, + 157, + 184, + 97, + 252, + 213, + 85, + 125, + 137, + 84, + 132, + 86, + 255, + 200, + 113, + 58, + 248, + 160, + 127, + 76, + 142, + 41, + 70, + 82, + 70, + 188, + 166, + 12, + 213, + 180, + 236, + 251 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + { + "node": { + "Branch": { + "children": [ + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0xf4ef70c3ea31780ddd533d1f46a7762f2bc3e6048a81904b62b8062b2c6d80" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 117, + 163, + 129, + 247, + 227, + 251, + 14, + 161, + 46, + 47, + 247, + 69, + 9, + 80, + 203, + 213, + 198, + 237, + 140, + 9, + 90, + 106, + 60, + 124, + 245, + 89, + 130, + 18, + 54, + 196, + 5, + 26 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0xe1c4c06eb7b427d20523ecb932e178aea42b4a45aa257839c4b37bae957de9" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 158, + 41, + 36, + 86, + 58, + 229, + 12, + 114, + 130, + 209, + 191, + 178, + 214, + 220, + 14, + 197, + 163, + 57, + 45, + 129, + 97, + 127, + 22, + 133, + 174, + 186, + 243, + 140, + 154, + 86, + 44, + 160 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0xe879e4e9f9faf2fbf45290292a78494b3b6fadacf3a7caadca41807c38b0335" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 79, + 240, + 66, + 127, + 37, + 76, + 40, + 99, + 166, + 17, + 46, + 133, + 19, + 7, + 96, + 75, + 161, + 208, + 56, + 22, + 13, + 50, + 33, + 113, + 147, + 3, + 101, + 197, + 15, + 0, + 86, + 117 + ] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0x3caabbefe324ab0bb367d394c5a23dac16c2345c81aa31c64df17b2d08f4923" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 166, + 64, + 93, + 42, + 27, + 0, + 87, + 147, + 160, + 244, + 226, + 18, + 198, + 94, + 126, + 7, + 186, + 111, + 72, + 254, + 7, + 79, + 223, + 213, + 8, + 90, + 79, + 40, + 46, + 234, + 44, + 168 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0xf2d5e7543485f45278e9b1f6a487feb4aec678d527e129b7aece8e583fe4f72" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 42, + 72, + 207, + 249, + 70, + 175, + 179, + 47, + 141, + 79, + 188, + 140, + 179, + 211, + 8, + 0, + 162, + 22, + 59, + 43, + 46, + 10, + 23, + 7, + 97, + 212, + 241, + 158, + 2, + 105, + 210, + 227 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0xa44ec1b61dc56f96d53050f431a760686e5993b54b75377ced5f391463d3221" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 140, + 59, + 155, + 157, + 144, + 153, + 113, + 135, + 171, + 27, + 158, + 202, + 251, + 199, + 164, + 5, + 70, + 195, + 82, + 251, + 239, + 175, + 83, + 4, + 47, + 197, + 35, + 9, + 192, + 148, + 53, + 56 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + "transactions_trie": { + "node": "Empty", + "hash": null + }, + "receipts_trie": { + "node": "Empty", + "hash": null + }, + "storage_tries": [ + [ + "0x03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x2e879e4e9f9faf2fbf45290292a78494b3b6fadacf3a7caadca41807c38b0335", + { + "node": "Empty", + "hash": null + } + ], + [ + "0xca44ec1b61dc56f96d53050f431a760686e5993b54b75377ced5f391463d3221", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x1ee1c4c06eb7b427d20523ecb932e178aea42b4a45aa257839c4b37bae957de9", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x0575f0b26f88f770e01663ec33a25e55811909f7bd5dab82adfd887cbc08f20a", + { + "node": "Empty", + "hash": null + } + ], + [ + "0xaf2d5e7543485f45278e9b1f6a487feb4aec678d527e129b7aece8e583fe4f72", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x33caabbefe324ab0bb367d394c5a23dac16c2345c81aa31c64df17b2d08f4923", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x14f4ef70c3ea31780ddd533d1f46a7762f2bc3e6048a81904b62b8062b2c6d80", + { + "node": "Empty", + "hash": null + } + ] + ] + }, + "trie_roots_after": { + "state_root": "0x39026113150402cf108f83cdf9e9c20b385b6cd2f40400736cb2b06e96235c3d", + "transactions_root": "0x7b87ed13feb0c9d9c5af9a834c70404fe6ab32c193c8def8266079108b2fb74d", + "receipts_root": "0xcabd56ba2ce6a126085d2f765c183bcea25b6cab61c78645368fde791b9067fa" + }, + "checkpoint_state_trie_root": "0xc0a86da777f09fac0d7c321cbd5c32425b7ced34a5fd3efb6d55dbe13bce5120", + "contract_code": { + "0x75a381f7e3fb0ea12e2ff7450950cbd5c6ed8c095a6a3c7cf559821236c4051a": [ + 108, + 114, + 101, + 118, + 101, + 114, + 116, + 101, + 100, + 32, + 100, + 97, + 116, + 97, + 96, + 0, + 85, + 109, + 114, + 101, + 118, + 101, + 114, + 116, + 32, + 109, + 101, + 115, + 115, + 97, + 103, + 101, + 96, + 0, + 82, + 96, + 0, + 110, + 15, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 253, + 0 + ], + "0x4ff0427f254c2863a6112e851307604ba1d038160d322171930365c50f005675": [ + 108, + 114, + 101, + 118, + 101, + 114, + 116, + 101, + 100, + 32, + 100, + 97, + 116, + 97, + 96, + 0, + 85, + 109, + 114, + 101, + 118, + 101, + 114, + 116, + 32, + 109, + 101, + 115, + 115, + 97, + 103, + 101, + 96, + 0, + 82, + 96, + 0, + 96, + 0, + 253, + 0 + ], + "0xa6405d2a1b005793a0f4e212c65e7e07ba6f48fe074fdfd5085a4f282eea2ca8": [ + 108, + 114, + 101, + 118, + 101, + 114, + 116, + 101, + 100, + 32, + 100, + 97, + 116, + 97, + 96, + 0, + 85, + 109, + 114, + 101, + 118, + 101, + 114, + 116, + 32, + 109, + 101, + 115, + 115, + 97, + 103, + 101, + 96, + 0, + 82, + 96, + 32, + 96, + 0, + 253, + 0 + ], + "0x2e9db861fcd5557d89548456ffc8713af8a07f4c8e29465246bca60cd5b4ecfb": [ + 96, + 32, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 53, + 98, + 2, + 73, + 240, + 241, + 96, + 1, + 85, + 96, + 0, + 81, + 96, + 2, + 85, + 0 + ], + "0x2a48cff946afb32f8d4fbc8cb3d30800a2163b2b2e0a170761d4f19e0269d2e3": [ + 108, + 114, + 101, + 118, + 101, + 114, + 116, + 101, + 100, + 32, + 100, + 97, + 116, + 97, + 96, + 0, + 85, + 109, + 114, + 101, + 118, + 101, + 114, + 116, + 32, + 109, + 101, + 115, + 115, + 97, + 103, + 101, + 96, + 0, + 82, + 110, + 15, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 255, + 96, + 0, + 253, + 0 + ], + "0x9e2924563ae50c7282d1bfb2d6dc0ec5a3392d81617f1685aebaf38c9a562ca0": [ + 108, + 114, + 101, + 118, + 101, + 114, + 116, + 101, + 100, + 32, + 100, + 97, + 116, + 97, + 96, + 0, + 85, + 109, + 114, + 101, + 118, + 101, + 114, + 116, + 32, + 109, + 101, + 115, + 115, + 97, + 103, + 101, + 96, + 0, + 82, + 96, + 0, + 97, + 1, + 0, + 253, + 0 + ], + "0x8c3b9b9d90997187ab1b9ecafbc7a40546c352fbefaf53042fc52309c0943538": [ + 108, + 114, + 101, + 118, + 101, + 114, + 116, + 101, + 100, + 32, + 100, + 97, + 116, + 97, + 96, + 0, + 85, + 109, + 114, + 101, + 118, + 101, + 114, + 116, + 32, + 109, + 101, + 115, + 115, + 97, + 103, + 101, + 96, + 0, + 82, + 96, + 0, + 96, + 1, + 253, + 0 + ], + "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470": [] + }, + "block_metadata": { + "block_beneficiary": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "block_timestamp": "0x3e8", + "block_number": "0x1", + "block_difficulty": "0x0", + "block_random": "0x0000000000000000000000000000000000000000000000000000000000020000", + "block_gaslimit": "0x989680", + "block_chain_id": "0x1", + "block_base_fee": "0xa", + "block_gas_used": "0xc47f", + "block_bloom": [ + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0" + ] + }, + "block_hashes": { + "prev_hashes": [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "cur_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } +} \ No newline at end of file diff --git a/evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json b/evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json new file mode 100644 index 000000000..aa4f33d79 --- /dev/null +++ b/evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json @@ -0,0 +1,2597 @@ +{ + "txn_number_before": "0x0", + "gas_used_before": "0x0", + "gas_used_after": "0x181f9", + "signed_txn": [ + 248, + 128, + 1, + 10, + 131, + 1, + 134, + 160, + 148, + 185, + 79, + 83, + 116, + 252, + 229, + 237, + 188, + 142, + 42, + 134, + 151, + 193, + 83, + 49, + 103, + 126, + 110, + 191, + 11, + 128, + 160, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 28, + 160, + 39, + 163, + 198, + 206, + 58, + 195, + 37, + 170, + 219, + 26, + 211, + 132, + 63, + 131, + 105, + 140, + 172, + 250, + 122, + 132, + 233, + 138, + 140, + 80, + 221, + 146, + 0, + 59, + 244, + 35, + 195, + 219, + 160, + 77, + 207, + 249, + 221, + 19, + 184, + 124, + 9, + 5, + 249, + 187, + 65, + 87, + 116, + 63, + 200, + 142, + 253, + 1, + 15, + 253, + 5, + 150, + 207, + 122, + 90, + 122, + 112, + 109, + 138, + 76, + 39 + ], + "withdrawals": [], + "tries": { + "state_trie": { + "node": { + "Branch": { + "children": [ + { + "node": { + "Branch": { + "children": [ + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b" + }, + "value": [ + 248, + 76, + 1, + 136, + 13, + 224, + 182, + 179, + 167, + 100, + 0, + 0, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x97a8ae1be85d5cb9bf7eabf07bf2b5aefb0b4e89cb4e138147f6a841ad22c0" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 209, + 134, + 10, + 175, + 222, + 137, + 33, + 140, + 185, + 0, + 0, + 231, + 29, + 6, + 215, + 5, + 173, + 174, + 97, + 243, + 106, + 255, + 1, + 115, + 112, + 27, + 115, + 120, + 112, + 242, + 50, + 247 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0x468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Branch": { + "children": [ + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x1df1fa259221d02aa4956eb0d35ace318ca24c0a33a64c1af96cf67cf245b6" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x1703c5eda8644a64cec152c58f5aacec93d72fb0bfa705f0473f9043a8357c" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x38f86bb73787385f15c8c5e9b870cb8011b5bfb4ffce95207317bce6193fcb" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 223, + 194, + 50, + 238, + 5, + 13, + 83, + 147, + 20, + 172, + 208, + 19, + 240, + 219, + 13, + 172, + 245, + 47, + 70, + 25, + 78, + 63, + 225, + 9, + 42, + 1, + 163, + 30, + 144, + 98, + 95, + 57 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0xb70e80538acdabd6137353b0f9d8d149f4dba91e8be2e7946e409bfdbe685b9" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0x89802d6ed1a28b049e9d4fe5334c5902fd9bc00c42821c82f82ee2da10be908" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Branch": { + "children": [ + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x3ab0970b73895b8c9959bae685c3a19f45eb5ad89d42b52a340ec4ac204d19" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0xfad888a2f79bcfe6633c369a5652e94379f63f5849d8e8fe519c586bb49633" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 204, + 8, + 96, + 247, + 209, + 100, + 9, + 104, + 167, + 16, + 166, + 84, + 71, + 3, + 225, + 110, + 135, + 211, + 243, + 27, + 187, + 69, + 131, + 14, + 139, + 239, + 97, + 87, + 11, + 169, + 110, + 245 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0x876da518a393dbd067dc72abfa08d475ed6447fca96d92ec3f9e7eba503ca61" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Branch": { + "children": [ + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0xc30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 144, + 180, + 176, + 252, + 26, + 173, + 212, + 27, + 37, + 52, + 240, + 180, + 27, + 190, + 115, + 62, + 6, + 178, + 7, + 106, + 117, + 141, + 115, + 25, + 174, + 231, + 110, + 21, + 154, + 250, + 125, + 238 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 62, + "packed": "0x2688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62" + }, + "value": [ + 248, + 68, + 1, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0xe51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 139, + 200, + 165, + 23, + 242, + 254, + 139, + 247, + 239, + 111, + 77, + 55, + 66, + 199, + 107, + 246, + 84, + 182, + 176, + 183, + 159, + 232, + 222, + 22, + 156, + 195, + 182, + 203, + 153, + 223, + 111, + 206 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + "transactions_trie": { + "node": "Empty", + "hash": null + }, + "receipts_trie": { + "node": "Empty", + "hash": null + }, + "storage_tries": [ + [ + "0x03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b", + { + "node": "Empty", + "hash": null + } + ], + [ + "0xd0c30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b", + { + "node": "Empty", + "hash": null + } + ], + [ + "0xee51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x0797a8ae1be85d5cb9bf7eabf07bf2b5aefb0b4e89cb4e138147f6a841ad22c0", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x5b70e80538acdabd6137353b0f9d8d149f4dba91e8be2e7946e409bfdbe685b9", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x471703c5eda8644a64cec152c58f5aacec93d72fb0bfa705f0473f9043a8357c", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x421df1fa259221d02aa4956eb0d35ace318ca24c0a33a64c1af96cf67cf245b6", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x8dfad888a2f79bcfe6633c369a5652e94379f63f5849d8e8fe519c586bb49633", + { + "node": "Empty", + "hash": null + } + ], + [ + "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62", + { + "node": "Empty", + "hash": null + } + ], + [ + "0xa876da518a393dbd067dc72abfa08d475ed6447fca96d92ec3f9e7eba503ca61", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x689802d6ed1a28b049e9d4fe5334c5902fd9bc00c42821c82f82ee2da10be908", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x8c3ab0970b73895b8c9959bae685c3a19f45eb5ad89d42b52a340ec4ac204d19", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x4b38f86bb73787385f15c8c5e9b870cb8011b5bfb4ffce95207317bce6193fcb", + { + "node": "Empty", + "hash": null + } + ] + ] + }, + "trie_roots_after": { + "state_root": "0x0fc37c246046ade1d363dccec6ccd0ecd8bb8a7f9ce6cc8f3f4cfdce0aa00c2b", + "transactions_root": "0xf77c8817ce7d022d381d0ea642545b06c550b4d882cf2f86799585367ed0ded1", + "receipts_root": "0xaab2111847f2d64d9574f3a287dce44aec2164a59b6f2b766e7956f9a046631e" + }, + "checkpoint_state_trie_root": "0x0a1503e7df13898f4abb85e5baa9e54cc9232946b87ac39f9191945cf744585a", + "contract_code": { + "0x8bc8a517f2fe8bf7ef6f4d3742c76bf654b6b0b79fe8de169cc3b6cb99df6fce": [ + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 1, + 97, + 195, + 80, + 241, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 2, + 97, + 195, + 80, + 241, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 3, + 97, + 195, + 80, + 241, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 4, + 97, + 195, + 80, + 241, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 5, + 97, + 195, + 80, + 241, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 6, + 97, + 195, + 80, + 241, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 7, + 97, + 195, + 80, + 241, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 8, + 97, + 195, + 80, + 241, + 80, + 90, + 96, + 1, + 85, + 90, + 96, + 2, + 85, + 90, + 96, + 3, + 85, + 0 + ], + "0x90b4b0fc1aadd41b2534f0b41bbe733e06b2076a758d7319aee76e159afa7dee": [ + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 53, + 90, + 242, + 0 + ], + "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470": [], + "0xcc0860f7d1640968a710a6544703e16e87d3f31bbb45830e8bef61570ba96ef5": [ + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 1, + 97, + 195, + 80, + 244, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 2, + 97, + 195, + 80, + 244, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 3, + 97, + 195, + 80, + 244, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 4, + 97, + 195, + 80, + 244, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 5, + 97, + 195, + 80, + 244, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 6, + 97, + 195, + 80, + 244, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 7, + 97, + 195, + 80, + 244, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 8, + 97, + 195, + 80, + 244, + 80, + 90, + 96, + 1, + 85, + 90, + 96, + 2, + 85, + 90, + 96, + 3, + 85, + 0 + ], + "0xdfc232ee050d539314acd013f0db0dacf52f46194e3fe1092a01a31e90625f39": [ + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 1, + 97, + 195, + 80, + 242, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 2, + 97, + 195, + 80, + 242, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 3, + 97, + 195, + 80, + 242, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 4, + 97, + 195, + 80, + 242, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 5, + 97, + 195, + 80, + 242, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 6, + 97, + 195, + 80, + 242, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 7, + 97, + 195, + 80, + 242, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 8, + 97, + 195, + 80, + 242, + 80, + 90, + 96, + 1, + 85, + 90, + 96, + 2, + 85, + 90, + 96, + 3, + 85, + 0 + ], + "0xd1860aafde89218cb90000e71d06d705adae61f36aff0173701b737870f232f7": [ + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 1, + 97, + 195, + 80, + 250, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 2, + 97, + 195, + 80, + 250, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 3, + 97, + 195, + 80, + 250, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 4, + 97, + 195, + 80, + 250, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 5, + 97, + 195, + 80, + 250, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 6, + 97, + 195, + 80, + 250, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 7, + 97, + 195, + 80, + 250, + 80, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 8, + 97, + 195, + 80, + 250, + 80, + 90, + 96, + 1, + 85, + 90, + 96, + 2, + 85, + 90, + 96, + 3, + 85, + 0 + ] + }, + "block_metadata": { + "block_beneficiary": "0x68795c4aa09d6f4ed3e5deddf8c2ad3049a601da", + "block_timestamp": "0x3e8", + "block_number": "0x1", + "block_difficulty": "0x0", + "block_random": "0x0000000000000000000000000000000000000000000000000000000000020000", + "block_gaslimit": "0x3d37ef", + "block_chain_id": "0x1", + "block_base_fee": "0xa", + "block_gas_used": "0x181f9", + "block_bloom": [ + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0" + ] + }, + "block_hashes": { + "prev_hashes": [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "cur_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } +} diff --git a/evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json b/evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json new file mode 100644 index 000000000..208c61413 --- /dev/null +++ b/evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json @@ -0,0 +1,919 @@ +{ + "txn_number_before": "0x0", + "gas_used_before": "0x0", + "gas_used_after": "0x11170", + "signed_txn": [ + 248, + 96, + 128, + 10, + 131, + 1, + 17, + 112, + 148, + 185, + 79, + 83, + 116, + 252, + 229, + 237, + 188, + 142, + 42, + 134, + 151, + 193, + 83, + 49, + 103, + 126, + 110, + 191, + 11, + 128, + 128, + 27, + 160, + 234, + 33, + 187, + 131, + 142, + 200, + 27, + 241, + 114, + 60, + 209, + 202, + 196, + 203, + 137, + 102, + 148, + 118, + 26, + 84, + 141, + 156, + 88, + 49, + 188, + 99, + 72, + 171, + 253, + 26, + 107, + 78, + 160, + 93, + 82, + 87, + 160, + 215, + 167, + 188, + 28, + 157, + 80, + 255, + 2, + 72, + 129, + 118, + 143, + 105, + 220, + 94, + 101, + 127, + 83, + 235, + 54, + 212, + 177, + 133, + 26, + 218, + 72, + 52, + 124 + ], + "withdrawals": [], + "tries": { + "state_trie": { + "node": { + "Branch": { + "children": [ + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0x3601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b" + }, + "value": [ + 248, + 73, + 128, + 133, + 232, + 212, + 165, + 16, + 0, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0x320ca9fbb7bc02ec98c352627dc8fbe89a00c1e6c0b19c60e9234718b2bc149" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 102, + 221, + 57, + 212, + 200, + 246, + 26, + 95, + 240, + 178, + 222, + 92, + 239, + 39, + 239, + 185, + 37, + 163, + 117, + 214, + 178, + 248, + 170, + 25, + 29, + 73, + 228, + 237, + 84, + 92, + 8, + 222 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": "Empty", + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0xc30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 220, + 36, + 63, + 39, + 89, + 23, + 47, + 152, + 149, + 30, + 41, + 211, + 83, + 224, + 114, + 132, + 76, + 34, + 8, + 142, + 17, + 42, + 58, + 164, + 230, + 187, + 192, + 54, + 24, + 7, + 211, + 152 + ] + } + }, + "hash": null + }, + { + "node": { + "Leaf": { + "nibbles": { + "count": 63, + "packed": "0xe51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a" + }, + "value": [ + 248, + 68, + 128, + 128, + 160, + 86, + 232, + 31, + 23, + 27, + 204, + 85, + 166, + 255, + 131, + 69, + 230, + 146, + 192, + 248, + 110, + 91, + 72, + 224, + 27, + 153, + 108, + 173, + 192, + 1, + 98, + 47, + 181, + 227, + 99, + 180, + 33, + 160, + 197, + 210, + 70, + 1, + 134, + 247, + 35, + 60, + 146, + 126, + 125, + 178, + 220, + 199, + 3, + 192, + 229, + 0, + 182, + 83, + 202, + 130, + 39, + 59, + 123, + 250, + 216, + 4, + 93, + 133, + 164, + 112 + ] + } + }, + "hash": null + }, + { + "node": "Empty", + "hash": null + } + ], + "value": [] + } + }, + "hash": null + }, + "transactions_trie": { + "node": "Empty", + "hash": null + }, + "receipts_trie": { + "node": "Empty", + "hash": null + }, + "storage_tries": [ + [ + "0xd0c30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b", + { + "node": "Empty", + "hash": null + } + ], + [ + "0xee51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a", + { + "node": "Empty", + "hash": null + } + ], + [ + "0x8320ca9fbb7bc02ec98c352627dc8fbe89a00c1e6c0b19c60e9234718b2bc149", + { + "node": "Empty", + "hash": null + } + ] + ] + }, + "trie_roots_after": { + "state_root": "0x8df6db58f0f048ccb2b8f034a21ee10846f63983128645b2b710413c260b1f9d", + "transactions_root": "0x4516e33b9d8f2afc0a088da8f64734624303147f14a037f577d2c3f4ba7a22bb", + "receipts_root": "0x33206fdb0b04af73aed5fcc49c377894a2ad7acc74a06782884999e9c75de4ba" + }, + "checkpoint_state_trie_root": "0xa56f414cf08a51a2df93dadb4832e894a0e3c134eb2745b16c481f740c0ecb36", + "contract_code": { + "0x66dd39d4c8f61a5ff0b2de5cef27efb925a375d6b2f8aa191d49e4ed545c08de": [ + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 115, + 16, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 97, + 117, + 48, + 241, + 96, + 1, + 85, + 0 + ], + "0xdc243f2759172f98951e29d353e072844c22088e112a3aa4e6bbc0361807d398": [ + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 96, + 0, + 115, + 201, + 79, + 83, + 116, + 252, + 229, + 237, + 188, + 142, + 42, + 134, + 151, + 193, + 83, + 49, + 103, + 126, + 110, + 191, + 11, + 97, + 117, + 48, + 241, + 96, + 0, + 85, + 96, + 1, + 96, + 2, + 85, + 0 + ], + "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470": [] + }, + "block_metadata": { + "block_beneficiary": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "block_timestamp": "0x3e8", + "block_number": "0x1", + "block_difficulty": "0x0", + "block_random": "0x0000000000000000000000000000000000000000000000000000000000020000", + "block_gaslimit": "0x989680", + "block_chain_id": "0x1", + "block_base_fee": "0xa", + "block_gas_used": "0x11170", + "block_bloom": [ + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0", + "0x0" + ] + }, + "block_hashes": { + "prev_hashes": [ + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000" + ], + "cur_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } +} diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm index 467a5b718..ac8da983a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list.asm @@ -631,7 +631,7 @@ global remove_slot: %stack (addr, key) -> (addr, key, 0, %%after) %jump(search_slot) %%after: - // stack: storage_found, cold_access, value_ptr, slot_ptr + // stack: storage_found, cold_access, value_ptr SWAP1 POP %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index 1e6759027..189f4031f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -10,6 +10,7 @@ global sload_current: DUP1 global debug_the_slot: %read_storage_linked_list + POP // the first element is `is_found` global debug_after_read_linked_list: %mload_trie_data global debug_read_val: diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index e36cd2579..c7b1ddfe5 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -19,7 +19,7 @@ use crate::cpu::columns::CpuColumnsView; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::generation::debug_inputs; -use crate::generation::mpt::load_all_mpts; +use crate::generation::mpt::{load_all_mpts, load_linked_lists_and_txn_and_receipt_mpts}; use crate::generation::rlp::all_rlp_prover_inputs_reversed; use crate::generation::state::{ all_withdrawals_prover_inputs_reversed, GenerationState, GenerationStateCheckpoint, @@ -159,8 +159,16 @@ impl Interpreter { self.generation_state.inputs = inputs.clone(); // Initialize the MPT's pointers. - let (trie_root_ptrs, trie_data) = - load_all_mpts(tries).expect("Invalid MPT data for preinitialization"); + let (trie_root_ptrs, state_leaves, storage_leaves, trie_data) = + load_linked_lists_and_txn_and_receipt_mpts(&inputs.tries) + .expect("Invalid MPT data for preinitialization"); + + self.generation_state.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] + .content = state_leaves.iter().map(|&val| Some(val)).collect(); + self.generation_state.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] + .content = storage_leaves.iter().map(|&val| Some(val)).collect(); + self.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()].content = + trie_data.iter().map(|&val| Some(val)).collect(); let trie_roots_after = &inputs.trie_roots_after; self.generation_state.trie_root_ptrs = trie_root_ptrs; diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index 150b6ad0a..b40f0a01b 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use anyhow::Result; +use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{Address, BigEndianHash, H256, U256}; use hex_literal::hex; use keccak_hash::keccak; @@ -271,6 +272,7 @@ fn prepare_interpreter_all_accounts( addr: [u8; 20], code: &[u8], ) -> Result<()> { + init_logger(); // Load all MPTs. initialize_mpts(interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); @@ -494,3 +496,7 @@ fn sload() -> Result<()> { assert_eq!(hash, expected_state_trie_hash); Ok(()) } + +fn init_logger() { + let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); +} diff --git a/evm_arithmetization/src/cpu/kernel/tests/add11.rs b/evm_arithmetization/src/cpu/kernel/tests/add11.rs index c2be6a0bd..c8384261d 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/add11.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/add11.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::str::FromStr; +use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{Address, BigEndianHash, H256}; use hex_literal::hex; use keccak_hash::keccak; @@ -165,6 +166,8 @@ fn test_add11_yml() { #[test] fn test_add11_yml_with_exception() { + init_logger(); + // In this test, we make sure that the user code throws a stack underflow // exception. let beneficiary = hex!("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"); @@ -305,3 +308,7 @@ fn test_add11_yml_with_exception() { .run() .expect("Proving add11 with exception failed."); } + +fn init_logger() { + let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); +} diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 00d7e56b4..8c60af18b 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -148,7 +148,7 @@ fn add11_yml() -> anyhow::Result<()> { transactions_root: transactions_trie.hash(), receipts_root: receipts_trie.hash(), }; - let inputs = GenerationInputs { + let _inputs = GenerationInputs { signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, @@ -165,6 +165,9 @@ fn add11_yml() -> anyhow::Result<()> { }, }; + let bytes = std::fs::read("./TouchToEmptyAccountRevert_d0g0v0_Shanghai.json").unwrap(); + let inputs = serde_json::from_slice(&bytes).unwrap(); + let mut timing = TimingTree::new("prove", log::Level::Debug); let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; timing.filter(Duration::from_millis(100)).print(); From c4f410da9c33f190c4732383825dafa4409d7548 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Fri, 7 Jun 2024 10:39:42 +0200 Subject: [PATCH 032/118] Fix hash mismatch --- .../src/cpu/kernel/aggregator.rs | 3 +- .../src/cpu/kernel/asm/core/access_lists.asm | 5 - .../src/cpu/kernel/asm/core/transfer.asm | 1 - .../src/cpu/kernel/asm/main.asm | 11 +- .../asm/mpt/insert/insert_trie_specific.asm | 2 - .../asm/mpt/linked_list/linked_list.asm | 15 -- .../asm/mpt/linked_list/mpt_set_payload.asm | 167 ++++++++++++++++++ .../kernel/asm/mpt/linked_list/set_leaves.asm | 137 -------------- .../src/cpu/kernel/asm/mpt/read.asm | 3 - .../kernel/asm/mpt/storage/storage_read.asm | 6 - .../src/cpu/kernel/tests/mpt/linked_list.rs | 3 - evm_arithmetization/src/generation/mpt.rs | 15 -- .../src/generation/prover_input.rs | 45 +---- evm_arithmetization/src/generation/state.rs | 1 + 14 files changed, 181 insertions(+), 233 deletions(-) create mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm delete mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm diff --git a/evm_arithmetization/src/cpu/kernel/aggregator.rs b/evm_arithmetization/src/cpu/kernel/aggregator.rs index 8c5439cf1..7fbafa02b 100644 --- a/evm_arithmetization/src/cpu/kernel/aggregator.rs +++ b/evm_arithmetization/src/cpu/kernel/aggregator.rs @@ -122,7 +122,8 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/mpt/insert/insert_extension.asm"), include_str!("asm/mpt/insert/insert_leaf.asm"), include_str!("asm/mpt/insert/insert_trie_specific.asm"), - include_str!("asm/mpt/linked_list.asm"), + include_str!("asm/mpt/linked_list/linked_list.asm"), + include_str!("asm/mpt/linked_list/mpt_set_payload.asm"), include_str!("asm/mpt/read.asm"), include_str!("asm/mpt/storage/storage_read.asm"), include_str!("asm/mpt/storage/storage_write.asm"), diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm index a500db8be..b88502baf 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm @@ -234,7 +234,6 @@ global insert_accessed_storage_keys: DUP4 GT DUP3 %eq_const(@SEGMENT_ACCESSED_STORAGE_KEYS) ADD // OR -global debug_before_jumpi1: %jumpi(insert_storage_key) // stack: pred_addr, pred_ptr, addr, key, retdest // We know that addr <= pred_addr. It must hold that pred_addr == addr. @@ -248,14 +247,11 @@ global debug_before_jumpi1: DUP1 DUP5 GT // stack: key > pred_key, pred_key, pred_ptr, addr, key, retdest -global debug_before_jumpi2: %jumpi(insert_storage_key) // stack: pred_key, pred_ptr, addr, key, retdest DUP4 // We know that key <= pred_key. It must hold that pred_key == key. -global debug_before_son_eaugles: %assert_eq -global debug_lo_son: // stack: pred_ptr, addr, key, retdest // Check that this is not a deleted node DUP1 @@ -265,7 +261,6 @@ global debug_lo_son: // The storage key is not in the list. PANIC -global debug_key_found: storage_key_found: // The address was already in the list // stack: pred_ptr, addr, key, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm index 0d0b7b754..0517cf3a8 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/transfer.asm @@ -66,7 +66,6 @@ global add_eth: // stack: addr, amount, retdest DUP1 %insert_touched_addresses DUP1 %mpt_read_state_trie -global debug_is_not_arriving_here: // stack: account_ptr, addr, amount, retdest DUP1 ISZERO %jumpi(add_eth_new_account) // If the account pointer is null, we need to create the account. %add_const(1) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 1449834a0..25ed906c5 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -36,7 +36,16 @@ global hash_initial_tries: // can check the value provided by the prover. // The trie data segment is already written by the linked lists %mload_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) %assert_eq + %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) +global debug_check_hash: + %assert_eq + + %mpt_set_payload_no_return + %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) + global debug_check_hash_after_setting_payloads: + %assert_eq + + // stack: trie_data_len %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_len diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm index 5508d6dc2..8d84e6774 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm @@ -7,9 +7,7 @@ global mpt_insert_state_trie: // stack: key, value_ptr, retdest DUP2 DUP2 -global debug_before_insert_account_no_return: %insert_account_no_return -global debug_account_inserted: %stack (key, value_ptr) -> (key, value_ptr, mpt_insert_state_trie_save) PUSH 64 // num_nibbles diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 5e8313d75..0f2cdd07c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -204,7 +204,6 @@ insert_new_account: PUSH 0 SWAP1 SWAP2 -global debug_before_jump: JUMP %macro search_account @@ -340,13 +339,10 @@ global insert_slot: PROVER_INPUT(linked_list::insert_slot) // stack: pred_ptr/5, addr, key, payload_ptr, retdest %get_valid_slot_ptr -global debug_the_ptr: // stack: pred_ptr, addr, key, payload_ptr, retdest DUP1 -global debug_before_mload: MLOAD_GENERAL -global debug_after_mload: DUP1 // stack: pred_addr, pred_addr, pred_ptr, addr, key, payload_ptr, retdest DUP4 @@ -357,12 +353,10 @@ global debug_after_mload: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(insert_new_slot) -global debug_after_first_jumpi: // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq -global debug_after_assert_eq: // stack: pred_ptr, addr, key, payload_ptr, retdest DUP1 %increment @@ -411,17 +405,14 @@ slot_found: %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP -global debug_insert_new_slot: insert_new_slot: // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest POP // get the value of the next address %add_const(4) -global debug_next_ptr_ptr: // stack: next_ptr_ptr, addr, key, payload_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 -global debug_mload_1: MLOAD_GENERAL // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest // Check that this is not a deleted node @@ -429,7 +420,6 @@ global debug_mload_1: %eq_const(@U256_MAX) %assert_zero DUP1 - global debug_mload_2: MLOAD_GENERAL // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 @@ -445,7 +435,6 @@ global debug_mload_1: // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 %increment -global debug_mload_3: MLOAD_GENERAL // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest DUP1 // This is added just to have the correct stack in next_node_ok @@ -459,21 +448,17 @@ next_node_ok: SWAP2 DUP2 // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, key, payload_ptr, retdest -global debug_mstore_1: MSTORE_GENERAL -global debug_after_mstore_1: // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the address in the new node DUP1 DUP4 -global debug_mload_5: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the key in the new node %increment DUP1 DUP5 -global debug_mload_6: MSTORE_GENERAL // stack: new_ptr + 1, next_ptr, addr, key, payload_ptr, retdest // Store payload_ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm new file mode 100644 index 000000000..ddf78482c --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm @@ -0,0 +1,167 @@ +// Set the trie with root at `node_ptr` leaves +// payloads pointers to mem[payload_ptr_ptr] + step*i, for +// for i =0..n_leaves. This is used to constraint that the +// initial state and account tries payload pointers are exactly +// those of the inital accounts and linked lists +// Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest +// Post stack: account_ptr_ptr, storage_ptr_ptr +global mpt_set_payload: + // stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + DUP1 %mload_trie_data + // stack: node_type, node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // Increment node_ptr, so it points to the node payload instead of its type. + SWAP1 %increment SWAP1 + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + + DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(skip) + DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_branch) + DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) + DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) + +skip: + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + %stack (node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) + JUMP + +%macro mpt_set_payload + %stack(node_ptr, account_ptr_ptr, storage_ptr_ptr) -> (node_ptr, account_ptr_ptr, storage_ptr_ptr, %%after) + %jump(mpt_set_payload) +%%after: +%endmacro + +%macro mpt_set_payload_no_return + PUSH %%after + PUSH @SEGMENT_STORAGE_LINKED_LIST + %add_const(7) // The first node is the special node, of size 5, so the first payload is at position 5 + 2. + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + %add_const(5) // The first node is the special node, of size 4, so the first payload is at position 4 + 1. + %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + %jump(mpt_set_payload) +%%after: + %pop2 +%endmacro + +// Pre stack: node_ptr, account_ptr_ptr, retdest +// Post stack: storage_ptr_ptr +global mpt_set_storage_payload: + // stack: node_ptr, storage_ptr_ptr, retdest + DUP1 %mload_trie_data + // stack: node_type, node_ptr, storage_ptr_ptr, retdest + // Increment node_ptr, so it points to the node payload instead of its type. + SWAP1 %increment SWAP1 + // stack: node_type, after_node_type, storage_ptr_ptr, retdest + + DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(storage_skip) + DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_storage_branch) + DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) + DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_storage_leaf) + +storage_skip: + // stack: node_type, after_node_type, storage_ptr_ptr, retdest + %stack (node_type, after_node_type, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) + JUMP + +%macro mpt_set_storage_payload + %stack(node_ptr, storage_ptr_ptr) -> (node_ptr, storage_ptr_ptr, %%after) + %jump(mpt_set_payload) +%%after: +%endmacro + +global set_payload_branch: + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + POP + + // Call encode_or_hash_node on each child + %rep 16 + %stack + (after_node_type, account_ptr_ptr, storage_ptr_ptr) -> + (after_node_type, account_ptr_ptr, storage_ptr_ptr, after_node_type) + // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + %mload_trie_data + // stack: child_i_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_encode, after_node_type, retdest + %mpt_set_payload + // stack: account_ptr_ptr', storage_ptr_ptr', after_node_type, retdest + SWAP1 + SWAP2 + %increment + %endrep + // stack: after_node_type', account_ptr_ptr', storage_ptr_ptr', retdest + %stack (after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) + JUMP + +set_payload_storage_branch: + // stack: node_type, after_node_type, storage_ptr_ptr, retdest + POP + + // Call encode_or_hash_node on each child + %rep 16 + %stack + (after_node_type, storage_ptr_ptr) -> + (after_node_type, storage_ptr_ptr, after_node_type) + // stack: after_node_type, storage_ptr_ptr, retdest + %mload_trie_data + // stack: child_i_ptr, storage_ptr_ptr, %%after_encode, after_node_type, retdest + %mpt_set_storage_payload + // stack: storage_ptr_ptr', after_node_type, retdest + SWAP1 + %increment + %endrep + // stack: after_node_type', storage_ptr_ptr', retdest + %stack (after_node_type, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) + JUMP + +set_payload_extension: + // stack: node_type, after_node_type, (account_ptr_ptr,) storage_ptr_ptr, retdest + POP + // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + %add_const(2) %mload_trie_data + // stack: child_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest + %jump(mpt_set_payload) + +set_payload_leaf: + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + POP + %add_const(2) // The payload pointer starts at index 3, after num_nibbles and packed_nibbles. + DUP1 + // stack payload_ptr_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %mload_trie_data + // stack account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %add_const(2) + %mload_trie_data // storage_root_ptr = account[2] + // stack storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %stack + (storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> + (storage_root_ptr, storage_ptr_ptr, after_set_storage_payload, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) + %jump(mpt_set_storage_payload) +after_set_storage_payload: + // stack: storage_ptr_ptr', storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, retdest + DUP4 + MLOAD_GENERAL // load the next payload pointer in the linked list + DUP1 %add_const(2) // new_storage_root_ptr_ptr = payload_ptr[2] + // stack: new_storage_root_ptr_ptr, new_payload_ptr, storage_root_ptr, storage_ptr_ptr', payload_ptr_ptr, account_ptr_ptr, retdest + %stack + (new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> + (new_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) + %mstore_trie_data // The account in the linked list has no storage root so we need to manually set it. + %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. + // stack: account_ptr_ptr, storage_ptr_ptr', retdest + %add_const(4) // The next pointer is at distance 4 + // stack: payload_ptr_ptr', storage_ptr_ptr', retdest + SWAP1 + SWAP2 + JUMP + +set_payload_storage_leaf: + // stack: node_type, after_node_type, storage_ptr_ptr, retdest + POP + // stack: after_node_type, storage_ptr_ptr, retdest + %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. + DUP2 + MLOAD_GENERAL + SWAP1 + %mstore_trie_data + // stack: storage_ptr_ptr, retdest + %add_const(5) // The next pointer is at distance 5 + // stack: storage_ptr_ptr', retdest + SWAP1 + JUMP \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm deleted file mode 100644 index 2066cefa8..000000000 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_leaves.asm +++ /dev/null @@ -1,137 +0,0 @@ -// Set the trie with root at `node_ptr` leaves -// payloads pointers to mem[payload_ptr_ptr] + step*i, for -// for i =0..n_leaves. This is used to constraint that the -// initial state and account tries payload pointers are exactly -// those of the inital accounts and linked lists -// Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest -// Post stack: account_ptr_ptr, storage_ptr_ptr -global mpt_set_payload: - // stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - DUP1 %mload_trie_data - // stack: node_type, node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - // Increment node_ptr, so it points to the node payload instead of its type. - SWAP1 %increment SWAP1 - // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - - DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(skip) - DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_branch) - DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) - DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) - -skip: - // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %stack (node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) - JUMP - -// Pre stack: node_ptr, account_ptr_ptr, retdest -// Post stack: storage_ptr_ptr -global mpt_set_storage_payload: - // stack: node_ptr, storage_ptr_ptr, retdest - DUP1 %mload_trie_data - // stack: node_type, node_ptr, storage_ptr_ptr, retdest - // Increment node_ptr, so it points to the node payload instead of its type. - SWAP1 %increment SWAP1 - // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest - - DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(storage_skip) - DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_storage_branch) - DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) - DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_storage_leaf) - -storage_skip: - // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest - %stack (node_type, node_payload_ptr, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) - JUMP - -global set_payload_branch: - // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - POP - - // Call encode_or_hash_node on each child - %rep 16 - %stack - (node_payload_ptr, account_ptr_ptr, storage_ptr_ptr) -> - (node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_mpt_set_payload, node_payload_ptr) - // stack: node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %mload_trie_data - // stack: child_i_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_encode, node_payload_ptr, retdest - %jump(mpt_set_payload) - %%after_mpt_set_payload: - // stack: account_ptr_ptr', storage_ptr_ptr', node_payload_ptr, retdest - SWAP1 - SWAP2 - %increment - %endrep - // stack: node_payload_ptr', account_ptr_ptr', storage_ptr_ptr', retdest - %stack (node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) - JUMP - -global set_payload_storage_branch: - // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest - POP - - // Call encode_or_hash_node on each child - %rep 16 - %stack - (node_payload_ptr, storage_ptr_ptr) -> - (node_payload_ptr, storage_ptr_ptr, %%after_mpt_set_payload, node_payload_ptr) - // stack: node_payload_ptr, storage_ptr_ptr, retdest - %mload_trie_data - // stack: child_i_ptr, storage_ptr_ptr, %%after_encode, node_payload_ptr, retdest - %jump(mpt_set_payload) - %%after_mpt_set_payload: - // stack: storage_ptr_ptr', node_payload_ptr, retdest - SWAP1 - %increment - %endrep - // stack: node_payload_ptr', storage_ptr_ptr', retdest - %stack (node_payload_ptr, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) - JUMP - -set_payload_extension: - // stack: node_type, node_payload_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest - POP - // stack: node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %add_const(2) %mload_trie_data - // stack: child_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest - %jump(mpt_set_payload) - -set_payload_leaf: - // stack: node_type, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - POP - // stack: node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - DUP1 %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. - MLOAD_GENERAL - // stack value_ptr, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %add_const(2) %mload_trie_data // storage_root_ptr = value[2] - // stack storage_root_ptr, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %stack - (storage_root_ptr, node_payload_ptr, account_ptr_ptr, storage_ptr_ptr) -> - (storage_root_ptr, storage_ptr_ptr, after_set_storage_payload, node_payload_ptr, account_ptr_ptr) - %jump(mpt_set_storage_payload) -after_set_storage_payload: - // stack: storage_ptr_ptr', node_payload_ptr, account_ptr_ptr, retdest - SWAP2 SWAP1 - - %add_const(2) - DUP2 - MSTORE_GENERAL - // stack: account_ptr_ptr, storage_ptr_ptr', retdest - %add_const(5) // The next pointer is at distance 4 - // stack: payload_ptr_ptr', storage_ptr_ptr', retdest - SWAP1 - SWAP2 - JUMP - -set_payload_storage_leaf: - // stack: node_type, node_payload_ptr, storage_ptr_ptr, retdest - POP - // stack: node_payload_ptr, storage_ptr_ptr, retdest - %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. - DUP2 - MSTORE_GENERAL - // stack: storage_ptr_ptr, retdest - %add_const(5) // The next pointer is at distance 5 - // stack: storage_ptr_ptr', retdest - SWAP1 - JUMP \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 677e2899b..09bf84123 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -6,11 +6,8 @@ global mpt_read_state_trie_test: DUP1 %read_accounts_linked_list // stack: ll_addr, address, retdest -global debug_ll_addr: %add_const(3) -global debug_before_read_tre_data: %mload_trie_data -global debug_ll_code_hash: // stack: ll_code_hash, address, retdest SWAP1 %mpt_read_state_trie_original diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index 1e6759027..ead8d712c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -8,13 +8,9 @@ global sload_current: // TEST STORAGE linked list DUP1 -global debug_the_slot: %read_storage_linked_list -global debug_after_read_linked_list: %mload_trie_data -global debug_read_val: %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) -global debug_stack_after_debug_read_val: // %stack (slot) -> (slot, after_storage_read) @@ -33,8 +29,6 @@ global after_storage_read: // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. - -global debug_donde_que_salta: %stack (value_ptr, ll_value, retdest) -> (retdest, 0) //%stack (value_ptr, retdest) -> (retdest, 0) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index d3637a7bb..5ee5a67b6 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -278,7 +278,6 @@ fn test_insert_and_delete_accounts() -> Result<()> { let offset = Segment::AccountsLinkedList as usize; // Insert all addresses for i in 0..n { - log::debug!("checking {i}-th insertion"); let addr = U256::from(addresses[i as usize].0.as_slice()); interpreter.push(0xdeadbeefu32.into()); interpreter.push(addr + delta_ptr); // ptr = addr + delta_ptr for the sake of the test @@ -315,7 +314,6 @@ fn test_insert_and_delete_accounts() -> Result<()> { // Test for address already in list. for i in 0..n { let addr_in_list = U256::from(addresses[i as usize].0.as_slice()); - log::debug!("checking already in the list {i}-th"); interpreter.push(retaddr); interpreter.push(U256::zero()); interpreter.push(addr_in_list); @@ -375,7 +373,6 @@ fn test_insert_and_delete_accounts() -> Result<()> { for (i, j) in (0..n).tuples() { // Remove addressese already in list. let addr_in_list = U256::from(addresses[i as usize].0.as_slice()); - log::debug!("Removing {i}-th addr = {:?}", addr_in_list); interpreter.push(retaddr); interpreter.push(addr_in_list); interpreter.generation_state.registers.program_counter = delete_account_label; diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index f1d9638d9..4a35e7952 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -399,25 +399,10 @@ associated storage trie hash" // Push the payload in the trie data trie_data.push(nonce); - log::debug!( - "added nonce = {:?} to trie_data at pos = {:?}", - trie_data[trie_data.len() - 1], - trie_data.len() - 1 - ); trie_data.push(balance); - log::debug!( - "added balance = {:?} to trie_data at pos = {:?}", - trie_data[trie_data.len() - 1], - trie_data.len() - 1 - ); // The Storage pointer is only written in the trie trie_data.push(0.into()); trie_data.push(code_hash.into_uint()); - log::debug!( - "added code_hash = {:?} to trie_data at pos = {:?}", - trie_data[trie_data.len() - 1], - trie_data.len() - 1 - ); get_storage_leaves( address, empty_nibbles(), diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index cd28f5a68..cbeef5b3b 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -386,26 +386,10 @@ impl GenerationState { fn run_next_storage_insert(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - log::debug!( - "storage access list = {:?}", - self.get_storage_keys_access_list() - ); - log::debug!("linda no?"); if let Some((([.., ptr], _), _)) = self .get_storage_keys_access_list()? .zip(self.get_storage_keys_access_list()?.skip(1)) .zip(self.get_storage_keys_access_list()?.skip(2)) - .inspect( - |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - log::debug!("radical"); - let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) - || (prev_addr == addr && prev_key <= key); - let next_is_strictly_larger = - next_addr > key || (next_addr == addr && next_key > key); - log::debug!("addr = {:?}, prev_addr = {:?}, prev_key = {:?}, next_addr = {:?}, next_key = {:?}, prev_is_less_or_equal = {:?}, next_is_strictly_larger = {:?}", - addr, prev_addr, prev_key, next_addr, next_key, prev_is_less_or_equal, next_is_strictly_larger); - } - ) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) @@ -413,10 +397,9 @@ impl GenerationState { let next_is_strictly_larger = next_addr > addr || (next_addr == addr && next_key > key); prev_is_less_or_equal && next_is_strictly_larger - } + }, ) { - log::debug!("ptr = {:?} found", ptr); Ok(ptr / U256::from(4)) } else { Ok((Segment::AccessedStorageKeys as usize).into()) @@ -443,10 +426,6 @@ impl GenerationState { /// `node[0] <= addr < next_node[0]` and `addr` is the top of the stack. fn run_next_insert_account(&self) -> Result { let addr = stack_peek(self, 0)?; - log::debug!( - "accounts linked list = {:?}", - self.get_accounts_linked_list() - ); if let Some((([.., pred_ptr], [node_addr, ..]), _)) = self .get_accounts_linked_list()? .zip(self.get_accounts_linked_list()?.skip(1)) @@ -455,7 +434,6 @@ impl GenerationState { (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr }) { - log::debug!("account found = {:?} at ptr = {:?}", node_addr, pred_ptr); Ok(pred_ptr / U256::from(ACCOUNTS_LINKED_LIST_NODE_SIZE)) } else { Ok((Segment::AccountsLinkedList as usize).into()) @@ -469,22 +447,10 @@ impl GenerationState { fn run_next_insert_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - log::debug!("storage linked list = {:?}", self.get_storage_linked_list()); if let Some((([.., pred_ptr], _), _)) = self .get_storage_linked_list()? .zip(self.get_storage_linked_list()?.skip(1)) .zip(self.get_storage_linked_list()?.skip(2)) - .inspect( - |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - log::debug!("radical"); - let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) - || (prev_addr == addr && prev_key <= key); - let next_is_strictly_larger = - next_addr > addr || (next_addr == addr && next_key > key); - log::debug!("addr = {:?}, key = {:?}, prev_addr = {:?}, prev_key = {:?}, next_addr = {:?}, next_key = {:?}, prev_is_less_or_equal = {:?}, next_is_strictly_larger = {:?}", - addr, key, prev_addr, prev_key, next_addr, next_key, prev_is_less_or_equal, next_is_strictly_larger); - } - ) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) @@ -512,15 +478,6 @@ impl GenerationState { .zip(self.get_accounts_linked_list()?.skip(2)) .find(|&(_, [next_node_addr, ..])| next_node_addr == addr) { - log::debug!( - "storage linked list = {:?}", - self.get_accounts_linked_list() - ); - log::debug!( - "deleting account with addr = {:?} and ptr = {:?}", - addr, - ptr - ); Ok((ptr / ACCOUNTS_LINKED_LIST_NODE_SIZE).into()) } else { Ok((Segment::AccountsLinkedList as usize).into()) diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index 5833219da..7239bf8a8 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -217,6 +217,7 @@ pub(crate) trait State { if might_overflow_op(op) { self.get_mut_registers().check_overflow = true; } + Ok(()) } Err(e) => { From 128f61490c420fa0e8be0d4bdcb8042490f3910b Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Mon, 10 Jun 2024 18:29:19 +0200 Subject: [PATCH 033/118] Add functions for updating final trie --- .../src/cpu/kernel/aggregator.rs | 1 + .../asm/mpt/linked_list/linked_list.asm | 28 ++- .../asm/mpt/linked_list/mpt_set_payload.asm | 8 +- .../asm/mpt/linked_list/set_final_tries.asm | 169 ++++++++++++++++++ .../cpu/kernel/constants/global_metadata.rs | 7 +- 5 files changed, 208 insertions(+), 5 deletions(-) create mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm diff --git a/evm_arithmetization/src/cpu/kernel/aggregator.rs b/evm_arithmetization/src/cpu/kernel/aggregator.rs index 7fbafa02b..a4ee34ce3 100644 --- a/evm_arithmetization/src/cpu/kernel/aggregator.rs +++ b/evm_arithmetization/src/cpu/kernel/aggregator.rs @@ -124,6 +124,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/mpt/insert/insert_trie_specific.asm"), include_str!("asm/mpt/linked_list/linked_list.asm"), include_str!("asm/mpt/linked_list/mpt_set_payload.asm"), + include_str!("asm/mpt/linked_list/set_final_tries.asm"), include_str!("asm/mpt/read.asm"), include_str!("asm/mpt/storage/storage_read.asm"), include_str!("asm/mpt/storage/storage_write.asm"), diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index d11b7c4db..b1434fa46 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -18,7 +18,7 @@ // The values at the respective positions are: // - 0: The account key // - 1: The key -// - 2: A ptr to the payload (the account values) +// - 2: A ptr to the payload (the stored value) // - 3: A counter indicating the number of times this slot have been accessed. // - 4: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. global init_linked_lists: @@ -614,3 +614,29 @@ global remove_slot: // stack: cold_access, value_ptr, slot_ptr POP %endmacro + +%macro first_account: + // stack: empty + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + %next_account +%end_macro + +%macro next_account + // stack: node_ptr + %add_const(3) + MLOAD_GENERAL + // stack: next_node_ptr +%endmacro + +%macro first_slot: + // stack: empty + PUSH @SEGMENT_STORAGE_LINKED_LIST + %next_slot +%end_macro + +%macro next_slot + // stack: node_ptr + %add_const(4) + MLOAD_GENERAL + // stack: next_node_ptr +%endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm index 14d0d14f1..d61db6678 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm @@ -1,7 +1,7 @@ // Set the trie with root at `node_ptr` leaves // payloads pointers to mem[payload_ptr_ptr] + step*i, for -// for i =0..n_leaves. This is used to constraint that the -// initial state and account tries payload pointers are exactly +// for i =0..n_leaves. This is used to constraint the +// initial state and account tries payload pointers such that they are exactly // those of the inital accounts and linked lists // Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest // Post stack: account_ptr_ptr, storage_ptr_ptr @@ -38,7 +38,9 @@ skip: %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) %jump(mpt_set_payload) %%after: - %pop2 + // We store account_ptr_ptr - 1, i.e. a pointer to the first node not in the initial state + %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) + POP %endmacro // Pre stack: node_ptr, account_ptr_ptr, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm new file mode 100644 index 000000000..a6ee3cc6b --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm @@ -0,0 +1,169 @@ +// Delete all leaves from the trie whose root is `node_ptr` and +// return +// Given a pointer `root_ptr` to the root of a trie, insert all accounts in +// the accounts_linked_list starting at `account_ptr_ptr` as well as the +// respective storage slots in `storage_ptr_ptr` +// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest +// Post stack: new_root_ptr. +global insert_all_accounts: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + SWAP3 + DUP3 + MLOAD_GENERAL + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + DUP1 + %eq_const(@U256_MAX) + %jumpi(no_more_accounts) + DUP4 + %increment + MLOAD_GENERAL + // stack: account_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %add_const(2) + DUP1 + %mload_trie_data + // stack: storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %stack + (storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr) -> + (storage_ptr_ptr, storage_root_ptr, key, after_insert_all_slots, storage_root_ptr_ptr, key) + %jump(insert_all_slots) +afert_insert_all_slots: + // stack: storage_ptr_ptr', storage_root_ptr', storage_root_ptr_ptr, key, root_ptr, account_ptr_ptr, retdest + SWAP2 + %mstore_trie_data + // stack: storage_ptr_ptr', key, root_ptr, account_ptr_ptr, retdest + DUP4 + %increment + MLOAD_GENERAL + + %stack + (payload_ptr, storage_ptr_ptr_p, key, root_ptr, account_ptr_ptr) -> + (root_ptr, 64, key, payload_ptr, after_insert_account, account_ptr_ptr, storage_ptr_ptr_p) + %jump(mpt_insert) +after_insert_account: + // stack: root_ptr', account_ptr_ptr, storage_ptr_ptr' + SWAP1 + %next_account + // stack: account_ptr_ptr', root_ptr', storage_ptr_ptr' + %jump(insert_all_accounts) + +no_more_accounts: + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %stack (key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest) ->(retdets, root_ptr) + JUMP + + + // stack: node_ptr, num_nibbles, key, value_ptr, retdest + +// Insert all slots before the account key changes +// Pre stack: addr, storage_ptr_ptr, root_ptr, retdest +// Post stack: storage_ptr_ptr', root_ptr' +global insert_all_slots + DUP2 + MLOAD_GENERAL + DUP2 + EQ + jumpi(insert_next_slot) + // The addr has changed, meaning that we've inserted all slots for addr + // stack: addr, storage_ptr_ptr, root_ptr, retdest + %stack (addr, storage_ptr_ptr, root_ptr, retdest) -> (retdest, storage_ptr_ptr, root_ptr) + JUMP +insert_next_slot: + // stack: addr, storage_ptr_ptr, root_ptr, retdest + DUP2 + %increment + MLOAD_GENERAL + // key, addr, storage_ptr_ptr, root_ptr, retdest + DUP3 + %add_const(2) + MLOAD_GENERAL + // stack: payload_ptr, key, addr, storage_ptr_ptr, root_ptr, retdest + %stack (payload_ptr, key, addr, storage_ptr_ptr, root_ptr) -> (root_ptr, 64, key, payload_ptr, after_insert_slot, storage_ptr_ptr, addr) + %jump(mpt_insert) +after_insert_slot: + // stack: root_ptr', storage_ptr_ptr, addr, retdest + SWAP1 + %next_slot + // stack: storage_ptr_ptr', root_ptr', addr + %stack (storage_ptr_ptr_p, root_ptr_p, addr) -> (addr, storage_ptr_ptr_p, root_ptr_p) + %jump(insert_all_slots) + +// Delete all the accounts which where deleted from the intial state. +// Delete also all slots deleted from the storage trie of non-deleted accounts. +// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest +// Post stack: new_root_ptr. +global delete_removed_accounts: + DUP1 + %mload_global_metadata(@GLOBAL_METADATA_INITAL_ACCOUNTS_LINKED_LIST_LEN) + EQ + %jumpi(delete_removed_accounts_end) + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP1 + %add_const(3) + %eq_const(@U256_MAX) // Check if the node was deleted + %jumpi(delete_account) + // The account is still there so we need to delete any removed slot + DUP1 + MLOAD_GENERAL + // stack: key, account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP1 + %increment + MLOAD_GENERAL // get payload_ptr + %add_const(2) // storage_root_ptr = payload_ptr[2] + DUP1 + %mload_trie_data + %stack + (storage_root_ptr, storage_root_ptr_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr) -> + (key, storage_root_ptr, storage_ptr_ptr, after_delete_removed_slots, storage_root_ptr_ptr, account_ptr_ptr, root_ptr) + %jump(delete_removed_slots) +after_delete_removed_slots: + // stack: storage_root_ptr', storage_ptr_ptr', storage_root_ptr_ptr, account_ptr_ptr, root_ptr, retdest + SWAP1 SWAP2 + %mstore_trie_data + // stack: storage_ptr_ptr', account_ptr_ptr, root_ptr, retdest + SWAP1 + %add_const(4) + // stack: account_ptr_ptr', storage_ptr_ptr', root_ptr, retdest + SWAP1 SWAP2 SWAP1 + %jump(delete_removed_accounts) + +delete_removed_accounts_end: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + %stack (account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr) + JUMP +delete_account: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP1 + MLOAD_GENERAL + %stack (key, account_ptr_ptr, root_ptr) -> (root_ptr, 64, key, after_mpt_delete, account_ptr_ptr) + // Pre stack: node_ptr, num_nibbles, key, retdest + // Post stack: updated_node_ptr + %jump(mpt_delete) +after_mpt_delete: + // stack: root_ptr', account_ptr_ptr, storage_ptr_ptr, retdest + SWAP1 + %add_const(4) + %jump(delte_removed_accounts) + +// Delete all slots in `storage_ptr_ptr` with address == `addr`. +// Pre stack: addr, root_ptr, storage_ptr_ptr, retdest +// Post stack: new_root_ptr, storage_ptr_ptr'. +delete_removed_slots: + DUP3 + MLOAD_GENERAL + EQ + %jumpi(delete_next_slot) + // If we are here we have deleted all the slots for this key + %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) + JUMP +delete_next_slot: + DUP3 + %increment + MLOAD_GENERAL + %stack (key, addr, root_ptr, storage_ptr_ptr) -> (root_ptr, 64, key, after_mpt_delete_slot, addr, storage_ptr_ptr) + %jump(mpt_delete) +after_mpt_delete_slot: + // stack: root_ptr', addr, storage_ptr_ptr + SWAP2 + %add_const(5) + %stack (storage_ptr_ptr_p, addr, root_ptr_p) -> (addr, root_ptr_p, storage_ptr_ptr_p) + %jump(delete_removed_slots) diff --git a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs index 24eeed49b..a302b482c 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs @@ -101,10 +101,11 @@ pub(crate) enum GlobalMetadata { // The address of the next available address in /// Segment::StorageLinkedList StorageLinkedListLen, + InitialAccountsLinkedListLen, } impl GlobalMetadata { - pub(crate) const COUNT: usize = 49; + pub(crate) const COUNT: usize = 50; /// Unscales this virtual offset by their respective `Segment` value. pub(crate) const fn unscale(&self) -> usize { @@ -162,6 +163,7 @@ impl GlobalMetadata { Self::KernelLen, Self::AccountsLinkedListLen, Self::StorageLinkedListLen, + Self::InitialAccountsLinkedListLen, ] } @@ -217,6 +219,9 @@ impl GlobalMetadata { Self::KernelLen => "GLOBAL_METADATA_KERNEL_LEN", Self::AccountsLinkedListLen => "GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN", Self::StorageLinkedListLen => "GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN", + Self::InitialAccountsLinkedListLen => { + "GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN" + } } } } From 95e3001dea4ea4514b9ed5d1986e75d895153077 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Tue, 11 Jun 2024 16:55:37 +0200 Subject: [PATCH 034/118] [WIP] eliminating trie call --- .../src/cpu/kernel/aggregator.rs | 4 +- .../src/cpu/kernel/asm/main.asm | 6 +- .../src/cpu/kernel/asm/mpt/delete/delete.asm | 2 + .../asm/mpt/insert/insert_trie_specific.asm | 13 +- .../asm/mpt/linked_list/linked_list.asm | 43 +++-- .../asm/mpt/linked_list/mpt_set_payload.asm | 169 ------------------ .../asm/mpt/linked_list/set_final_tries.asm | 169 ------------------ .../src/cpu/kernel/asm/mpt/read.asm | 46 +---- .../kernel/asm/mpt/storage/storage_read.asm | 32 +--- .../kernel/asm/mpt/storage/storage_write.asm | 36 +--- .../asm/transactions/common_decoding.asm | 35 ++-- .../src/cpu/kernel/tests/mpt/linked_list.rs | 4 +- 12 files changed, 75 insertions(+), 484 deletions(-) delete mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm delete mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm diff --git a/evm_arithmetization/src/cpu/kernel/aggregator.rs b/evm_arithmetization/src/cpu/kernel/aggregator.rs index a4ee34ce3..f7253d6d0 100644 --- a/evm_arithmetization/src/cpu/kernel/aggregator.rs +++ b/evm_arithmetization/src/cpu/kernel/aggregator.rs @@ -123,8 +123,8 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/mpt/insert/insert_leaf.asm"), include_str!("asm/mpt/insert/insert_trie_specific.asm"), include_str!("asm/mpt/linked_list/linked_list.asm"), - include_str!("asm/mpt/linked_list/mpt_set_payload.asm"), - include_str!("asm/mpt/linked_list/set_final_tries.asm"), + include_str!("asm/mpt/linked_list/initial_tries.asm"), + include_str!("asm/mpt/linked_list/final_tries.asm"), include_str!("asm/mpt/read.asm"), include_str!("asm/mpt/storage/storage_read.asm"), include_str!("asm/mpt/storage/storage_write.asm"), diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 9e9958560..3f3e02fa4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -49,7 +49,7 @@ global hash_initial_tries: global debug_check_hash: %assert_eq - %mpt_set_payload_no_return + %set_initial_tries %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) global debug_check_hash_after_setting_payloads: %assert_eq @@ -111,7 +111,9 @@ global perform_final_checks: %pop3 PUSH 1 // initial trie data length global check_state_trie: - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) %assert_eq + %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) +global debug_check_final_trie: + %assert_eq global check_txn_trie: %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq global check_receipt_trie: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index 913ba1fcf..24bf81df2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -26,6 +26,8 @@ mpt_delete_leaf: global delete_account: %stack (address, retdest) -> (address, delete_account_save, retdest) %addr_to_state_key + DUP1 + %remove_account_from_linked_list // stack: key, delete_account_save, retdest PUSH 64 // stack: 64, key, delete_account_save, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm index e5f29b352..3541e71a4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm @@ -6,18 +6,7 @@ // TODO: Have this take an address and do %mpt_insert_state_trie? To match mpt_read_state_trie. global mpt_insert_state_trie: // stack: key, value_ptr, retdest - // TODO: Use only the account linked list - DUP2 DUP2 - %insert_account_no_return - %stack (key, value_ptr) - -> (key, value_ptr, mpt_insert_state_trie_save) - PUSH 64 // num_nibbles - %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - // stack: state_root_ptr, num_nibbles, key, value_ptr, mpt_insert_state_trie_save, retdest - %jump(mpt_insert) -mpt_insert_state_trie_save: - // stack: updated_node_ptr, retdest - %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + %insert_account_to_linked_list_no_return JUMP %macro mpt_insert_state_trie diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index b1434fa46..3d33e1492 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -63,15 +63,15 @@ global init_linked_lists: %%after: %endmacro -%macro insert_account +%macro insert_account_to_linked_list %stack (addr, ptr) -> (addr, ptr, %%after) - %jump(insert_account) + %jump(insert_account_to_linked_list) %%after: // stack: cold_access %endmacro -%macro insert_account_no_return - %insert_account +%macro insert_account_to_linked_list_no_return + %insert_account_to_linked_list %pop2 %endmacro @@ -94,7 +94,7 @@ global init_linked_lists: /// Inserts the account addr and payload pointer into the linked list if it is not already present. /// Return `1, payload_ptr` if the account was inserted, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. -global insert_account: +global insert_account_to_linked_list: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr, payload_ptr, retdest @@ -262,7 +262,13 @@ account_not_found: SWAP1 JUMP -/// Remove the storage key and its value from the access list. +%macro remove_account_from_linked_list + PUSH %%after + SWAP1 + %jump(remove_account) +%%after: +%endmacro +/// Remove the address and its value from the access list. /// Panics if the key is not in the list. global remove_account: // stack: addr, retdest @@ -549,9 +555,12 @@ slot_not_found: JUMP +%macro remove_slot + %stack (addr, key) -> (addr, key, %%after) +%%after: +%endmacro /// Remove the storage key and its value from the list. /// Panics if the key is not in the list. - global remove_slot: // stack: addr, key, retdest PROVER_INPUT(linked_list::remove_slot) @@ -611,15 +620,25 @@ global remove_slot: %stack (addr, key) -> (addr, key, 0, %%after) %jump(search_slot) %%after: - // stack: cold_access, value_ptr, slot_ptr + // stack: cold_access, slot_ptr POP %endmacro -%macro first_account: +%macro read_storage_linked_list_w_addr + // stack: slot, address + %slot_to_storage_key + SWAP1 + %addr_to_state_key + %stack (addr, key) -> (addr, key, 0, %%after) + %jump(search_slot) +%%after: +%endmacro + +%macro first_account // stack: empty PUSH @SEGMENT_ACCOUNTS_LINKED_LIST %next_account -%end_macro +%endmacro %macro next_account // stack: node_ptr @@ -628,11 +647,11 @@ global remove_slot: // stack: next_node_ptr %endmacro -%macro first_slot: +%macro first_slot // stack: empty PUSH @SEGMENT_STORAGE_LINKED_LIST %next_slot -%end_macro +%endmacro %macro next_slot // stack: node_ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm deleted file mode 100644 index d61db6678..000000000 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/mpt_set_payload.asm +++ /dev/null @@ -1,169 +0,0 @@ -// Set the trie with root at `node_ptr` leaves -// payloads pointers to mem[payload_ptr_ptr] + step*i, for -// for i =0..n_leaves. This is used to constraint the -// initial state and account tries payload pointers such that they are exactly -// those of the inital accounts and linked lists -// Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest -// Post stack: account_ptr_ptr, storage_ptr_ptr -global mpt_set_payload: - // stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - DUP1 %mload_trie_data - // stack: node_type, node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - // Increment node_ptr, so it points to the node payload instead of its type. - SWAP1 %increment SWAP1 - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - - DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(skip) - DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_branch) - DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) - DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) - -skip: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - %stack (node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) - JUMP - -%macro mpt_set_payload - %stack(node_ptr, account_ptr_ptr, storage_ptr_ptr) -> (node_ptr, account_ptr_ptr, storage_ptr_ptr, %%after) - %jump(mpt_set_payload) -%%after: -%endmacro - -%macro mpt_set_payload_no_return - PUSH %%after - PUSH @SEGMENT_STORAGE_LINKED_LIST - %add_const(7) // The first node is the special node, of size 5, so the first payload is at position 5 + 2. - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - %add_const(5) // The first node is the special node, of size 4, so the first payload is at position 4 + 1. - %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - %jump(mpt_set_payload) -%%after: - // We store account_ptr_ptr - 1, i.e. a pointer to the first node not in the initial state - %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) - POP -%endmacro - -// Pre stack: node_ptr, account_ptr_ptr, retdest -// Post stack: storage_ptr_ptr -global mpt_set_storage_payload: - // stack: node_ptr, storage_ptr_ptr, retdest - DUP1 %mload_trie_data - // stack: node_type, node_ptr, storage_ptr_ptr, retdest - // Increment node_ptr, so it points to the node payload instead of its type. - SWAP1 %increment SWAP1 - // stack: node_type, after_node_type, storage_ptr_ptr, retdest - - DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(storage_skip) - DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_storage_branch) - DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) - DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_storage_leaf) - -storage_skip: - // stack: node_type, after_node_type, storage_ptr_ptr, retdest - %stack (node_type, after_node_type, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) - JUMP - -%macro mpt_set_storage_payload - %stack(node_ptr, storage_ptr_ptr) -> (node_ptr, storage_ptr_ptr, %%after) - %jump(mpt_set_storage_payload) -%%after: -%endmacro - -set_payload_branch: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - POP - - // Call mpt_set_payload on each child - %rep 16 - %stack - (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> - (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, child_ptr_ptr) - // stack: child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %mload_trie_data - // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_encode, child_ptr_ptr, retdest - %mpt_set_payload - // stack: account_ptr_ptr', storage_ptr_ptr', child_ptr_ptr, retdest - SWAP1 - SWAP2 - %increment - %endrep - // stack: child_ptr_ptr', account_ptr_ptr', storage_ptr_ptr', retdest - %stack (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) - JUMP - -set_payload_storage_branch: - // stack: node_type, child_ptr_ptr, storage_ptr_ptr, retdest - POP - - // Call mpt_set_storage_payload on each child - %rep 16 - %stack - (child_ptr_ptr, storage_ptr_ptr) -> - (child_ptr_ptr, storage_ptr_ptr, child_ptr_ptr) - // stack: child_ptr_ptr, storage_ptr_ptr, child_ptr_ptr, retdest - %mload_trie_data - // stack: child_ptr, storage_ptr_ptr, child_ptr_ptr, retdest - %mpt_set_storage_payload - // stack: storage_ptr_ptr', child_ptr_ptr, retdest - SWAP1 - %increment - %endrep - // stack: child_ptr_ptr', storage_ptr_ptr', retdest - %stack (child_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) - JUMP - -set_payload_extension: - // stack: node_type, after_node_type, (account_ptr_ptr,) storage_ptr_ptr, retdest - POP - // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - %add_const(2) %mload_trie_data - // stack: child_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest - %jump(mpt_set_payload) - -set_payload_leaf: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest - POP - %add_const(2) // The payload pointer starts at index 3, after num_nibbles and packed_nibbles. - DUP1 - // stack payload_ptr_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %mload_trie_data - // stack account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %add_const(2) - %mload_trie_data // storage_root_ptr = account[2] - // stack storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest - %stack - (storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> - (storage_root_ptr, storage_ptr_ptr, after_set_storage_payload, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) - %jump(mpt_set_storage_payload) -after_set_storage_payload: - // stack: storage_ptr_ptr', storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, retdest - DUP4 - MLOAD_GENERAL // load the next payload pointer in the linked list - DUP1 %add_const(2) // new_storage_root_ptr_ptr = payload_ptr[2] - // stack: new_storage_root_ptr_ptr, new_payload_ptr, storage_root_ptr, storage_ptr_ptr', payload_ptr_ptr, account_ptr_ptr, retdest - %stack - (new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> - (new_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) - %mstore_trie_data // The account in the linked list has no storage root so we need to manually set it. - %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. - // stack: account_ptr_ptr, storage_ptr_ptr', retdest - %add_const(4) // The next pointer is at distance 4 - // stack: payload_ptr_ptr', storage_ptr_ptr', retdest - SWAP1 - SWAP2 - JUMP - -set_payload_storage_leaf: - // stack: node_type, after_node_type, storage_ptr_ptr, retdest - POP - // stack: after_node_type, storage_ptr_ptr, retdest - %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. - DUP2 - MLOAD_GENERAL - SWAP1 - %mstore_trie_data - // stack: storage_ptr_ptr, retdest - %add_const(5) // The next pointer is at distance 5 - // stack: storage_ptr_ptr', retdest - SWAP1 - JUMP \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm deleted file mode 100644 index a6ee3cc6b..000000000 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/set_final_tries.asm +++ /dev/null @@ -1,169 +0,0 @@ -// Delete all leaves from the trie whose root is `node_ptr` and -// return -// Given a pointer `root_ptr` to the root of a trie, insert all accounts in -// the accounts_linked_list starting at `account_ptr_ptr` as well as the -// respective storage slots in `storage_ptr_ptr` -// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest -// Post stack: new_root_ptr. -global insert_all_accounts: - // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest - SWAP3 - DUP3 - MLOAD_GENERAL - // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest - DUP1 - %eq_const(@U256_MAX) - %jumpi(no_more_accounts) - DUP4 - %increment - MLOAD_GENERAL - // stack: account_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest - %add_const(2) - DUP1 - %mload_trie_data - // stack: storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest - %stack - (storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr) -> - (storage_ptr_ptr, storage_root_ptr, key, after_insert_all_slots, storage_root_ptr_ptr, key) - %jump(insert_all_slots) -afert_insert_all_slots: - // stack: storage_ptr_ptr', storage_root_ptr', storage_root_ptr_ptr, key, root_ptr, account_ptr_ptr, retdest - SWAP2 - %mstore_trie_data - // stack: storage_ptr_ptr', key, root_ptr, account_ptr_ptr, retdest - DUP4 - %increment - MLOAD_GENERAL - - %stack - (payload_ptr, storage_ptr_ptr_p, key, root_ptr, account_ptr_ptr) -> - (root_ptr, 64, key, payload_ptr, after_insert_account, account_ptr_ptr, storage_ptr_ptr_p) - %jump(mpt_insert) -after_insert_account: - // stack: root_ptr', account_ptr_ptr, storage_ptr_ptr' - SWAP1 - %next_account - // stack: account_ptr_ptr', root_ptr', storage_ptr_ptr' - %jump(insert_all_accounts) - -no_more_accounts: - // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest - %stack (key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest) ->(retdets, root_ptr) - JUMP - - - // stack: node_ptr, num_nibbles, key, value_ptr, retdest - -// Insert all slots before the account key changes -// Pre stack: addr, storage_ptr_ptr, root_ptr, retdest -// Post stack: storage_ptr_ptr', root_ptr' -global insert_all_slots - DUP2 - MLOAD_GENERAL - DUP2 - EQ - jumpi(insert_next_slot) - // The addr has changed, meaning that we've inserted all slots for addr - // stack: addr, storage_ptr_ptr, root_ptr, retdest - %stack (addr, storage_ptr_ptr, root_ptr, retdest) -> (retdest, storage_ptr_ptr, root_ptr) - JUMP -insert_next_slot: - // stack: addr, storage_ptr_ptr, root_ptr, retdest - DUP2 - %increment - MLOAD_GENERAL - // key, addr, storage_ptr_ptr, root_ptr, retdest - DUP3 - %add_const(2) - MLOAD_GENERAL - // stack: payload_ptr, key, addr, storage_ptr_ptr, root_ptr, retdest - %stack (payload_ptr, key, addr, storage_ptr_ptr, root_ptr) -> (root_ptr, 64, key, payload_ptr, after_insert_slot, storage_ptr_ptr, addr) - %jump(mpt_insert) -after_insert_slot: - // stack: root_ptr', storage_ptr_ptr, addr, retdest - SWAP1 - %next_slot - // stack: storage_ptr_ptr', root_ptr', addr - %stack (storage_ptr_ptr_p, root_ptr_p, addr) -> (addr, storage_ptr_ptr_p, root_ptr_p) - %jump(insert_all_slots) - -// Delete all the accounts which where deleted from the intial state. -// Delete also all slots deleted from the storage trie of non-deleted accounts. -// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest -// Post stack: new_root_ptr. -global delete_removed_accounts: - DUP1 - %mload_global_metadata(@GLOBAL_METADATA_INITAL_ACCOUNTS_LINKED_LIST_LEN) - EQ - %jumpi(delete_removed_accounts_end) - // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest - DUP1 - %add_const(3) - %eq_const(@U256_MAX) // Check if the node was deleted - %jumpi(delete_account) - // The account is still there so we need to delete any removed slot - DUP1 - MLOAD_GENERAL - // stack: key, account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest - DUP1 - %increment - MLOAD_GENERAL // get payload_ptr - %add_const(2) // storage_root_ptr = payload_ptr[2] - DUP1 - %mload_trie_data - %stack - (storage_root_ptr, storage_root_ptr_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr) -> - (key, storage_root_ptr, storage_ptr_ptr, after_delete_removed_slots, storage_root_ptr_ptr, account_ptr_ptr, root_ptr) - %jump(delete_removed_slots) -after_delete_removed_slots: - // stack: storage_root_ptr', storage_ptr_ptr', storage_root_ptr_ptr, account_ptr_ptr, root_ptr, retdest - SWAP1 SWAP2 - %mstore_trie_data - // stack: storage_ptr_ptr', account_ptr_ptr, root_ptr, retdest - SWAP1 - %add_const(4) - // stack: account_ptr_ptr', storage_ptr_ptr', root_ptr, retdest - SWAP1 SWAP2 SWAP1 - %jump(delete_removed_accounts) - -delete_removed_accounts_end: - // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest - %stack (account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr) - JUMP -delete_account: - // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest - DUP1 - MLOAD_GENERAL - %stack (key, account_ptr_ptr, root_ptr) -> (root_ptr, 64, key, after_mpt_delete, account_ptr_ptr) - // Pre stack: node_ptr, num_nibbles, key, retdest - // Post stack: updated_node_ptr - %jump(mpt_delete) -after_mpt_delete: - // stack: root_ptr', account_ptr_ptr, storage_ptr_ptr, retdest - SWAP1 - %add_const(4) - %jump(delte_removed_accounts) - -// Delete all slots in `storage_ptr_ptr` with address == `addr`. -// Pre stack: addr, root_ptr, storage_ptr_ptr, retdest -// Post stack: new_root_ptr, storage_ptr_ptr'. -delete_removed_slots: - DUP3 - MLOAD_GENERAL - EQ - %jumpi(delete_next_slot) - // If we are here we have deleted all the slots for this key - %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) - JUMP -delete_next_slot: - DUP3 - %increment - MLOAD_GENERAL - %stack (key, addr, root_ptr, storage_ptr_ptr) -> (root_ptr, 64, key, after_mpt_delete_slot, addr, storage_ptr_ptr) - %jump(mpt_delete) -after_mpt_delete_slot: - // stack: root_ptr', addr, storage_ptr_ptr - SWAP2 - %add_const(5) - %stack (storage_ptr_ptr_p, addr, root_ptr_p) -> (addr, root_ptr_p, storage_ptr_ptr_p) - %jump(delete_removed_slots) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 7ba7ca224..9ec6aad08 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -1,26 +1,12 @@ -// TODO: Use only linked lists -global mpt_read_state_trie_test: +// Given an address, return a pointer to the associated account data, which +// consists of four words (nonce, balance, storage_root, code_hash), in the +// trie_data segment. Returns null if the address is not found. +global mpt_read_state_trie: // stack: addr, retdest // stack: address, retdest - //TEST linked list - DUP1 %read_accounts_linked_list - // stack: ll_addr, address, retdest - %add_const(3) - %mload_trie_data - // stack: ll_code_hash, address, retdest - SWAP1 - %mpt_read_state_trie_original - DUP1 - %add_const(3) - %mload_trie_data - // stack: code_hash, account_ptr, ll_code_hash, retdest - SWAP1 SWAP2 - // stack: ll_code_hash, code_hash, account_ptr, retdest -global debug_at_least_the_code_hash_is_the_same: - %assert_eq - // END TEST linked list + // stack: account_ptr SWAP1 JUMP @@ -29,27 +15,7 @@ global debug_at_least_the_code_hash_is_the_same: // Convenience macro to call mpt_read_state_trie and return where we left off. %macro mpt_read_state_trie %stack (addr) -> (addr, %%after) - %jump(mpt_read_state_trie_test) -%%after: -%endmacro - - -// Given an address, return a pointer to the associated account data, which -// consists of four words (nonce, balance, storage_root, code_hash), in the -// state trie. Returns null if the address is not found. -global mpt_read_state_trie_original: - // stack: addr, retdest - %addr_to_state_key - // stack: key, retdest - PUSH 64 // num_nibbles - %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // node_ptr - // stack: node_ptr, num_nibbles, key, retdest - %jump(mpt_read) - -// Convenience macro to call mpt_read_state_trie and return where we left off. -%macro mpt_read_state_trie_original - %stack (addr) -> (addr, %%after) - %jump(mpt_read_state_trie_original) + %jump(mpt_read_state_trie) %%after: %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index c83bbd469..fae4f326f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -6,45 +6,21 @@ global sload_current: - // TODO: Use only the linked list - // TEST STORAGE linked list - DUP1 - %read_storage_linked_list - %mload_trie_data - %stack (ll_value, slot) -> (slot, after_storage_read, ll_value) - - // %stack (slot) -> (slot, after_storage_read) - - - %slot_to_storage_key - // stack: storage_key, after_storage_read - PUSH 64 // storage_key has 64 nibbles - %current_storage_trie - // stack: storage_root_ptr, 64, storage_key, after_storage_read - %jump(mpt_read) - -global after_storage_read: - // stack: value_ptr, ll_value, retdest + %read_storage_linked_list + // stack: value_ptr, retdest DUP1 %jumpi(storage_key_exists) // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. - %stack (value_ptr, ll_value, retdest) -> (retdest, 0) - //%stack (value_ptr, retdest) -> (retdest, 0) + %stack (value_ptr, retdest) -> (retdest, 0) JUMP -global storage_key_exists: +storage_key_exists: // stack: value_ptr, retdest - // actually: value_ptr, ll_value, retdest %mload_trie_data // stack: value, retdest - // atually: value, ll_value, retdest - DUP2 -global debug_the_storage_value_is_the_same: - %assert_eq - SWAP1 JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index b7aa3b5af..425ef70e4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -119,34 +119,11 @@ sstore_after_refund: %append_to_trie_data // stack: slot, value_ptr, kexit_info - // TEST storage write - // TEST STORAGE linked list - DUP2 - DUP2 %slot_to_storage_key %address %addr_to_state_key %insert_slot_no_return - // Next, call mpt_insert on the current account's storage root. - %stack (slot, value_ptr) -> (slot, value_ptr, after_storage_insert) - %slot_to_storage_key - // stack: storage_key, value_ptr, after_storage_insert, kexit_info - PUSH 64 // storage_key has 64 nibbles - %current_storage_trie - // stack: storage_root_ptr, 64, storage_key, value_ptr, after_storage_insert, kexit_info - %jump(mpt_insert) - -after_storage_insert: - // stack: new_storage_root_ptr, kexit_info - %current_account_data - // stack: account_ptr, new_storage_root_ptr, kexit_info - - // Update the copied account with our new storage root pointer. - %add_const(2) - // stack: account_storage_root_ptr_ptr, new_storage_root_ptr, kexit_info - %mstore_trie_data - // stack: kexit_info EXIT_KERNEL sstore_noop: @@ -158,11 +135,10 @@ sstore_noop: sstore_delete: // stack: slot, value, kexit_info SWAP1 POP - PUSH after_storage_insert SWAP1 - // stack: slot, after_storage_insert, kexit_info + // stack: slot, kexit_info %slot_to_storage_key - // stack: storage_key, after_storage_insert, kexit_info - PUSH 64 // storage_key has 64 nibbles - %current_storage_trie - // stack: storage_root_ptr, 64, storage_key, after_storage_insert, kexit_info - %jump(mpt_delete) + // stack: storage_key, kexit_info + %address + %addr_to_state_key + %remove_slot + EXIT_KERNEL diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm index 223e0a62e..7e64234dd 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm @@ -236,22 +236,21 @@ after_read: sload_with_addr: - %stack (slot, addr) -> (slot, addr, after_storage_read) - %slot_to_storage_key - // stack: storage_key, addr, after_storage_read - PUSH 64 // storage_key has 64 nibbles - %stack (n64, storage_key, addr, after_storage_read) -> (addr, n64, storage_key, after_storage_read) - %mpt_read_state_trie - // stack: account_ptr, 64, storage_key, after_storage_read - DUP1 ISZERO %jumpi(ret_zero) // TODO: Fix this. This should never happen. - // stack: account_ptr, 64, storage_key, after_storage_read - %add_const(2) - // stack: storage_root_ptr_ptr - %mload_trie_data - // stack: storage_root_ptr, 64, storage_key, after_storage_read - %jump(mpt_read) -ret_zero: - // stack: account_ptr, 64, storage_key, after_storage_read, retdest - %pop4 - PUSH 0 SWAP1 JUMP + %read_storage_linked_list_w_addr + + // stack: value_ptr, retdest + DUP1 %jumpi(storage_key_exists) + + // Storage key not found. Return default value_ptr = 0, + // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. + %stack (value_ptr, retdest) -> (retdest, 0) + + JUMP + +storage_key_exists: + // stack: value_ptr, retdest + %mload_trie_data + // stack: value, retdest + SWAP1 + JUMP diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 5ee5a67b6..beae50361 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -141,7 +141,7 @@ fn test_insert_account() -> Result<()> { let mut interpreter = Interpreter::::new(init_label, initial_stack); interpreter.run()?; - let insert_account_label = KERNEL.global_labels["insert_account"]; + let insert_account_label = KERNEL.global_labels["insert_account_to_linked_list"]; let retaddr = 0xdeadbeefu32.into(); let mut rng = thread_rng(); @@ -256,7 +256,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { let mut interpreter = Interpreter::::new(init_label, initial_stack); interpreter.run()?; - let insert_account_label = KERNEL.global_labels["insert_account"]; + let insert_account_label = KERNEL.global_labels["insert_account_to_linked_list"]; let retaddr = 0xdeadbeefu32.into(); let mut rng = thread_rng(); From 660a4f4e1064810c998a9e351fe3a4939b88f4cc Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Tue, 11 Jun 2024 23:04:22 +0200 Subject: [PATCH 035/118] [WIP] Fix kexit_data issue --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 2 ++ .../src/cpu/kernel/asm/mpt/storage/storage_write.asm | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 3d33e1492..5791e4a9f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -557,8 +557,10 @@ slot_not_found: %macro remove_slot %stack (addr, key) -> (addr, key, %%after) + %jump(remove_slot) %%after: %endmacro + /// Remove the storage key and its value from the list. /// Panics if the key is not in the list. global remove_slot: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index 425ef70e4..a94ad2fcf 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -109,6 +109,7 @@ sstore_after_refund: // If the value is zero, delete the slot from the storage trie. // stack: slot, value, kexit_info +global debug_kexit_info: DUP2 ISZERO %jumpi(sstore_delete) // First we write the value to MPT data, and get a pointer to it. @@ -132,6 +133,7 @@ sstore_noop: EXIT_KERNEL // Delete the slot from the storage trie. +global debug_sstore_delete: sstore_delete: // stack: slot, value, kexit_info SWAP1 POP @@ -140,5 +142,7 @@ sstore_delete: // stack: storage_key, kexit_info %address %addr_to_state_key +global debug_remove_slot: %remove_slot +global debug_que_pasa_por_dios_santo: EXIT_KERNEL From 287cddd46c578907fd46a95cf5781955cd0d0c75 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Tue, 11 Jun 2024 23:58:15 +0200 Subject: [PATCH 036/118] Merge with journaling branch --- .../cpu/kernel/asm/journal/storage_change.asm | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm index e162db2b4..6dda9268e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm @@ -4,29 +4,6 @@ %journal_add_3(@JOURNAL_ENTRY_STORAGE_CHANGE) %endmacro -global revert_storage_change_original: - // stack: entry_type, ptr, retdest - POP - %journal_load_3 - // stack: address, slot, prev_value, retdest - DUP3 ISZERO %jumpi(delete) - // stack: address, slot, prev_value, retdest - SWAP1 %slot_to_storage_key - // stack: storage_key, address, prev_value, retdest - PUSH 64 // storage_key has 64 nibbles - // stack: 64, storage_key, address, prev_value, retdest - DUP3 %mpt_read_state_trie - DUP1 ISZERO %jumpi(panic) - // stack: account_ptr, 64, storage_key, address, prev_value, retdest - %add_const(2) - // stack: storage_root_ptr_ptr, 64, storage_key, address, prev_value, retdest - %mload_trie_data - %get_trie_data_size - DUP6 %append_to_trie_data - %stack (prev_value_ptr, storage_root_ptr, num_nibbles, storage_key, address, prev_value, retdest) -> - (storage_root_ptr, num_nibbles, storage_key, prev_value_ptr, new_storage_root, address, retdest) - %jump(mpt_insert) - global revert_storage_change: // stack: entry_type, ptr, retdest POP @@ -41,23 +18,6 @@ global revert_storage_change: %mstore_trie_data JUMP -delete_original: - // stack: address, slot, prev_value, retdest - SWAP2 POP - %stack (slot, address, retdest) -> (slot, new_storage_root, address, retdest) - %slot_to_storage_key - // stack: storage_key, new_storage_root, address, retdest - PUSH 64 // storage_key has 64 nibbles - // stack: 64, storage_key, new_storage_root, address, retdest - DUP4 %mpt_read_state_trie - DUP1 ISZERO %jumpi(panic) - // stack: account_ptr, 64, storage_key, new_storage_root, address, retdest - %add_const(2) - // stack: storage_root_ptr_ptr, 64, storage_key, new_storage_root, address, retdest - %mload_trie_data - // stack: storage_root_ptr, 64, storage_key, new_storage_root, address, retdest - %jump(mpt_delete) - delete: // stack: address, slot, prev_value, retdest SWAP2 POP From 9915fed9444994bbc1a3889667a829ec9f73e76b Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 12 Jun 2024 00:41:14 +0200 Subject: [PATCH 037/118] [WIP] set final tries --- .../src/cpu/kernel/asm/main.asm | 1 + .../asm/mpt/linked_list/final_tries.asm | 199 ++++++++++++++++++ .../asm/mpt/linked_list/initial_tries.asm | 169 +++++++++++++++ 3 files changed, 369 insertions(+) create mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm create mode 100644 evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 3f3e02fa4..758ff502b 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -111,6 +111,7 @@ global perform_final_checks: %pop3 PUSH 1 // initial trie data length global check_state_trie: + %set_final_tries %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) global debug_check_final_trie: %assert_eq diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm new file mode 100644 index 000000000..fb9d8b61a --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -0,0 +1,199 @@ +// Given a pointer `root_ptr` to the root of a trie, insert all accounts in +// the accounts_linked_list starting at `account_ptr_ptr` as well as the +// respective storage slots in `storage_ptr_ptr`. +// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest +// Post stack: new_root_ptr. +global insert_all_accounts: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + SWAP3 + DUP3 + MLOAD_GENERAL + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + DUP1 + %eq_const(@U256_MAX) + %jumpi(no_more_accounts) + DUP4 + %increment + MLOAD_GENERAL + // stack: account_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %add_const(2) + DUP1 + %mload_trie_data + // stack: storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %stack + (storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr) -> + (key, storage_ptr_ptr, storage_root_ptr, after_insert_all_slots, storage_root_ptr_ptr, key) + %jump(insert_all_slots) +after_insert_all_slots: + // stack: storage_ptr_ptr', storage_root_ptr', storage_root_ptr_ptr, key, root_ptr, account_ptr_ptr, retdest + SWAP2 + %mstore_trie_data + // stack: storage_ptr_ptr', key, root_ptr, account_ptr_ptr, retdest + DUP4 + %increment + MLOAD_GENERAL + %stack + (payload_ptr, storage_ptr_ptr_p, key, root_ptr, account_ptr_ptr) -> + (root_ptr, 64, key, payload_ptr, after_insert_account, account_ptr_ptr, storage_ptr_ptr_p) + %jump(mpt_insert) +after_insert_account: + // stack: root_ptr', account_ptr_ptr, storage_ptr_ptr', retdest + SWAP1 + %next_account + // stack: account_ptr_ptr', root_ptr', storage_ptr_ptr', retdest + %jump(insert_all_accounts) + +no_more_accounts: + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest + %stack (key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest) ->(retdest, root_ptr) + JUMP + +// Insert all slots before the account key changes +// Pre stack: addr, storage_ptr_ptr, root_ptr, retdest +// Post stack: storage_ptr_ptr', root_ptr' +global insert_all_slots: + DUP2 + MLOAD_GENERAL + DUP2 + EQ // Check that the node addres is the same as `addr` + %jumpi(insert_next_slot) + // The addr has changed, meaning that we've inserted all slots for addr + // stack: addr, storage_ptr_ptr, root_ptr, retdest + %stack (addr, storage_ptr_ptr, root_ptr, retdest) -> (retdest, storage_ptr_ptr, root_ptr) + JUMP +insert_next_slot: + // stack: addr, storage_ptr_ptr, root_ptr, retdest + DUP2 + %increment + MLOAD_GENERAL + // key, addr, storage_ptr_ptr, root_ptr, retdest + DUP3 + %add_const(2) + MLOAD_GENERAL + // stack: payload_ptr, key, addr, storage_ptr_ptr, root_ptr, retdest + %stack (payload_ptr, key, addr, storage_ptr_ptr, root_ptr) -> (root_ptr, 64, key, payload_ptr, after_insert_slot, storage_ptr_ptr, addr) + %jump(mpt_insert) +after_insert_slot: + // stack: root_ptr', storage_ptr_ptr, addr, retdest + SWAP1 + %next_slot + // stack: storage_ptr_ptr', root_ptr', addr + %stack (storage_ptr_ptr_p, root_ptr_p, addr) -> (addr, storage_ptr_ptr_p, root_ptr_p) + %jump(insert_all_slots) + +// Delete all the accounts, referenced by the respective nodes in the linked list starting at +// `account_ptr_ptr, which where deleted from the intial state. Delete also all slots deleted +// from the storage trie of non-deleted accounts. +// Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest +// Post stack: new_root_ptr. +global delete_removed_accounts: + DUP1 + // We assume that the size of the initial accounts linked list, containing the accounts + // of the initial state, was store at `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. + %mload_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) + // The inital accounts linked was store at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. + // If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it + // suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN` + EQ + %jumpi(delete_removed_accounts_end) + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP1 + %next_account + %eq_const(@U256_MAX) // Check if the next node pointer is @U256_MAX, the node was deleted + %jumpi(delete_account) + // The account is still there so we need to delete any removed slot + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP1 + MLOAD_GENERAL + // stack: key, account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP2 + %increment + MLOAD_GENERAL // get payload_ptr + %add_const(2) // storage_root_ptr_ptr = payload_ptr + 2 + DUP1 + %mload_trie_data + %stack + (storage_root_ptr, storage_root_ptr_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr) -> + (key, storage_root_ptr, storage_ptr_ptr, after_delete_removed_slots, storage_root_ptr_ptr, account_ptr_ptr, root_ptr) + %jump(delete_removed_slots) +after_delete_removed_slots: + // stack: storage_root_ptr', storage_ptr_ptr', storage_root_ptr_ptr, account_ptr_ptr, root_ptr, retdest + SWAP1 SWAP2 + // stack: storage_root_ptr_ptr, storage_root_ptr', storage_ptr_ptr', account_ptr_ptr, root_ptr, retdest + %mstore_trie_data + // stack: storage_ptr_ptr', account_ptr_ptr, root_ptr, retdest + SWAP1 + %add_const(4) // The next account in memory + // stack: account_ptr_ptr', storage_ptr_ptr', root_ptr, retdest + SWAP1 SWAP2 SWAP1 + %jump(delete_removed_accounts) + +delete_removed_accounts_end: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + %stack (account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr) + JUMP +delete_account: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP1 + MLOAD_GENERAL + %stack (key, account_ptr_ptr, root_ptr) -> (root_ptr, 64, key, after_mpt_delete, account_ptr_ptr) + // Pre stack: node_ptr, num_nibbles, key, retdest + // Post stack: updated_node_ptr + %jump(mpt_delete) +after_mpt_delete: + // stack: root_ptr', account_ptr_ptr, storage_ptr_ptr, retdest + SWAP1 + %add_const(4) + %jump(delete_removed_accounts) + +// Delete all slots in `storage_ptr_ptr` with address == `addr`. +// Pre stack: addr, root_ptr, storage_ptr_ptr, retdest +// Post stack: new_root_ptr, storage_ptr_ptr'. +// TODO: If there are slots with the last address which where inserted +// and/or deleted, they will aso processed in `delete_next_slot`. This +// wouldn't represent any problem, but we should double-check. +delete_removed_slots: + DUP3 + MLOAD_GENERAL + DUP2 + EQ + %jumpi(delete_next_slot) + // If we are here we have deleted all the slots for this key + %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) + JUMP +delete_next_slot: + // stack: addr, root_ptr, storage_ptr_ptr, retdest + DUP3 + %increment + MLOAD_GENERAL + %stack (key, addr, root_ptr, storage_ptr_ptr) -> (root_ptr, 64, key, after_mpt_delete_slot, addr, storage_ptr_ptr) + %jump(mpt_delete) +after_mpt_delete_slot: + // stack: root_ptr', addr, storage_ptr_ptr + SWAP2 + %add_const(5) + %stack (storage_ptr_ptr_p, addr, root_ptr_p) -> (addr, root_ptr_p, storage_ptr_ptr_p) + %jump(delete_removed_slots) + +%macro set_final_tries + PUSH %%after + PUSH @SEGMENT_STORAGE_LINKED_LIST + %add_const(5) // Skip the first node. + %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + %add_const(4) // Skip the first node. + %jump(delete_removed_accounts) +%%after: + // stack: new_state_root + PUSH %%after_after SWAP1 + // stack: new_state_root, %%after_after + PUSH @SEGMENT_STORAGE_LINKED_LIST + %next_slot + SWAP1 + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + %next_account + %jump(insert_all_accounts) +%%after_after: + //stack: new_state_root + %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) +%endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm new file mode 100644 index 000000000..ca9e40e99 --- /dev/null +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -0,0 +1,169 @@ +// Set the trie with root at `node_ptr` leaves +// payloads pointers to mem[payload_ptr_ptr] + step*i, for +// for i =0..n_leaves. This is used to constraint the +// initial state and account tries payload pointers such that they are exactly +// those of the inital accounts and linked lists +// Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest +// Post stack: account_ptr_ptr, storage_ptr_ptr +global mpt_set_payload: + // stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + DUP1 %mload_trie_data + // stack: node_type, node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // Increment node_ptr, so it points to the node payload instead of its type. + SWAP1 %increment SWAP1 + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + + DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(skip) + DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_branch) + DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) + DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) + +skip: + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + %stack (node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) + JUMP + +%macro mpt_set_payload + %stack(node_ptr, account_ptr_ptr, storage_ptr_ptr) -> (node_ptr, account_ptr_ptr, storage_ptr_ptr, %%after) + %jump(mpt_set_payload) +%%after: +%endmacro + +%macro set_initial_tries + PUSH %%after + PUSH @SEGMENT_STORAGE_LINKED_LIST + %add_const(7) // The first node is the special node, of size 5, so the first payload is at position 5 + 2. + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + %add_const(5) // The first node is the special node, of size 4, so the first payload is at position 4 + 1. + %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + %jump(mpt_set_payload) +%%after: + // We store account_ptr_ptr - 1, i.e. a pointer to the first node not in the initial state + %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) + POP +%endmacro + +// Pre stack: node_ptr, account_ptr_ptr, retdest +// Post stack: storage_ptr_ptr +global mpt_set_storage_payload: + // stack: node_ptr, storage_ptr_ptr, retdest + DUP1 %mload_trie_data + // stack: node_type, node_ptr, storage_ptr_ptr, retdest + // Increment node_ptr, so it points to the node payload instead of its type. + SWAP1 %increment SWAP1 + // stack: node_type, after_node_type, storage_ptr_ptr, retdest + + DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(storage_skip) + DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_storage_branch) + DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) + DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_storage_leaf) + +storage_skip: + // stack: node_type, after_node_type, storage_ptr_ptr, retdest + %stack (node_type, after_node_type, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) + JUMP + +%macro mpt_set_storage_payload + %stack(node_ptr, storage_ptr_ptr) -> (node_ptr, storage_ptr_ptr, %%after) + %jump(mpt_set_storage_payload) +%%after: +%endmacro + +set_payload_branch: + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + POP + + // Call mpt_set_payload on each child + %rep 16 + %stack + (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> + (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, child_ptr_ptr) + // stack: child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %mload_trie_data + // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_encode, child_ptr_ptr, retdest + %mpt_set_payload + // stack: account_ptr_ptr', storage_ptr_ptr', child_ptr_ptr, retdest + SWAP1 + SWAP2 + %increment + %endrep + // stack: child_ptr_ptr', account_ptr_ptr', storage_ptr_ptr', retdest + %stack (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) + JUMP + +set_payload_storage_branch: + // stack: node_type, child_ptr_ptr, storage_ptr_ptr, retdest + POP + + // Call mpt_set_storage_payload on each child + %rep 16 + %stack + (child_ptr_ptr, storage_ptr_ptr) -> + (child_ptr_ptr, storage_ptr_ptr, child_ptr_ptr) + // stack: child_ptr_ptr, storage_ptr_ptr, child_ptr_ptr, retdest + %mload_trie_data + // stack: child_ptr, storage_ptr_ptr, child_ptr_ptr, retdest + %mpt_set_storage_payload + // stack: storage_ptr_ptr', child_ptr_ptr, retdest + SWAP1 + %increment + %endrep + // stack: child_ptr_ptr', storage_ptr_ptr', retdest + %stack (child_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, storage_ptr_ptr) + JUMP + +set_payload_extension: + // stack: node_type, after_node_type, (account_ptr_ptr,) storage_ptr_ptr, retdest + POP + // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + %add_const(2) %mload_trie_data + // stack: child_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest + %jump(mpt_set_payload) + +set_payload_leaf: + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + POP + %add_const(2) // The payload pointer starts at index 3, after num_nibbles and packed_nibbles. + DUP1 + // stack payload_ptr_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %mload_trie_data + // stack account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %add_const(2) + %mload_trie_data // storage_root_ptr = account[2] + // stack storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %stack + (storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> + (storage_root_ptr, storage_ptr_ptr, after_set_storage_payload, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) + %jump(mpt_set_storage_payload) +after_set_storage_payload: + // stack: storage_ptr_ptr', storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, retdest + DUP4 + MLOAD_GENERAL // load the next payload pointer in the linked list + DUP1 %add_const(2) // new_storage_root_ptr_ptr = payload_ptr[2] + // stack: new_storage_root_ptr_ptr, new_payload_ptr, storage_root_ptr, storage_ptr_ptr', payload_ptr_ptr, account_ptr_ptr, retdest + %stack + (new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> + (new_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) + %mstore_trie_data // The account in the linked list has no storage root so we need to manually set it. + %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. + // stack: account_ptr_ptr, storage_ptr_ptr', retdest + %add_const(4) // The next pointer is at distance 4 + // stack: payload_ptr_ptr', storage_ptr_ptr', retdest + SWAP1 + SWAP2 + JUMP + +set_payload_storage_leaf: + // stack: node_type, after_node_type, storage_ptr_ptr, retdest + POP + // stack: after_node_type, storage_ptr_ptr, retdest + %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. + DUP2 + MLOAD_GENERAL + SWAP1 + %mstore_trie_data + // stack: storage_ptr_ptr, retdest + %add_const(5) // The next pointer is at distance 5 + // stack: storage_ptr_ptr', retdest + SWAP1 + JUMP \ No newline at end of file From 9a28eb5a62f108a4d030c02f1a77a2136213b767 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 12 Jun 2024 13:45:38 +0200 Subject: [PATCH 038/118] Mutate storage payload on insertions --- .../src/cpu/kernel/asm/main.asm | 11 +++++-- .../src/cpu/kernel/asm/mpt/delete/delete.asm | 1 + .../asm/mpt/linked_list/final_tries.asm | 29 ++++++++++++++++--- .../asm/mpt/linked_list/initial_tries.asm | 1 + .../asm/mpt/linked_list/linked_list.asm | 8 ++++- .../kernel/asm/mpt/storage/storage_write.asm | 7 +++++ evm_arithmetization/src/generation/state.rs | 21 ++++++++++++++ .../src/generation/trie_extractor.rs | 1 + evm_arithmetization/tests/erc721.rs | 14 +++++++++ 9 files changed, 86 insertions(+), 7 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 758ff502b..625cd44ad 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -106,8 +106,15 @@ execute_withdrawals_post_stack_op: global perform_final_checks: // stack: cum_gas, txn_counter, num_nibbles, txn_nb // Check that we end up with the correct `cum_gas`, `txn_nb` and bloom filter. - %mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_AFTER) %assert_eq - DUP3 %mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_AFTER) %assert_eq + %mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_AFTER) +global debug_check_gas: + //%assert_eq + %pop2 + + + DUP3 %mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_AFTER) +global debug_check_txn_number: + %assert_eq %pop3 PUSH 1 // initial trie data length global check_state_trie: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index 24bf81df2..9110d83b1 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -15,6 +15,7 @@ global mpt_delete: DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(mpt_delete_extension) DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(mpt_delete_leaf) %eq_const(@MPT_NODE_EMPTY) %jumpi(panic) // This should never happen. + PANIC mpt_delete_leaf: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index fb9d8b61a..1c986cff5 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -5,25 +5,29 @@ // Post stack: new_root_ptr. global insert_all_accounts: // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest - SWAP3 + SWAP2 DUP3 MLOAD_GENERAL // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest DUP1 %eq_const(@U256_MAX) %jumpi(no_more_accounts) +global debug_next_account: DUP4 %increment +global debug_before_loading_account_ptr: MLOAD_GENERAL // stack: account_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %add_const(2) DUP1 +global debug_before_loading_storage_root_ptr: %mload_trie_data // stack: storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %stack (storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr) -> (key, storage_ptr_ptr, storage_root_ptr, after_insert_all_slots, storage_root_ptr_ptr, key) %jump(insert_all_slots) +global debug_after_insert_all_slots: after_insert_all_slots: // stack: storage_ptr_ptr', storage_root_ptr', storage_root_ptr_ptr, key, root_ptr, account_ptr_ptr, retdest SWAP2 @@ -91,6 +95,7 @@ global delete_removed_accounts: // We assume that the size of the initial accounts linked list, containing the accounts // of the initial state, was store at `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. %mload_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) +global debug_inital_accounts_linked_list_len: // The inital accounts linked was store at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. // If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it // suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN` @@ -101,6 +106,7 @@ global delete_removed_accounts: %next_account %eq_const(@U256_MAX) // Check if the next node pointer is @U256_MAX, the node was deleted %jumpi(delete_account) +global debug_maybe_delete_slots: // The account is still there so we need to delete any removed slot // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP1 @@ -115,7 +121,9 @@ global delete_removed_accounts: %stack (storage_root_ptr, storage_root_ptr_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr) -> (key, storage_root_ptr, storage_ptr_ptr, after_delete_removed_slots, storage_root_ptr_ptr, account_ptr_ptr, root_ptr) +global debug_delete_removed_slots: %jump(delete_removed_slots) +global debug_after_delete_removed_slots: after_delete_removed_slots: // stack: storage_root_ptr', storage_ptr_ptr', storage_root_ptr_ptr, account_ptr_ptr, root_ptr, retdest SWAP1 SWAP2 @@ -132,6 +140,7 @@ delete_removed_accounts_end: // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest %stack (account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr) JUMP +global debug_delete_account: delete_account: // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP1 @@ -150,18 +159,30 @@ after_mpt_delete: // Pre stack: addr, root_ptr, storage_ptr_ptr, retdest // Post stack: new_root_ptr, storage_ptr_ptr'. // TODO: If there are slots with the last address which where inserted -// and/or deleted, they will aso processed in `delete_next_slot`. This +// and/or deleted, they will aso processed in `delete_this_slot`. This // wouldn't represent any problem, but we should double-check. delete_removed_slots: DUP3 MLOAD_GENERAL DUP2 EQ - %jumpi(delete_next_slot) + %jumpi(maybe_delete_this_slot) // If we are here we have deleted all the slots for this key %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) JUMP -delete_next_slot: +maybe_delete_this_slot: + // stack: addr, root_ptr, storage_ptr_ptr, retdest + DUP3 + %next_slot + %eq_const(@U256_MAX) // Check if the node was deleted + %jumpi(delete_this_slot) + // The slot was not deleted, so we skip it. + // stack: addr, root_ptr, storage_ptr_ptr, retdest + SWAP2 + %next_slot + SWAP2 + %jump(delete_removed_slots) +delete_this_slot: // stack: addr, root_ptr, storage_ptr_ptr, retdest DUP3 %increment diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index ca9e40e99..675225a39 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -39,6 +39,7 @@ skip: %jump(mpt_set_payload) %%after: // We store account_ptr_ptr - 1, i.e. a pointer to the first node not in the initial state + %decrement %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) POP %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index fb29f586a..a8a83e7ce 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -338,7 +338,8 @@ global remove_account: %add_const(@SEGMENT_STORAGE_LINKED_LIST) %endmacro -/// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present. +/// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present, +/// or modify its payload if it was already present. /// Return `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. global insert_slot: @@ -396,6 +397,11 @@ slot_found: DUP1 MLOAD_GENERAL // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest + DUP2 + DUP6 +global debug_store_new_payload: + MSTORE_GENERAL // Store the new payload + SWAP1 %increment DUP1 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index a94ad2fcf..40255ef05 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -114,12 +114,19 @@ global debug_kexit_info: // First we write the value to MPT data, and get a pointer to it. %get_trie_data_size +global debug_value_ptr: // stack: value_ptr, slot, value, kexit_info SWAP2 // stack: value, slot, value_ptr, kexit_info %append_to_trie_data // stack: slot, value_ptr, kexit_info + // DEBUG + DUP2 %mload_trie_data +global debug_the_value: + POP + // ENDDEBUG + %slot_to_storage_key %address %addr_to_state_key diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index 7239bf8a8..b2fea0dd5 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -210,6 +210,27 @@ pub(crate) trait State { let checkpoint = self.checkpoint(); let result = self.try_perform_instruction(); + { + if self.get_clock() == 78246 { + let state_trie_ptr = u256_to_usize( + self.get_generation_state() + .memory + .read_global_metadata(GlobalMetadata::StateTrieRoot), + ) + .map_err(|_| anyhow!("State trie pointer is too large to fit in a usize."))?; + log::debug!( + "Final state trie: {:?}", + get_state_trie::( + &self.get_generation_state().memory, + state_trie_ptr + ) + ); + log::debug!( + "storage linked list = {:?}", + self.get_generation_state().get_storage_linked_list() + ) + } + } match result { Ok(op) => { self.apply_ops(checkpoint); diff --git a/evm_arithmetization/src/generation/trie_extractor.rs b/evm_arithmetization/src/generation/trie_extractor.rs index 0d825643f..a753ee90e 100644 --- a/evm_arithmetization/src/generation/trie_extractor.rs +++ b/evm_arithmetization/src/generation/trie_extractor.rs @@ -197,6 +197,7 @@ pub(crate) fn read_state_rlp_value( get_trie(memory, slice[2].unwrap_or_default().as_usize(), |_, x| { Ok(rlp::encode(&read_storage_trie_value(x)).to_vec()) })?; + log::debug!("storage_trie = {:#?}", storage_trie); let account = AccountRlp { nonce: slice[0].unwrap_or_default(), balance: slice[1].unwrap_or_default(), diff --git a/evm_arithmetization/tests/erc721.rs b/evm_arithmetization/tests/erc721.rs index 86dd34002..d78b533dc 100644 --- a/evm_arithmetization/tests/erc721.rs +++ b/evm_arithmetization/tests/erc721.rs @@ -90,11 +90,24 @@ fn test_erc721() -> anyhow::Result<()> { balance: owner_account.balance - gas_used * 0xa, ..owner_account }; + log::debug!("owner_account_after = {:#?}", owner_account_after); + log::debug!("rlp = {:?}", rlp::encode(&owner_account_after).to_vec()); state_trie_after.insert(owner_nibbles, rlp::encode(&owner_account_after).to_vec())?; let contract_account_after = AccountRlp { storage_root: contract_storage_after()?.hash(), ..contract_account()? }; + let contract_rlp = vec![ + 248, 68, 128, 128, 160, 21, 52, 201, 120, 135, 151, 240, 89, 222, 226, 171, 199, 255, + 87, 189, 219, 149, 32, 147, 208, 175, 248, 2, 82, 224, 19, 247, 121, 120, 120, 158, + 114, 160, 108, 86, 199, 147, 155, 81, 154, 182, 112, 252, 61, 74, 85, 168, 162, 62, + 164, 186, 205, 30, 25, 127, 235, 17, 118, 229, 147, 70, 202, 97, 137, 184, + ]; + let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); + log::debug!("constract_account_after = {:#?}", contract_account_after); + log::debug!("contracto = {:#?}", contracto); + log::debug!("rlp = {:?}", rlp::encode(&contract_account_after).to_vec()); + log::debug!("contrc_storage_trie = {:#?}", contract_storage_after()); state_trie_after.insert( contract_nibbles, rlp::encode(&contract_account_after).to_vec(), @@ -176,6 +189,7 @@ fn test_erc721() -> anyhow::Result<()> { }, }; + log::debug!("Expected final trie = {:#?}", expected_state_trie_after); let mut timing = TimingTree::new("prove", log::Level::Debug); let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; timing.filter(Duration::from_millis(100)).print(); From 09a03b283dc1099d07dc3575cbc74d7ebf6309d4 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 12 Jun 2024 17:49:00 +0200 Subject: [PATCH 039/118] Fix deletions in final trie computation --- .../asm/mpt/linked_list/final_tries.asm | 6 +++- .../asm/mpt/linked_list/linked_list.asm | 31 +++++++++++++++++-- .../src/generation/prover_input.rs | 1 + 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 1c986cff5..13ab418bd 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -170,24 +170,28 @@ delete_removed_slots: // If we are here we have deleted all the slots for this key %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) JUMP +global debug_maybe_delete_this_slot: maybe_delete_this_slot: // stack: addr, root_ptr, storage_ptr_ptr, retdest DUP3 %next_slot %eq_const(@U256_MAX) // Check if the node was deleted +global debug_shoul_we_delete_this_slot: %jumpi(delete_this_slot) // The slot was not deleted, so we skip it. // stack: addr, root_ptr, storage_ptr_ptr, retdest SWAP2 - %next_slot + %add_const(5) SWAP2 %jump(delete_removed_slots) +global debug_delete_this_slot: delete_this_slot: // stack: addr, root_ptr, storage_ptr_ptr, retdest DUP3 %increment MLOAD_GENERAL %stack (key, addr, root_ptr, storage_ptr_ptr) -> (root_ptr, 64, key, after_mpt_delete_slot, addr, storage_ptr_ptr) +global debug_before_deleting: %jump(mpt_delete) after_mpt_delete_slot: // stack: root_ptr', addr, storage_ptr_ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index a8a83e7ce..dbd66b7e0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -385,11 +385,11 @@ global before_jumpi: DUP1 %add_const(4) MLOAD_GENERAL - %jump_neq_const(@U256_MAX, slot_found) + %jump_neq_const(@U256_MAX, slot_found_write) // The storage key is not in the list. PANIC -slot_found: +slot_found_write: // The slot was already in the list // stack: pred_ptr, addr, key, payload_ptr, retdest // Load the the payload pointer and access counter @@ -549,10 +549,11 @@ global search_slot: DUP1 %add_const(4) MLOAD_GENERAL - %jump_neq_const(@U256_MAX, slot_found) + %jump_neq_const(@U256_MAX, slot_found_no_write) // The storage key is not in the list. PANIC +global debug_slot_not_found: slot_not_found: // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest %pop4 @@ -561,6 +562,30 @@ slot_not_found: SWAP1 JUMP +slot_found_no_write: + // The slot was already in the list + // stack: pred_ptr, addr, key, payload_ptr, retdest + // Load the the payload pointer and access counter + %add_const(2) + DUP1 + MLOAD_GENERAL + // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest + SWAP1 + %increment + DUP1 + MLOAD_GENERAL + %increment + // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, key, payload_ptr, retdest + SWAP1 + DUP2 + // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest + MSTORE_GENERAL + // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest + // If access_ctr == 1 then this it's a cold access + %eq_const(1) + %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + JUMP + %macro remove_slot %stack (addr, key) -> (addr, key, %%after) diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 09973f0dd..4f14fe4b1 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -462,6 +462,7 @@ impl GenerationState { fn run_next_insert_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; + log::debug!("le storage ll = {:?}", self.get_storage_linked_list()); if let Some((([.., pred_ptr], _), _)) = self .get_storage_linked_list()? .zip(self.get_storage_linked_list()?.skip(1)) From 7661bcea1b2f009d5062b0462c5e73e882857276 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 12 Jun 2024 18:17:32 +0200 Subject: [PATCH 040/118] Remove double hashing of the initial state trie --- evm_arithmetization/src/cpu/kernel/asm/main.asm | 3 --- 1 file changed, 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 625cd44ad..1ebd9e520 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -45,9 +45,6 @@ global hash_initial_tries: // can check the value provided by the prover. // The trie data segment is already written by the linked lists %mload_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) -global debug_check_hash: - %assert_eq %set_initial_tries %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) From a14489278fe92687d5a1cc42603a4557463b90ce Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Wed, 12 Jun 2024 14:59:10 -0400 Subject: [PATCH 041/118] Misc --- .../asm/mpt/linked_list/linked_list.asm | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index dbd66b7e0..926e3d253 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -82,10 +82,11 @@ global init_linked_lists: %macro get_valid_account_ptr // stack: ptr/4 DUP1 + PUSH 4 %mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) // By construction, both @SEGMENT_ACCESSED_STORAGE_KEYS and the unscaled list len // must be multiples of 4 - %div_const(4) + DIV // stack: @SEGMENT_ACCESSED_STORAGE_KEYS/4 + accessed_strg_keys_len/4, ptr/4, ptr/4 %assert_gt %mul_const(4) @@ -200,10 +201,7 @@ insert_new_account: %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) // stack: addr, payload_ptr, retdest // TODO: Don't for get to %journal_add_account_loaded - POP - PUSH 0 - SWAP1 - SWAP2 + %stack (addr, payload_ptr, retdest) -> (0, retdest, payload_ptr) JUMP %macro search_account @@ -502,13 +500,13 @@ next_node_ok: SWAP2 JUMP -/// Search the pair (addres, storage_key) in the storage the linked list. +/// Search the pair (address, storage_key) in the storage the linked list. /// Returns `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present /// and this is the first access, or `0, original_ptr` if it was already present and accessed. // TODO: Not sure if this is correct, bc if a value is not found we need to return 0 but keep track of it for // having the right cold_access global search_slot: - // stack: addr, payload_ptr, retdest + // stack: addr, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) // stack: pred_ptr/5, addr, key, payload_ptr, retdest %get_valid_slot_ptr @@ -555,11 +553,9 @@ global search_slot: global debug_slot_not_found: slot_not_found: -// stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest - %pop4 - SWAP1 - PUSH 1 - SWAP1 + // stack: pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest + %stack (pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest) + -> (retdest, 1, payload_ptr) JUMP slot_found_no_write: From dbc5a6a58814e420511ebc7f9ee59c3676f7f212 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Thu, 13 Jun 2024 10:05:28 +0200 Subject: [PATCH 042/118] trace_decoder/Cargo.toml --- trace_decoder/Cargo.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 08ebdcf48..3f32e2f65 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -25,6 +25,8 @@ rlp-derive = { workspace = true } serde = { workspace = true } serde_with = "3.4.0" thiserror = { workspace = true } +serde_json = { workspace = true } +plonky2 = { workspace = true } # Local dependencies mpt_trie = { version = "0.2.1", path = "../mpt_trie" } From 6bea2768951b1731bfe4738ce28d04fb258b291e Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Thu, 13 Jun 2024 09:39:12 -0400 Subject: [PATCH 043/118] Fix return from read_storage_linked_list_w_addr --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 926e3d253..9731db681 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -662,6 +662,8 @@ global remove_slot: %stack (addr, key) -> (addr, key, 0, %%after) %jump(search_slot) %%after: + // stack: cold_access, slot_ptr + POP %endmacro %macro first_account From 7660051fda17de3787fc7184eb96cf561f585738 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Thu, 13 Jun 2024 17:24:28 +0200 Subject: [PATCH 044/118] [WIP] debugging unit tests --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index dbd66b7e0..956a025a9 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -411,6 +411,7 @@ global debug_store_new_payload: SWAP1 DUP2 // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest +global debug_no_me_llamo_popotan: MSTORE_GENERAL // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest // If access_ctr == 1 then this it's a cold access @@ -465,6 +466,7 @@ next_node_ok: // Write the address in the new node DUP1 DUP4 +global debug_yo_no_me_llamo_javier: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the key in the new node From f0068aa55ea3a5f3cb6c320c5f9effa17f2b1d09 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Thu, 13 Jun 2024 14:41:23 -0400 Subject: [PATCH 045/118] Fix set_payload_storage_extension and bring back final gas check --- .../src/cpu/kernel/asm/main.asm | 3 +-- .../asm/mpt/linked_list/initial_tries.asm | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 1ebd9e520..35fbeeb72 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -105,8 +105,7 @@ global perform_final_checks: // Check that we end up with the correct `cum_gas`, `txn_nb` and bloom filter. %mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_AFTER) global debug_check_gas: - //%assert_eq - %pop2 + %assert_eq DUP3 %mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_AFTER) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index 675225a39..87885fba0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -56,7 +56,7 @@ global mpt_set_storage_payload: DUP1 %eq_const(@MPT_NODE_EMPTY) %jumpi(storage_skip) DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(set_payload_storage_branch) - DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_extension) + DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(set_payload_storage_extension) DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_storage_leaf) storage_skip: @@ -79,9 +79,9 @@ set_payload_branch: %stack (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> (child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, child_ptr_ptr) - // stack: child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: child_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, child_ptr_ptr, retdest %mload_trie_data - // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, %%after_encode, child_ptr_ptr, retdest + // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, child_ptr_ptr, retdest %mpt_set_payload // stack: account_ptr_ptr', storage_ptr_ptr', child_ptr_ptr, retdest SWAP1 @@ -114,12 +114,19 @@ set_payload_storage_branch: JUMP set_payload_extension: - // stack: node_type, after_node_type, (account_ptr_ptr,) storage_ptr_ptr, retdest + // stack: node_type, after_node_type, storage_ptr_ptr, retdest POP - // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: after_node_type, storage_ptr_ptr, retdest %add_const(2) %mload_trie_data - // stack: child_ptr, (account_ptr_ptr,) storage_ptr_ptr, retdest + // stack: child_ptr, after_node_type, storage_ptr_ptr, retdest %jump(mpt_set_payload) +set_payload_storage_extension: + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + POP + // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + %add_const(2) %mload_trie_data + // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + %jump(mpt_set_storage_payload) set_payload_leaf: // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest From a4c3f91ae9007a974e7df68b5b0e5a4dca2d87a8 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Fri, 14 Jun 2024 11:40:29 +0200 Subject: [PATCH 046/118] Fix failing shanghai blocks --- .../src/cpu/kernel/asm/mpt/delete/delete.asm | 5 ++-- .../asm/mpt/linked_list/final_tries.asm | 12 +++++--- .../asm/mpt/linked_list/initial_tries.asm | 6 ++-- .../asm/mpt/linked_list/linked_list.asm | 5 ++-- .../cpu/kernel/constants/global_metadata.rs | 5 +++- .../src/cpu/kernel/tests/account_code.rs | 6 ++-- evm_arithmetization/src/generation/mod.rs | 8 +++++ evm_arithmetization/src/generation/state.rs | 30 +++++-------------- 8 files changed, 41 insertions(+), 36 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index 9110d83b1..d249f6b55 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -14,11 +14,12 @@ global mpt_delete: DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(mpt_delete_branch) DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(mpt_delete_extension) DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(mpt_delete_leaf) + global debug_delete_empty_node: %eq_const(@MPT_NODE_EMPTY) %jumpi(panic) // This should never happen. PANIC -mpt_delete_leaf: +global mpt_delete_leaf: // stack: node_type, node_payload_ptr, num_nibbles, key, retdest %pop4 PUSH 0 // empty node ptr @@ -35,7 +36,7 @@ global delete_account: %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) // stack: state_root_prt, 64, key, delete_account_save, retdest %jump(mpt_delete) -delete_account_save: +global delete_account_save: // stack: updated_state_root_ptr, retdest %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 13ab418bd..df297d616 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -155,17 +155,21 @@ after_mpt_delete: %add_const(4) %jump(delete_removed_accounts) -// Delete all slots in `storage_ptr_ptr` with address == `addr`. +// Delete all slots in `storage_ptr_ptr` with address == `addr` and +// address < @GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN. // Pre stack: addr, root_ptr, storage_ptr_ptr, retdest // Post stack: new_root_ptr, storage_ptr_ptr'. -// TODO: If there are slots with the last address which where inserted -// and/or deleted, they will aso processed in `delete_this_slot`. This -// wouldn't represent any problem, but we should double-check. delete_removed_slots: DUP3 MLOAD_GENERAL DUP2 EQ + %mload_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) + DUP5 +global debug_in_inital_storage: + LT + MUL // AND + // jump if we either change the address or reach the en of the initial linked list %jumpi(maybe_delete_this_slot) // If we are here we have deleted all the slots for this key %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index 87885fba0..5140ed917 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -38,10 +38,12 @@ skip: %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) %jump(mpt_set_payload) %%after: - // We store account_ptr_ptr - 1, i.e. a pointer to the first node not in the initial state + // We store account_ptr_ptr - 1, i.e. a pointer to the first node not in the initial state. %decrement %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) - POP + // We store storage_ptr_ptr - 2, i.e. a pointer to the first node not in the initial state. + %sub_const(2) + %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) %endmacro // Pre stack: node_ptr, account_ptr_ptr, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 64be9ac8f..87fbb354a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -126,7 +126,6 @@ global insert_account_to_linked_list: %jump_neq_const(@U256_MAX, account_found) // The storage key is not in the list. PANIC - account_found: // The address was already in the list // stack: pred_ptr, addr, payload_ptr, retdest @@ -150,7 +149,7 @@ account_found: %eq_const(1) %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP - +//DEBUG insert_new_account: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest POP @@ -201,7 +200,7 @@ insert_new_account: %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) // stack: addr, payload_ptr, retdest // TODO: Don't for get to %journal_add_account_loaded - %stack (addr, payload_ptr, retdest) -> (0, retdest, payload_ptr) + %stack (addr, payload_ptr, retdest) -> (retdest, 0, payload_ptr) JUMP %macro search_account diff --git a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs index a302b482c..2fc55c4fa 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs @@ -102,10 +102,11 @@ pub(crate) enum GlobalMetadata { /// Segment::StorageLinkedList StorageLinkedListLen, InitialAccountsLinkedListLen, + InitialStorageLinkedListLen, } impl GlobalMetadata { - pub(crate) const COUNT: usize = 50; + pub(crate) const COUNT: usize = 51; /// Unscales this virtual offset by their respective `Segment` value. pub(crate) const fn unscale(&self) -> usize { @@ -164,6 +165,7 @@ impl GlobalMetadata { Self::AccountsLinkedListLen, Self::StorageLinkedListLen, Self::InitialAccountsLinkedListLen, + Self::InitialStorageLinkedListLen, ] } @@ -222,6 +224,7 @@ impl GlobalMetadata { Self::InitialAccountsLinkedListLen => { "GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN" } + Self::InitialStorageLinkedListLen => "GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN", } } } diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index b40f0a01b..f6f61fb4b 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -272,7 +272,6 @@ fn prepare_interpreter_all_accounts( addr: [u8; 20], code: &[u8], ) -> Result<()> { - init_logger(); // Load all MPTs. initialize_mpts(interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); @@ -305,6 +304,7 @@ fn prepare_interpreter_all_accounts( /// Tests an SSTORE within a code similar to the contract code in add11_yml. #[test] fn sstore() -> Result<()> { + init_logger(); // We take the same `to` account as in add11_yml. let addr = hex!("095e7baea6a6c7c4c2dfeb977efac326af552d87"); @@ -339,10 +339,12 @@ fn sstore() -> Result<()> { let init_accessed_addresses = KERNEL.global_labels["init_access_lists"]; interpreter.generation_state.registers.program_counter = init_accessed_addresses; interpreter.push(0xdeadbeefu32.into()); + log::debug!("coma comida"); interpreter.run()?; // Prepare the interpreter by inserting the account in the state trie. prepare_interpreter_all_accounts(&mut interpreter, trie_inputs, addr, &code)?; + log::debug!("cpto"); interpreter.run()?; @@ -396,7 +398,7 @@ fn sstore() -> Result<()> { /// Tests an SLOAD within a code similar to the contract code in add11_yml. #[test] fn sload() -> Result<()> { - // We take the same `to` account as in add11_yml. + init_logger(); // We take the same `to` account as in add11_yml. let addr = hex!("095e7baea6a6c7c4c2dfeb977efac326af552d87"); let addr_hashed = keccak(addr); diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index efb15775c..0373350e3 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -241,6 +241,14 @@ pub fn generate_traces, const D: usize>( "Trace lengths (before padding): {:?}", state.traces.get_lengths() ); + log::debug!( + "Final accounts linked list: {:?}", + state.get_accounts_linked_list() + ); + log::debug!( + "Final storage linked list: {:?}", + state.get_storage_linked_list() + ); let read_metadata = |field| state.memory.read_global_metadata(field); let trie_roots_before = TrieRoots { diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index b2fea0dd5..1aae8dd39 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -210,27 +210,6 @@ pub(crate) trait State { let checkpoint = self.checkpoint(); let result = self.try_perform_instruction(); - { - if self.get_clock() == 78246 { - let state_trie_ptr = u256_to_usize( - self.get_generation_state() - .memory - .read_global_metadata(GlobalMetadata::StateTrieRoot), - ) - .map_err(|_| anyhow!("State trie pointer is too large to fit in a usize."))?; - log::debug!( - "Final state trie: {:?}", - get_state_trie::( - &self.get_generation_state().memory, - state_trie_ptr - ) - ); - log::debug!( - "storage linked list = {:?}", - self.get_generation_state().get_storage_linked_list() - ) - } - } match result { Ok(op) => { self.apply_ops(checkpoint); @@ -389,7 +368,14 @@ impl GenerationState { }; let trie_root_ptrs = state.preinitialize_linked_lists_and_txn_and_receipt_mpts(&inputs.tries); - + log::debug!( + "Initial accounts linked list = {:?}", + state.get_accounts_linked_list() + ); + log::debug!( + "Initial storage linked list = {:?}", + state.get_storage_linked_list() + ); state.trie_root_ptrs = trie_root_ptrs; Ok(state) } From 3922c068bbb8f924fbf41687a43434ce2929145b Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 21 Jun 2024 16:17:13 +0100 Subject: [PATCH 047/118] Fix run_next_addresses_remove and some revertions --- .../cpu/kernel/asm/journal/account_destroyed.asm | 14 ++++++++------ .../cpu/kernel/asm/journal/account_loaded.asm | 1 - .../src/cpu/kernel/asm/journal/code_change.asm | 5 +++-- .../src/cpu/kernel/asm/journal/nonce_change.asm | 5 +++-- .../cpu/kernel/asm/journal/storage_change.asm | 16 ++-------------- .../src/generation/prover_input.rs | 2 +- 6 files changed, 17 insertions(+), 26 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index e784fd6b9..54eecd632 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -43,19 +43,21 @@ revert_account_destroyed_contd: // Remove `prev_balance` from `target`'s balance. // stack: target, address, prev_balance, retdest %read_accounts_linked_list - // stack: target_found, target_payload_ptr, address, prev_balance, retdest - // The target should have been accessed before - %assert_eq_const(1) %add_const(1) + // stack: cold_access, target_payload_ptr, address, prev_balance, retdest + POP + DUP1 %assert_nonzero + %add_const(1) // stack: target_balance_ptr, address, prev_balance, retdest DUP3 DUP2 %mload_trie_data // stack: target_balance, prev_balance, target_balance_ptr, address, prev_balance, retdest SUB SWAP1 %mstore_trie_data // stack: address, prev_balance, retdest %read_accounts_linked_list - // stack: address_found, account_payload, prev_balance, retdest - %assert_eq_const(1) + // stack: cold_access, account_payload_ptr, prev_balance, retdest + POP + DUP1 %assert_nonzero %increment - // stack: account_balance_payload, prev_balance, retdest + // stack: account_balance_payload_ptr, prev_balance, retdest %mstore_trie_data JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm index 4d3bb473c..d7da0a788 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_loaded.asm @@ -11,7 +11,6 @@ global revert_account_loaded: POP %journal_load_1 // stack: address, retdest - // TODO: remove 1 from the counter in the linked_lists. DUP1 %eq_const(@RIP160) %jumpi(ripemd) %jump(remove_accessed_addresses) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm index 5e902dc6a..c66febc77 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm @@ -10,8 +10,9 @@ global revert_code_change: %journal_load_2 // stack: address, prev_codehash, retdest %read_accounts_linked_list - // stack: address_found, account_ptr, prev_codehash, retdest - %assert_eq_const(1) + // stack: cold_access, account_ptr, prev_codehash, retdest + POP + DUP1 %assert_nonzero // stack: account_ptr, prev_codehash, retdest %add_const(3) // stack: codehash_ptr, prev_codehash, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm index 8ac1eee9e..7e299cd0f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm @@ -10,8 +10,9 @@ global revert_nonce_change: %journal_load_2 // stack: address, prev_nonce, retdest %read_accounts_linked_list - // stack: found_address, payload_ptr, prev_nonce, retdest - %assert_eq_const(1) // The address should already be present. + // stack: cold_access, payload_ptr, prev_nonce, retdest + POP + DUP1 %assert_nonzero // stack: nonce_ptr, prev_nonce retdest %mstore_trie_data // stack: retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm index 6dda9268e..60a39ce43 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm @@ -12,8 +12,8 @@ global revert_storage_change: DUP3 ISZERO %jumpi(delete) // stack: address, slot, prev_value, retdest %read_slot_linked_list - // stack: storage_found, cold_access, value_ptr, prev_value, retdest - %assert_eq_const(1) POP + // stack: cold_access, value_ptr, prev_value, retdest + POP DUP1 %assert_nonzero // stack: value_ptr, prev_value, retdest %mstore_trie_data JUMP @@ -26,15 +26,3 @@ delete: SWAP1 %addr_to_state_key // stack: addr_key, slot_key, retdest %jump(remove_slot) - -new_storage_root: - // stack: new_storage_root_ptr, address, retdest - DUP2 %mpt_read_state_trie - // stack: account_ptr, new_storage_root_ptr, address, retdest - - // Update account with our new storage root pointer. - %add_const(2) - // stack: account_storage_root_ptr_ptr, new_storage_root_ptr, address, retdest - %mstore_trie_data - // stack: address, retdest - POP JUMP diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 4f14fe4b1..e045454b7 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -387,7 +387,7 @@ impl GenerationState { let addr = stack_peek(self, 0)?; if let Some(([_, ptr], _)) = self .get_addresses_access_list()? - .zip(self.get_addresses_access_list()?.skip(1)) + .zip(self.get_addresses_access_list()?.skip(2)) .find(|&(_, [next_addr, _])| next_addr == addr) { Ok(ptr / U256::from(2)) From 24e6e6b4307b382d26f41f249a800c918c41c0f2 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Mon, 24 Jun 2024 08:18:41 +0100 Subject: [PATCH 048/118] Some journaling fixes --- .../src/cpu/kernel/asm/journal/account_destroyed.asm | 6 ++---- .../src/cpu/kernel/asm/journal/code_change.asm | 3 +-- .../src/cpu/kernel/asm/journal/nonce_change.asm | 5 ++--- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index 54eecd632..2a6606b76 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -43,8 +43,7 @@ revert_account_destroyed_contd: // Remove `prev_balance` from `target`'s balance. // stack: target, address, prev_balance, retdest %read_accounts_linked_list - // stack: cold_access, target_payload_ptr, address, prev_balance, retdest - POP + // stack: target_payload_ptr, address, prev_balance, retdest DUP1 %assert_nonzero %add_const(1) // stack: target_balance_ptr, address, prev_balance, retdest @@ -53,8 +52,7 @@ revert_account_destroyed_contd: SUB SWAP1 %mstore_trie_data // stack: address, prev_balance, retdest %read_accounts_linked_list - // stack: cold_access, account_payload_ptr, prev_balance, retdest - POP + // stack: account_payload_ptr, prev_balance, retdest DUP1 %assert_nonzero %increment // stack: account_balance_payload_ptr, prev_balance, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm index c66febc77..0fc33f9dd 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/code_change.asm @@ -10,8 +10,7 @@ global revert_code_change: %journal_load_2 // stack: address, prev_codehash, retdest %read_accounts_linked_list - // stack: cold_access, account_ptr, prev_codehash, retdest - POP + // stack: account_ptr, prev_codehash, retdest DUP1 %assert_nonzero // stack: account_ptr, prev_codehash, retdest %add_const(3) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm index 7e299cd0f..397957e0b 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/nonce_change.asm @@ -10,10 +10,9 @@ global revert_nonce_change: %journal_load_2 // stack: address, prev_nonce, retdest %read_accounts_linked_list - // stack: cold_access, payload_ptr, prev_nonce, retdest - POP + // stack: payload_ptr, prev_nonce, retdest DUP1 %assert_nonzero - // stack: nonce_ptr, prev_nonce retdest + // stack: nonce_ptr, prev_nonce, retdest %mstore_trie_data // stack: retdest JUMP From 4355a511d7607d5e2b3aed7e8bc08ae2a7eca942 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Mon, 24 Jun 2024 14:43:29 +0100 Subject: [PATCH 049/118] FIx revert_storage_change and revert_account_created --- .../kernel/asm/journal/account_created.asm | 1 + .../cpu/kernel/asm/journal/storage_change.asm | 8 +- .../asm/mpt/linked_list/linked_list.asm | 162 +++++++++++++++++- 3 files changed, 163 insertions(+), 8 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm index 5dc446167..6e72cb8b2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm @@ -9,5 +9,6 @@ global revert_account_created: POP %journal_load_1 // stack: address, retdest + %addr_to_state_key %remove_account_from_linked_list JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm index 60a39ce43..b6ca4edcb 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm @@ -11,11 +11,9 @@ global revert_storage_change: // stack: address, slot, prev_value, retdest DUP3 ISZERO %jumpi(delete) // stack: address, slot, prev_value, retdest - %read_slot_linked_list - // stack: cold_access, value_ptr, prev_value, retdest - POP DUP1 %assert_nonzero - // stack: value_ptr, prev_value, retdest - %mstore_trie_data + %insert_slot_with_value + // stack: cold_access, value_ptr + %pop2 JUMP delete: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 87fbb354a..f528d9690 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -126,7 +126,7 @@ global insert_account_to_linked_list: %jump_neq_const(@U256_MAX, account_found) // The storage key is not in the list. PANIC -account_found: +global account_found: // The address was already in the list // stack: pred_ptr, addr, payload_ptr, retdest // Load the the payload pointer and access counter @@ -150,7 +150,7 @@ account_found: %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) JUMP //DEBUG -insert_new_account: +global insert_new_account: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest POP // get the value of the next address @@ -309,7 +309,7 @@ global remove_account: %stack (addr, key, ptr) -> (addr, key, ptr, %%after) %jump(insert_slot) %%after: - // stack: cold_access + // stack: cold_access, value_ptr %endmacro %macro insert_slot_no_return @@ -335,6 +335,162 @@ global remove_account: %add_const(@SEGMENT_STORAGE_LINKED_LIST) %endmacro +/// Inserts the pair (addres, storage_key) and a new payload pointer into the linked list if it is not already present, +/// or modify its payload if it was already present. +/// Return `1, new_payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present +/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +global insert_slot_with_value: + // stack: addr, key, value, retdest + PROVER_INPUT(linked_list::insert_slot) + // stack: pred_ptr/5, addr, key, value, retdest + %get_valid_slot_ptr + + // stack: pred_ptr, addr, key, value, retdest + DUP1 + MLOAD_GENERAL + DUP1 + // stack: pred_addr, pred_addr, pred_ptr, addr, key, value, retdest + DUP4 + GT + DUP3 %eq_const(@SEGMENT_STORAGE_LINKED_LIST) + ADD // OR + // If the predesessor is strictly smaller or the predecessor is the special + // node with key @U256_MAX (and hence we're inserting a new minimum), then + // we need to insert a new node. + %jumpi(insert_new_slot_with_value) + // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. + DUP3 + %assert_eq + // stack: pred_ptr, addr, key, value, retdest + DUP1 + %increment + MLOAD_GENERAL + // stack: pred_key, pred_ptr, addr, key, value, retdest + DUP1 DUP5 + GT + %jumpi(insert_new_slot_with_value) + // stack: pred_key, pred_ptr, addr, key, value, retdest + DUP4 + // We know that key <= pred_key. It must hold that pred_key == key. + %assert_eq + + // stack: pred_ptr, addr, key, value, retdest + // Check that this is not a deleted node + DUP1 + %add_const(4) + MLOAD_GENERAL + %jump_neq_const(@U256_MAX, slot_found_write_value) + // The storage key is not in the list. + PANIC + +insert_new_slot_with_value: + // stack: pred_addr or pred_key, pred_ptr, addr, key, value, retdest + POP + // get the value of the next address + %add_const(4) + // stack: next_ptr_ptr, addr, key, value, retdest + %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) + DUP2 + MLOAD_GENERAL + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // Check that this is not a deleted node + DUP1 + %eq_const(@U256_MAX) + %assert_zero + DUP1 + MLOAD_GENERAL + // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + DUP1 + DUP6 + // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). + // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. + LT + %jumpi(next_node_ok) + // If addr <= next_addr, then it addr must be equal to next_addr + // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + DUP5 + %assert_eq + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + DUP1 + %increment + MLOAD_GENERAL + // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + DUP1 // This is added just to have the correct stack in next_node_ok + DUP7 + // The next key must be strictly larger + %assert_lt +next_node_ok_with_value: + // stack: next_addr or next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + POP + // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + SWAP2 + DUP2 + // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, key, value, retdest + MSTORE_GENERAL + // stack: new_ptr, next_ptr, addr, key, value, retdest + // Write the address in the new node + DUP1 + DUP4 +global debug_yo_no_me_llamo_javier_with_value: + MSTORE_GENERAL + // stack: new_ptr, next_ptr, addr, key, value, retdest + // Write the key in the new node + %increment + DUP1 + DUP5 + MSTORE_GENERAL + // stack: new_ptr + 1, next_ptr, addr, key, value, retdest + // Append the value to `TrieDataSegment` and write the resulting payload_ptr. + %increment + DUP1 + %get_trie_data_size + // stack: new_payload_ptr, new_ptr+2, new_ptr+2, next_ptr, addr, key, value, retdest + %stack (new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr, key, value) -> (value, new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr, key, new_payload_ptr) + %append_to_trie_data + MSTORE_GENERAL + + // stack: new_ptr + 2, next_ptr, addr, key, new_payload_ptr, retdest + // Store the counter + %increment + DUP1 + PUSH 0 + MSTORE_GENERAL + // stack: new_ptr + 3, next_ptr, addr, key, new_payload_ptr, retdest + %increment + DUP1 + // stack: new_next_ptr, new_next_ptr, next_ptr, addr, key, new_payload_ptr, retdest + SWAP2 + MSTORE_GENERAL + // stack: new_next_ptr, addr, key, new_payload_ptr, retdest + %increment + %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) + // stack: addr, key, new_payload_ptr, retdest + %pop2 + PUSH 0 + SWAP1 + SWAP2 + JUMP + +slot_found_write_value: + // stack: pred_ptr, addr, key, value, retdest + %add_const(2) MLOAD_GENERAL + %stack (payload_ptr, addr, key, value) -> (payload_ptr, value, payload_ptr) + %mstore_trie_data + // stack: payload_ptr, retdest + // the cold_access is no longer used here, so we can set any value. + %stack (payload_ptr, retdest) -> (retdest, 0, payload_ptr) + JUMP + +%macro insert_slot_with_value + %stack (addr, slot, value) -> (addr, slot, value, %%after) + SWAP1 %slot_to_storage_key + SWAP1 %addr_to_state_key + %jump(insert_slot_with_value) +%%after: + // stack: cold_access, value_ptr +%endmacro + /// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present, /// or modify its payload if it was already present. /// Return `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present From 33235a9be5b3991dcb2b85af46917e783a292553 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Mon, 24 Jun 2024 17:23:09 +0200 Subject: [PATCH 050/118] Fix delete account --- evm_arithmetization/src/cpu/kernel/asm/main.asm | 1 + .../src/cpu/kernel/asm/mpt/delete/delete.asm | 12 +----------- evm_arithmetization/src/generation/mod.rs | 11 +++++------ evm_arithmetization/tests/add11_yml.rs | 5 ++++- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 35fbeeb72..bd13e0dca 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -113,6 +113,7 @@ global debug_check_txn_number: %assert_eq %pop3 PUSH 1 // initial trie data length + global check_state_trie: %set_final_tries %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index d249f6b55..46db25f98 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -26,19 +26,9 @@ global mpt_delete_leaf: SWAP1 JUMP global delete_account: - %stack (address, retdest) -> (address, delete_account_save, retdest) %addr_to_state_key - DUP1 %remove_account_from_linked_list - // stack: key, delete_account_save, retdest - PUSH 64 - // stack: 64, key, delete_account_save, retdest - %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) - // stack: state_root_prt, 64, key, delete_account_save, retdest - %jump(mpt_delete) -global delete_account_save: - // stack: updated_state_root_ptr, retdest - %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + // retdest JUMP %macro delete_account diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 0373350e3..0f0f877ee 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -231,12 +231,6 @@ pub fn generate_traces, const D: usize>( let cpu_res = timed!(timing, "simulate CPU", simulate_cpu(&mut state)); - if cpu_res.is_err() { - let _ = output_debug_tries(&state); - - cpu_res?; - } - log::info!( "Trace lengths (before padding): {:?}", state.traces.get_lengths() @@ -250,6 +244,11 @@ pub fn generate_traces, const D: usize>( state.get_storage_linked_list() ); + if cpu_res.is_err() { + let _ = output_debug_tries(&state); + + cpu_res?; + } let read_metadata = |field| state.memory.read_global_metadata(field); let trie_roots_before = TrieRoots { state_root: H256::from_uint(&read_metadata(StateTrieRootDigestBefore)), diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 8c60af18b..a4b899305 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -165,7 +165,10 @@ fn add11_yml() -> anyhow::Result<()> { }, }; - let bytes = std::fs::read("./TouchToEmptyAccountRevert_d0g0v0_Shanghai.json").unwrap(); + let bytes = std::fs::read( + "/Users/agonzalez/Downloads/TouchToEmptyAccountRevert3_Paris_d0g0v0_Shanghai.json", + ) + .unwrap(); let inputs = serde_json::from_slice(&bytes).unwrap(); let mut timing = TimingTree::new("prove", log::Level::Debug); From f54864a2fcf7a8b4b7e1b6ff8fa14eab6fc1e202 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Mon, 24 Jun 2024 17:54:20 +0200 Subject: [PATCH 051/118] [WIP] fixing LoopCallsDepthThenRevert3_d0g0v0_Shanghai.json --- evm_arithmetization/tests/add11_yml.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index a4b899305..cf5d06b61 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -165,10 +165,9 @@ fn add11_yml() -> anyhow::Result<()> { }, }; - let bytes = std::fs::read( - "/Users/agonzalez/Downloads/TouchToEmptyAccountRevert3_Paris_d0g0v0_Shanghai.json", - ) - .unwrap(); + let bytes = + std::fs::read("/Users/agonzalez/Downloads/LoopCallsDepthThenRevert3_d0g0v0_Shanghai.json") + .unwrap(); let inputs = serde_json::from_slice(&bytes).unwrap(); let mut timing = TimingTree::new("prove", log::Level::Debug); From 89450029ccce73eb641f4c0e5107a6dbf0b5a50f Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 25 Jun 2024 14:28:01 +0100 Subject: [PATCH 052/118] Add an overwrite version of account insertion and use it for mpt_insert_state_trie --- .../RevertOpcodeReturn_d5g0v0_Shanghai.json | 1665 ----------- ...recompiledTouch_nonce_d0g0v0_Shanghai.json | 2597 ----------------- ...hToEmptyAccountRevert_d0g0v0_Shanghai.json | 919 ------ .../asm/mpt/insert/insert_trie_specific.asm | 2 +- .../asm/mpt/linked_list/linked_list.asm | 67 + evm_arithmetization/tests/add11_yml.rs | 8 +- 6 files changed, 69 insertions(+), 5189 deletions(-) delete mode 100644 evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json delete mode 100644 evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json delete mode 100644 evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json diff --git a/evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json b/evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json deleted file mode 100644 index 42e20cd82..000000000 --- a/evm_arithmetization/RevertOpcodeReturn_d5g0v0_Shanghai.json +++ /dev/null @@ -1,1665 +0,0 @@ -{ - "txn_number_before": "0x0", - "gas_used_before": "0x0", - "gas_used_after": "0xc47f", - "signed_txn": [ - 248, - 128, - 128, - 10, - 131, - 12, - 53, - 0, - 148, - 160, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 128, - 160, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 166, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 27, - 160, - 97, - 145, - 39, - 137, - 40, - 226, - 6, - 123, - 99, - 190, - 156, - 203, - 125, - 224, - 240, - 146, - 148, - 148, - 14, - 215, - 23, - 249, - 230, - 222, - 139, - 224, - 1, - 119, - 92, - 87, - 205, - 42, - 160, - 70, - 2, - 193, - 98, - 140, - 130, - 135, - 18, - 187, - 237, - 75, - 2, - 254, - 199, - 39, - 29, - 79, - 99, - 15, - 183, - 49, - 48, - 182, - 174, - 14, - 49, - 207, - 204, - 24, - 110, - 143, - 67 - ], - "withdrawals": [], - "tries": { - "state_trie": { - "node": { - "Branch": { - "children": [ - { - "node": { - "Branch": { - "children": [ - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b" - }, - "value": [ - 248, - 73, - 128, - 133, - 232, - 212, - 165, - 16, - 0, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x75f0b26f88f770e01663ec33a25e55811909f7bd5dab82adfd887cbc08f20a" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 46, - 157, - 184, - 97, - 252, - 213, - 85, - 125, - 137, - 84, - 132, - 86, - 255, - 200, - 113, - 58, - 248, - 160, - 127, - 76, - 142, - 41, - 70, - 82, - 70, - 188, - 166, - 12, - 213, - 180, - 236, - 251 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - { - "node": { - "Branch": { - "children": [ - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0xf4ef70c3ea31780ddd533d1f46a7762f2bc3e6048a81904b62b8062b2c6d80" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 117, - 163, - 129, - 247, - 227, - 251, - 14, - 161, - 46, - 47, - 247, - 69, - 9, - 80, - 203, - 213, - 198, - 237, - 140, - 9, - 90, - 106, - 60, - 124, - 245, - 89, - 130, - 18, - 54, - 196, - 5, - 26 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0xe1c4c06eb7b427d20523ecb932e178aea42b4a45aa257839c4b37bae957de9" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 158, - 41, - 36, - 86, - 58, - 229, - 12, - 114, - 130, - 209, - 191, - 178, - 214, - 220, - 14, - 197, - 163, - 57, - 45, - 129, - 97, - 127, - 22, - 133, - 174, - 186, - 243, - 140, - 154, - 86, - 44, - 160 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0xe879e4e9f9faf2fbf45290292a78494b3b6fadacf3a7caadca41807c38b0335" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 79, - 240, - 66, - 127, - 37, - 76, - 40, - 99, - 166, - 17, - 46, - 133, - 19, - 7, - 96, - 75, - 161, - 208, - 56, - 22, - 13, - 50, - 33, - 113, - 147, - 3, - 101, - 197, - 15, - 0, - 86, - 117 - ] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0x3caabbefe324ab0bb367d394c5a23dac16c2345c81aa31c64df17b2d08f4923" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 166, - 64, - 93, - 42, - 27, - 0, - 87, - 147, - 160, - 244, - 226, - 18, - 198, - 94, - 126, - 7, - 186, - 111, - 72, - 254, - 7, - 79, - 223, - 213, - 8, - 90, - 79, - 40, - 46, - 234, - 44, - 168 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0xf2d5e7543485f45278e9b1f6a487feb4aec678d527e129b7aece8e583fe4f72" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 42, - 72, - 207, - 249, - 70, - 175, - 179, - 47, - 141, - 79, - 188, - 140, - 179, - 211, - 8, - 0, - 162, - 22, - 59, - 43, - 46, - 10, - 23, - 7, - 97, - 212, - 241, - 158, - 2, - 105, - 210, - 227 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0xa44ec1b61dc56f96d53050f431a760686e5993b54b75377ced5f391463d3221" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 140, - 59, - 155, - 157, - 144, - 153, - 113, - 135, - 171, - 27, - 158, - 202, - 251, - 199, - 164, - 5, - 70, - 195, - 82, - 251, - 239, - 175, - 83, - 4, - 47, - 197, - 35, - 9, - 192, - 148, - 53, - 56 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - "transactions_trie": { - "node": "Empty", - "hash": null - }, - "receipts_trie": { - "node": "Empty", - "hash": null - }, - "storage_tries": [ - [ - "0x03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x2e879e4e9f9faf2fbf45290292a78494b3b6fadacf3a7caadca41807c38b0335", - { - "node": "Empty", - "hash": null - } - ], - [ - "0xca44ec1b61dc56f96d53050f431a760686e5993b54b75377ced5f391463d3221", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x1ee1c4c06eb7b427d20523ecb932e178aea42b4a45aa257839c4b37bae957de9", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x0575f0b26f88f770e01663ec33a25e55811909f7bd5dab82adfd887cbc08f20a", - { - "node": "Empty", - "hash": null - } - ], - [ - "0xaf2d5e7543485f45278e9b1f6a487feb4aec678d527e129b7aece8e583fe4f72", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x33caabbefe324ab0bb367d394c5a23dac16c2345c81aa31c64df17b2d08f4923", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x14f4ef70c3ea31780ddd533d1f46a7762f2bc3e6048a81904b62b8062b2c6d80", - { - "node": "Empty", - "hash": null - } - ] - ] - }, - "trie_roots_after": { - "state_root": "0x39026113150402cf108f83cdf9e9c20b385b6cd2f40400736cb2b06e96235c3d", - "transactions_root": "0x7b87ed13feb0c9d9c5af9a834c70404fe6ab32c193c8def8266079108b2fb74d", - "receipts_root": "0xcabd56ba2ce6a126085d2f765c183bcea25b6cab61c78645368fde791b9067fa" - }, - "checkpoint_state_trie_root": "0xc0a86da777f09fac0d7c321cbd5c32425b7ced34a5fd3efb6d55dbe13bce5120", - "contract_code": { - "0x75a381f7e3fb0ea12e2ff7450950cbd5c6ed8c095a6a3c7cf559821236c4051a": [ - 108, - 114, - 101, - 118, - 101, - 114, - 116, - 101, - 100, - 32, - 100, - 97, - 116, - 97, - 96, - 0, - 85, - 109, - 114, - 101, - 118, - 101, - 114, - 116, - 32, - 109, - 101, - 115, - 115, - 97, - 103, - 101, - 96, - 0, - 82, - 96, - 0, - 110, - 15, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 253, - 0 - ], - "0x4ff0427f254c2863a6112e851307604ba1d038160d322171930365c50f005675": [ - 108, - 114, - 101, - 118, - 101, - 114, - 116, - 101, - 100, - 32, - 100, - 97, - 116, - 97, - 96, - 0, - 85, - 109, - 114, - 101, - 118, - 101, - 114, - 116, - 32, - 109, - 101, - 115, - 115, - 97, - 103, - 101, - 96, - 0, - 82, - 96, - 0, - 96, - 0, - 253, - 0 - ], - "0xa6405d2a1b005793a0f4e212c65e7e07ba6f48fe074fdfd5085a4f282eea2ca8": [ - 108, - 114, - 101, - 118, - 101, - 114, - 116, - 101, - 100, - 32, - 100, - 97, - 116, - 97, - 96, - 0, - 85, - 109, - 114, - 101, - 118, - 101, - 114, - 116, - 32, - 109, - 101, - 115, - 115, - 97, - 103, - 101, - 96, - 0, - 82, - 96, - 32, - 96, - 0, - 253, - 0 - ], - "0x2e9db861fcd5557d89548456ffc8713af8a07f4c8e29465246bca60cd5b4ecfb": [ - 96, - 32, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 53, - 98, - 2, - 73, - 240, - 241, - 96, - 1, - 85, - 96, - 0, - 81, - 96, - 2, - 85, - 0 - ], - "0x2a48cff946afb32f8d4fbc8cb3d30800a2163b2b2e0a170761d4f19e0269d2e3": [ - 108, - 114, - 101, - 118, - 101, - 114, - 116, - 101, - 100, - 32, - 100, - 97, - 116, - 97, - 96, - 0, - 85, - 109, - 114, - 101, - 118, - 101, - 114, - 116, - 32, - 109, - 101, - 115, - 115, - 97, - 103, - 101, - 96, - 0, - 82, - 110, - 15, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 96, - 0, - 253, - 0 - ], - "0x9e2924563ae50c7282d1bfb2d6dc0ec5a3392d81617f1685aebaf38c9a562ca0": [ - 108, - 114, - 101, - 118, - 101, - 114, - 116, - 101, - 100, - 32, - 100, - 97, - 116, - 97, - 96, - 0, - 85, - 109, - 114, - 101, - 118, - 101, - 114, - 116, - 32, - 109, - 101, - 115, - 115, - 97, - 103, - 101, - 96, - 0, - 82, - 96, - 0, - 97, - 1, - 0, - 253, - 0 - ], - "0x8c3b9b9d90997187ab1b9ecafbc7a40546c352fbefaf53042fc52309c0943538": [ - 108, - 114, - 101, - 118, - 101, - 114, - 116, - 101, - 100, - 32, - 100, - 97, - 116, - 97, - 96, - 0, - 85, - 109, - 114, - 101, - 118, - 101, - 114, - 116, - 32, - 109, - 101, - 115, - 115, - 97, - 103, - 101, - 96, - 0, - 82, - 96, - 0, - 96, - 1, - 253, - 0 - ], - "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470": [] - }, - "block_metadata": { - "block_beneficiary": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "block_timestamp": "0x3e8", - "block_number": "0x1", - "block_difficulty": "0x0", - "block_random": "0x0000000000000000000000000000000000000000000000000000000000020000", - "block_gaslimit": "0x989680", - "block_chain_id": "0x1", - "block_base_fee": "0xa", - "block_gas_used": "0xc47f", - "block_bloom": [ - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0" - ] - }, - "block_hashes": { - "prev_hashes": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "cur_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } -} \ No newline at end of file diff --git a/evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json b/evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json deleted file mode 100644 index aa4f33d79..000000000 --- a/evm_arithmetization/RevertPrecompiledTouch_nonce_d0g0v0_Shanghai.json +++ /dev/null @@ -1,2597 +0,0 @@ -{ - "txn_number_before": "0x0", - "gas_used_before": "0x0", - "gas_used_after": "0x181f9", - "signed_txn": [ - 248, - 128, - 1, - 10, - 131, - 1, - 134, - 160, - 148, - 185, - 79, - 83, - 116, - 252, - 229, - 237, - 188, - 142, - 42, - 134, - 151, - 193, - 83, - 49, - 103, - 126, - 110, - 191, - 11, - 128, - 160, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 16, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 28, - 160, - 39, - 163, - 198, - 206, - 58, - 195, - 37, - 170, - 219, - 26, - 211, - 132, - 63, - 131, - 105, - 140, - 172, - 250, - 122, - 132, - 233, - 138, - 140, - 80, - 221, - 146, - 0, - 59, - 244, - 35, - 195, - 219, - 160, - 77, - 207, - 249, - 221, - 19, - 184, - 124, - 9, - 5, - 249, - 187, - 65, - 87, - 116, - 63, - 200, - 142, - 253, - 1, - 15, - 253, - 5, - 150, - 207, - 122, - 90, - 122, - 112, - 109, - 138, - 76, - 39 - ], - "withdrawals": [], - "tries": { - "state_trie": { - "node": { - "Branch": { - "children": [ - { - "node": { - "Branch": { - "children": [ - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b" - }, - "value": [ - 248, - 76, - 1, - 136, - 13, - 224, - 182, - 179, - 167, - 100, - 0, - 0, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x97a8ae1be85d5cb9bf7eabf07bf2b5aefb0b4e89cb4e138147f6a841ad22c0" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 209, - 134, - 10, - 175, - 222, - 137, - 33, - 140, - 185, - 0, - 0, - 231, - 29, - 6, - 215, - 5, - 173, - 174, - 97, - 243, - 106, - 255, - 1, - 115, - 112, - 27, - 115, - 120, - 112, - 242, - 50, - 247 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0x468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Branch": { - "children": [ - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x1df1fa259221d02aa4956eb0d35ace318ca24c0a33a64c1af96cf67cf245b6" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x1703c5eda8644a64cec152c58f5aacec93d72fb0bfa705f0473f9043a8357c" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x38f86bb73787385f15c8c5e9b870cb8011b5bfb4ffce95207317bce6193fcb" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 223, - 194, - 50, - 238, - 5, - 13, - 83, - 147, - 20, - 172, - 208, - 19, - 240, - 219, - 13, - 172, - 245, - 47, - 70, - 25, - 78, - 63, - 225, - 9, - 42, - 1, - 163, - 30, - 144, - 98, - 95, - 57 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0xb70e80538acdabd6137353b0f9d8d149f4dba91e8be2e7946e409bfdbe685b9" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0x89802d6ed1a28b049e9d4fe5334c5902fd9bc00c42821c82f82ee2da10be908" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Branch": { - "children": [ - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x3ab0970b73895b8c9959bae685c3a19f45eb5ad89d42b52a340ec4ac204d19" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0xfad888a2f79bcfe6633c369a5652e94379f63f5849d8e8fe519c586bb49633" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 204, - 8, - 96, - 247, - 209, - 100, - 9, - 104, - 167, - 16, - 166, - 84, - 71, - 3, - 225, - 110, - 135, - 211, - 243, - 27, - 187, - 69, - 131, - 14, - 139, - 239, - 97, - 87, - 11, - 169, - 110, - 245 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0x876da518a393dbd067dc72abfa08d475ed6447fca96d92ec3f9e7eba503ca61" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Branch": { - "children": [ - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0xc30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 144, - 180, - 176, - 252, - 26, - 173, - 212, - 27, - 37, - 52, - 240, - 180, - 27, - 190, - 115, - 62, - 6, - 178, - 7, - 106, - 117, - 141, - 115, - 25, - 174, - 231, - 110, - 21, - 154, - 250, - 125, - 238 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 62, - "packed": "0x2688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62" - }, - "value": [ - 248, - 68, - 1, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0xe51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 139, - 200, - 165, - 23, - 242, - 254, - 139, - 247, - 239, - 111, - 77, - 55, - 66, - 199, - 107, - 246, - 84, - 182, - 176, - 183, - 159, - 232, - 222, - 22, - 156, - 195, - 182, - 203, - 153, - 223, - 111, - 206 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - "transactions_trie": { - "node": "Empty", - "hash": null - }, - "receipts_trie": { - "node": "Empty", - "hash": null - }, - "storage_tries": [ - [ - "0x03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b", - { - "node": "Empty", - "hash": null - } - ], - [ - "0xd0c30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b", - { - "node": "Empty", - "hash": null - } - ], - [ - "0xee51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x0797a8ae1be85d5cb9bf7eabf07bf2b5aefb0b4e89cb4e138147f6a841ad22c0", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x5b70e80538acdabd6137353b0f9d8d149f4dba91e8be2e7946e409bfdbe685b9", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x471703c5eda8644a64cec152c58f5aacec93d72fb0bfa705f0473f9043a8357c", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x421df1fa259221d02aa4956eb0d35ace318ca24c0a33a64c1af96cf67cf245b6", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x8dfad888a2f79bcfe6633c369a5652e94379f63f5849d8e8fe519c586bb49633", - { - "node": "Empty", - "hash": null - } - ], - [ - "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62", - { - "node": "Empty", - "hash": null - } - ], - [ - "0xa876da518a393dbd067dc72abfa08d475ed6447fca96d92ec3f9e7eba503ca61", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x689802d6ed1a28b049e9d4fe5334c5902fd9bc00c42821c82f82ee2da10be908", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x8c3ab0970b73895b8c9959bae685c3a19f45eb5ad89d42b52a340ec4ac204d19", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x4b38f86bb73787385f15c8c5e9b870cb8011b5bfb4ffce95207317bce6193fcb", - { - "node": "Empty", - "hash": null - } - ] - ] - }, - "trie_roots_after": { - "state_root": "0x0fc37c246046ade1d363dccec6ccd0ecd8bb8a7f9ce6cc8f3f4cfdce0aa00c2b", - "transactions_root": "0xf77c8817ce7d022d381d0ea642545b06c550b4d882cf2f86799585367ed0ded1", - "receipts_root": "0xaab2111847f2d64d9574f3a287dce44aec2164a59b6f2b766e7956f9a046631e" - }, - "checkpoint_state_trie_root": "0x0a1503e7df13898f4abb85e5baa9e54cc9232946b87ac39f9191945cf744585a", - "contract_code": { - "0x8bc8a517f2fe8bf7ef6f4d3742c76bf654b6b0b79fe8de169cc3b6cb99df6fce": [ - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 1, - 97, - 195, - 80, - 241, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 2, - 97, - 195, - 80, - 241, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 3, - 97, - 195, - 80, - 241, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 4, - 97, - 195, - 80, - 241, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 5, - 97, - 195, - 80, - 241, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 6, - 97, - 195, - 80, - 241, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 7, - 97, - 195, - 80, - 241, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 8, - 97, - 195, - 80, - 241, - 80, - 90, - 96, - 1, - 85, - 90, - 96, - 2, - 85, - 90, - 96, - 3, - 85, - 0 - ], - "0x90b4b0fc1aadd41b2534f0b41bbe733e06b2076a758d7319aee76e159afa7dee": [ - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 53, - 90, - 242, - 0 - ], - "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470": [], - "0xcc0860f7d1640968a710a6544703e16e87d3f31bbb45830e8bef61570ba96ef5": [ - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 1, - 97, - 195, - 80, - 244, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 2, - 97, - 195, - 80, - 244, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 3, - 97, - 195, - 80, - 244, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 4, - 97, - 195, - 80, - 244, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 5, - 97, - 195, - 80, - 244, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 6, - 97, - 195, - 80, - 244, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 7, - 97, - 195, - 80, - 244, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 8, - 97, - 195, - 80, - 244, - 80, - 90, - 96, - 1, - 85, - 90, - 96, - 2, - 85, - 90, - 96, - 3, - 85, - 0 - ], - "0xdfc232ee050d539314acd013f0db0dacf52f46194e3fe1092a01a31e90625f39": [ - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 1, - 97, - 195, - 80, - 242, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 2, - 97, - 195, - 80, - 242, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 3, - 97, - 195, - 80, - 242, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 4, - 97, - 195, - 80, - 242, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 5, - 97, - 195, - 80, - 242, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 6, - 97, - 195, - 80, - 242, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 7, - 97, - 195, - 80, - 242, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 8, - 97, - 195, - 80, - 242, - 80, - 90, - 96, - 1, - 85, - 90, - 96, - 2, - 85, - 90, - 96, - 3, - 85, - 0 - ], - "0xd1860aafde89218cb90000e71d06d705adae61f36aff0173701b737870f232f7": [ - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 1, - 97, - 195, - 80, - 250, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 2, - 97, - 195, - 80, - 250, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 3, - 97, - 195, - 80, - 250, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 4, - 97, - 195, - 80, - 250, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 5, - 97, - 195, - 80, - 250, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 6, - 97, - 195, - 80, - 250, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 7, - 97, - 195, - 80, - 250, - 80, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 8, - 97, - 195, - 80, - 250, - 80, - 90, - 96, - 1, - 85, - 90, - 96, - 2, - 85, - 90, - 96, - 3, - 85, - 0 - ] - }, - "block_metadata": { - "block_beneficiary": "0x68795c4aa09d6f4ed3e5deddf8c2ad3049a601da", - "block_timestamp": "0x3e8", - "block_number": "0x1", - "block_difficulty": "0x0", - "block_random": "0x0000000000000000000000000000000000000000000000000000000000020000", - "block_gaslimit": "0x3d37ef", - "block_chain_id": "0x1", - "block_base_fee": "0xa", - "block_gas_used": "0x181f9", - "block_bloom": [ - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0" - ] - }, - "block_hashes": { - "prev_hashes": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "cur_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } -} diff --git a/evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json b/evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json deleted file mode 100644 index 208c61413..000000000 --- a/evm_arithmetization/TouchToEmptyAccountRevert_d0g0v0_Shanghai.json +++ /dev/null @@ -1,919 +0,0 @@ -{ - "txn_number_before": "0x0", - "gas_used_before": "0x0", - "gas_used_after": "0x11170", - "signed_txn": [ - 248, - 96, - 128, - 10, - 131, - 1, - 17, - 112, - 148, - 185, - 79, - 83, - 116, - 252, - 229, - 237, - 188, - 142, - 42, - 134, - 151, - 193, - 83, - 49, - 103, - 126, - 110, - 191, - 11, - 128, - 128, - 27, - 160, - 234, - 33, - 187, - 131, - 142, - 200, - 27, - 241, - 114, - 60, - 209, - 202, - 196, - 203, - 137, - 102, - 148, - 118, - 26, - 84, - 141, - 156, - 88, - 49, - 188, - 99, - 72, - 171, - 253, - 26, - 107, - 78, - 160, - 93, - 82, - 87, - 160, - 215, - 167, - 188, - 28, - 157, - 80, - 255, - 2, - 72, - 129, - 118, - 143, - 105, - 220, - 94, - 101, - 127, - 83, - 235, - 54, - 212, - 177, - 133, - 26, - 218, - 72, - 52, - 124 - ], - "withdrawals": [], - "tries": { - "state_trie": { - "node": { - "Branch": { - "children": [ - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0x3601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b" - }, - "value": [ - 248, - 73, - 128, - 133, - 232, - 212, - 165, - 16, - 0, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0x320ca9fbb7bc02ec98c352627dc8fbe89a00c1e6c0b19c60e9234718b2bc149" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 102, - 221, - 57, - 212, - 200, - 246, - 26, - 95, - 240, - 178, - 222, - 92, - 239, - 39, - 239, - 185, - 37, - 163, - 117, - 214, - 178, - 248, - 170, - 25, - 29, - 73, - 228, - 237, - 84, - 92, - 8, - 222 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": "Empty", - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0xc30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 220, - 36, - 63, - 39, - 89, - 23, - 47, - 152, - 149, - 30, - 41, - 211, - 83, - 224, - 114, - 132, - 76, - 34, - 8, - 142, - 17, - 42, - 58, - 164, - 230, - 187, - 192, - 54, - 24, - 7, - 211, - 152 - ] - } - }, - "hash": null - }, - { - "node": { - "Leaf": { - "nibbles": { - "count": 63, - "packed": "0xe51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a" - }, - "value": [ - 248, - 68, - 128, - 128, - 160, - 86, - 232, - 31, - 23, - 27, - 204, - 85, - 166, - 255, - 131, - 69, - 230, - 146, - 192, - 248, - 110, - 91, - 72, - 224, - 27, - 153, - 108, - 173, - 192, - 1, - 98, - 47, - 181, - 227, - 99, - 180, - 33, - 160, - 197, - 210, - 70, - 1, - 134, - 247, - 35, - 60, - 146, - 126, - 125, - 178, - 220, - 199, - 3, - 192, - 229, - 0, - 182, - 83, - 202, - 130, - 39, - 59, - 123, - 250, - 216, - 4, - 93, - 133, - 164, - 112 - ] - } - }, - "hash": null - }, - { - "node": "Empty", - "hash": null - } - ], - "value": [] - } - }, - "hash": null - }, - "transactions_trie": { - "node": "Empty", - "hash": null - }, - "receipts_trie": { - "node": "Empty", - "hash": null - }, - "storage_tries": [ - [ - "0xd0c30dcd188e2cdd56c50b2044d150873010914736f94d07d26ff74c7f0cf89b", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b", - { - "node": "Empty", - "hash": null - } - ], - [ - "0xee51ea7e15b3ec83d9e87eac953fcb2444be7f09e9b1e6e02a47fe32c5a9163a", - { - "node": "Empty", - "hash": null - } - ], - [ - "0x8320ca9fbb7bc02ec98c352627dc8fbe89a00c1e6c0b19c60e9234718b2bc149", - { - "node": "Empty", - "hash": null - } - ] - ] - }, - "trie_roots_after": { - "state_root": "0x8df6db58f0f048ccb2b8f034a21ee10846f63983128645b2b710413c260b1f9d", - "transactions_root": "0x4516e33b9d8f2afc0a088da8f64734624303147f14a037f577d2c3f4ba7a22bb", - "receipts_root": "0x33206fdb0b04af73aed5fcc49c377894a2ad7acc74a06782884999e9c75de4ba" - }, - "checkpoint_state_trie_root": "0xa56f414cf08a51a2df93dadb4832e894a0e3c134eb2745b16c481f740c0ecb36", - "contract_code": { - "0x66dd39d4c8f61a5ff0b2de5cef27efb925a375d6b2f8aa191d49e4ed545c08de": [ - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 115, - 16, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 97, - 117, - 48, - 241, - 96, - 1, - 85, - 0 - ], - "0xdc243f2759172f98951e29d353e072844c22088e112a3aa4e6bbc0361807d398": [ - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 96, - 0, - 115, - 201, - 79, - 83, - 116, - 252, - 229, - 237, - 188, - 142, - 42, - 134, - 151, - 193, - 83, - 49, - 103, - 126, - 110, - 191, - 11, - 97, - 117, - 48, - 241, - 96, - 0, - 85, - 96, - 1, - 96, - 2, - 85, - 0 - ], - "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470": [] - }, - "block_metadata": { - "block_beneficiary": "0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "block_timestamp": "0x3e8", - "block_number": "0x1", - "block_difficulty": "0x0", - "block_random": "0x0000000000000000000000000000000000000000000000000000000000020000", - "block_gaslimit": "0x989680", - "block_chain_id": "0x1", - "block_base_fee": "0xa", - "block_gas_used": "0x11170", - "block_bloom": [ - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0", - "0x0" - ] - }, - "block_hashes": { - "prev_hashes": [ - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000" - ], - "cur_hash": "0x0000000000000000000000000000000000000000000000000000000000000000" - } -} diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm index 3541e71a4..4b2c09ba2 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm @@ -6,7 +6,7 @@ // TODO: Have this take an address and do %mpt_insert_state_trie? To match mpt_read_state_trie. global mpt_insert_state_trie: // stack: key, value_ptr, retdest - %insert_account_to_linked_list_no_return + %insert_account_with_overwrite_no_return JUMP %macro mpt_insert_state_trie diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index f528d9690..b81c77e34 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -70,11 +70,23 @@ global init_linked_lists: // stack: cold_access %endmacro +%macro insert_account_with_overwrite + %stack (addr, ptr) -> (addr, ptr, %%after) + %jump(insert_account_with_overwrite) +%%after: + // stack: cold_access +%endmacro + %macro insert_account_to_linked_list_no_return %insert_account_to_linked_list %pop2 %endmacro +%macro insert_account_with_overwrite_no_return + %insert_account_with_overwrite + %pop2 +%endmacro + // Multiply the value at the top of the stack, denoted by ptr/4, by 4 // and abort if ptr/4 >= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN]/4 // In this way 4*ptr/4 must be pointing to the beginning of a node. @@ -203,6 +215,61 @@ global insert_new_account: %stack (addr, payload_ptr, retdest) -> (retdest, 0, payload_ptr) JUMP +global insert_account_with_overwrite: + // stack: addr, payload_ptr, retdest + PROVER_INPUT(linked_list::insert_account) + // stack: pred_ptr/4, addr, payload_ptr, retdest + %get_valid_account_ptr + // stack: pred_ptr, addr, payload_ptr, retdest + DUP1 + MLOAD_GENERAL + DUP1 + // stack: pred_addr, pred_addr, pred_ptr, addr, payload_ptr, retdest + DUP4 GT + DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) + ADD // OR + // If the predesessor is strictly smaller or the predecessor is the special + // node with key @U256_MAX (and hence we're inserting a new minimum), then + // we need to insert a new node. + %jumpi(insert_new_account) + // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. + DUP3 + %assert_eq + // stack: pred_ptr, addr, payload_ptr, retdest + + // stack: pred_ptr, addr, payload_ptr, retdest + // Check that this is not a deleted node + DUP1 + %add_const(3) + MLOAD_GENERAL + %jump_neq_const(@U256_MAX, account_found_with_overwrite) + // The storage key is not in the list. + PANIC + +account_found_with_overwrite: + // The address was already in the list + // stack: pred_ptr, addr, payload_ptr, retdest + // Load the the payload pointer and access counter + %increment + DUP1 + // stack: payload_ptr_ptr, pred_ptr+1, addr, payload_ptr, retdest + DUP4 MSTORE_GENERAL + %increment + DUP1 + MLOAD_GENERAL + %increment + // stack: access_ctr + 1, access_ctr_ptr, addr, payload_ptr, retdest + SWAP1 + DUP2 + // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, addr, payload_ptr, retdest + MSTORE_GENERAL + // stack: access_ctr + 1, addr, payload_ptr, retdest + // If access_ctr == 1 then this it's a cold access + %eq_const(1) + %stack (cold_access, addr, payload_ptr, retdest) -> (retdest, cold_access, payload_ptr) + JUMP + %macro search_account %stack (addr, ptr) -> (addr, ptr, %%after) %jump(search_account) diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index a4b899305..00d7e56b4 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -148,7 +148,7 @@ fn add11_yml() -> anyhow::Result<()> { transactions_root: transactions_trie.hash(), receipts_root: receipts_trie.hash(), }; - let _inputs = GenerationInputs { + let inputs = GenerationInputs { signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, @@ -165,12 +165,6 @@ fn add11_yml() -> anyhow::Result<()> { }, }; - let bytes = std::fs::read( - "/Users/agonzalez/Downloads/TouchToEmptyAccountRevert3_Paris_d0g0v0_Shanghai.json", - ) - .unwrap(); - let inputs = serde_json::from_slice(&bytes).unwrap(); - let mut timing = TimingTree::new("prove", log::Level::Debug); let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; timing.filter(Duration::from_millis(100)).print(); From 87b0c63a97aeb3eabedbe1cf7f731f952bb43edd Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Tue, 25 Jun 2024 18:31:44 +0200 Subject: [PATCH 053/118] Fix final state trie hash mismatch --- .../src/cpu/kernel/asm/main.asm | 24 ++-- .../src/cpu/kernel/interpreter.rs | 6 +- .../src/cpu/kernel/tests/account_code.rs | 2 +- evm_arithmetization/src/generation/mod.rs | 13 ++- evm_arithmetization/src/generation/mpt.rs | 105 +++++++++--------- .../src/generation/prover_input.rs | 37 +++++- evm_arithmetization/src/generation/state.rs | 6 +- .../src/generation/trie_extractor.rs | 7 +- evm_arithmetization/src/witness/transition.rs | 23 +++- evm_arithmetization/tests/erc721.rs | 1 + 10 files changed, 144 insertions(+), 80 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index bd13e0dca..645a8b254 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -32,9 +32,7 @@ global main: PROVER_INPUT(trie_ptr::trie_data_size) %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) - // Initialize the state, transaction and receipt trie root pointers. - PROVER_INPUT(trie_ptr::state) - %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + // Initialize the transaction and receipt trie root pointers. PROVER_INPUT(trie_ptr::txn) %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT) PROVER_INPUT(trie_ptr::receipt) @@ -46,10 +44,10 @@ global hash_initial_tries: // The trie data segment is already written by the linked lists %mload_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) - %set_initial_tries - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) - global debug_check_hash_after_setting_payloads: - %assert_eq + // %set_initial_tries + // %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) + // global debug_check_hash_after_setting_payloads: + // %assert_eq // stack: trie_data_len @@ -112,6 +110,18 @@ global debug_check_gas: global debug_check_txn_number: %assert_eq %pop3 + + %mload_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) + PROVER_INPUT(trie_ptr::state) + %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + %mpt_hash_state_trie + SWAP1 %set_trie_data_size + %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) +global debug_check_initial_trie: + %assert_eq + + %set_initial_tries + PUSH 1 // initial trie data length global check_state_trie: diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index a38642163..794301bdc 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -168,14 +168,12 @@ impl Interpreter { self.generation_state.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] .content = storage_leaves.iter().map(|&val| Some(val)).collect(); self.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()].content = - trie_data.iter().map(|&val| Some(val)).collect(); + trie_data.clone(); let trie_roots_after = &inputs.trie_roots_after; self.generation_state.trie_root_ptrs = trie_root_ptrs; // Initialize the `TrieData` segment. - let preinit_trie_data_segment = MemorySegmentState { - content: trie_data.iter().map(|&elt| Some(elt)).collect::>(), - }; + let preinit_trie_data_segment = MemorySegmentState { content: trie_data }; self.insert_preinitialized_segment(Segment::TrieData, preinit_trie_data_segment); // Update the RLP and withdrawal prover inputs. diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index f6f61fb4b..9b70f6c5b 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -54,7 +54,7 @@ pub(crate) fn initialize_mpts( interpreter .generation_state .memory - .set(trie_addr, data.into()); + .set(trie_addr, data.unwrap_or_default().into()); } } diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 0f0f877ee..ba89b9c63 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -33,7 +33,7 @@ pub mod mpt; pub(crate) mod prover_input; pub(crate) mod rlp; pub(crate) mod state; -mod trie_extractor; +pub(crate) mod trie_extractor; use self::state::State; use crate::witness::util::mem_write_log; @@ -235,6 +235,17 @@ pub fn generate_traces, const D: usize>( "Trace lengths (before padding): {:?}", state.traces.get_lengths() ); + let final_state_trie: HashedPartialTrie = get_state_trie( + &state.memory, + u256_to_usize( + state + .memory + .read_global_metadata(GlobalMetadata::StateTrieRoot), + ) + .unwrap(), + ) + .unwrap(); + log::debug!("Final state trie: {:?}", final_state_trie); log::debug!( "Final accounts linked list: {:?}", state.get_accounts_linked_list() diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index fbcc0100f..2ad97e28e 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -129,7 +129,7 @@ const fn empty_nibbles() -> Nibbles { fn load_mpt( trie: &HashedPartialTrie, - trie_data: &mut Vec, + trie_data: &mut Vec>, parse_value: &F, ) -> Result where @@ -138,66 +138,66 @@ where let node_ptr = trie_data.len(); let type_of_trie = PartialTrieType::of(trie) as u32; if type_of_trie > 0 { - trie_data.push(type_of_trie.into()); + trie_data.push(Some(type_of_trie.into())); } match trie.deref() { Node::Empty => Ok(0), Node::Hash(h) => { - trie_data.push(h2u(*h)); + trie_data.push(Some(h2u(*h))); Ok(node_ptr) } Node::Branch { children, value } => { // First, set children pointers to 0. let first_child_ptr = trie_data.len(); - trie_data.extend(vec![U256::zero(); 16]); + trie_data.extend(vec![Some(U256::zero()); 16]); // Then, set value. if value.is_empty() { - trie_data.push(U256::zero()); + trie_data.push(Some(U256::zero())); } else { - let parsed_value = parse_value(value)?; - trie_data.push((trie_data.len() + 1).into()); + let parsed_value = parse_value(value)?.into_iter().map(Some); + trie_data.push(Some((trie_data.len() + 1).into())); trie_data.extend(parsed_value); } // Now, load all children and update their pointers. for (i, child) in children.iter().enumerate() { let child_ptr = load_mpt(child, trie_data, parse_value)?; - trie_data[first_child_ptr + i] = child_ptr.into(); + trie_data[first_child_ptr + i] = Some(child_ptr.into()); } Ok(node_ptr) } Node::Extension { nibbles, child } => { - trie_data.push(nibbles.count.into()); - trie_data.push( + trie_data.push(Some(nibbles.count.into())); + trie_data.push(Some( nibbles .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?, - ); - trie_data.push((trie_data.len() + 1).into()); + )); + trie_data.push(Some((trie_data.len() + 1).into())); let child_ptr = load_mpt(child, trie_data, parse_value)?; if child_ptr == 0 { - trie_data.push(0.into()); + trie_data.push(Some(0.into())); } Ok(node_ptr) } Node::Leaf { nibbles, value } => { - trie_data.push(nibbles.count.into()); - trie_data.push( + trie_data.push(Some(nibbles.count.into())); + trie_data.push(Some( nibbles .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?, - ); + )); // Set `value_ptr_ptr`. - trie_data.push((trie_data.len() + 1).into()); + trie_data.push(Some((trie_data.len() + 1).into())); - let leaf = parse_value(value)?; + let leaf = parse_value(value)?.into_iter().map(Some); trie_data.extend(leaf); Ok(node_ptr) @@ -208,18 +208,19 @@ where fn load_state_trie( trie: &HashedPartialTrie, key: Nibbles, - trie_data: &mut Vec, + trie_data: &mut Vec>, + storage_tries_by_state_key: &HashMap, ) -> Result { let node_ptr = trie_data.len(); let type_of_trie = PartialTrieType::of(trie) as u32; if type_of_trie > 0 { - trie_data.push(type_of_trie.into()); + trie_data.push(Some(type_of_trie.into())); } match trie.deref() { Node::Empty => Ok(0), Node::Hash(h) => { - trie_data.push(h2u(*h)); + trie_data.push(Some(h2u(*h))); Ok(node_ptr) } @@ -231,9 +232,9 @@ fn load_state_trie( } // First, set children pointers to 0. let first_child_ptr = trie_data.len(); - trie_data.extend(vec![U256::zero(); 16]); + trie_data.extend(vec![Some(U256::zero()); 16]); // Then, set value pointer to 0. - trie_data.push(U256::zero()); + trie_data.push(Some(U256::zero())); // Now, load all children and update their pointers. for (i, child) in children.iter().enumerate() { @@ -244,25 +245,25 @@ fn load_state_trie( let child_ptr = load_state_trie(child, extended_key, trie_data, storage_tries_by_state_key)?; - trie_data[first_child_ptr + i] = child_ptr.into(); + trie_data[first_child_ptr + i] = Some(child_ptr.into()); } Ok(node_ptr) } Node::Extension { nibbles, child } => { - trie_data.push(nibbles.count.into()); - trie_data.push( + trie_data.push(Some(nibbles.count.into())); + trie_data.push(Some( nibbles .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?, - ); + )); // Set `value_ptr_ptr`. - trie_data.push((trie_data.len() + 1).into()); + trie_data.push(Some((trie_data.len() + 1).into())); let extended_key = key.merge_nibbles(nibbles); let child_ptr = load_state_trie(child, extended_key, trie_data, storage_tries_by_state_key)?; if child_ptr == 0 { - trie_data.push(0.into()); + trie_data.push(Some(0.into())); } Ok(node_ptr) @@ -286,24 +287,24 @@ fn load_state_trie( assert_eq!(storage_trie.hash(), storage_root, "In TrieInputs, an account's storage_root didn't match the associated storage trie hash"); - trie_data.push(nibbles.count.into()); - trie_data.push( + trie_data.push(Some(nibbles.count.into())); + trie_data.push(Some( nibbles .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?, - ); + )); // Set `value_ptr_ptr`. - trie_data.push((trie_data.len() + 1).into()); + trie_data.push(Some((trie_data.len() + 1).into())); - trie_data.push(nonce); - trie_data.push(balance); + trie_data.push(Some(nonce)); + trie_data.push(Some(balance)); // Storage trie ptr. let storage_ptr_ptr = trie_data.len(); - trie_data.push((trie_data.len() + 2).into()); - trie_data.push(code_hash.into_uint()); + trie_data.push(Some((trie_data.len() + 2).into())); + trie_data.push(Some(code_hash.into_uint())); let storage_ptr = load_mpt(storage_trie, trie_data, &parse_storage_value)?; if storage_ptr == 0 { - trie_data[storage_ptr_ptr] = 0.into(); + trie_data[storage_ptr_ptr] = Some(0.into()); } Ok(node_ptr) @@ -316,7 +317,7 @@ fn get_state_and_storage_leaves( key: Nibbles, state_leaves: &mut Vec, storage_leaves: &mut Vec, - trie_data: &mut Vec, + trie_data: &mut Vec>, storage_tries_by_state_key: &HashMap, ) -> Result<(), ProgramError> { match trie.deref() { @@ -398,11 +399,11 @@ associated storage trie hash" state_leaves.push((Segment::AccountsLinkedList as usize).into()); // Push the payload in the trie data - trie_data.push(nonce); - trie_data.push(balance); + trie_data.push(Some(nonce)); + trie_data.push(Some(balance)); // The Storage pointer is only written in the trie - trie_data.push(0.into()); - trie_data.push(code_hash.into_uint()); + trie_data.push(Some(0.into())); + trie_data.push(Some(code_hash.into_uint())); get_storage_leaves( address, empty_nibbles(), @@ -423,7 +424,7 @@ pub(crate) fn get_storage_leaves( key: Nibbles, trie: &HashedPartialTrie, storage_leaves: &mut Vec, - trie_data: &mut Vec, + trie_data: &mut Vec>, parse_value: &F, ) -> Result<(), ProgramError> where @@ -484,7 +485,7 @@ where // Set the next node as the inital node storage_leaves.push((Segment::StorageLinkedList as usize).into()); - let leaf = parse_value(value)?; + let leaf = parse_value(value)?.into_iter().map(Some); trie_data.extend(leaf); Ok(()) @@ -495,8 +496,8 @@ where pub(crate) fn load_all_mpts( trie_inputs: &TrieInputs, -) -> Result<(TrieRootPtrs, Vec), ProgramError> { - let mut trie_data = vec![U256::zero()]; +) -> Result<(TrieRootPtrs, Vec>), ProgramError> { + let mut trie_data = vec![Some(U256::zero())]; let storage_tries_by_state_key = trie_inputs .storage_tries .iter() @@ -533,12 +534,12 @@ pub(crate) fn load_all_mpts( pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( trie_inputs: &TrieInputs, -) -> Result<(TrieRootPtrs, Vec, Vec, Vec), ProgramError> { +) -> Result<(TrieRootPtrs, Vec, Vec, Vec>), ProgramError> { let mut state_leaves = empty_list_mem::(Segment::AccountsLinkedList).to_vec(); let mut storage_leaves = empty_list_mem::(Segment::StorageLinkedList).to_vec(); - let mut trie_data = vec![U256::zero()]; + let mut trie_data = vec![Some(U256::zero())]; let storage_tries_by_state_key = trie_inputs .storage_tries @@ -568,11 +569,11 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( ); // TODO: Remove after checking correctness of linked lists - let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; + // let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; Ok(( TrieRootPtrs { - state_root_ptr: Some(state_root_ptr), + state_root_ptr: None, txn_root_ptr, receipt_root_ptr, }, @@ -584,7 +585,7 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( pub(crate) fn load_state_mpt( trie_inputs: &TrieInputs, - trie_data: &mut Vec, + trie_data: &mut Vec>, ) -> Result { let storage_tries_by_state_key = trie_inputs .storage_tries diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index e045454b7..2b3664caa 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -5,11 +5,15 @@ use std::str::FromStr; use anyhow::{bail, Error}; use ethereum_types::{BigEndianHash, H256, U256, U512}; use itertools::Itertools; +use mpt_trie::partial_trie::HashedPartialTrie; use num_bigint::BigUint; use plonky2::field::types::Field; use serde::{Deserialize, Serialize}; use super::linked_list::LinkedList; +use super::mpt::load_state_mpt; +use super::state::State; +use super::trie_extractor::get_state_trie; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::simulate_cpu_and_get_user_jumps; @@ -73,11 +77,34 @@ impl GenerationState { fn run_trie_ptr(&mut self, input_fn: &ProverInputFn) -> Result { let trie = input_fn.0[1].as_str(); match trie { - "state" => self - .trie_root_ptrs - .state_root_ptr - .ok_or(ProgramError::ProverInputError(InvalidInput)) - .map(U256::from), + "state" => match self.trie_root_ptrs.state_root_ptr { + Some(state_root_ptr) => Ok(state_root_ptr), + None => { + log::debug!( + "trie_data_len before: = {:?}", + self.memory.contexts[0].segments[Segment::TrieData.unscale()] + .content + .len() + ); + let n = load_state_mpt( + &self.inputs.tries, + &mut self.memory.contexts[0].segments[Segment::TrieData.unscale()].content, + )?; + log::debug!( + "state_trie before = {:?}", + get_state_trie::(&self.memory, n) + ); + log::debug!( + "trie_data_len after = {:?}", + self.memory.contexts[0].segments[Segment::TrieData.unscale()] + .content + .len() + ); + log::debug!("and n = {:?} ", n); + Ok(n) + } + } + .map(U256::from), "txn" => Ok(U256::from(self.trie_root_ptrs.txn_root_ptr)), "receipt" => Ok(U256::from(self.trie_root_ptrs.receipt_root_ptr)), "trie_data_size" => Ok(U256::from( diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index 1aae8dd39..6127a4b86 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -320,8 +320,7 @@ impl GenerationState { let (trie_roots_ptrs, trie_data) = load_all_mpts(trie_inputs).expect("Invalid MPT data for preinitialization"); - self.memory.contexts[0].segments[Segment::TrieData.unscale()].content = - trie_data.iter().map(|&val| Some(val)).collect(); + self.memory.contexts[0].segments[Segment::TrieData.unscale()].content = trie_data; trie_roots_ptrs } @@ -338,8 +337,7 @@ impl GenerationState { state_leaves.iter().map(|&val| Some(val)).collect(); self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()].content = storage_leaves.iter().map(|&val| Some(val)).collect(); - self.memory.contexts[0].segments[Segment::TrieData.unscale()].content = - trie_data.iter().map(|&val| Some(val)).collect(); + self.memory.contexts[0].segments[Segment::TrieData.unscale()].content = trie_data; trie_roots_ptrs } diff --git a/evm_arithmetization/src/generation/trie_extractor.rs b/evm_arithmetization/src/generation/trie_extractor.rs index a753ee90e..c29385c25 100644 --- a/evm_arithmetization/src/generation/trie_extractor.rs +++ b/evm_arithmetization/src/generation/trie_extractor.rs @@ -197,7 +197,7 @@ pub(crate) fn read_state_rlp_value( get_trie(memory, slice[2].unwrap_or_default().as_usize(), |_, x| { Ok(rlp::encode(&read_storage_trie_value(x)).to_vec()) })?; - log::debug!("storage_trie = {:#?}", storage_trie); + // log::debug!("storage_trie = {:?}", storage_trie); let account = AccountRlp { nonce: slice[0].unwrap_or_default(), balance: slice[1].unwrap_or_default(), @@ -231,10 +231,7 @@ pub(crate) fn read_receipt_rlp_value( Ok(bytes) } -pub(crate) fn get_state_trie( - memory: &MemoryState, - ptr: usize, -) -> Result { +pub fn get_state_trie(memory: &MemoryState, ptr: usize) -> Result { get_trie(memory, ptr, read_state_rlp_value) } diff --git a/evm_arithmetization/src/witness/transition.rs b/evm_arithmetization/src/witness/transition.rs index 462757280..5c0be9556 100644 --- a/evm_arithmetization/src/witness/transition.rs +++ b/evm_arithmetization/src/witness/transition.rs @@ -1,17 +1,22 @@ use ethereum_types::U256; use log::log_enabled; +use mpt_trie::partial_trie::HashedPartialTrie; +use mpt_trie::partial_trie::PartialTrie; use plonky2::field::types::Field; use super::util::{mem_read_gp_with_log_and_fill, stack_pop_with_log_and_fill}; use crate::cpu::columns::CpuColumnsView; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; +use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::membus::NUM_GP_CHANNELS; use crate::cpu::stack::{ EQ_STACK_BEHAVIOR, IS_ZERO_STACK_BEHAVIOR, JUMPI_OP, JUMP_OP, MIGHT_OVERFLOW, STACK_BEHAVIORS, }; use crate::generation::state::State; +use crate::generation::trie_extractor::get_state_trie; use crate::memory::segments::Segment; +use crate::util::u256_to_usize; use crate::witness::errors::ProgramError; use crate::witness::gas::gas_to_charge; use crate::witness::memory::MemoryAddress; @@ -19,7 +24,6 @@ use crate::witness::operation::*; use crate::witness::state::RegistersState; use crate::witness::util::mem_read_code_with_log_and_fill; use crate::{arithmetic, logic}; - pub(crate) fn read_code_memory>( state: &mut T, row: &mut CpuColumnsView, @@ -287,6 +291,23 @@ pub(crate) fn log_kernel_instruction>(state: &mut S, op: O state.get_generation_state().stack(), ), ); + if state.get_clock() <= 65945 && state.get_clock() >= 64176 { + log::debug!( + "state_trie before = {:?}", + get_state_trie::( + &state.get_generation_state().memory, + u256_to_usize( + state + .get_generation_state() + .memory + .read_global_metadata(GlobalMetadata::StateTrieRoot) + ) + .unwrap() + ) + .unwrap() + .hash() + ); + } assert!(pc < KERNEL.code.len(), "Kernel PC is out of range: {}", pc); } diff --git a/evm_arithmetization/tests/erc721.rs b/evm_arithmetization/tests/erc721.rs index d78b533dc..7bf1a9b5d 100644 --- a/evm_arithmetization/tests/erc721.rs +++ b/evm_arithmetization/tests/erc721.rs @@ -189,6 +189,7 @@ fn test_erc721() -> anyhow::Result<()> { }, }; + log::debug!("state hash ={:?}", inputs.tries.state_trie.hash()); log::debug!("Expected final trie = {:#?}", expected_state_trie_after); let mut timing = TimingTree::new("prove", log::Level::Debug); let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; From ef231c095160dff82864f2bd5b5c112bf53e0413 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 25 Jun 2024 18:49:45 +0100 Subject: [PATCH 054/118] Fix insert_new_slot_with_value --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index b81c77e34..ae1a05b9e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -473,7 +473,7 @@ insert_new_slot_with_value: // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. LT - %jumpi(next_node_ok) + %jumpi(next_node_ok_with_value) // If addr <= next_addr, then it addr must be equal to next_addr // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest DUP5 From 44e316e477befea3af06c368ca5fe545eb2517e3 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 26 Jun 2024 10:44:31 +0200 Subject: [PATCH 055/118] Debugging variedContext_d10g0v0_Shanghai.json --- evm_arithmetization/src/generation/mod.rs | 13 +++++++++++++ evm_arithmetization/tests/add11_yml.rs | 6 +++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 0f0f877ee..0f3463100 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -235,6 +235,19 @@ pub fn generate_traces, const D: usize>( "Trace lengths (before padding): {:?}", state.traces.get_lengths() ); + + let final_state_trie: HashedPartialTrie = get_state_trie( + &state.memory, + u256_to_usize( + state + .memory + .read_global_metadata(GlobalMetadata::StateTrieRoot), + ) + .unwrap(), + ) + .unwrap(); + log::debug!("Final state trie: {:?}", final_state_trie); + log::debug!( "Final accounts linked list: {:?}", state.get_accounts_linked_list() diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 00d7e56b4..966b59fa0 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -148,7 +148,7 @@ fn add11_yml() -> anyhow::Result<()> { transactions_root: transactions_trie.hash(), receipts_root: receipts_trie.hash(), }; - let inputs = GenerationInputs { + let _inputs = GenerationInputs { signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, @@ -165,6 +165,10 @@ fn add11_yml() -> anyhow::Result<()> { }, }; + let bytes = + std::fs::read("/Users/agonzalez/Downloads/variedContext_d10g0v0_Shanghai.json").unwrap(); + let inputs = serde_json::from_slice(&bytes).unwrap(); + let mut timing = TimingTree::new("prove", log::Level::Debug); let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; timing.filter(Duration::from_millis(100)).print(); From 29ca9df5599bdaa4d7290abf844efc4f060779d3 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 26 Jun 2024 12:32:22 +0200 Subject: [PATCH 056/118] Fix variedContext_d10g0v0_Shanghai --- .../cpu/kernel/asm/mpt/linked_list/final_tries.asm | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index df297d616..0e14b8aeb 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -58,6 +58,12 @@ no_more_accounts: global insert_all_slots: DUP2 MLOAD_GENERAL + // stack: next_addr, addr, storage_ptr_ptr, root_ptr, retdest + DUP1 + DUP3 + GT // If addr > next_addr it means was deleted + // addr > next_addr, next_addr, addr, storage_ptr_ptr, root_ptr, retdest + %jumpi(skip_deleted_slot) DUP2 EQ // Check that the node addres is the same as `addr` %jumpi(insert_next_slot) @@ -65,6 +71,14 @@ global insert_all_slots: // stack: addr, storage_ptr_ptr, root_ptr, retdest %stack (addr, storage_ptr_ptr, root_ptr, retdest) -> (retdest, storage_ptr_ptr, root_ptr) JUMP + +skip_deleted_slot: + POP + SWAP1 + %next_slot + SWAP1 + %jump(insert_all_slots) + insert_next_slot: // stack: addr, storage_ptr_ptr, root_ptr, retdest DUP2 From bf91f448877d76fd21a0cc790a50fea8db5b5491 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 26 Jun 2024 13:30:01 +0200 Subject: [PATCH 057/118] [WIP] Fixing vitalikTransactionTestParis_d0g0v0_Shanghai --- .../src/cpu/kernel/asm/journal/account_destroyed.asm | 4 +++- evm_arithmetization/tests/add11_yml.rs | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index 2a6606b76..2077f7a72 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -44,7 +44,9 @@ revert_account_destroyed_contd: // stack: target, address, prev_balance, retdest %read_accounts_linked_list // stack: target_payload_ptr, address, prev_balance, retdest - DUP1 %assert_nonzero + DUP1 +global debug_sera_aca: + %assert_nonzero %add_const(1) // stack: target_balance_ptr, address, prev_balance, retdest DUP3 DUP2 %mload_trie_data diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 966b59fa0..abd3b204a 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -165,8 +165,10 @@ fn add11_yml() -> anyhow::Result<()> { }, }; - let bytes = - std::fs::read("/Users/agonzalez/Downloads/variedContext_d10g0v0_Shanghai.json").unwrap(); + let bytes = std::fs::read( + "/Users/agonzalez/Downloads/vitalikTransactionTestParis_d0g0v0_Shanghai.json", + ) + .unwrap(); let inputs = serde_json::from_slice(&bytes).unwrap(); let mut timing = TimingTree::new("prove", log::Level::Debug); From b83871dc1be2b4a89105eb74fd75371ed82f8eef Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 27 Jun 2024 12:49:19 +0100 Subject: [PATCH 058/118] Delete all associated slots when an account is deleted --- .../src/cpu/kernel/asm/mpt/delete/delete.asm | 6 ++- .../asm/mpt/linked_list/final_tries.asm | 13 ------ .../asm/mpt/linked_list/linked_list.asm | 43 +++++++++++++++++-- .../src/generation/prover_input.rs | 15 +++++++ 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index 46db25f98..36d4e0b2f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -27,8 +27,12 @@ global mpt_delete_leaf: global delete_account: %addr_to_state_key + DUP1 %remove_account_from_linked_list - // retdest + // stack: addr_to_state_key, retdest + + // Now we also need to remove all the storage nodes associated with the deleted account. + %remove_all_account_slots JUMP %macro delete_account diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 0e14b8aeb..b91a9b7ed 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -58,12 +58,6 @@ no_more_accounts: global insert_all_slots: DUP2 MLOAD_GENERAL - // stack: next_addr, addr, storage_ptr_ptr, root_ptr, retdest - DUP1 - DUP3 - GT // If addr > next_addr it means was deleted - // addr > next_addr, next_addr, addr, storage_ptr_ptr, root_ptr, retdest - %jumpi(skip_deleted_slot) DUP2 EQ // Check that the node addres is the same as `addr` %jumpi(insert_next_slot) @@ -72,13 +66,6 @@ global insert_all_slots: %stack (addr, storage_ptr_ptr, root_ptr, retdest) -> (retdest, storage_ptr_ptr, root_ptr) JUMP -skip_deleted_slot: - POP - SWAP1 - %next_slot - SWAP1 - %jump(insert_all_slots) - insert_next_slot: // stack: addr, storage_ptr_ptr, root_ptr, retdest DUP2 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index ae1a05b9e..16de91a6a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -853,9 +853,46 @@ global remove_slot: %pop2 JUMP -/// Search the account addr and payload pointer into the linked list. -/// Return `1, payload_ptr` if the account was inserted, `1, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +/// Called when an account is deleted: it deletes all slots associated with the account. +global remove_all_account_slots: + // stack: addr, retdest + PROVER_INPUT(linked_list::remove_address_slots) + // pred_ptr/5, retdest + %get_valid_slot_ptr + +global debug_after_valid_ptr: + // stack: pred_ptr, addr, retdest + // First, check that the previous address is not `addr` + DUP1 MLOAD_GENERAL + // stack: pred_addr, pred_ptr, addr, retdest + DUP3 EQ %jumpi(panic) + // stack: pred_ptr, addr, retdest + // Now, while the next address is `addr`, remove the slot. + +global remove_all_slots_loop: + // stack: pred_ptr, addr, retdest + %add_const(4) MLOAD_GENERAL DUP1 + // stack: cur_ptr, cur_ptr, addr, retdest + DUP1 %eq_const(@U256_MAX) %jumpi(remove_all_slots_end) + MLOAD_GENERAL + // stack: cur_addr, cur_ptr, addr, retdest + DUP1 DUP4 EQ ISZERO %jumpi(remove_all_slots_end) + // stack: cur_addr, cur_ptr, addr, retdest + DUP2 %increment MLOAD_GENERAL SWAP1 + // stack: cur_addr, cur_key, cur_ptr, addr, retdest + %remove_slot + // stack: cur_ptr, addr, retdest + %jump(remove_all_slots_loop) + +global remove_all_slots_end: + // stack: cur_addr, cur_ptr, addr, retdest + %pop3 JUMP + +%macro remove_all_account_slots + %stack (addr) -> (addr, %%after) + %jump(remove_all_account_slots) +%%after: +%endmacro %macro read_accounts_linked_list %stack (addr) -> (addr, 0, %%after) diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index e045454b7..c1ccc534c 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -286,6 +286,7 @@ impl GenerationState { "remove_account" => self.run_next_remove_account(), "insert_slot" => self.run_next_insert_slot(), "remove_slot" => self.run_next_remove_slot(), + "remove_address_slots" => self.run_next_remove_address_slots(), "accounts_linked_list_len" => Ok((Segment::AccountsLinkedList as usize + self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] .content @@ -518,6 +519,20 @@ impl GenerationState { Ok((Segment::StorageLinkedList as usize).into()) } } + + fn run_next_remove_address_slots(&self) -> Result { + let addr = stack_peek(self, 0)?; + if let Some(([.., ptr], _)) = self + .get_storage_linked_list()? + .zip(self.get_storage_linked_list()?.skip(2)) + .find(|&(_, [next_addr, next_key, ..])| next_addr == addr) + { + Ok((ptr - U256::from(Segment::StorageLinkedList as usize)) + / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) + } else { + Ok((Segment::StorageLinkedList as usize).into()) + } + } } impl GenerationState { From c6fed71f4eac52e50436351905d08299adc691e2 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 27 Jun 2024 14:38:44 +0100 Subject: [PATCH 059/118] Fix run_next_remove_address_slots --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 4 ++-- evm_arithmetization/src/generation/prover_input.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 16de91a6a..fd7ed7c7e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -869,7 +869,7 @@ global debug_after_valid_ptr: // stack: pred_ptr, addr, retdest // Now, while the next address is `addr`, remove the slot. -global remove_all_slots_loop: +remove_all_slots_loop: // stack: pred_ptr, addr, retdest %add_const(4) MLOAD_GENERAL DUP1 // stack: cur_ptr, cur_ptr, addr, retdest @@ -884,7 +884,7 @@ global remove_all_slots_loop: // stack: cur_ptr, addr, retdest %jump(remove_all_slots_loop) -global remove_all_slots_end: +remove_all_slots_end: // stack: cur_addr, cur_ptr, addr, retdest %pop3 JUMP diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index c1ccc534c..3354d5719 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -525,7 +525,7 @@ impl GenerationState { if let Some(([.., ptr], _)) = self .get_storage_linked_list()? .zip(self.get_storage_linked_list()?.skip(2)) - .find(|&(_, [next_addr, next_key, ..])| next_addr == addr) + .find(|&(_, [next_addr, next_key, ..])| next_addr == addr || next_addr == U256::MAX) { Ok((ptr - U256::from(Segment::StorageLinkedList as usize)) / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) From 268604e2907b6943558f8cec5ee80248ed69f4c7 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Thu, 27 Jun 2024 15:41:52 +0200 Subject: [PATCH 060/118] Copy initial accounts and slots --- .../src/cpu/kernel/asm/main.asm | 4 + .../asm/mpt/linked_list/initial_tries.asm | 7 +- .../asm/mpt/linked_list/linked_list.asm | 178 ++++++++++++------ 3 files changed, 128 insertions(+), 61 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 645a8b254..5ac12b9d8 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -31,6 +31,10 @@ global main: %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) PROVER_INPUT(trie_ptr::trie_data_size) %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) + + // Store the inital accounts and slots for hashing later + %store_initial_accounts + %store_initial_slots // Initialize the transaction and receipt trie root pointers. PROVER_INPUT(trie_ptr::txn) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index 5140ed917..241f873bf 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -32,9 +32,9 @@ skip: %macro set_initial_tries PUSH %%after PUSH @SEGMENT_STORAGE_LINKED_LIST - %add_const(7) // The first node is the special node, of size 5, so the first payload is at position 5 + 2. + %add_const(8) // The first node is the special node, of size 5, so the first payload is at position 5 + 3. PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - %add_const(5) // The first node is the special node, of size 4, so the first payload is at position 4 + 1. + %add_const(6) // The first node is the special node, of size 4, so the first payload is at position 4 + 2. %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) %jump(mpt_set_payload) %%after: @@ -154,7 +154,9 @@ after_set_storage_payload: %stack (new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> (new_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) +global debug_sera_aca: %mstore_trie_data // The account in the linked list has no storage root so we need to manually set it. +global debug_sera_aca_signo_de_interrogacion: %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. // stack: account_ptr_ptr, storage_ptr_ptr', retdest %add_const(4) // The next pointer is at distance 4 @@ -171,6 +173,7 @@ set_payload_storage_leaf: DUP2 MLOAD_GENERAL SWAP1 +global debug_o_quizas_aca: %mstore_trie_data // stack: storage_ptr_ptr, retdest %add_const(5) // The next pointer is at distance 5 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index f528d9690..5757f2534 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -11,7 +11,7 @@ // The values at the respective positions are: // - 0: The account key // - 1: A ptr to the payload (the account values) -// - 2: A counter indicating the number of times this address have been accessed. +// - 2: A ptr to the intial payload. // - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. // Initialize also an empty storage linked list (@U256_MAX)⮌ // which is written as [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST @@ -19,7 +19,7 @@ // - 0: The account key // - 1: The key // - 2: A ptr to the payload (the stored value) -// - 3: A counter indicating the number of times this slot have been accessed. +// - 3: A ptr to the inital payload. // - 4: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. global init_linked_lists: // stack: (empty) @@ -63,6 +63,63 @@ global init_linked_lists: %%after: %endmacro +%macro store_initial_accounts + PUSH %%after + %jump(store_initial_accounts) +%%after: +%endmacro + +/// Iterates over the inital account linked list and shallow copies +/// the accounts, storing a pointer to the copied account in the node. +global store_initial_accounts: + // stack: retdest + + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + %next_account +loop_store_initial_accounts: + // stack: current_node_ptr + %get_trie_data_size + DUP2 + MLOAD_GENERAL + // stack: current_addr, cpy_ptr, current_node_ptr, retdest + %eq_const(@U256_MAX) + %jumpi(store_initial_accounts_end) + DUP2 + %increment + MLOAD_GENERAL + // stack: nonce_ptr, cpy_ptr, current_node_ptr, retdest + DUP1 + %mload_trie_data // nonce + %append_to_trie_data + %increment + // stack: balance_ptr, cpy_ptr, current_node_ptr, retdest + DUP1 + %mload_trie_data // balance + %append_to_trie_data + %increment // The storage_root_ptr is not really necessary + // stack: storage_root_ptr_ptr, cpy_ptr, current_node_ptr, retdest + DUP1 + %mload_trie_data // storage_root_ptr + %append_to_trie_data + %increment + // stack: code_hash_ptr, cpy_ptr, current_node_ptr, retdest + %mload_trie_data // code_hash + %append_to_trie_data + %increment + // stack: cpy_ptr, current_node_ptr, retdest + DUP2 + %add_const(2) + SWAP1 +global debug_store_account_cpy_ptr: + MSTORE_GENERAL // Store cpy_ptr + %next_account + %jump(loop_store_initial_accounts) + +store_initial_accounts_end: + %pop2 + JUMP + + %macro insert_account_to_linked_list %stack (addr, ptr) -> (addr, ptr, %%after) %jump(insert_account_to_linked_list) @@ -131,23 +188,10 @@ global account_found: // stack: pred_ptr, addr, payload_ptr, retdest // Load the the payload pointer and access counter %increment - DUP1 - MLOAD_GENERAL - // stack: orig_payload_ptr, pred_ptr + 1, addr, payload_ptr, retdest - SWAP1 - %increment - DUP1 MLOAD_GENERAL - %increment - // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, payload_ptr, retdest - SWAP1 - DUP2 - // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest - MSTORE_GENERAL - // stack: access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest - // If access_ctr == 1 then this it's a cold access - %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + // stack: orig_payload_ptr, addr, payload_ptr, retdest + // TODO: Remove the now unused cold_access + %stack (orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, 0, orig_payload_ptr) JUMP //DEBUG global insert_new_account: @@ -188,7 +232,7 @@ global insert_new_account: // stack: new_ptr + 1, next_ptr, addr, payload_ptr, retdest %increment DUP1 - PUSH 0 + DUP5 MSTORE_GENERAL %increment DUP1 @@ -305,6 +349,51 @@ global remove_account: // // +%macro store_initial_slots + PUSH %%after + %jump(store_initial_slots) +%%after: +%endmacro + + +/// Iterates over the inital account linked list and shallow copies +/// the accounts, storing a pointer to the copied account in the node. +global store_initial_slots: + // stack: retdest + + PUSH @SEGMENT_STORAGE_LINKED_LIST + %next_slot + +global debug_el_loooooop: +loop_store_initial_slots: + // stack: current_node_ptr + %get_trie_data_size + DUP2 + MLOAD_GENERAL + // stack: current_addr, cpy_ptr, current_node_ptr, retdest + %eq_const(@U256_MAX) + %jumpi(store_initial_slots_end) + DUP2 + %add_const(2) + MLOAD_GENERAL +global debug_payload_ptr: + // stack: payload_ptr, cpy_ptr, current_node_ptr, retdest + %mload_trie_data // nonce + %append_to_trie_data + // stack: cpy_ptr, current_node_ptr, retdest + DUP2 + %add_const(3) + SWAP1 +global store_cpy_ptr: + MSTORE_GENERAL // Store cpy_ptr + %next_slot + %jump(loop_store_initial_slots) + +store_initial_slots_end: + %pop2 + JUMP + + %macro insert_slot %stack (addr, key, ptr) -> (addr, key, ptr, %%after) %jump(insert_slot) @@ -432,7 +521,6 @@ next_node_ok_with_value: // Write the address in the new node DUP1 DUP4 -global debug_yo_no_me_llamo_javier_with_value: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, key, value, retdest // Write the key in the new node @@ -451,10 +539,10 @@ global debug_yo_no_me_llamo_javier_with_value: MSTORE_GENERAL // stack: new_ptr + 2, next_ptr, addr, key, new_payload_ptr, retdest - // Store the counter + // Store the payload ptr copy %increment DUP1 - PUSH 0 + DUP6 MSTORE_GENERAL // stack: new_ptr + 3, next_ptr, addr, key, new_payload_ptr, retdest %increment @@ -550,26 +638,12 @@ slot_found_write: DUP1 MLOAD_GENERAL // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest - DUP2 - DUP6 + SWAP1 + DUP5 global debug_store_new_payload: MSTORE_GENERAL // Store the new payload - - SWAP1 - %increment - DUP1 - MLOAD_GENERAL - %increment - // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, key, payload_ptr, retdest - SWAP1 - DUP2 - // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest -global debug_no_me_llamo_popotan: - MSTORE_GENERAL - // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest - // If access_ctr == 1 then this it's a cold access - %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + // TODO: remove the unused cold access + %stack (orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, 0, orig_payload_ptr) JUMP insert_new_slot: // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest @@ -619,7 +693,6 @@ next_node_ok: // Write the address in the new node DUP1 DUP4 -global debug_yo_no_me_llamo_javier: MSTORE_GENERAL // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest // Write the key in the new node @@ -635,10 +708,10 @@ global debug_yo_no_me_llamo_javier: MSTORE_GENERAL // stack: new_ptr + 2, next_ptr, addr, key, payload_ptr, retdest - // Store the counter + // Store the copy of payload_ptr %increment DUP1 - PUSH 0 + DUP6 MSTORE_GENERAL // stack: new_ptr + 3, next_ptr, addr, key, payload_ptr, retdest %increment @@ -720,23 +793,10 @@ slot_found_no_write: // stack: pred_ptr, addr, key, payload_ptr, retdest // Load the the payload pointer and access counter %add_const(2) - DUP1 MLOAD_GENERAL - // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest - SWAP1 - %increment - DUP1 - MLOAD_GENERAL - %increment - // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, key, payload_ptr, retdest - SWAP1 - DUP2 - // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest - MSTORE_GENERAL - // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest - // If access_ctr == 1 then this it's a cold access - %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + // stack: orig_payload_ptr, addr, key, payload_ptr, retdest + // TODO: remove the now unused cold access (the 0) + %stack (orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, 0, orig_payload_ptr) JUMP From 7e99b143507297e1d4b046996922b50e43e3d813 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 27 Jun 2024 21:45:05 +0100 Subject: [PATCH 061/118] Fix find condition in run_next_remove_address_slots --- evm_arithmetization/src/generation/prover_input.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 3354d5719..484cfdf76 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -522,12 +522,19 @@ impl GenerationState { fn run_next_remove_address_slots(&self) -> Result { let addr = stack_peek(self, 0)?; - if let Some(([.., ptr], _)) = self + if let Some((([.., pred_ptr], _), _)) = self .get_storage_linked_list()? + .zip(self.get_storage_linked_list()?.skip(1)) .zip(self.get_storage_linked_list()?.skip(2)) - .find(|&(_, [next_addr, next_key, ..])| next_addr == addr || next_addr == U256::MAX) + .find( + |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { + let prev_is_less = (prev_addr < addr || prev_addr == U256::MAX); + let next_is_larger_or_equal = next_addr >= addr; + prev_is_less && next_is_larger_or_equal + }, + ) { - Ok((ptr - U256::from(Segment::StorageLinkedList as usize)) + Ok((pred_ptr - U256::from(Segment::StorageLinkedList as usize)) / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) } else { Ok((Segment::StorageLinkedList as usize).into()) From cc71c4b055b613df259f0738d82901ea78edb0ec Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Mon, 1 Jul 2024 18:26:54 +0200 Subject: [PATCH 062/118] Deep copy of accounts and slots --- .../src/cpu/kernel/asm/mpt/accounts.asm | 36 +++++++++++++++++++ .../asm/mpt/linked_list/linked_list.asm | 4 ++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm index 0ee987b4c..bb699716d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm @@ -19,3 +19,39 @@ %mload_trie_data // stack: storage_root_ptr %endmacro + +%macro clone_account + // stack: account_ptr + %get_trie_data_size + // stack: cloned_accouint_ptr + SWAP1 + DUP1 + // Balance + %mload_trie_data + %append_to_trie_data + %increment + // Nonce + %increment + DUP1 + %mload_trie_data + %append_to_trie_data + // Storage trie root + %increment + DUP1 + %mload_trie_data + %append_to_trie_data + // Codehash + %increment + %mload_trie_data + %append_to_trie_data + // stack: cloned_account_ptr +%endmacro + +%macro clone_slot + // stack: slot_ptr + %get_trie_data_size + // stack: cloned_slot_ptr + SWAP1 + %mload_trie_data + %append_to_trie_data +%endmacro \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index ee5b5e69b..49e365009 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -246,6 +246,7 @@ global insert_new_account: %increment DUP1 DUP5 + %clone_account MSTORE_GENERAL %increment DUP1 @@ -446,7 +447,7 @@ loop_store_initial_slots: MLOAD_GENERAL global debug_payload_ptr: // stack: payload_ptr, cpy_ptr, current_node_ptr, retdest - %mload_trie_data // nonce + %mload_trie_data %append_to_trie_data // stack: cpy_ptr, current_node_ptr, retdest DUP2 @@ -611,6 +612,7 @@ next_node_ok_with_value: %increment DUP1 DUP6 + %clone_slot MSTORE_GENERAL // stack: new_ptr + 3, next_ptr, addr, key, new_payload_ptr, retdest %increment From 81118832db21ce48f74508b10b97bcccb8bf8749 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Tue, 2 Jul 2024 13:55:25 +0200 Subject: [PATCH 063/118] [WIP] Testing evm test suite --- .../src/cpu/kernel/interpreter.rs | 8 +-- evm_arithmetization/src/witness/transition.rs | 17 ------ evm_arithmetization/tests/add11_yml.rs | 54 +++++++++++++++---- trace_decoder/Cargo.toml | 1 + 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index 794301bdc..6364a4ad3 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -542,15 +542,15 @@ impl State for Interpreter { } fn log_debug(&self, msg: String) { - if !self.is_jumpdest_analysis { + // if !self.is_jumpdest_analysis { log::debug!("{}", msg); - } + // } } fn log(&self, level: Level, msg: String) { - if !self.is_jumpdest_analysis { + // if !self.is_jumpdest_analysis { log::log!(level, "{}", msg); - } + // } } } diff --git a/evm_arithmetization/src/witness/transition.rs b/evm_arithmetization/src/witness/transition.rs index 5c0be9556..5e94f82db 100644 --- a/evm_arithmetization/src/witness/transition.rs +++ b/evm_arithmetization/src/witness/transition.rs @@ -291,23 +291,6 @@ pub(crate) fn log_kernel_instruction>(state: &mut S, op: O state.get_generation_state().stack(), ), ); - if state.get_clock() <= 65945 && state.get_clock() >= 64176 { - log::debug!( - "state_trie before = {:?}", - get_state_trie::( - &state.get_generation_state().memory, - u256_to_usize( - state - .get_generation_state() - .memory - .read_global_metadata(GlobalMetadata::StateTrieRoot) - ) - .unwrap() - ) - .unwrap() - .hash() - ); - } assert!(pc < KERNEL.code.len(), "Kernel PC is out of range: {}", pc); } diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index abd3b204a..c0242e1ea 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -1,4 +1,6 @@ use std::collections::HashMap; +use std::fs; +use std::path::Path; use std::str::FromStr; use std::time::Duration; @@ -8,6 +10,7 @@ use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; use evm_arithmetization::prover::prove; +use evm_arithmetization::prover::testing::simulate_execution; use evm_arithmetization::verifier::verify_proof; use evm_arithmetization::{AllStark, Node, StarkConfig}; use hex_literal::hex; @@ -164,18 +167,47 @@ fn add11_yml() -> anyhow::Result<()> { cur_hash: H256::default(), }, }; + let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stRandom/randomStatetest163_d0g0v0_Shanghai.json"); + visit_dirs(dir)?; + // let bytes = + // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ + // stTimeConsuming/static_Call50000_sha256_d0g0v0_Shanghai.json").unwrap(); + // let inputs = serde_json::from_slice(&bytes).unwrap(); + + // let mut timing = TimingTree::new("prove", log::Level::Debug); + // // let proof = prove::(&all_stark, &config, inputs, &mut + // timing, // None)?; + // simulate_execution::(inputs)?; + // timing.filter(Duration::from_millis(100)).print(); + + Ok(()) + // verify_proof(&all_stark, proof, &config) +} - let bytes = std::fs::read( - "/Users/agonzalez/Downloads/vitalikTransactionTestParis_d0g0v0_Shanghai.json", - ) - .unwrap(); - let inputs = serde_json::from_slice(&bytes).unwrap(); - - let mut timing = TimingTree::new("prove", log::Level::Debug); - let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; - timing.filter(Duration::from_millis(100)).print(); - - verify_proof(&all_stark, proof, &config) +fn visit_dirs(dir: &Path) -> anyhow::Result<()> { + if dir == Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stTimeConsuming") + { + return Ok(()); + } + if dir.is_dir() { + log::info!("Found directory: {:?}", dir); + for entry in fs::read_dir(dir)? { + let entry = entry?; + let path = entry.path(); + visit_dirs(&path)?; // Recurse into the subdirectory + } + } else if dir.is_file() { + log::info!("Found file: {:?}", dir); + let bytes = std::fs::read(dir).unwrap(); + let inputs = serde_json::from_slice(&bytes).unwrap(); + + let mut timing = TimingTree::new("prove", log::Level::Debug); + // let proof = prove::(&all_stark, &config, inputs, &mut timing, + // None)?; + simulate_execution::(inputs)?; + timing.filter(Duration::from_millis(100)).print(); + } + Ok(()) } fn init_logger() { diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 618d53af4..04aef3522 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -28,6 +28,7 @@ thiserror = { workspace = true } serde_json = { workspace = true } plonky2 = { workspace = true } + # Local dependencies mpt_trie = { workspace = true } evm_arithmetization = { workspace = true } From 05d75abaf1e7e0a8f3181261eddb67b9d65a1725 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 2 Jul 2024 14:03:47 +0100 Subject: [PATCH 064/118] Fix most unit tests and fix revert_account_created --- .../kernel/asm/journal/account_created.asm | 3 +- .../asm/mpt/linked_list/final_tries.asm | 19 +- .../src/cpu/kernel/tests/account_code.rs | 211 +++++++++++++----- .../src/cpu/kernel/tests/balance.rs | 82 +------ .../src/cpu/kernel/tests/mpt/delete.rs | 69 +++++- .../src/cpu/kernel/tests/mpt/insert.rs | 32 +++ .../src/cpu/kernel/tests/mpt/load.rs | 24 +- 7 files changed, 285 insertions(+), 155 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm index 6e72cb8b2..4748d5cbc 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_created.asm @@ -9,6 +9,5 @@ global revert_account_created: POP %journal_load_1 // stack: address, retdest - %addr_to_state_key - %remove_account_from_linked_list + %delete_account JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index b91a9b7ed..6d221226d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -205,25 +205,32 @@ after_mpt_delete_slot: %stack (storage_ptr_ptr_p, addr, root_ptr_p) -> (addr, root_ptr_p, storage_ptr_ptr_p) %jump(delete_removed_slots) -%macro set_final_tries - PUSH %%after +global set_final_tries: + PUSH set_final_tries_after PUSH @SEGMENT_STORAGE_LINKED_LIST %add_const(5) // Skip the first node. %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) PUSH @SEGMENT_ACCOUNTS_LINKED_LIST %add_const(4) // Skip the first node. %jump(delete_removed_accounts) -%%after: +set_final_tries_after: // stack: new_state_root - PUSH %%after_after SWAP1 - // stack: new_state_root, %%after_after + PUSH set_final_tries_after_after SWAP1 + // stack: new_state_root, set_final_tries_after_after PUSH @SEGMENT_STORAGE_LINKED_LIST %next_slot SWAP1 PUSH @SEGMENT_ACCOUNTS_LINKED_LIST %next_account %jump(insert_all_accounts) -%%after_after: +set_final_tries_after_after: //stack: new_state_root %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + JUMP + +%macro set_final_tries + // stack: (empty) + PUSH %%after + %jump(set_final_tries) +%%after: %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index f6f61fb4b..5ef200f17 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -6,7 +6,7 @@ use ethereum_types::{Address, BigEndianHash, H256, U256}; use hex_literal::hex; use keccak_hash::keccak; use mpt_trie::nibbles::Nibbles; -use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; +use mpt_trie::partial_trie::{HashedPartialTrie, Node, PartialTrie}; use plonky2::field::goldilocks_field::GoldilocksField as F; use plonky2::field::types::Field; use rand::{thread_rng, Rng}; @@ -16,20 +16,58 @@ use crate::cpu::kernel::constants::context_metadata::ContextMetadata::{self, Gas use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; use crate::cpu::kernel::tests::mpt::nibbles_64; -use crate::generation::mpt::{load_all_mpts, AccountRlp}; +use crate::generation::mpt::{ + load_all_mpts, load_linked_lists_and_txn_and_receipt_mpts, AccountRlp, +}; use crate::generation::TrieInputs; use crate::memory::segments::Segment; -use crate::witness::memory::MemoryAddress; +use crate::util::h2u; +use crate::witness::memory::{MemoryAddress, MemorySegmentState}; use crate::witness::operation::CONTEXT_SCALING_FACTOR; -use crate::Node; pub(crate) fn initialize_mpts( interpreter: &mut Interpreter, trie_inputs: &TrieInputs, ) { // Load all MPTs. - let (trie_root_ptrs, trie_data) = - load_all_mpts(trie_inputs).expect("Invalid MPT data for preinitialization"); + let (trie_root_ptrs, state_leaves, storage_leaves, trie_data) = + load_linked_lists_and_txn_and_receipt_mpts(&trie_inputs) + .expect("Invalid MPT data for preinitialization"); + + interpreter.generation_state.memory.contexts[0].segments + [Segment::AccountsLinkedList.unscale()] + .content = state_leaves.iter().map(|&val| Some(val)).collect(); + interpreter.generation_state.memory.contexts[0].segments + [Segment::StorageLinkedList.unscale()] + .content = storage_leaves.iter().map(|&val| Some(val)).collect(); + interpreter.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()].content = + trie_data.iter().map(|&val| Some(val)).collect(); + interpreter.generation_state.trie_root_ptrs = trie_root_ptrs.clone(); + + let accounts_len = Segment::AccountsLinkedList as usize + + interpreter.generation_state.memory.contexts[0].segments + [Segment::AccountsLinkedList.unscale()] + .content + .len(); + let accounts_len_addr = MemoryAddress { + context: 0, + segment: Segment::GlobalMetadata.unscale(), + virt: GlobalMetadata::AccountsLinkedListLen.unscale(), + }; + let storage_len_addr = MemoryAddress { + context: 0, + segment: Segment::GlobalMetadata.unscale(), + virt: GlobalMetadata::StorageLinkedListLen.unscale(), + }; + let storage_len = Segment::StorageLinkedList as usize + + interpreter.generation_state.memory.contexts[0].segments + [Segment::StorageLinkedList.unscale()] + .content + .len(); + interpreter.set_memory_multi_addresses(&[ + (accounts_len_addr, accounts_len.into()), + (storage_len_addr, storage_len.into()), + ]); let state_addr = MemoryAddress::new_bundle((GlobalMetadata::StateTrieRoot as usize).into()).unwrap(); @@ -58,35 +96,26 @@ pub(crate) fn initialize_mpts( } } -// Test account with a given code hash. -fn test_account(code: &[u8]) -> AccountRlp { - AccountRlp { - nonce: U256::from(1111), - balance: U256::from(2222), - storage_root: HashedPartialTrie::from(Node::Empty).hash(), - code_hash: keccak(code), - } -} - -fn random_code() -> Vec { - let mut rng = thread_rng(); - let num_bytes = rng.gen_range(0..1000); - (0..num_bytes).map(|_| rng.gen()).collect() -} - // Stolen from `tests/mpt/insert.rs` // Prepare the interpreter by inserting the account in the state trie. -fn prepare_interpreter( +pub(crate) fn prepare_interpreter( interpreter: &mut Interpreter, address: Address, account: &AccountRlp, ) -> Result<()> { + init_logger(); let mpt_insert_state_trie = KERNEL.global_labels["mpt_insert_state_trie"]; - let mpt_hash_state_trie = KERNEL.global_labels["mpt_hash_state_trie"]; - let mut state_trie: HashedPartialTrie = Default::default(); - let trie_inputs = Default::default(); + let mpt_hash_state_trie = KERNEL.global_labels["check_state_trie"]; + let mut state_trie: HashedPartialTrie = HashedPartialTrie::from(Node::Empty); + let trie_inputs = TrieInputs { + state_trie: HashedPartialTrie::from(Node::Empty), + transactions_trie: HashedPartialTrie::from(Node::Empty), + receipts_trie: HashedPartialTrie::from(Node::Empty), + storage_tries: vec![], + }; initialize_mpts(interpreter, &trie_inputs); + assert_eq!(interpreter.stack(), vec![]); let k = nibbles_64(U256::from_big_endian( keccak(address.to_fixed_bytes()).as_bytes(), @@ -120,6 +149,7 @@ fn prepare_interpreter( .expect("The stack should not overflow"); // key interpreter.run()?; + assert_eq!( interpreter.stack().len(), 0, @@ -127,13 +157,46 @@ fn prepare_interpreter( interpreter.stack() ); + // Set initial tries. + interpreter + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::StorageLinkedList as usize + 7).into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::AccountsLinkedList as usize + 5).into()) + .expect("The stack should not overflow"); + interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); + + // Now, set the payload. + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["mpt_set_payload"]; + + interpreter.run()?; + + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); + interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + // Now, execute mpt_hash_state_trie. + state_trie.insert(k, rlp::encode(account).to_vec()); + let expected_state_trie_hash = state_trie.hash(); + interpreter.set_global_metadata_field( + GlobalMetadata::StateTrieRootDigestAfter, + h2u(expected_state_trie_hash), + ); + interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; + interpreter + .halt_offsets + .push(KERNEL.global_labels["check_txn_trie"]); interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push(1.into()) // Initial length of the trie data segment, unused. + .push(interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)) // Initial trie data segment size, unused. .expect("The stack should not overflow"); interpreter.run()?; @@ -143,15 +206,26 @@ fn prepare_interpreter( "Expected 2 items on stack after hashing, found {:?}", interpreter.stack() ); - let hash = H256::from_uint(&interpreter.stack()[1]); - - state_trie.insert(k, rlp::encode(account).to_vec()); - let expected_state_trie_hash = state_trie.hash(); - assert_eq!(hash, expected_state_trie_hash); Ok(()) } +// Test account with a given code hash. +fn test_account(code: &[u8]) -> AccountRlp { + AccountRlp { + nonce: U256::from(1111), + balance: U256::from(2222), + storage_root: HashedPartialTrie::from(Node::Empty).hash(), + code_hash: keccak(code), + } +} + +fn random_code() -> Vec { + let mut rng = thread_rng(); + let num_bytes = rng.gen_range(0..1000); + (0..num_bytes).map(|_| rng.gen()).collect() +} + #[test] fn test_extcodesize() -> Result<()> { let code = random_code(); @@ -186,6 +260,7 @@ fn test_extcodesize() -> Result<()> { #[test] fn test_extcodecopy() -> Result<()> { + init_logger(); let code = random_code(); let account = test_account(&code); @@ -276,6 +351,36 @@ fn prepare_interpreter_all_accounts( initialize_mpts(interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); + // Set initial tries. + interpreter + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::StorageLinkedList as usize + 7).into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::AccountsLinkedList as usize + 5).into()) + .expect("The stack should not overflow"); + interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); + + // Now, set the payload. + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["mpt_set_payload"]; + + interpreter.run()?; + + assert_eq!( + interpreter.stack().len(), + 2, + "Expected 2 items on stack after hashing, found {:?}", + interpreter.stack() + ); + + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); + interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + // Switch context and initialize memory with the data we need for the tests. interpreter.generation_state.registers.program_counter = 0; interpreter.set_code(1, code.to_vec()); @@ -339,12 +444,10 @@ fn sstore() -> Result<()> { let init_accessed_addresses = KERNEL.global_labels["init_access_lists"]; interpreter.generation_state.registers.program_counter = init_accessed_addresses; interpreter.push(0xdeadbeefu32.into()); - log::debug!("coma comida"); interpreter.run()?; // Prepare the interpreter by inserting the account in the state trie. prepare_interpreter_all_accounts(&mut interpreter, trie_inputs, addr, &code)?; - log::debug!("cpto"); interpreter.run()?; @@ -365,8 +468,21 @@ fn sstore() -> Result<()> { .hash(), ..AccountRlp::default() }; - // Now, execute mpt_hash_state_trie. - let mpt_hash_state_trie = KERNEL.global_labels["mpt_hash_state_trie"]; + + let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty); + expected_state_trie_after.insert(addr_nibbles, rlp::encode(&account_after).to_vec()); + + let expected_state_trie_hash = expected_state_trie_after.hash(); + + interpreter.set_global_metadata_field( + GlobalMetadata::StateTrieRootDigestAfter, + h2u(expected_state_trie_hash), + ); + interpreter + .halt_offsets + .push(KERNEL.global_labels["check_txn_trie"]); + // Now, execute mpt_hash_state_trie and check that the hash is correct. + let mpt_hash_state_trie = KERNEL.global_labels["check_state_trie"]; interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; interpreter.set_is_kernel(true); interpreter.set_context(0); @@ -378,20 +494,6 @@ fn sstore() -> Result<()> { .expect("The stack should not overflow"); interpreter.run()?; - assert_eq!( - interpreter.stack().len(), - 2, - "Expected 2 items on stack after hashing, found {:?}", - interpreter.stack() - ); - - let hash = H256::from_uint(&interpreter.stack()[1]); - - let mut expected_state_trie_after = HashedPartialTrie::from(Node::Empty); - expected_state_trie_after.insert(addr_nibbles, rlp::encode(&account_after).to_vec()); - - let expected_state_trie_hash = expected_state_trie_after.hash(); - assert_eq!(hash, expected_state_trie_hash); Ok(()) } @@ -472,7 +574,7 @@ fn sload() -> Result<()> { .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow."); interpreter - .push(1.into()) // Initial length of the trie data segment, unused. + .push(interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)) // Initial length of the trie data segment, unused. .expect("The stack should not overflow."); interpreter.run()?; @@ -484,13 +586,6 @@ fn sload() -> Result<()> { ); let trie_data_segment_len = interpreter.stack()[0]; - assert_eq!( - trie_data_segment_len, - interpreter - .get_memory_segment(Segment::TrieData) - .len() - .into() - ); let hash = H256::from_uint(&interpreter.stack()[1]); diff --git a/evm_arithmetization/src/cpu/kernel/tests/balance.rs b/evm_arithmetization/src/cpu/kernel/tests/balance.rs index 034df53a8..f8d473fe8 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/balance.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/balance.rs @@ -1,4 +1,5 @@ use anyhow::Result; +use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{Address, BigEndianHash, H256, U256}; use keccak_hash::keccak; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; @@ -9,7 +10,7 @@ use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; -use crate::cpu::kernel::tests::account_code::initialize_mpts; +use crate::cpu::kernel::tests::account_code::prepare_interpreter; use crate::cpu::kernel::tests::mpt::nibbles_64; use crate::generation::mpt::AccountRlp; use crate::Node; @@ -24,83 +25,8 @@ fn test_account(balance: U256) -> AccountRlp { } } -// Stolen from `tests/mpt/insert.rs` -// Prepare the interpreter by inserting the account in the state trie. -fn prepare_interpreter( - interpreter: &mut Interpreter, - address: Address, - account: &AccountRlp, -) -> Result<()> { - let mpt_insert_state_trie = KERNEL.global_labels["mpt_insert_state_trie"]; - let mpt_hash_state_trie = KERNEL.global_labels["mpt_hash_state_trie"]; - let mut state_trie: HashedPartialTrie = Default::default(); - let trie_inputs = Default::default(); - - initialize_mpts(interpreter, &trie_inputs); - assert_eq!(interpreter.stack(), vec![]); - - let k = nibbles_64(U256::from_big_endian( - keccak(address.to_fixed_bytes()).as_bytes(), - )); - // Next, execute mpt_insert_state_trie. - interpreter.generation_state.registers.program_counter = mpt_insert_state_trie; - let trie_data = interpreter.get_trie_data_mut(); - if trie_data.is_empty() { - // In the assembly we skip over 0, knowing trie_data[0] = 0 by default. - // Since we don't explicitly set it to 0, we need to do so here. - trie_data.push(Some(0.into())); - } - let value_ptr = trie_data.len(); - trie_data.push(Some(account.nonce)); - trie_data.push(Some(account.balance)); - // In memory, storage_root gets interpreted as a pointer to a storage trie, - // so we have to ensure the pointer is valid. It's easiest to set it to 0, - // which works as an empty node, since trie_data[0] = 0 = MPT_TYPE_EMPTY. - trie_data.push(Some(H256::zero().into_uint())); - trie_data.push(Some(account.code_hash.into_uint())); - let trie_data_len = trie_data.len().into(); - interpreter.set_global_metadata_field(GlobalMetadata::TrieDataSize, trie_data_len); - interpreter - .push(0xDEADBEEFu32.into()) - .expect("The stack should not overflow"); - interpreter - .push(value_ptr.into()) - .expect("The stack should not overflow"); // value_ptr - interpreter - .push(k.try_into().unwrap()) - .expect("The stack should not overflow"); // key - - interpreter.run()?; - assert_eq!( - interpreter.stack().len(), - 0, - "Expected empty stack after insert, found {:?}", - interpreter.stack() - ); - - // Now, execute mpt_hash_state_trie. - interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; - interpreter - .push(0xDEADBEEFu32.into()) - .expect("The stack should not overflow"); - interpreter - .push(1.into()) // Initial trie data segment size, unused. - .expect("The stack should not overflow"); - interpreter.run()?; - - assert_eq!( - interpreter.stack().len(), - 2, - "Expected 2 items on stack after hashing, found {:?}", - interpreter.stack() - ); - let hash = H256::from_uint(&interpreter.stack()[1]); - - state_trie.insert(k, rlp::encode(account).to_vec()); - let expected_state_trie_hash = state_trie.hash(); - assert_eq!(hash, expected_state_trie_hash); - - Ok(()) +fn init_logger() { + let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); } #[test] diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs index 15a3a36cd..157747327 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs @@ -1,4 +1,5 @@ use anyhow::Result; +use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{BigEndianHash, H256}; use mpt_trie::nibbles::{Nibbles, NibblesIntern}; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; @@ -11,11 +12,19 @@ use crate::cpu::kernel::interpreter::Interpreter; use crate::cpu::kernel::tests::account_code::initialize_mpts; use crate::cpu::kernel::tests::mpt::{nibbles_64, test_account_1_rlp, test_account_2}; use crate::generation::mpt::AccountRlp; +use crate::generation::state::State; use crate::generation::TrieInputs; +use crate::memory::segments::Segment; +use crate::util::h2u; use crate::Node; +fn init_logger() { + let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); +} + #[test] fn mpt_delete_empty() -> Result<()> { + init_logger(); test_state_trie(Default::default(), nibbles_64(0xABC), test_account_2()) } @@ -105,6 +114,29 @@ fn test_state_trie( initialize_mpts(&mut interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); + // Set initial tries. + interpreter + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::StorageLinkedList as usize + 7).into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::AccountsLinkedList as usize + 5).into()) + .expect("The stack should not overflow"); + interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); + + // Now, set the payload. + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["mpt_set_payload"]; + + interpreter.run()?; + + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); + interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + // Next, execute mpt_insert_state_trie. interpreter.generation_state.registers.program_counter = mpt_insert_state_trie; let trie_data = interpreter.get_trie_data_mut(); @@ -140,6 +172,14 @@ fn test_state_trie( interpreter.stack() ); + // Now, run `set_final_tries` so that the trie roots are correct. + interpreter + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["set_final_tries"]; + interpreter.run()?; + // Next, execute mpt_delete, deleting the account we just inserted. let state_trie_ptr = interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot); interpreter.generation_state.registers.program_counter = mpt_delete; @@ -159,20 +199,39 @@ fn test_state_trie( let state_trie_ptr = interpreter.pop().expect("The stack should not be empty"); interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_trie_ptr); + // Now, run `set_final_tries` again so that the trie roots are correct. + interpreter + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["set_final_tries"]; + interpreter.run()?; + // Now, execute mpt_hash_state_trie. + let expected_state_trie_hash = state_trie.hash(); + interpreter.set_global_metadata_field( + GlobalMetadata::StateTrieRootDigestAfter, + h2u(expected_state_trie_hash), + ); + interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; + interpreter + .halt_offsets + .push(KERNEL.global_labels["check_txn_trie"]); interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push(1.into()) // Initial length of the trie data segment, unused. + .push(interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)) // Initial trie data segment size, unused. .expect("The stack should not overflow"); interpreter.run()?; - let state_trie_hash = - H256::from_uint(&interpreter.pop().expect("The stack should not be empty")); - let expected_state_trie_hash = state_trie.hash(); - assert_eq!(state_trie_hash, expected_state_trie_hash); + assert_eq!( + interpreter.stack().len(), + 2, + "Expected 2 items on stack after hashing, found {:?}", + interpreter.stack() + ); Ok(()) } diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs index 771921173..4e61298ff 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs @@ -13,6 +13,7 @@ use crate::cpu::kernel::tests::mpt::{ }; use crate::generation::mpt::AccountRlp; use crate::generation::TrieInputs; +use crate::memory::segments::Segment; use crate::Node; #[test] @@ -180,6 +181,29 @@ fn test_state_trie( initialize_mpts(&mut interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); + // Set initial tries. + interpreter + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::StorageLinkedList as usize + 7).into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::AccountsLinkedList as usize + 5).into()) + .expect("The stack should not overflow"); + interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); + + // Now, set the payload. + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["mpt_set_payload"]; + + interpreter.run()?; + + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); + interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); + // Next, execute mpt_insert_state_trie. interpreter.generation_state.registers.program_counter = mpt_insert_state_trie; let trie_data = interpreter.get_trie_data_mut(); @@ -216,6 +240,14 @@ fn test_state_trie( interpreter.stack() ); + // Now, run `set_final_tries` so that the trie roots are correct. + interpreter + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["set_final_tries"]; + interpreter.run()?; + // Now, execute mpt_hash_state_trie. interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; interpreter diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/load.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/load.rs index 9aa8a1f0b..d3acf14db 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/load.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/load.rs @@ -70,14 +70,20 @@ fn load_all_mpts_leaf() -> Result<()> { assert_eq!( interpreter.get_trie_data(), vec![ - 0.into(), + 0.into(), // First address is unused, so that 0 can be treated as a null pointer. + // The next four elements correspond to the account stored in the linked list. + test_account_1().nonce, + test_account_1().balance, + 0.into(), // pointer to storage trie root before insertion + test_account_1().code_hash.into_uint(), + // Values used for hashing. type_leaf, 3.into(), 0xABC.into(), - 5.into(), // value ptr + 9.into(), // value ptr test_account_1().nonce, test_account_1().balance, - 9.into(), // pointer to storage trie root + 13.into(), // pointer to storage trie root test_account_1().code_hash.into_uint(), // These last two elements encode the storage trie, which is a hash node. (PartialTrieType::Hash as u32).into(), @@ -208,17 +214,23 @@ fn load_all_mpts_ext_to_leaf() -> Result<()> { interpreter.get_trie_data(), vec![ 0.into(), // First address is unused, so that 0 can be treated as a null pointer. + // The next four elements correspond to the account stored in the linked list. + test_account_1().nonce, + test_account_1().balance, + 0.into(), // pointer to storage trie root before insertion + test_account_1().code_hash.into_uint(), + // Values used for hashing. type_extension, 3.into(), // 3 nibbles 0xABC.into(), // key part - 5.into(), // Pointer to the leaf node immediately below. + 9.into(), // Pointer to the leaf node immediately below. type_leaf, 3.into(), // 3 nibbles 0xDEF.into(), // key part - 9.into(), // value pointer + 13.into(), // value pointer test_account_1().nonce, test_account_1().balance, - 13.into(), // pointer to storage trie root + 17.into(), // pointer to storage trie root test_account_1().code_hash.into_uint(), // These last two elements encode the storage trie, which is a hash node. (PartialTrieType::Hash as u32).into(), From f35c2c84085bfed2bc175e68d9960bc92546b77e Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 2 Jul 2024 14:34:50 +0100 Subject: [PATCH 065/118] FIx linked list test and a bit of cleanup --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 2 -- .../src/cpu/kernel/tests/mpt/linked_list.rs | 2 +- evm_arithmetization/tests/add11_yml.rs | 8 +------- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index fd7ed7c7e..b84fd42fa 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -211,7 +211,6 @@ global insert_new_account: %increment %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) // stack: addr, payload_ptr, retdest - // TODO: Don't for get to %journal_add_account_loaded %stack (addr, payload_ptr, retdest) -> (retdest, 0, payload_ptr) JUMP @@ -717,7 +716,6 @@ global debug_yo_no_me_llamo_javier: %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) // stack: addr, key, payload_ptr, retdest - // TODO: Don't for get to %journal_add_storage_loaded!!! %pop2 PUSH 0 SWAP1 diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index beae50361..322c1553e 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -488,7 +488,7 @@ fn test_insert_and_delete_storage() -> Result<()> { let [addr_in_list, key_in_list] = addresses_and_keys[i as usize].map(|x| U256::from(x.0.as_slice())); interpreter.push(retaddr); - interpreter.push(U256::zero()); + interpreter.push(addr_in_list + delta_ptr); interpreter.push(key_in_list); interpreter.push(addr_in_list); interpreter.generation_state.registers.program_counter = insert_slot_label; diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index abd3b204a..00d7e56b4 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -148,7 +148,7 @@ fn add11_yml() -> anyhow::Result<()> { transactions_root: transactions_trie.hash(), receipts_root: receipts_trie.hash(), }; - let _inputs = GenerationInputs { + let inputs = GenerationInputs { signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, @@ -165,12 +165,6 @@ fn add11_yml() -> anyhow::Result<()> { }, }; - let bytes = std::fs::read( - "/Users/agonzalez/Downloads/vitalikTransactionTestParis_d0g0v0_Shanghai.json", - ) - .unwrap(); - let inputs = serde_json::from_slice(&bytes).unwrap(); - let mut timing = TimingTree::new("prove", log::Level::Debug); let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; timing.filter(Duration::from_millis(100)).print(); From 244c9a8cadc91767391643ab7ad40ee6274167f0 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 3 Jul 2024 10:20:48 +0200 Subject: [PATCH 066/118] [WIP] Debugging /stExample/basefeeExample_d0g0v0_Shanghai --- .../src/cpu/kernel/asm/core/process_txn.asm | 5 ++++- .../cpu/kernel/asm/transactions/type_0.asm | 1 + .../cpu/kernel/asm/transactions/type_1.asm | 1 + .../cpu/kernel/asm/transactions/type_2.asm | 5 +++++ .../src/cpu/kernel/interpreter.rs | 2 +- .../src/generation/prover_input.rs | 2 ++ evm_arithmetization/tests/add11_yml.rs | 20 ++++++++++++++++++- 7 files changed, 33 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm index 860edf592..fa92bf1c4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm @@ -32,11 +32,14 @@ global process_normalized_txn: // stack: sender_nonce, sender, retdest %mload_txn_field(@TXN_FIELD_NONCE) // stack: tx_nonce, sender_nonce, sender, retdest +global debug_before_invalid_txn_1: %assert_eq(invalid_txn_1) // stack: sender, retdest // Assert sender has no code. - DUP1 %ext_code_empty %assert_nonzero(invalid_txn_1) + DUP1 %ext_code_empty +global debug_sender_has_no_code: + %assert_nonzero(invalid_txn_1) // stack: sender, retdest // Assert sender balance >= gas_limit * gas_price + value. diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm index 12d105b8a..a7be6763c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm @@ -168,6 +168,7 @@ store_origin: %jumpi(panic) // stack: address, retdest +global debug_mstore_txn_field_origin_0: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm index f8a7a556e..c3ba3a290 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm @@ -133,6 +133,7 @@ store_origin: %jumpi(panic) // stack: address, retdest +global debug_mstore_txn_field_origin_1: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm index 41bdfd4ed..f18d627e8 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm @@ -34,6 +34,7 @@ global process_type_2_txn: %decode_and_store_s // stack: rlp_addr, retdest +global debug_before_alloc_rlp_block: POP // stack: retdest @@ -42,6 +43,7 @@ global process_type_2_txn: // keccak256(0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list])) type_2_compute_signed_data: %alloc_rlp_block +global debug_rlp_addr_start: // stack: rlp_addr_start, retdest %mload_txn_field(@TXN_FIELD_CHAIN_ID) // stack: chain_id, rlp_start, retdest @@ -61,6 +63,7 @@ type_2_compute_signed_data: %mload_txn_field(@TXN_FIELD_MAX_FEE_PER_GAS) %encode_rlp_scalar_swapped_inputs // stack: rlp_addr, rlp_start, retdest +global debug_rlp_addr_2: %mload_txn_field(@TXN_FIELD_GAS_LIMIT) %encode_rlp_scalar_swapped_inputs @@ -79,6 +82,7 @@ zero_to: after_to: %mload_txn_field(@TXN_FIELD_VALUE) %encode_rlp_scalar_swapped_inputs +global debug_rlp_addr_3: // stack: rlp_addr, rlp_start, retdest // Encode txn data. @@ -140,6 +144,7 @@ store_origin: %jumpi(panic) // stack: address, retdest +global debug_mstore_txn_field_origin_2: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index 6364a4ad3..59a4b3233 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -117,7 +117,7 @@ impl Interpreter { jumpdest_table: HashMap::new(), is_jumpdest_analysis: false, clock: 0, - }; + }; interpreter.generation_state.registers.program_counter = initial_offset; let initial_stack_len = initial_stack.len(); interpreter.generation_state.registers.stack_len = initial_stack_len; diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 1c0a187f6..21dce6f81 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -308,6 +308,8 @@ impl GenerationState { /// Generates either the next used jump address or the proof for the last /// jump address. fn run_linked_list(&mut self, input_fn: &ProverInputFn) -> Result { + log::debug!("Current accounts ll = {:?}", self.get_accounts_linked_list()); + log::debug!("Current storage ll = {:?}", self.get_storage_linked_list()); match input_fn.0[1].as_str() { "insert_account" => self.run_next_insert_account(), "remove_account" => self.run_next_remove_account(), diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index c0242e1ea..f49e8c39b 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -167,7 +167,25 @@ fn add11_yml() -> anyhow::Result<()> { cur_hash: H256::default(), }, }; - let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stRandom/randomStatetest163_d0g0v0_Shanghai.json"); + + let good = vec![ + 248, 74, 1, 134, 15, 255, 255, 251, 152, 107, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, + 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, + 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, + 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, + ]; + let good: AccountRlp = rlp::decode(&good).unwrap(); + log::debug!("good = {:#?}", good); + let bad = vec![ + 248, 74, 134, 16, 0, 0, 0, 0, 0, 128, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, + 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, + 33, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + ]; + let bad: AccountRlp = rlp::decode(&bad).unwrap(); + log::debug!("bad = {:#?}", bad); + + let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests//stExample/basefeeExample_d0g0v0_Shanghai.json"); visit_dirs(dir)?; // let bytes = // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ From 54b360af5739e8e8a2646f748198d46ee2df9467 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Wed, 3 Jul 2024 12:29:56 +0100 Subject: [PATCH 067/118] Fix merge and add batch sizes to the benchmark --- .env | 2 + Cargo.lock | 91 ++++++++++--------- .../src/cpu/kernel/constants/mod.rs | 2 +- evm_arithmetization/src/prover.rs | 2 +- trace_decoder/benches/block_processing.rs | 42 +++++---- 5 files changed, 79 insertions(+), 60 deletions(-) diff --git a/.env b/.env index 1fc1ae611..409acd928 100644 --- a/.env +++ b/.env @@ -6,3 +6,5 @@ KECCAK_CIRCUIT_SIZE=14..20 KECCAK_SPONGE_CIRCUIT_SIZE=9..15 LOGIC_CIRCUIT_SIZE=12..18 MEMORY_CIRCUIT_SIZE=17..28 +MEMORY_BEFORE_CIRCUIT_SIZE=7..19 +MEMORY_AFTER_CIRCUIT_SIZE=7..19 diff --git a/Cargo.lock b/Cargo.lock index 2604625cc..932aea482 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,9 +206,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b155716bab55763c95ba212806cf43d05bcc70e5f35b02bad20cf5ec7fe11fed" +checksum = "a43b18702501396fa9bcdeecd533bc85fac75150d308fc0f6800a01e6234a003" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8037e03c7f462a063f28daec9fda285a9a89da003c552f8637a80b9c8fd96241" +checksum = "d83524c1f6162fcb5b0decf775498a125066c86dda6066ed609531b0e912f85a" dependencies = [ "proc-macro2", "quote", @@ -1024,7 +1024,7 @@ dependencies = [ "bitflags 2.6.0", "cexpr", "clang-sys", - "itertools 0.11.0", + "itertools 0.12.1", "lazy_static", "lazycell", "log", @@ -1178,9 +1178,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.101" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac367972e516d45567c7eafc73d24e1c193dcf200a8d94e9db7b3d38b349572d" +checksum = "74b6a57f98764a267ff415d50a25e6e166f3831a5071af4995296ea97d210490" dependencies = [ "jobserver", "libc", @@ -1265,9 +1265,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +checksum = "84b3edb18336f4df585bc9aa31dd99c036dfa5dc5e9a2939a722a188f3a8970d" dependencies = [ "clap_builder", "clap_derive", @@ -1275,9 +1275,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.7" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +checksum = "c1c09dd5ada6c6c78075d6fd0da3f90d8080651e2d6cc8eb2f1aaa4034ced708" dependencies = [ "anstream", "anstyle", @@ -1287,9 +1287,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.5" +version = "4.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2434,9 +2434,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "c4fe55fb7a772d59a5ff1dfbff4fe0258d19b89fec4b233e75d35d5d2316badc" dependencies = [ "bytes", "futures-channel", @@ -2470,9 +2470,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" dependencies = [ "bytes", "futures-channel", @@ -2678,6 +2678,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.13.0" @@ -2900,9 +2909,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" @@ -3052,9 +3061,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", @@ -3150,9 +3159,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" dependencies = [ "memchr", ] @@ -3395,9 +3404,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +checksum = "cd53dff83f26735fdc1ca837098ccf133605d794cdae66acfc2bfac3ec809d95" dependencies = [ "memchr", "thiserror", @@ -3406,9 +3415,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +checksum = "2a548d2beca6773b1c244554d36fcf8548a8a58e74156968211567250e48e49a" dependencies = [ "pest", "pest_generator", @@ -3416,9 +3425,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", @@ -3429,9 +3438,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.10" +version = "2.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +checksum = "a941429fea7e08bedec25e4f6785b6ffaacc6b755da98df5ef3e7dcf4a124c4f" dependencies = [ "once_cell", "pest", @@ -4422,9 +4431,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.118" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d947f6b3163d8857ea16c4fa0dd4840d52f3041039a85decd46867eb1abef2e4" +checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" dependencies = [ "itoa", "ryu", @@ -4464,9 +4473,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad483d2ab0149d5a5ebcd9972a3852711e0153d863bf5a5d0391d28883c4a20" +checksum = "079f3a42cd87588d924ed95b533f8d30a483388c4e400ab736a7058e34f16169" dependencies = [ "base64", "chrono", @@ -4482,9 +4491,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.8.1" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65569b702f41443e8bc8bbb1c5779bd0450bbe723b56198980e80ec45780bce2" +checksum = "bc03aad67c1d26b7de277d51c86892e7d9a0110a2fe44bf6b26cc569fba302d6" dependencies = [ "darling", "proc-macro2", @@ -5699,18 +5708,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", diff --git a/evm_arithmetization/src/cpu/kernel/constants/mod.rs b/evm_arithmetization/src/cpu/kernel/constants/mod.rs index bbbd8f8dc..666dbf79f 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/mod.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/mod.rs @@ -119,7 +119,7 @@ const MISC_CONSTANTS: [(&str, [u8; 32]); 5] = [ // *Note*: Changing this will break some tests. ( "FINAL_REGISTERS_ADDR", - hex!("0000000000000000000000000000000000000000000000000000002200000006"), + hex!("0000000000000000000000000000000000000000000000000000002100000006"), ), ]; diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index a660d88bf..6ab08896f 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -600,7 +600,7 @@ pub(crate) fn generate_next_segment( segment_data.registers_after = updated_registers; Some((segment_data, partial_segment_data)) } else { - None + panic!("Segment generation failed"); } } diff --git a/trace_decoder/benches/block_processing.rs b/trace_decoder/benches/block_processing.rs index 945cbbe88..5dd49fb0f 100644 --- a/trace_decoder/benches/block_processing.rs +++ b/trace_decoder/benches/block_processing.rs @@ -26,23 +26,31 @@ fn criterion_benchmark(c: &mut Criterion) { let bytes = std::fs::read("benches/block_input.json").unwrap(); let prover_input: ProverInput = serde_json::from_slice(&bytes).unwrap(); - let batch_size = 2; - - c.bench_function("Block 19240650 processing", |b| { - b.iter_batched( - || prover_input.clone(), - |pi| { - pi.block_trace - .into_txn_proof_gen_ir( - &ProcessingMeta::new(resolve_code_hash_fn), - prover_input.other_data.clone(), - batch_size, - ) - .unwrap() - }, - BatchSize::LargeInput, - ) - }); + let batch_sizes = vec![1, 2, 4, 8]; + + let mut group = c.benchmark_group("Benchmark group"); + + for batch_size in batch_sizes { + let batch_size_string = + format!("Block 19240650 processing, with batch_size = {batch_size}"); + group.bench_function(batch_size_string, |b| { + b.iter_batched( + || prover_input.clone(), + |pi| { + pi.block_trace + .into_txn_proof_gen_ir( + &ProcessingMeta::new(resolve_code_hash_fn), + prover_input.other_data.clone(), + batch_size, + ) + .unwrap() + }, + BatchSize::LargeInput, + ) + }); + } + + group.finish() } criterion_group!( From da7902b6215fca124c6733efb313d2ec15d1ae3e Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Wed, 3 Jul 2024 12:48:47 +0100 Subject: [PATCH 068/118] Fix test_only in zero_bin --- .env | 4 ++-- Cargo.lock | 1 + zero_bin/ops/src/lib.rs | 11 ++++++----- zero_bin/prover/Cargo.toml | 1 + zero_bin/prover/src/lib.rs | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.env b/.env index 409acd928..52113a893 100644 --- a/.env +++ b/.env @@ -6,5 +6,5 @@ KECCAK_CIRCUIT_SIZE=14..20 KECCAK_SPONGE_CIRCUIT_SIZE=9..15 LOGIC_CIRCUIT_SIZE=12..18 MEMORY_CIRCUIT_SIZE=17..28 -MEMORY_BEFORE_CIRCUIT_SIZE=7..19 -MEMORY_AFTER_CIRCUIT_SIZE=7..19 +MEMORY_BEFORE_CIRCUIT_SIZE=7..23 +MEMORY_AFTER_CIRCUIT_SIZE=7..27 diff --git a/Cargo.lock b/Cargo.lock index 932aea482..e59e8d14d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3820,6 +3820,7 @@ dependencies = [ "num-traits", "ops", "paladin-core", + "plonky2", "proof_gen", "ruint", "serde", diff --git a/zero_bin/ops/src/lib.rs b/zero_bin/ops/src/lib.rs index 352bf2fdd..86ae8c0a4 100644 --- a/zero_bin/ops/src/lib.rs +++ b/zero_bin/ops/src/lib.rs @@ -64,19 +64,20 @@ impl Operation for SegmentProof { type Output = (); fn execute(&self, input: Self::Input) -> Result { - let _span = TxProofSpan::new(&input); + let gen_input = input.0; + let _span = TxProofSpan::new(&gen_input); if self.save_inputs_on_error { evm_arithmetization::prover::testing::simulate_execution::( - input.clone(), + gen_input.clone(), ) .map_err(|err| { if let Err(write_err) = save_inputs_to_disk( format!( "b{}_txn_{}_input.log", - input.block_metadata.block_number, input.txn_number_before + gen_input.block_metadata.block_number, gen_input.txn_number_before ), - input, + gen_input, ) { error!("Failed to save txn proof input to disk: {:?}", write_err); } @@ -85,7 +86,7 @@ impl Operation for SegmentProof { })?; } else { evm_arithmetization::prover::testing::simulate_execution::( - input.0.clone(), + gen_input.clone(), ) .map_err(|err| FatalError::from_anyhow(err, FatalStrategy::Terminate))?; } diff --git a/zero_bin/prover/Cargo.toml b/zero_bin/prover/Cargo.toml index fc16214fa..3c2d9e131 100644 --- a/zero_bin/prover/Cargo.toml +++ b/zero_bin/prover/Cargo.toml @@ -11,6 +11,7 @@ categories.workspace = true [dependencies] serde = { workspace = true } proof_gen = { workspace = true } +plonky2 = { workspace = true } trace_decoder = { workspace = true } tracing = { workspace = true } paladin-core = { workspace = true } diff --git a/zero_bin/prover/src/lib.rs b/zero_bin/prover/src/lib.rs index 9346fa441..24592665d 100644 --- a/zero_bin/prover/src/lib.rs +++ b/zero_bin/prover/src/lib.rs @@ -129,7 +129,7 @@ impl BlockProverInput { max_cpu_len_log: usize, _previous: Option>>, batch_size: usize, - save_inputs_on_error: bool, + _save_inputs_on_error: bool, ) -> Result { use evm_arithmetization::prover::testing::simulate_all_segments_interpreter; use plonky2::field::goldilocks_field::GoldilocksField; From ca490c10a569eaf2064c8c71d1532e117389a29d Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 3 Jul 2024 10:20:48 +0200 Subject: [PATCH 069/118] Fix rlp pointers error --- .../src/cpu/kernel/asm/core/nonce.asm | 4 ++- .../src/cpu/kernel/asm/core/process_txn.asm | 5 +++- .../src/cpu/kernel/asm/main.asm | 2 ++ .../cpu/kernel/asm/transactions/type_0.asm | 1 + .../cpu/kernel/asm/transactions/type_1.asm | 1 + .../cpu/kernel/asm/transactions/type_2.asm | 12 ++++++++ .../src/cpu/kernel/interpreter.rs | 2 +- .../src/generation/prover_input.rs | 2 ++ evm_arithmetization/src/prover.rs | 28 +++++++++++++++++++ evm_arithmetization/tests/add11_yml.rs | 19 ++++++++++++- 10 files changed, 72 insertions(+), 4 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm b/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm index 48486be9e..a087f779f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm @@ -27,7 +27,9 @@ global increment_nonce: // stack: account_ptr, address, retdest DUP1 ISZERO %jumpi(increment_nonce_no_such_account) // stack: nonce_ptr, address, retdest - DUP1 %mload_trie_data + DUP1 +global debug_nonce_ptr: + %mload_trie_data // stack: nonce, nonce_ptr, address, retdest DUP1 DUP4 %journal_add_nonce_change // stack: nonce, nonce_ptr, address, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm index 860edf592..fa92bf1c4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm @@ -32,11 +32,14 @@ global process_normalized_txn: // stack: sender_nonce, sender, retdest %mload_txn_field(@TXN_FIELD_NONCE) // stack: tx_nonce, sender_nonce, sender, retdest +global debug_before_invalid_txn_1: %assert_eq(invalid_txn_1) // stack: sender, retdest // Assert sender has no code. - DUP1 %ext_code_empty %assert_nonzero(invalid_txn_1) + DUP1 %ext_code_empty +global debug_sender_has_no_code: + %assert_nonzero(invalid_txn_1) // stack: sender, retdest // Assert sender balance >= gas_limit * gas_price + value. diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 7abe2c1ae..05d13befb 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -18,6 +18,7 @@ global main: // Initialize the RLP DATA pointer to its initial position, // skipping over the preinitialized empty node. PUSH @INITIAL_TXN_RLP_ADDR + %add_const(@MAX_RLP_BLOB_SIZE) %mstore_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE) // Encode constant nodes @@ -129,6 +130,7 @@ global debug_new_len: %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) global debug_check_initial_trie: %assert_eq + %jump(panic) PUSH 1 // initial trie data length diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm index 12d105b8a..a7be6763c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm @@ -168,6 +168,7 @@ store_origin: %jumpi(panic) // stack: address, retdest +global debug_mstore_txn_field_origin_0: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm index f8a7a556e..c3ba3a290 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm @@ -133,6 +133,7 @@ store_origin: %jumpi(panic) // stack: address, retdest +global debug_mstore_txn_field_origin_1: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm index 41bdfd4ed..e832451c3 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm @@ -10,9 +10,13 @@ global process_type_2_txn: // stack: retdest // Initial rlp address offset of 1 (skipping over the 0x02 byte) + %mload_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE) +global debug_inital_rlp_data_size: + POP PUSH 1 PUSH @INITIAL_TXN_RLP_ADDR %build_kernel_address +global debug_initial_txn_rlp_addr: // stack: rlp_addr, retdest %decode_rlp_list_len // We don't actually need the length. @@ -34,6 +38,10 @@ global process_type_2_txn: %decode_and_store_s // stack: rlp_addr, retdest +%mload_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE) +global debug_rlp_data_size_before_alloc: + POP +global debug_before_alloc_rlp_block: POP // stack: retdest @@ -42,6 +50,7 @@ global process_type_2_txn: // keccak256(0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list])) type_2_compute_signed_data: %alloc_rlp_block +global debug_rlp_addr_start: // stack: rlp_addr_start, retdest %mload_txn_field(@TXN_FIELD_CHAIN_ID) // stack: chain_id, rlp_start, retdest @@ -61,6 +70,7 @@ type_2_compute_signed_data: %mload_txn_field(@TXN_FIELD_MAX_FEE_PER_GAS) %encode_rlp_scalar_swapped_inputs // stack: rlp_addr, rlp_start, retdest +global debug_rlp_addr_2: %mload_txn_field(@TXN_FIELD_GAS_LIMIT) %encode_rlp_scalar_swapped_inputs @@ -79,6 +89,7 @@ zero_to: after_to: %mload_txn_field(@TXN_FIELD_VALUE) %encode_rlp_scalar_swapped_inputs +global debug_rlp_addr_3: // stack: rlp_addr, rlp_start, retdest // Encode txn data. @@ -140,6 +151,7 @@ store_origin: %jumpi(panic) // stack: address, retdest +global debug_mstore_txn_field_origin_2: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index 6364a4ad3..59a4b3233 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -117,7 +117,7 @@ impl Interpreter { jumpdest_table: HashMap::new(), is_jumpdest_analysis: false, clock: 0, - }; + }; interpreter.generation_state.registers.program_counter = initial_offset; let initial_stack_len = initial_stack.len(); interpreter.generation_state.registers.stack_len = initial_stack_len; diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 1c0a187f6..21dce6f81 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -308,6 +308,8 @@ impl GenerationState { /// Generates either the next used jump address or the proof for the last /// jump address. fn run_linked_list(&mut self, input_fn: &ProverInputFn) -> Result { + log::debug!("Current accounts ll = {:?}", self.get_accounts_linked_list()); + log::debug!("Current storage ll = {:?}", self.get_storage_linked_list()); match input_fn.0[1].as_str() { "insert_account" => self.run_next_insert_account(), "remove_account" => self.run_next_remove_account(), diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index f6c40cf89..35b0f0dff 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -368,6 +368,10 @@ pub fn check_abort_signal(abort_signal: Option>) -> Result<()> { /// A utility module designed to test witness generation externally. pub mod testing { + use mpt_trie::partial_trie::HashedPartialTrie; + use crate::{cpu::kernel::constants::global_metadata::GlobalMetadata, generation::trie_extractor::get_state_trie, util::u256_to_usize}; + use mpt_trie::partial_trie::PartialTrie; + use super::*; use crate::{ cpu::kernel::interpreter::Interpreter, @@ -382,6 +386,30 @@ pub mod testing { let mut interpreter: Interpreter = Interpreter::new_with_generation_inputs(initial_offset, initial_stack, inputs); let result = interpreter.run(); + + let final_state_trie: HashedPartialTrie = get_state_trie( + &interpreter.get_generation_state().memory, + u256_to_usize( + interpreter.get_generation_state() + .memory + .read_global_metadata(GlobalMetadata::StateTrieRoot), + ) + .unwrap(), + ) + .unwrap(); + log::debug!("Final state trie: {:?}", final_state_trie); + log::debug!("Final state trie hash: {:?}", final_state_trie.hash()); + log::debug!( + "Final accounts linked list: {:?}", + interpreter.get_generation_state().get_accounts_linked_list() + ); + log::debug!( + "Final storage linked list: {:?}", + interpreter.get_generation_state().get_storage_linked_list() + ); + + + if result.is_err() { output_debug_tries(interpreter.get_generation_state())?; } diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index c0242e1ea..8518c0e35 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -167,7 +167,24 @@ fn add11_yml() -> anyhow::Result<()> { cur_hash: H256::default(), }, }; - let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stRandom/randomStatetest163_d0g0v0_Shanghai.json"); + + let contract_rlp = vec![ + 248, 68, 128, 10, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, + 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, + 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, + 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, + ]; + let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); + log::debug!("contracto ok = {:#?}", contracto); + let contract_rlp = vec![ + 248, 68, 10, 128, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, + 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ]; + let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); + log::debug!("contracto not ok = {:#?}", contracto); + + let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stCreateTest/CreateCollisionToEmpty2_d0g0v0_Shanghai.json"); visit_dirs(dir)?; // let bytes = // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ From c07c4a4817407eafa74c5c164b4939a6f7b88a65 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Wed, 3 Jul 2024 16:03:09 -0400 Subject: [PATCH 070/118] Remove panic --- evm_arithmetization/src/cpu/kernel/asm/main.asm | 1 - 1 file changed, 1 deletion(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 05d13befb..10c9533af 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -130,7 +130,6 @@ global debug_new_len: %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) global debug_check_initial_trie: %assert_eq - %jump(panic) PUSH 1 // initial trie data length From c1d8b4c4c0649c36079d103cfba2c7c1516756aa Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Thu, 4 Jul 2024 10:06:39 +0200 Subject: [PATCH 071/118] [WIP] Debugging InitCollisionParis_d2g0v0_Shanghai --- evm_arithmetization/tests/add11_yml.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 8518c0e35..4b72c3b2e 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -184,7 +184,7 @@ fn add11_yml() -> anyhow::Result<()> { let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); log::debug!("contracto not ok = {:#?}", contracto); - let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stCreateTest/CreateCollisionToEmpty2_d0g0v0_Shanghai.json"); + let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stSStoreTest/InitCollisionParis_d2g0v0_Shanghai.json"); visit_dirs(dir)?; // let bytes = // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ From eaddcc14dc5cfdfadef6c08594a329c09e2bfdfc Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Thu, 4 Jul 2024 11:13:27 +0200 Subject: [PATCH 072/118] [WIP] Debugging stCallCodes/callcallcodecallcode_011_SuicideEnd_d0g0v0_Shanghai --- evm_arithmetization/tests/add11_yml.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 4b72c3b2e..64d1cd124 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -184,7 +184,7 @@ fn add11_yml() -> anyhow::Result<()> { let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); log::debug!("contracto not ok = {:#?}", contracto); - let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stSStoreTest/InitCollisionParis_d2g0v0_Shanghai.json"); + let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stCallCodes/callcallcodecallcode_011_SuicideEnd_d0g0v0_Shanghai.json"); visit_dirs(dir)?; // let bytes = // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ From 29c23a90f13621ec1c885f681e9b4ec36e437d6d Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 4 Jul 2024 11:56:01 +0100 Subject: [PATCH 073/118] Fix remove_all_slots --- .../asm/mpt/linked_list/linked_list.asm | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index b84fd42fa..31c919cd5 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -866,22 +866,26 @@ global debug_after_valid_ptr: DUP3 EQ %jumpi(panic) // stack: pred_ptr, addr, retdest // Now, while the next address is `addr`, remove the slot. + %add_const(4) MLOAD_GENERAL remove_all_slots_loop: - // stack: pred_ptr, addr, retdest - %add_const(4) MLOAD_GENERAL DUP1 + // stack: cur_ptr, addr, retdest + DUP1 // stack: cur_ptr, cur_ptr, addr, retdest DUP1 %eq_const(@U256_MAX) %jumpi(remove_all_slots_end) - MLOAD_GENERAL - // stack: cur_addr, cur_ptr, addr, retdest - DUP1 DUP4 EQ ISZERO %jumpi(remove_all_slots_end) - // stack: cur_addr, cur_ptr, addr, retdest - DUP2 %increment MLOAD_GENERAL SWAP1 - // stack: cur_addr, cur_key, cur_ptr, addr, retdest + %add_const(4) MLOAD_GENERAL SWAP1 DUP1 + // stack: cur_ptr, cur_ptr, next_ptr, addr, retdest + MLOAD_GENERAL + // stack: cur_addr, cur_ptr, next_ptr, addr, retdest + DUP1 DUP5 EQ ISZERO %jumpi(remove_all_slots_pop_and_end) + // stack: cur_addr, cur_ptr, next_ptr, addr, retdest + SWAP1 %increment MLOAD_GENERAL SWAP1 + // stack: cur_addr, cur_key, next_ptr, addr, retdest %remove_slot - // stack: cur_ptr, addr, retdest + // stack: next_ptr, addr, retdest %jump(remove_all_slots_loop) - +remove_all_slots_pop_and_end: + POP remove_all_slots_end: // stack: cur_addr, cur_ptr, addr, retdest %pop3 JUMP From 71e3eeed6b12a440b60ca36dd5df887ba5bdfed4 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Thu, 4 Jul 2024 14:37:23 +0200 Subject: [PATCH 074/118] Clean code --- .../src/cpu/kernel/asm/core/nonce.asm | 1 - .../src/cpu/kernel/asm/core/process_txn.asm | 4 +- .../src/cpu/kernel/asm/main.asm | 22 ++----- .../src/cpu/kernel/asm/mpt/delete/delete.asm | 1 - .../asm/mpt/linked_list/final_tries.asm | 15 ----- .../asm/mpt/linked_list/initial_tries.asm | 3 - .../asm/mpt/linked_list/linked_list.asm | 12 ---- .../kernel/asm/mpt/storage/storage_write.asm | 6 -- .../cpu/kernel/asm/transactions/type_0.asm | 1 - .../cpu/kernel/asm/transactions/type_1.asm | 1 - .../cpu/kernel/asm/transactions/type_2.asm | 6 -- .../src/cpu/kernel/interpreter.rs | 8 +-- .../src/cpu/kernel/tests/account_code.rs | 2 +- .../src/generation/prover_input.rs | 25 +------- .../src/generation/trie_extractor.rs | 2 - evm_arithmetization/tests/add11_yml.rs | 63 ++----------------- evm_arithmetization/tests/erc721.rs | 15 ----- 17 files changed, 16 insertions(+), 171 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm b/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm index a087f779f..dd763f08f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm @@ -28,7 +28,6 @@ global increment_nonce: DUP1 ISZERO %jumpi(increment_nonce_no_such_account) // stack: nonce_ptr, address, retdest DUP1 -global debug_nonce_ptr: %mload_trie_data // stack: nonce, nonce_ptr, address, retdest DUP1 DUP4 %journal_add_nonce_change diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm index fa92bf1c4..90b671bbc 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm @@ -32,13 +32,11 @@ global process_normalized_txn: // stack: sender_nonce, sender, retdest %mload_txn_field(@TXN_FIELD_NONCE) // stack: tx_nonce, sender_nonce, sender, retdest -global debug_before_invalid_txn_1: %assert_eq(invalid_txn_1) // stack: sender, retdest // Assert sender has no code. - DUP1 %ext_code_empty -global debug_sender_has_no_code: + DUP1 %ext_code_empty %assert_nonzero(invalid_txn_1) // stack: sender, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 10c9533af..a4a41e198 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -31,7 +31,6 @@ global main: PROVER_INPUT(linked_list::storage_linked_list_len) %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) PROVER_INPUT(trie_ptr::trie_data_size) -global debug_trie_data_size_1: %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) // Store the inital accounts and slots for hashing later @@ -50,19 +49,12 @@ global hash_initial_tries: // The trie data segment is already written by the linked lists %get_trie_data_size - // %set_initial_tries - // %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) - // global debug_check_hash_after_setting_payloads: - // %assert_eq - - // stack: trie_data_len %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_len %mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_BEFORE) %assert_eq // stack: trie_data_full_len -global debug_trie_size_here: %set_trie_data_size global start_txn: @@ -109,34 +101,28 @@ global perform_final_checks: // stack: cum_gas, txn_counter, num_nibbles, txn_nb // Check that we end up with the correct `cum_gas`, `txn_nb` and bloom filter. %mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_AFTER) -global debug_check_gas: %assert_eq DUP3 %mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_AFTER) -global debug_check_txn_number: %assert_eq %pop3 PROVER_INPUT(trie_ptr::state) %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) -global debug_the_trie_that_works: - %set_initial_tries - %get_trie_data_size -global debug_old_len: + %set_initial_tries + %get_trie_data_size %mpt_hash_state_trie -global debug_new_len: + SWAP1 %set_trie_data_size %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) -global debug_check_initial_trie: %assert_eq PUSH 1 // initial trie data length global check_state_trie: %set_final_tries - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) -global debug_check_final_trie: + %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) %assert_eq global check_txn_trie: %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index 36d4e0b2f..10f50b3e4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -14,7 +14,6 @@ global mpt_delete: DUP1 %eq_const(@MPT_NODE_BRANCH) %jumpi(mpt_delete_branch) DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(mpt_delete_extension) DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(mpt_delete_leaf) - global debug_delete_empty_node: %eq_const(@MPT_NODE_EMPTY) %jumpi(panic) // This should never happen. PANIC diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 0ee55a667..2d4d32f3d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -12,22 +12,18 @@ global insert_all_accounts: DUP1 %eq_const(@U256_MAX) %jumpi(no_more_accounts) -global debug_next_account: DUP4 %increment -global debug_before_loading_account_ptr: MLOAD_GENERAL // stack: account_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %add_const(2) DUP1 -global debug_before_loading_storage_root_ptr: %mload_trie_data // stack: storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %stack (storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr) -> (key, storage_ptr_ptr, storage_root_ptr, after_insert_all_slots, storage_root_ptr_ptr, key) %jump(insert_all_slots) -global debug_after_insert_all_slots: after_insert_all_slots: // stack: storage_ptr_ptr', storage_root_ptr', storage_root_ptr_ptr, key, root_ptr, account_ptr_ptr, retdest SWAP2 @@ -96,7 +92,6 @@ global delete_removed_accounts: // We assume that the size of the initial accounts linked list, containing the accounts // of the initial state, was store at `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. %mload_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) -global debug_inital_accounts_linked_list_len: // The inital accounts linked was store at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. // If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it // suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN` @@ -107,7 +102,6 @@ global debug_inital_accounts_linked_list_len: %next_account %eq_const(@U256_MAX) // Check if the next node pointer is @U256_MAX, the node was deleted %jumpi(delete_account) -global debug_maybe_delete_slots: // The account is still there so we need to delete any removed slot // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP1 @@ -116,16 +110,13 @@ global debug_maybe_delete_slots: DUP2 %add_const(2) MLOAD_GENERAL // get intitial payload_ptr -global debug_inital_payload_ptr: %add_const(2) // storage_root_ptr_ptr = payload_ptr + 2 DUP1 %mload_trie_data %stack (storage_root_ptr, storage_root_ptr_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr) -> (key, storage_root_ptr, storage_ptr_ptr, after_delete_removed_slots, storage_root_ptr_ptr, account_ptr_ptr, root_ptr) -global debug_delete_removed_slots: %jump(delete_removed_slots) -global debug_after_delete_removed_slots: after_delete_removed_slots: // stack: storage_root_ptr', storage_ptr_ptr', storage_root_ptr_ptr, account_ptr_ptr, root_ptr, retdest SWAP1 SWAP2 @@ -142,7 +133,6 @@ delete_removed_accounts_end: // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest %stack (account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr) JUMP -global debug_delete_account: delete_account: // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP1 @@ -169,7 +159,6 @@ delete_removed_slots: EQ %mload_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) DUP5 -global debug_in_inital_storage: LT MUL // AND // jump if we either change the address or reach the en of the initial linked list @@ -177,13 +166,11 @@ global debug_in_inital_storage: // If we are here we have deleted all the slots for this key %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) JUMP -global debug_maybe_delete_this_slot: maybe_delete_this_slot: // stack: addr, root_ptr, storage_ptr_ptr, retdest DUP3 %next_slot %eq_const(@U256_MAX) // Check if the node was deleted -global debug_shoul_we_delete_this_slot: %jumpi(delete_this_slot) // The slot was not deleted, so we skip it. // stack: addr, root_ptr, storage_ptr_ptr, retdest @@ -191,14 +178,12 @@ global debug_shoul_we_delete_this_slot: %add_const(5) SWAP2 %jump(delete_removed_slots) -global debug_delete_this_slot: delete_this_slot: // stack: addr, root_ptr, storage_ptr_ptr, retdest DUP3 %increment MLOAD_GENERAL %stack (key, addr, root_ptr, storage_ptr_ptr) -> (root_ptr, 64, key, after_mpt_delete_slot, addr, storage_ptr_ptr) -global debug_before_deleting: %jump(mpt_delete) after_mpt_delete_slot: // stack: root_ptr', addr, storage_ptr_ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index f94e98bba..cd64f166e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -154,9 +154,7 @@ after_set_storage_payload: %stack (new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> (new_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) -global debug_sera_aca: %mstore_trie_data // The account in the linked list has no storage root so we need to manually set it. -global debug_sera_aca_signo_de_interrogacion: %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. // stack: account_ptr_ptr, storage_ptr_ptr', retdest %add_const(4) // The next pointer is at distance 4 @@ -173,7 +171,6 @@ set_payload_storage_leaf: DUP2 MLOAD_GENERAL SWAP1 -global debug_o_quizas_aca: %mstore_trie_data // stack: storage_ptr_ptr, retdest %add_const(5) // The next pointer is at distance 5 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 51d000d9a..5c3bbf656 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -90,13 +90,11 @@ loop_store_initial_accounts: // stack: nonce_ptr, cpy_ptr, current_node_ptr, retdest DUP1 %mload_trie_data // nonce -global debug_storing_nonce: %append_to_trie_data %increment // stack: balance_ptr, cpy_ptr, current_node_ptr, retdest DUP1 %mload_trie_data // balance -global debug_storing_balance: %append_to_trie_data %increment // The storage_root_ptr is not really necessary // stack: storage_root_ptr_ptr, cpy_ptr, current_node_ptr, retdest @@ -105,15 +103,12 @@ global debug_storing_balance: %append_to_trie_data %increment // stack: code_hash_ptr, cpy_ptr, current_node_ptr, retdest -global debug_loading_code_hash: %mload_trie_data // code_hash -global debug_code_hash: %append_to_trie_data // stack: cpy_ptr, current_node_ptr, retdest DUP2 %add_const(2) SWAP1 -global debug_store_account_cpy_ptr: MSTORE_GENERAL // Store cpy_ptr %next_account %jump(loop_store_initial_accounts) @@ -421,7 +416,6 @@ global store_initial_slots: PUSH @SEGMENT_STORAGE_LINKED_LIST %next_slot -global debug_el_loooooop: loop_store_initial_slots: // stack: current_node_ptr %get_trie_data_size @@ -433,7 +427,6 @@ loop_store_initial_slots: DUP2 %add_const(2) MLOAD_GENERAL -global debug_payload_ptr: // stack: payload_ptr, cpy_ptr, current_node_ptr, retdest %mload_trie_data %append_to_trie_data @@ -698,7 +691,6 @@ slot_found_write: // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest SWAP1 DUP5 -global debug_store_new_payload: MSTORE_GENERAL // Store the new payload // TODO: remove the unused cold access %stack (orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, 0, orig_payload_ptr) @@ -837,8 +829,6 @@ global search_slot: %jump_neq_const(@U256_MAX, slot_found_no_write) // The storage key is not in the list. PANIC - -global debug_slot_not_found: slot_not_found: // stack: pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest %stack (pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest) @@ -909,8 +899,6 @@ global remove_all_account_slots: PROVER_INPUT(linked_list::remove_address_slots) // pred_ptr/5, retdest %get_valid_slot_ptr - -global debug_after_valid_ptr: // stack: pred_ptr, addr, retdest // First, check that the previous address is not `addr` DUP1 MLOAD_GENERAL diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index 40255ef05..ca38b8735 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -109,12 +109,10 @@ sstore_after_refund: // If the value is zero, delete the slot from the storage trie. // stack: slot, value, kexit_info -global debug_kexit_info: DUP2 ISZERO %jumpi(sstore_delete) // First we write the value to MPT data, and get a pointer to it. %get_trie_data_size -global debug_value_ptr: // stack: value_ptr, slot, value, kexit_info SWAP2 // stack: value, slot, value_ptr, kexit_info @@ -123,7 +121,6 @@ global debug_value_ptr: // DEBUG DUP2 %mload_trie_data -global debug_the_value: POP // ENDDEBUG @@ -140,7 +137,6 @@ sstore_noop: EXIT_KERNEL // Delete the slot from the storage trie. -global debug_sstore_delete: sstore_delete: // stack: slot, value, kexit_info SWAP1 POP @@ -149,7 +145,5 @@ sstore_delete: // stack: storage_key, kexit_info %address %addr_to_state_key -global debug_remove_slot: %remove_slot -global debug_que_pasa_por_dios_santo: EXIT_KERNEL diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm index a7be6763c..12d105b8a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_0.asm @@ -168,7 +168,6 @@ store_origin: %jumpi(panic) // stack: address, retdest -global debug_mstore_txn_field_origin_0: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm index c3ba3a290..f8a7a556e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_1.asm @@ -133,7 +133,6 @@ store_origin: %jumpi(panic) // stack: address, retdest -global debug_mstore_txn_field_origin_1: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm index f4272a1c0..41bdfd4ed 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/type_2.asm @@ -13,7 +13,6 @@ global process_type_2_txn: PUSH 1 PUSH @INITIAL_TXN_RLP_ADDR %build_kernel_address -global debug_initial_txn_rlp_addr: // stack: rlp_addr, retdest %decode_rlp_list_len // We don't actually need the length. @@ -35,7 +34,6 @@ global debug_initial_txn_rlp_addr: %decode_and_store_s // stack: rlp_addr, retdest -global debug_before_alloc_rlp_block: POP // stack: retdest @@ -44,7 +42,6 @@ global debug_before_alloc_rlp_block: // keccak256(0x02 || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, destination, amount, data, access_list])) type_2_compute_signed_data: %alloc_rlp_block -global debug_rlp_addr_start: // stack: rlp_addr_start, retdest %mload_txn_field(@TXN_FIELD_CHAIN_ID) // stack: chain_id, rlp_start, retdest @@ -64,7 +61,6 @@ global debug_rlp_addr_start: %mload_txn_field(@TXN_FIELD_MAX_FEE_PER_GAS) %encode_rlp_scalar_swapped_inputs // stack: rlp_addr, rlp_start, retdest -global debug_rlp_addr_2: %mload_txn_field(@TXN_FIELD_GAS_LIMIT) %encode_rlp_scalar_swapped_inputs @@ -83,7 +79,6 @@ zero_to: after_to: %mload_txn_field(@TXN_FIELD_VALUE) %encode_rlp_scalar_swapped_inputs -global debug_rlp_addr_3: // stack: rlp_addr, rlp_start, retdest // Encode txn data. @@ -145,7 +140,6 @@ store_origin: %jumpi(panic) // stack: address, retdest -global debug_mstore_txn_field_origin_2: %mstore_txn_field(@TXN_FIELD_ORIGIN) // stack: retdest %jump(process_normalized_txn) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index 59a4b3233..166cdbc0b 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -542,15 +542,15 @@ impl State for Interpreter { } fn log_debug(&self, msg: String) { - // if !self.is_jumpdest_analysis { + if !self.is_jumpdest_analysis { log::debug!("{}", msg); - // } + } } fn log(&self, level: Level, msg: String) { - // if !self.is_jumpdest_analysis { + if !self.is_jumpdest_analysis { log::log!(level, "{}", msg); - // } + } } } diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index 1416f745a..f3a2ed6c1 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -41,7 +41,7 @@ pub(crate) fn initialize_mpts( [Segment::StorageLinkedList.unscale()] .content = storage_leaves.iter().map(|&val| Some(val)).collect(); interpreter.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()].content = - trie_data.iter().map(|&val| Some(val)).collect(); + trie_data.clone(); interpreter.generation_state.trie_root_ptrs = trie_root_ptrs.clone(); let accounts_len = Segment::AccountsLinkedList as usize diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 21dce6f81..5bb8fae6b 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -80,28 +80,10 @@ impl GenerationState { "state" => match self.trie_root_ptrs.state_root_ptr { Some(state_root_ptr) => Ok(state_root_ptr), None => { - log::debug!( - "trie_data_len before: = {:?}", - self.memory.contexts[0].segments[Segment::TrieData.unscale()] - .content - .len() - ); - let n = load_state_mpt( + load_state_mpt( &self.inputs.tries, &mut self.memory.contexts[0].segments[Segment::TrieData.unscale()].content, - )?; - log::debug!( - "state_trie before: = {:?}", - get_state_trie::(&self.memory, n) - ); - log::debug!( - "trie_data_len after = {:?}", - self.memory.contexts[0].segments[Segment::TrieData.unscale()] - .content - .len() - ); - log::debug!("and n = {:?} ", n); - Ok(n) + ) } } .map(U256::from), @@ -308,8 +290,6 @@ impl GenerationState { /// Generates either the next used jump address or the proof for the last /// jump address. fn run_linked_list(&mut self, input_fn: &ProverInputFn) -> Result { - log::debug!("Current accounts ll = {:?}", self.get_accounts_linked_list()); - log::debug!("Current storage ll = {:?}", self.get_storage_linked_list()); match input_fn.0[1].as_str() { "insert_account" => self.run_next_insert_account(), "remove_account" => self.run_next_remove_account(), @@ -492,7 +472,6 @@ impl GenerationState { fn run_next_insert_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - log::debug!("le storage ll = {:?}", self.get_storage_linked_list()); if let Some((([.., pred_ptr], _), _)) = self .get_storage_linked_list()? .zip(self.get_storage_linked_list()?.skip(1)) diff --git a/evm_arithmetization/src/generation/trie_extractor.rs b/evm_arithmetization/src/generation/trie_extractor.rs index 433e3773f..189f92771 100644 --- a/evm_arithmetization/src/generation/trie_extractor.rs +++ b/evm_arithmetization/src/generation/trie_extractor.rs @@ -197,8 +197,6 @@ pub(crate) fn read_state_rlp_value( get_trie(memory, slice[2].unwrap_or_default().as_usize(), |_, x| { Ok(rlp::encode(&read_storage_trie_value(x)).to_vec()) })?; - log::debug!("storage_trie = {:?}", storage_trie); - log::debug!("storage_trie hash = {:?}", storage_trie.hash()); let account = AccountRlp { nonce: slice[0].unwrap_or_default(), balance: slice[1].unwrap_or_default(), diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 187f59b46..00d7e56b4 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -1,6 +1,4 @@ use std::collections::HashMap; -use std::fs; -use std::path::Path; use std::str::FromStr; use std::time::Duration; @@ -10,7 +8,6 @@ use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; use evm_arithmetization::prover::prove; -use evm_arithmetization::prover::testing::simulate_execution; use evm_arithmetization::verifier::verify_proof; use evm_arithmetization::{AllStark, Node, StarkConfig}; use hex_literal::hex; @@ -168,63 +165,11 @@ fn add11_yml() -> anyhow::Result<()> { }, }; - let contract_rlp = vec![ - 248, 68, 128, 10, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, - 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, - 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, - 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, - ]; - let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); - log::debug!("contracto ok = {:#?}", contracto); - let contract_rlp = vec![ - 248, 68, 10, 128, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, - 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - ]; - let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); - log::debug!("contracto not ok = {:#?}", contracto); - - let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stCallCodes/callcallcodecallcode_011_SuicideEnd_d0g0v0_Shanghai.json"); - visit_dirs(dir)?; - // let bytes = - // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ - // stTimeConsuming/static_Call50000_sha256_d0g0v0_Shanghai.json").unwrap(); - // let inputs = serde_json::from_slice(&bytes).unwrap(); - - // let mut timing = TimingTree::new("prove", log::Level::Debug); - // // let proof = prove::(&all_stark, &config, inputs, &mut - // timing, // None)?; - // simulate_execution::(inputs)?; - // timing.filter(Duration::from_millis(100)).print(); - - Ok(()) - // verify_proof(&all_stark, proof, &config) -} + let mut timing = TimingTree::new("prove", log::Level::Debug); + let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; + timing.filter(Duration::from_millis(100)).print(); -fn visit_dirs(dir: &Path) -> anyhow::Result<()> { - if dir == Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stTimeConsuming") - { - return Ok(()); - } - if dir.is_dir() { - log::info!("Found directory: {:?}", dir); - for entry in fs::read_dir(dir)? { - let entry = entry?; - let path = entry.path(); - visit_dirs(&path)?; // Recurse into the subdirectory - } - } else if dir.is_file() { - log::info!("Found file: {:?}", dir); - let bytes = std::fs::read(dir).unwrap(); - let inputs = serde_json::from_slice(&bytes).unwrap(); - - let mut timing = TimingTree::new("prove", log::Level::Debug); - // let proof = prove::(&all_stark, &config, inputs, &mut timing, - // None)?; - simulate_execution::(inputs)?; - timing.filter(Duration::from_millis(100)).print(); - } - Ok(()) + verify_proof(&all_stark, proof, &config) } fn init_logger() { diff --git a/evm_arithmetization/tests/erc721.rs b/evm_arithmetization/tests/erc721.rs index d9f4950b8..86dd34002 100644 --- a/evm_arithmetization/tests/erc721.rs +++ b/evm_arithmetization/tests/erc721.rs @@ -90,24 +90,11 @@ fn test_erc721() -> anyhow::Result<()> { balance: owner_account.balance - gas_used * 0xa, ..owner_account }; - log::debug!("owner_account_after = {:#?}", owner_account_after); - log::debug!("rlp = {:?}", rlp::encode(&owner_account_after).to_vec()); state_trie_after.insert(owner_nibbles, rlp::encode(&owner_account_after).to_vec())?; let contract_account_after = AccountRlp { storage_root: contract_storage_after()?.hash(), ..contract_account()? }; - let contract_rlp = vec![ - 248, 68, 128, 128, 160, 170, 228, 246, 195, 175, 195, 151, 238, 191, 55, 177, 52, 189, - 63, 57, 60, 183, 166, 42, 180, 177, 68, 248, 100, 159, 53, 229, 131, 170, 243, 88, 168, - 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2, - ]; - let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); - log::debug!("constract_account_after = {:#?}", contract_account()); - log::debug!("contracto = {:#?}", contracto); - log::debug!("rlp = {:?}", rlp::encode(&contract_account_after).to_vec()); - log::debug!("contrc_storage_trie = {:#?}", contract_storage_after()); state_trie_after.insert( contract_nibbles, rlp::encode(&contract_account_after).to_vec(), @@ -189,8 +176,6 @@ fn test_erc721() -> anyhow::Result<()> { }, }; - log::debug!("state hash ={:?}", inputs.tries.state_trie.hash()); - log::debug!("Expected final trie = {:#?}", expected_state_trie_after); let mut timing = TimingTree::new("prove", log::Level::Debug); let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; timing.filter(Duration::from_millis(100)).print(); From 352767ffde5422640b5579e9ea270d8450ea05a2 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Thu, 4 Jul 2024 14:57:51 +0200 Subject: [PATCH 075/118] Fix account code initialize mpts --- evm_arithmetization/src/cpu/kernel/tests/account_code.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index f3a2ed6c1..553574d79 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -78,12 +78,15 @@ pub(crate) fn initialize_mpts( let len_addr = MemoryAddress::new_bundle((GlobalMetadata::TrieDataSize as usize).into()).unwrap(); - let to_set = [ - (state_addr, trie_root_ptrs.state_root_ptr.unwrap().into()), + let mut to_set = vec![]; + if let Some(state_root_ptr) = trie_root_ptrs.state_root_ptr { + to_set.push( (state_addr, state_root_ptr.into())); + } + to_set.extend([ (txn_addr, trie_root_ptrs.txn_root_ptr.into()), (receipts_addr, trie_root_ptrs.receipt_root_ptr.into()), (len_addr, trie_data.len().into()), - ]; + ]); interpreter.set_memory_multi_addresses(&to_set); From a31692a7cf9423463fb405c1db171a3de3282d68 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 4 Jul 2024 11:27:31 +0100 Subject: [PATCH 076/118] Apply comments and fix CI. --- zero_bin/leader/src/cli.rs | 6 +++--- zero_bin/ops/src/lib.rs | 25 ++++++++++++++----------- zero_bin/prover/src/lib.rs | 6 ++---- zero_bin/tools/prove_stdio.sh | 26 +++++++++++++++++++++----- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/zero_bin/leader/src/cli.rs b/zero_bin/leader/src/cli.rs index ecbe21562..9ec32a420 100644 --- a/zero_bin/leader/src/cli.rs +++ b/zero_bin/leader/src/cli.rs @@ -29,7 +29,7 @@ pub(crate) enum Command { previous_proof: Option, #[arg(short, long, default_value_t = 20)] max_cpu_len_log: usize, - #[arg(short, long, default_value_t = 2)] + #[arg(short, long, default_value_t = 1)] batch_size: usize, /// If true, save the public inputs to disk on error. #[arg(short, long, default_value_t = false)] @@ -59,7 +59,7 @@ pub(crate) enum Command { /// The log of the max number of CPU cycles per proof. #[arg(short, long, default_value_t = 20)] max_cpu_len_log: usize, - #[arg(short, long, default_value_t = 2)] + #[arg(short, long, default_value_t = 1)] batch_size: usize, /// If true, save the public inputs to disk on error. #[arg(short, long, default_value_t = false)] @@ -94,7 +94,7 @@ pub(crate) enum Command { output_dir: PathBuf, #[arg(short, long, default_value_t = 20)] max_cpu_len_log: usize, - #[arg(short, long, default_value_t = 2)] + #[arg(short, long, default_value_t = 1)] batch_size: usize, /// If true, save the public inputs to disk on error. #[arg(short, long, default_value_t = false)] diff --git a/zero_bin/ops/src/lib.rs b/zero_bin/ops/src/lib.rs index 86ae8c0a4..96584ae33 100644 --- a/zero_bin/ops/src/lib.rs +++ b/zero_bin/ops/src/lib.rs @@ -31,7 +31,7 @@ impl Operation for SegmentProof { fn execute(&self, all_data: Self::Input) -> Result { let input = all_data.0.clone(); - let _span = TxProofSpan::new(&input); + let _span = SegmentProofSpan::new(&input, all_data.1.segment_index()); let proof = if self.save_inputs_on_error { zero_bin_common::prover_state::p_manager() .generate_segment_proof(all_data) @@ -65,7 +65,7 @@ impl Operation for SegmentProof { fn execute(&self, input: Self::Input) -> Result { let gen_input = input.0; - let _span = TxProofSpan::new(&gen_input); + let _span = SegmentProofSpan::new(&gen_input, input.1.segment_index()); if self.save_inputs_on_error { evm_arithmetization::prover::testing::simulate_execution::( @@ -99,18 +99,21 @@ impl Operation for SegmentProof { /// /// - When created, it starts a span with the transaction proof id. /// - When dropped, it logs the time taken by the transaction proof. -struct TxProofSpan { +struct SegmentProofSpan { _span: tracing::span::EnteredSpan, start: Instant, descriptor: String, } -impl TxProofSpan { +impl SegmentProofSpan { /// Get a unique id for the transaction proof. - fn get_id(ir: &GenerationInputs) -> String { + fn get_id(ir: &GenerationInputs, segment_index: usize) -> String { format!( - "b{} - {}", - ir.block_metadata.block_number, ir.txn_number_before + "b{} - {}_{} ({})", + ir.block_metadata.block_number, + ir.txn_number_before, + ir.txn_number_before + ir.signed_txns.len(), + segment_index ) } @@ -135,8 +138,8 @@ impl TxProofSpan { /// Create a new transaction proof span. /// /// When dropped, it logs the time taken by the transaction proof. - fn new(ir: &GenerationInputs) -> Self { - let id = Self::get_id(ir); + fn new(ir: &GenerationInputs, segment_index: usize) -> Self { + let id = Self::get_id(ir, segment_index); let span = info_span!("p_gen", id).entered(); let start = Instant::now(); let descriptor = Self::get_descriptor(ir); @@ -148,11 +151,11 @@ impl TxProofSpan { } } -impl Drop for TxProofSpan { +impl Drop for SegmentProofSpan { fn drop(&mut self) { event!( Level::INFO, - "txn proof ({}) took {:?}", + "segment proof ({}) took {:?}", self.descriptor, self.start.elapsed() ); diff --git a/zero_bin/prover/src/lib.rs b/zero_bin/prover/src/lib.rs index 24592665d..aa5367dc0 100644 --- a/zero_bin/prover/src/lib.rs +++ b/zero_bin/prover/src/lib.rs @@ -5,10 +5,7 @@ use alloy::primitives::{BlockNumber, U256}; use anyhow::{Context, Result}; use futures::{future::BoxFuture, stream::FuturesOrdered, FutureExt, TryFutureExt, TryStreamExt}; use num_traits::ToPrimitive as _; -use paladin::{ - directive::{Directive, IndexedStream}, - runtime::Runtime, -}; +use paladin::runtime::Runtime; use proof_gen::proof_types::GeneratedBlockProof; use serde::{Deserialize, Serialize}; use tokio::io::AsyncWriteExt; @@ -47,6 +44,7 @@ impl BlockProverInput { use anyhow::Context as _; use evm_arithmetization::prover::SegmentDataIterator; use futures::{stream::FuturesUnordered, FutureExt}; + use paladin::directive::{Directive, IndexedStream}; let block_number = self.get_block_number(); info!("Proving block {block_number}"); diff --git a/zero_bin/tools/prove_stdio.sh b/zero_bin/tools/prove_stdio.sh index 43f62dd59..a1b8eee47 100755 --- a/zero_bin/tools/prove_stdio.sh +++ b/zero_bin/tools/prove_stdio.sh @@ -51,17 +51,31 @@ if [[ $TEST_ONLY == "test_only" ]]; then export KECCAK_SPONGE_CIRCUIT_SIZE="9..10" export LOGIC_CIRCUIT_SIZE="12..13" export MEMORY_CIRCUIT_SIZE="17..18" + export MEMORY_BEFORE_CIRCUIT_SIZE="17..18" + export MEMORY_AFTER_CIRCUIT_SIZE="17..18" else if [[ $INPUT_FILE == *"witness_b19240705"* ]]; then # These sizes are configured specifically for block 19240705. Don't use this in other scenarios echo "Using specific circuit sizes for witness_b19240705.json" export ARITHMETIC_CIRCUIT_SIZE="16..19" - export BYTE_PACKING_CIRCUIT_SIZE="16..19" + export BYTE_PACKING_CIRCUIT_SIZE="15..19" export CPU_CIRCUIT_SIZE="18..21" - export KECCAK_CIRCUIT_SIZE="15..18" - export KECCAK_SPONGE_CIRCUIT_SIZE="10..13" - export LOGIC_CIRCUIT_SIZE="13..17" - export MEMORY_CIRCUIT_SIZE="20..23" + export KECCAK_CIRCUIT_SIZE="13..17" + export KECCAK_SPONGE_CIRCUIT_SIZE="8..13" + export LOGIC_CIRCUIT_SIZE="11..16" + export MEMORY_CIRCUIT_SIZE="19..23" + export MEMORY_BEFORE_CIRCUIT_SIZE="7..18" + export MEMORY_AFTER_CIRCUIT_SIZE="7..18" + elif [[ $INPUT_FILE == *"witness_b2_b7.json"* ]]; then + export ARITHMETIC_CIRCUIT_SIZE="13..17" + export BYTE_PACKING_CIRCUIT_SIZE="13..15" + export CPU_CIRCUIT_SIZE="16..17" + export KECCAK_CIRCUIT_SIZE="9..12" + export KECCAK_SPONGE_CIRCUIT_SIZE="7..9" + export LOGIC_CIRCUIT_SIZE="10..12" + export MEMORY_CIRCUIT_SIZE="18..20" + export MEMORY_BEFORE_CIRCUIT_SIZE="15..17" + export MEMORY_AFTER_CIRCUIT_SIZE="7..8" else export ARITHMETIC_CIRCUIT_SIZE="16..23" export BYTE_PACKING_CIRCUIT_SIZE="9..21" @@ -70,6 +84,8 @@ else export KECCAK_SPONGE_CIRCUIT_SIZE="9..15" export LOGIC_CIRCUIT_SIZE="12..18" export MEMORY_CIRCUIT_SIZE="17..28" + export MEMORY_BEFORE_CIRCUIT_SIZE="7..27" + export MEMORY_AFTER_CIRCUIT_SIZE="7..28" fi fi From 2ce9465da06fbb584ff7241ff46bbbcf4990b440 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 4 Jul 2024 18:03:43 +0100 Subject: [PATCH 077/118] Improve remove_all_slots_loop --- .../asm/mpt/linked_list/linked_list.asm | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 31c919cd5..6416824a0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -865,30 +865,38 @@ global debug_after_valid_ptr: // stack: pred_addr, pred_ptr, addr, retdest DUP3 EQ %jumpi(panic) // stack: pred_ptr, addr, retdest - // Now, while the next address is `addr`, remove the slot. - %add_const(4) MLOAD_GENERAL + DUP1 +// Now, while the next address is `addr`, remove the next slot. remove_all_slots_loop: - // stack: cur_ptr, addr, retdest - DUP1 - // stack: cur_ptr, cur_ptr, addr, retdest + // stack: pred_ptr, pred_ptr, addr, retdest + %add_const(4) DUP1 MLOAD_GENERAL + // stack: cur_ptr, cur_ptr_ptr, pred_ptr, addr, retdest DUP1 %eq_const(@U256_MAX) %jumpi(remove_all_slots_end) - %add_const(4) MLOAD_GENERAL SWAP1 DUP1 - // stack: cur_ptr, cur_ptr, next_ptr, addr, retdest - MLOAD_GENERAL - // stack: cur_addr, cur_ptr, next_ptr, addr, retdest - DUP1 DUP5 EQ ISZERO %jumpi(remove_all_slots_pop_and_end) - // stack: cur_addr, cur_ptr, next_ptr, addr, retdest - SWAP1 %increment MLOAD_GENERAL SWAP1 - // stack: cur_addr, cur_key, next_ptr, addr, retdest - %remove_slot - // stack: next_ptr, addr, retdest + DUP1 %add_const(4) MLOAD_GENERAL + // stack: next_ptr, cur_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + SWAP1 DUP1 + // stack: cur_ptr, cur_ptr, next_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + MLOAD_GENERAL + DUP6 EQ ISZERO %jumpi(remove_all_slots_pop_and_end) + + // Remove slot: update the value in cur_ptr_ptr, and set cur_ptr+4 to @U256_MAX. + // stack: cur_ptr, next_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + SWAP2 SWAP1 + // stack: next_ptr, cur_ptr_ptr, cur_ptr, pred_ptr, addr, retdest + MSTORE_GENERAL + // stack: cur_ptr, pred_ptr, addr, retdest + %add_const(4) PUSH @U256_MAX + MSTORE_GENERAL + // stack: pred_ptr, addr, retdest + DUP1 %jump(remove_all_slots_loop) + remove_all_slots_pop_and_end: POP remove_all_slots_end: // stack: cur_addr, cur_ptr, addr, retdest - %pop3 JUMP + %pop4 JUMP %macro remove_all_account_slots %stack (addr) -> (addr, %%after) From 9d6072b2c9483ddae595f8ca27676dacf5327479 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Fri, 5 Jul 2024 08:09:41 -0400 Subject: [PATCH 078/118] Fix stack comment --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 6416824a0..d484e5b0e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -895,7 +895,7 @@ remove_all_slots_loop: remove_all_slots_pop_and_end: POP remove_all_slots_end: - // stack: cur_addr, cur_ptr, addr, retdest + // stack: next_ptr, cur_ptr_ptr, pred_ptr, addr, retdest %pop4 JUMP %macro remove_all_account_slots From 899d471909ecfa8d064f2e64c1bb0e4122eb4498 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Fri, 5 Jul 2024 08:17:50 -0400 Subject: [PATCH 079/118] Misc, faster get_valid_slot_ptr --- .../cpu/kernel/asm/mpt/linked_list/linked_list.asm | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index d484e5b0e..503c53815 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -388,13 +388,16 @@ global remove_account: // In this way @SEGMENT_STORAGE_LINKED_LIST + 5*ptr/5 must be pointing to the beginning of a node. // TODO: Maybe we should check here if the node have been deleted. %macro get_valid_slot_ptr - // stack: ptr/5 + // stack: ptr/5 DUP1 + PUSH 5 + PUSH @SEGMENT_STORAGE_LINKED_LIST + // stack: segment, 5, ptr/5, ptr/5 %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) - %sub_const(@SEGMENT_STORAGE_LINKED_LIST) - // By construction, the unscaled list len - // must be multiple of 5 - %div_const(5) + SUB + // stack: accessed_strg_keys_len, 5, ptr/5, ptr/5 + // By construction, the unscaled list len must be multiple of 5 + DIV // stack: accessed_strg_keys_len/5, ptr/5, ptr/5 %assert_gt %mul_const(5) From c9ad38edb0839968606bcc83b90e8aefa7c7348e Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Fri, 5 Jul 2024 12:57:18 +0200 Subject: [PATCH 080/118] [WIP] Debugging erc20 --- .../src/cpu/kernel/asm/main.asm | 2 + .../src/cpu/kernel/asm/mpt/accounts.asm | 5 + .../src/cpu/kernel/asm/mpt/hash/hash.asm | 3 + .../asm/mpt/linked_list/final_tries.asm | 1 + .../asm/mpt/linked_list/initial_tries.asm | 2 + .../asm/mpt/linked_list/linked_list.asm | 2 + .../src/cpu/kernel/tests/account_code.rs | 112 +++++++++++++++--- .../src/cpu/kernel/tests/mpt/linked_list.rs | 67 +++++------ evm_arithmetization/src/generation/mpt.rs | 1 + .../src/generation/prover_input.rs | 2 + evm_arithmetization/tests/erc20.rs | 19 +++ 11 files changed, 162 insertions(+), 54 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index a4a41e198..31391be80 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -116,6 +116,7 @@ global perform_final_checks: SWAP1 %set_trie_data_size %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) +global debug_st_1: %assert_eq PUSH 1 // initial trie data length @@ -123,6 +124,7 @@ global perform_final_checks: global check_state_trie: %set_final_tries %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) +global debug_st_2: %assert_eq global check_txn_trie: %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm index bb699716d..61f638910 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm @@ -49,7 +49,12 @@ %macro clone_slot // stack: slot_ptr + DUP1 + %jumpi(%%non_zero_ptr) + %jump(%%avoid_clonning_zero_ptr) +%%non_zero_ptr: %get_trie_data_size +%%avoid_clonning_zero_ptr: // stack: cloned_slot_ptr SWAP1 %mload_trie_data diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm index e2c460d1a..be573e55c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -57,6 +57,7 @@ global encode_or_hash_node: DUP1 PUSH @MPT_NODE_HASH SUB +global debug_o: %jumpi(encode_or_hash_concrete_node) // If we got here, node_type == @MPT_NODE_HASH. @@ -74,6 +75,8 @@ global encode_or_hash_node: SWAP2 %add_const(2) %stack (cur_len, encode_value, hash, retdest) -> (retdest, hash, 32, cur_len) JUMP + +global debug_encode_or_hash_concrete_node: encode_or_hash_concrete_node: %stack (node_type, node_ptr, encode_value, cur_len) -> (node_type, node_ptr, encode_value, cur_len, maybe_hash_node) %jump(encode_node) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 2d4d32f3d..719d072be 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -95,6 +95,7 @@ global delete_removed_accounts: // The inital accounts linked was store at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. // If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it // suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN` +global debug_eq: EQ %jumpi(delete_removed_accounts_end) // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index cd64f166e..a01917ece 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -19,6 +19,7 @@ global mpt_set_payload: DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) skip: +global debug_skip: // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest %stack (node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) JUMP @@ -130,6 +131,7 @@ set_payload_storage_extension: // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %jump(mpt_set_storage_payload) +global debug_set_payload_leaf: set_payload_leaf: // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest POP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 5c3bbf656..6eb0a078d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -79,6 +79,7 @@ global store_initial_accounts: loop_store_initial_accounts: // stack: current_node_ptr %get_trie_data_size +global debug_new_ptr: DUP2 MLOAD_GENERAL // stack: current_addr, cpy_ptr, current_node_ptr, retdest @@ -762,6 +763,7 @@ next_node_ok: %increment DUP1 DUP6 + %clone_slot MSTORE_GENERAL // stack: new_ptr + 3, next_ptr, addr, key, payload_ptr, retdest %increment diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index 553574d79..119ad3c99 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -17,7 +17,7 @@ use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; use crate::cpu::kernel::tests::mpt::nibbles_64; use crate::generation::mpt::{ - load_all_mpts, load_linked_lists_and_txn_and_receipt_mpts, AccountRlp, + load_all_mpts, load_linked_lists_and_txn_and_receipt_mpts, load_state_mpt, AccountRlp, }; use crate::generation::TrieInputs; use crate::memory::segments::Segment; @@ -30,7 +30,14 @@ pub(crate) fn initialize_mpts( trie_inputs: &TrieInputs, ) { // Load all MPTs. - let (trie_root_ptrs, state_leaves, storage_leaves, trie_data) = + log::debug!("trie input = {:?}", trie_inputs); + log::debug!( + "trie_data len = {:?}", + interpreter.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()] + .content + .len() + ); + let (mut trie_root_ptrs, state_leaves, storage_leaves, trie_data) = load_linked_lists_and_txn_and_receipt_mpts(&trie_inputs) .expect("Invalid MPT data for preinitialization"); @@ -44,11 +51,38 @@ pub(crate) fn initialize_mpts( trie_data.clone(); interpreter.generation_state.trie_root_ptrs = trie_root_ptrs.clone(); + log::debug!( + "real init acc ll = {:?}", + interpreter.generation_state.get_accounts_linked_list() + ); + log::debug!( + "real init sto ll = {:?}", + interpreter.generation_state.get_storage_linked_list() + ); + if trie_root_ptrs.state_root_ptr.is_none() { + trie_root_ptrs.state_root_ptr = Some( + load_state_mpt( + &trie_inputs, + &mut interpreter.generation_state.memory.contexts[0].segments + [Segment::TrieData.unscale()] + .content, + ) + .expect("Invalid MPT data for preinitialization"), + ); + log::debug!("state root ptr = {:?}", trie_root_ptrs.state_root_ptr); + } + let accounts_len = Segment::AccountsLinkedList as usize + interpreter.generation_state.memory.contexts[0].segments [Segment::AccountsLinkedList.unscale()] .content .len(); + log::debug!("accounts len = {accounts_len}"); + let storage_len = Segment::StorageLinkedList as usize + + interpreter.generation_state.memory.contexts[0].segments + [Segment::StorageLinkedList.unscale()] + .content + .len(); let accounts_len_addr = MemoryAddress { context: 0, segment: Segment::GlobalMetadata.unscale(), @@ -59,16 +93,37 @@ pub(crate) fn initialize_mpts( segment: Segment::GlobalMetadata.unscale(), virt: GlobalMetadata::StorageLinkedListLen.unscale(), }; - let storage_len = Segment::StorageLinkedList as usize - + interpreter.generation_state.memory.contexts[0].segments - [Segment::StorageLinkedList.unscale()] - .content - .len(); + let initial_accounts_len_addr = MemoryAddress { + context: 0, + segment: Segment::GlobalMetadata.unscale(), + virt: GlobalMetadata::InitialAccountsLinkedListLen.unscale(), + }; + let initial_storage_len_addr = MemoryAddress { + context: 0, + segment: Segment::GlobalMetadata.unscale(), + virt: GlobalMetadata::InitialStorageLinkedListLen.unscale(), + }; + let trie_data_len_addr = MemoryAddress { + context: 0, + segment: Segment::GlobalMetadata.unscale(), + virt: GlobalMetadata::TrieDataSize.unscale(), + }; + let trie_data_len = interpreter.generation_state.memory.contexts[0].segments + [Segment::TrieData.unscale()] + .content + .len(); interpreter.set_memory_multi_addresses(&[ (accounts_len_addr, accounts_len.into()), (storage_len_addr, storage_len.into()), + (trie_data_len_addr, trie_data_len.into()), + (initial_accounts_len_addr, accounts_len.into()), + (initial_storage_len_addr, storage_len.into()), ]); + log::debug!("the constant = {:?}", interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)); + + log::debug!("trie data len = {trie_data_len}"); + let state_addr = MemoryAddress::new_bundle((GlobalMetadata::StateTrieRoot as usize).into()).unwrap(); let txn_addr = @@ -80,12 +135,12 @@ pub(crate) fn initialize_mpts( let mut to_set = vec![]; if let Some(state_root_ptr) = trie_root_ptrs.state_root_ptr { - to_set.push( (state_addr, state_root_ptr.into())); + log::debug!("setiando el trai a {:?}", state_root_ptr); + to_set.push((state_addr, state_root_ptr.into())); } to_set.extend([ (txn_addr, trie_root_ptrs.txn_root_ptr.into()), (receipts_addr, trie_root_ptrs.receipt_root_ptr.into()), - (len_addr, trie_data.len().into()), ]); interpreter.set_memory_multi_addresses(&to_set); @@ -354,19 +409,42 @@ fn prepare_interpreter_all_accounts( initialize_mpts(interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); - // Set initial tries. + // Copy the initial account and storage pointers interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["store_initial_accounts"]; + interpreter.run()?; interpreter - .push((Segment::StorageLinkedList as usize + 7).into()) + .push(0xDEADBEEFu32.into()) + .expect("The stack should not overflow"); + interpreter.generation_state.registers.program_counter = + KERNEL.global_labels["store_initial_slots"]; + interpreter.run()?; + + log::debug!( + "real init acc ll = {:?}", + interpreter.generation_state.get_accounts_linked_list() + ); + log::debug!( + "real init sto ll = {:?}", + interpreter.generation_state.get_storage_linked_list() + ); + + // Set the pointers to the intial payloads. + interpreter + .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push((Segment::AccountsLinkedList as usize + 5).into()) + .push((Segment::StorageLinkedList as usize + 8).into()) + .expect("The stack should not overflow"); + interpreter + .push((Segment::AccountsLinkedList as usize + 6).into()) .expect("The stack should not overflow"); interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); - // Now, set the payload. + // Now, set the payloads in the state trie leaves. interpreter.generation_state.registers.program_counter = KERNEL.global_labels["mpt_set_payload"]; @@ -375,12 +453,13 @@ fn prepare_interpreter_all_accounts( assert_eq!( interpreter.stack().len(), 2, - "Expected 2 items on stack after hashing, found {:?}", + "Expected 2 items on stack after setting the inital trie payloads, found {:?}", interpreter.stack() ); - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + log::debug!(": = {acc_ptr}"); + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); @@ -504,6 +583,7 @@ fn sstore() -> Result<()> { #[test] fn sload() -> Result<()> { init_logger(); // We take the same `to` account as in add11_yml. + let addr = hex!("095e7baea6a6c7c4c2dfeb977efac326af552d87"); let addr_hashed = keccak(addr); diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 322c1553e..a701e32ea 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -93,39 +93,39 @@ fn test_list_iterator() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be an accounts list"); - let Some([addr, ptr, ctr, scaled_pos_1]) = accounts_list.next() else { + let Some([addr, ptr, ptr_cpy, scaled_pos_1]) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); - let Some([addr, ptr, ctr, scaled_pos_1]) = accounts_list.next() else { + let Some([addr, ptr, ptr_cpy, scaled_pos_1]) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); let mut storage_list = interpreter .generation_state .get_storage_linked_list() .expect("Since we called init_access_lists there must be a storage list"); - let Some([addr, key, ptr, ctr, scaled_pos_1]) = storage_list.next() else { + let Some([addr, key, ptr, ptr_cpy, scaled_pos_1]) = storage_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(key, U256::zero()); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); assert_eq!(scaled_pos_1, (Segment::StorageLinkedList as usize).into()); - let Some([addr, key, ptr, ctr, scaled_pos_1]) = storage_list.next() else { + let Some([addr, key, ptr, ptr_cpy, scaled_pos_1]) = storage_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); assert_eq!(scaled_pos_1, (Segment::StorageLinkedList as usize).into()); Ok(()) @@ -163,22 +163,22 @@ fn test_insert_account() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some([addr, ptr, ctr, scaled_next_pos]) = list.next() else { + let Some([addr, ptr, ptr_cpy, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::from(address.0.as_slice())); assert_eq!(ptr, payload_ptr); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); // ptr_cpy is zero because the trie_data segment is empty assert_eq!( scaled_next_pos, (Segment::AccountsLinkedList as usize).into() ); - let Some([addr, ptr, ctr, scaled_new_pos]) = list.next() else { + let Some([addr, ptr, ptr_cpy, scaled_new_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); assert_eq!( scaled_new_pos, (Segment::AccountsLinkedList as usize + 4).into() @@ -220,24 +220,24 @@ fn test_insert_storage() -> Result<()> { .get_storage_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some([inserted_addr, inserted_key, ptr, ctr, scaled_next_pos]) = list.next() else { + let Some([inserted_addr, inserted_key, ptr, ptr_cpy, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(inserted_addr, U256::from(address.0.as_slice())); assert_eq!(inserted_key, U256::from(key.0.as_slice())); assert_eq!(ptr, payload_ptr); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); // ptr_cpy is zero because the trie data segment is empty assert_eq!( scaled_next_pos, (Segment::StorageLinkedList as usize).into() ); - let Some([inserted_addr, inserted_key, ptr, ctr, scaled_new_pos]) = list.next() else { + let Some([inserted_addr, inserted_key, ptr, ptr_cpy, scaled_new_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(inserted_addr, U256::MAX); assert_eq!(inserted_key, U256::zero()); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); assert_eq!( scaled_new_pos, (Segment::StorageLinkedList as usize + 5).into() @@ -292,12 +292,15 @@ fn test_insert_and_delete_accounts() -> Result<()> { interpreter.pop().expect("The stack can't be empty"), addr + delta_ptr ); - // The counter must be 0 + // The copied ptr is at distance 4, the size of an account, from the previous copied ptr. + log::debug!("ptr_cpy = {:?}", interpreter.generation_state.memory.get_with_init( + MemoryAddress::new_bundle(U256::from(offset + 4 * (i + 1) + 2)).unwrap(), + )); assert_eq!( interpreter.generation_state.memory.get_with_init( MemoryAddress::new_bundle(U256::from(offset + 4 * (i + 1) + 2)).unwrap(), ), - U256::zero() + (4*i).into() ); } @@ -321,19 +324,12 @@ fn test_insert_and_delete_accounts() -> Result<()> { interpreter.run()?; assert_eq!( interpreter.pop().expect("The stack can't be empty"), - U256::one() + U256::zero() ); assert_eq!( interpreter.pop().expect("The stack can't be empty"), addr_in_list + delta_ptr ); - // The counter must be one now - assert_eq!( - interpreter.generation_state.memory.get_with_init( - MemoryAddress::new_bundle(U256::from(offset + 4 * (i + 1) + 2)).unwrap(), - ), - U256::one() - ); } // Test for address not in the list. @@ -393,18 +389,16 @@ fn test_insert_and_delete_accounts() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - for (i, [addr, ptr, ctr, _]) in list.enumerate() { + for (i, [addr, ptr, ptr_cpy, _]) in list.enumerate() { if addr == U256::MAX { assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); break; } let addr_in_list = U256::from(new_addresses[i].0.as_slice()); assert_eq!(addr, addr_in_list); assert_eq!(ptr, addr + delta_ptr); - // ctr is 0 for the lowest address because is never accessed - assert_eq!(ctr, if i == 0 { U256::zero() } else { U256::one() }); } Ok(()) @@ -469,7 +463,7 @@ fn test_insert_and_delete_storage() -> Result<()> { interpreter.generation_state.memory.get_with_init( MemoryAddress::new_bundle(U256::from(offset + 5 * (i + 1) + 3)).unwrap(), ), - U256::zero() + i.into() ); } @@ -495,18 +489,17 @@ fn test_insert_and_delete_storage() -> Result<()> { interpreter.run()?; assert_eq!( interpreter.pop().expect("The stack can't be empty"), - U256::one() + U256::zero() ); assert_eq!( interpreter.pop().expect("The stack can't be empty"), addr_in_list + delta_ptr ); - // The counter must be one now assert_eq!( interpreter.generation_state.memory.get_with_init( MemoryAddress::new_bundle(U256::from(offset + 5 * (i + 1) + 3)).unwrap(), ), - U256::one() + i.into() ); } @@ -570,21 +563,19 @@ fn test_insert_and_delete_storage() -> Result<()> { .get_storage_linked_list() .expect("Since we called init_access_lists there must be a list"); - for (i, [addr, key, ptr, ctr, _]) in list.enumerate() { + for (i, [addr, key, ptr, ptr_cpy, _]) in list.enumerate() { if addr == U256::MAX { // assert_eq!(addr, U256::MAX); assert_eq!(key, U256::zero()); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + assert_eq!(ptr_cpy, U256::zero()); break; } let [addr_in_list, key_in_list] = new_addresses[i].map(|x| U256::from(x.0.as_slice())); assert_eq!(addr, addr_in_list); assert_eq!(key, key_in_list); assert_eq!(ptr, addr + delta_ptr); - // ctr is 0 for the lowest address because is never accessed - assert_eq!(ctr, if i == 0 { U256::zero() } else { U256::one() }); } Ok(()) diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index 2ad97e28e..fb518c766 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -360,6 +360,7 @@ fn get_state_and_storage_leaves( Ok(()) } Node::Leaf { nibbles, value } => { + log::debug!("Pura hoja"); let account: AccountRlp = rlp::decode(value).map_err(|_| ProgramError::InvalidRlp)?; let AccountRlp { nonce, diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 5bb8fae6b..560b9ff86 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -290,6 +290,8 @@ impl GenerationState { /// Generates either the next used jump address or the proof for the last /// jump address. fn run_linked_list(&mut self, input_fn: &ProverInputFn) -> Result { + log::debug!("account ll = {:?}", self.get_accounts_linked_list()); + log::debug!("storage ll = {:?}", self.get_storage_linked_list()); match input_fn.0[1].as_str() { "insert_account" => self.run_next_insert_account(), "remove_account" => self.run_next_remove_account(), diff --git a/evm_arithmetization/tests/erc20.rs b/evm_arithmetization/tests/erc20.rs index 609579af9..563fdae46 100644 --- a/evm_arithmetization/tests/erc20.rs +++ b/evm_arithmetization/tests/erc20.rs @@ -57,6 +57,8 @@ fn test_erc20() -> anyhow::Result<()> { let giver_state_key = keccak(giver); let token_state_key = keccak(token); + log::debug!("the keys {:?} - {:?} - {:?}", sender_state_key, giver_state_key, token_state_key); + let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap(); let giver_nibbles = Nibbles::from_bytes_be(giver_state_key.as_bytes()).unwrap(); let token_nibbles = Nibbles::from_bytes_be(token_state_key.as_bytes()).unwrap(); @@ -118,6 +120,23 @@ fn test_erc20() -> anyhow::Result<()> { state_trie_after }; + log::debug!("sender account = {:?}", sender_account()); + + log::debug!("expected state trie = {:?}", expected_state_trie_after); + let account: AccountRlp = rlp::decode(&[ + 248, 78, 1, 138, 2, 30, 25, 224, 201, 186, 178, 55, 97, 2, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 197, 210, 70, 1, + 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, + 123, 250, 216, 4, 93, 133, 164, 112, + ])?; + log::debug!("account ok = {:?}", account); + let account: AccountRlp = rlp::decode(&[ + 248, 78, 1, 138, 2, 30, 25, 224, 201, 186, 178, 55, 97, 2, 160, 86, 232, 31, 23, 27, 204, + 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, + 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, + 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, + ])?; + log::debug!("account not ok = {:?}", account); let receipt_0 = LegacyReceiptRlp { status: true, cum_gas_used: gas_used, From e4adcb0c81042f5ea767d93f08fb2995bad99d02 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Fri, 5 Jul 2024 09:07:00 -0400 Subject: [PATCH 081/118] Remove counter update and cold_access --- .../cpu/kernel/asm/journal/storage_change.asm | 4 +- .../asm/mpt/linked_list/linked_list.asm | 135 +++++------------- 2 files changed, 41 insertions(+), 98 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm index b6ca4edcb..afe2ca130 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm @@ -12,8 +12,8 @@ global revert_storage_change: DUP3 ISZERO %jumpi(delete) // stack: address, slot, prev_value, retdest %insert_slot_with_value - // stack: cold_access, value_ptr - %pop2 + // stack: value_ptr + POP JUMP delete: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 503c53815..7d6bbc921 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -67,24 +67,24 @@ global init_linked_lists: %stack (addr, ptr) -> (addr, ptr, %%after) %jump(insert_account_to_linked_list) %%after: - // stack: cold_access + // stack: payload_ptr %endmacro %macro insert_account_with_overwrite %stack (addr, ptr) -> (addr, ptr, %%after) %jump(insert_account_with_overwrite) %%after: - // stack: cold_access + // stack: payload_ptr %endmacro %macro insert_account_to_linked_list_no_return %insert_account_to_linked_list - %pop2 + POP %endmacro %macro insert_account_with_overwrite_no_return %insert_account_with_overwrite - %pop2 + POP %endmacro // Multiply the value at the top of the stack, denoted by ptr/4, by 4 @@ -105,8 +105,7 @@ global init_linked_lists: %endmacro /// Inserts the account addr and payload pointer into the linked list if it is not already present. -/// Return `1, payload_ptr` if the account was inserted, `1, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +/// Return `payload_ptr` if the account was inserted, `original_ptr` if it was already present. global insert_account_to_linked_list: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) @@ -146,20 +145,9 @@ global account_found: DUP1 MLOAD_GENERAL // stack: orig_payload_ptr, pred_ptr + 1, addr, payload_ptr, retdest - SWAP1 - %increment - DUP1 - MLOAD_GENERAL - %increment - // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, payload_ptr, retdest - SWAP1 - DUP2 - // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest - MSTORE_GENERAL - // stack: access_ctr + 1, orig_payload_ptr, addr, payload_ptr, retdest - // If access_ctr == 1 then this it's a cold access - %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + + // TODO: we don't update `access_ctr` anymore as unused, consider removing / replacing + %stack (orig_payload_ptr, pred_ptr, addr, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP //DEBUG global insert_new_account: @@ -211,7 +199,7 @@ global insert_new_account: %increment %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) // stack: addr, payload_ptr, retdest - %stack (addr, payload_ptr, retdest) -> (retdest, 0, payload_ptr) + %stack (addr, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP global insert_account_with_overwrite: @@ -254,37 +242,28 @@ account_found_with_overwrite: DUP1 // stack: payload_ptr_ptr, pred_ptr+1, addr, payload_ptr, retdest DUP4 MSTORE_GENERAL - %increment - DUP1 - MLOAD_GENERAL - %increment - // stack: access_ctr + 1, access_ctr_ptr, addr, payload_ptr, retdest - SWAP1 - DUP2 - // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, addr, payload_ptr, retdest - MSTORE_GENERAL - // stack: access_ctr + 1, addr, payload_ptr, retdest - // If access_ctr == 1 then this it's a cold access - %eq_const(1) - %stack (cold_access, addr, payload_ptr, retdest) -> (retdest, cold_access, payload_ptr) + + // stack: pred_ptr+1, addr, payload_ptr, retdest + // TODO: we don't update `access_ctr` anymore as unused, consider removing / replacing + + %stack (pred_ptr, addr, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP %macro search_account %stack (addr, ptr) -> (addr, ptr, %%after) %jump(search_account) %%after: - // stack: cold_access + // stack: %endmacro %macro search_account_no_return %search_account - %pop2 + POP %endmacro /// Search the account addr andin the linked list. -/// Return `1, payload_ptr` if the account was not found, `1, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +/// Return `payload_ptr` if the account was not found, `original_ptr` if it was already present. global search_account: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) @@ -319,10 +298,7 @@ global search_account: account_not_found: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest - %pop3 - SWAP1 - PUSH 1 - SWAP1 + %stack (pred_addr, pred_ptr, addr, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP %macro remove_account_from_linked_list @@ -375,12 +351,12 @@ global remove_account: %stack (addr, key, ptr) -> (addr, key, ptr, %%after) %jump(insert_slot) %%after: - // stack: cold_access, value_ptr + // stack: value_ptr %endmacro %macro insert_slot_no_return %insert_slot - %pop2 + POP %endmacro // Multiply the value at the top of the stack, denoted by ptr/5, by 5 @@ -406,8 +382,7 @@ global remove_account: /// Inserts the pair (addres, storage_key) and a new payload pointer into the linked list if it is not already present, /// or modify its payload if it was already present. -/// Return `1, new_payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +/// Return `new_payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global insert_slot_with_value: // stack: addr, key, value, retdest PROVER_INPUT(linked_list::insert_slot) @@ -535,10 +510,7 @@ global debug_yo_no_me_llamo_javier_with_value: %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) // stack: addr, key, new_payload_ptr, retdest - %pop2 - PUSH 0 - SWAP1 - SWAP2 + %stack (addr, key, new_payload_ptr, retdest) -> (retdest, new_payload_ptr) JUMP slot_found_write_value: @@ -547,8 +519,7 @@ slot_found_write_value: %stack (payload_ptr, addr, key, value) -> (payload_ptr, value, payload_ptr) %mstore_trie_data // stack: payload_ptr, retdest - // the cold_access is no longer used here, so we can set any value. - %stack (payload_ptr, retdest) -> (retdest, 0, payload_ptr) + %stack (payload_ptr, retdest) -> (retdest, payload_ptr) JUMP %macro insert_slot_with_value @@ -557,7 +528,7 @@ slot_found_write_value: SWAP1 %addr_to_state_key %jump(insert_slot_with_value) %%after: - // stack: cold_access, value_ptr + // stack: value_ptr %endmacro /// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present, @@ -621,24 +592,15 @@ slot_found_write: // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest DUP2 DUP6 + // stack: payload_ptr, pred_ptr + 2, orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest global debug_store_new_payload: MSTORE_GENERAL // Store the new payload + // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest + + // TODO: we don't update `access_ctr` anymore as unused, consider removing / replacing - SWAP1 - %increment - DUP1 - MLOAD_GENERAL - %increment - // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, key, payload_ptr, retdest - SWAP1 - DUP2 - // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest -global debug_no_me_llamo_popotan: - MSTORE_GENERAL // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest - // If access_ctr == 1 then this it's a cold access - %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + %stack (orig_payload_ptr, pred_ptr, addr, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP insert_new_slot: // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest @@ -719,17 +681,11 @@ global debug_yo_no_me_llamo_javier: %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) // stack: addr, key, payload_ptr, retdest - %pop2 - PUSH 0 - SWAP1 - SWAP2 + %stack (addr, key, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP /// Search the pair (address, storage_key) in the storage the linked list. -/// Returns `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. -// TODO: Not sure if this is correct, bc if a value is not found we need to return 0 but keep track of it for -// having the right cold_access +/// Returns `payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global search_slot: // stack: addr, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) @@ -780,7 +736,7 @@ global debug_slot_not_found: slot_not_found: // stack: pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest %stack (pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest) - -> (retdest, 1, payload_ptr) + -> (retdest, payload_ptr) JUMP slot_found_no_write: @@ -791,20 +747,10 @@ slot_found_no_write: DUP1 MLOAD_GENERAL // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest - SWAP1 - %increment - DUP1 - MLOAD_GENERAL - %increment - // stack: access_ctr + 1, access_ctr_ptr, orig_payload_ptr, addr, key, payload_ptr, retdest - SWAP1 - DUP2 - // stack: access_ctr + 1, access_ctr_ptr, access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest - MSTORE_GENERAL - // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest - // If access_ctr == 1 then this it's a cold access - %eq_const(1) - %stack (cold_access, orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, cold_access, orig_payload_ptr) + + // TODO: we don't update `access_ctr` anymore as unused, consider removing / replacing + + %stack (orig_payload_ptr, pred_ptr, addr, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP @@ -912,8 +858,7 @@ remove_all_slots_end: %addr_to_state_key %jump(search_account) %%after: - // stack: cold_access, account_ptr - POP + // stack: account_ptr %endmacro %macro read_storage_linked_list @@ -924,8 +869,7 @@ remove_all_slots_end: %stack (addr, key) -> (addr, key, 0, %%after) %jump(search_slot) %%after: - // stack: cold_access, slot_ptr - POP + // stack: slot_ptr %endmacro %macro read_storage_linked_list_w_addr @@ -936,8 +880,7 @@ remove_all_slots_end: %stack (addr, key) -> (addr, key, 0, %%after) %jump(search_slot) %%after: - // stack: cold_access, slot_ptr - POP + // stack: slot_ptr %endmacro %macro first_account From bb4e2d29510e44535cf9fdf38a84234fdb310a63 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 5 Jul 2024 15:11:27 +0100 Subject: [PATCH 082/118] Fix log_opcode circuit sizes --- evm_arithmetization/tests/log_opcode.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm_arithmetization/tests/log_opcode.rs b/evm_arithmetization/tests/log_opcode.rs index 0008f462e..fd925af78 100644 --- a/evm_arithmetization/tests/log_opcode.rs +++ b/evm_arithmetization/tests/log_opcode.rs @@ -456,8 +456,8 @@ fn test_log_with_aggreg() -> anyhow::Result<()> { 8..9, 6..12, 17..20, - 16..17, - 7..17, + 16..18, + 7..18, ], &config, ); From 99d0b8a446474f75b9c4b5c2906ec78916a04c9a Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Fri, 5 Jul 2024 17:04:46 -0400 Subject: [PATCH 083/118] Fix stack comment and remove ctr update --- .../asm/mpt/linked_list/linked_list.asm | 40 +++++++------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 7d6bbc921..b70facf3d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -140,7 +140,7 @@ global insert_account_to_linked_list: global account_found: // The address was already in the list // stack: pred_ptr, addr, payload_ptr, retdest - // Load the the payload pointer and access counter + // Load the payload pointer %increment DUP1 MLOAD_GENERAL @@ -237,7 +237,7 @@ global insert_account_with_overwrite: account_found_with_overwrite: // The address was already in the list // stack: pred_ptr, addr, payload_ptr, retdest - // Load the the payload pointer and access counter + // Load the payload pointer %increment DUP1 // stack: payload_ptr_ptr, pred_ptr+1, addr, payload_ptr, retdest @@ -490,27 +490,23 @@ global debug_yo_no_me_llamo_javier_with_value: DUP1 %get_trie_data_size // stack: new_payload_ptr, new_ptr+2, new_ptr+2, next_ptr, addr, key, value, retdest - %stack (new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr, key, value) -> (value, new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr, key, new_payload_ptr) + %stack (new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr, key, value, retdest) + -> (value, new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, retdest, new_payload_ptr) %append_to_trie_data MSTORE_GENERAL - // stack: new_ptr + 2, next_ptr, addr, key, new_payload_ptr, retdest - // Store the counter - %increment - DUP1 - PUSH 0 - MSTORE_GENERAL - // stack: new_ptr + 3, next_ptr, addr, key, new_payload_ptr, retdest - %increment + // stack: new_ptr + 2, next_ptr, retdest, new_payload_ptr + // TODO: We skip counter update as it is unused. + %add_const(2) + // stack: new_next_ptr=new_ptr + 4, next_ptr, payload_ptr, retdest DUP1 - // stack: new_next_ptr, new_next_ptr, next_ptr, addr, key, new_payload_ptr, retdest + // stack: new_next_ptr, new_next_ptr, next_ptr, retdest, new_payload_ptr SWAP2 MSTORE_GENERAL - // stack: new_next_ptr, addr, key, new_payload_ptr, retdest + // stack: new_next_ptr, retdest, new_payload_ptr %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) - // stack: addr, key, new_payload_ptr, retdest - %stack (addr, key, new_payload_ptr, retdest) -> (retdest, new_payload_ptr) + // stack: retdest, new_payload_ptr JUMP slot_found_write_value: @@ -533,8 +529,7 @@ slot_found_write_value: /// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present, /// or modify its payload if it was already present. -/// Return `1, payload_ptr` if the storage key was inserted, `1, original_ptr` if it was already present -/// and this is the first access, or `0, original_ptr` if it was already present and accessed. +/// Return `payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global insert_slot: // stack: addr, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) @@ -599,7 +594,6 @@ global debug_store_new_payload: // TODO: we don't update `access_ctr` anymore as unused, consider removing / replacing - // stack: access_ctr + 1, orig_payload_ptr, addr, key, payload_ptr, retdest %stack (orig_payload_ptr, pred_ptr, addr, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP insert_new_slot: @@ -666,13 +660,9 @@ global debug_yo_no_me_llamo_javier: MSTORE_GENERAL // stack: new_ptr + 2, next_ptr, addr, key, payload_ptr, retdest - // Store the counter - %increment - DUP1 - PUSH 0 - MSTORE_GENERAL - // stack: new_ptr + 3, next_ptr, addr, key, payload_ptr, retdest - %increment + // TODO: We skip counter update as it is unused. + %add_const(2) + // stack: new_next_ptr=new_ptr + 4, next_ptr, addr, key, payload_ptr, retdest DUP1 // stack: new_next_ptr, new_next_ptr, next_ptr, addr, key, payload_ptr, retdest SWAP2 From e59e28229d0ebd4c9745cc1c38f7349e2ac18a29 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Mon, 8 Jul 2024 15:13:44 +0100 Subject: [PATCH 084/118] Fix preinitialization --- .../src/cpu/kernel/interpreter.rs | 20 ++++-- .../src/generation/linked_list.rs | 18 ++--- .../src/generation/prover_input.rs | 71 +++++++++++++------ evm_arithmetization/src/witness/memory.rs | 18 +++++ 4 files changed, 91 insertions(+), 36 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index e8019be56..98fad8f15 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -266,19 +266,29 @@ impl Interpreter { .expect("Invalid MPT data for preinitialization"); self.generation_state.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] - .content = state_leaves.iter().map(|&val| Some(val)).collect(); + .content = vec![]; self.generation_state.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] - .content = storage_leaves.iter().map(|&val| Some(val)).collect(); - self.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()].content = - trie_data.iter().map(|&val| Some(val)).collect(); + .content = vec![]; + let trie_roots_after = &inputs.trie_roots_after; self.generation_state.trie_root_ptrs = trie_root_ptrs; // Initialize the `TrieData` segment. let preinit_trie_data_segment = MemorySegmentState { - content: trie_data.iter().map(|&elt| Some(elt)).collect::>(), + content: trie_data.iter().map(|&elt| Some(elt)).collect(), + }; + let preinit_accounts_ll_segment = MemorySegmentState { + content: state_leaves.iter().map(|&val| Some(val)).collect(), + }; + let preinit_storage_ll_segment = MemorySegmentState { + content: storage_leaves.iter().map(|&val| Some(val)).collect(), }; self.insert_preinitialized_segment(Segment::TrieData, preinit_trie_data_segment); + self.insert_preinitialized_segment( + Segment::AccountsLinkedList, + preinit_accounts_ll_segment, + ); + self.insert_preinitialized_segment(Segment::StorageLinkedList, preinit_storage_ll_segment); // Update the RLP and withdrawal prover inputs. let rlp_prover_inputs = all_rlp_prover_inputs_reversed(&inputs.signed_txns); diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index 6e8cfb00b..b49a6965d 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -27,8 +27,8 @@ use crate::witness::memory::MemoryAddress; // `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - // 1]` holds the address of the next node, where i = node_size * j. #[derive(Clone)] -pub(crate) struct LinkedList<'a, const N: usize> { - mem: &'a [Option], +pub(crate) struct LinkedList { + mem: Vec>, mem_len: usize, offset: usize, pos: usize, @@ -46,16 +46,16 @@ pub(crate) fn empty_list_mem(segment: Segment) -> [U256; N] { }) } -impl<'a, const N: usize> LinkedList<'a, N> { +impl<'a, const N: usize> LinkedList { pub fn from_mem_and_segment( - mem: &'a [Option], + mem: &[Option], segment: Segment, ) -> Result { - Self::from_mem_len_and_segment(mem, mem.len(), segment) + Self::from_mem_len_and_segment(&mem, mem.len(), segment) } pub fn from_mem_len_and_segment( - mem: &'a [Option], + mem: &[Option], mem_len: usize, segment: Segment, ) -> Result { @@ -64,7 +64,7 @@ impl<'a, const N: usize> LinkedList<'a, N> { } let mem_len = mem.len(); Ok(Self { - mem, + mem: mem.to_vec(), mem_len, offset: segment as usize, pos: 0, @@ -72,7 +72,7 @@ impl<'a, const N: usize> LinkedList<'a, N> { } } -impl<'a, const N: usize> fmt::Debug for LinkedList<'a, N> { +impl<'a, const N: usize> fmt::Debug for LinkedList { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "Linked List {{"); let cloned_list = self.clone(); @@ -87,7 +87,7 @@ impl<'a, const N: usize> fmt::Debug for LinkedList<'a, N> { } } -impl<'a, const N: usize> Iterator for LinkedList<'a, N> { +impl<'a, const N: usize> Iterator for LinkedList { type Item = [U256; N]; fn next(&mut self) -> Option { diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index b420aaad8..c791c42ad 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -18,7 +18,7 @@ use crate::generation::prover_input::EvmField::{ Bls381Base, Bls381Scalar, Bn254Base, Bn254Scalar, Secp256k1Base, Secp256k1Scalar, }; use crate::generation::prover_input::FieldOp::{Inverse, Sqrt}; -use crate::generation::state::GenerationState; +use crate::generation::state::{GenerationState, State}; use crate::memory::segments::Segment; use crate::memory::segments::Segment::BnPairing; use crate::util::{biguint_to_mem_vec, mem_vec_to_biguint, u256_to_u8, u256_to_usize}; @@ -88,11 +88,20 @@ impl GenerationState { .map(U256::from), "txn" => Ok(U256::from(self.trie_root_ptrs.txn_root_ptr)), "receipt" => Ok(U256::from(self.trie_root_ptrs.receipt_root_ptr)), - "trie_data_size" => Ok(U256::from( - self.memory.contexts[0].segments[Segment::TrieData.unscale()] - .content - .len(), - )), + "trie_data_size" => Ok(self + .memory + .preinitialized_segments + .get(&Segment::TrieData) + .unwrap_or(&crate::witness::memory::MemorySegmentState { content: vec![] }) + .content + .len() + .max( + self.memory.contexts[0].segments[Segment::TrieData.unscale()] + .content + .len(), + ) + .into()), + _ => Err(ProgramError::ProverInputError(InvalidInput)), } } @@ -295,16 +304,38 @@ impl GenerationState { "insert_slot" => self.run_next_insert_slot(), "remove_slot" => self.run_next_remove_slot(), "remove_address_slots" => self.run_next_remove_address_slots(), - "accounts_linked_list_len" => Ok((Segment::AccountsLinkedList as usize - + self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] + "accounts_linked_list_len" => { + let len = self + .memory + .preinitialized_segments + .get(&Segment::AccountsLinkedList) + .unwrap_or(&crate::witness::memory::MemorySegmentState { content: vec![] }) .content - .len()) - .into()), - "storage_linked_list_len" => Ok((Segment::StorageLinkedList as usize - + self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] + .len() + .max( + self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] + .content + .len(), + ); + + Ok((Segment::AccountsLinkedList as usize + len).into()) + } + "storage_linked_list_len" => { + let len = self + .memory + .preinitialized_segments + .get(&Segment::StorageLinkedList) + .unwrap_or(&crate::witness::memory::MemorySegmentState { content: vec![] }) .content - .len()) - .into()), + .len() + .max( + self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] + .content + .len(), + ); + + Ok((Segment::StorageLinkedList as usize + len).into()) + } _ => Err(ProgramError::ProverInputError(InvalidInput)), } } @@ -651,10 +682,8 @@ impl GenerationState { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next // available virtual address in the segment. In order to get the length // we need to substract `Segment::AccountsLinkedList` as usize. - LinkedList::from_mem_and_segment( - &self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content, - Segment::AccountsLinkedList, - ) + let accounts_mem = self.memory.get_ll_memory(Segment::AccountsLinkedList); + LinkedList::from_mem_and_segment(&accounts_mem, Segment::AccountsLinkedList) } pub(crate) fn get_storage_linked_list( @@ -663,10 +692,8 @@ impl GenerationState { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next // available virtual address in the segment. In order to get the length // we need to substract `Segment::AccountsLinkedList` as usize. - LinkedList::from_mem_and_segment( - &self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()].content, - Segment::StorageLinkedList, - ) + let storage_mem = self.memory.get_ll_memory(Segment::StorageLinkedList); + LinkedList::from_mem_and_segment(&storage_mem, Segment::StorageLinkedList) } fn get_global_metadata(&self, data: GlobalMetadata) -> U256 { diff --git a/evm_arithmetization/src/witness/memory.rs b/evm_arithmetization/src/witness/memory.rs index ac5215698..5aaf4e23a 100644 --- a/evm_arithmetization/src/witness/memory.rs +++ b/evm_arithmetization/src/witness/memory.rs @@ -215,6 +215,24 @@ impl MemoryState { Some(val) } + pub(crate) fn get_ll_memory(&self, segment: Segment) -> Vec> { + assert!(segment == Segment::AccountsLinkedList || segment == Segment::StorageLinkedList); + + let len = self + .preinitialized_segments + .get(&segment) + .unwrap_or(&MemorySegmentState { content: vec![] }) + .content + .len() + .max(self.contexts[0].segments[segment.unscale()].content.len()); + + let vals = (0..len) + .map(|i| Some(self.get_with_init(MemoryAddress::new(0, segment, i)))) + .collect::>(); + + vals + } + /// Returns a memory value, or 0 if the memory is unset. If we have some /// preinitialized segments (in interpreter mode), then the values might not /// be stored in memory yet. If the value in memory is not set and the From ac6f85ec31db33d83a0cbae71ee0fc28b1e8c648 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Tue, 9 Jul 2024 18:48:19 +0200 Subject: [PATCH 085/118] Fix unit tests --- .../src/cpu/kernel/asm/main.asm | 2 ++ .../asm/mpt/linked_list/final_tries.asm | 5 +++++ .../asm/mpt/linked_list/initial_tries.asm | 20 ++++++++++++++++--- evm_arithmetization/src/generation/mpt.rs | 3 +-- .../src/generation/prover_input.rs | 9 ++++++--- evm_arithmetization/tests/erc20.rs | 15 +++++++++----- 6 files changed, 41 insertions(+), 13 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 31391be80..670150ffa 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -109,6 +109,8 @@ global perform_final_checks: %pop3 PROVER_INPUT(trie_ptr::state) + +global debug_state_trie_ptr: %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) %set_initial_tries %get_trie_data_size diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 719d072be..0c7c2bf92 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -12,18 +12,23 @@ global insert_all_accounts: DUP1 %eq_const(@U256_MAX) %jumpi(no_more_accounts) + // stack: key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest DUP4 %increment MLOAD_GENERAL +global debug_account_ptr: // stack: account_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %add_const(2) DUP1 %mload_trie_data +global debug_storage_root_ptr: // stack: storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %stack (storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr) -> (key, storage_ptr_ptr, storage_root_ptr, after_insert_all_slots, storage_root_ptr_ptr, key) %jump(insert_all_slots) + +global debug_after_insert_all_slots: after_insert_all_slots: // stack: storage_ptr_ptr', storage_root_ptr', storage_root_ptr_ptr, key, root_ptr, account_ptr_ptr, retdest SWAP2 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index a01917ece..d89b35cdf 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -52,6 +52,7 @@ global debug_skip: global mpt_set_storage_payload: // stack: node_ptr, storage_ptr_ptr, retdest DUP1 %mload_trie_data +global debug_storage_node_type: // stack: node_type, node_ptr, storage_ptr_ptr, retdest // Increment node_ptr, so it points to the node payload instead of its type. SWAP1 %increment SWAP1 @@ -142,6 +143,10 @@ set_payload_leaf: // stack account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %add_const(2) %mload_trie_data // storage_root_ptr = account[2] + + DUP1 %mload_trie_data +global debug_node_type: + POP // stack storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %stack (storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> @@ -150,13 +155,22 @@ set_payload_leaf: after_set_storage_payload: // stack: storage_ptr_ptr', storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, retdest DUP4 +global debueg_the_intial_ptr: MLOAD_GENERAL // load the next payload pointer in the linked list DUP1 %add_const(2) // new_storage_root_ptr_ptr = payload_ptr[2] // stack: new_storage_root_ptr_ptr, new_payload_ptr, storage_root_ptr, storage_ptr_ptr', payload_ptr_ptr, account_ptr_ptr, retdest + // Load also the old "dynamic" payload for storing the storage_root_ptr + DUP6 %decrement +global debug_the_dyn_ptr: + MLOAD_GENERAL + %add_const(2) // dyn_storage_root_ptr_ptr = dyn_paylod_ptr[2] %stack - (new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> - (new_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) - %mstore_trie_data // The account in the linked list has no storage root so we need to manually set it. + (dyn_storage_root_ptr_ptr, new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> + (new_storage_root_ptr_ptr, storage_root_ptr, dyn_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) +global debug_setting_intial_account_ptr: + %mstore_trie_data // The initial account pointer in the linked list has no storage root so we need to manually set it. +global debug_setting_dyn_account_storage: + %mstore_trie_data // The dynamic account pointer in the linked list has no storage root so we need to manually set it. %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. // stack: account_ptr_ptr, storage_ptr_ptr', retdest %add_const(4) // The next pointer is at distance 4 diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index fb518c766..fa7df92e6 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -139,13 +139,13 @@ where let type_of_trie = PartialTrieType::of(trie) as u32; if type_of_trie > 0 { trie_data.push(Some(type_of_trie.into())); + log::debug!("pushed hash node at {node_ptr} with val = {:?}", trie_data[node_ptr]); } match trie.deref() { Node::Empty => Ok(0), Node::Hash(h) => { trie_data.push(Some(h2u(*h))); - Ok(node_ptr) } Node::Branch { children, value } => { @@ -221,7 +221,6 @@ fn load_state_trie( Node::Empty => Ok(0), Node::Hash(h) => { trie_data.push(Some(h2u(*h))); - Ok(node_ptr) } Node::Branch { children, value } => { diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 560b9ff86..0d95b1457 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -80,17 +80,20 @@ impl GenerationState { "state" => match self.trie_root_ptrs.state_root_ptr { Some(state_root_ptr) => Ok(state_root_ptr), None => { - load_state_mpt( + let n = load_state_mpt( &self.inputs.tries, &mut self.memory.contexts[0].segments[Segment::TrieData.unscale()].content, - ) + )?; + log::debug!("guessed state trie = {:?}", get_state_trie::(&self.memory, n)); + Ok(n) } } .map(U256::from), "txn" => Ok(U256::from(self.trie_root_ptrs.txn_root_ptr)), "receipt" => Ok(U256::from(self.trie_root_ptrs.receipt_root_ptr)), "trie_data_size" => Ok(U256::from( - self.memory.contexts[0].segments[Segment::TrieData.unscale()] + self.memory + .contexts[0].segments[Segment::TrieData.unscale()] .content .len(), )), diff --git a/evm_arithmetization/tests/erc20.rs b/evm_arithmetization/tests/erc20.rs index 563fdae46..5d7099d66 100644 --- a/evm_arithmetization/tests/erc20.rs +++ b/evm_arithmetization/tests/erc20.rs @@ -57,7 +57,12 @@ fn test_erc20() -> anyhow::Result<()> { let giver_state_key = keccak(giver); let token_state_key = keccak(token); - log::debug!("the keys {:?} - {:?} - {:?}", sender_state_key, giver_state_key, token_state_key); + log::debug!( + "the keys {:?} - {:?} - {:?}", + sender_state_key, + giver_state_key, + token_state_key + ); let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap(); let giver_nibbles = Nibbles::from_bytes_be(giver_state_key.as_bytes()).unwrap(); @@ -131,10 +136,10 @@ fn test_erc20() -> anyhow::Result<()> { ])?; log::debug!("account ok = {:?}", account); let account: AccountRlp = rlp::decode(&[ - 248, 78, 1, 138, 2, 30, 25, 224, 201, 186, 178, 55, 97, 2, 160, 86, 232, 31, 23, 27, 204, - 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, - 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, - 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112, + 248, 78, 128, 138, 2, 30, 25, 224, 201, 186, 178, 64, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 197, 210, 70, 1, + 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, + 123, 250, 216, 4, 93, 133, 164, 112, ])?; log::debug!("account not ok = {:?}", account); let receipt_0 = LegacyReceiptRlp { From 74c55a6b8cc273946f489e834b47482421e2bb86 Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 10 Jul 2024 10:20:01 +0200 Subject: [PATCH 086/118] Debugging stShift/shr01_d0g0v0_Shanghai --- evm_arithmetization/tests/add11_yml.rs | 66 ++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index 00d7e56b4..c02141cfd 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -1,4 +1,6 @@ use std::collections::HashMap; +use std::fs; +use std::path::Path; use std::str::FromStr; use std::time::Duration; @@ -8,6 +10,7 @@ use evm_arithmetization::generation::mpt::{AccountRlp, LegacyReceiptRlp}; use evm_arithmetization::generation::{GenerationInputs, TrieInputs}; use evm_arithmetization::proof::{BlockHashes, BlockMetadata, TrieRoots}; use evm_arithmetization::prover::prove; +use evm_arithmetization::prover::testing::simulate_execution; use evm_arithmetization::verifier::verify_proof; use evm_arithmetization::{AllStark, Node, StarkConfig}; use hex_literal::hex; @@ -148,7 +151,7 @@ fn add11_yml() -> anyhow::Result<()> { transactions_root: transactions_trie.hash(), receipts_root: receipts_trie.hash(), }; - let inputs = GenerationInputs { + let _inputs = GenerationInputs { signed_txn: Some(txn.to_vec()), withdrawals: vec![], tries: tries_before, @@ -165,11 +168,64 @@ fn add11_yml() -> anyhow::Result<()> { }, }; - let mut timing = TimingTree::new("prove", log::Level::Debug); - let proof = prove::(&all_stark, &config, inputs, &mut timing, None)?; - timing.filter(Duration::from_millis(100)).print(); + let contract_rlp = vec![ + 248, 76, 128, 136, 13, 224, 182, 179, 167, 100, 0, 0, 160, 130, 30, 37, 86, 162, 144, 200, + 100, 5, 248, 22, 10, 45, 102, 32, 66, 164, 49, 186, 69, 107, 157, 178, 101, 199, 155, 184, + 55, 192, 75, 229, 240, 160, 57, 160, 134, 121, 22, 167, 121, 85, 39, 97, 89, 233, 92, 162, + 37, 154, 128, 251, 69, 156, 253, 188, 138, 94, 26, 190, 85, 63, 251, 76, 243, 98, + ]; + let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); + log::debug!("good = {:#?}", contracto); + let contract_rlp = vec![ + 248, 76, 128, 136, 13, 224, 182, 179, 167, 100, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, + 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, + 181, 227, 99, 180, 33, 160, 57, 160, 134, 121, 22, 167, 121, 85, 39, 97, 89, 233, 92, 162, + 37, 154, 128, 251, 69, 156, 253, 188, 138, 94, 26, 190, 85, 63, 251, 76, 243, 98, + ]; + let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); + log::debug!("bad = {:#?}", contracto); + + let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stShift/shr01_d0g0v0_Shanghai.json"); + visit_dirs(dir)?; + // let bytes = + // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ + // stTimeConsuming/static_Call50000_sha256_d0g0v0_Shanghai.json").unwrap(); + // let inputs = serde_json::from_slice(&bytes).unwrap(); + + // let mut timing = TimingTree::new("prove", log::Level::Debug); + // // let proof = prove::(&all_stark, &config, inputs, &mut + // timing, // None)?; + // simulate_execution::(inputs)?; + // timing.filter(Duration::from_millis(100)).print(); + + Ok(()) + // verify_proof(&all_stark, proof, &config) +} - verify_proof(&all_stark, proof, &config) +fn visit_dirs(dir: &Path) -> anyhow::Result<()> { + if dir == Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stTimeConsuming") + { + return Ok(()); + } + if dir.is_dir() { + log::info!("Found directory: {:?}", dir); + for entry in fs::read_dir(dir)? { + let entry = entry?; + let path = entry.path(); + visit_dirs(&path)?; // Recurse into the subdirectory + } + } else if dir.is_file() { + log::info!("Found file: {:?}", dir); + let bytes = std::fs::read(dir).unwrap(); + let inputs = serde_json::from_slice(&bytes).unwrap(); + + let mut timing = TimingTree::new("prove", log::Level::Debug); + // let proof = prove::(&all_stark, &config, inputs, &mut timing, + // None)?; + simulate_execution::(inputs)?; + timing.filter(Duration::from_millis(100)).print(); + } + Ok(()) } fn init_logger() { From 6aeb8d33ebb6abe6fd4d420c5b36bc4faa10981f Mon Sep 17 00:00:00 2001 From: Alonso Gonzalez Date: Wed, 10 Jul 2024 13:27:18 +0200 Subject: [PATCH 087/118] Fixing shiftSignedCombinations_d0g0v0_Shanghai --- .../src/cpu/kernel/asm/mpt/linked_list/final_tries.asm | 9 +++++++-- evm_arithmetization/src/cpu/kernel/interpreter.rs | 8 ++++---- evm_arithmetization/src/generation/prover_input.rs | 5 +++-- evm_arithmetization/tests/add11_yml.rs | 2 +- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 0c7c2bf92..d1bcd8707 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -117,10 +117,14 @@ global debug_eq: %add_const(2) MLOAD_GENERAL // get intitial payload_ptr %add_const(2) // storage_root_ptr_ptr = payload_ptr + 2 - DUP1 %mload_trie_data + // stack: storage_root_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest + DUP3 + %increment + MLOAD_GENERAL // get dynamic payload_ptr + %add_const(2) // storage_root_ptr_ptr = dyn_payload_ptr + 2 %stack - (storage_root_ptr, storage_root_ptr_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr) -> + (storage_root_ptr_ptr, storage_root_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr) -> (key, storage_root_ptr, storage_ptr_ptr, after_delete_removed_slots, storage_root_ptr_ptr, account_ptr_ptr, root_ptr) %jump(delete_removed_slots) after_delete_removed_slots: @@ -192,6 +196,7 @@ delete_this_slot: %stack (key, addr, root_ptr, storage_ptr_ptr) -> (root_ptr, 64, key, after_mpt_delete_slot, addr, storage_ptr_ptr) %jump(mpt_delete) after_mpt_delete_slot: +global debug_after_mpt_delete_slot: // stack: root_ptr', addr, storage_ptr_ptr SWAP2 %add_const(5) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index 166cdbc0b..59a4b3233 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -542,15 +542,15 @@ impl State for Interpreter { } fn log_debug(&self, msg: String) { - if !self.is_jumpdest_analysis { + // if !self.is_jumpdest_analysis { log::debug!("{}", msg); - } + // } } fn log(&self, level: Level, msg: String) { - if !self.is_jumpdest_analysis { + // if !self.is_jumpdest_analysis { log::log!(level, "{}", msg); - } + // } } } diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 0d95b1457..33789dbcb 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -5,6 +5,7 @@ use std::str::FromStr; use anyhow::{bail, Error}; use ethereum_types::{BigEndianHash, H256, U256, U512}; use itertools::Itertools; +use log::{Level, Log}; use mpt_trie::partial_trie::HashedPartialTrie; use num_bigint::BigUint; use plonky2::field::types::Field; @@ -293,8 +294,8 @@ impl GenerationState { /// Generates either the next used jump address or the proof for the last /// jump address. fn run_linked_list(&mut self, input_fn: &ProverInputFn) -> Result { - log::debug!("account ll = {:?}", self.get_accounts_linked_list()); - log::debug!("storage ll = {:?}", self.get_storage_linked_list()); + self.log(log::Level::Debug, format!("account ll = {:?}", self.get_accounts_linked_list())); + self.log(log::Level::Debug, format!("storage ll = {:?}", self.get_storage_linked_list())); match input_fn.0[1].as_str() { "insert_account" => self.run_next_insert_account(), "remove_account" => self.run_next_remove_account(), diff --git a/evm_arithmetization/tests/add11_yml.rs b/evm_arithmetization/tests/add11_yml.rs index c02141cfd..1cd1e908f 100644 --- a/evm_arithmetization/tests/add11_yml.rs +++ b/evm_arithmetization/tests/add11_yml.rs @@ -185,7 +185,7 @@ fn add11_yml() -> anyhow::Result<()> { let contracto: AccountRlp = rlp::decode(&contract_rlp).unwrap(); log::debug!("bad = {:#?}", contracto); - let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stShift/shr01_d0g0v0_Shanghai.json"); + let dir = Path::new("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/stShift/shiftSignedCombinations_d0g0v0_Shanghai.json"); visit_dirs(dir)?; // let bytes = // std::fs::read("/Users/agonzalez/evm-tests-suite-parsed/serialized_tests/ From 6a10adcaf28facc153a64b6605fa988a29c525ea Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 11 Jul 2024 11:15:23 +0100 Subject: [PATCH 088/118] Remove counter assertions from linked_lists tests --- .../src/cpu/kernel/tests/mpt/linked_list.rs | 95 ++++--------------- 1 file changed, 17 insertions(+), 78 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 322c1553e..58f0ecb9e 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -93,39 +93,35 @@ fn test_list_iterator() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be an accounts list"); - let Some([addr, ptr, ctr, scaled_pos_1]) = accounts_list.next() else { + let Some([addr, ptr, _ctr, scaled_pos_1]) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); - let Some([addr, ptr, ctr, scaled_pos_1]) = accounts_list.next() else { + let Some([addr, ptr, _ctr, scaled_pos_1]) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); let mut storage_list = interpreter .generation_state .get_storage_linked_list() .expect("Since we called init_access_lists there must be a storage list"); - let Some([addr, key, ptr, ctr, scaled_pos_1]) = storage_list.next() else { + let Some([addr, key, ptr, _ctr, scaled_pos_1]) = storage_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(key, U256::zero()); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); assert_eq!(scaled_pos_1, (Segment::StorageLinkedList as usize).into()); - let Some([addr, key, ptr, ctr, scaled_pos_1]) = storage_list.next() else { + let Some([addr, key, ptr, _ctr, scaled_pos_1]) = storage_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); assert_eq!(scaled_pos_1, (Segment::StorageLinkedList as usize).into()); Ok(()) @@ -156,29 +152,27 @@ fn test_insert_account() -> Result<()> { interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!(interpreter.stack(), &[payload_ptr, U256::zero()]); + assert_eq!(interpreter.stack(), &[payload_ptr]); let mut list = interpreter .generation_state .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some([addr, ptr, ctr, scaled_next_pos]) = list.next() else { + let Some([addr, ptr, _ctr, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::from(address.0.as_slice())); assert_eq!(ptr, payload_ptr); - assert_eq!(ctr, U256::zero()); assert_eq!( scaled_next_pos, (Segment::AccountsLinkedList as usize).into() ); - let Some([addr, ptr, ctr, scaled_new_pos]) = list.next() else { + let Some([addr, ptr, _ctr, scaled_new_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); assert_eq!( scaled_new_pos, (Segment::AccountsLinkedList as usize + 4).into() @@ -213,31 +207,29 @@ fn test_insert_storage() -> Result<()> { interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!(interpreter.stack(), &[payload_ptr, U256::zero()]); + assert_eq!(interpreter.stack(), &[payload_ptr]); let mut list = interpreter .generation_state .get_storage_linked_list() .expect("Since we called init_access_lists there must be a list"); - let Some([inserted_addr, inserted_key, ptr, ctr, scaled_next_pos]) = list.next() else { + let Some([inserted_addr, inserted_key, ptr, _ctr, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(inserted_addr, U256::from(address.0.as_slice())); assert_eq!(inserted_key, U256::from(key.0.as_slice())); assert_eq!(ptr, payload_ptr); - assert_eq!(ctr, U256::zero()); assert_eq!( scaled_next_pos, (Segment::StorageLinkedList as usize).into() ); - let Some([inserted_addr, inserted_key, ptr, ctr, scaled_new_pos]) = list.next() else { + let Some([inserted_addr, inserted_key, ptr, _ctr, scaled_new_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; assert_eq!(inserted_addr, U256::MAX); assert_eq!(inserted_key, U256::zero()); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); assert_eq!( scaled_new_pos, (Segment::StorageLinkedList as usize + 5).into() @@ -284,21 +276,10 @@ fn test_insert_and_delete_accounts() -> Result<()> { interpreter.push(addr); interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - U256::zero() - ); assert_eq!( interpreter.pop().expect("The stack can't be empty"), addr + delta_ptr ); - // The counter must be 0 - assert_eq!( - interpreter.generation_state.memory.get_with_init( - MemoryAddress::new_bundle(U256::from(offset + 4 * (i + 1) + 2)).unwrap(), - ), - U256::zero() - ); } // The next free address in Segment::AccounLinkedList must be offset + (n + @@ -319,21 +300,11 @@ fn test_insert_and_delete_accounts() -> Result<()> { interpreter.push(addr_in_list); interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - U256::one() - ); + assert_eq!( interpreter.pop().expect("The stack can't be empty"), addr_in_list + delta_ptr ); - // The counter must be one now - assert_eq!( - interpreter.generation_state.memory.get_with_init( - MemoryAddress::new_bundle(U256::from(offset + 4 * (i + 1) + 2)).unwrap(), - ), - U256::one() - ); } // Test for address not in the list. @@ -343,10 +314,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - U256::zero() - ); + assert_eq!( interpreter.pop().expect("The stack can't be empty"), U256::from(addr_not_in_list.0.as_slice()) + delta_ptr @@ -393,18 +361,15 @@ fn test_insert_and_delete_accounts() -> Result<()> { .get_accounts_linked_list() .expect("Since we called init_access_lists there must be a list"); - for (i, [addr, ptr, ctr, _]) in list.enumerate() { + for (i, [addr, ptr, _ctr, _]) in list.enumerate() { if addr == U256::MAX { assert_eq!(addr, U256::MAX); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); break; } let addr_in_list = U256::from(new_addresses[i].0.as_slice()); assert_eq!(addr, addr_in_list); assert_eq!(ptr, addr + delta_ptr); - // ctr is 0 for the lowest address because is never accessed - assert_eq!(ctr, if i == 0 { U256::zero() } else { U256::one() }); } Ok(()) @@ -456,21 +421,10 @@ fn test_insert_and_delete_storage() -> Result<()> { interpreter.push(addr); interpreter.generation_state.registers.program_counter = insert_slot_label; interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - U256::zero() - ); assert_eq!( interpreter.pop().expect("The stack can't be empty"), addr + delta_ptr ); - // The counter must be 0 - assert_eq!( - interpreter.generation_state.memory.get_with_init( - MemoryAddress::new_bundle(U256::from(offset + 5 * (i + 1) + 3)).unwrap(), - ), - U256::zero() - ); } // The next free node in Segment::StorageLinkedList must be at offset + (n + @@ -493,21 +447,11 @@ fn test_insert_and_delete_storage() -> Result<()> { interpreter.push(addr_in_list); interpreter.generation_state.registers.program_counter = insert_slot_label; interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - U256::one() - ); + assert_eq!( interpreter.pop().expect("The stack can't be empty"), addr_in_list + delta_ptr ); - // The counter must be one now - assert_eq!( - interpreter.generation_state.memory.get_with_init( - MemoryAddress::new_bundle(U256::from(offset + 5 * (i + 1) + 3)).unwrap(), - ), - U256::one() - ); } // Test for address not in the list. @@ -518,10 +462,7 @@ fn test_insert_and_delete_storage() -> Result<()> { interpreter.generation_state.registers.program_counter = insert_slot_label; interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - U256::zero() - ); + assert_eq!( interpreter.pop().expect("The stack can't be empty"), U256::from(addr_not_in_list.0.as_slice()) + delta_ptr @@ -570,21 +511,19 @@ fn test_insert_and_delete_storage() -> Result<()> { .get_storage_linked_list() .expect("Since we called init_access_lists there must be a list"); - for (i, [addr, key, ptr, ctr, _]) in list.enumerate() { + for (i, [addr, key, ptr, _ctr, _]) in list.enumerate() { if addr == U256::MAX { // assert_eq!(addr, U256::MAX); assert_eq!(key, U256::zero()); assert_eq!(ptr, U256::zero()); - assert_eq!(ctr, U256::zero()); + break; } let [addr_in_list, key_in_list] = new_addresses[i].map(|x| U256::from(x.0.as_slice())); assert_eq!(addr, addr_in_list); assert_eq!(key, key_in_list); assert_eq!(ptr, addr + delta_ptr); - // ctr is 0 for the lowest address because is never accessed - assert_eq!(ctr, if i == 0 { U256::zero() } else { U256::one() }); } Ok(()) From 5074895aa97cb226ffa74fe937b6dfdb44b6b4ed Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 11 Jul 2024 18:05:16 +0100 Subject: [PATCH 089/118] Fix preinitialization and start cleanup --- .../src/cpu/kernel/tests/account_code.rs | 32 ------------------- evm_arithmetization/src/generation/mpt.rs | 3 -- .../src/generation/prover_input.rs | 20 ++++++------ evm_arithmetization/src/generation/state.rs | 30 +++++++++-------- evm_arithmetization/src/witness/memory.rs | 14 +++++--- evm_arithmetization/tests/erc20.rs | 24 -------------- 6 files changed, 38 insertions(+), 85 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index 4523ac448..92709b11d 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -30,13 +30,6 @@ pub(crate) fn initialize_mpts( trie_inputs: &TrieInputs, ) { // Load all MPTs. - log::debug!("trie input = {:?}", trie_inputs); - log::debug!( - "trie_data len = {:?}", - interpreter.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()] - .content - .len() - ); let (mut trie_root_ptrs, state_leaves, storage_leaves, trie_data) = load_linked_lists_and_txn_and_receipt_mpts(&trie_inputs) .expect("Invalid MPT data for preinitialization"); @@ -51,14 +44,6 @@ pub(crate) fn initialize_mpts( trie_data.clone(); interpreter.generation_state.trie_root_ptrs = trie_root_ptrs.clone(); - log::debug!( - "real init acc ll = {:?}", - interpreter.generation_state.get_accounts_linked_list() - ); - log::debug!( - "real init sto ll = {:?}", - interpreter.generation_state.get_storage_linked_list() - ); if trie_root_ptrs.state_root_ptr.is_none() { trie_root_ptrs.state_root_ptr = Some( load_state_mpt( @@ -69,7 +54,6 @@ pub(crate) fn initialize_mpts( ) .expect("Invalid MPT data for preinitialization"), ); - log::debug!("state root ptr = {:?}", trie_root_ptrs.state_root_ptr); } let accounts_len = Segment::AccountsLinkedList as usize @@ -77,7 +61,6 @@ pub(crate) fn initialize_mpts( [Segment::AccountsLinkedList.unscale()] .content .len(); - log::debug!("accounts len = {accounts_len}"); let storage_len = Segment::StorageLinkedList as usize + interpreter.generation_state.memory.contexts[0].segments [Segment::StorageLinkedList.unscale()] @@ -120,10 +103,6 @@ pub(crate) fn initialize_mpts( (initial_storage_len_addr, storage_len.into()), ]); - log::debug!("the constant = {:?}", interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)); - - log::debug!("trie data len = {trie_data_len}"); - let state_addr = MemoryAddress::new_bundle((GlobalMetadata::StateTrieRoot as usize).into()).unwrap(); let txn_addr = @@ -135,7 +114,6 @@ pub(crate) fn initialize_mpts( let mut to_set = vec![]; if let Some(state_root_ptr) = trie_root_ptrs.state_root_ptr { - log::debug!("setiando el trai a {:?}", state_root_ptr); to_set.push((state_addr, state_root_ptr.into())); } to_set.extend([ @@ -426,15 +404,6 @@ fn prepare_interpreter_all_accounts( KERNEL.global_labels["store_initial_slots"]; interpreter.run()?; - log::debug!( - "real init acc ll = {:?}", - interpreter.generation_state.get_accounts_linked_list() - ); - log::debug!( - "real init sto ll = {:?}", - interpreter.generation_state.get_storage_linked_list() - ); - // Set the pointers to the intial payloads. interpreter .push(0xDEADBEEFu32.into()) @@ -461,7 +430,6 @@ fn prepare_interpreter_all_accounts( ); let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; - log::debug!(": = {acc_ptr}"); let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index a514b079d..7578ad462 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -530,9 +530,6 @@ pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( &storage_tries_by_state_key, ); - // TODO: Remove after checking correctness of linked lists - // let state_root_ptr = load_state_mpt(trie_inputs, &mut trie_data)?; - Ok(( TrieRootPtrs { state_root_ptr: None, diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 10d8e9bb5..250682691 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -89,13 +89,15 @@ impl GenerationState { "state" => match self.trie_root_ptrs.state_root_ptr { Some(state_root_ptr) => Ok(state_root_ptr), None => { - let n = load_state_mpt( - &self.inputs.tries, - &mut self.memory.contexts[0].segments[Segment::TrieData.unscale()].content, - )?; - log::debug!( - "guessed state trie = {:?}", - get_state_trie::(&self.memory, n) + let mut new_content = self.memory.get_preinit_memory(Segment::TrieData); + + let n = load_state_mpt(&self.inputs.trimmed_tries, &mut new_content)?; + + self.memory.insert_preinitialized_segment( + Segment::TrieData, + crate::witness::memory::MemorySegmentState { + content: new_content, + }, ); Ok(n) } @@ -704,7 +706,7 @@ impl GenerationState { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next // available virtual address in the segment. In order to get the length // we need to substract `Segment::AccountsLinkedList` as usize. - let accounts_mem = self.memory.get_ll_memory(Segment::AccountsLinkedList); + let accounts_mem = self.memory.get_preinit_memory(Segment::AccountsLinkedList); LinkedList::from_mem_and_segment(&accounts_mem, Segment::AccountsLinkedList) } @@ -714,7 +716,7 @@ impl GenerationState { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next // available virtual address in the segment. In order to get the length // we need to substract `Segment::AccountsLinkedList` as usize. - let storage_mem = self.memory.get_ll_memory(Segment::StorageLinkedList); + let storage_mem = self.memory.get_preinit_memory(Segment::StorageLinkedList); LinkedList::from_mem_and_segment(&storage_mem, Segment::StorageLinkedList) } diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index aa7f72b8c..fee9e6c74 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -382,11 +382,22 @@ impl GenerationState { load_linked_lists_and_txn_and_receipt_mpts(trie_inputs) .expect("Invalid MPT data for preinitialization"); - self.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()].content = - state_leaves.iter().map(|&val| Some(val)).collect(); - self.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()].content = - storage_leaves.iter().map(|&val| Some(val)).collect(); - self.memory.contexts[0].segments[Segment::TrieData.unscale()].content = trie_data; + self.memory.insert_preinitialized_segment( + Segment::AccountsLinkedList, + crate::witness::memory::MemorySegmentState { + content: state_leaves.iter().map(|&val| Some(val)).collect(), + }, + ); + self.memory.insert_preinitialized_segment( + Segment::StorageLinkedList, + crate::witness::memory::MemorySegmentState { + content: storage_leaves.iter().map(|&val| Some(val)).collect(), + }, + ); + self.memory.insert_preinitialized_segment( + Segment::TrieData, + crate::witness::memory::MemorySegmentState { content: trie_data }, + ); trie_roots_ptrs } @@ -416,14 +427,7 @@ impl GenerationState { }; let trie_root_ptrs = state.preinitialize_linked_lists_and_txn_and_receipt_mpts(&inputs.tries); - log::debug!( - "Initial accounts linked list = {:?}", - state.get_accounts_linked_list() - ); - log::debug!( - "Initial storage linked list = {:?}", - state.get_storage_linked_list() - ); + state.trie_root_ptrs = trie_root_ptrs; Ok(state) } diff --git a/evm_arithmetization/src/witness/memory.rs b/evm_arithmetization/src/witness/memory.rs index 5aaf4e23a..da80c5a08 100644 --- a/evm_arithmetization/src/witness/memory.rs +++ b/evm_arithmetization/src/witness/memory.rs @@ -215,9 +215,15 @@ impl MemoryState { Some(val) } - pub(crate) fn get_ll_memory(&self, segment: Segment) -> Vec> { - assert!(segment == Segment::AccountsLinkedList || segment == Segment::StorageLinkedList); - + /// Returns the memory values associated with a preinitialized segment. We + /// need a specific behaviour here, since the values can be stored either in + /// `preinitialized_segments` or in the memory itself. + pub(crate) fn get_preinit_memory(&self, segment: Segment) -> Vec> { + assert!( + segment == Segment::AccountsLinkedList + || segment == Segment::StorageLinkedList + || segment == Segment::TrieData + ); let len = self .preinitialized_segments .get(&segment) @@ -254,7 +260,7 @@ impl MemoryState { .len() { self.preinitialized_segments.get(&segment).unwrap().content[offset] - .expect("We checked that the offset is not out of bounds.") + .unwrap_or_default() } else { 0.into() } diff --git a/evm_arithmetization/tests/erc20.rs b/evm_arithmetization/tests/erc20.rs index 6ed47de0e..6748729d0 100644 --- a/evm_arithmetization/tests/erc20.rs +++ b/evm_arithmetization/tests/erc20.rs @@ -57,13 +57,6 @@ fn test_erc20() -> anyhow::Result<()> { let giver_state_key = keccak(giver); let token_state_key = keccak(token); - log::debug!( - "the keys {:?} - {:?} - {:?}", - sender_state_key, - giver_state_key, - token_state_key - ); - let sender_nibbles = Nibbles::from_bytes_be(sender_state_key.as_bytes()).unwrap(); let giver_nibbles = Nibbles::from_bytes_be(giver_state_key.as_bytes()).unwrap(); let token_nibbles = Nibbles::from_bytes_be(token_state_key.as_bytes()).unwrap(); @@ -125,23 +118,6 @@ fn test_erc20() -> anyhow::Result<()> { state_trie_after }; - log::debug!("sender account = {:?}", sender_account()); - - log::debug!("expected state trie = {:?}", expected_state_trie_after); - let account: AccountRlp = rlp::decode(&[ - 248, 78, 1, 138, 2, 30, 25, 224, 201, 186, 178, 55, 97, 2, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 197, 210, 70, 1, - 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, - 123, 250, 216, 4, 93, 133, 164, 112, - ])?; - log::debug!("account ok = {:?}", account); - let account: AccountRlp = rlp::decode(&[ - 248, 78, 128, 138, 2, 30, 25, 224, 201, 186, 178, 64, 0, 0, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 197, 210, 70, 1, - 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, - 123, 250, 216, 4, 93, 133, 164, 112, - ])?; - log::debug!("account not ok = {:?}", account); let receipt_0 = LegacyReceiptRlp { status: true, cum_gas_used: gas_used, From 6e043f929f76ee95acbb72d0e46d57518ab2f69d Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 11 Jul 2024 23:00:22 +0100 Subject: [PATCH 090/118] Fix test_process_receipt --- evm_arithmetization/src/cpu/kernel/tests/receipt.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/receipt.rs b/evm_arithmetization/src/cpu/kernel/tests/receipt.rs index ee22fc1f2..87e0f98cc 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/receipt.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/receipt.rs @@ -59,6 +59,8 @@ fn test_process_receipt() -> Result<()> { 0.into(), // data_len ], ); + interpreter.set_memory_segment(Segment::TrieData, vec![0.into()]); + interpreter.set_global_metadata_field(GlobalMetadata::TrieDataSize, 1.into()); interpreter.set_txn_field(NormalizedTxnField::GasLimit, U256::from(5000)); interpreter.set_memory_segment(Segment::TxnBloom, vec![0.into(); 256]); interpreter.set_memory_segment(Segment::Logs, vec![0.into()]); @@ -71,7 +73,7 @@ fn test_process_receipt() -> Result<()> { // The expected TrieData has the form [payload_len, status, cum_gas_used, // bloom_filter, logs_payload_len, num_logs, [logs]] - let mut expected_trie_data: Vec = vec![323.into(), success, 2000.into()]; + let mut expected_trie_data: Vec = vec![0.into(), 323.into(), success, 2000.into()]; expected_trie_data.extend( expected_bloom .into_iter() From 439b4a0b5d1c8417f968bfcf4f8c764682613afb Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Thu, 11 Jul 2024 19:18:50 -0400 Subject: [PATCH 091/118] Fix MPT insert tests --- .../src/cpu/kernel/tests/mpt/insert.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs index 4cf03cfdc..79592a7e4 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs @@ -14,6 +14,7 @@ use crate::cpu::kernel::tests::mpt::{ use crate::generation::mpt::AccountRlp; use crate::generation::TrieInputs; use crate::memory::segments::Segment; +use crate::util::h2u; use crate::Node; #[test] @@ -249,12 +250,22 @@ fn test_state_trie( interpreter.run()?; // Now, execute mpt_hash_state_trie. + state_trie.insert(k, rlp::encode(&account).to_vec()); + let expected_state_trie_hash = state_trie.hash(); + interpreter.set_global_metadata_field( + GlobalMetadata::StateTrieRootDigestAfter, + h2u(expected_state_trie_hash), + ); + interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; + interpreter + .halt_offsets + .push(KERNEL.global_labels["check_txn_trie"]); interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push(1.into()) // Initial length of the trie data segment, unused. + .push(interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)) // Initial trie data segment size, unused. .expect("The stack should not overflow"); interpreter.run()?; @@ -264,11 +275,6 @@ fn test_state_trie( "Expected 2 items on stack after hashing, found {:?}", interpreter.stack() ); - let hash = H256::from_uint(&interpreter.stack()[1]); - - state_trie.insert(k, rlp::encode(&account).to_vec()); - let expected_state_trie_hash = state_trie.hash(); - assert_eq!(hash, expected_state_trie_hash); Ok(()) } From d3dd09a8a1ad9e9f9473aea55fd3e5ebf77660fc Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 12 Jul 2024 08:48:36 +0100 Subject: [PATCH 092/118] Add check in mpt_insert tests --- .../src/cpu/kernel/tests/mpt/insert.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs index 79592a7e4..6ff88fd55 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs @@ -1,4 +1,5 @@ use anyhow::Result; +use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{BigEndianHash, H256}; use mpt_trie::nibbles::Nibbles; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; @@ -174,7 +175,7 @@ fn test_state_trie( storage_tries: vec![], }; let mpt_insert_state_trie = KERNEL.global_labels["mpt_insert_state_trie"]; - let mpt_hash_state_trie = KERNEL.global_labels["mpt_hash_state_trie"]; + let check_state_trie = KERNEL.global_labels["check_state_trie"]; let initial_stack = vec![]; let mut interpreter: Interpreter = Interpreter::new(0, initial_stack, None); @@ -241,15 +242,8 @@ fn test_state_trie( interpreter.stack() ); - // Now, run `set_final_tries` so that the trie roots are correct. - interpreter - .push(0xDEADBEEFu32.into()) - .expect("The stack should not overflow"); - interpreter.generation_state.registers.program_counter = - KERNEL.global_labels["set_final_tries"]; - interpreter.run()?; - - // Now, execute mpt_hash_state_trie. + // Now, execute mpt_hash_state_trie and check the hash value (both are done + // under `check_state_trie`). state_trie.insert(k, rlp::encode(&account).to_vec()); let expected_state_trie_hash = state_trie.hash(); interpreter.set_global_metadata_field( @@ -257,7 +251,7 @@ fn test_state_trie( h2u(expected_state_trie_hash), ); - interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; + interpreter.generation_state.registers.program_counter = check_state_trie; interpreter .halt_offsets .push(KERNEL.global_labels["check_txn_trie"]); From b9b8c5c1903e0636fd10d4d4d06d1287b6742fae Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 12 Jul 2024 13:29:29 +0100 Subject: [PATCH 093/118] Additional fixes --- .../src/cpu/kernel/asm/main.asm | 2 ++ .../src/cpu/kernel/tests/mpt/delete.rs | 32 ++++++++++--------- .../src/cpu/kernel/tests/mpt/insert.rs | 23 ++++++++----- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index c36ef72c8..02e507512 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -82,10 +82,12 @@ global main: PROVER_INPUT(trie_ptr::trie_data_size) %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) +global store_initial: // Store the inital accounts and slots for hashing later %store_initial_accounts %store_initial_slots +global after_store_initial: // Initialize the transaction and receipt trie root pointers. PROVER_INPUT(trie_ptr::txn) %mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs index 3040852fe..371d4f056 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs @@ -114,15 +114,22 @@ fn test_state_trie( initialize_mpts(&mut interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); + // Store initial accounts and storage. + interpreter + .halt_offsets + .push(KERNEL.global_labels["after_store_initial"]); + interpreter.generation_state.registers.program_counter = KERNEL.global_labels["store_initial"]; + interpreter.run(); + // Set initial tries. interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push((Segment::StorageLinkedList as usize + 7).into()) + .push((Segment::StorageLinkedList as usize + 8).into()) .expect("The stack should not overflow"); interpreter - .push((Segment::AccountsLinkedList as usize + 5).into()) + .push((Segment::AccountsLinkedList as usize + 6).into()) .expect("The stack should not overflow"); interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); @@ -132,8 +139,10 @@ fn test_state_trie( interpreter.run()?; - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + assert_eq!(interpreter.stack_len(), 2); + + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); @@ -199,14 +208,6 @@ fn test_state_trie( let state_trie_ptr = interpreter.pop().expect("The stack should not be empty"); interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_trie_ptr); - // Now, run `set_final_tries` again so that the trie roots are correct. - interpreter - .push(0xDEADBEEFu32.into()) - .expect("The stack should not overflow"); - interpreter.generation_state.registers.program_counter = - KERNEL.global_labels["set_final_tries"]; - interpreter.run()?; - // Now, execute mpt_hash_state_trie. let expected_state_trie_hash = state_trie.hash(); interpreter.set_global_metadata_field( @@ -215,9 +216,7 @@ fn test_state_trie( ); interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; - interpreter - .halt_offsets - .push(KERNEL.global_labels["check_txn_trie"]); + interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); @@ -233,5 +232,8 @@ fn test_state_trie( interpreter.stack() ); + let hash = interpreter.pop().expect("The stack should not be empty"); + assert_eq!(hash, h2u(expected_state_trie_hash)); + Ok(()) } diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs index 6ff88fd55..6cfd1c9bd 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs @@ -183,15 +183,22 @@ fn test_state_trie( initialize_mpts(&mut interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); + // Store initial accounts and storage. + interpreter + .halt_offsets + .push(KERNEL.global_labels["after_store_initial"]); + interpreter.generation_state.registers.program_counter = KERNEL.global_labels["store_initial"]; + interpreter.run(); + // Set initial tries. interpreter .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push((Segment::StorageLinkedList as usize + 7).into()) + .push((Segment::StorageLinkedList as usize + 8).into()) .expect("The stack should not overflow"); interpreter - .push((Segment::AccountsLinkedList as usize + 5).into()) + .push((Segment::AccountsLinkedList as usize + 6).into()) .expect("The stack should not overflow"); interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); @@ -201,8 +208,8 @@ fn test_state_trie( interpreter.run()?; - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); @@ -255,9 +262,9 @@ fn test_state_trie( interpreter .halt_offsets .push(KERNEL.global_labels["check_txn_trie"]); - interpreter - .push(0xDEADBEEFu32.into()) - .expect("The stack should not overflow"); + // interpreter + // .push(0xDEADBEEFu32.into()) + // .expect("The stack should not overflow"); interpreter .push(interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)) // Initial trie data segment size, unused. .expect("The stack should not overflow"); @@ -265,7 +272,7 @@ fn test_state_trie( assert_eq!( interpreter.stack().len(), - 2, + 1, "Expected 2 items on stack after hashing, found {:?}", interpreter.stack() ); From 9d994c1b7dfe6c6628bf9471ba1b435e9bcc93b5 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Mon, 15 Jul 2024 16:53:00 +0100 Subject: [PATCH 094/118] Pass preinitialized_segments when necessary --- evm_arithmetization/src/cpu/kernel/interpreter.rs | 4 ++++ evm_arithmetization/src/generation/mod.rs | 5 +++++ evm_arithmetization/src/generation/prover_input.rs | 1 + evm_arithmetization/src/generation/state.rs | 3 +++ evm_arithmetization/src/prover.rs | 14 +++++++++++--- 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index d2abd70d1..325419f4a 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -667,6 +667,10 @@ impl State for Interpreter { memory_state.contexts[ctx_idx] = ctx.clone(); } } + if self.generation_state.set_preinit { + memory_state.preinitialized_segments = + self.generation_state.memory.preinitialized_segments.clone(); + } Some(memory_state) } diff --git a/evm_arithmetization/src/generation/mod.rs b/evm_arithmetization/src/generation/mod.rs index 8d69399a5..a669ef2e3 100644 --- a/evm_arithmetization/src/generation/mod.rs +++ b/evm_arithmetization/src/generation/mod.rs @@ -411,6 +411,7 @@ pub fn generate_traces, const D: usize>( // previous segment execution, if any. let GenerationSegmentData { is_dummy, + set_preinit, segment_index, max_cpu_len_log, memory, @@ -419,6 +420,10 @@ pub fn generate_traces, const D: usize>( extra_data, } = segment_data; + if segment_data.set_preinit { + state.memory.preinitialized_segments = segment_data.memory.preinitialized_segments.clone(); + } + for &(address, val) in &actual_mem_before { state.memory.set(address, val); } diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 8cb2dca20..3d916bf01 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -89,6 +89,7 @@ impl GenerationState { "state" => match self.trie_root_ptrs.state_root_ptr { Some(state_root_ptr) => Ok(state_root_ptr), None => { + self.set_preinit = true; let mut new_content = self.memory.get_preinit_memory(Segment::TrieData); let n = load_state_mpt(&self.inputs.trimmed_tries, &mut new_content)?; diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index fee9e6c74..e3b21d113 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -341,6 +341,7 @@ pub struct GenerationState { pub(crate) next_txn_index: usize, + pub(crate) set_preinit: bool, /// Memory used by stale contexts can be pruned so proving segments can be /// smaller. pub(crate) stale_contexts: Vec, @@ -413,6 +414,7 @@ impl GenerationState { memory: MemoryState::new(kernel_code), traces: Traces::default(), next_txn_index: 0, + set_preinit: false, stale_contexts: Vec::new(), rlp_prover_inputs, withdrawal_prover_inputs, @@ -503,6 +505,7 @@ impl GenerationState { memory: self.memory.clone(), traces: Traces::default(), next_txn_index: 0, + set_preinit: self.set_preinit, stale_contexts: Vec::new(), rlp_prover_inputs: self.rlp_prover_inputs.clone(), state_key_to_address: self.state_key_to_address.clone(), diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index c20f1397a..8e99e1b75 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -39,6 +39,8 @@ use crate::witness::state::RegistersState; pub struct GenerationSegmentData { /// Indicates whether this corresponds to a dummy segment. pub(crate) is_dummy: bool, + /// Indicates whether we should set the preinitialized trie data segment. + pub(crate) set_preinit: bool, /// Indicates the position of this segment in a sequence of /// executions for a larger payload. pub(crate) segment_index: usize, @@ -494,6 +496,7 @@ pub fn check_abort_signal(abort_signal: Option>) -> Result<()> { #[allow(clippy::unwrap_or_default)] fn build_segment_data( segment_index: usize, + set_preinit: bool, registers_before: Option, registers_after: Option, memory: Option, @@ -501,6 +504,7 @@ fn build_segment_data( ) -> GenerationSegmentData { GenerationSegmentData { is_dummy: false, + set_preinit, segment_index, registers_before: registers_before.unwrap_or(RegistersState::new()), registers_after: registers_after.unwrap_or(RegistersState::new()), @@ -576,7 +580,7 @@ pub(crate) fn generate_next_segment( interpreter.generation_state.memory = partial.memory.clone(); partial } else { - build_segment_data(0, None, None, None, &interpreter) + build_segment_data(0, false, None, None, None, &interpreter) }; let segment_index = segment_data.segment_index; @@ -591,6 +595,7 @@ pub(crate) fn generate_next_segment( let partial_segment_data = Some(build_segment_data( segment_index + 1, + interpreter.generation_state.set_preinit || segment_data.set_preinit, Some(updated_registers), Some(updated_registers), mem_after, @@ -621,7 +626,7 @@ pub fn generate_all_data_segments( let mut segment_index = 0; - let mut segment_data = build_segment_data(segment_index, None, None, None, &interpreter); + let mut segment_data = build_segment_data(segment_index, false, None, None, None, &interpreter); while segment_data.registers_after.program_counter != KERNEL.global_labels["halt"] { let (updated_registers, mem_after) = @@ -635,6 +640,7 @@ pub fn generate_all_data_segments( segment_data = build_segment_data( segment_index, + interpreter.generation_state.set_preinit, Some(updated_registers), Some(updated_registers), mem_after, @@ -737,7 +743,8 @@ pub mod testing { let mut segment_index = 0; - let mut segment_data = build_segment_data(segment_index, None, None, None, &interpreter); + let mut segment_data = + build_segment_data(segment_index, false, None, None, None, &interpreter); while segment_data.registers_after.program_counter != KERNEL.global_labels["halt"] { segment_index += 1; @@ -747,6 +754,7 @@ pub mod testing { segment_data = build_segment_data( segment_index, + interpreter.generation_state.set_preinit, Some(updated_registers), Some(updated_registers), mem_after, From 1756b03fb564d6c725638389e82a0bc8bea19cbf Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Mon, 15 Jul 2024 18:20:02 +0100 Subject: [PATCH 095/118] Fix all unit tests --- .../src/cpu/kernel/tests/mpt/insert.rs | 3 ++- .../src/cpu/kernel/tests/mpt/mod.rs | 23 +++++++++++++++++++ evm_arithmetization/tests/log_opcode.rs | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs index 6cfd1c9bd..4553eec89 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs @@ -5,6 +5,7 @@ use mpt_trie::nibbles::Nibbles; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; use plonky2::field::goldilocks_field::GoldilocksField as F; +use super::{test_account_1, test_account_1_empty_storage_rlp}; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; @@ -28,7 +29,7 @@ fn mpt_insert_leaf_identical_keys() -> Result<()> { let key = nibbles_64(0xABC); let state_trie = Node::Leaf { nibbles: key, - value: test_account_1_rlp(), + value: test_account_1_empty_storage_rlp(), } .into(); test_state_trie(state_trie, key, test_account_2()) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs index 403887c4f..cf8f8597a 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/mod.rs @@ -1,6 +1,7 @@ use ethereum_types::{BigEndianHash, H256, U256}; use mpt_trie::nibbles::Nibbles; use mpt_trie::partial_trie::HashedPartialTrie; +use mpt_trie::partial_trie::PartialTrie; use crate::generation::mpt::AccountRlp; use crate::Node; @@ -38,10 +39,23 @@ pub(crate) fn test_account_1() -> AccountRlp { } } +pub(crate) fn test_account_1_empty_storage() -> AccountRlp { + AccountRlp { + nonce: U256::from(1111), + balance: U256::from(2222), + storage_root: HashedPartialTrie::from(Node::Empty).hash(), + code_hash: H256::from_uint(&U256::from(4444)), + } +} + pub(crate) fn test_account_1_rlp() -> Vec { rlp::encode(&test_account_1()).to_vec() } +pub(crate) fn test_account_1_empty_storage_rlp() -> Vec { + rlp::encode(&test_account_1_empty_storage()).to_vec() +} + pub(crate) fn test_account_2() -> AccountRlp { AccountRlp { nonce: U256::from(5555), @@ -51,6 +65,15 @@ pub(crate) fn test_account_2() -> AccountRlp { } } +pub(crate) fn test_account_2_empty_storage() -> AccountRlp { + AccountRlp { + nonce: U256::from(5555), + balance: U256::from(6666), + storage_root: HashedPartialTrie::from(Node::Empty).hash(), + code_hash: H256::from_uint(&U256::from(8888)), + } +} + pub(crate) fn test_account_2_rlp() -> Vec { rlp::encode(&test_account_2()).to_vec() } diff --git a/evm_arithmetization/tests/log_opcode.rs b/evm_arithmetization/tests/log_opcode.rs index fd925af78..1cc03d048 100644 --- a/evm_arithmetization/tests/log_opcode.rs +++ b/evm_arithmetization/tests/log_opcode.rs @@ -450,7 +450,7 @@ fn test_log_with_aggreg() -> anyhow::Result<()> { &all_stark, &[ 16..17, - 11..15, + 8..10, 12..17, 8..11, 8..9, From 19aa2644fed3c6bcc388014a1b255b695224d811 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 16 Jul 2024 12:14:57 +0100 Subject: [PATCH 096/118] Cleanup --- .../kernel/asm/journal/account_destroyed.asm | 26 -------------- .../src/cpu/kernel/asm/main.asm | 3 -- .../src/cpu/kernel/asm/mpt/accounts.asm | 2 +- .../src/cpu/kernel/asm/mpt/delete/delete.asm | 2 +- .../src/cpu/kernel/asm/mpt/hash/hash.asm | 2 -- .../asm/mpt/linked_list/final_tries.asm | 5 --- .../asm/mpt/linked_list/initial_tries.asm | 9 +---- .../asm/mpt/linked_list/linked_list.asm | 9 +++-- .../src/cpu/kernel/asm/mpt/read.asm | 2 -- .../kernel/asm/mpt/storage/storage_read.asm | 2 -- .../kernel/asm/mpt/storage/storage_write.asm | 5 --- .../cpu/kernel/constants/global_metadata.rs | 6 +++- .../src/cpu/kernel/tests/account_code.rs | 28 +++++---------- .../src/cpu/kernel/tests/add11.rs | 7 ---- .../src/cpu/kernel/tests/balance.rs | 5 --- .../src/cpu/kernel/tests/mpt/delete.rs | 8 +---- .../src/cpu/kernel/tests/mpt/hash.rs | 2 +- .../src/cpu/kernel/tests/mpt/insert.rs | 7 ++-- .../src/cpu/kernel/tests/mpt/linked_list.rs | 22 +++++------- .../src/cpu/kernel/tests/mpt/read.rs | 2 +- evm_arithmetization/src/generation/mpt.rs | 22 ++++++------ .../src/generation/prover_input.rs | 34 +++++++++++-------- evm_arithmetization/src/generation/state.rs | 2 ++ evm_arithmetization/src/prover.rs | 4 +-- evm_arithmetization/src/witness/transition.rs | 5 --- 25 files changed, 70 insertions(+), 151 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index be91c7517..6927f4eb7 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -4,32 +4,6 @@ %journal_add_3(@JOURNAL_ENTRY_ACCOUNT_DESTROYED) %endmacro -global revert_account_destroyed_original: - // stack: entry_type, ptr, retdest - POP - %journal_load_3 - // stack: address, target, prev_balance, retdest - PUSH revert_account_destroyed_contd DUP2 - %jump(remove_selfdestruct_list) -revert_account_destroyed_contd_original: - // stack: address, target, prev_balance, retdest - SWAP1 - // Remove `prev_balance` from `target`'s balance. - // stack: target, address, prev_balance, retdest - %mpt_read_state_trie - %add_const(1) - // stack: target_balance_ptr, address, prev_balance, retdest - DUP3 - DUP2 %mload_trie_data - // stack: target_balance, prev_balance, target_balance_ptr, address, prev_balance, retdest - SUB SWAP1 %mstore_trie_data - // Set `address`'s balance to `prev_balance`. - // stack: address, prev_balance, retdest - %mpt_read_state_trie - %add_const(1) - %mstore_trie_data - JUMP - global revert_account_destroyed: // stack: entry_type, ptr, retdest POP diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 02e507512..a03050fe0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -167,7 +167,6 @@ global perform_final_checks: PROVER_INPUT(trie_ptr::state) -global debug_state_trie_ptr: %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) %set_initial_tries %get_trie_data_size @@ -175,7 +174,6 @@ global debug_state_trie_ptr: SWAP1 %set_trie_data_size %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_BEFORE) -global debug_st_1: %assert_eq PUSH 1 // initial trie data length @@ -183,7 +181,6 @@ global debug_st_1: global check_state_trie: %set_final_tries %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) -global debug_st_2: %assert_eq global check_txn_trie: %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm index 61f638910..e80dea021 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm @@ -59,4 +59,4 @@ SWAP1 %mload_trie_data %append_to_trie_data -%endmacro \ No newline at end of file +%endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index 10f50b3e4..6fb4f4162 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -18,7 +18,7 @@ global mpt_delete: PANIC -global mpt_delete_leaf: +mpt_delete_leaf: // stack: node_type, node_payload_ptr, num_nibbles, key, retdest %pop4 PUSH 0 // empty node ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm index be573e55c..652b9f22f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -57,7 +57,6 @@ global encode_or_hash_node: DUP1 PUSH @MPT_NODE_HASH SUB -global debug_o: %jumpi(encode_or_hash_concrete_node) // If we got here, node_type == @MPT_NODE_HASH. @@ -76,7 +75,6 @@ global debug_o: %stack (cur_len, encode_value, hash, retdest) -> (retdest, hash, 32, cur_len) JUMP -global debug_encode_or_hash_concrete_node: encode_or_hash_concrete_node: %stack (node_type, node_ptr, encode_value, cur_len) -> (node_type, node_ptr, encode_value, cur_len, maybe_hash_node) %jump(encode_node) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index d1bcd8707..f35131c1c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -16,19 +16,16 @@ global insert_all_accounts: DUP4 %increment MLOAD_GENERAL -global debug_account_ptr: // stack: account_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %add_const(2) DUP1 %mload_trie_data -global debug_storage_root_ptr: // stack: storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr, root_ptr, account_ptr_ptr, retdest %stack (storage_root_ptr, storage_root_ptr_ptr, key, storage_ptr_ptr) -> (key, storage_ptr_ptr, storage_root_ptr, after_insert_all_slots, storage_root_ptr_ptr, key) %jump(insert_all_slots) -global debug_after_insert_all_slots: after_insert_all_slots: // stack: storage_ptr_ptr', storage_root_ptr', storage_root_ptr_ptr, key, root_ptr, account_ptr_ptr, retdest SWAP2 @@ -100,7 +97,6 @@ global delete_removed_accounts: // The inital accounts linked was store at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. // If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it // suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN` -global debug_eq: EQ %jumpi(delete_removed_accounts_end) // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest @@ -196,7 +192,6 @@ delete_this_slot: %stack (key, addr, root_ptr, storage_ptr_ptr) -> (root_ptr, 64, key, after_mpt_delete_slot, addr, storage_ptr_ptr) %jump(mpt_delete) after_mpt_delete_slot: -global debug_after_mpt_delete_slot: // stack: root_ptr', addr, storage_ptr_ptr SWAP2 %add_const(5) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index d89b35cdf..69b7eb9f0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -19,7 +19,6 @@ global mpt_set_payload: DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) skip: -global debug_skip: // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest %stack (node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) JUMP @@ -52,7 +51,6 @@ global debug_skip: global mpt_set_storage_payload: // stack: node_ptr, storage_ptr_ptr, retdest DUP1 %mload_trie_data -global debug_storage_node_type: // stack: node_type, node_ptr, storage_ptr_ptr, retdest // Increment node_ptr, so it points to the node payload instead of its type. SWAP1 %increment SWAP1 @@ -132,7 +130,6 @@ set_payload_storage_extension: // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %jump(mpt_set_storage_payload) -global debug_set_payload_leaf: set_payload_leaf: // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest POP @@ -145,7 +142,6 @@ set_payload_leaf: %mload_trie_data // storage_root_ptr = account[2] DUP1 %mload_trie_data -global debug_node_type: POP // stack storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %stack @@ -161,15 +157,12 @@ global debueg_the_intial_ptr: // stack: new_storage_root_ptr_ptr, new_payload_ptr, storage_root_ptr, storage_ptr_ptr', payload_ptr_ptr, account_ptr_ptr, retdest // Load also the old "dynamic" payload for storing the storage_root_ptr DUP6 %decrement -global debug_the_dyn_ptr: MLOAD_GENERAL %add_const(2) // dyn_storage_root_ptr_ptr = dyn_paylod_ptr[2] %stack (dyn_storage_root_ptr_ptr, new_storage_root_ptr_ptr, new_payload_ptr, storage_ptr_ptr_p, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) -> (new_storage_root_ptr_ptr, storage_root_ptr, dyn_storage_root_ptr_ptr, storage_root_ptr, payload_ptr_ptr, new_payload_ptr, account_ptr_ptr, storage_ptr_ptr_p) -global debug_setting_intial_account_ptr: %mstore_trie_data // The initial account pointer in the linked list has no storage root so we need to manually set it. -global debug_setting_dyn_account_storage: %mstore_trie_data // The dynamic account pointer in the linked list has no storage root so we need to manually set it. %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. // stack: account_ptr_ptr, storage_ptr_ptr', retdest @@ -192,4 +185,4 @@ set_payload_storage_leaf: %add_const(5) // The next pointer is at distance 5 // stack: storage_ptr_ptr', retdest SWAP1 - JUMP \ No newline at end of file + JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 75eb0133a..14f193834 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -79,7 +79,6 @@ global store_initial_accounts: loop_store_initial_accounts: // stack: current_node_ptr %get_trie_data_size -global debug_new_ptr: DUP2 MLOAD_GENERAL // stack: current_addr, cpy_ptr, current_node_ptr, retdest @@ -193,7 +192,7 @@ global insert_account_to_linked_list: %jump_neq_const(@U256_MAX, account_found) // The storage key is not in the list. PANIC -global account_found: +account_found: // The address was already in the list // stack: pred_ptr, addr, payload_ptr, retdest // Load the payload pointer @@ -202,8 +201,8 @@ global account_found: // stack: orig_payload_ptr, addr, payload_ptr, retdest %stack (orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP -//DEBUG -global insert_new_account: + +insert_new_account: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest POP // get the value of the next address @@ -556,6 +555,7 @@ insert_new_slot_with_value: DUP7 // The next key must be strictly larger %assert_lt + next_node_ok_with_value: // stack: next_addr or next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest POP @@ -656,7 +656,6 @@ global insert_slot: // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest DUP1 DUP5 GT -global before_jumpi: %jumpi(insert_new_slot) // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest DUP4 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 8f2e7a1b0..aa2c9bf1c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -3,8 +3,6 @@ // trie_data segment. Returns null if the address is not found. global mpt_read_state_trie: // stack: addr, retdest - // stack: address, retdest - %read_accounts_linked_list // stack: account_ptr SWAP1 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index fae4f326f..983b2ac43 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -5,8 +5,6 @@ %endmacro global sload_current: - - %read_storage_linked_list // stack: value_ptr, retdest DUP1 %jumpi(storage_key_exists) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index ca38b8735..425ef70e4 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -119,11 +119,6 @@ sstore_after_refund: %append_to_trie_data // stack: slot, value_ptr, kexit_info - // DEBUG - DUP2 %mload_trie_data - POP - // ENDDEBUG - %slot_to_storage_key %address %addr_to_state_key diff --git a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs index 2fc55c4fa..4349590b8 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/global_metadata.rs @@ -98,10 +98,14 @@ pub(crate) enum GlobalMetadata { /// The address of the next available address in /// Segment::AccountsLinkedList AccountsLinkedListLen, - // The address of the next available address in + /// The address of the next available address in /// Segment::StorageLinkedList StorageLinkedListLen, + /// Length of the `AccountsLinkedList` segment after insertion of the + /// initial accounts. InitialAccountsLinkedListLen, + /// Length of the `StorageLinkedList` segment after insertion of the + /// initial storage slots. InitialStorageLinkedListLen, } diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index e6bf98982..1e5d93786 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use anyhow::Result; -use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{Address, BigEndianHash, H256, U256}; use hex_literal::hex; use keccak_hash::keccak; @@ -139,9 +138,8 @@ pub(crate) fn prepare_interpreter( address: Address, account: &AccountRlp, ) -> Result<()> { - init_logger(); let mpt_insert_state_trie = KERNEL.global_labels["mpt_insert_state_trie"]; - let mpt_hash_state_trie = KERNEL.global_labels["check_state_trie"]; + let check_state_trie = KERNEL.global_labels["check_state_trie"]; let mut state_trie: HashedPartialTrie = HashedPartialTrie::from(Node::Empty); let trie_inputs = TrieInputs { state_trie: HashedPartialTrie::from(Node::Empty), @@ -198,10 +196,10 @@ pub(crate) fn prepare_interpreter( .push(0xDEADBEEFu32.into()) .expect("The stack should not overflow"); interpreter - .push((Segment::StorageLinkedList as usize + 7).into()) + .push((Segment::StorageLinkedList as usize + 8).into()) .expect("The stack should not overflow"); interpreter - .push((Segment::AccountsLinkedList as usize + 5).into()) + .push((Segment::AccountsLinkedList as usize + 6).into()) .expect("The stack should not overflow"); interpreter.push(interpreter.get_global_metadata_field(GlobalMetadata::StateTrieRoot)); @@ -211,12 +209,12 @@ pub(crate) fn prepare_interpreter( interpreter.run()?; - let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 1; - let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + let acc_ptr = interpreter.pop().expect("The stack should not be empty") - 2; + let storage_ptr = interpreter.pop().expect("The stack should not be empty") - 3; interpreter.set_global_metadata_field(GlobalMetadata::InitialAccountsLinkedListLen, acc_ptr); interpreter.set_global_metadata_field(GlobalMetadata::InitialStorageLinkedListLen, storage_ptr); - // Now, execute mpt_hash_state_trie. + // Now, execute `mpt_hash_state_trie`. state_trie.insert(k, rlp::encode(account).to_vec()); let expected_state_trie_hash = state_trie.hash(); interpreter.set_global_metadata_field( @@ -224,7 +222,7 @@ pub(crate) fn prepare_interpreter( h2u(expected_state_trie_hash), ); - interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; + interpreter.generation_state.registers.program_counter = check_state_trie; interpreter .halt_offsets .push(KERNEL.global_labels["check_txn_trie"]); @@ -299,7 +297,6 @@ fn test_extcodesize() -> Result<()> { #[test] fn test_extcodecopy() -> Result<()> { - init_logger(); let code = random_code(); let account = test_account(&code); @@ -462,7 +459,6 @@ fn prepare_interpreter_all_accounts( /// Tests an SSTORE within a code similar to the contract code in add11_yml. #[test] fn sstore() -> Result<()> { - init_logger(); // We take the same `to` account as in add11_yml. let addr = hex!("095e7baea6a6c7c4c2dfeb977efac326af552d87"); @@ -534,7 +530,7 @@ fn sstore() -> Result<()> { interpreter .halt_offsets .push(KERNEL.global_labels["check_txn_trie"]); - // Now, execute mpt_hash_state_trie and check that the hash is correct. + // Now, execute `mpt_hash_state_trie` and check that the hash is correct. let mpt_hash_state_trie = KERNEL.global_labels["check_state_trie"]; interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; interpreter.set_is_kernel(true); @@ -553,8 +549,6 @@ fn sstore() -> Result<()> { /// Tests an SLOAD within a code similar to the contract code in add11_yml. #[test] fn sload() -> Result<()> { - init_logger(); // We take the same `to` account as in add11_yml. - let addr = hex!("095e7baea6a6c7c4c2dfeb977efac326af552d87"); let addr_hashed = keccak(addr); @@ -618,7 +612,7 @@ fn sload() -> Result<()> { interpreter .pop() .expect("The stack length should not be empty."); - // Now, execute mpt_hash_state_trie. We check that the state trie has not + // Now, execute `mpt_hash_state_trie`. We check that the state trie has not // changed. let mpt_hash_state_trie = KERNEL.global_labels["mpt_hash_state_trie"]; interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; @@ -647,7 +641,3 @@ fn sload() -> Result<()> { assert_eq!(hash, expected_state_trie_hash); Ok(()) } - -fn init_logger() { - let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); -} diff --git a/evm_arithmetization/src/cpu/kernel/tests/add11.rs b/evm_arithmetization/src/cpu/kernel/tests/add11.rs index a29d1ce46..7026c8ed2 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/add11.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/add11.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::str::FromStr; -use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{Address, BigEndianHash, H256}; use hex_literal::hex; use keccak_hash::keccak; @@ -166,8 +165,6 @@ fn test_add11_yml() { #[test] fn test_add11_yml_with_exception() { - init_logger(); - // In this test, we make sure that the user code throws a stack underflow // exception. let beneficiary = hex!("2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"); @@ -308,7 +305,3 @@ fn test_add11_yml_with_exception() { .run() .expect("Proving add11 with exception failed."); } - -fn init_logger() { - let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); -} diff --git a/evm_arithmetization/src/cpu/kernel/tests/balance.rs b/evm_arithmetization/src/cpu/kernel/tests/balance.rs index 36233bb99..4dbcdb722 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/balance.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/balance.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{Address, BigEndianHash, H256, U256}; use keccak_hash::keccak; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; @@ -25,10 +24,6 @@ fn test_account(balance: U256) -> AccountRlp { } } -fn init_logger() { - let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); -} - #[test] fn test_balance() -> Result<()> { let mut rng = thread_rng(); diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs index 371d4f056..44602f92c 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/delete.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{BigEndianHash, H256}; use mpt_trie::nibbles::{Nibbles, NibblesIntern}; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; @@ -18,13 +17,8 @@ use crate::memory::segments::Segment; use crate::util::h2u; use crate::Node; -fn init_logger() { - let _ = try_init_from_env(Env::default().filter_or(DEFAULT_FILTER_ENV, "info")); -} - #[test] fn mpt_delete_empty() -> Result<()> { - init_logger(); test_state_trie(Default::default(), nibbles_64(0xABC), test_account_2()) } @@ -208,7 +202,7 @@ fn test_state_trie( let state_trie_ptr = interpreter.pop().expect("The stack should not be empty"); interpreter.set_global_metadata_field(GlobalMetadata::StateTrieRoot, state_trie_ptr); - // Now, execute mpt_hash_state_trie. + // Now, execute `mpt_hash_state_trie`. let expected_state_trie_hash = state_trie.hash(); interpreter.set_global_metadata_field( GlobalMetadata::StateTrieRootDigestAfter, diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/hash.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/hash.rs index 1f7562bf7..59c5fb384 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/hash.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/hash.rs @@ -117,7 +117,7 @@ fn test_state_trie(trie_inputs: TrieInputs) -> Result<()> { initialize_mpts(&mut interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); - // Now, execute mpt_hash_state_trie. + // Now, execute `mpt_hash_state_trie`. interpreter.generation_state.registers.program_counter = mpt_hash_state_trie; interpreter .push(0xDEADBEEFu32.into()) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs index 4553eec89..28352c69e 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/insert.rs @@ -1,5 +1,4 @@ use anyhow::Result; -use env_logger::{try_init_from_env, Env, DEFAULT_FILTER_ENV}; use ethereum_types::{BigEndianHash, H256}; use mpt_trie::nibbles::Nibbles; use mpt_trie::partial_trie::{HashedPartialTrie, PartialTrie}; @@ -250,7 +249,7 @@ fn test_state_trie( interpreter.stack() ); - // Now, execute mpt_hash_state_trie and check the hash value (both are done + // Now, execute `mpt_hash_state_trie` and check the hash value (both are done // under `check_state_trie`). state_trie.insert(k, rlp::encode(&account).to_vec()); let expected_state_trie_hash = state_trie.hash(); @@ -263,9 +262,7 @@ fn test_state_trie( interpreter .halt_offsets .push(KERNEL.global_labels["check_txn_trie"]); - // interpreter - // .push(0xDEADBEEFu32.into()) - // .expect("The stack should not overflow"); + interpreter .push(interpreter.get_global_metadata_field(GlobalMetadata::TrieDataSize)) // Initial trie data segment size, unused. .expect("The stack should not overflow"); diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 760a136eb..d93764e80 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -262,13 +262,11 @@ fn test_insert_and_delete_accounts() -> Result<()> { let mut rng = thread_rng(); let n = 10; let mut addresses = (0..n) - // .map(|_| rng.gen::
()) .map(|i| Address::from_low_u64_be(i as u64 + 5)) .collect::>() .into_iter() .collect::>(); let delta_ptr = 100; - // let addr_not_in_list = rng.gen::
(); let addr_not_in_list = Address::from_low_u64_be(4); assert!( !addresses.contains(&addr_not_in_list), @@ -349,7 +347,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { U256::from(offset + (n + 2) * 4) ); - // Remove all even nodes + // Remove all even nodes. let delete_account_label = KERNEL.global_labels["remove_account"]; let mut new_addresses = vec![]; @@ -365,11 +363,11 @@ fn test_insert_and_delete_accounts() -> Result<()> { // we add the non deleted addres to new_addresses new_addresses.push(addresses[j]); } - // the last address is not removed + // The last address is not removed. new_addresses.push(*addresses.last().unwrap()); - // We need to sort the list in order to properly compare with - // the linked list the interpreter's memory + // We need to sort the list in order to properly compare + // the linked list with the interpreter's memory. new_addresses.sort(); let mut list = interpreter @@ -409,7 +407,6 @@ fn test_insert_and_delete_storage() -> Result<()> { let mut rng = thread_rng(); let n = 10; let mut addresses_and_keys = (0..n) - // .map(|_| rng.gen::
()) .map(|i| { [ Address::from_low_u64_be(i as u64 + 5), @@ -420,7 +417,6 @@ fn test_insert_and_delete_storage() -> Result<()> { .into_iter() .collect::>(); let delta_ptr = 100; - // let addr_not_in_list = rng.gen::
(); let addr_not_in_list = Address::from_low_u64_be(4); let key_not_in_list = H160::from_low_u64_be(5); assert!( @@ -510,13 +506,13 @@ fn test_insert_and_delete_storage() -> Result<()> { U256::from(offset + (n + 2) * 5) ); - // Remove all even nodes + // Remove all even nodes. let remove_slot_label = KERNEL.global_labels["remove_slot"]; let mut new_addresses = vec![]; for (i, j) in (0..n).tuples() { - // Test for [address, ke] already in list. + // Test for [address, key] already in list. let [addr_in_list, key_in_list] = addresses_and_keys[i].map(|x| U256::from(x.0.as_slice())); interpreter.push(retaddr); interpreter.push(key_in_list); @@ -527,11 +523,11 @@ fn test_insert_and_delete_storage() -> Result<()> { // we add the non deleted addres to new_addresses new_addresses.push(addresses_and_keys[j]); } - // the last address is not removed + // The last address is not removed. new_addresses.push(*addresses_and_keys.last().unwrap()); - // We need to sort the list in order to properly compare with - // the linked list the interpreter's memory + // We need to sort the list in order to properly compare + // the linked list with the interpreter's memory. new_addresses.sort(); let mut list = interpreter diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs index b8a1e0722..571b45c38 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/read.rs @@ -25,7 +25,7 @@ fn mpt_read() -> Result<()> { initialize_mpts(&mut interpreter, &trie_inputs); assert_eq!(interpreter.stack(), vec![]); - // Now, execute mpt_read on the state trie. + // Now, execute `mpt_read` on the state trie. interpreter.generation_state.registers.program_counter = mpt_read; interpreter .push(0xdeadbeefu32.into()) diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index 4991d50f2..cadb89e5b 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -382,26 +382,26 @@ fn get_state_and_storage_leaves( associated storage trie hash" ); - // The last leaf must point to the new one + // The last leaf must point to the new one. let len = state_leaves.len(); state_leaves[len - 1] = U256::from(Segment::AccountsLinkedList as usize + state_leaves.len()); - // The nibbles are the address? + // The nibbles are the address. let address = merged_key .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?; state_leaves.push(address); // Set `value_ptr_ptr`. state_leaves.push(trie_data.len().into()); - // Set counter + // Set counter. state_leaves.push(0.into()); - // Set the next node as the inital node + // Set the next node as the inital node. state_leaves.push((Segment::AccountsLinkedList as usize).into()); - // Push the payload in the trie data + // Push the payload in the trie data. trie_data.push(Some(nonce)); trie_data.push(Some(balance)); - // The Storage pointer is only written in the trie + // The Storage pointer is only written in the trie. trie_data.push(Some(0.into())); trie_data.push(Some(code_hash.into_uint())); get_storage_leaves( @@ -465,14 +465,14 @@ where Ok(()) } Node::Leaf { nibbles, value } => { - // The last leaf must point to the new one + // The last leaf must point to the new one. let len = storage_leaves.len(); let merged_key = key.merge_nibbles(nibbles); storage_leaves[len - 1] = U256::from(Segment::StorageLinkedList as usize + storage_leaves.len()); - // Write the address + // Write the address. storage_leaves.push(address); - // Write the key + // Write the key. storage_leaves.push( merged_key .try_into() @@ -480,9 +480,9 @@ where ); // Write `value_ptr_ptr`. storage_leaves.push((trie_data.len()).into()); - // Write the counter + // Write the counter. storage_leaves.push(0.into()); - // Set the next node as the inital node + // Set the next node as the inital node. storage_leaves.push((Segment::StorageLinkedList as usize).into()); let leaf = parse_value(value)?.into_iter().map(Some); diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 3d916bf01..07d2eb8db 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -416,7 +416,7 @@ impl GenerationState { /// Returns a non-jumpdest proof for the address on the top of the stack. A /// non-jumpdest proof is the closest address to the address on the top of - /// the stack, if the closses address is >= 32, or zero otherwise. + /// the stack, if the closest address is >= 32, or zero otherwise. fn run_next_non_jumpdest_proof(&self) -> Result { let code = self.get_current_code()?; let address = u256_to_usize(stack_peek(self, 0)?)?; @@ -448,7 +448,7 @@ impl GenerationState { /// Returns a pointer to an element in the list whose value is such that /// `value < addr == next_value` and addr is the top of the stack. - /// If the element is not in the list returns loops forever + /// If the element is not in the list, it loops forever fn run_next_addresses_remove(&self) -> Result { let addr = stack_peek(self, 0)?; if let Some(([_, ptr], _)) = self @@ -503,7 +503,7 @@ impl GenerationState { } } - /// Returns a pointer to an node in the list such that + /// Returns a pointer to a node in the list such that /// `node[0] <= addr < next_node[0]` and `addr` is the top of the stack. fn run_next_insert_account(&self) -> Result { let addr = stack_peek(self, 0)?; @@ -523,7 +523,7 @@ impl GenerationState { /// Returns an unscaled pointer to an element in the list such that /// `node[0] <= addr < next_node[0]`, or node[0] == addr and `node[1] <= - /// key < next_node[1]`, where `addr` and `key` are the elements at top + /// key < next_node[1]`, where `addr` and `key` are the elements at the top /// of the stack. fn run_next_insert_slot(&self) -> Result { let addr = stack_peek(self, 0)?; @@ -549,9 +549,9 @@ impl GenerationState { } } - /// Returns a pointer `ptr`` to a node of the form [next_addr, ..] in the - /// list such that `next_addr = addr` and addr is the top of the stack. - /// If the element is not in the list loops forever + /// Returns a pointer `ptr` to a node of the form [next_addr, ..] in the + /// list such that `next_addr = addr` and `addr` is the top of the stack. + /// If the element is not in the list, loops forever. fn run_next_remove_account(&self) -> Result { let addr = stack_peek(self, 0)?; if let Some(([.., ptr], _)) = self @@ -565,10 +565,10 @@ impl GenerationState { } } - /// Returns a pointer `ptr`to an a node = [next_addr, next_key] in the list - /// such that `next_addr == addr` and `next_key == key `, + /// Returns a pointer `ptr` to a node = `[next_addr, next_key]` in the list + /// such that `next_addr == addr` and `next_key == key`, /// and `addr, key` are the elements at the top of the stack. - /// If the element is not in the list loops forever + /// If the element is not in the list, loops forever. fn run_next_remove_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; @@ -584,6 +584,12 @@ impl GenerationState { } } + /// Returns a pointer `ptr` to a storage node in the storage linked list. + /// The node's next element = `[next_addr, next_key]` is such that + /// `next_addr = addr`, if such an element exists, or such that + /// `next_addr = @U256_MAX`. This is used to determine the first storage + /// node for the account at `addr`. `addr` is the element at the top of the + /// stack. fn run_next_remove_address_slots(&self) -> Result { let addr = stack_peek(self, 0)?; if let Some((([.., pred_ptr], _), _)) = self @@ -705,7 +711,7 @@ impl GenerationState { &self, ) -> Result, ProgramError> { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next - // available virtual address in the segment. In order to get the length + // available virtual address in the segment. In order to get the length, // we need to substract `Segment::AccountsLinkedList` as usize. let accounts_mem = self.memory.get_preinit_memory(Segment::AccountsLinkedList); LinkedList::from_mem_and_segment(&accounts_mem, Segment::AccountsLinkedList) @@ -715,8 +721,8 @@ impl GenerationState { &self, ) -> Result, ProgramError> { // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next - // available virtual address in the segment. In order to get the length - // we need to substract `Segment::AccountsLinkedList` as usize. + // available virtual address in the segment. In order to get the length, + // we need to substract `Segment::StorageLinkedList` as usize. let storage_mem = self.memory.get_preinit_memory(Segment::StorageLinkedList); LinkedList::from_mem_and_segment(&storage_mem, Segment::StorageLinkedList) } @@ -734,7 +740,7 @@ impl GenerationState { ) -> Result, ProgramError> { // GlobalMetadata::AccessedStorageKeysLen stores the value of the next available // virtual address in the segment. In order to get the length we need - // to substract Segment::AccessedStorageKeys as usize + // to substract `Segment::AccessedStorageKeys` as usize. LinkedList::from_mem_and_segment( &self.memory.contexts[0].segments[Segment::AccessedStorageKeys.unscale()].content, Segment::AccessedStorageKeys, diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index e3b21d113..61dfa5d6f 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -341,6 +341,8 @@ pub struct GenerationState { pub(crate) next_txn_index: usize, + /// Indicates whether we should set the preinitialized segments before + /// proving. pub(crate) set_preinit: bool, /// Memory used by stale contexts can be pruned so proving segments can be /// smaller. diff --git a/evm_arithmetization/src/prover.rs b/evm_arithmetization/src/prover.rs index 8e99e1b75..54f7165d9 100644 --- a/evm_arithmetization/src/prover.rs +++ b/evm_arithmetization/src/prover.rs @@ -39,7 +39,8 @@ use crate::witness::state::RegistersState; pub struct GenerationSegmentData { /// Indicates whether this corresponds to a dummy segment. pub(crate) is_dummy: bool, - /// Indicates whether we should set the preinitialized trie data segment. + /// Indicates whether we should set the preinitialized segments before + /// proving. pub(crate) set_preinit: bool, /// Indicates the position of this segment in a sequence of /// executions for a larger payload. @@ -654,7 +655,6 @@ pub fn generate_all_data_segments( /// A utility module designed to test witness generation externally. pub mod testing { use mpt_trie::partial_trie::HashedPartialTrie; - use mpt_trie::partial_trie::PartialTrie; use super::*; use crate::{ diff --git a/evm_arithmetization/src/witness/transition.rs b/evm_arithmetization/src/witness/transition.rs index 9bd64831a..35c3b2a91 100644 --- a/evm_arithmetization/src/witness/transition.rs +++ b/evm_arithmetization/src/witness/transition.rs @@ -1,22 +1,17 @@ use ethereum_types::U256; use log::log_enabled; -use mpt_trie::partial_trie::HashedPartialTrie; -use mpt_trie::partial_trie::PartialTrie; use plonky2::field::types::Field; use super::util::{mem_read_gp_with_log_and_fill, stack_pop_with_log_and_fill}; use crate::cpu::columns::CpuColumnsView; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::context_metadata::ContextMetadata; -use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::membus::NUM_GP_CHANNELS; use crate::cpu::stack::{ EQ_STACK_BEHAVIOR, IS_ZERO_STACK_BEHAVIOR, JUMPI_OP, JUMP_OP, MIGHT_OVERFLOW, STACK_BEHAVIORS, }; use crate::generation::state::State; -use crate::generation::trie_extractor::get_state_trie; use crate::memory::segments::Segment; -use crate::util::u256_to_usize; use crate::witness::errors::ProgramError; use crate::witness::gas::gas_to_charge; use crate::witness::memory::MemoryAddress; From e725678002eb5ec0f32292d0ac7d6c4184269a23 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 16 Jul 2024 13:13:59 +0100 Subject: [PATCH 097/118] More comments cleanup --- .../kernel/asm/journal/account_destroyed.asm | 2 +- .../asm/mpt/linked_list/final_tries.asm | 16 +++-- .../asm/mpt/linked_list/initial_tries.asm | 7 +- .../asm/mpt/linked_list/linked_list.asm | 66 ++++++++----------- .../src/cpu/kernel/asm/mpt/read.asm | 2 +- 5 files changed, 41 insertions(+), 52 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index 6927f4eb7..d5dd70f81 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -12,7 +12,7 @@ global revert_account_destroyed: PUSH revert_account_destroyed_contd DUP2 %jump(remove_selfdestruct_list) revert_account_destroyed_contd: - // stack: address: target, prev_balance, retdest + // stack: address, target, prev_balance, retdest SWAP1 // Remove `prev_balance` from `target`'s balance. // stack: target, address, prev_balance, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index f35131c1c..bc8ebb106 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -85,16 +85,17 @@ after_insert_slot: %jump(insert_all_slots) // Delete all the accounts, referenced by the respective nodes in the linked list starting at -// `account_ptr_ptr, which where deleted from the intial state. Delete also all slots deleted -// from the storage trie of non-deleted accounts. +// `account_ptr_ptr`, which where deleted from the intial state. Delete also all slots of non-deleted accounts +// deleted from the storage trie. // Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest // Post stack: new_root_ptr. global delete_removed_accounts: + // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP1 // We assume that the size of the initial accounts linked list, containing the accounts - // of the initial state, was store at `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. + // of the initial state, was stored at `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. %mload_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) - // The inital accounts linked was store at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. + // The inital accounts linked list was stored at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. // If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it // suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN` EQ @@ -102,9 +103,9 @@ global delete_removed_accounts: // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP1 %next_account - %eq_const(@U256_MAX) // Check if the next node pointer is @U256_MAX, the node was deleted + %eq_const(@U256_MAX) // If the next node pointer is @U256_MAX, the node was deleted %jumpi(delete_account) - // The account is still there so we need to delete any removed slot + // The account is still there so we need to delete any removed slot. // stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP1 MLOAD_GENERAL @@ -154,10 +155,11 @@ after_mpt_delete: %jump(delete_removed_accounts) // Delete all slots in `storage_ptr_ptr` with address == `addr` and -// `storage_ptr_ptr` < @GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN. +// `storage_ptr_ptr` < `@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN`. // Pre stack: addr, root_ptr, storage_ptr_ptr, retdest // Post stack: new_root_ptr, storage_ptr_ptr'. delete_removed_slots: + // stack: addr, root_ptr, storage_ptr_ptr, retdest DUP3 MLOAD_GENERAL // stack: address, addr, root_ptr, storage_ptr_ptr, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index 69b7eb9f0..fd4d529f0 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -1,8 +1,8 @@ -// Set the trie with root at `node_ptr` leaves -// payloads pointers to mem[payload_ptr_ptr] + step*i, for +// Set the payload pointers of the leaves in the trie with root at `node_ptr` +// to mem[payload_ptr_ptr] + step*i, // for i =0..n_leaves. This is used to constraint the // initial state and account tries payload pointers such that they are exactly -// those of the inital accounts and linked lists +// those of the inital accounts and linked lists. // Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest // Post stack: account_ptr_ptr, storage_ptr_ptr global mpt_set_payload: @@ -151,7 +151,6 @@ set_payload_leaf: after_set_storage_payload: // stack: storage_ptr_ptr', storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, retdest DUP4 -global debueg_the_intial_ptr: MLOAD_GENERAL // load the next payload pointer in the linked list DUP1 %add_const(2) // new_storage_root_ptr_ptr = payload_ptr[2] // stack: new_storage_root_ptr_ptr, new_payload_ptr, storage_root_ptr, storage_ptr_ptr', payload_ptr_ptr, account_ptr_ptr, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 14f193834..3abf4955d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -6,14 +6,14 @@ /// Searching and inserting is done by guessing the predecessor in the list. /// If the address/storage key isn't found in the array, it is inserted at the end. -// Initialize an empty account linked list (@U256_MAX)⮌ +// Initialize an empty account linked list (@U256_MAX) // which is written as [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST // The values at the respective positions are: // - 0: The account key // - 1: A ptr to the payload (the account values) // - 2: A ptr to the intial payload. // - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. -// Initialize also an empty storage linked list (@U256_MAX)⮌ +// Initialize also an empty storage linked list (@U256_MAX) // which is written as [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST // The values at the respective positions are: // - 0: The account key @@ -24,8 +24,8 @@ global init_linked_lists: // stack: (empty) - // Initialize SEGMENT_ACCOUNTS_LINKED_LIST - // Store @U256_MAX at the beggining of the segment + // Initialize SEGMENT_ACCOUNTS_LINKED_LIST. + // Store @U256_MAX at the beginning of the segment. PUSH @SEGMENT_ACCOUNTS_LINKED_LIST // ctx == virt == 0 DUP1 PUSH @U256_MAX @@ -36,12 +36,12 @@ global init_linked_lists: PUSH @SEGMENT_ACCOUNTS_LINKED_LIST MSTORE_GENERAL - // Store the segment scaled length + // Store the segment scaled length. %increment %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) - // Initialize SEGMENT_STORAGE_LINKED_LIST - // Store @U256_MAX at the beggining of the segment + // Initialize SEGMENT_STORAGE_LINKED_LIST. + // Store @U256_MAX at the beginning of the segment. PUSH @SEGMENT_STORAGE_LINKED_LIST // ctx == virt == 0 DUP1 PUSH @U256_MAX @@ -52,7 +52,7 @@ global init_linked_lists: PUSH @SEGMENT_STORAGE_LINKED_LIST MSTORE_GENERAL - // Store the segment scaled length + // Store the segment scaled length. %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) JUMP @@ -73,7 +73,6 @@ global init_linked_lists: /// the accounts, storing a pointer to the copied account in the node. global store_initial_accounts: // stack: retdest - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST %next_account loop_store_initial_accounts: @@ -142,12 +141,12 @@ store_initial_accounts_end: POP %endmacro -// Multiply the value at the top of the stack, denoted by ptr/4, by 4 -// and abort if ptr/4 >= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN]/4 -// In this way 4*ptr/4 must be pointing to the beginning of a node. -// TODO: Maybe we should check here if the node have been deleted. +// Multiplies the value at the top of the stack, denoted by ptr/4, by 4 +// and aborts if ptr/4 >= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN]/4 +// This way, 4*ptr/4 must be pointing to the beginning of a node. +// TODO: Maybe we should check here if the node has been deleted. %macro get_valid_account_ptr - // stack: ptr/4 + // stack: ptr/4 DUP1 PUSH 4 %mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) @@ -160,7 +159,7 @@ store_initial_accounts_end: %endmacro /// Inserts the account addr and payload pointer into the linked list if it is not already present. -/// Return `payload_ptr` if the account was inserted, `original_ptr` if it was already present. +/// Returns `payload_ptr` if the account was inserted, `original_ptr` if it was already present. global insert_account_to_linked_list: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) @@ -310,8 +309,8 @@ account_found_with_overwrite: %endmacro -/// Search the account addr andin the linked list. -/// Return `payload_ptr` if the account was not found, `original_ptr` if it was already present. +/// Searches the account addr andin the linked list. +/// Returns `payload_ptr` if the account was not found, `original_ptr` if it was already present. global search_account: // stack: addr, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) @@ -356,7 +355,7 @@ account_not_found: %%after: %endmacro -/// Remove the address and its value from the access list. +/// Removes the address and its value from the access list. /// Panics if the key is not in the list. global remove_account: // stack: addr, retdest @@ -406,7 +405,6 @@ global remove_account: /// the accounts, storing a pointer to the copied account in the node. global store_initial_slots: // stack: retdest - PUSH @SEGMENT_STORAGE_LINKED_LIST %next_slot @@ -428,7 +426,6 @@ loop_store_initial_slots: DUP2 %add_const(3) SWAP1 -global store_cpy_ptr: MSTORE_GENERAL // Store cpy_ptr %next_slot %jump(loop_store_initial_slots) @@ -450,10 +447,10 @@ store_initial_slots_end: POP %endmacro -// Multiply the value at the top of the stack, denoted by ptr/5, by 5 -// and abort if ptr/5 >= (mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN] - @SEGMENT_STORAGE_LINKED_LIST)/5 -// In this way @SEGMENT_STORAGE_LINKED_LIST + 5*ptr/5 must be pointing to the beginning of a node. -// TODO: Maybe we should check here if the node have been deleted. +// Multiplies the value at the top of the stack, denoted by ptr/5, by 5 +// and aborts if ptr/5 >= (mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN] - @SEGMENT_STORAGE_LINKED_LIST)/5. +// This way, @SEGMENT_STORAGE_LINKED_LIST + 5*ptr/5 must be pointing to the beginning of a node. +// TODO: Maybe we should check here if the node has been deleted. %macro get_valid_slot_ptr // stack: ptr/5 DUP1 @@ -472,8 +469,8 @@ store_initial_slots_end: %endmacro /// Inserts the pair (addres, storage_key) and a new payload pointer into the linked list if it is not already present, -/// or modify its payload if it was already present. -/// Return `new_payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. +/// or modifies its payload if it was already present. +/// Returns `new_payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global insert_slot_with_value: // stack: addr, key, value, retdest PROVER_INPUT(linked_list::insert_slot) @@ -624,8 +621,8 @@ slot_found_write_value: %endmacro /// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present, -/// or modify its payload if it was already present. -/// Return `payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. +/// or modifies its payload if it was already present. +/// Returns `payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global insert_slot: // stack: addr, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) @@ -767,7 +764,7 @@ next_node_ok: %stack (addr, key, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP -/// Search the pair (address, storage_key) in the storage the linked list. +/// Searches the pair (address, storage_key) in the storage the linked list. /// Returns `payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global search_slot: // stack: addr, key, payload_ptr, retdest @@ -837,7 +834,7 @@ slot_found_no_write: %%after: %endmacro -/// Remove the storage key and its value from the list. +/// Removes the storage key and its value from the list. /// Panics if the key is not in the list. global remove_slot: // stack: addr, key, retdest @@ -983,12 +980,3 @@ remove_all_slots_end: MLOAD_GENERAL // stack: next_node_ptr %endmacro - -%macro read_slot_linked_list - // stack: address, slot - %addr_to_state_key - SWAP1 %slot_to_storage_key - %stack (slot_key, addr_key) -> (addr_key, slot_key, 0, %%after) - %jump(search_slot) -%%after: -%endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index aa2c9bf1c..1dc9dc7c3 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -1,6 +1,6 @@ // Given an address, return a pointer to the associated account data, which // consists of four words (nonce, balance, storage_root, code_hash), in the -// trie_data segment. Returns null if the address is not found. +// trie_data segment. Return null if the address is not found. global mpt_read_state_trie: // stack: addr, retdest %read_accounts_linked_list From 6436d12cdab3f983ff531abcb859bf925a720542 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Sat, 13 Jul 2024 12:36:08 -0400 Subject: [PATCH 098/118] Do not store memory content as vec --- .../src/cpu/kernel/tests/mpt/linked_list.rs | 50 ++++++---- .../src/generation/linked_list.rs | 16 +-- .../src/generation/prover_input.rs | 99 ++++++++++--------- 3 files changed, 92 insertions(+), 73 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index d93764e80..90c99b6a1 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -14,6 +14,7 @@ use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; +use crate::generation::linked_list::LinkedList; use crate::memory::segments::Segment::{self, AccessedAddresses, AccessedStorageKeys}; use crate::util::u256_to_usize; use crate::witness::errors::ProgramError; @@ -88,10 +89,12 @@ fn test_list_iterator() -> Result<()> { interpreter.run()?; // test the list iterator - let mut accounts_list = interpreter + let accounts_mem = interpreter .generation_state - .get_accounts_linked_list() - .expect("Since we called init_access_lists there must be an accounts list"); + .memory + .get_preinit_memory(Segment::AccountsLinkedList); + let mut accounts_list = + LinkedList::from_mem_and_segment(&accounts_mem, Segment::AccountsLinkedList).unwrap(); let Some([addr, ptr, ptr_cpy, scaled_pos_1]) = accounts_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); @@ -108,10 +111,12 @@ fn test_list_iterator() -> Result<()> { assert_eq!(ptr_cpy, U256::zero()); assert_eq!(scaled_pos_1, (Segment::AccountsLinkedList as usize).into()); - let mut storage_list = interpreter + let accounts_mem = interpreter .generation_state - .get_storage_linked_list() - .expect("Since we called init_access_lists there must be a storage list"); + .memory + .get_preinit_memory(Segment::StorageLinkedList); + let mut storage_list = + LinkedList::from_mem_and_segment(&accounts_mem, Segment::StorageLinkedList).unwrap(); let Some([addr, key, ptr, ptr_cpy, scaled_pos_1]) = storage_list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); }; @@ -158,10 +163,12 @@ fn test_insert_account() -> Result<()> { interpreter.run()?; assert_eq!(interpreter.stack(), &[payload_ptr]); - let mut list = interpreter + let accounts_mem = interpreter .generation_state - .get_accounts_linked_list() - .expect("Since we called init_access_lists there must be a list"); + .memory + .get_preinit_memory(Segment::AccountsLinkedList); + let mut list = + LinkedList::from_mem_and_segment(&accounts_mem, Segment::AccountsLinkedList).unwrap(); let Some([addr, ptr, ptr_cpy, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); @@ -215,10 +222,12 @@ fn test_insert_storage() -> Result<()> { interpreter.run()?; assert_eq!(interpreter.stack(), &[payload_ptr]); - let mut list = interpreter + let accounts_mem = interpreter .generation_state - .get_storage_linked_list() - .expect("Since we called init_access_lists there must be a list"); + .memory + .get_preinit_memory(Segment::StorageLinkedList); + let mut list = + LinkedList::from_mem_and_segment(&accounts_mem, Segment::StorageLinkedList).unwrap(); let Some([inserted_addr, inserted_key, ptr, ptr_cpy, scaled_next_pos]) = list.next() else { return Err(anyhow::Error::msg("Couldn't get value")); @@ -370,10 +379,12 @@ fn test_insert_and_delete_accounts() -> Result<()> { // the linked list with the interpreter's memory. new_addresses.sort(); - let mut list = interpreter + let accounts_mem = interpreter .generation_state - .get_accounts_linked_list() - .expect("Since we called init_access_lists there must be a list"); + .memory + .get_preinit_memory(Segment::AccountsLinkedList); + let mut list = + LinkedList::from_mem_and_segment(&accounts_mem, Segment::AccountsLinkedList).unwrap(); for (i, [addr, ptr, ptr_cpy, _]) in list.enumerate() { if addr == U256::MAX { @@ -530,14 +541,15 @@ fn test_insert_and_delete_storage() -> Result<()> { // the linked list with the interpreter's memory. new_addresses.sort(); - let mut list = interpreter + let accounts_mem = interpreter .generation_state - .get_storage_linked_list() - .expect("Since we called init_access_lists there must be a list"); + .memory + .get_preinit_memory(Segment::StorageLinkedList); + let mut list = + LinkedList::from_mem_and_segment(&accounts_mem, Segment::StorageLinkedList).unwrap(); for (i, [addr, key, ptr, ptr_cpy, _]) in list.enumerate() { if addr == U256::MAX { - // assert_eq!(addr, U256::MAX); assert_eq!(key, U256::zero()); assert_eq!(ptr, U256::zero()); diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index 0ced29f38..6e8cfb00b 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -27,8 +27,8 @@ use crate::witness::memory::MemoryAddress; // `access_list_mem[i..i + node_size - 1]`, and `access_list_mem[i + node_size - // 1]` holds the address of the next node, where i = node_size * j. #[derive(Clone)] -pub(crate) struct LinkedList { - mem: Vec>, +pub(crate) struct LinkedList<'a, const N: usize> { + mem: &'a [Option], mem_len: usize, offset: usize, pos: usize, @@ -46,16 +46,16 @@ pub(crate) fn empty_list_mem(segment: Segment) -> [U256; N] { }) } -impl LinkedList { +impl<'a, const N: usize> LinkedList<'a, N> { pub fn from_mem_and_segment( - mem: &[Option], + mem: &'a [Option], segment: Segment, ) -> Result { Self::from_mem_len_and_segment(mem, mem.len(), segment) } pub fn from_mem_len_and_segment( - mem: &[Option], + mem: &'a [Option], mem_len: usize, segment: Segment, ) -> Result { @@ -64,7 +64,7 @@ impl LinkedList { } let mem_len = mem.len(); Ok(Self { - mem: mem.to_vec(), + mem, mem_len, offset: segment as usize, pos: 0, @@ -72,7 +72,7 @@ impl LinkedList { } } -impl fmt::Debug for LinkedList { +impl<'a, const N: usize> fmt::Debug for LinkedList<'a, N> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "Linked List {{"); let cloned_list = self.clone(); @@ -87,7 +87,7 @@ impl fmt::Debug for LinkedList { } } -impl Iterator for LinkedList { +impl<'a, const N: usize> Iterator for LinkedList<'a, N> { type Item = [U256; N]; fn next(&mut self) -> Option { diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 07d2eb8db..13abec4bd 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -316,14 +316,6 @@ impl GenerationState { /// Generates either the next used jump address or the proof for the last /// jump address. fn run_linked_list(&mut self, input_fn: &ProverInputFn) -> Result { - self.log( - log::Level::Debug, - format!("account ll = {:?}", self.get_accounts_linked_list()), - ); - self.log( - log::Level::Debug, - format!("storage ll = {:?}", self.get_storage_linked_list()), - ); match input_fn.0[1].as_str() { "insert_account" => self.run_next_insert_account(), "remove_account" => self.run_next_remove_account(), @@ -507,10 +499,17 @@ impl GenerationState { /// `node[0] <= addr < next_node[0]` and `addr` is the top of the stack. fn run_next_insert_account(&self) -> Result { let addr = stack_peek(self, 0)?; - if let Some((([.., pred_ptr], [node_addr, ..]), _)) = self - .get_accounts_linked_list()? - .zip(self.get_accounts_linked_list()?.skip(1)) - .zip(self.get_accounts_linked_list()?.skip(2)) + let accounts_mem = self.memory.get_preinit_memory(Segment::AccountsLinkedList); + let accounts_linked_list = + LinkedList::::from_mem_and_segment( + &accounts_mem, + Segment::AccountsLinkedList, + )?; + + if let Some((([.., pred_ptr], [node_addr, ..]), _)) = accounts_linked_list + .clone() + .zip(accounts_linked_list.clone().skip(1)) + .zip(accounts_linked_list.skip(2)) .find(|&((_, [prev_addr, ..]), [next_addr, ..])| { (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr }) @@ -528,10 +527,17 @@ impl GenerationState { fn run_next_insert_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - if let Some((([.., pred_ptr], _), _)) = self - .get_storage_linked_list()? - .zip(self.get_storage_linked_list()?.skip(1)) - .zip(self.get_storage_linked_list()?.skip(2)) + let storage_mem = self.memory.get_preinit_memory(Segment::StorageLinkedList); + let storage_linked_list = + LinkedList::::from_mem_and_segment( + &storage_mem, + Segment::StorageLinkedList, + )?; + + if let Some((([.., pred_ptr], _), _)) = storage_linked_list + .clone() + .zip(storage_linked_list.clone().skip(1)) + .zip(storage_linked_list.skip(2)) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) @@ -554,9 +560,16 @@ impl GenerationState { /// If the element is not in the list, loops forever. fn run_next_remove_account(&self) -> Result { let addr = stack_peek(self, 0)?; - if let Some(([.., ptr], _)) = self - .get_accounts_linked_list()? - .zip(self.get_accounts_linked_list()?.skip(2)) + let accounts_mem = self.memory.get_preinit_memory(Segment::AccountsLinkedList); + let accounts_linked_list = + LinkedList::::from_mem_and_segment( + &accounts_mem, + Segment::AccountsLinkedList, + )?; + + if let Some(([.., ptr], _)) = accounts_linked_list + .clone() + .zip(accounts_linked_list.skip(2)) .find(|&(_, [next_node_addr, ..])| next_node_addr == addr) { Ok(ptr / ACCOUNTS_LINKED_LIST_NODE_SIZE) @@ -572,9 +585,16 @@ impl GenerationState { fn run_next_remove_slot(&self) -> Result { let addr = stack_peek(self, 0)?; let key = stack_peek(self, 1)?; - if let Some(([.., ptr], _)) = self - .get_storage_linked_list()? - .zip(self.get_storage_linked_list()?.skip(2)) + let storage_mem = self.memory.get_preinit_memory(Segment::StorageLinkedList); + let storage_linked_list = + LinkedList::::from_mem_and_segment( + &storage_mem, + Segment::StorageLinkedList, + )?; + + if let Some(([.., ptr], _)) = storage_linked_list + .clone() + .zip(storage_linked_list.skip(2)) .find(|&(_, [next_addr, next_key, ..])| next_addr == addr && next_key == key) { Ok((ptr - U256::from(Segment::StorageLinkedList as usize)) @@ -592,10 +612,17 @@ impl GenerationState { /// stack. fn run_next_remove_address_slots(&self) -> Result { let addr = stack_peek(self, 0)?; - if let Some((([.., pred_ptr], _), _)) = self - .get_storage_linked_list()? - .zip(self.get_storage_linked_list()?.skip(1)) - .zip(self.get_storage_linked_list()?.skip(2)) + let storage_mem = self.memory.get_preinit_memory(Segment::StorageLinkedList); + let storage_linked_list = + LinkedList::::from_mem_and_segment( + &storage_mem, + Segment::StorageLinkedList, + )?; + + if let Some((([.., pred_ptr], _), _)) = storage_linked_list + .clone() + .zip(storage_linked_list.clone().skip(1)) + .zip(storage_linked_list.skip(2)) .find( |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { let prev_is_less = (prev_addr < addr || prev_addr == U256::MAX); @@ -707,26 +734,6 @@ impl GenerationState { ) } - pub(crate) fn get_accounts_linked_list( - &self, - ) -> Result, ProgramError> { - // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next - // available virtual address in the segment. In order to get the length, - // we need to substract `Segment::AccountsLinkedList` as usize. - let accounts_mem = self.memory.get_preinit_memory(Segment::AccountsLinkedList); - LinkedList::from_mem_and_segment(&accounts_mem, Segment::AccountsLinkedList) - } - - pub(crate) fn get_storage_linked_list( - &self, - ) -> Result, ProgramError> { - // `GlobalMetadata::AccountsLinkedListLen` stores the value of the next - // available virtual address in the segment. In order to get the length, - // we need to substract `Segment::StorageLinkedList` as usize. - let storage_mem = self.memory.get_preinit_memory(Segment::StorageLinkedList); - LinkedList::from_mem_and_segment(&storage_mem, Segment::StorageLinkedList) - } - fn get_global_metadata(&self, data: GlobalMetadata) -> U256 { self.memory.get_with_init(MemoryAddress::new( 0, From dcf05754c982c5b7f0e6a031a205897062a333d4 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Sat, 13 Jul 2024 16:03:56 -0400 Subject: [PATCH 099/118] Prevent needless conversion --- .../src/cpu/kernel/interpreter.rs | 4 +- .../src/cpu/kernel/tests/account_code.rs | 4 +- .../src/generation/linked_list.rs | 8 ++-- evm_arithmetization/src/generation/mpt.rs | 43 +++++++++++-------- evm_arithmetization/src/generation/state.rs | 4 +- 5 files changed, 35 insertions(+), 28 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index 325419f4a..aa842bdb3 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -274,10 +274,10 @@ impl Interpreter { // Initialize the `TrieData` segment. let preinit_trie_data_segment = MemorySegmentState { content: trie_data }; let preinit_accounts_ll_segment = MemorySegmentState { - content: state_leaves.iter().map(|&val| Some(val)).collect(), + content: state_leaves, }; let preinit_storage_ll_segment = MemorySegmentState { - content: storage_leaves.iter().map(|&val| Some(val)).collect(), + content: storage_leaves, }; self.insert_preinitialized_segment(Segment::TrieData, preinit_trie_data_segment); self.insert_preinitialized_segment( diff --git a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs index 1e5d93786..2d3e5f0ad 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/account_code.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/account_code.rs @@ -35,10 +35,10 @@ pub(crate) fn initialize_mpts( interpreter.generation_state.memory.contexts[0].segments [Segment::AccountsLinkedList.unscale()] - .content = state_leaves.iter().map(|&val| Some(val)).collect(); + .content = state_leaves; interpreter.generation_state.memory.contexts[0].segments [Segment::StorageLinkedList.unscale()] - .content = storage_leaves.iter().map(|&val| Some(val)).collect(); + .content = storage_leaves; interpreter.generation_state.memory.contexts[0].segments[Segment::TrieData.unscale()].content = trie_data.clone(); interpreter.generation_state.trie_root_ptrs = trie_root_ptrs.clone(); diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index 6e8cfb00b..f5fe42d07 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -34,14 +34,14 @@ pub(crate) struct LinkedList<'a, const N: usize> { pos: usize, } -pub(crate) fn empty_list_mem(segment: Segment) -> [U256; N] { +pub(crate) fn empty_list_mem(segment: Segment) -> [Option; N] { std::array::from_fn(|i| { if i == 0 { - U256::MAX + Some(U256::MAX) } else if i == N - 1 { - (segment as usize).into() + Some((segment as usize).into()) } else { - U256::zero() + Some(U256::zero()) } }) } diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index cadb89e5b..1acebddbf 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -315,8 +315,8 @@ fn load_state_trie( fn get_state_and_storage_leaves( trie: &HashedPartialTrie, key: Nibbles, - state_leaves: &mut Vec, - storage_leaves: &mut Vec, + state_leaves: &mut Vec>, + storage_leaves: &mut Vec>, trie_data: &mut Vec>, storage_tries_by_state_key: &HashMap, ) -> Result<(), ProgramError> { @@ -384,19 +384,20 @@ associated storage trie hash" // The last leaf must point to the new one. let len = state_leaves.len(); - state_leaves[len - 1] = - U256::from(Segment::AccountsLinkedList as usize + state_leaves.len()); + state_leaves[len - 1] = Some(U256::from( + Segment::AccountsLinkedList as usize + state_leaves.len(), + )); // The nibbles are the address. let address = merged_key .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?; - state_leaves.push(address); + state_leaves.push(Some(address)); // Set `value_ptr_ptr`. - state_leaves.push(trie_data.len().into()); + state_leaves.push(Some(trie_data.len().into())); // Set counter. - state_leaves.push(0.into()); + state_leaves.push(Some(0.into())); // Set the next node as the inital node. - state_leaves.push((Segment::AccountsLinkedList as usize).into()); + state_leaves.push(Some((Segment::AccountsLinkedList as usize).into())); // Push the payload in the trie data. trie_data.push(Some(nonce)); @@ -423,7 +424,7 @@ pub(crate) fn get_storage_leaves( address: U256, key: Nibbles, trie: &HashedPartialTrie, - storage_leaves: &mut Vec, + storage_leaves: &mut Vec>, trie_data: &mut Vec>, parse_value: &F, ) -> Result<(), ProgramError> @@ -468,22 +469,23 @@ where // The last leaf must point to the new one. let len = storage_leaves.len(); let merged_key = key.merge_nibbles(nibbles); - storage_leaves[len - 1] = - U256::from(Segment::StorageLinkedList as usize + storage_leaves.len()); + storage_leaves[len - 1] = Some(U256::from( + Segment::StorageLinkedList as usize + storage_leaves.len(), + )); // Write the address. - storage_leaves.push(address); + storage_leaves.push(Some(address)); // Write the key. - storage_leaves.push( + storage_leaves.push(Some( merged_key .try_into() .map_err(|_| ProgramError::IntegerTooLarge)?, - ); + )); // Write `value_ptr_ptr`. - storage_leaves.push((trie_data.len()).into()); + storage_leaves.push(Some((trie_data.len()).into())); // Write the counter. - storage_leaves.push(0.into()); + storage_leaves.push(Some(0.into())); // Set the next node as the inital node. - storage_leaves.push((Segment::StorageLinkedList as usize).into()); + storage_leaves.push(Some((Segment::StorageLinkedList as usize).into())); let leaf = parse_value(value)?.into_iter().map(Some); trie_data.extend(leaf); @@ -499,7 +501,12 @@ where /// - the vector of state trie leaves /// - the vector of storage trie leaves /// - the `TrieData` segment's memory content -type TriePtrsLinkedLists = (TrieRootPtrs, Vec, Vec, Vec>); +type TriePtrsLinkedLists = ( + TrieRootPtrs, + Vec>, + Vec>, + Vec>, +); pub(crate) fn load_linked_lists_and_txn_and_receipt_mpts( trie_inputs: &TrieInputs, diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index 61dfa5d6f..eb885dcb9 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -388,13 +388,13 @@ impl GenerationState { self.memory.insert_preinitialized_segment( Segment::AccountsLinkedList, crate::witness::memory::MemorySegmentState { - content: state_leaves.iter().map(|&val| Some(val)).collect(), + content: state_leaves, }, ); self.memory.insert_preinitialized_segment( Segment::StorageLinkedList, crate::witness::memory::MemorySegmentState { - content: storage_leaves.iter().map(|&val| Some(val)).collect(), + content: storage_leaves, }, ); self.memory.insert_preinitialized_segment( From 97b21afbfcf9840ac4dc44c7fc37f669a3504776 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Sat, 13 Jul 2024 16:11:43 -0400 Subject: [PATCH 100/118] Remove needless copy --- evm_arithmetization/src/generation/state.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/evm_arithmetization/src/generation/state.rs b/evm_arithmetization/src/generation/state.rs index eb885dcb9..f33d37581 100644 --- a/evm_arithmetization/src/generation/state.rs +++ b/evm_arithmetization/src/generation/state.rs @@ -184,7 +184,6 @@ pub(crate) trait State { max_cpu_len_log.map(|max_len_log| (1 << max_len_log) - NUM_EXTRA_CYCLES_AFTER); let mut final_registers = RegistersState::default(); - let final_mem = self.get_active_memory(); let mut running = true; let mut final_clock = 0; loop { From 94a61e7e3575076dc76b95087758b0f69743e626 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Sat, 13 Jul 2024 17:30:29 -0400 Subject: [PATCH 101/118] Remove needless checks --- .../src/cpu/kernel/interpreter.rs | 33 ++++--------------- evm_arithmetization/src/witness/memory.rs | 14 +++++--- 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index aa842bdb3..eefbce825 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -143,16 +143,10 @@ pub(crate) fn set_registers_and_run( .iter() .enumerate() .for_each(|(i, reg_content)| { - let (addr, val) = ( - MemoryAddress::new_u256s( - 0.into(), - (Segment::RegistersStates.unscale()).into(), - i.into(), - ) - .expect("All input values are known to be valid for MemoryAddress"), + interpreter.generation_state.memory.set( + MemoryAddress::new(0, Segment::RegistersStates, i), *reg_content, - ); - interpreter.generation_state.memory.set(addr, val); + ) }); interpreter.run() @@ -355,12 +349,7 @@ impl Interpreter { let final_block_bloom_fields = (0..8) .map(|i| { ( - MemoryAddress::new_u256s( - U256::zero(), - (Segment::GlobalBlockBloom.unscale()).into(), - i.into(), - ) - .expect("This cannot panic as `virt` fits in a `u32`"), + MemoryAddress::new(0, Segment::GlobalBlockBloom, i), metadata.block_bloom[i], ) }) @@ -372,12 +361,7 @@ impl Interpreter { let block_hashes_fields = (0..256) .map(|i| { ( - MemoryAddress::new_u256s( - U256::zero(), - (Segment::BlockHashes.unscale()).into(), - i.into(), - ) - .expect("This cannot panic as `virt` fits in a `u32`"), + MemoryAddress::new(0, Segment::BlockHashes, i), h2u(inputs.block_hashes.prev_hashes[i]), ) }) @@ -397,12 +381,7 @@ impl Interpreter { let registers_before_fields = (0..registers_before.len()) .map(|i| { ( - MemoryAddress::new_u256s( - 0.into(), - (Segment::RegistersStates.unscale()).into(), - i.into(), - ) - .unwrap(), + MemoryAddress::new(0, Segment::RegistersStates, i), registers_before[i], ) }) diff --git a/evm_arithmetization/src/witness/memory.rs b/evm_arithmetization/src/witness/memory.rs index 16ea7e5ac..e69e75f96 100644 --- a/evm_arithmetization/src/witness/memory.rs +++ b/evm_arithmetization/src/witness/memory.rs @@ -79,11 +79,17 @@ impl MemoryAddress { /// It will recover the virtual offset as the lowest 32-bit limb, the /// segment as the next limb, and the context as the next one. pub(crate) fn new_bundle(addr: U256) -> Result { - let virt = addr.low_u32().into(); - let segment = (addr >> SEGMENT_SCALING_FACTOR).low_u32().into(); - let context = (addr >> CONTEXT_SCALING_FACTOR).low_u32().into(); + let virt = addr.low_u32() as usize; + let segment = (addr >> SEGMENT_SCALING_FACTOR).low_u32() as usize; + let context = (addr >> CONTEXT_SCALING_FACTOR).low_u32() as usize; + + if segment >= Segment::COUNT { + return Err(MemoryError(SegmentTooLarge { + segment: segment.into(), + })); + } - Self::new_u256s(context, segment, virt) + Ok(Self::new(context, Segment::all()[segment], virt)) } pub(crate) fn increment(&mut self) { From 3c915f30ddb5f17556214bc55d4e9eeb4851bc30 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Sat, 13 Jul 2024 18:36:08 -0400 Subject: [PATCH 102/118] Use tuple_windows instead --- .../src/generation/linked_list.rs | 6 +- .../src/generation/prover_input.rs | 64 ++++++++----------- 2 files changed, 27 insertions(+), 43 deletions(-) diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index f5fe42d07..02825d00e 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -51,21 +51,19 @@ impl<'a, const N: usize> LinkedList<'a, N> { mem: &'a [Option], segment: Segment, ) -> Result { - Self::from_mem_len_and_segment(mem, mem.len(), segment) + Self::from_mem_len_and_segment(mem, segment) } pub fn from_mem_len_and_segment( mem: &'a [Option], - mem_len: usize, segment: Segment, ) -> Result { if mem.is_empty() { return Err(ProgramError::ProverInputError(InvalidInput)); } - let mem_len = mem.len(); Ok(Self { mem, - mem_len, + mem_len: mem.len(), offset: segment as usize, pos: 0, }) diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 13abec4bd..3216ac61d 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -506,11 +506,9 @@ impl GenerationState { Segment::AccountsLinkedList, )?; - if let Some((([.., pred_ptr], [node_addr, ..]), _)) = accounts_linked_list - .clone() - .zip(accounts_linked_list.clone().skip(1)) - .zip(accounts_linked_list.skip(2)) - .find(|&((_, [prev_addr, ..]), [next_addr, ..])| { + if let Some(([.., pred_ptr], [node_addr, ..], _)) = accounts_linked_list + .tuple_windows() + .find(|&(_, [prev_addr, ..], [next_addr, ..])| { (prev_addr <= addr || prev_addr == U256::MAX) && addr < next_addr }) { @@ -534,20 +532,15 @@ impl GenerationState { Segment::StorageLinkedList, )?; - if let Some((([.., pred_ptr], _), _)) = storage_linked_list - .clone() - .zip(storage_linked_list.clone().skip(1)) - .zip(storage_linked_list.skip(2)) - .find( - |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) - || (prev_addr == addr && prev_key <= key); - let next_is_strictly_larger = - next_addr > addr || (next_addr == addr && next_key > key); - prev_is_less_or_equal && next_is_strictly_larger - }, - ) - { + if let Some(([.., pred_ptr], _, _)) = storage_linked_list.tuple_windows().find( + |&(_, [prev_addr, prev_key, ..], [next_addr, next_key, ..])| { + let prev_is_less_or_equal = (prev_addr < addr || prev_addr == U256::MAX) + || (prev_addr == addr && prev_key <= key); + let next_is_strictly_larger = + next_addr > addr || (next_addr == addr && next_key > key); + prev_is_less_or_equal && next_is_strictly_larger + }, + ) { Ok((pred_ptr - U256::from(Segment::StorageLinkedList as usize)) / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) } else { @@ -567,10 +560,9 @@ impl GenerationState { Segment::AccountsLinkedList, )?; - if let Some(([.., ptr], _)) = accounts_linked_list - .clone() - .zip(accounts_linked_list.skip(2)) - .find(|&(_, [next_node_addr, ..])| next_node_addr == addr) + if let Some(([.., ptr], _, _)) = accounts_linked_list + .tuple_windows() + .find(|&(_, _, [next_node_addr, ..])| next_node_addr == addr) { Ok(ptr / ACCOUNTS_LINKED_LIST_NODE_SIZE) } else { @@ -592,10 +584,9 @@ impl GenerationState { Segment::StorageLinkedList, )?; - if let Some(([.., ptr], _)) = storage_linked_list - .clone() - .zip(storage_linked_list.skip(2)) - .find(|&(_, [next_addr, next_key, ..])| next_addr == addr && next_key == key) + if let Some(([.., ptr], _, _)) = storage_linked_list + .tuple_windows() + .find(|&(_, _, [next_addr, next_key, ..])| next_addr == addr && next_key == key) { Ok((ptr - U256::from(Segment::StorageLinkedList as usize)) / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) @@ -619,18 +610,13 @@ impl GenerationState { Segment::StorageLinkedList, )?; - if let Some((([.., pred_ptr], _), _)) = storage_linked_list - .clone() - .zip(storage_linked_list.clone().skip(1)) - .zip(storage_linked_list.skip(2)) - .find( - |&((_, [prev_addr, prev_key, ..]), [next_addr, next_key, ..])| { - let prev_is_less = (prev_addr < addr || prev_addr == U256::MAX); - let next_is_larger_or_equal = next_addr >= addr; - prev_is_less && next_is_larger_or_equal - }, - ) - { + if let Some(([.., pred_ptr], _, _)) = storage_linked_list.tuple_windows().find( + |&(_, [prev_addr, prev_key, ..], [next_addr, next_key, ..])| { + let prev_is_less = (prev_addr < addr || prev_addr == U256::MAX); + let next_is_larger_or_equal = next_addr >= addr; + prev_is_less && next_is_larger_or_equal + }, + ) { Ok((pred_ptr - U256::from(Segment::StorageLinkedList as usize)) / U256::from(STORAGE_LINKED_LIST_NODE_SIZE)) } else { From 526c45646a446465fa158eddefc746c00891bf49 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Sun, 14 Jul 2024 13:10:55 -0400 Subject: [PATCH 103/118] Typo --- evm_arithmetization/src/generation/linked_list.rs | 2 +- evm_arithmetization/src/generation/prover_input.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/generation/linked_list.rs b/evm_arithmetization/src/generation/linked_list.rs index 02825d00e..d72cf3340 100644 --- a/evm_arithmetization/src/generation/linked_list.rs +++ b/evm_arithmetization/src/generation/linked_list.rs @@ -15,7 +15,7 @@ use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::KERNEL; use crate::cpu::kernel::constants::global_metadata::GlobalMetadata; use crate::cpu::kernel::interpreter::Interpreter; -use crate::memory::segments::Segment::{self, AccessedAddresses, AccessedStorageKeys}; +use crate::memory::segments::Segment; use crate::util::u256_to_usize; use crate::witness::errors::ProgramError; use crate::witness::errors::ProverInputError; diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 3216ac61d..e68d1bf15 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -39,7 +39,7 @@ use crate::witness::util::{current_context_peek, stack_peek}; #[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize)] pub struct ProverInputFn(Vec); -pub const ADRESSSES_ACCESS_LIST_LEN: usize = 2; +pub const ADDRESSES_ACCESS_LIST_LEN: usize = 2; pub const STORAGE_KEYS_ACCESS_LIST_LEN: usize = 4; pub const ACCOUNTS_LINKED_LIST_NODE_SIZE: usize = 4; pub const STORAGE_LINKED_LIST_NODE_SIZE: usize = 5; @@ -707,7 +707,7 @@ impl GenerationState { pub(crate) fn get_addresses_access_list( &self, - ) -> Result, ProgramError> { + ) -> Result, ProgramError> { // `GlobalMetadata::AccessedAddressesLen` stores the value of the next available // virtual address in the segment. In order to get the length we need // to substract `Segment::AccessedAddresses` as usize. From b992e9effaa816588c47eba1dc2297e8a1702a18 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Tue, 16 Jul 2024 09:11:52 -0400 Subject: [PATCH 104/118] Remove leftover --- zero_bin/prover/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zero_bin/prover/src/lib.rs b/zero_bin/prover/src/lib.rs index aa5367dc0..f22a5290f 100644 --- a/zero_bin/prover/src/lib.rs +++ b/zero_bin/prover/src/lib.rs @@ -47,7 +47,6 @@ impl BlockProverInput { use paladin::directive::{Directive, IndexedStream}; let block_number = self.get_block_number(); - info!("Proving block {block_number}"); let other_data = self.other_data; let txs = self.block_trace.into_txn_proof_gen_ir( From d9840d4bb5fc9d9e9a19b7278ea6d34eead13bd3 Mon Sep 17 00:00:00 2001 From: Robin Salen Date: Tue, 16 Jul 2024 10:23:48 -0400 Subject: [PATCH 105/118] Remove unrelated changes --- Cargo.lock | 1 - .../src/cpu/kernel/asm/core/access_lists.asm | 1 - .../src/cpu/kernel/asm/core/nonce.asm | 3 +-- .../src/cpu/kernel/asm/core/process_txn.asm | 3 +-- .../src/cpu/kernel/asm/journal/account_destroyed.asm | 5 +++-- evm_arithmetization/src/cpu/kernel/asm/main.asm | 12 ++++-------- .../src/cpu/kernel/asm/mpt/delete/delete.asm | 1 - .../src/cpu/kernel/asm/mpt/hash/hash.asm | 1 - .../src/cpu/kernel/asm/mpt/storage/storage_read.asm | 8 -------- .../cpu/kernel/asm/transactions/common_decoding.asm | 3 +-- evm_arithmetization/tests/erc721.rs | 1 - trace_decoder/Cargo.toml | 3 --- 12 files changed, 10 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cb62deaf7..4c1f122b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5109,7 +5109,6 @@ dependencies = [ "keccak-hash 0.10.0", "log", "mpt_trie", - "plonky2", "pretty_env_logger", "rlp", "serde", diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm index fea9c2ebf..552cbc7d8 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm @@ -274,7 +274,6 @@ global insert_accessed_storage_keys: %jump_neq_const(@U256_MAX, storage_key_found) // The storage key is not in the list. PANIC - storage_key_found: // The address was already in the list // stack: pred_ptr, addr, key, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm b/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm index dd763f08f..48486be9e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/nonce.asm @@ -27,8 +27,7 @@ global increment_nonce: // stack: account_ptr, address, retdest DUP1 ISZERO %jumpi(increment_nonce_no_such_account) // stack: nonce_ptr, address, retdest - DUP1 - %mload_trie_data + DUP1 %mload_trie_data // stack: nonce, nonce_ptr, address, retdest DUP1 DUP4 %journal_add_nonce_change // stack: nonce, nonce_ptr, address, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm index 28932f80b..e457c34b1 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/process_txn.asm @@ -36,8 +36,7 @@ global process_normalized_txn: // stack: sender, retdest // Assert sender has no code. - DUP1 %ext_code_empty - %assert_nonzero(invalid_txn_1) + DUP1 %ext_code_empty %assert_nonzero(invalid_txn_1) // stack: sender, retdest // Assert sender balance >= gas_limit * gas_price + value. diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index d5dd70f81..63679455b 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -22,7 +22,8 @@ revert_account_destroyed_contd: %assert_nonzero %add_const(1) // stack: target_balance_ptr, address, prev_balance, retdest - DUP3 DUP2 %mload_trie_data + DUP3 + DUP2 %mload_trie_data // stack: target_balance, prev_balance, target_balance_ptr, address, prev_balance, retdest SUB SWAP1 %mstore_trie_data // stack: address, prev_balance, retdest @@ -33,4 +34,4 @@ revert_account_destroyed_contd: // stack: account_balance_payload_ptr, prev_balance, retdest %mstore_trie_data JUMP - + diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index a03050fe0..6bb3d94af 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -157,12 +157,9 @@ global execute_withdrawals: global perform_final_checks: // stack: cum_gas, txn_counter, num_nibbles, txn_nb // Check that we end up with the correct `cum_gas`, `txn_nb` and bloom filter. - %mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_AFTER) - %assert_eq - - - DUP3 %mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_AFTER) - %assert_eq + %mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_AFTER) %assert_eq + DUP3 + %mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_AFTER) %assert_eq %pop3 PROVER_INPUT(trie_ptr::state) @@ -180,8 +177,7 @@ global perform_final_checks: global check_state_trie: %set_final_tries - %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) - %assert_eq + %mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) %assert_eq global check_txn_trie: %mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq global check_receipt_trie: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm index 6fb4f4162..ffef18bbf 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/delete/delete.asm @@ -15,7 +15,6 @@ global mpt_delete: DUP1 %eq_const(@MPT_NODE_EXTENSION) %jumpi(mpt_delete_extension) DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(mpt_delete_leaf) %eq_const(@MPT_NODE_EMPTY) %jumpi(panic) // This should never happen. - PANIC mpt_delete_leaf: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm index 652b9f22f..e2c460d1a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/hash/hash.asm @@ -74,7 +74,6 @@ global encode_or_hash_node: SWAP2 %add_const(2) %stack (cur_len, encode_value, hash, retdest) -> (retdest, hash, 32, cur_len) JUMP - encode_or_hash_concrete_node: %stack (node_type, node_ptr, encode_value, cur_len) -> (node_type, node_ptr, encode_value, cur_len, maybe_hash_node) %jump(encode_node) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm index 983b2ac43..d4a7ca36a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_read.asm @@ -12,14 +12,6 @@ global sload_current: // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. %stack (value_ptr, retdest) -> (retdest, 0) - - JUMP - -storage_key_exists: - // stack: value_ptr, retdest - %mload_trie_data - // stack: value, retdest - SWAP1 JUMP // Read a word from the current account's storage trie. diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm index c9ce645d4..49caffe87 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm @@ -253,10 +253,9 @@ sload_with_addr: // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. %stack (value_ptr, retdest) -> (retdest, 0) - JUMP -storage_key_exists: +global storage_key_exists: // stack: value_ptr, retdest %mload_trie_data // stack: value, retdest diff --git a/evm_arithmetization/tests/erc721.rs b/evm_arithmetization/tests/erc721.rs index 49df40747..53a05e365 100644 --- a/evm_arithmetization/tests/erc721.rs +++ b/evm_arithmetization/tests/erc721.rs @@ -177,7 +177,6 @@ fn test_erc721() -> anyhow::Result<()> { }; let max_cpu_len_log = 20; - let mut timing = TimingTree::new("prove", log::Level::Debug); let proofs = prove_all_segments::( diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 75d21b804..0155e8126 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -21,9 +21,6 @@ rlp = { workspace = true } serde = { workspace = true } serde_with = { workspace = true } thiserror = { workspace = true } -serde_json = { workspace = true } -plonky2 = { workspace = true } - # Local dependencies mpt_trie = { workspace = true } From b0c4248f8cccfc90780f765863b821bf7e22e684 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 16 Jul 2024 16:43:21 +0100 Subject: [PATCH 106/118] Fix clone_slot --- .../src/cpu/kernel/asm/mpt/accounts.asm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm index e80dea021..d9a905e65 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm @@ -47,15 +47,15 @@ // stack: cloned_account_ptr %endmacro +// The slot_ptr cannot be 0, because `insert_slot` +// is only called in `revert_storage_change` (where the case `slot_ptr = 0` +// is dealt with differently), and in `storage_write`, +// where writing 0 actually corresponds to a `delete`. %macro clone_slot // stack: slot_ptr - DUP1 - %jumpi(%%non_zero_ptr) - %jump(%%avoid_clonning_zero_ptr) -%%non_zero_ptr: + DUP1 %assert_nonzero %get_trie_data_size -%%avoid_clonning_zero_ptr: - // stack: cloned_slot_ptr + // stack: cloned_slot_ptr, slot_ptr SWAP1 %mload_trie_data %append_to_trie_data From 80212ae7b28bdbcb26fce7a8583c219354d6f0ab Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 16 Jul 2024 17:35:54 +0100 Subject: [PATCH 107/118] Remove assert 0 from clone_slot --- evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm | 1 - 1 file changed, 1 deletion(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm index d9a905e65..7a9d76541 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm @@ -53,7 +53,6 @@ // where writing 0 actually corresponds to a `delete`. %macro clone_slot // stack: slot_ptr - DUP1 %assert_nonzero %get_trie_data_size // stack: cloned_slot_ptr, slot_ptr SWAP1 From 7445d5333c63a0a7c91a612f47008e371671ce52 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 16 Jul 2024 18:32:51 +0100 Subject: [PATCH 108/118] Fix next_node_ok_with_value --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 3abf4955d..f706aeb21 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -583,14 +583,14 @@ next_node_ok_with_value: %append_to_trie_data MSTORE_GENERAL - // stack: new_ptr + 2, next_ptr, addr, key, new_payload_ptr, retdest + // stack: new_ptr + 2, next_ptr, new_payload_ptr, retdest // Store the payload ptr copy %increment DUP1 - DUP6 + DUP4 %clone_slot MSTORE_GENERAL - // stack: new_ptr + 3, next_ptr, addr, key, new_payload_ptr, retdest + // stack: new_ptr + 3, next_ptr, new_payload_ptr, retdest %increment DUP1 // stack: new_next_ptr, new_next_ptr, next_ptr, retdest, new_payload_ptr From b46da0e2be781ba9996187b859a79036fee4e743 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 18 Jul 2024 11:43:36 +0100 Subject: [PATCH 109/118] Apply comments and cleanup --- .../src/cpu/kernel/asm/core/access_lists.asm | 12 +-- .../src/cpu/kernel/asm/core/util.asm | 6 ++ .../src/cpu/kernel/asm/mpt/accounts.asm | 2 +- .../asm/mpt/linked_list/final_tries.asm | 16 ++-- .../asm/mpt/linked_list/initial_tries.asm | 4 +- .../asm/mpt/linked_list/linked_list.asm | 75 +++++++++---------- .../kernel/asm/mpt/storage/storage_write.asm | 8 +- .../src/cpu/kernel/constants/mod.rs | 12 +++ .../src/cpu/kernel/tests/receipt.rs | 6 +- .../src/generation/trie_extractor.rs | 5 +- 10 files changed, 83 insertions(+), 63 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm index 552cbc7d8..d54d63a39 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/access_lists.asm @@ -21,8 +21,7 @@ global init_access_lists: // Store @U256_MAX at the beginning of the segment PUSH @SEGMENT_ACCESSED_ADDRESSES // ctx == virt == 0 DUP1 - PUSH @U256_MAX - MSTORE_GENERAL + %mstore_u256_max // Store @SEGMENT_ACCESSED_ADDRESSES at address 1 %increment DUP1 @@ -38,8 +37,7 @@ global init_access_lists: // Store @U256_MAX at the beginning of the segment PUSH @SEGMENT_ACCESSED_STORAGE_KEYS // ctx == virt == 0 DUP1 - PUSH @U256_MAX - MSTORE_GENERAL + %mstore_u256_max // Store @SEGMENT_ACCESSED_STORAGE_KEYS at address 3 %add_const(3) DUP1 @@ -201,8 +199,7 @@ global remove_accessed_addresses: MLOAD_GENERAL // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, retdest SWAP1 - PUSH @U256_MAX - MSTORE_GENERAL + %mstore_u256_max // stack: next_next_ptr, next_ptr_ptr, addr, retdest MSTORE_GENERAL POP @@ -385,8 +382,7 @@ global remove_accessed_storage_keys: MLOAD_GENERAL // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest SWAP1 - PUSH @U256_MAX - MSTORE_GENERAL + %mstore_u256_max // stack: next_next_ptr, next_ptr_ptr, addr, key, retdest MSTORE_GENERAL %pop2 diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/util.asm b/evm_arithmetization/src/cpu/kernel/asm/core/util.asm index df1c53396..545354720 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/util.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/util.asm @@ -93,3 +93,9 @@ SET_CONTEXT // stack: (empty) %endmacro + +%macro mstore_u256_max + // stack (empty) + PUSH @U256_MAX + MSTORE_GENERAL +%endmacro \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm index 7a9d76541..06fb26c2c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/accounts.asm @@ -23,7 +23,7 @@ %macro clone_account // stack: account_ptr %get_trie_data_size - // stack: cloned_accouint_ptr + // stack: cloned_account_ptr SWAP1 DUP1 // Balance diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index bc8ebb106..fb91cc17d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -131,7 +131,7 @@ after_delete_removed_slots: %mstore_trie_data // stack: storage_ptr_ptr', account_ptr_ptr, root_ptr, retdest SWAP1 - %add_const(4) // The next account in memory + %add_const(@ACCOUNTS_LINKED_LISTS_NODE_SIZE) // The next account in memory // stack: account_ptr_ptr', storage_ptr_ptr', root_ptr, retdest SWAP1 SWAP2 SWAP1 %jump(delete_removed_accounts) @@ -151,7 +151,7 @@ delete_account: after_mpt_delete: // stack: root_ptr', account_ptr_ptr, storage_ptr_ptr, retdest SWAP1 - %add_const(4) + %add_const(@ACCOUNTS_LINKED_LISTS_NODE_SIZE) %jump(delete_removed_accounts) // Delete all slots in `storage_ptr_ptr` with address == `addr` and @@ -165,11 +165,13 @@ delete_removed_slots: // stack: address, addr, root_ptr, storage_ptr_ptr, retdest DUP2 EQ + // stack: loaded_address == addr, addr, root_ptr, storage_ptr_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) DUP5 LT MUL // AND - // jump if we either change the address or reach the en of the initial linked list + // stack: loaded_address == addr AND storage_ptr_ptr < GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN, addr, root_ptr, storage_ptr_ptr, retdest + // jump if we either change the address or reach the end of the initial linked list %jumpi(maybe_delete_this_slot) // If we are here we have deleted all the slots for this key %stack (addr, root_ptr, storage_ptr_ptr, retdest) -> (retdest, root_ptr, storage_ptr_ptr) @@ -183,7 +185,7 @@ maybe_delete_this_slot: // The slot was not deleted, so we skip it. // stack: addr, root_ptr, storage_ptr_ptr, retdest SWAP2 - %add_const(5) + %add_const(@STORAGE_LINKED_LISTS_NODE_SIZE) SWAP2 %jump(delete_removed_slots) delete_this_slot: @@ -196,17 +198,17 @@ delete_this_slot: after_mpt_delete_slot: // stack: root_ptr', addr, storage_ptr_ptr SWAP2 - %add_const(5) + %add_const(@STORAGE_LINKED_LISTS_NODE_SIZE) %stack (storage_ptr_ptr_p, addr, root_ptr_p) -> (addr, root_ptr_p, storage_ptr_ptr_p) %jump(delete_removed_slots) global set_final_tries: PUSH set_final_tries_after PUSH @SEGMENT_STORAGE_LINKED_LIST - %add_const(5) // Skip the first node. + %add_const(@STORAGE_LINKED_LISTS_NODE_SIZE) // Skip the first node. %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - %add_const(4) // Skip the first node. + %add_const(@ACCOUNTS_LINKED_LISTS_NODE_SIZE) // Skip the first node. %jump(delete_removed_accounts) set_final_tries_after: // stack: new_state_root diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index fd4d529f0..cebcd1290 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -165,7 +165,7 @@ after_set_storage_payload: %mstore_trie_data // The dynamic account pointer in the linked list has no storage root so we need to manually set it. %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. // stack: account_ptr_ptr, storage_ptr_ptr', retdest - %add_const(4) // The next pointer is at distance 4 + %add_const(@STORAGE_NEXT_NODE_PTR) // The next pointer is at distance `STORAGE_NEXT_NODE_PTR` // stack: payload_ptr_ptr', storage_ptr_ptr', retdest SWAP1 SWAP2 @@ -181,7 +181,7 @@ set_payload_storage_leaf: SWAP1 %mstore_trie_data // stack: storage_ptr_ptr, retdest - %add_const(5) // The next pointer is at distance 5 + %add_const(@STORAGE_LINKED_LISTS_NODE_SIZE) // The next pointer is at distance `STORAGE_LINKED_LISTS_NODE_SIZE` // stack: storage_ptr_ptr', retdest SWAP1 JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index f706aeb21..582014324 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -1,10 +1,13 @@ -/// Access lists for addresses and storage keys. -/// The access list is stored in a sorted linked list in SEGMENT_ACCESSED_ADDRESSES for addresses and -/// SEGMENT_ACCESSED_STORAGE_KEYS segment for storage keys. The length of -/// the segments is stored in the global metadata. +/// Linked lists for accounts and storage slots. +/// The accounts linked list is stored in SEGMENT_ACCOUNTS_LINKED_LIST while the slots +/// are stored in SEGMENT_STORAGE_LINKED_LIST. The length of +/// the segments is stored in the associated global metadata. /// Both arrays are stored in the kernel memory (context=0). /// Searching and inserting is done by guessing the predecessor in the list. -/// If the address/storage key isn't found in the array, it is inserted at the end. +/// If the address/storage key isn't found in the array, it is inserted +/// at the correct location. These linked lists are used to keep track of +/// inserted and deleted accounts/slots during the execution, so that the +/// initial and final MPT state tries can be reconstructed at the end of the execution. // Initialize an empty account linked list (@U256_MAX) // which is written as [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST @@ -28,10 +31,9 @@ global init_linked_lists: // Store @U256_MAX at the beginning of the segment. PUSH @SEGMENT_ACCOUNTS_LINKED_LIST // ctx == virt == 0 DUP1 - PUSH @U256_MAX - MSTORE_GENERAL - // Store @SEGMENT_ACCOUNTS_LINKED_LIST at address 2 - %add_const(3) + %mstore_u256_max + // Store @SEGMENT_ACCOUNTS_LINKED_LIST at address `ACCOUNTS_NEXT_NODE_PTR`. + %add_const(@ACCOUNTS_NEXT_NODE_PTR) DUP1 PUSH @SEGMENT_ACCOUNTS_LINKED_LIST MSTORE_GENERAL @@ -44,10 +46,9 @@ global init_linked_lists: // Store @U256_MAX at the beginning of the segment. PUSH @SEGMENT_STORAGE_LINKED_LIST // ctx == virt == 0 DUP1 - PUSH @U256_MAX - MSTORE_GENERAL - // Store @SEGMENT_ACCOUNTS_LINKED_LIST at address 2 - %add_const(4) + %mstore_u256_max + // Store @SEGMENT_STORAGE_LINKED_LIST at address `STORAGE_NEXT_NODE_PTR` + %add_const(@STORAGE_NEXT_NODE_PTR) DUP1 PUSH @SEGMENT_STORAGE_LINKED_LIST MSTORE_GENERAL @@ -186,7 +187,7 @@ global insert_account_to_linked_list: // stack: pred_ptr, addr, payload_ptr, retdest // Check that this is not a deleted node DUP1 - %add_const(3) + %add_const(@ACCOUNTS_NEXT_NODE_PTR) MLOAD_GENERAL %jump_neq_const(@U256_MAX, account_found) // The storage key is not in the list. @@ -205,7 +206,7 @@ insert_new_account: // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest POP // get the value of the next address - %add_const(3) + %add_const(@ACCOUNTS_NEXT_NODE_PTR) // stack: next_ptr_ptr, addr, payload_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) DUP2 @@ -280,7 +281,7 @@ global insert_account_with_overwrite: // stack: pred_ptr, addr, payload_ptr, retdest // Check that this is not a deleted node DUP1 - %add_const(3) + %add_const(@ACCOUNTS_NEXT_NODE_PTR) MLOAD_GENERAL %jump_neq_const(@U256_MAX, account_found_with_overwrite) // The storage key is not in the list. @@ -337,7 +338,7 @@ global search_account: // stack: pred_ptr, addr, payload_ptr, retdest // Check that this is not a deleted node DUP1 - %add_const(3) + %add_const(@ACCOUNTS_NEXT_NODE_PTR) MLOAD_GENERAL %jump_neq_const(@U256_MAX, account_found) // The storage key is not in the list. @@ -363,7 +364,7 @@ global remove_account: // stack: pred_ptr/4, addr, retdest %get_valid_account_ptr // stack: pred_ptr, addr, retdest - %add_const(3) + %add_const(@ACCOUNTS_NEXT_NODE_PTR) // stack: next_ptr_ptr, addr, retdest DUP1 MLOAD_GENERAL @@ -374,14 +375,13 @@ global remove_account: DUP4 %assert_eq // stack: next_ptr, next_ptr_ptr, addr, retdest - %add_const(3) + %add_const(@ACCOUNTS_NEXT_NODE_PTR) // stack: next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest DUP1 MLOAD_GENERAL // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, retdest SWAP1 - PUSH @U256_MAX - MSTORE_GENERAL + %mstore_u256_max // stack: next_next_ptr, next_ptr_ptr, addr, retdest MSTORE_GENERAL POP @@ -424,7 +424,7 @@ loop_store_initial_slots: %append_to_trie_data // stack: cpy_ptr, current_node_ptr, retdest DUP2 - %add_const(3) + %add_const(@STORAGE_COPY_PAYLOAD_PTR) SWAP1 MSTORE_GENERAL // Store cpy_ptr %next_slot @@ -510,7 +510,7 @@ global insert_slot_with_value: // stack: pred_ptr, addr, key, value, retdest // Check that this is not a deleted node DUP1 - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) MLOAD_GENERAL %jump_neq_const(@U256_MAX, slot_found_write_value) // The storage key is not in the list. @@ -520,7 +520,7 @@ insert_new_slot_with_value: // stack: pred_addr or pred_key, pred_ptr, addr, key, value, retdest POP // get the value of the next address - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) // stack: next_ptr_ptr, addr, key, value, retdest %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 @@ -663,7 +663,7 @@ global insert_slot: // stack: pred_ptr, addr, key, payload_ptr, retdest // Check that this is not a deleted node DUP1 - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) MLOAD_GENERAL %jump_neq_const(@U256_MAX, slot_found_write) // The storage key is not in the list. @@ -686,7 +686,7 @@ insert_new_slot: // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest POP // get the value of the next address - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) // stack: next_ptr_ptr, addr, key, payload_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 @@ -806,7 +806,7 @@ global search_slot: // stack: pred_ptr, addr, key, payload_ptr, retdest // Check that this is not a deleted node DUP1 - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) MLOAD_GENERAL %jump_neq_const(@U256_MAX, slot_found_no_write) // The storage key is not in the list. @@ -829,7 +829,7 @@ slot_found_no_write: %macro remove_slot - %stack (addr, key) -> (addr, key, %%after) + %stack (key, addr) -> (addr, key, %%after) %jump(remove_slot) %%after: %endmacro @@ -842,7 +842,7 @@ global remove_slot: // stack: pred_ptr/5, addr, key, retdest %get_valid_slot_ptr // stack: pred_ptr, addr, key, retdest - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) // stack: next_ptr_ptr, addr, key, retdest DUP1 MLOAD_GENERAL @@ -860,15 +860,14 @@ global remove_slot: DUP5 %assert_eq // stack: next_ptr, next_ptr_ptr, addr, key, retdest - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) // stack: next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest DUP1 MLOAD_GENERAL // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest // Mark the next node as deleted SWAP1 - PUSH @U256_MAX - MSTORE_GENERAL + %mstore_u256_max // stack: next_next_ptr, next_ptr_ptr, addr, key, retdest MSTORE_GENERAL %pop2 @@ -891,10 +890,10 @@ global remove_all_account_slots: // Now, while the next address is `addr`, remove the next slot. remove_all_slots_loop: // stack: pred_ptr, pred_ptr, addr, retdest - %add_const(4) DUP1 MLOAD_GENERAL + %add_const(@STORAGE_NEXT_NODE_PTR) DUP1 MLOAD_GENERAL // stack: cur_ptr, cur_ptr_ptr, pred_ptr, addr, retdest DUP1 %eq_const(@U256_MAX) %jumpi(remove_all_slots_end) - DUP1 %add_const(4) MLOAD_GENERAL + DUP1 %add_const(@STORAGE_NEXT_NODE_PTR) MLOAD_GENERAL // stack: next_ptr, cur_ptr, cur_ptr_ptr, pred_ptr, addr, retdest SWAP1 DUP1 // stack: cur_ptr, cur_ptr, next_ptr, cur_ptr_ptr, pred_ptr, addr, retdest @@ -907,8 +906,8 @@ remove_all_slots_loop: // stack: next_ptr, cur_ptr_ptr, cur_ptr, pred_ptr, addr, retdest MSTORE_GENERAL // stack: cur_ptr, pred_ptr, addr, retdest - %add_const(4) PUSH @U256_MAX - MSTORE_GENERAL + %add_const(@STORAGE_NEXT_NODE_PTR) + %mstore_u256_max // stack: pred_ptr, addr, retdest DUP1 %jump(remove_all_slots_loop) @@ -963,7 +962,7 @@ remove_all_slots_end: %macro next_account // stack: node_ptr - %add_const(3) + %add_const(@ACCOUNTS_NEXT_NODE_PTR) MLOAD_GENERAL // stack: next_node_ptr %endmacro @@ -976,7 +975,7 @@ remove_all_slots_end: %macro next_slot // stack: node_ptr - %add_const(4) + %add_const(@STORAGE_NEXT_NODE_PTR) MLOAD_GENERAL // stack: next_node_ptr %endmacro diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index 425ef70e4..a188661d3 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -134,11 +134,11 @@ sstore_noop: // Delete the slot from the storage trie. sstore_delete: // stack: slot, value, kexit_info - SWAP1 POP - // stack: slot, kexit_info - %slot_to_storage_key - // stack: storage_key, kexit_info %address %addr_to_state_key + // stack: addr_key, slot, value, kexit_info + SWAP2 POP + // stack: slot, addr_key, kexit_info + %slot_to_storage_key %remove_slot EXIT_KERNEL diff --git a/evm_arithmetization/src/cpu/kernel/constants/mod.rs b/evm_arithmetization/src/cpu/kernel/constants/mod.rs index 610b28dc9..d24d3dff0 100644 --- a/evm_arithmetization/src/cpu/kernel/constants/mod.rs +++ b/evm_arithmetization/src/cpu/kernel/constants/mod.rs @@ -54,6 +54,10 @@ pub(crate) fn evm_constants() -> HashMap { c.insert(name.into(), U256::from(value)); } + for (name, value) in LINKED_LISTS_CONSTANTS { + c.insert(name.into(), U256::from(value)); + } + c.insert(MAX_NONCE.0.into(), U256::from(MAX_NONCE.1)); c.insert(CALL_STACK_LIMIT.0.into(), U256::from(CALL_STACK_LIMIT.1)); @@ -321,3 +325,11 @@ const CODE_SIZE_LIMIT: [(&str, u64); 3] = [ const MAX_NONCE: (&str, u64) = ("MAX_NONCE", 0xffffffffffffffff); const CALL_STACK_LIMIT: (&str, u64) = ("CALL_STACK_LIMIT", 1024); + +const LINKED_LISTS_CONSTANTS: [(&str, u16); 5] = [ + ("ACCOUNTS_LINKED_LISTS_NODE_SIZE", 4), + ("STORAGE_LINKED_LISTS_NODE_SIZE", 5), + ("ACCOUNTS_NEXT_NODE_PTR", 3), + ("STORAGE_NEXT_NODE_PTR", 4), + ("STORAGE_COPY_PAYLOAD_PTR", 3), +]; diff --git a/evm_arithmetization/src/cpu/kernel/tests/receipt.rs b/evm_arithmetization/src/cpu/kernel/tests/receipt.rs index 87e0f98cc..4c688d3ef 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/receipt.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/receipt.rs @@ -71,8 +71,10 @@ fn test_process_receipt() -> Result<()> { let segment_read = interpreter.get_memory_segment(Segment::TrieData); - // The expected TrieData has the form [payload_len, status, cum_gas_used, - // bloom_filter, logs_payload_len, num_logs, [logs]] + // The expected TrieData has the form [0, payload_len, status, cum_gas_used, + // bloom_filter, logs_payload_len, num_logs, [logs]]. + // The 0 is always the first element of `TrieSegmentData`, as it corresponds to + // the null pointer. let mut expected_trie_data: Vec = vec![0.into(), 323.into(), success, 2000.into()]; expected_trie_data.extend( expected_bloom diff --git a/evm_arithmetization/src/generation/trie_extractor.rs b/evm_arithmetization/src/generation/trie_extractor.rs index 189f92771..0d825643f 100644 --- a/evm_arithmetization/src/generation/trie_extractor.rs +++ b/evm_arithmetization/src/generation/trie_extractor.rs @@ -230,7 +230,10 @@ pub(crate) fn read_receipt_rlp_value( Ok(bytes) } -pub fn get_state_trie(memory: &MemoryState, ptr: usize) -> Result { +pub(crate) fn get_state_trie( + memory: &MemoryState, + ptr: usize, +) -> Result { get_trie(memory, ptr, read_state_rlp_value) } From 04ab8f7f32235802387f97c97c326ec0cb24275e Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Mon, 22 Jul 2024 14:04:15 +0100 Subject: [PATCH 110/118] Fix next_node_ok_with_value and tiny cleanup --- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 9 +++++---- evm_arithmetization/src/cpu/kernel/interpreter.rs | 5 ----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 582014324..474861001 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -579,7 +579,7 @@ next_node_ok_with_value: %get_trie_data_size // stack: new_payload_ptr, new_ptr+2, new_ptr+2, next_ptr, addr, key, value, retdest %stack (new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr, key, value, retdest) - -> (value, new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, retdest, new_payload_ptr) + -> (value, new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, new_payload_ptr, retdest) %append_to_trie_data MSTORE_GENERAL @@ -593,13 +593,14 @@ next_node_ok_with_value: // stack: new_ptr + 3, next_ptr, new_payload_ptr, retdest %increment DUP1 - // stack: new_next_ptr, new_next_ptr, next_ptr, retdest, new_payload_ptr + // stack: new_next_ptr, new_next_ptr, next_ptr, new_payload_ptr, retdest SWAP2 MSTORE_GENERAL - // stack: new_next_ptr, retdest, new_payload_ptr + // stack: new_next_ptr, new_payload_ptr, retdest %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) - // stack: retdest, new_payload_ptr + // stack: new_payload_ptr, retdest + SWAP1 JUMP slot_found_write_value: diff --git a/evm_arithmetization/src/cpu/kernel/interpreter.rs b/evm_arithmetization/src/cpu/kernel/interpreter.rs index eefbce825..6d4f42235 100644 --- a/evm_arithmetization/src/cpu/kernel/interpreter.rs +++ b/evm_arithmetization/src/cpu/kernel/interpreter.rs @@ -257,11 +257,6 @@ impl Interpreter { load_linked_lists_and_txn_and_receipt_mpts(&inputs.tries) .expect("Invalid MPT data for preinitialization"); - self.generation_state.memory.contexts[0].segments[Segment::AccountsLinkedList.unscale()] - .content = vec![]; - self.generation_state.memory.contexts[0].segments[Segment::StorageLinkedList.unscale()] - .content = vec![]; - let trie_roots_after = &inputs.trie_roots_after; self.generation_state.trie_root_ptrs = trie_root_ptrs; From 90cb9d1c700c53ba728d976b0ba92ef468db5c56 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 23 Jul 2024 11:30:49 +0100 Subject: [PATCH 111/118] Start addressing comments --- .../src/cpu/kernel/asm/core/util.asm | 2 +- .../kernel/asm/journal/account_destroyed.asm | 1 + .../asm/mpt/linked_list/linked_list.asm | 443 ++++++++---------- .../src/cpu/kernel/asm/mpt/read.asm | 2 +- .../src/cpu/kernel/tests/mpt/linked_list.rs | 105 +++-- 5 files changed, 281 insertions(+), 272 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/core/util.asm b/evm_arithmetization/src/cpu/kernel/asm/core/util.asm index 545354720..871784301 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/core/util.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/core/util.asm @@ -95,7 +95,7 @@ %endmacro %macro mstore_u256_max - // stack (empty) + // stack: addr PUSH @U256_MAX MSTORE_GENERAL %endmacro \ No newline at end of file diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm index 63679455b..45c178a6f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/account_destroyed.asm @@ -26,6 +26,7 @@ revert_account_destroyed_contd: DUP2 %mload_trie_data // stack: target_balance, prev_balance, target_balance_ptr, address, prev_balance, retdest SUB SWAP1 %mstore_trie_data + // Set `address`'s balance to `prev_balance`. // stack: address, prev_balance, retdest %read_accounts_linked_list // stack: account_payload_ptr, prev_balance, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 474861001..800a6b93e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -8,61 +8,25 @@ /// at the correct location. These linked lists are used to keep track of /// inserted and deleted accounts/slots during the execution, so that the /// initial and final MPT state tries can be reconstructed at the end of the execution. - -// Initialize an empty account linked list (@U256_MAX) -// which is written as [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST -// The values at the respective positions are: -// - 0: The account key -// - 1: A ptr to the payload (the account values) -// - 2: A ptr to the intial payload. -// - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. -// Initialize also an empty storage linked list (@U256_MAX) -// which is written as [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST -// The values at the respective positions are: -// - 0: The account key -// - 1: The key -// - 2: A ptr to the payload (the stored value) -// - 3: A ptr to the inital payload. -// - 4: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. -global init_linked_lists: - // stack: (empty) - - // Initialize SEGMENT_ACCOUNTS_LINKED_LIST. - // Store @U256_MAX at the beginning of the segment. - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST // ctx == virt == 0 - DUP1 - %mstore_u256_max - // Store @SEGMENT_ACCOUNTS_LINKED_LIST at address `ACCOUNTS_NEXT_NODE_PTR`. - %add_const(@ACCOUNTS_NEXT_NODE_PTR) - DUP1 - PUSH @SEGMENT_ACCOUNTS_LINKED_LIST - MSTORE_GENERAL - - // Store the segment scaled length. - %increment - %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) - - // Initialize SEGMENT_STORAGE_LINKED_LIST. - // Store @U256_MAX at the beginning of the segment. - PUSH @SEGMENT_STORAGE_LINKED_LIST // ctx == virt == 0 - DUP1 - %mstore_u256_max - // Store @SEGMENT_STORAGE_LINKED_LIST at address `STORAGE_NEXT_NODE_PTR` - %add_const(@STORAGE_NEXT_NODE_PTR) - DUP1 - PUSH @SEGMENT_STORAGE_LINKED_LIST - MSTORE_GENERAL - - // Store the segment scaled length. - %increment - %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) - JUMP - -%macro init_linked_lists - PUSH %%after - %jump(init_account_linked_lists) -%%after: -%endmacro +/// An empty account linked list is written as +/// [@U256_MAX, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST. +/// The linked list is preinitialized by appending accounts to the segment. Each account is encoded +/// using 4 values. +/// The values at the respective positions are: +/// - 0: The account key +/// - 1: A ptr to the payload (the account values) +/// - 2: A ptr to the intial payload. +/// - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. +/// Similarly, an empty storage linked list is written as +/// [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST. +/// The linked list is preinitialized by appending storage slots to the segment. +/// Each slot is encoded using 5 values. +/// The values at the respective positions are: +/// - 0: The account key +/// - 1: The slot key +/// - 2: A ptr to the payload (the stored value) +/// - 3: A ptr to the initial payload. +/// - 4: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. %macro store_initial_accounts PUSH %%after @@ -81,7 +45,7 @@ loop_store_initial_accounts: %get_trie_data_size DUP2 MLOAD_GENERAL - // stack: current_addr, cpy_ptr, current_node_ptr, retdest + // stack: current_addr_key, cpy_ptr, current_node_ptr, retdest %eq_const(@U256_MAX) %jumpi(store_initial_accounts_end) DUP2 @@ -119,42 +83,45 @@ store_initial_accounts_end: %macro insert_account_to_linked_list - %stack (addr, ptr) -> (addr, ptr, %%after) + %stack (addr_key, ptr) -> (addr_key, ptr, %%after) %jump(insert_account_to_linked_list) %%after: // stack: payload_ptr %endmacro %macro insert_account_with_overwrite - %stack (addr, ptr) -> (addr, ptr, %%after) + %stack (addr_key, ptr) -> (addr_key, ptr, %%after) %jump(insert_account_with_overwrite) %%after: // stack: payload_ptr %endmacro -%macro insert_account_to_linked_list_no_return - %insert_account_to_linked_list - POP -%endmacro - %macro insert_account_with_overwrite_no_return %insert_account_with_overwrite POP %endmacro // Multiplies the value at the top of the stack, denoted by ptr/4, by 4 -// and aborts if ptr/4 >= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN]/4 +// and aborts if ptr/4 <= mem[@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN]/4. +// Also checks that ptr >= @SEGMENT_ACCOUNTS_LINKED_LIST. // This way, 4*ptr/4 must be pointing to the beginning of a node. // TODO: Maybe we should check here if the node has been deleted. %macro get_valid_account_ptr + // stack: ptr/4 + // Check that the pointer is greater than the segment. + PUSH @SEGMENT_ACCOUNTS_LINKED_LIST + DUP2 + %mul_const(4) + // stack: ptr, @SEGMENT_ACCOUNTS_LINKED_LIST, ptr/4 + %increment %assert_gt // stack: ptr/4 DUP1 PUSH 4 %mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) - // By construction, both @SEGMENT_ACCESSED_STORAGE_KEYS and the unscaled list len + // By construction, both @SEGMENT_ACCOUNTS_LINKED_LIST and the unscaled list len // must be multiples of 4 DIV - // stack: @SEGMENT_ACCESSED_STORAGE_KEYS/4 + accessed_strg_keys_len/4, ptr/4, ptr/4 + // stack: @SEGMENT_ACCOUNTS_LINKED_LIST/4 + accounts_linked_list_len/4, ptr/4, ptr/4 %assert_gt %mul_const(4) %endmacro @@ -162,15 +129,15 @@ store_initial_accounts_end: /// Inserts the account addr and payload pointer into the linked list if it is not already present. /// Returns `payload_ptr` if the account was inserted, `original_ptr` if it was already present. global insert_account_to_linked_list: - // stack: addr, payload_ptr, retdest + // stack: addr_key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) - // stack: pred_ptr/4, addr, payload_ptr, retdest + // stack: pred_ptr/4, addr_key, payload_ptr, retdest %get_valid_account_ptr - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest DUP1 MLOAD_GENERAL DUP1 - // stack: pred_addr, pred_addr, pred_ptr, addr, payload_ptr, retdest + // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest DUP4 GT DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) ADD // OR @@ -178,13 +145,13 @@ global insert_account_to_linked_list: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(insert_new_account) - // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %add_const(@ACCOUNTS_NEXT_NODE_PTR) @@ -194,50 +161,50 @@ global insert_account_to_linked_list: PANIC account_found: // The address was already in the list - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest // Load the payload pointer %increment MLOAD_GENERAL - // stack: orig_payload_ptr, addr, payload_ptr, retdest - %stack (orig_payload_ptr, addr, payload_ptr, retdest) -> (retdest, orig_payload_ptr) + // stack: orig_payload_ptr, addr_key, payload_ptr, retdest + %stack (orig_payload_ptr, addr_key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP insert_new_account: - // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest POP // get the value of the next address %add_const(@ACCOUNTS_NEXT_NODE_PTR) - // stack: next_ptr_ptr, addr, payload_ptr, retdest + // stack: next_ptr_ptr, addr_key, payload_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) DUP2 MLOAD_GENERAL - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, payload_ptr, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %eq_const(@U256_MAX) %assert_zero DUP1 MLOAD_GENERAL - // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, payload_ptr, retdest + // stack: next_addr_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, payload_ptr, retdest DUP5 - // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). - // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. + // Here, (addr_key > pred_addr_key) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). + // We should have (addr_key < next_addr_key), meaning the new value can be inserted between pred_ptr and next_ptr. %assert_lt - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, payload_ptr, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, payload_ptr, retdest SWAP2 DUP2 - // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, payload_ptr, retdest + // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr_key, payload_ptr, retdest MSTORE_GENERAL - // stack: new_ptr, next_ptr, addr, payload_ptr, retdest + // stack: new_ptr, next_ptr, addr_key, payload_ptr, retdest DUP1 DUP4 MSTORE_GENERAL - // stack: new_ptr, next_ptr, addr, payload_ptr, retdest + // stack: new_ptr, next_ptr, addr_key, payload_ptr, retdest %increment DUP1 DUP5 MSTORE_GENERAL - // stack: new_ptr + 1, next_ptr, addr, payload_ptr, retdest + // stack: new_ptr + 1, next_ptr, addr_key, payload_ptr, retdest %increment DUP1 DUP5 @@ -245,26 +212,26 @@ insert_new_account: MSTORE_GENERAL %increment DUP1 - // stack: new_next_ptr, new_next_ptr, next_ptr, addr, payload_ptr, retdest + // stack: new_next_ptr, new_next_ptr, next_ptr, addr_key, payload_ptr, retdest SWAP2 MSTORE_GENERAL - // stack: new_next_ptr, addr, payload_ptr, retdest + // stack: new_next_ptr, addr_key, payload_ptr, retdest %increment %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) - // stack: addr, payload_ptr, retdest - %stack (addr, payload_ptr, retdest) -> (retdest, payload_ptr) + // stack: addr_key, payload_ptr, retdest + %stack (addr_key, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP global insert_account_with_overwrite: - // stack: addr, payload_ptr, retdest + // stack: addr_key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) - // stack: pred_ptr/4, addr, payload_ptr, retdest + // stack: pred_ptr/4, addr_key, payload_ptr, retdest %get_valid_account_ptr - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest DUP1 MLOAD_GENERAL DUP1 - // stack: pred_addr, pred_addr, pred_ptr, addr, payload_ptr, retdest + // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest DUP4 GT DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) ADD // OR @@ -272,13 +239,13 @@ global insert_account_with_overwrite: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(insert_new_account) - // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %add_const(@ACCOUNTS_NEXT_NODE_PTR) @@ -289,16 +256,16 @@ global insert_account_with_overwrite: account_found_with_overwrite: // The address was already in the list - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest // Load the payload pointer %increment - // stack: payload_ptr_ptr, addr, payload_ptr, retdest + // stack: payload_ptr_ptr, addr_key, payload_ptr, retdest DUP3 MSTORE_GENERAL - %stack (addr, payload_ptr, retdest) -> (retdest, payload_ptr) + %stack (addr_key, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP %macro search_account - %stack (addr, ptr) -> (addr, ptr, %%after) + %stack (addr_key, ptr) -> (addr_key, ptr, %%after) %jump(search_account) %%after: // stack: @@ -313,15 +280,15 @@ account_found_with_overwrite: /// Searches the account addr andin the linked list. /// Returns `payload_ptr` if the account was not found, `original_ptr` if it was already present. global search_account: - // stack: addr, payload_ptr, retdest + // stack: addr_key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) - // stack: pred_ptr/4, addr, payload_ptr, retdest + // stack: pred_ptr/4, addr_key, payload_ptr, retdest %get_valid_account_ptr - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest DUP1 MLOAD_GENERAL DUP1 - // stack: pred_addr, pred_addr, pred_ptr, addr, payload_ptr, retdest + // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest DUP4 GT DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) ADD // OR @@ -329,13 +296,13 @@ global search_account: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(account_not_found) - // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest - // stack: pred_ptr, addr, payload_ptr, retdest + // stack: pred_ptr, addr_key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %add_const(@ACCOUNTS_NEXT_NODE_PTR) @@ -345,8 +312,8 @@ global search_account: PANIC account_not_found: - // stack: pred_addr, pred_ptr, addr, payload_ptr, retdest - %stack (pred_addr, pred_ptr, addr, payload_ptr, retdest) -> (retdest, payload_ptr) + // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest + %stack (pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP %macro remove_account_from_linked_list @@ -359,30 +326,30 @@ account_not_found: /// Removes the address and its value from the access list. /// Panics if the key is not in the list. global remove_account: - // stack: addr, retdest + // stack: addr_key, retdest PROVER_INPUT(linked_list::remove_account) - // stack: pred_ptr/4, addr, retdest + // stack: pred_ptr/4, addr_key, retdest %get_valid_account_ptr - // stack: pred_ptr, addr, retdest + // stack: pred_ptr, addr_key, retdest %add_const(@ACCOUNTS_NEXT_NODE_PTR) - // stack: next_ptr_ptr, addr, retdest + // stack: next_ptr_ptr, addr_key, retdest DUP1 MLOAD_GENERAL - // stack: next_ptr, next_ptr_ptr, addr, retdest + // stack: next_ptr, next_ptr_ptr, addr_key, retdest DUP1 MLOAD_GENERAL - // stack: next_addr, next_ptr, next_ptr_ptr, addr, retdest + // stack: next_addr_key, next_ptr, next_ptr_ptr, addr_key, retdest DUP4 %assert_eq - // stack: next_ptr, next_ptr_ptr, addr, retdest + // stack: next_ptr, next_ptr_ptr, addr_key, retdest %add_const(@ACCOUNTS_NEXT_NODE_PTR) - // stack: next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_next_ptr_ptr, next_ptr_ptr, addr_key, key, retdest DUP1 MLOAD_GENERAL - // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, retdest + // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr_key, retdest SWAP1 %mstore_u256_max - // stack: next_next_ptr, next_ptr_ptr, addr, retdest + // stack: next_next_ptr, next_ptr_ptr, addr_key, retdest MSTORE_GENERAL POP JUMP @@ -413,7 +380,7 @@ loop_store_initial_slots: %get_trie_data_size DUP2 MLOAD_GENERAL - // stack: current_addr, cpy_ptr, current_node_ptr, retdest + // stack: current_addr_key, cpy_ptr, current_node_ptr, retdest %eq_const(@U256_MAX) %jumpi(store_initial_slots_end) DUP2 @@ -436,7 +403,7 @@ store_initial_slots_end: %macro insert_slot - %stack (addr, key, ptr) -> (addr, key, ptr, %%after) + %stack (addr_key, key, ptr) -> (addr_key, key, ptr, %%after) %jump(insert_slot) %%after: // stack: value_ptr @@ -468,20 +435,20 @@ store_initial_slots_end: %add_const(@SEGMENT_STORAGE_LINKED_LIST) %endmacro -/// Inserts the pair (addres, storage_key) and a new payload pointer into the linked list if it is not already present, +/// Inserts the pair (address_key, storage_key) and a new payload pointer into the linked list if it is not already present, /// or modifies its payload if it was already present. /// Returns `new_payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global insert_slot_with_value: - // stack: addr, key, value, retdest + // stack: addr_key, key, value, retdest PROVER_INPUT(linked_list::insert_slot) - // stack: pred_ptr/5, addr, key, value, retdest + // stack: pred_ptr/5, addr_key, key, value, retdest %get_valid_slot_ptr - // stack: pred_ptr, addr, key, value, retdest + // stack: pred_ptr, addr_key, key, value, retdest DUP1 MLOAD_GENERAL DUP1 - // stack: pred_addr, pred_addr, pred_ptr, addr, key, value, retdest + // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, key, value, retdest DUP4 GT DUP3 %eq_const(@SEGMENT_STORAGE_LINKED_LIST) @@ -490,24 +457,24 @@ global insert_slot_with_value: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(insert_new_slot_with_value) - // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr, key, value, retdest + // stack: pred_ptr, addr_key, key, value, retdest DUP1 %increment MLOAD_GENERAL - // stack: pred_key, pred_ptr, addr, key, value, retdest + // stack: pred_key, pred_ptr, addr_key, key, value, retdest DUP1 DUP5 GT %jumpi(insert_new_slot_with_value) - // stack: pred_key, pred_ptr, addr, key, value, retdest + // stack: pred_key, pred_ptr, addr_key, key, value, retdest DUP4 // We know that key <= pred_key. It must hold that pred_key == key. %assert_eq - // stack: pred_ptr, addr, key, value, retdest + // stack: pred_ptr, addr_key, key, value, retdest // Check that this is not a deleted node DUP1 %add_const(@STORAGE_NEXT_NODE_PTR) @@ -517,68 +484,68 @@ global insert_slot_with_value: PANIC insert_new_slot_with_value: - // stack: pred_addr or pred_key, pred_ptr, addr, key, value, retdest + // stack: pred_addr or pred_key, pred_ptr, addr_key, key, value, retdest POP // get the value of the next address %add_const(@STORAGE_NEXT_NODE_PTR) - // stack: next_ptr_ptr, addr, key, value, retdest + // stack: next_ptr_ptr, addr_key, key, value, retdest %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 MLOAD_GENERAL - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest // Check that this is not a deleted node DUP1 %eq_const(@U256_MAX) %assert_zero DUP1 MLOAD_GENERAL - // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // stack: next_addr_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest DUP1 DUP6 - // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). - // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. + // Here, (addr_key > pred_addr_key) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). + // We should have (addr_key < next_addr_key), meaning the new value can be inserted between pred_ptr and next_ptr. LT %jumpi(next_node_ok_with_value) - // If addr <= next_addr, then it addr must be equal to next_addr - // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // If addr_key <= next_addr_key, then it addr must be equal to next_addr + // stack: next_addr_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest DUP5 %assert_eq - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest DUP1 %increment MLOAD_GENERAL - // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest DUP1 // This is added just to have the correct stack in next_node_ok DUP7 // The next key must be strictly larger %assert_lt next_node_ok_with_value: - // stack: next_addr or next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // stack: next_addr or next_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest POP - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, value, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, value, retdest SWAP2 DUP2 - // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, key, value, retdest + // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr_key, key, value, retdest MSTORE_GENERAL - // stack: new_ptr, next_ptr, addr, key, value, retdest + // stack: new_ptr, next_ptr, addr_key, key, value, retdest // Write the address in the new node DUP1 DUP4 MSTORE_GENERAL - // stack: new_ptr, next_ptr, addr, key, value, retdest + // stack: new_ptr, next_ptr, addr_key, key, value, retdest // Write the key in the new node %increment DUP1 DUP5 MSTORE_GENERAL - // stack: new_ptr + 1, next_ptr, addr, key, value, retdest + // stack: new_ptr + 1, next_ptr, addr_key, key, value, retdest // Append the value to `TrieDataSegment` and write the resulting payload_ptr. %increment DUP1 %get_trie_data_size - // stack: new_payload_ptr, new_ptr+2, new_ptr+2, next_ptr, addr, key, value, retdest - %stack (new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr, key, value, retdest) + // stack: new_payload_ptr, new_ptr+2, new_ptr+2, next_ptr, addr_key, key, value, retdest + %stack (new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr_key, key, value, retdest) -> (value, new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, new_payload_ptr, retdest) %append_to_trie_data MSTORE_GENERAL @@ -604,37 +571,39 @@ next_node_ok_with_value: JUMP slot_found_write_value: - // stack: pred_ptr, addr, key, value, retdest + // stack: pred_ptr, addr_key, key, value, retdest %add_const(2) MLOAD_GENERAL - %stack (payload_ptr, addr, key, value) -> (payload_ptr, value, payload_ptr) + %stack (payload_ptr, addr_key, key, value) -> (payload_ptr, value, payload_ptr) %mstore_trie_data // stack: payload_ptr, retdest %stack (payload_ptr, retdest) -> (retdest, payload_ptr) JUMP %macro insert_slot_with_value - %stack (addr, slot, value) -> (addr, slot, value, %%after) - SWAP1 %slot_to_storage_key - SWAP1 %addr_to_state_key + // stack: addr, slot, value + %addr_to_state_key + SWAP1 + %slot_to_storage_key + %stack (slot_key, addr_key, value) -> (addr_key, slot_key, value, %%after) %jump(insert_slot_with_value) %%after: // stack: value_ptr %endmacro -/// Inserts the pair (addres, storage_key) and payload pointer into the linked list if it is not already present, +/// Inserts the pair (address_key, storage_key) and payload pointer into the linked list if it is not already present, /// or modifies its payload if it was already present. /// Returns `payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global insert_slot: - // stack: addr, key, payload_ptr, retdest + // stack: addr_key, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) - // stack: pred_ptr/5, addr, key, payload_ptr, retdest + // stack: pred_ptr/5, addr_key, key, payload_ptr, retdest %get_valid_slot_ptr - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest DUP1 MLOAD_GENERAL DUP1 - // stack: pred_addr, pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, key, payload_ptr, retdest DUP4 GT DUP3 %eq_const(@SEGMENT_STORAGE_LINKED_LIST) @@ -643,25 +612,25 @@ global insert_slot: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(insert_new_slot) - // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest DUP1 %increment MLOAD_GENERAL - // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_key, pred_ptr, addr_key, key, payload_ptr, retdest DUP1 DUP5 GT %jumpi(insert_new_slot) - // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_key, pred_ptr, addr_key, key, payload_ptr, retdest DUP4 // We know that key <= pred_key. It must hold that pred_key == key. %assert_eq - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %add_const(@STORAGE_NEXT_NODE_PTR) @@ -672,112 +641,112 @@ global insert_slot: slot_found_write: // The slot was already in the list - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest // Load the the payload pointer and access counter %add_const(2) DUP1 MLOAD_GENERAL - // stack: orig_payload_ptr, pred_ptr + 2, addr, key, payload_ptr, retdest + // stack: orig_payload_ptr, pred_ptr + 2, addr_key, key, payload_ptr, retdest SWAP1 DUP5 MSTORE_GENERAL // Store the new payload - %stack (orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) + %stack (orig_payload_ptr, addr_key, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP insert_new_slot: - // stack: pred_addr or pred_key, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_addr or pred_key, pred_ptr, addr_key, key, payload_ptr, retdest POP // get the value of the next address %add_const(@STORAGE_NEXT_NODE_PTR) - // stack: next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_ptr_ptr, addr_key, key, payload_ptr, retdest %mload_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) DUP2 MLOAD_GENERAL - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %eq_const(@U256_MAX) %assert_zero DUP1 MLOAD_GENERAL - // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_addr_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest DUP1 DUP6 - // Here, (addr > pred_addr) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). - // We should have (addr < next_addr), meaning the new value can be inserted between pred_ptr and next_ptr. + // Here, (addr_key > pred_addr_key) || (pred_ptr == @SEGMENT_ACCOUNTS_LINKED_LIST). + // We should have (addr_key < next_addr_key), meaning the new value can be inserted between pred_ptr and next_ptr. LT %jumpi(next_node_ok) - // If addr <= next_addr, then it addr must be equal to next_addr - // stack: next_addr, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // If addr_key <= next_addr_key, then it addr must be equal to next_addr + // stack: next_addr_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest DUP5 %assert_eq - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest DUP1 %increment MLOAD_GENERAL - // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest DUP1 // This is added just to have the correct stack in next_node_ok DUP7 // The next key must be strictly larger %assert_lt next_node_ok: - // stack: next_addr or next_key, next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_addr or next_key, next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest POP - // stack: next_ptr, new_ptr, next_ptr_ptr, addr, key, payload_ptr, retdest + // stack: next_ptr, new_ptr, next_ptr_ptr, addr_key, key, payload_ptr, retdest SWAP2 DUP2 - // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr, key, payload_ptr, retdest + // stack: new_ptr, next_ptr_ptr, new_ptr, next_ptr, addr_key, key, payload_ptr, retdest MSTORE_GENERAL - // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest + // stack: new_ptr, next_ptr, addr_key, key, payload_ptr, retdest // Write the address in the new node DUP1 DUP4 MSTORE_GENERAL - // stack: new_ptr, next_ptr, addr, key, payload_ptr, retdest + // stack: new_ptr, next_ptr, addr_key, key, payload_ptr, retdest // Write the key in the new node %increment DUP1 DUP5 MSTORE_GENERAL - // stack: new_ptr + 1, next_ptr, addr, key, payload_ptr, retdest + // stack: new_ptr + 1, next_ptr, addr_key, key, payload_ptr, retdest // Store payload_ptr %increment DUP1 DUP6 MSTORE_GENERAL - // stack: new_ptr + 2, next_ptr, addr, key, payload_ptr, retdest + // stack: new_ptr + 2, next_ptr, addr_key, key, payload_ptr, retdest // Store the copy of payload_ptr %increment DUP1 DUP6 %clone_slot MSTORE_GENERAL - // stack: new_ptr + 3, next_ptr, addr, key, payload_ptr, retdest + // stack: new_ptr + 3, next_ptr, addr_key, key, payload_ptr, retdest %increment DUP1 - // stack: new_next_ptr, new_next_ptr, next_ptr, addr, key, payload_ptr, retdest + // stack: new_next_ptr, new_next_ptr, next_ptr, addr_key, key, payload_ptr, retdest SWAP2 MSTORE_GENERAL - // stack: new_next_ptr, addr, key, payload_ptr, retdest + // stack: new_next_ptr, addr_key, key, payload_ptr, retdest %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) - // stack: addr, key, payload_ptr, retdest - %stack (addr, key, payload_ptr, retdest) -> (retdest, payload_ptr) + // stack: addr_key, key, payload_ptr, retdest + %stack (addr_key, key, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP -/// Searches the pair (address, storage_key) in the storage the linked list. +/// Searches the pair (address_key, storage_key) in the storage the linked list. /// Returns `payload_ptr` if the storage key was inserted, `original_ptr` if it was already present. global search_slot: - // stack: addr, key, payload_ptr, retdest + // stack: addr_key, key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_slot) - // stack: pred_ptr/5, addr, key, payload_ptr, retdest + // stack: pred_ptr/5, addr_key, key, payload_ptr, retdest %get_valid_slot_ptr - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest DUP1 MLOAD_GENERAL DUP1 - // stack: pred_addr, pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, key, payload_ptr, retdest DUP4 GT DUP3 %eq_const(@SEGMENT_STORAGE_LINKED_LIST) @@ -786,25 +755,25 @@ global search_slot: // node with key @U256_MAX (and hence we're inserting a new minimum), then // the slot was not found %jumpi(slot_not_found) - // stack: pred_addr, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, key, payload_ptr, retdest // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest DUP1 %increment MLOAD_GENERAL - // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_key, pred_ptr, addr_key, key, payload_ptr, retdest DUP1 DUP5 GT %jumpi(slot_not_found) - // stack: pred_key, pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_key, pred_ptr, addr_key, key, payload_ptr, retdest DUP4 // We know that key <= pred_key. It must hold that pred_key == key. %assert_eq - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %add_const(@STORAGE_NEXT_NODE_PTR) @@ -813,24 +782,24 @@ global search_slot: // The storage key is not in the list. PANIC slot_not_found: - // stack: pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest - %stack (pred_addr_or_pred_key, pred_ptr, addr, key, payload_ptr, retdest) + // stack: pred_addr_or_pred_key, pred_ptr, addr_key, key, payload_ptr, retdest + %stack (pred_addr_or_pred_key, pred_ptr, addr_key, key, payload_ptr, retdest) -> (retdest, payload_ptr) JUMP slot_found_no_write: // The slot was already in the list - // stack: pred_ptr, addr, key, payload_ptr, retdest + // stack: pred_ptr, addr_key, key, payload_ptr, retdest // Load the the payload pointer and access counter %add_const(2) MLOAD_GENERAL - // stack: orig_payload_ptr, addr, key, payload_ptr, retdest - %stack (orig_payload_ptr, addr, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) + // stack: orig_payload_ptr, addr_key, key, payload_ptr, retdest + %stack (orig_payload_ptr, addr_key, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) JUMP %macro remove_slot - %stack (key, addr) -> (addr, key, %%after) + %stack (key, addr_key) -> (addr_key, key, %%after) %jump(remove_slot) %%after: %endmacro @@ -838,89 +807,89 @@ slot_found_no_write: /// Removes the storage key and its value from the list. /// Panics if the key is not in the list. global remove_slot: - // stack: addr, key, retdest + // stack: addr_key, key, retdest PROVER_INPUT(linked_list::remove_slot) - // stack: pred_ptr/5, addr, key, retdest + // stack: pred_ptr/5, addr_key, key, retdest %get_valid_slot_ptr - // stack: pred_ptr, addr, key, retdest + // stack: pred_ptr, addr_key, key, retdest %add_const(@STORAGE_NEXT_NODE_PTR) - // stack: next_ptr_ptr, addr, key, retdest + // stack: next_ptr_ptr, addr_key, key, retdest DUP1 MLOAD_GENERAL - // stack: next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_ptr, next_ptr_ptr, addr_key, key, retdest DUP1 MLOAD_GENERAL - // stack: next_addr, next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_addr_key, next_ptr, next_ptr_ptr, addr_key, key, retdest DUP4 %assert_eq - // stack: next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_ptr, next_ptr_ptr, addr_key, key, retdest DUP1 %increment MLOAD_GENERAL - // stack: next_key, next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_key, next_ptr, next_ptr_ptr, addr_key, key, retdest DUP5 %assert_eq - // stack: next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_ptr, next_ptr_ptr, addr_key, key, retdest %add_const(@STORAGE_NEXT_NODE_PTR) - // stack: next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_next_ptr_ptr, next_ptr_ptr, addr_key, key, retdest DUP1 MLOAD_GENERAL - // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_next_ptr, next_next_ptr_ptr, next_ptr_ptr, addr_key, key, retdest // Mark the next node as deleted SWAP1 %mstore_u256_max - // stack: next_next_ptr, next_ptr_ptr, addr, key, retdest + // stack: next_next_ptr, next_ptr_ptr, addr_key, key, retdest MSTORE_GENERAL %pop2 JUMP /// Called when an account is deleted: it deletes all slots associated with the account. global remove_all_account_slots: - // stack: addr, retdest + // stack: addr_key, retdest PROVER_INPUT(linked_list::remove_address_slots) // pred_ptr/5, retdest %get_valid_slot_ptr - // stack: pred_ptr, addr, retdest + // stack: pred_ptr, addr_key, retdest // First, check that the previous address is not `addr` DUP1 MLOAD_GENERAL - // stack: pred_addr, pred_ptr, addr, retdest + // stack: pred_addr_key, pred_ptr, addr_key, retdest DUP3 EQ %jumpi(panic) - // stack: pred_ptr, addr, retdest + // stack: pred_ptr, addr_key, retdest DUP1 // Now, while the next address is `addr`, remove the next slot. remove_all_slots_loop: - // stack: pred_ptr, pred_ptr, addr, retdest + // stack: pred_ptr, pred_ptr, addr_key, retdest %add_const(@STORAGE_NEXT_NODE_PTR) DUP1 MLOAD_GENERAL - // stack: cur_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + // stack: cur_ptr, cur_ptr_ptr, pred_ptr, addr_key, retdest DUP1 %eq_const(@U256_MAX) %jumpi(remove_all_slots_end) DUP1 %add_const(@STORAGE_NEXT_NODE_PTR) MLOAD_GENERAL - // stack: next_ptr, cur_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + // stack: next_ptr, cur_ptr, cur_ptr_ptr, pred_ptr, addr_key, retdest SWAP1 DUP1 - // stack: cur_ptr, cur_ptr, next_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + // stack: cur_ptr, cur_ptr, next_ptr, cur_ptr_ptr, pred_ptr, addr_key, retdest MLOAD_GENERAL DUP6 EQ ISZERO %jumpi(remove_all_slots_pop_and_end) // Remove slot: update the value in cur_ptr_ptr, and set cur_ptr+4 to @U256_MAX. - // stack: cur_ptr, next_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + // stack: cur_ptr, next_ptr, cur_ptr_ptr, pred_ptr, addr_key, retdest SWAP2 SWAP1 - // stack: next_ptr, cur_ptr_ptr, cur_ptr, pred_ptr, addr, retdest + // stack: next_ptr, cur_ptr_ptr, cur_ptr, pred_ptr, addr_key, retdest MSTORE_GENERAL - // stack: cur_ptr, pred_ptr, addr, retdest + // stack: cur_ptr, pred_ptr, addr_key, retdest %add_const(@STORAGE_NEXT_NODE_PTR) %mstore_u256_max - // stack: pred_ptr, addr, retdest + // stack: pred_ptr, addr_key, retdest DUP1 %jump(remove_all_slots_loop) remove_all_slots_pop_and_end: POP remove_all_slots_end: - // stack: next_ptr, cur_ptr_ptr, pred_ptr, addr, retdest + // stack: next_ptr, cur_ptr_ptr, pred_ptr, addr_key, retdest %pop4 JUMP %macro remove_all_account_slots - %stack (addr) -> (addr, %%after) + %stack (addr_key) -> (addr_key, %%after) %jump(remove_all_account_slots) %%after: %endmacro @@ -938,7 +907,7 @@ remove_all_slots_end: %slot_to_storage_key %address %addr_to_state_key - %stack (addr, key) -> (addr, key, 0, %%after) + %stack (addr_key, key) -> (addr_key, key, 0, %%after) %jump(search_slot) %%after: // stack: slot_ptr @@ -949,7 +918,7 @@ remove_all_slots_end: %slot_to_storage_key SWAP1 %addr_to_state_key - %stack (addr, key) -> (addr, key, 0, %%after) + %stack (addr_key, key) -> (addr_key, key, 0, %%after) %jump(search_slot) %%after: // stack: slot_ptr diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm index 1dc9dc7c3..7f078931c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/read.asm @@ -4,7 +4,7 @@ global mpt_read_state_trie: // stack: addr, retdest %read_accounts_linked_list - // stack: account_ptr + // stack: account_ptr, retdest SWAP1 JUMP diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 90c99b6a1..817326744 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -28,14 +28,8 @@ fn init_logger() { #[test] fn test_init_linked_lists() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_linked_lists"]; - // Check the initial state of the linked list in the kernel. - let initial_stack = vec![0xdeadbeefu32.into()]; - let mut interpreter = Interpreter::::new(init_label, initial_stack, None); - interpreter.run()?; - - assert!(interpreter.stack().is_empty()); + let mut interpreter = Interpreter::::new(0, vec![], None); // Check the initial accounts linked list let acc_addr_list: Vec = (0..4) @@ -82,11 +76,8 @@ fn test_init_linked_lists() -> Result<()> { #[test] fn test_list_iterator() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_linked_lists"]; - let initial_stack = vec![0xdeadbeefu32.into()]; - let mut interpreter = Interpreter::::new(init_label, initial_stack, None); - interpreter.run()?; + let mut interpreter = Interpreter::::new(0, vec![], None); // test the list iterator let accounts_mem = interpreter @@ -139,12 +130,24 @@ fn test_list_iterator() -> Result<()> { #[test] fn test_insert_account() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_linked_lists"]; - // Test for address already in list. - let initial_stack = vec![0xdeadbeefu32.into()]; - let mut interpreter = Interpreter::::new(init_label, initial_stack, None); - interpreter.run()?; + let mut interpreter = Interpreter::::new(0, vec![], None); + + // Initialize the accounts linked list. + let init_accounts_ll = vec![ + Some(U256::MAX), + Some(0.into()), + Some(0.into()), + Some((Segment::AccountsLinkedList as usize).into()), + ]; + let init_len = init_accounts_ll.len(); + interpreter.generation_state.memory.contexts[0].segments + [Segment::AccountsLinkedList.unscale()] + .content = init_accounts_ll; + interpreter.set_global_metadata_field( + GlobalMetadata::AccountsLinkedListLen, + (Segment::AccountsLinkedList as usize + init_len).into(), + ); let insert_account_label = KERNEL.global_labels["insert_account_to_linked_list"]; @@ -196,12 +199,25 @@ fn test_insert_account() -> Result<()> { #[test] fn test_insert_storage() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_linked_lists"]; - // Test for address already in list. - let initial_stack = vec![0xdeadbeefu32.into()]; - let mut interpreter = Interpreter::::new(init_label, initial_stack, None); - interpreter.run()?; + let mut interpreter = Interpreter::::new(0, vec![], None); + + // Initialize the storage linked list. + let init_storage_ll = vec![ + Some(U256::MAX), + Some(0.into()), + Some(0.into()), + Some(0.into()), + Some((Segment::StorageLinkedList as usize).into()), + ]; + let init_len = init_storage_ll.len(); + interpreter.generation_state.memory.contexts[0].segments + [Segment::StorageLinkedList.unscale()] + .content = init_storage_ll; + interpreter.set_global_metadata_field( + GlobalMetadata::StorageLinkedListLen, + (Segment::StorageLinkedList as usize + init_len).into(), + ); let insert_account_label = KERNEL.global_labels["insert_slot"]; @@ -258,12 +274,23 @@ fn test_insert_storage() -> Result<()> { fn test_insert_and_delete_accounts() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_linked_lists"]; - - // Test for address already in list. - let initial_stack = vec![0xdeadbeefu32.into()]; - let mut interpreter = Interpreter::::new(init_label, initial_stack, None); - interpreter.run()?; + let mut interpreter = Interpreter::::new(0, vec![], None); + + // Initialize the accounts linked list. + let init_accounts_ll = vec![ + Some(U256::MAX), + Some(0.into()), + Some(0.into()), + Some((Segment::AccountsLinkedList as usize).into()), + ]; + let init_len = init_accounts_ll.len(); + interpreter.generation_state.memory.contexts[0].segments + [Segment::AccountsLinkedList.unscale()] + .content = init_accounts_ll; + interpreter.set_global_metadata_field( + GlobalMetadata::AccountsLinkedListLen, + (Segment::AccountsLinkedList as usize + init_len).into(), + ); let insert_account_label = KERNEL.global_labels["insert_account_to_linked_list"]; @@ -405,12 +432,24 @@ fn test_insert_and_delete_accounts() -> Result<()> { fn test_insert_and_delete_storage() -> Result<()> { init_logger(); - let init_label = KERNEL.global_labels["init_linked_lists"]; - - // Test for address already in list. - let initial_stack = vec![0xdeadbeefu32.into()]; - let mut interpreter = Interpreter::::new(init_label, initial_stack, None); - interpreter.run()?; + let mut interpreter = Interpreter::::new(0, vec![], None); + + // Initialize the storage linked list. + let init_storage_ll = vec![ + Some(U256::MAX), + Some(0.into()), + Some(0.into()), + Some(0.into()), + Some((Segment::StorageLinkedList as usize).into()), + ]; + let init_len = init_storage_ll.len(); + interpreter.generation_state.memory.contexts[0].segments + [Segment::StorageLinkedList.unscale()] + .content = init_storage_ll; + interpreter.set_global_metadata_field( + GlobalMetadata::StorageLinkedListLen, + (Segment::StorageLinkedList as usize + init_len).into(), + ); let insert_slot_label = KERNEL.global_labels["insert_slot"]; From f92c4ebe355e33cb944a2802a1020357725cdacf Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 23 Jul 2024 16:10:54 +0100 Subject: [PATCH 112/118] Remove unnecessary linked_lists methods and payload_ptr --- .../asm/mpt/insert/insert_trie_specific.asm | 2 +- .../asm/mpt/linked_list/linked_list.asm | 119 +++++------------- .../src/cpu/kernel/tests/mpt/linked_list.rs | 19 +-- 3 files changed, 35 insertions(+), 105 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm index 4b2c09ba2..e1e82b562 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/insert/insert_trie_specific.asm @@ -6,7 +6,7 @@ // TODO: Have this take an address and do %mpt_insert_state_trie? To match mpt_read_state_trie. global mpt_insert_state_trie: // stack: key, value_ptr, retdest - %insert_account_with_overwrite_no_return + %insert_account_with_overwrite JUMP %macro mpt_insert_state_trie diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 800a6b93e..a995d540c 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -81,24 +81,10 @@ store_initial_accounts_end: %pop2 JUMP - -%macro insert_account_to_linked_list - %stack (addr_key, ptr) -> (addr_key, ptr, %%after) - %jump(insert_account_to_linked_list) -%%after: - // stack: payload_ptr -%endmacro - %macro insert_account_with_overwrite %stack (addr_key, ptr) -> (addr_key, ptr, %%after) %jump(insert_account_with_overwrite) %%after: - // stack: payload_ptr -%endmacro - -%macro insert_account_with_overwrite_no_return - %insert_account_with_overwrite - POP %endmacro // Multiplies the value at the top of the stack, denoted by ptr/4, by 4 @@ -126,9 +112,7 @@ store_initial_accounts_end: %mul_const(4) %endmacro -/// Inserts the account addr and payload pointer into the linked list if it is not already present. -/// Returns `payload_ptr` if the account was inserted, `original_ptr` if it was already present. -global insert_account_to_linked_list: +global insert_account_with_overwrite: // stack: addr_key, payload_ptr, retdest PROVER_INPUT(linked_list::insert_account) // stack: pred_ptr/4, addr_key, payload_ptr, retdest @@ -149,24 +133,24 @@ global insert_account_to_linked_list: // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr_key, payload_ptr, retdest // stack: pred_ptr, addr_key, payload_ptr, retdest // Check that this is not a deleted node DUP1 %add_const(@ACCOUNTS_NEXT_NODE_PTR) MLOAD_GENERAL - %jump_neq_const(@U256_MAX, account_found) + %jump_neq_const(@U256_MAX, account_found_with_overwrite) // The storage key is not in the list. PANIC -account_found: + +account_found_with_overwrite: // The address was already in the list // stack: pred_ptr, addr_key, payload_ptr, retdest // Load the payload pointer %increment - MLOAD_GENERAL - // stack: orig_payload_ptr, addr_key, payload_ptr, retdest - %stack (orig_payload_ptr, addr_key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) + // stack: payload_ptr_ptr, addr_key, payload_ptr, retdest + DUP3 MSTORE_GENERAL + %pop2 JUMP insert_new_account: @@ -219,76 +203,22 @@ insert_new_account: %increment %mstore_global_metadata(@GLOBAL_METADATA_ACCOUNTS_LINKED_LIST_LEN) // stack: addr_key, payload_ptr, retdest - %stack (addr_key, payload_ptr, retdest) -> (retdest, payload_ptr) - JUMP - -global insert_account_with_overwrite: - // stack: addr_key, payload_ptr, retdest - PROVER_INPUT(linked_list::insert_account) - // stack: pred_ptr/4, addr_key, payload_ptr, retdest - %get_valid_account_ptr - // stack: pred_ptr, addr_key, payload_ptr, retdest - DUP1 - MLOAD_GENERAL - DUP1 - // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest - DUP4 GT - DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) - ADD // OR - // If the predesessor is strictly smaller or the predecessor is the special - // node with key @U256_MAX (and hence we're inserting a new minimum), then - // we need to insert a new node. - %jumpi(insert_new_account) - // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest - // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. - DUP3 - %assert_eq - // stack: pred_ptr, addr_key, payload_ptr, retdest - - // stack: pred_ptr, addr_key, payload_ptr, retdest - // Check that this is not a deleted node - DUP1 - %add_const(@ACCOUNTS_NEXT_NODE_PTR) - MLOAD_GENERAL - %jump_neq_const(@U256_MAX, account_found_with_overwrite) - // The storage key is not in the list. - PANIC - -account_found_with_overwrite: - // The address was already in the list - // stack: pred_ptr, addr_key, payload_ptr, retdest - // Load the payload pointer - %increment - // stack: payload_ptr_ptr, addr_key, payload_ptr, retdest - DUP3 MSTORE_GENERAL - %stack (addr_key, payload_ptr, retdest) -> (retdest, payload_ptr) + %pop2 JUMP -%macro search_account - %stack (addr_key, ptr) -> (addr_key, ptr, %%after) - %jump(search_account) -%%after: - // stack: -%endmacro - -%macro search_account_no_return - %search_account - POP -%endmacro - -/// Searches the account addr andin the linked list. +/// Searches the account addr in the linked list. /// Returns `payload_ptr` if the account was not found, `original_ptr` if it was already present. global search_account: - // stack: addr_key, payload_ptr, retdest + // stack: addr_key, retdest PROVER_INPUT(linked_list::insert_account) - // stack: pred_ptr/4, addr_key, payload_ptr, retdest + // stack: pred_ptr/4, addr_key, retdest %get_valid_account_ptr - // stack: pred_ptr, addr_key, payload_ptr, retdest + // stack: pred_ptr, addr_key, retdest DUP1 MLOAD_GENERAL DUP1 - // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest + // stack: pred_addr_key, pred_addr_key, pred_ptr, addr_key, retdest DUP4 GT DUP3 %eq_const(@SEGMENT_ACCOUNTS_LINKED_LIST) ADD // OR @@ -296,13 +226,12 @@ global search_account: // node with key @U256_MAX (and hence we're inserting a new minimum), then // we need to insert a new node. %jumpi(account_not_found) - // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest - // If we are here we know that addr <= pred_addr. But this is only possible if pred_addr == addr. + // stack: pred_addr_key, pred_ptr, addr_key, retdest + // If we are here we know that addr_key <= pred_addr_key. But this is only possible if pred_addr == addr. DUP3 %assert_eq - // stack: pred_ptr, addr_key, payload_ptr, retdest - // stack: pred_ptr, addr_key, payload_ptr, retdest + // stack: pred_ptr, addr_key, retdest // Check that this is not a deleted node DUP1 %add_const(@ACCOUNTS_NEXT_NODE_PTR) @@ -311,9 +240,19 @@ global search_account: // The storage key is not in the list. PANIC +account_found: + // The address was already in the list + // stack: pred_ptr, addr_key, retdest + // Load the payload pointer + %increment + MLOAD_GENERAL + // stack: orig_payload_ptr, addr_key, retdest + %stack (orig_payload_ptr, addr_key, retdest) -> (retdest, orig_payload_ptr) + JUMP + account_not_found: - // stack: pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest - %stack (pred_addr_key, pred_ptr, addr_key, payload_ptr, retdest) -> (retdest, payload_ptr) + // stack: pred_addr_key, pred_ptr, addr_key, retdest + %stack (pred_addr_key, pred_ptr, addr_key, retdest) -> (retdest, 0) JUMP %macro remove_account_from_linked_list @@ -895,7 +834,7 @@ remove_all_slots_end: %endmacro %macro read_accounts_linked_list - %stack (addr) -> (addr, 0, %%after) + %stack (addr) -> (addr, %%after) %addr_to_state_key %jump(search_account) %%after: diff --git a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs index 817326744..5cd6b568f 100644 --- a/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs +++ b/evm_arithmetization/src/cpu/kernel/tests/mpt/linked_list.rs @@ -149,7 +149,7 @@ fn test_insert_account() -> Result<()> { (Segment::AccountsLinkedList as usize + init_len).into(), ); - let insert_account_label = KERNEL.global_labels["insert_account_to_linked_list"]; + let insert_account_label = KERNEL.global_labels["insert_account_with_overwrite"]; let retaddr = 0xdeadbeefu32.into(); let mut rng = thread_rng(); @@ -164,7 +164,6 @@ fn test_insert_account() -> Result<()> { interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!(interpreter.stack(), &[payload_ptr]); let accounts_mem = interpreter .generation_state @@ -292,7 +291,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { (Segment::AccountsLinkedList as usize + init_len).into(), ); - let insert_account_label = KERNEL.global_labels["insert_account_to_linked_list"]; + let insert_account_label = KERNEL.global_labels["insert_account_with_overwrite"]; let retaddr = 0xdeadbeefu32.into(); let mut rng = thread_rng(); @@ -318,10 +317,7 @@ fn test_insert_and_delete_accounts() -> Result<()> { interpreter.push(addr); interpreter.generation_state.registers.program_counter = insert_account_label; interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - addr + delta_ptr - ); + // The copied ptr is at distance 4, the size of an account, from the previous // copied ptr. assert_eq!( @@ -342,13 +338,13 @@ fn test_insert_and_delete_accounts() -> Result<()> { U256::from(offset + (n + 1) * 4) ); + let search_account_label = KERNEL.global_labels["search_account"]; // Test for address already in list. for i in 0..n { let addr_in_list = U256::from(addresses[i].0.as_slice()); interpreter.push(retaddr); - interpreter.push(U256::zero()); interpreter.push(addr_in_list); - interpreter.generation_state.registers.program_counter = insert_account_label; + interpreter.generation_state.registers.program_counter = search_account_label; interpreter.run()?; assert_eq!( @@ -365,11 +361,6 @@ fn test_insert_and_delete_accounts() -> Result<()> { interpreter.run()?; - assert_eq!( - interpreter.pop().expect("The stack can't be empty"), - U256::from(addr_not_in_list.0.as_slice()) + delta_ptr - ); - // Now the list of accounts have address 4 addresses.push(addr_not_in_list); From 7ebae472535361330db07ed7129c275bffa79aa0 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Wed, 17 Jul 2024 20:54:48 +0100 Subject: [PATCH 113/118] Store storage value in linked list --- .../cpu/kernel/asm/journal/storage_change.asm | 2 - .../src/cpu/kernel/asm/main.asm | 4 ++ .../asm/mpt/linked_list/final_tries.asm | 8 ++- .../asm/mpt/linked_list/initial_tries.asm | 10 ++- .../asm/mpt/linked_list/linked_list.asm | 64 ++++++++----------- .../kernel/asm/mpt/storage/storage_write.asm | 12 +--- .../asm/transactions/common_decoding.asm | 5 +- evm_arithmetization/src/generation/mpt.rs | 15 +++-- .../src/generation/prover_input.rs | 5 ++ 9 files changed, 61 insertions(+), 64 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm index afe2ca130..695975c1f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/journal/storage_change.asm @@ -12,8 +12,6 @@ global revert_storage_change: DUP3 ISZERO %jumpi(delete) // stack: address, slot, prev_value, retdest %insert_slot_with_value - // stack: value_ptr - POP JUMP delete: diff --git a/evm_arithmetization/src/cpu/kernel/asm/main.asm b/evm_arithmetization/src/cpu/kernel/asm/main.asm index 6bb3d94af..2d8e811be 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/main.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/main.asm @@ -165,6 +165,10 @@ global perform_final_checks: PROVER_INPUT(trie_ptr::state) %mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) + + PROVER_INPUT(trie_ptr::trie_data_size) + %mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE) + %set_initial_tries %get_trie_data_size %mpt_hash_state_trie diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index fb91cc17d..8eb19a063 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -69,11 +69,13 @@ insert_next_slot: DUP2 %increment MLOAD_GENERAL - // key, addr, storage_ptr_ptr, root_ptr, retdest + // stack: key, addr, storage_ptr_ptr, root_ptr, retdest DUP3 %add_const(2) MLOAD_GENERAL - // stack: payload_ptr, key, addr, storage_ptr_ptr, root_ptr, retdest + // stack: value, key, addr, storage_ptr_ptr, root_ptr, retdest + %get_trie_data_size // payload_ptr + SWAP1 %append_to_trie_data // append the value to the trie data segment %stack (payload_ptr, key, addr, storage_ptr_ptr, root_ptr) -> (root_ptr, 64, key, payload_ptr, after_insert_slot, storage_ptr_ptr, addr) %jump(mpt_insert) after_insert_slot: @@ -112,7 +114,7 @@ global delete_removed_accounts: // stack: key, account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest DUP2 %add_const(2) - MLOAD_GENERAL // get intitial payload_ptr + MLOAD_GENERAL // get initial payload_ptr %add_const(2) // storage_root_ptr_ptr = payload_ptr + 2 %mload_trie_data // stack: storage_root_ptr, key, account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index cebcd1290..158f132cb 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -32,7 +32,7 @@ skip: %macro set_initial_tries PUSH %%after PUSH @SEGMENT_STORAGE_LINKED_LIST - %add_const(8) // The first node is the special node, of size 5, so the first payload is at position 5 + 3. + %add_const(8) // The first node is the special node, of size 5, so the first value is at position 5 + 3. PUSH @SEGMENT_ACCOUNTS_LINKED_LIST %add_const(6) // The first node is the special node, of size 4, so the first payload is at position 4 + 2. %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT) @@ -174,10 +174,14 @@ after_set_storage_payload: set_payload_storage_leaf: // stack: node_type, after_node_type, storage_ptr_ptr, retdest POP - // stack: after_node_type, storage_ptr_ptr, retdest + // stack: after_node_type, storage_ptr_ptr, retdest %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. - DUP2 + %get_trie_data_size + // stack: value_ptr, value_ptr_ptr, storage_ptr_ptr, retdest + DUP3 MLOAD_GENERAL + // stack: value, value_ptr, value_ptr_ptr, storage_ptr_ptr, retdest + %append_to_trie_data SWAP1 %mstore_trie_data // stack: storage_ptr_ptr, retdest diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index a995d540c..44b374e0d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -316,28 +316,26 @@ global store_initial_slots: loop_store_initial_slots: // stack: current_node_ptr - %get_trie_data_size - DUP2 + DUP1 MLOAD_GENERAL - // stack: current_addr_key, cpy_ptr, current_node_ptr, retdest + // stack: current_addr_key, current_node_ptr, retdest %eq_const(@U256_MAX) %jumpi(store_initial_slots_end) - DUP2 + DUP1 %add_const(2) MLOAD_GENERAL - // stack: payload_ptr, cpy_ptr, current_node_ptr, retdest - %mload_trie_data - %append_to_trie_data - // stack: cpy_ptr, current_node_ptr, retdest + // stack: value, current_node_ptr, retdest DUP2 %add_const(@STORAGE_COPY_PAYLOAD_PTR) + // stack: cpy_value_ptr, value, current_node_ptr, retdest SWAP1 - MSTORE_GENERAL // Store cpy_ptr + MSTORE_GENERAL // Store cpy_value + // stack: current_node_ptr, retdest %next_slot %jump(loop_store_initial_slots) store_initial_slots_end: - %pop2 + POP JUMP @@ -350,7 +348,6 @@ store_initial_slots_end: %macro insert_slot_no_return %insert_slot - POP %endmacro // Multiplies the value at the top of the stack, denoted by ptr/5, by 5 @@ -481,41 +478,31 @@ next_node_ok_with_value: // stack: new_ptr + 1, next_ptr, addr_key, key, value, retdest // Append the value to `TrieDataSegment` and write the resulting payload_ptr. %increment - DUP1 - %get_trie_data_size - // stack: new_payload_ptr, new_ptr+2, new_ptr+2, next_ptr, addr_key, key, value, retdest - %stack (new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr_key, key, value, retdest) - -> (value, new_payload_ptr, new_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, new_payload_ptr, retdest) - %append_to_trie_data - MSTORE_GENERAL - - // stack: new_ptr + 2, next_ptr, new_payload_ptr, retdest - // Store the payload ptr copy - %increment - DUP1 - DUP4 - %clone_slot - MSTORE_GENERAL - // stack: new_ptr + 3, next_ptr, new_payload_ptr, retdest + DUP1 %increment + // stack: new_ptr+2, next_ptr, addr_key, key, value, retdest + %stack (new_cloned_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr_key, key, value, retdest) + -> (value, new_cloned_payload_ptr_ptr, value, new_payload_ptr_ptr, new_cloned_payload_ptr_ptr, next_ptr, retdest) + MSTORE_GENERAL // Store copied value. + MSTORE_GENERAL // Store value. + + // stack: new_ptr + 3, next_ptr, retdest %increment DUP1 - // stack: new_next_ptr, new_next_ptr, next_ptr, new_payload_ptr, retdest + // stack: new_next_ptr_ptr, new_next_ptr_ptr, next_ptr, retdest SWAP2 MSTORE_GENERAL - // stack: new_next_ptr, new_payload_ptr, retdest + // stack: new_next_ptr_ptr, retdest %increment %mstore_global_metadata(@GLOBAL_METADATA_STORAGE_LINKED_LIST_LEN) - // stack: new_payload_ptr, retdest - SWAP1 + // stack: retdest JUMP slot_found_write_value: // stack: pred_ptr, addr_key, key, value, retdest - %add_const(2) MLOAD_GENERAL - %stack (payload_ptr, addr_key, key, value) -> (payload_ptr, value, payload_ptr) - %mstore_trie_data - // stack: payload_ptr, retdest - %stack (payload_ptr, retdest) -> (retdest, payload_ptr) + %add_const(2) + %stack (payload_ptr, addr_key, key, value) -> (value, payload_ptr) + MSTORE_GENERAL + // stack: retdest JUMP %macro insert_slot_with_value @@ -526,7 +513,6 @@ slot_found_write_value: %stack (slot_key, addr_key, value) -> (addr_key, slot_key, value, %%after) %jump(insert_slot_with_value) %%after: - // stack: value_ptr %endmacro /// Inserts the pair (address_key, storage_key) and payload pointer into the linked list if it is not already present, @@ -732,8 +718,8 @@ slot_found_no_write: // Load the the payload pointer and access counter %add_const(2) MLOAD_GENERAL - // stack: orig_payload_ptr, addr_key, key, payload_ptr, retdest - %stack (orig_payload_ptr, addr_key, key, payload_ptr, retdest) -> (retdest, orig_payload_ptr) + // stack: orig_value, addr_key, key, payload_ptr, retdest + %stack (orig_value, addr_key, key, payload_ptr, retdest) -> (retdest, orig_value) JUMP diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm index a188661d3..589c44094 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/storage/storage_write.asm @@ -111,18 +111,10 @@ sstore_after_refund: // stack: slot, value, kexit_info DUP2 ISZERO %jumpi(sstore_delete) - // First we write the value to MPT data, and get a pointer to it. - %get_trie_data_size - // stack: value_ptr, slot, value, kexit_info - SWAP2 - // stack: value, slot, value_ptr, kexit_info - %append_to_trie_data - // stack: slot, value_ptr, kexit_info - %slot_to_storage_key + // stack: slot, value, kexit_info %address - %addr_to_state_key - %insert_slot_no_return + %insert_slot_with_value EXIT_KERNEL diff --git a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm index 49caffe87..a21369e43 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/transactions/common_decoding.asm @@ -252,12 +252,11 @@ sload_with_addr: // Storage key not found. Return default value_ptr = 0, // which derefs to 0 since @SEGMENT_TRIE_DATA[0] = 0. - %stack (value_ptr, retdest) -> (retdest, 0) + %stack (value, retdest) -> (retdest, 0) + JUMP global storage_key_exists: - // stack: value_ptr, retdest - %mload_trie_data // stack: value, retdest SWAP1 JUMP diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index 1acebddbf..fcb2e2da0 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -214,6 +214,7 @@ fn load_state_trie( storage_tries_by_state_key: &HashMap, ) -> Result { let node_ptr = trie_data.len(); + log::debug!("node ptr {:?}", node_ptr); let type_of_trie = PartialTrieType::of(trie) as u32; if type_of_trie > 0 { trie_data.push(Some(type_of_trie.into())); @@ -481,15 +482,21 @@ where .map_err(|_| ProgramError::IntegerTooLarge)?, )); // Write `value_ptr_ptr`. - storage_leaves.push(Some((trie_data.len()).into())); + let leaves = parse_value(value)? + .into_iter() + .map(Some) + .collect::>(); + let leaf = match leaves.len() { + 0 => Some(0.into()), + 1 => leaves[0], + _ => panic!("Slot can only store one value."), + }; + storage_leaves.push(leaf); // Write the counter. storage_leaves.push(Some(0.into())); // Set the next node as the inital node. storage_leaves.push(Some((Segment::StorageLinkedList as usize).into())); - let leaf = parse_value(value)?.into_iter().map(Some); - trie_data.extend(leaf); - Ok(()) } _ => Ok(()), diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index e68d1bf15..9997552b4 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -90,6 +90,10 @@ impl GenerationState { Some(state_root_ptr) => Ok(state_root_ptr), None => { self.set_preinit = true; + let l = self.memory.contexts[0].segments[Segment::TrieData.unscale()] + .content + .len(); + let mut new_content = self.memory.get_preinit_memory(Segment::TrieData); let n = load_state_mpt(&self.inputs.trimmed_tries, &mut new_content)?; @@ -100,6 +104,7 @@ impl GenerationState { content: new_content, }, ); + Ok(n) } } From e1e1fca09ad7d8ce36d38b3ddddd2f32785a2798 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Tue, 23 Jul 2024 18:12:35 +0100 Subject: [PATCH 114/118] Fix Clippy and cleanup --- evm_arithmetization/src/generation/mpt.rs | 20 ++----------------- .../src/generation/prover_input.rs | 5 ----- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index fcb2e2da0..78f8765b4 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -411,7 +411,6 @@ associated storage trie hash" empty_nibbles(), storage_trie, storage_leaves, - trie_data, &parse_storage_value, )?; @@ -426,7 +425,6 @@ pub(crate) fn get_storage_leaves( key: Nibbles, trie: &HashedPartialTrie, storage_leaves: &mut Vec>, - trie_data: &mut Vec>, parse_value: &F, ) -> Result<(), ProgramError> where @@ -440,14 +438,7 @@ where count: 1, packed: i.into(), }); - get_storage_leaves( - address, - extended_key, - child, - storage_leaves, - trie_data, - parse_value, - )?; + get_storage_leaves(address, extended_key, child, storage_leaves, parse_value)?; } Ok(()) @@ -455,14 +446,7 @@ where Node::Extension { nibbles, child } => { let extended_key = key.merge_nibbles(nibbles); - get_storage_leaves( - address, - extended_key, - child, - storage_leaves, - trie_data, - parse_value, - )?; + get_storage_leaves(address, extended_key, child, storage_leaves, parse_value)?; Ok(()) } diff --git a/evm_arithmetization/src/generation/prover_input.rs b/evm_arithmetization/src/generation/prover_input.rs index 9997552b4..e68d1bf15 100644 --- a/evm_arithmetization/src/generation/prover_input.rs +++ b/evm_arithmetization/src/generation/prover_input.rs @@ -90,10 +90,6 @@ impl GenerationState { Some(state_root_ptr) => Ok(state_root_ptr), None => { self.set_preinit = true; - let l = self.memory.contexts[0].segments[Segment::TrieData.unscale()] - .content - .len(); - let mut new_content = self.memory.get_preinit_memory(Segment::TrieData); let n = load_state_mpt(&self.inputs.trimmed_tries, &mut new_content)?; @@ -104,7 +100,6 @@ impl GenerationState { content: new_content, }, ); - Ok(n) } } From b52acc29084d1ebdc4d9c0e33a089535a233fe94 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 26 Jul 2024 14:23:31 +0100 Subject: [PATCH 115/118] Apply comments --- evm_arithmetization/src/generation/mpt.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index 78f8765b4..e71ec41af 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -214,7 +214,6 @@ fn load_state_trie( storage_tries_by_state_key: &HashMap, ) -> Result { let node_ptr = trie_data.len(); - log::debug!("node ptr {:?}", node_ptr); let type_of_trie = PartialTrieType::of(trie) as u32; if type_of_trie > 0 { trie_data.push(Some(type_of_trie.into())); @@ -471,9 +470,8 @@ where .map(Some) .collect::>(); let leaf = match leaves.len() { - 0 => Some(0.into()), 1 => leaves[0], - _ => panic!("Slot can only store one value."), + _ => panic!("Slot can only store exactly one value."), }; storage_leaves.push(leaf); // Write the counter. From d7dfec4e4ee2dfc30206025710cdd928ff5121fc Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Thu, 1 Aug 2024 11:13:04 +0100 Subject: [PATCH 116/118] Only write to TrieData if value nonzero --- .../cpu/kernel/asm/mpt/linked_list/final_tries.asm | 3 +++ .../kernel/asm/mpt/linked_list/initial_tries.asm | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 8eb19a063..689dcb94a 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -74,8 +74,11 @@ insert_next_slot: %add_const(2) MLOAD_GENERAL // stack: value, key, addr, storage_ptr_ptr, root_ptr, retdest + // If the value is 0, then payload_ptr = 0, and we don't need to insert a value in the `TrieData` segment. + DUP1 ISZERO %jumpi(insert_with_payload_ptr) %get_trie_data_size // payload_ptr SWAP1 %append_to_trie_data // append the value to the trie data segment +insert_with_payload_ptr: %stack (payload_ptr, key, addr, storage_ptr_ptr, root_ptr) -> (root_ptr, 64, key, payload_ptr, after_insert_slot, storage_ptr_ptr, addr) %jump(mpt_insert) after_insert_slot: diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index 158f132cb..9f3500fce 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -176,12 +176,17 @@ set_payload_storage_leaf: POP // stack: after_node_type, storage_ptr_ptr, retdest %add_const(2) // The value pointer starts at index 3, after num_nibbles and packed_nibbles. + // stack: value_ptr_ptr, storage_ptr_ptr, retdest + DUP2 MLOAD_GENERAL + // stack: value, value_ptr_ptr, storage_ptr_ptr, retdest + // If value == 0, then value_ptr = 0, and we don't need to append the value to the `TrieData` segment. + DUP1 ISZERO %jumpi(set_payload_storage_leaf_end) %get_trie_data_size - // stack: value_ptr, value_ptr_ptr, storage_ptr_ptr, retdest - DUP3 - MLOAD_GENERAL - // stack: value, value_ptr, value_ptr_ptr, storage_ptr_ptr, retdest + // stack: value_ptr, value, value_ptr_ptr, storage_ptr_ptr, retdest + SWAP1 %append_to_trie_data +set_payload_storage_leaf_end: + // stack: value_ptr, value_ptr_ptr, storage_ptr_ptr, retdest SWAP1 %mstore_trie_data // stack: storage_ptr_ptr, retdest From f2b29b28bb50f4fb3a5feb5d4899ee094141b57c Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 2 Aug 2024 21:10:22 +0100 Subject: [PATCH 117/118] Fix comments and name changed in merge --- .../asm/mpt/linked_list/final_tries.asm | 4 +-- .../asm/mpt/linked_list/initial_tries.asm | 25 +++++++++---------- .../asm/mpt/linked_list/linked_list.asm | 8 +++--- evm_arithmetization/src/generation/mpt.rs | 4 +-- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm index 689dcb94a..9db07083d 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/final_tries.asm @@ -90,7 +90,7 @@ after_insert_slot: %jump(insert_all_slots) // Delete all the accounts, referenced by the respective nodes in the linked list starting at -// `account_ptr_ptr`, which where deleted from the intial state. Delete also all slots of non-deleted accounts +// `account_ptr_ptr`, which where deleted from the initial state. Delete also all slots of non-deleted accounts // deleted from the storage trie. // Pre stack: account_ptr_ptr, root_ptr, storage_ptr_ptr, retdest // Post stack: new_root_ptr. @@ -100,7 +100,7 @@ global delete_removed_accounts: // We assume that the size of the initial accounts linked list, containing the accounts // of the initial state, was stored at `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. %mload_global_metadata(@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN) - // The inital accounts linked list was stored at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. + // The initial accounts linked list was stored at addresses smaller than `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN`. // If we also know that `@SEGMENT_ACCOUNT_LINKED_LIST <= account_ptr_ptr`, for deleting node at `addr_ptr_ptr` it // suffices to check that `account_ptr_ptr` != `@GLOBAL_METADATA_INITIAL_ACCOUNTS_LINKED_LIST_LEN` EQ diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index 6c34daa9f..c7bff476f 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -48,7 +48,7 @@ skip: %mstore_global_metadata(@GLOBAL_METADATA_INITIAL_STORAGE_LINKED_LIST_LEN) %endmacro -// Pre stack: node_ptr, account_ptr_ptr, retdest +// Pre stack: node_ptr, storage_ptr_ptr, retdest // Post stack: storage_ptr_ptr global mpt_set_storage_payload: // stack: node_ptr, storage_ptr_ptr, retdest @@ -118,18 +118,19 @@ set_payload_storage_branch: JUMP set_payload_extension: - // stack: node_type, after_node_type, storage_ptr_ptr, retdest + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr,retdest POP - // stack: after_node_type, storage_ptr_ptr, retdest + // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest %add_const(2) %mload_trie_data - // stack: child_ptr, after_node_type, storage_ptr_ptr, retdest + // stack: child_ptr, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest %jump(mpt_set_payload) + set_payload_storage_extension: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: node_type, after_node_type, storage_ptr_ptr, retdest POP - // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: after_node_type, storage_ptr_ptr, retdest %add_const(2) %mload_trie_data - // stack: child_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: child_ptr, storage_ptr_ptr, retdest %jump(mpt_set_storage_payload) set_payload_leaf: @@ -137,15 +138,13 @@ set_payload_leaf: POP %add_const(2) // The payload pointer starts at index 3, after num_nibbles and packed_nibbles. DUP1 - // stack payload_ptr_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: payload_ptr_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %mload_trie_data - // stack account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: account_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %add_const(2) %mload_trie_data // storage_root_ptr = account[2] - DUP1 %mload_trie_data - POP - // stack storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest + // stack: storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr, retdest %stack (storage_root_ptr, payload_ptr_ptr, account_ptr_ptr, storage_ptr_ptr) -> (storage_root_ptr, storage_ptr_ptr, after_set_storage_payload, storage_root_ptr, payload_ptr_ptr, account_ptr_ptr) @@ -167,7 +166,7 @@ after_set_storage_payload: %mstore_trie_data // The dynamic account pointer in the linked list has no storage root so we need to manually set it. %mstore_trie_data // Set the leaf payload pointing to next account in the linked list. // stack: account_ptr_ptr, storage_ptr_ptr', retdest - %add_const(@STORAGE_NEXT_NODE_PTR) // The next pointer is at distance `STORAGE_NEXT_NODE_PTR` + %add_const(@ACCOUNTS_LINKED_LISTS_NODE_SIZE) // The next pointer is at distance `ACCOUNTS_LINKED_LISTS_NODE_SIZE` // stack: payload_ptr_ptr', storage_ptr_ptr', retdest SWAP1 SWAP2 diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 24d38ee83..65c9d5287 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -15,7 +15,7 @@ /// The values at the respective positions are: /// - 0: The account key /// - 1: A ptr to the payload (the account values) -/// - 2: A ptr to the intial payload. +/// - 2: A ptr to the initial payload. /// - 3: A ptr (in segment @SEGMENT_ACCOUNTS_LINKED_LIST) to the next node in the list. /// Similarly, an empty storage linked list is written as /// [@U256_MAX, _, _, _, @SEGMENT_ACCOUNTS_LINKED_LIST] in SEGMENT_ACCOUNTS_LINKED_LIST. @@ -221,7 +221,7 @@ insert_new_account: /// Searches the account addr in the linked list. -/// Returns `payload_ptr` if the account was not found, `original_ptr` if it was already present. +/// Returns 0 if the account was not found or `original_ptr` if it was already present. global search_account: // stack: addr_key, retdest PROVER_INPUT(linked_list::insert_account) @@ -320,7 +320,7 @@ global remove_account: %endmacro -/// Iterates over the inital account linked list and shallow copies +/// Iterates over the initial account linked list and shallow copies /// the accounts, storing a pointer to the copied account in the node. /// Computes the length of `SEGMENT_STORAGE_LINKED_LIST` and /// checks against `GLOBAL_METADATA_STORAGE_LINKED_LIST_NEXT_AVAILABLE`. @@ -503,7 +503,7 @@ next_node_ok_with_value: // Append the value to `TrieDataSegment` and write the resulting payload_ptr. %increment DUP1 %increment - // stack: new_ptr+2, next_ptr, addr_key, key, value, retdest + // stack: new_ptr+3, new_payload_ptr_ptr, next_ptr, addr_key, key, value, retdest %stack (new_cloned_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr_key, key, value, retdest) -> (value, new_cloned_payload_ptr_ptr, value, new_payload_ptr_ptr, new_cloned_payload_ptr_ptr, next_ptr, retdest) MSTORE_GENERAL // Store copied value. diff --git a/evm_arithmetization/src/generation/mpt.rs b/evm_arithmetization/src/generation/mpt.rs index e71ec41af..32c286066 100644 --- a/evm_arithmetization/src/generation/mpt.rs +++ b/evm_arithmetization/src/generation/mpt.rs @@ -396,7 +396,7 @@ associated storage trie hash" state_leaves.push(Some(trie_data.len().into())); // Set counter. state_leaves.push(Some(0.into())); - // Set the next node as the inital node. + // Set the next node as the initial node. state_leaves.push(Some((Segment::AccountsLinkedList as usize).into())); // Push the payload in the trie data. @@ -476,7 +476,7 @@ where storage_leaves.push(leaf); // Write the counter. storage_leaves.push(Some(0.into())); - // Set the next node as the inital node. + // Set the next node as the initial node. storage_leaves.push(Some((Segment::StorageLinkedList as usize).into())); Ok(()) From d201a1f3572c99d6f74f66b35720b018edc12fc4 Mon Sep 17 00:00:00 2001 From: Linda Guiga Date: Fri, 2 Aug 2024 22:15:27 +0100 Subject: [PATCH 118/118] Apply comments --- .../cpu/kernel/asm/mpt/linked_list/initial_tries.asm | 6 +++--- .../src/cpu/kernel/asm/mpt/linked_list/linked_list.asm | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm index c7bff476f..795453667 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/initial_tries.asm @@ -2,7 +2,7 @@ // to mem[payload_ptr_ptr] + step*i, // for i =0..n_leaves. This is used to constraint the // initial state and account tries payload pointers such that they are exactly -// those of the inital accounts and linked lists. +// those of the initial accounts and linked lists. // Pre stack: node_ptr, account_ptr_ptr, storage_ptr_ptr, retdest // Post stack: account_ptr_ptr, storage_ptr_ptr global mpt_set_payload: @@ -19,7 +19,7 @@ global mpt_set_payload: DUP1 %eq_const(@MPT_NODE_LEAF) %jumpi(set_payload_leaf) DUP1 %eq_const(@MPT_NODE_HASH) %jumpi(skip) PANIC - + skip: // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest %stack (node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest) -> (retdest, account_ptr_ptr, storage_ptr_ptr) @@ -118,7 +118,7 @@ set_payload_storage_branch: JUMP set_payload_extension: - // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr,retdest + // stack: node_type, after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest POP // stack: after_node_type, account_ptr_ptr, storage_ptr_ptr, retdest %add_const(2) %mload_trie_data diff --git a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm index 65c9d5287..ce7b9659e 100644 --- a/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm +++ b/evm_arithmetization/src/cpu/kernel/asm/mpt/linked_list/linked_list.asm @@ -330,7 +330,7 @@ global store_initial_slots: PUSH @SEGMENT_STORAGE_LINKED_LIST ADD // stack: cur_len, retdest - PUSH @SEGMENT_STORAGE_LINKED_LIST + PUSH @SEGMENT_STORAGE_LINKED_LIST %next_slot loop_store_initial_slots: @@ -500,12 +500,12 @@ next_node_ok_with_value: DUP5 MSTORE_GENERAL // stack: new_ptr + 1, next_ptr, addr_key, key, value, retdest - // Append the value to `TrieDataSegment` and write the resulting payload_ptr. + // Write the value in the linked list. %increment DUP1 %increment - // stack: new_ptr+3, new_payload_ptr_ptr, next_ptr, addr_key, key, value, retdest - %stack (new_cloned_payload_ptr_ptr, new_payload_ptr_ptr, next_ptr, addr_key, key, value, retdest) - -> (value, new_cloned_payload_ptr_ptr, value, new_payload_ptr_ptr, new_cloned_payload_ptr_ptr, next_ptr, retdest) + // stack: new_ptr+3, new_value_ptr, next_ptr, addr_key, key, value, retdest + %stack (new_cloned_value_ptr, new_value_ptr, next_ptr, addr_key, key, value, retdest) + -> (value, new_cloned_value_ptr, value, new_value_ptr, new_cloned_value_ptr, next_ptr, retdest) MSTORE_GENERAL // Store copied value. MSTORE_GENERAL // Store value.