mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-07-30 03:03:27 +00:00
Merge pull request #1399 from topos-protocol/refactor_encode_funcs
Refactor encode funcs
This commit is contained in:
commit
95c83add38
@ -15,6 +15,9 @@ global main:
|
||||
// Initialize the RLP DATA pointer to its initial position (ctx == virt == 0, segment = RLP)
|
||||
PUSH @SEGMENT_RLP_RAW
|
||||
%mstore_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE)
|
||||
|
||||
// Encode constant nodes
|
||||
%initialize_rlp_segment
|
||||
|
||||
// Initialize the state, transaction and receipt trie root pointers.
|
||||
PROVER_INPUT(trie_ptr::state)
|
||||
|
||||
@ -47,10 +47,9 @@ mpt_hash_hash_rlp_after_unpacking:
|
||||
// The result is given as a (value, length) pair, where the length is given
|
||||
// in bytes.
|
||||
//
|
||||
// Pre stack: node_ptr, encode_value, retdest
|
||||
// Post stack: result, result_len
|
||||
// Pre stack: node_ptr, encode_value, cur_len, retdest
|
||||
// Post stack: result, result_len, cur_len
|
||||
global encode_or_hash_node:
|
||||
// stack: node_ptr, encode_value, cur_len, retdest
|
||||
DUP1 %mload_trie_data
|
||||
|
||||
// Check if we're dealing with a concrete node, i.e. not a hash node.
|
||||
@ -118,19 +117,8 @@ encode_node:
|
||||
|
||||
global encode_node_empty:
|
||||
// stack: node_type, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// Then length of `TrieData` is unchanged here.
|
||||
%pop3
|
||||
// stack: cur_len, retdest
|
||||
// An empty node is encoded as a single byte, 0x80, which is the RLP encoding of the empty string.
|
||||
// TODO: Write this byte just once to RLP memory, then we can always return (0, 1).
|
||||
%alloc_rlp_block
|
||||
// stack: rlp_start, cur_len, retdest
|
||||
PUSH 0x80
|
||||
// stack: 0x80, rlp_start, cur_len, retdest
|
||||
DUP2
|
||||
// stack: rlp_start, 0x80, rlp_start, cur_len, retdest
|
||||
%mstore_rlp
|
||||
%stack (rlp_start, cur_len, retdest) -> (retdest, rlp_start, 1, cur_len)
|
||||
%stack (cur_len, retdest) -> (retdest, @ENCODED_EMPTY_NODE_POS, 1, cur_len)
|
||||
JUMP
|
||||
|
||||
global encode_node_branch:
|
||||
@ -141,33 +129,19 @@ global encode_node_branch:
|
||||
SWAP2 %add_const(18) SWAP2
|
||||
// stack: node_payload_ptr, encode_value, cur_len, retdest
|
||||
|
||||
// Get the next unused offset within the encoded child buffers.
|
||||
// Then immediately increment the next unused offset by 16, so any
|
||||
// recursive calls will use nonoverlapping offsets.
|
||||
// TODO: Allocate a block of RLP memory instead?
|
||||
%mload_global_metadata(@GLOBAL_METADATA_TRIE_ENCODED_CHILD_SIZE)
|
||||
DUP1 %add_const(16)
|
||||
%mstore_global_metadata(@GLOBAL_METADATA_TRIE_ENCODED_CHILD_SIZE)
|
||||
// stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// We will call encode_or_hash_node on each child. For the i'th child, we
|
||||
// will store the result in SEGMENT_TRIE_ENCODED_CHILD[base + i], and its length in
|
||||
// SEGMENT_TRIE_ENCODED_CHILD_LEN[base + i].
|
||||
// Allocate a block of RLP memory
|
||||
%alloc_rlp_block DUP1
|
||||
// stack: rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len retdest
|
||||
|
||||
// Call encode_or_hash_node on each child
|
||||
%encode_child(0) %encode_child(1) %encode_child(2) %encode_child(3)
|
||||
%encode_child(4) %encode_child(5) %encode_child(6) %encode_child(7)
|
||||
%encode_child(8) %encode_child(9) %encode_child(10) %encode_child(11)
|
||||
%encode_child(12) %encode_child(13) %encode_child(14) %encode_child(15)
|
||||
// stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
|
||||
// Now, append each child to our RLP tape.
|
||||
%alloc_rlp_block DUP1
|
||||
// stack: rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%append_child(0) %append_child(1) %append_child(2) %append_child(3)
|
||||
%append_child(4) %append_child(5) %append_child(6) %append_child(7)
|
||||
%append_child(8) %append_child(9) %append_child(10) %append_child(11)
|
||||
%append_child(12) %append_child(13) %append_child(14) %append_child(15)
|
||||
// stack: rlp_pos', rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, cur_len, retdest
|
||||
|
||||
%stack (rlp_pos, rlp_start, base_offset, node_payload_ptr)
|
||||
%stack (rlp_pos, rlp_start, node_payload_ptr)
|
||||
-> (node_payload_ptr, rlp_pos, rlp_start)
|
||||
%add_const(16)
|
||||
// stack: value_ptr_ptr, rlp_pos', rlp_start, encode_value, cur_len, retdest
|
||||
@ -199,48 +173,36 @@ encode_node_branch_prepend_prefix:
|
||||
-> (retdest, rlp_prefix_start, rlp_len, cur_len)
|
||||
JUMP
|
||||
|
||||
|
||||
// Part of the encode_node_branch function. Encodes the i'th child.
|
||||
// Stores the result in SEGMENT_TRIE_ENCODED_CHILD[base + i], and its length in
|
||||
// SEGMENT_TRIE_ENCODED_CHILD_LEN[base + i].
|
||||
%macro encode_child(i)
|
||||
// stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// stack: rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest
|
||||
PUSH %%after_encode
|
||||
DUP4 DUP4
|
||||
// stack: node_payload_ptr, encode_value, %%after_encode, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
DUP6 DUP6 DUP6
|
||||
// stack: node_payload_ptr, encode_value, cur_len, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%add_const($i) %mload_trie_data
|
||||
// stack: child_i_ptr, encode_value, %%after_encode, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%stack(child_i_ptr, encode_value, after_encode, base_offset, node_payload_ptr, encode_value, cur_len) -> (child_i_ptr, encode_value, cur_len, after_encode, base_offset, node_payload_ptr, encode_value)
|
||||
// stack: child_i_ptr, encode_value, cur_len, %%after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%stack
|
||||
(child_i_ptr, encode_value, cur_len, after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, cur_len, retdest) ->
|
||||
(child_i_ptr, encode_value, cur_len, after_encode, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest)
|
||||
%jump(encode_or_hash_node)
|
||||
%%after_encode:
|
||||
// stack: result, result_len, cur_len, base_offset, node_payload_ptr, encode_value, retdest
|
||||
%stack(result, result_len, cur_len, base_offset, node_payload_ptr, encode_value) -> (result, result_len, base_offset, node_payload_ptr, encode_value, cur_len)
|
||||
DUP3 %add_const($i) %mstore_kernel(@SEGMENT_TRIE_ENCODED_CHILD)
|
||||
// stack: result_len, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
DUP2 %add_const($i) %mstore_kernel(@SEGMENT_TRIE_ENCODED_CHILD_LEN)
|
||||
// stack: base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%endmacro
|
||||
|
||||
// Part of the encode_node_branch function. Appends the i'th child's RLP.
|
||||
%macro append_child(i)
|
||||
// stack: rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
DUP3 %add_const($i) %mload_kernel(@SEGMENT_TRIE_ENCODED_CHILD) // load result
|
||||
DUP4 %add_const($i) %mload_kernel(@SEGMENT_TRIE_ENCODED_CHILD_LEN) // load result_len
|
||||
// stack: result_len, result, rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// stack: result, result_len, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest
|
||||
// If result_len != 32, result is raw RLP, with an appropriate RLP prefix already.
|
||||
DUP1 %sub_const(32) %jumpi(%%unpack)
|
||||
SWAP1 DUP1 %sub_const(32) %jumpi(%%unpack)
|
||||
// Otherwise, result is a hash, and we need to add the prefix 0x80 + 32 = 160.
|
||||
// stack: result_len, result, rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// stack: result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest
|
||||
PUSH 160
|
||||
DUP4 // rlp_pos
|
||||
DUP5 // rlp_pos
|
||||
%mstore_rlp
|
||||
SWAP2 %increment SWAP2 // rlp_pos += 1
|
||||
SWAP3 %increment SWAP3 // rlp_pos += 1
|
||||
%%unpack:
|
||||
%stack (result_len, result, rlp_pos, rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest)
|
||||
%stack (result_len, result, cur_len, rlp_pos, rlp_start, node_payload_ptr, encode_value, retdest)
|
||||
-> (rlp_pos, result, result_len, %%after_unpacking,
|
||||
rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest)
|
||||
rlp_start, node_payload_ptr, encode_value, cur_len, retdest)
|
||||
%jump(mstore_unpacking)
|
||||
%%after_unpacking:
|
||||
// stack: rlp_pos', rlp_start, base_offset, node_payload_ptr, encode_value, cur_len, retdest
|
||||
// stack: rlp_pos', rlp_start, node_payload_ptr, encode_value, cur_len, retdest
|
||||
%endmacro
|
||||
|
||||
global encode_node_extension:
|
||||
|
||||
@ -101,6 +101,10 @@ 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
|
||||
|
||||
@ -10,6 +10,12 @@
|
||||
// stack: (empty)
|
||||
%endmacro
|
||||
|
||||
%macro initialize_rlp_segment
|
||||
PUSH 0x80
|
||||
PUSH @ENCODED_EMPTY_NODE_POS
|
||||
%mstore_rlp
|
||||
%endmacro
|
||||
|
||||
%macro alloc_rlp_block
|
||||
// stack: (empty)
|
||||
%mload_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE)
|
||||
@ -17,7 +23,7 @@
|
||||
// In our model it's fine to use memory in a sparse way, as long as the gaps aren't larger than
|
||||
// 2^16 or so. So instead of the caller specifying the size of the block they need, we'll just
|
||||
// allocate 0x10000 = 2^16 bytes, much larger than any RLP blob the EVM could possibly create.
|
||||
DUP1 %add_const(0x10000)
|
||||
DUP1 %add_const(@MAX_RLP_BLOB_SIZE)
|
||||
// stack: block_end, block_start
|
||||
%mstore_global_metadata(@GLOBAL_METADATA_RLP_DATA_SIZE)
|
||||
// stack: block_start
|
||||
|
||||
@ -37,10 +37,6 @@ pub(crate) enum GlobalMetadata {
|
||||
TransactionTrieRootDigestAfter,
|
||||
ReceiptTrieRootDigestAfter,
|
||||
|
||||
/// The sizes of the `TrieEncodedChild` and `TrieEncodedChildLen` buffers. In other words, the
|
||||
/// next available offset in these buffers.
|
||||
TrieEncodedChildSize,
|
||||
|
||||
// Block metadata.
|
||||
BlockBeneficiary,
|
||||
BlockTimestamp,
|
||||
@ -98,7 +94,7 @@ pub(crate) enum GlobalMetadata {
|
||||
}
|
||||
|
||||
impl GlobalMetadata {
|
||||
pub(crate) const COUNT: usize = 48;
|
||||
pub(crate) const COUNT: usize = 47;
|
||||
|
||||
/// Unscales this virtual offset by their respective `Segment` value.
|
||||
pub(crate) const fn unscale(&self) -> usize {
|
||||
@ -120,7 +116,6 @@ impl GlobalMetadata {
|
||||
Self::StateTrieRootDigestAfter,
|
||||
Self::TransactionTrieRootDigestAfter,
|
||||
Self::ReceiptTrieRootDigestAfter,
|
||||
Self::TrieEncodedChildSize,
|
||||
Self::BlockBeneficiary,
|
||||
Self::BlockTimestamp,
|
||||
Self::BlockNumber,
|
||||
@ -174,7 +169,6 @@ impl GlobalMetadata {
|
||||
Self::StateTrieRootDigestAfter => "GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER",
|
||||
Self::TransactionTrieRootDigestAfter => "GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER",
|
||||
Self::ReceiptTrieRootDigestAfter => "GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER",
|
||||
Self::TrieEncodedChildSize => "GLOBAL_METADATA_TRIE_ENCODED_CHILD_SIZE",
|
||||
Self::BlockBeneficiary => "GLOBAL_METADATA_BLOCK_BENEFICIARY",
|
||||
Self::BlockTimestamp => "GLOBAL_METADATA_BLOCK_TIMESTAMP",
|
||||
Self::BlockNumber => "GLOBAL_METADATA_BLOCK_NUMBER",
|
||||
|
||||
@ -2,6 +2,7 @@ use std::collections::HashMap;
|
||||
|
||||
use ethereum_types::U256;
|
||||
use hex_literal::hex;
|
||||
use static_assertions::const_assert;
|
||||
|
||||
use crate::cpu::kernel::constants::context_metadata::ContextMetadata;
|
||||
use crate::cpu::kernel::constants::global_metadata::GlobalMetadata;
|
||||
@ -89,12 +90,23 @@ pub(crate) fn evm_constants() -> HashMap<String, U256> {
|
||||
c
|
||||
}
|
||||
|
||||
const MISC_CONSTANTS: [(&str, [u8; 32]); 1] = [
|
||||
const MISC_CONSTANTS: [(&str, [u8; 32]); 3] = [
|
||||
// Base for limbs used in bignum arithmetic.
|
||||
(
|
||||
"BIGNUM_LIMB_BASE",
|
||||
hex!("0000000000000000000000000000000100000000000000000000000000000000"),
|
||||
),
|
||||
// Position in SEGMENT_RLP_RAW where the empty node encoding is stored. It is
|
||||
// equal to u32::MAX + @SEGMENT_RLP_RAW so that all rlp pointers are much smaller than that.
|
||||
(
|
||||
"ENCODED_EMPTY_NODE_POS",
|
||||
hex!("0000000000000000000000000000000000000000000000000000000CFFFFFFFF"),
|
||||
),
|
||||
// 0x10000 = 2^16 bytes, much larger than any RLP blob the EVM could possibly create.
|
||||
(
|
||||
"MAX_RLP_BLOB_SIZE",
|
||||
hex!("0000000000000000000000000000000000000000000000000000000000010000"),
|
||||
),
|
||||
];
|
||||
|
||||
const HASH_CONSTANTS: [(&str, [u8; 32]); 2] = [
|
||||
|
||||
@ -140,12 +140,14 @@ enum InterpreterMemOpKind {
|
||||
|
||||
impl<'a> Interpreter<'a> {
|
||||
pub(crate) fn new_with_kernel(initial_offset: usize, initial_stack: Vec<U256>) -> Self {
|
||||
Self::new(
|
||||
let mut result = Self::new(
|
||||
&KERNEL.code,
|
||||
initial_offset,
|
||||
initial_stack,
|
||||
&KERNEL.prover_inputs,
|
||||
)
|
||||
);
|
||||
result.initialize_rlp_segment();
|
||||
result
|
||||
}
|
||||
|
||||
pub(crate) fn new(
|
||||
@ -1193,6 +1195,14 @@ impl<'a> Interpreter<'a> {
|
||||
}
|
||||
self.generation_state.registers.context = context;
|
||||
}
|
||||
|
||||
/// Writes the encoding of 0 to position @ENCODED_EMPTY_NODE_POS.
|
||||
pub(crate) fn initialize_rlp_segment(&mut self) {
|
||||
self.generation_state.memory.set(
|
||||
MemoryAddress::new(0, Segment::RlpRaw, 0xFFFFFFFF),
|
||||
128.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Computes the two's complement of the given integer.
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use ethereum_types::U256;
|
||||
use num::traits::AsPrimitive;
|
||||
|
||||
pub(crate) const SEGMENT_SCALING_FACTOR: usize = 32;
|
||||
@ -39,46 +40,40 @@ pub(crate) enum Segment {
|
||||
RlpRaw = 12 << SEGMENT_SCALING_FACTOR,
|
||||
/// Contains all trie data. It is owned by the kernel, so it only lives on context 0.
|
||||
TrieData = 13 << SEGMENT_SCALING_FACTOR,
|
||||
/// A buffer used to store the encodings of a branch node's children.
|
||||
TrieEncodedChild = 14 << SEGMENT_SCALING_FACTOR,
|
||||
/// A buffer used to store the lengths of the encodings of a branch node's children.
|
||||
TrieEncodedChildLen = 15 << SEGMENT_SCALING_FACTOR,
|
||||
/// A table of values 2^i for i=0..255 for use with shift
|
||||
/// instructions; initialised by `kernel/asm/shift.asm::init_shift_table()`.
|
||||
ShiftTable = 16 << SEGMENT_SCALING_FACTOR,
|
||||
JumpdestBits = 17 << SEGMENT_SCALING_FACTOR,
|
||||
EcdsaTable = 18 << SEGMENT_SCALING_FACTOR,
|
||||
BnWnafA = 19 << SEGMENT_SCALING_FACTOR,
|
||||
BnWnafB = 20 << SEGMENT_SCALING_FACTOR,
|
||||
BnTableQ = 21 << SEGMENT_SCALING_FACTOR,
|
||||
BnPairing = 22 << SEGMENT_SCALING_FACTOR,
|
||||
ShiftTable = 14 << SEGMENT_SCALING_FACTOR,
|
||||
JumpdestBits = 15 << SEGMENT_SCALING_FACTOR,
|
||||
EcdsaTable = 16 << SEGMENT_SCALING_FACTOR,
|
||||
BnWnafA = 17 << SEGMENT_SCALING_FACTOR,
|
||||
BnWnafB = 18 << SEGMENT_SCALING_FACTOR,
|
||||
BnTableQ = 19 << SEGMENT_SCALING_FACTOR,
|
||||
BnPairing = 20 << SEGMENT_SCALING_FACTOR,
|
||||
/// List of addresses that have been accessed in the current transaction.
|
||||
AccessedAddresses = 23 << SEGMENT_SCALING_FACTOR,
|
||||
AccessedAddresses = 21 << SEGMENT_SCALING_FACTOR,
|
||||
/// List of storage keys that have been accessed in the current transaction.
|
||||
AccessedStorageKeys = 24 << SEGMENT_SCALING_FACTOR,
|
||||
AccessedStorageKeys = 22 << SEGMENT_SCALING_FACTOR,
|
||||
/// List of addresses that have called SELFDESTRUCT in the current transaction.
|
||||
SelfDestructList = 25 << SEGMENT_SCALING_FACTOR,
|
||||
SelfDestructList = 23 << SEGMENT_SCALING_FACTOR,
|
||||
/// Contains the bloom filter of a transaction.
|
||||
TxnBloom = 26 << SEGMENT_SCALING_FACTOR,
|
||||
TxnBloom = 24 << SEGMENT_SCALING_FACTOR,
|
||||
/// Contains the bloom filter present in the block header.
|
||||
GlobalBlockBloom = 27 << SEGMENT_SCALING_FACTOR,
|
||||
GlobalBlockBloom = 25 << SEGMENT_SCALING_FACTOR,
|
||||
/// List of log pointers pointing to the LogsData segment.
|
||||
Logs = 28 << SEGMENT_SCALING_FACTOR,
|
||||
LogsData = 29 << SEGMENT_SCALING_FACTOR,
|
||||
Logs = 26 << SEGMENT_SCALING_FACTOR,
|
||||
LogsData = 27 << SEGMENT_SCALING_FACTOR,
|
||||
/// Journal of state changes. List of pointers to `JournalData`. Length in `GlobalMetadata`.
|
||||
Journal = 30 << SEGMENT_SCALING_FACTOR,
|
||||
JournalData = 31 << SEGMENT_SCALING_FACTOR,
|
||||
JournalCheckpoints = 32 << SEGMENT_SCALING_FACTOR,
|
||||
Journal = 28 << SEGMENT_SCALING_FACTOR,
|
||||
JournalData = 29 << SEGMENT_SCALING_FACTOR,
|
||||
JournalCheckpoints = 30 << SEGMENT_SCALING_FACTOR,
|
||||
/// List of addresses that have been touched in the current transaction.
|
||||
TouchedAddresses = 33 << SEGMENT_SCALING_FACTOR,
|
||||
TouchedAddresses = 31 << SEGMENT_SCALING_FACTOR,
|
||||
/// List of checkpoints for the current context. Length in `ContextMetadata`.
|
||||
ContextCheckpoints = 34 << SEGMENT_SCALING_FACTOR,
|
||||
ContextCheckpoints = 32 << SEGMENT_SCALING_FACTOR,
|
||||
/// List of 256 previous block hashes.
|
||||
BlockHashes = 35 << SEGMENT_SCALING_FACTOR,
|
||||
BlockHashes = 33 << SEGMENT_SCALING_FACTOR,
|
||||
}
|
||||
|
||||
impl Segment {
|
||||
pub(crate) const COUNT: usize = 36;
|
||||
pub(crate) const COUNT: usize = 34;
|
||||
|
||||
/// Unscales this segment by `SEGMENT_SCALING_FACTOR`.
|
||||
pub(crate) const fn unscale(&self) -> usize {
|
||||
@ -101,8 +96,6 @@ impl Segment {
|
||||
Self::TxnData,
|
||||
Self::RlpRaw,
|
||||
Self::TrieData,
|
||||
Self::TrieEncodedChild,
|
||||
Self::TrieEncodedChildLen,
|
||||
Self::ShiftTable,
|
||||
Self::JumpdestBits,
|
||||
Self::EcdsaTable,
|
||||
@ -143,8 +136,6 @@ impl Segment {
|
||||
Segment::TxnData => "SEGMENT_TXN_DATA",
|
||||
Segment::RlpRaw => "SEGMENT_RLP_RAW",
|
||||
Segment::TrieData => "SEGMENT_TRIE_DATA",
|
||||
Segment::TrieEncodedChild => "SEGMENT_TRIE_ENCODED_CHILD",
|
||||
Segment::TrieEncodedChildLen => "SEGMENT_TRIE_ENCODED_CHILD_LEN",
|
||||
Segment::ShiftTable => "SEGMENT_SHIFT_TABLE",
|
||||
Segment::JumpdestBits => "SEGMENT_JUMPDEST_BITS",
|
||||
Segment::EcdsaTable => "SEGMENT_KERNEL_ECDSA_TABLE",
|
||||
@ -184,8 +175,6 @@ impl Segment {
|
||||
Segment::TxnData => 8,
|
||||
Segment::RlpRaw => 8,
|
||||
Segment::TrieData => 256,
|
||||
Segment::TrieEncodedChild => 256,
|
||||
Segment::TrieEncodedChildLen => 6,
|
||||
Segment::ShiftTable => 256,
|
||||
Segment::JumpdestBits => 1,
|
||||
Segment::EcdsaTable => 256,
|
||||
@ -208,4 +197,17 @@ impl Segment {
|
||||
Segment::BlockHashes => 256,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn constant(&self, virt: usize) -> Option<U256> {
|
||||
match self {
|
||||
Segment::RlpRaw => {
|
||||
if virt == 0xFFFFFFFF {
|
||||
Some(U256::from(0x80))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,6 +190,11 @@ impl MemoryState {
|
||||
}
|
||||
|
||||
let segment = Segment::all()[address.segment];
|
||||
|
||||
if let Some(constant) = Segment::constant(&segment, address.virt) {
|
||||
return constant;
|
||||
}
|
||||
|
||||
let val = self.contexts[address.context].segments[address.segment].get(address.virt);
|
||||
assert!(
|
||||
val.bits() <= segment.bit_range(),
|
||||
@ -207,6 +212,15 @@ impl MemoryState {
|
||||
}
|
||||
|
||||
let segment = Segment::all()[address.segment];
|
||||
|
||||
if let Some(constant) = Segment::constant(&segment, address.virt) {
|
||||
assert!(
|
||||
constant == val,
|
||||
"Attempting to set constant {} to incorrect value",
|
||||
address.virt
|
||||
);
|
||||
return;
|
||||
}
|
||||
assert!(
|
||||
val.bits() <= segment.bit_range(),
|
||||
"Value {} exceeds {:?} range of {} bits",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user