Call stack depth (#1081)

This commit is contained in:
wborgeaud 2023-06-07 18:54:06 +02:00 committed by GitHub
parent 0f8743174e
commit 0f7e1c0b61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 6 deletions

View File

@ -22,14 +22,15 @@ global sys_call:
// 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
DUP2 %insert_touched_addresses
%call_charge_gas(1, 1)
%check_depth
%checkpoint // Checkpoint
%create_context
// stack: new_ctx, kexit_info, callgas, address, value, args_offset, args_size, ret_offset, ret_size
// TODO: Consider call depth
%stack (new_ctx, kexit_info, callgas, address, value, args_offset, args_size, ret_offset, ret_size) ->
(new_ctx, args_offset, args_size, new_ctx, kexit_info, callgas, address, value, args_offset, args_size, ret_offset, ret_size)
@ -74,9 +75,11 @@ 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)
%check_depth
%checkpoint // Checkpoint
// stack: kexit_info, callgas, address, value, args_offset, args_size, ret_offset, ret_size
%create_context
@ -127,12 +130,14 @@ global sys_staticcall:
// 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
DUP2 %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)
%call_charge_gas(0, 1)
%check_depth
%checkpoint // Checkpoint
// stack: kexit_info, callgas, address, value, args_offset, args_size, ret_offset, ret_size
%create_context
@ -180,11 +185,13 @@ 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)
%call_charge_gas(0, 0)
%check_depth
%checkpoint // Checkpoint
// stack: kexit_info, callgas, address, value, args_offset, args_size, ret_offset, ret_size
%create_context
@ -244,6 +251,20 @@ call_insufficient_balance:
%mstore_context_metadata(@CTX_METADATA_RETURNDATA_SIZE, 0)
EXIT_KERNEL
%macro check_depth
%call_depth
%gt_const(@CALL_STACK_LIMIT)
%jumpi(call_too_deep)
%endmacro
call_too_deep:
%stack (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
// because it will already be 0 by default.
%macro set_static_true
@ -342,6 +363,7 @@ call_insufficient_balance:
DUP1 // new_ctx
SET_CONTEXT
%checkpoint // Checkpoint
%increment_call_depth
// Perform jumpdest analyis
PUSH %%after
%mload_context_metadata(@CTX_METADATA_CODE_SIZE)

View File

@ -200,6 +200,7 @@ global terminate_common:
// Go back to the parent context.
%mload_context_metadata(@CTX_METADATA_PARENT_CONTEXT)
SET_CONTEXT
%decrement_call_depth
// stack: (empty)
// Load the fields that we stored in SEGMENT_KERNEL_GENERAL.

View File

@ -325,3 +325,19 @@ global sys_basefee:
%jumpi(fault_exception)
// stack: sum
%endmacro
%macro call_depth
%mload_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%endmacro
%macro increment_call_depth
%mload_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%increment
%mstore_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%endmacro
%macro decrement_call_depth
%mload_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%decrement
%mstore_global_metadata(@GLOBAL_METADATA_CALL_STACK_DEPTH)
%endmacro

View File

@ -68,10 +68,11 @@ pub(crate) enum GlobalMetadata {
// Boolean flag indicating if the txn is a contract creation txn.
ContractCreation = 33,
IsPrecompileFromEoa = 34,
CallStackDepth = 35,
}
impl GlobalMetadata {
pub(crate) const COUNT: usize = 34;
pub(crate) const COUNT: usize = 35;
pub(crate) fn all() -> [Self; Self::COUNT] {
[
@ -109,6 +110,7 @@ impl GlobalMetadata {
Self::AccessListRlpLen,
Self::ContractCreation,
Self::IsPrecompileFromEoa,
Self::CallStackDepth,
]
}
@ -149,6 +151,7 @@ impl GlobalMetadata {
Self::AccessListRlpLen => "GLOBAL_METADATA_ACCESS_LIST_RLP_LEN",
Self::ContractCreation => "GLOBAL_METADATA_CONTRACT_CREATION",
Self::IsPrecompileFromEoa => "GLOBAL_METADATA_IS_PRECOMPILE_FROM_EOA",
Self::CallStackDepth => "GLOBAL_METADATA_CALL_STACK_DEPTH",
}
}
}

View File

@ -55,6 +55,7 @@ pub fn evm_constants() -> HashMap<String, U256> {
}
c.insert(MAX_NONCE.0.into(), U256::from(MAX_NONCE.1));
c.insert(CALL_STACK_LIMIT.0.into(), U256::from(CALL_STACK_LIMIT.1));
for segment in Segment::all() {
c.insert(segment.var_name().into(), (segment as u32).into());
@ -264,3 +265,4 @@ const CODE_SIZE_LIMIT: [(&str, u64); 3] = [
];
const MAX_NONCE: (&str, u64) = ("MAX_NONCE", 0xffffffffffffffff);
const CALL_STACK_LIMIT: (&str, u64) = ("CALL_STACK_LIMIT", 1024);