Fix to add_eth

It was creating a new account with the hash of an empty storage trie, when really it should be a pointer to an empty storage trie. We can use 0 as this pointer since `@SEGMENT_TRIE_DATA[0] = 0 = @MPT_NODE_EMPTY`.

Also a couple tweaks that helped me debug, like moving the memory value range checks from the interpreter into `MemoryState`, so they're done in actual witness generation as well as interpreter tests.
This commit is contained in:
Daniel Lubarov 2022-12-09 18:53:24 -08:00
parent 95eeed46f0
commit 7557f320d4
5 changed files with 37 additions and 39 deletions

View File

@ -97,7 +97,7 @@ global add_eth_new_account:
PUSH 0 %append_to_trie_data // nonce
%append_to_trie_data // balance
// stack: addr, new_account_ptr, retdest
PUSH @EMPTY_NODE_HASH %append_to_trie_data // storage root
PUSH 0 %append_to_trie_data // storage root pointer
PUSH @EMPTY_STRING_HASH %append_to_trie_data // code hash
// stack: addr, new_account_ptr, retdest
%addr_to_state_key

View File

@ -15,7 +15,7 @@ use crate::generation::prover_input::ProverInputFn;
use crate::generation::state::GenerationState;
use crate::generation::GenerationInputs;
use crate::memory::segments::Segment;
use crate::witness::memory::{MemoryContextState, MemorySegmentState, MemoryState};
use crate::witness::memory::{MemoryAddress, MemoryContextState, MemorySegmentState, MemoryState};
use crate::witness::util::stack_peek;
type F = GoldilocksField;
@ -25,22 +25,11 @@ const DEFAULT_HALT_OFFSET: usize = 0xdeadbeef;
impl MemoryState {
fn mload_general(&self, context: usize, segment: Segment, offset: usize) -> U256 {
let value = self.contexts[context].segments[segment as usize].get(offset);
assert!(
value.bits() <= segment.bit_range(),
"Value read from memory exceeds expected range of {:?} segment",
segment
);
value
self.get(MemoryAddress::new(context, segment, offset))
}
fn mstore_general(&mut self, context: usize, segment: Segment, offset: usize, value: U256) {
assert!(
value.bits() <= segment.bit_range(),
"Value written to memory exceeds expected range of {:?} segment",
segment
);
self.contexts[context].segments[segment as usize].set(offset, value)
self.set(MemoryAddress::new(context, segment, offset), value);
}
}
@ -735,13 +724,6 @@ impl<'a> Interpreter<'a> {
let segment = Segment::all()[self.pop().as_usize()];
let offset = self.pop().as_usize();
let value = self.pop();
assert!(
value.bits() <= segment.bit_range(),
"Value {} exceeds {:?} range of {} bits",
value,
segment,
segment.bit_range()
);
self.generation_state
.memory
.mstore_general(context, segment, offset, value);

View File

@ -11,7 +11,6 @@ pub enum MemoryChannel {
use MemoryChannel::{Code, GeneralPurpose};
use crate::memory::segments::Segment;
use crate::util::u256_saturating_cast_usize;
impl MemoryChannel {
pub fn index(&self) -> usize {
@ -42,10 +41,17 @@ impl MemoryAddress {
}
pub(crate) fn new_u256s(context: U256, segment: U256, virt: U256) -> Self {
assert!(context.bits() <= 32, "context too large: {}", context);
assert!(
segment < Segment::COUNT.into(),
"segment too large: {}",
segment
);
assert!(virt.bits() <= 32, "virt too large: {}", virt);
Self {
context: u256_saturating_cast_usize(context),
segment: u256_saturating_cast_usize(segment),
virt: u256_saturating_cast_usize(virt),
context: context.as_usize(),
segment: segment.as_usize(),
virt: virt.as_usize(),
}
}
@ -136,10 +142,27 @@ impl MemoryState {
}
pub fn get(&self, address: MemoryAddress) -> U256 {
self.contexts[address.context].segments[address.segment].get(address.virt)
let segment = Segment::all()[address.segment];
let val = self.contexts[address.context].segments[address.segment].get(address.virt);
assert!(
val.bits() <= segment.bit_range(),
"Value {} exceeds {:?} range of {} bits",
val,
segment,
segment.bit_range()
);
val
}
pub fn set(&mut self, address: MemoryAddress, val: U256) {
let segment = Segment::all()[address.segment];
assert!(
val.bits() <= segment.bit_range(),
"Value {} exceeds {:?} range of {} bits",
val,
segment,
segment.bit_range()
);
self.contexts[address.context].segments[address.segment].set(address.virt, val);
}
}

View File

@ -190,11 +190,8 @@ pub(crate) fn generate_jump<F: Field>(
state.traces.push_memory(log_in0);
state.traces.push_cpu(row);
// TODO: First check if it's a valid JUMPDEST
state.registers.program_counter = u256_saturating_cast_usize(dst);
log::debug!(
"Jumping to {}",
KERNEL.offset_name(state.registers.program_counter)
);
// TODO: Set other cols like input0_upper_sum_inv.
Ok(())
}
@ -211,12 +208,8 @@ pub(crate) fn generate_jumpi<F: Field>(
state.registers.program_counter = if cond.is_zero() {
state.registers.program_counter + 1
} else {
let dst_usize = u256_saturating_cast_usize(dst);
log::debug!(
"Jumping to {}",
KERNEL.offset_name(state.registers.program_counter)
);
dst_usize
// TODO: First check if it's a valid JUMPDEST
u256_saturating_cast_usize(dst)
};
// TODO: Set other cols like input0_upper_sum_inv.
Ok(())

View File

@ -107,8 +107,8 @@ fn test_simple_transfer() -> anyhow::Result<()> {
}
fn eth_to_wei(eth: U256) -> U256 {
// 1 ether = 2^18 wei.
eth << 18
// 1 ether = 10^18 wei.
eth * (U256::from(10u8) << 18)
}
fn init_logger() {