Implement receipts of types 1 and 2

This commit is contained in:
Linda Guiga 2023-09-04 11:15:04 +01:00
parent 760f09a8aa
commit 9ba2b895b9
No known key found for this signature in database
3 changed files with 106 additions and 51 deletions

View File

@ -53,6 +53,18 @@ process_receipt_after_bloom:
// stack: payload_len, status, new_cum_gas, txn_nb, new_cum_gas, txn_nb, retdest
// Now we can write the receipt in MPT_TRIE_DATA.
%get_trie_data_size
// stack: receipt_ptr, payload_len, status, new_cum_gas, txn_nb, new_cum_gas, txn_nb, retdest
// Write transaction type if necessary. RLP_RAW contains, at index 0, the current transaction type.
PUSH 0
%mload_kernel(@SEGMENT_RLP_RAW)
DUP1
// stack: first_txn_byte, first_txn_byte, receipt_ptr, payload_len, status, new_cum_gas, txn_nb, new_cum_gas, txn_nb, retdest
%eq_const(1) %jumpi(receipt_nonzero_type)
DUP1 %eq_const(2) %jumpi(receipt_nonzero_type)
// If we are here, we are dealing with a legacy transaction, and we do not need to write the type.
POP
process_receipt_after_type:
// stack: receipt_ptr, payload_len, status, new_cum_gas, txn_nb, new_cum_gas, txn_nb, retdest
// Write payload_len.
SWAP1
@ -206,6 +218,11 @@ process_receipt_after_write:
%stack (new_cum_gas, txn_nb, retdest) -> (retdest, new_cum_gas, txn_nb)
JUMP
receipt_nonzero_type:
// stack: txn_type, receipt_ptr, payload_len, status, new_cum_gas, txn_nb, new_cum_gas, txn_nb, retdest
%append_to_trie_data
%jump(process_receipt_after_type)
failed_receipt:
// stack: status, new_cum_gas, txn_nb
// It is the receipt of a failed transaction, so set num_logs to 0. This will also lead to Bloom filter = 0.

View File

@ -102,138 +102,167 @@ global encode_txn:
// We assume a receipt in memory is stored as:
// [payload_len, status, cum_gas_used, bloom, logs_payload_len, num_logs, [logs]].
// A log is [payload_len, address, num_topics, [topics], data_len, [data]].
// TODO: support type >0 receipts.
global encode_receipt:
// stack: rlp_pos, value_ptr, retdest
// There is a double encoding! What we compute is:
// RLP(RLP(receipt)).
// either RLP(RLP(receipt)) for Legacy transactions or RLP(txn_type||RLP(receipt)) for transactions of type 1 or 2.
// First encode the wrapper prefix.
DUP2 %mload_trie_data
// stack: first_byte, rlp_pos, value_ptr, retdest
// The first byte is either the transaction type or the first byte of the RLP encoding.
DUP1 PUSH 3 GT %jumpi(encode_nonzero_receipt_type)
// If we are here, then the first byte is the payload length.
%rlp_list_len
// stack: rlp_receipt_len, rlp_pos, value_ptr, retdest
SWAP1 %encode_rlp_multi_byte_string_prefix
// stack: rlp_pos, value_ptr, retdest
encode_receipt_after_type:
// stack: rlp_pos, payload_len_ptr, retdest
// Then encode the receipt prefix.
// `payload_ptr` is either `value_ptr` or `value_ptr+1`, depending on the transaction type.
DUP2 %mload_trie_data
// stack: payload_len, rlp_pos, value_ptr, retdest
// stack: payload_len, rlp_pos, payload_len_ptr, retdest
SWAP1 %encode_rlp_list_prefix
// stack: rlp_pos, value_ptr, retdest
// stack: rlp_pos, payload_len_ptr, retdest
// Encode status.
DUP2 %increment %mload_trie_data
// stack: status, rlp_pos, value_ptr, retdest
// stack: status, rlp_pos, payload_len_ptr, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos, value_ptr, retdest
// stack: rlp_pos, payload_len_ptr, retdest
// Encode cum_gas_used.
DUP2 %add_const(2) %mload_trie_data
// stack: cum_gas_used, rlp_pos, value_ptr, retdest
// stack: cum_gas_used, rlp_pos, payload_len_ptr, retdest
SWAP1 %encode_rlp_scalar
// stack: rlp_pos, value_ptr, retdest
// stack: rlp_pos, payload_len_ptr, retdest
// Encode bloom.
PUSH 256 // Bloom length.
DUP3 %add_const(3) PUSH @SEGMENT_TRIE_DATA PUSH 0 // MPT src address.
DUP5
// stack: rlp_pos, SRC, 256, rlp_pos, value_ptr, retdest
// stack: rlp_pos, SRC, 256, rlp_pos, payload_len_ptr, retdest
%encode_rlp_string
// stack: rlp_pos, old_rlp_pos, value_ptr, retdest
// stack: rlp_pos, old_rlp_pos, payload_len_ptr, retdest
SWAP1 POP
// stack: rlp_pos, value_ptr, retdest
// stack: rlp_pos, payload_len_ptr, retdest
// Encode logs prefix.
DUP2 %add_const(259) %mload_trie_data
// stack: logs_payload_len, rlp_pos, value_ptr, retdest
// stack: logs_payload_len, rlp_pos, payload_len_ptr, retdest
SWAP1 %encode_rlp_list_prefix
// stack: rlp_pos, value_ptr, retdest
// stack: rlp_pos, payload_len_ptr, retdest
DUP2 %add_const(261)
// stack: logs_ptr, rlp_pos, value_ptr, retdest
// stack: logs_ptr, rlp_pos, payload_len_ptr, retdest
DUP3 %add_const(260) %mload_trie_data
// stack: num_logs, logs_ptr, rlp_pos, value_ptr, retdest
// stack: num_logs, logs_ptr, rlp_pos, payload_len_ptr, retdest
PUSH 0
encode_receipt_logs_loop:
// stack: i, num_logs, current_log_ptr, rlp_pos, value_ptr, retdest
// stack: i, num_logs, current_log_ptr, rlp_pos, payload_len_ptr, retdest
DUP2 DUP2 EQ
// stack: i == num_logs, i, num_logs, current_log_ptr, rlp_pos, value_ptr, retdest
// stack: i == num_logs, i, num_logs, current_log_ptr, rlp_pos, payload_len_ptr, retdest
%jumpi(encode_receipt_end)
// stack: i, num_logs, current_log_ptr, rlp_pos, value_ptr, retdest
// stack: i, num_logs, current_log_ptr, rlp_pos, payload_len_ptr, retdest
DUP3 DUP5
// stack: rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
// Encode log prefix.
DUP2 %mload_trie_data
// stack: payload_len, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: payload_len, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
SWAP1 %encode_rlp_list_prefix
// stack: rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
// Encode address.
DUP2 %increment %mload_trie_data
// stack: address, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: address, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
SWAP1 %encode_rlp_160
// stack: rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
DUP2 %add_const(2) %mload_trie_data
// stack: num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
// Encode topics prefix.
DUP1 %mul_const(33)
// stack: topics_payload_len, num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: topics_payload_len, num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
DUP3 %encode_rlp_list_prefix
// stack: new_rlp_pos, num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: new_rlp_pos, num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
SWAP2 POP
// stack: num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: num_topics, rlp_pos, current_log_ptr, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
SWAP2 %add_const(3)
// stack: topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
PUSH 0
encode_receipt_topics_loop:
// stack: j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
DUP4 DUP2 EQ
// stack: j == num_topics, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: j == num_topics, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
%jumpi(encode_receipt_topics_end)
// stack: j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
DUP2 DUP2 ADD
%mload_trie_data
// stack: current_topic, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: current_topic, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
DUP4
// stack: rlp_pos, current_topic, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: rlp_pos, current_topic, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
%encode_rlp_256
// stack: new_rlp_pos, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: new_rlp_pos, j, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
SWAP3 POP
// stack: j, topics_ptr, new_rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: j, topics_ptr, new_rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
%increment
%jump(encode_receipt_topics_loop)
encode_receipt_topics_end:
// stack: num_topics, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: num_topics, topics_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
ADD
// stack: data_len_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, value_ptr, retdest
// stack: data_len_ptr, rlp_pos, num_topics, i, num_logs, current_log_ptr, old_rlp_pos, payload_len_ptr, retdest
SWAP5 POP
// stack: rlp_pos, num_topics, i, num_logs, data_len_ptr, old_rlp_pos, value_ptr, retdest
// stack: rlp_pos, num_topics, i, num_logs, data_len_ptr, old_rlp_pos, payload_len_ptr, retdest
SWAP5 POP
// stack: num_topics, i, num_logs, data_len_ptr, rlp_pos, value_ptr, retdest
// stack: num_topics, i, num_logs, data_len_ptr, rlp_pos, payload_len_ptr, retdest
POP
// stack: i, num_logs, data_len_ptr, rlp_pos, value_ptr, retdest
// stack: i, num_logs, data_len_ptr, rlp_pos, payload_len_ptr, retdest
// Encode data prefix.
DUP3 %mload_trie_data
// stack: data_len, i, num_logs, data_len_ptr, rlp_pos, value_ptr, retdest
// stack: data_len, i, num_logs, data_len_ptr, rlp_pos, payload_len_ptr, retdest
DUP4 %increment DUP2 ADD
// stack: next_log_ptr, data_len, i, num_logs, data_len_ptr, rlp_pos, value_ptr, retdest
// stack: next_log_ptr, data_len, i, num_logs, data_len_ptr, rlp_pos, payload_len_ptr, retdest
SWAP4 %increment
// stack: data_ptr, data_len, i, num_logs, next_log_ptr, rlp_pos, value_ptr, retdest
// stack: data_ptr, data_len, i, num_logs, next_log_ptr, rlp_pos, payload_len_ptr, retdest
PUSH @SEGMENT_TRIE_DATA PUSH 0
// stack: SRC, data_len, i, num_logs, next_log_ptr, rlp_pos, value_ptr, retdest
// stack: SRC, data_len, i, num_logs, next_log_ptr, rlp_pos, payload_len_ptr, retdest
DUP8
// stack: rlp_pos, SRC, data_len, i, num_logs, next_log_ptr, rlp_pos, value_ptr, retdest
// stack: rlp_pos, SRC, data_len, i, num_logs, next_log_ptr, rlp_pos, payload_len_ptr, retdest
%encode_rlp_string
// stack: new_rlp_pos, i, num_logs, next_log_ptr, rlp_pos, value_ptr, retdest
// stack: new_rlp_pos, i, num_logs, next_log_ptr, rlp_pos, payload_len_ptr, retdest
SWAP4 POP
// stack: i, num_logs, next_log_ptr, new_rlp_pos, value_ptr, retdest
// stack: i, num_logs, next_log_ptr, new_rlp_pos, payload_len_ptr, retdest
%increment
%jump(encode_receipt_logs_loop)
encode_receipt_end:
// stack: num_logs, num_logs, current_log_ptr, rlp_pos, value_ptr, retdest
// stack: num_logs, num_logs, current_log_ptr, rlp_pos, payload_len_ptr, retdest
%pop3
// stack: rlp_pos, value_ptr, retdest
// stack: rlp_pos, payload_len_ptr, retdest
SWAP1 POP
// stack: rlp_pos, retdest
SWAP1
JUMP
encode_nonzero_receipt_type:
// stack: txn_type, rlp_pos, value_ptr, retdest
DUP3 %increment %mload_trie_data
// stack: payload_len, txn_type, rlp_pos, value_ptr, retdest
// The transaction type is encoded in 1 byte
%increment %rlp_list_len
// stack: rlp_receipt_len, txn_type, rlp_pos, value_ptr, retdest
DUP3 %encode_rlp_multi_byte_string_prefix
// stack: rlp_pos, txn_type, old_rlp_pos, value_ptr, retdest
DUP2 DUP2
%mstore_rlp
%increment
// stack: rlp_pos, txn_type, old_rlp_pos, value_ptr, retdest
SWAP1 POP
// stack: rlp_pos, old_rlp_pos, value_ptr, retdest
SWAP1 POP
// stack: rlp_pos, value_ptr, retdest
// We replace `value_ptr` with `paylaod_len_ptr` so we can encode the rest of the data more easily
SWAP1 %increment SWAP1
// stack: rlp_pos, payload_len_ptr, retdest
%jump(encode_receipt_after_type)
global encode_storage_value:
// stack: rlp_pos, value_ptr, retdest
SWAP1 %mload_trie_data SWAP1

View File

@ -33,9 +33,13 @@ global mpt_load_txn_trie_value:
global mpt_load_receipt_trie_value:
// stack: retdest
// Load first byte. It is either `payload_len` or the transaction type.
PROVER_INPUT(mpt) DUP1 %append_to_trie_data
// If the first byte is less than 3, then it is the transaction type, equal to either 1 or 2.
// In that case, we still need to load the payload length.
PUSH 3 GT %jumpi(mpt_load_payload_len)
// Load payload_len.
PROVER_INPUT(mpt) %append_to_trie_data
mpt_load_after_type:
// Load status.
PROVER_INPUT(mpt) %append_to_trie_data
// Load cum_gas_used.
@ -117,6 +121,11 @@ mpt_load_receipt_trie_value_end:
%pop2
JUMP
mpt_load_payload_len:
// stack: retdest
PROVER_INPUT(mpt) %append_to_trie_data
%jump(mpt_load_after_type)
global mpt_load_storage_trie_value:
// stack: retdest
PROVER_INPUT(mpt)