Add refund journal event and checkpoint after access address event (#1040)

This commit is contained in:
wborgeaud 2023-05-16 14:36:17 +02:00 committed by GitHub
parent bde7fb5019
commit 244d5e9b3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 47 additions and 16 deletions

View File

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

View File

@ -11,8 +11,6 @@ global sys_call:
MUL // Cheaper than AND
%jumpi(fault_exception)
%checkpoint // Checkpoint
%stack (kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size) ->
(args_size, args_offset, kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size)
%checked_mem_expansion
@ -23,8 +21,9 @@ global sys_call:
SWAP2
// stack: address, gas, kexit_info, value, args_offset, args_size, ret_offset, ret_size
%u256_to_addr // Truncate to 160 bits
DUP1 %insert_touched_addresses
DUP1 %insert_accessed_addresses
%checkpoint // Checkpoint
DUP1 %insert_touched_addresses
%call_charge_gas(1, 1)
@ -59,7 +58,6 @@ global sys_call:
// Creates a new sub context as if calling itself, but with the code of the
// given account. In particular the storage remains the same.
global sys_callcode:
%checkpoint // Checkpoint
// stack: kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size
%stack (kexit_info, gas, address, value, args_offset, args_size, ret_offset, ret_size) ->
@ -73,6 +71,7 @@ global sys_callcode:
// stack: address, gas, kexit_info, value, args_offset, args_size, ret_offset, ret_size
%u256_to_addr // Truncate to 160 bits
DUP1 %insert_accessed_addresses
%checkpoint // Checkpoint
%call_charge_gas(1, 0)
@ -111,8 +110,6 @@ global sys_callcode:
// are CREATE, CREATE2, LOG0, LOG1, LOG2, LOG3, LOG4, SSTORE, SELFDESTRUCT and
// CALL if the value sent is not 0.
global sys_staticcall:
%checkpoint // Checkpoint
// stack: kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size
%stack (kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size) ->
(args_size, args_offset, kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size)
@ -124,8 +121,9 @@ global sys_staticcall:
SWAP2
// stack: address, gas, kexit_info, args_offset, args_size, ret_offset, ret_size
%u256_to_addr // Truncate to 160 bits
DUP1 %insert_touched_addresses
DUP1 %insert_accessed_addresses
%checkpoint // Checkpoint
DUP1 %insert_touched_addresses
// Add a value of 0 to the stack. Slightly inefficient but that way we can reuse %call_charge_gas.
%stack (cold_access, address, gas, kexit_info) -> (cold_access, address, gas, kexit_info, 0)
@ -162,7 +160,6 @@ global sys_staticcall:
// given account. In particular the storage, the current sender and the current
// value remain the same.
global sys_delegatecall:
%checkpoint // Checkpoint
// stack: kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size
%stack (kexit_info, gas, address, args_offset, args_size, ret_offset, ret_size) ->
@ -176,6 +173,7 @@ global sys_delegatecall:
// stack: address, gas, kexit_info, args_offset, args_size, ret_offset, ret_size
%u256_to_addr // Truncate to 160 bits
DUP1 %insert_accessed_addresses
%checkpoint // Checkpoint
// Add a value of 0 to the stack. Slightly inefficient but that way we can reuse %call_charge_gas.
%stack (cold_access, address, gas, kexit_info) -> (cold_access, address, gas, kexit_info, 0)

View File

@ -28,6 +28,7 @@ global refund_gas_hook:
%macro refund_gas_original
// stack: amount
DUP1 %journal_refund
%mload_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER)
ADD
%mstore_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER)

View File

@ -173,7 +173,6 @@ global process_contract_creation_txn_after_constructor:
// stack: leftover_gas, new_ctx, address, retdest
%pay_coinbase_and_refund_sender
// TODO: Delete accounts in self-destruct list and empty touched addresses.
%delete_all_touched_addresses
%delete_all_selfdestructed_addresses
// stack: new_ctx, address, retdest
@ -264,16 +263,26 @@ process_message_txn_code_loaded_finish:
global process_message_txn_after_call:
// stack: success, leftover_gas, new_ctx, retdest
POP // TODO: Success will go into the receipt when we support that.
DUP1 POP // TODO: Success will go into the receipt when we support that.
ISZERO %jumpi(process_message_txn_fail)
process_message_txn_after_call_contd:
// stack: leftover_gas, new_ctx, retdest
%pay_coinbase_and_refund_sender
// TODO: Delete accounts in self-destruct list and empty touched addresses.
%delete_all_touched_addresses
%delete_all_selfdestructed_addresses
// stack: new_ctx, retdest
POP
JUMP
process_message_txn_fail:
// stack: leftover_gas, new_ctx, retdest
// Transfer value back to the caller.
%mload_txn_field(@TXN_FIELD_VALUE)
%mload_txn_field(@TXN_FIELD_ORIGIN)
%mload_txn_field(@TXN_FIELD_TO)
%transfer_eth %jumpi(panic)
%jump(process_message_txn_after_call_contd)
%macro pay_coinbase_and_refund_sender
// stack: leftover_gas
DUP1

View File

@ -5,7 +5,8 @@
%endmacro
global revert_code_change:
// stack: ptr, retdest
// stack: entry_ptr, ptr, retdest
POP
%journal_load_2
// stack: address, prev_codehash, retdest
%mpt_read_state_trie

View File

@ -0,0 +1,15 @@
// struct Refund { amount }
%macro journal_refund
%journal_add_1(@JOURNAL_ENTRY_REFUND)
%endmacro
global revert_refund:
// stack: entry_type, ptr, retdest
POP
%journal_load_1
// stack: amount, retdest
%mload_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER)
SUB
%mstore_global_metadata(@GLOBAL_METADATA_REFUND_COUNTER)
JUMP

View File

@ -13,7 +13,8 @@
DUP1 %eq_const(@JOURNAL_ENTRY_NONCE_CHANGE) %jumpi(revert_nonce_change)
DUP1 %eq_const(@JOURNAL_ENTRY_STORAGE_CHANGE) %jumpi(revert_storage_change)
DUP1 %eq_const(@JOURNAL_ENTRY_STORAGE_LOADED) %jumpi(revert_storage_loaded)
%eq_const(@JOURNAL_ENTRY_CODE_CHANGE) %jumpi(revert_code_change)
DUP1 %eq_const(@JOURNAL_ENTRY_CODE_CHANGE) %jumpi(revert_code_change)
DUP1 %eq_const(@JOURNAL_ENTRY_REFUND) %jumpi(revert_refund)
PANIC // This should never happen.
%%after:
// stack: journal_size-1

View File

@ -21,8 +21,10 @@ global revert_storage_change:
%add_const(2)
// stack: storage_root_ptr_ptr, 64, storage_key, address, prev_value, retdest
%mload_trie_data
%stack (storage_root_ptr, num_nibbles, storage_key, address, prev_value, retdest) ->
(storage_root_ptr, num_nibbles, storage_key, prev_value, new_storage_root, address, retdest)
%get_trie_data_size
DUP6 %append_to_trie_data
%stack (prev_value_ptr, storage_root_ptr, num_nibbles, storage_key, address, prev_value, retdest) ->
(storage_root_ptr, num_nibbles, storage_key, prev_value_ptr, new_storage_root, address, retdest)
%jump(mpt_insert)
delete:

View File

@ -9,10 +9,11 @@ pub(crate) enum JournalEntry {
StorageChange = 5,
StorageLoaded = 6,
CodeChange = 7,
Refund = 8,
}
impl JournalEntry {
pub(crate) const COUNT: usize = 8;
pub(crate) const COUNT: usize = 9;
pub(crate) fn all() -> [Self; Self::COUNT] {
[
@ -24,6 +25,7 @@ impl JournalEntry {
Self::StorageChange,
Self::StorageLoaded,
Self::CodeChange,
Self::Refund,
]
}
@ -38,6 +40,7 @@ impl JournalEntry {
Self::StorageChange => "JOURNAL_ENTRY_STORAGE_CHANGE",
Self::StorageLoaded => "JOURNAL_ENTRY_STORAGE_LOADED",
Self::CodeChange => "JOURNAL_ENTRY_CODE_CHANGE",
Self::Refund => "JOURNAL_ENTRY_REFUND",
}
}
}