2024-01-09 11:32:31 +01:00

92 lines
3.9 KiB
NASM

global main:
// First, hash the kernel code
%mload_global_metadata(@GLOBAL_METADATA_KERNEL_LEN)
PUSH 0
// stack: addr, len
KECCAK_GENERAL
// stack: hash
%mload_global_metadata(@GLOBAL_METADATA_KERNEL_HASH)
// stack: expected_hash, hash
%assert_eq
// Initialise the shift table
%shift_table_init
// 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)
%mstore_global_metadata(@GLOBAL_METADATA_STATE_TRIE_ROOT)
PROVER_INPUT(trie_ptr::txn)
%mstore_global_metadata(@GLOBAL_METADATA_TXN_TRIE_ROOT)
PROVER_INPUT(trie_ptr::receipt)
%mstore_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_ROOT)
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
// 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
%mstore_global_metadata(@GLOBAL_METADATA_TRIE_DATA_SIZE)
global start_txn:
// stack: (empty)
// The special case of an empty trie (i.e. for the first transaction)
// is handled outside of the kernel.
%mload_global_metadata(@GLOBAL_METADATA_TXN_NUMBER_BEFORE)
// stack: txn_nb
%mload_global_metadata(@GLOBAL_METADATA_BLOCK_GAS_USED_BEFORE)
// stack: init_used_gas, txn_nb
DUP2 %scalar_to_rlp
// stack: txn_counter, init_gas_used, txn_nb
DUP1 %num_bytes %mul_const(2)
// stack: num_nibbles, txn_counter, init_gas_used, txn_nb
SWAP2
// stack: init_gas_used, txn_counter, num_nibbles, txn_nb
// If the prover has no txn for us to process, halt.
PROVER_INPUT(no_txn)
%jumpi(execute_withdrawals)
// Call route_txn. When we return, we will process the txn receipt.
PUSH txn_after
// stack: retdest, prev_gas_used, txn_counter, num_nibbles, txn_nb
DUP4 DUP4 %increment_bounded_rlp
%stack (next_txn_counter, next_num_nibbles, retdest, prev_gas_used, txn_counter, num_nibbles) -> (txn_counter, num_nibbles, retdest, prev_gas_used, txn_counter, num_nibbles, next_txn_counter, next_num_nibbles)
%jump(route_txn)
global txn_after:
// stack: success, leftover_gas, cur_cum_gas, prev_txn_counter, prev_num_nibbles, txn_counter, num_nibbles, txn_nb
%process_receipt
// stack: new_cum_gas, txn_counter, num_nibbles, txn_nb
SWAP3 %increment SWAP3
global execute_withdrawals:
// stack: cum_gas, txn_counter, num_nibbles, txn_nb
%withdrawals
global hash_final_tries:
// 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
%pop3
PUSH 1 // initial trie data length
%mpt_hash_state_trie %mload_global_metadata(@GLOBAL_METADATA_STATE_TRIE_DIGEST_AFTER) %assert_eq
%mpt_hash_txn_trie %mload_global_metadata(@GLOBAL_METADATA_TXN_TRIE_DIGEST_AFTER) %assert_eq
%mpt_hash_receipt_trie %mload_global_metadata(@GLOBAL_METADATA_RECEIPT_TRIE_DIGEST_AFTER) %assert_eq
// We don't need the trie data length here.
POP
%jump(halt)