Minor fixes to returndata and create (#1043)

* Fix returndata

* Add AccountCreated event

* returndatacopy_afterFailing_create.json passes

* Fix
This commit is contained in:
wborgeaud 2023-05-17 10:06:12 +02:00 committed by GitHub
parent ce6ac9f888
commit 84c156066b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 76 additions and 16 deletions

View File

@ -145,6 +145,7 @@ pub(crate) fn combined_kernel() -> Kernel {
include_str!("asm/journal/storage_loaded.asm"),
include_str!("asm/journal/code_change.asm"),
include_str!("asm/journal/refund.asm"),
include_str!("asm/journal/account_created.asm"),
include_str!("asm/journal/revert.asm"),
include_str!("asm/transactions/common_decoding.asm"),
include_str!("asm/transactions/router.asm"),

View File

@ -230,6 +230,8 @@ call_insufficient_balance:
%stack (new_ctx, kexit_info, callgas, address, value, args_offset, args_size, ret_offset, ret_size) ->
(callgas, kexit_info, 0)
%shl_const(192) SWAP1 SUB
// stack: kexit_info', 0
%mstore_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 0)
EXIT_KERNEL
// Set @CTX_METADATA_STATIC to 1. Note that there is no corresponding set_static_false routine

View File

@ -70,11 +70,15 @@ global create_common:
// stack: address, value, code_offset, code_len, kexit_info
DUP1 %insert_accessed_addresses_no_return
// TODO: Check call stack depth.
// TODO: Check balance of caller first.
// Increment the sender's nonce.
%address
%increment_nonce
// stack: address, value, code_offset, code_len, kexit_info
%checkpoint
// Deduct value from the caller.
DUP2
%address
@ -133,13 +137,15 @@ run_constructor:
// (Old context) stack: new_ctx, address, kexit_info
after_constructor:
// stack: success, leftover_gas, new_ctx, address, kexit_info
DUP1 ISZERO %jumpi(after_constructor_failed)
%pop_checkpoint
// stack: success, leftover_gas, new_ctx, address, kexit_info
SWAP2
// stack: new_ctx, leftover_gas, success, address, kexit_info
POP
// TODO: Skip blocks below if success is false.
// EIP-3541: Reject new contract code starting with the 0xEF byte
PUSH 0 %mload_current(@SEGMENT_RETURNDATA) %eq_const(0xEF) %jumpi(fault_exception)
@ -168,6 +174,7 @@ after_constructor:
// Set the return data size to 0.
%mstore_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 0)
after_constructor_contd:
// stack: leftover_gas, success, address, kexit_info
%shl_const(192)
// stack: leftover_gas << 192, success, address, kexit_info
@ -181,6 +188,11 @@ after_constructor:
// stack: kexit_info, address_if_success
EXIT_KERNEL
after_constructor_failed:
%revert_checkpoint
%stack (success, leftover_gas, new_ctx, address, kexit_info) -> (leftover_gas, success, address, kexit_info)
%jump(after_constructor_contd)
%macro set_codehash
%stack (addr, codehash) -> (addr, codehash, %%after)
%jump(set_codehash)

View File

@ -3,6 +3,7 @@
// Post stack: status
%macro create_contract_account
// stack: value, address
DUP2 %journal_add_account_created
DUP2 %insert_touched_addresses
DUP2 %mpt_read_state_trie
// stack: existing_account_ptr, value, address

View File

@ -139,7 +139,7 @@ global sys_revert:
sys_revert_finish:
%leftover_gas
// stack: leftover_gas
// TODO: Revert state changes.
%revert_checkpoint
PUSH 0 // success
%jump(terminate_common)

View File

@ -0,0 +1,13 @@
// struct AccountCreated { address }
%macro journal_add_account_created
%journal_add_1(@JOURNAL_ENTRY_ACCOUNT_CREATED)
%endmacro
global revert_account_created:
// stack: entry_type, ptr, retdest
POP
%journal_load_1
// stack: address, retdest
%delete_account
JUMP

View File

@ -15,6 +15,7 @@
DUP1 %eq_const(@JOURNAL_ENTRY_STORAGE_LOADED) %jumpi(revert_storage_loaded)
DUP1 %eq_const(@JOURNAL_ENTRY_CODE_CHANGE) %jumpi(revert_code_change)
DUP1 %eq_const(@JOURNAL_ENTRY_REFUND) %jumpi(revert_refund)
DUP1 %eq_const(@JOURNAL_ENTRY_ACCOUNT_CREATED) %jumpi(revert_account_created)
PANIC // This should never happen.
%%after:
// stack: journal_size-1

View File

@ -126,7 +126,7 @@ sys_calldataload_after_mload_packing:
PUSH @GAS_VERYLOW
DUP5
// stack: size, Gverylow, kexit_info, dest_offset, offset, size
ISZERO %jumpi(%%wcopy_empty)
ISZERO %jumpi(wcopy_empty)
// stack: Gverylow, kexit_info, dest_offset, offset, size
DUP5 %num_bytes_to_num_words %mul_const(@GAS_COPY) ADD %charge_gas
@ -140,31 +140,31 @@ sys_calldataload_after_mload_packing:
// stack: total_size, kexit_info, dest_offset, offset, size
DUP4
// stack: offset, total_size, kexit_info, dest_offset, offset, size
GT %jumpi(%%wcopy_large_offset)
GT %jumpi(wcopy_large_offset)
GET_CONTEXT
%stack (context, kexit_info, dest_offset, offset, size) ->
(context, @SEGMENT_MAIN_MEMORY, dest_offset, context, $segment, offset, size, %%after, kexit_info)
(context, @SEGMENT_MAIN_MEMORY, dest_offset, context, $segment, offset, size, wcopy_after, kexit_info)
%jump(memcpy)
%endmacro
%%after:
// stack: kexit_info
EXIT_KERNEL
%%wcopy_empty:
wcopy_empty:
// stack: Gverylow, kexit_info, dest_offset, offset, size
%charge_gas
%stack (kexit_info, dest_offset, offset, size) -> (kexit_info)
EXIT_KERNEL
%%wcopy_large_offset:
wcopy_large_offset:
// offset is larger than the size of the {CALLDATA,CODE,RETURNDATA}. So we just have to write zeros.
// stack: kexit_info, dest_offset, offset, size
GET_CONTEXT
%stack (context, kexit_info, dest_offset, offset, size) ->
(context, @SEGMENT_MAIN_MEMORY, dest_offset, 0, size, %%after, kexit_info)
(context, @SEGMENT_MAIN_MEMORY, dest_offset, 0, size, wcopy_after, kexit_info)
%jump(memset)
%endmacro
wcopy_after:
// stack: kexit_info
EXIT_KERNEL
global sys_calldatacopy:
%wcopy(@SEGMENT_CALLDATA, @CTX_METADATA_CALLDATA_SIZE)
@ -172,5 +172,32 @@ global sys_calldatacopy:
global sys_codecopy:
%wcopy(@SEGMENT_CODE, @CTX_METADATA_CODE_SIZE)
// Same as %wcopy but with overflow checks.
global sys_returndatacopy:
%wcopy(@SEGMENT_RETURNDATA, @CTX_METADATA_RETURNDATA_SIZE)
// stack: kexit_info, dest_offset, offset, size
PUSH @GAS_VERYLOW
DUP5
// stack: size, Gverylow, kexit_info, dest_offset, offset, size
ISZERO %jumpi(wcopy_empty)
// stack: Gverylow, kexit_info, dest_offset, offset, size
DUP5 %num_bytes_to_num_words %mul_const(@GAS_COPY) ADD %charge_gas
%stack (kexit_info, dest_offset, offset, size) -> (dest_offset, size, kexit_info, dest_offset, offset, size)
%add_or_fault
// stack: expanded_num_bytes, kexit_info, dest_offset, offset, size, kexit_info
DUP1 %ensure_reasonable_offset
%update_mem_bytes
// stack: kexit_info, dest_offset, offset, size, kexit_info
DUP4 DUP4 %add_or_fault // Overflow check
%mload_context_metadata(@CTX_METADATA_RETURNDATA_SIZE) LT %jumpi(fault_exception) // Data len check
%mload_context_metadata(@CTX_METADATA_RETURNDATA_SIZE)
// stack: total_size, kexit_info, dest_offset, offset, size
DUP4
// stack: offset, total_size, kexit_info, dest_offset, offset, size
GT %jumpi(wcopy_large_offset)
GET_CONTEXT
%stack (context, kexit_info, dest_offset, offset, size) ->
(context, @SEGMENT_MAIN_MEMORY, dest_offset, context, @SEGMENT_RETURNDATA, offset, size, wcopy_after, kexit_info)
%jump(memcpy)

View File

@ -10,10 +10,11 @@ pub(crate) enum JournalEntry {
StorageLoaded = 6,
CodeChange = 7,
Refund = 8,
AccountCreated = 9,
}
impl JournalEntry {
pub(crate) const COUNT: usize = 9;
pub(crate) const COUNT: usize = 10;
pub(crate) fn all() -> [Self; Self::COUNT] {
[
@ -26,6 +27,7 @@ impl JournalEntry {
Self::StorageLoaded,
Self::CodeChange,
Self::Refund,
Self::AccountCreated,
]
}
@ -41,6 +43,7 @@ impl JournalEntry {
Self::StorageLoaded => "JOURNAL_ENTRY_STORAGE_LOADED",
Self::CodeChange => "JOURNAL_ENTRY_CODE_CHANGE",
Self::Refund => "JOURNAL_ENTRY_REFUND",
Self::AccountCreated => "JOURNAL_ENTRY_ACCOUNT_CREATED",
}
}
}