Skip to content
This repository has been archived by the owner on Feb 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request 0xPolygonZero#1209 from topos-protocol/receipts-al…
Browse files Browse the repository at this point in the history
…l-types

Implement receipts of types 1 and 2
  • Loading branch information
LindaGuiga authored Sep 6, 2023
2 parents dd3b61a + bf21b27 commit a709654
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 51 deletions.
16 changes: 16 additions & 0 deletions evm/src/cpu/kernel/asm/core/create_receipt.asm
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ 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)
// stack: first_txn_byte, receipt_ptr, payload_len, status, new_cum_gas, txn_nb, new_cum_gas, txn_nb, retdest
DUP1 %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
Expand Down Expand Up @@ -206,6 +217,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.
Expand Down
125 changes: 76 additions & 49 deletions evm/src/cpu/kernel/asm/mpt/hash/hash_trie_specific.asm
Original file line number Diff line number Diff line change
Expand Up @@ -102,138 +102,165 @@ 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_value, rlp_pos, value_ptr, retdest
// The first value is either the transaction type or the payload length.
// Since the receipt contains at least the 256-bytes long bloom filter, payload_len > 3.
DUP1 %lt_const(3) %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
%stack (rlp_pos, txn_type, old_rlp_pos, value_ptr, retdest) -> (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
Expand Down
13 changes: 11 additions & 2 deletions evm/src/cpu/kernel/asm/mpt/load/load_trie_specific.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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.
%lt_const(3) %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.
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit a709654

Please sign in to comment.