From f717a40b85a1921296b45dbe7c48de347ffec496 Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Sun, 19 Mar 2023 20:17:30 -0700 Subject: [PATCH] Charge for memory expansion --- evm/src/cpu/kernel/asm/account_code.asm | 20 ++++-- evm/src/cpu/kernel/asm/core/syscall_stubs.asm | 2 - evm/src/cpu/kernel/asm/memory/core.asm | 18 ----- evm/src/cpu/kernel/asm/memory/metadata.asm | 72 +++++++++++++++---- evm/src/cpu/kernel/asm/memory/syscalls.asm | 18 +++++ evm/src/cpu/kernel/asm/util/basic_macros.asm | 22 +++--- .../cpu/kernel/constants/context_metadata.rs | 8 +-- evm/src/cpu/kernel/interpreter.rs | 2 +- 8 files changed, 110 insertions(+), 52 deletions(-) diff --git a/evm/src/cpu/kernel/asm/account_code.asm b/evm/src/cpu/kernel/asm/account_code.asm index f10fbc19..3b18e309 100644 --- a/evm/src/cpu/kernel/asm/account_code.asm +++ b/evm/src/cpu/kernel/asm/account_code.asm @@ -1,6 +1,12 @@ -retzero: - %stack (account_ptr, retdest) -> (retdest, 0) - JUMP +global sys_extcodehash: + // stack: kexit_info, address + // TODO: Charge gas. + SWAP1 + // stack: address, kexit_info + %extcodehash + // stack: hash, kexit_info + SWAP1 + EXIT_KERNEL global extcodehash: // stack: address, retdest @@ -12,6 +18,9 @@ global extcodehash: %mload_trie_data // stack: codehash, retdest SWAP1 JUMP +retzero: + %stack (account_ptr, retdest) -> (retdest, 0) + JUMP %macro extcodehash %stack (address) -> (address, %%after) @@ -32,6 +41,7 @@ global extcodehash: global sys_extcodesize: // stack: kexit_info, address + // TODO: Charge gas. SWAP1 // stack: address, kexit_info %extcodesize @@ -61,6 +71,8 @@ global extcodesize: // Pre stack: kexit_info, address, dest_offset, offset, size // Post stack: (empty) global sys_extcodecopy: + // TODO: Call %update_mem_bytes to expand memory. + // TODO: Charge other gas. %stack (kexit_info, address, dest_offset, offset, size) -> (address, dest_offset, offset, size, kexit_info) %extcodecopy @@ -104,7 +116,7 @@ extcodecopy_loop: // stack: opcode, offset, code_size, dest_offset, i, size, retdest DUP4 // stack: dest_offset, opcode, offset, code_size, dest_offset, i, size, retdest - %mstore_main + %mstore_current(@SEGMENT_MAIN_MEMORY) // stack: offset, code_size, dest_offset, i, size, retdest %increment // stack: offset+1, code_size, dest_offset, i, size, retdest diff --git a/evm/src/cpu/kernel/asm/core/syscall_stubs.asm b/evm/src/cpu/kernel/asm/core/syscall_stubs.asm index 6dcbbb6e..d7f29081 100644 --- a/evm/src/cpu/kernel/asm/core/syscall_stubs.asm +++ b/evm/src/cpu/kernel/asm/core/syscall_stubs.asm @@ -35,8 +35,6 @@ global sys_returndatasize: PANIC global sys_returndatacopy: PANIC -global sys_extcodehash: - PANIC global sys_blockhash: PANIC global sys_coinbase: diff --git a/evm/src/cpu/kernel/asm/memory/core.asm b/evm/src/cpu/kernel/asm/memory/core.asm index 8f59a128..24f35ada 100644 --- a/evm/src/cpu/kernel/asm/memory/core.asm +++ b/evm/src/cpu/kernel/asm/memory/core.asm @@ -419,21 +419,3 @@ %mstore_kernel_general_2 // stack: (empty) %endmacro - -%macro mload_main - // stack: offset - DUP1 - // stack: offset, offset - %update_msize - // stack: offset - %mload_current(@SEGMENT_MAIN_MEMORY) -%endmacro - -%macro mstore_main - // stack: offset, value - DUP1 - // stack: offset, offset, value - %update_msize - // stack: offset, value - %mstore_current(@SEGMENT_MAIN_MEMORY) -%endmacro diff --git a/evm/src/cpu/kernel/asm/memory/metadata.asm b/evm/src/cpu/kernel/asm/memory/metadata.asm index 7ea6d9e5..9b9ce7c2 100644 --- a/evm/src/cpu/kernel/asm/memory/metadata.asm +++ b/evm/src/cpu/kernel/asm/memory/metadata.asm @@ -78,8 +78,13 @@ global sys_callvalue: SWAP1 EXIT_KERNEL +%macro mem_words + %mload_context_metadata(@CTX_METADATA_MEM_WORDS) +%endmacro + %macro msize - %mload_context_metadata(@CTX_METADATA_MSIZE) + %mem_words + %mul_const(32) %endmacro global sys_msize: @@ -89,17 +94,56 @@ global sys_msize: SWAP1 EXIT_KERNEL -%macro update_msize - // stack: offset - %add_const(32) - // stack: 32 + offset - %div_const(32) - // stack: (offset+32)/32 = ceil_div_usize(offset+1, 32) - %mul_const(32) - // stack: ceil_div_usize(offset+1, 32) * 32 - %msize - // stack: current_msize, ceil_div_usize(offset+1, 32) * 32 - %max - // stack: new_msize - %mstore_context_metadata(@CTX_METADATA_MSIZE) +%macro update_mem_words + // stack: num_words, kexit_info + %mem_words + // stack: old_num_words, num_words, kexit_info + DUP2 DUP2 GT + // stack: old_num_words > num_words, old_num_words, num_words, kexit_info + %jumpi(%%end) + // stack: old_num_words, num_words, kexit_info + %memory_cost + // stack: old_cost, num_words, kexit_info + SWAP1 + // stack: num_words, old_cost, kexit_info + DUP1 %mstore_context_metadata(@CTX_METADATA_MEM_WORDS) + // stack: num_words, old_cost, kexit_info + %memory_cost + // stack: new_cost, old_cost, kexit_info + SUB + // stack: additional_cost, kexit_info + %charge_gas +%%end: + // stack: kexit_info +%endmacro + +%macro update_mem_bytes + // stack: num_bytes, kexit_info + %num_bytes_to_num_words + // stack: num_words, kexit_info + %update_mem_words + // stack: kexit_info +%endmacro + +%macro num_bytes_to_num_words + // stack: num_bytes + %add_const(31) + // stack: 31 + num_bytes + %div_const(32) + // stack: (num_bytes + 31) / 32 +%endmacro + +%macro memory_cost + // stack: num_words + DUP1 + // stack: num_words, msize + %mul_const(@GAS_MEMORY) + // stack: num_words * GAS_MEMORY, msize + SWAP1 + // stack: num_words, num_words * GAS_MEMORY + %square + %div_const(512) + // stack: num_words^2 / 512, num_words * GAS_MEMORY + ADD + // stack: cost = num_words^2 / 512 + num_words * GAS_MEMORY %endmacro diff --git a/evm/src/cpu/kernel/asm/memory/syscalls.asm b/evm/src/cpu/kernel/asm/memory/syscalls.asm index 3b56a7fd..03cf3421 100644 --- a/evm/src/cpu/kernel/asm/memory/syscalls.asm +++ b/evm/src/cpu/kernel/asm/memory/syscalls.asm @@ -1,4 +1,10 @@ global sys_mload: + // stack: kexit_info, offset + %charge_gas_const(@GAS_VERYLOW) + // stack: kexit_info, offset + DUP2 %add_const(32) + // stack: expanded_num_bytes, kexit_info, offset + %update_mem_bytes // stack: kexit_info, offset PUSH 0 // acc = 0 // stack: acc, kexit_info, offset @@ -38,6 +44,12 @@ global sys_mload: EXIT_KERNEL global sys_mstore: + // stack: kexit_info, offset, value + %charge_gas_const(@GAS_VERYLOW) + // stack: kexit_info, offset, value + DUP2 %add_const(32) + // stack: expanded_num_bytes, kexit_info, offset, value + %update_mem_bytes // stack: kexit_info, offset, value DUP3 PUSH 0 BYTE DUP3 %add_const( 0) %mstore_current(@SEGMENT_MAIN_MEMORY) DUP3 PUSH 1 BYTE DUP3 %add_const( 1) %mstore_current(@SEGMENT_MAIN_MEMORY) @@ -75,6 +87,12 @@ global sys_mstore: EXIT_KERNEL global sys_mstore8: + // stack: kexit_info, offset, value + %charge_gas_const(@GAS_VERYLOW) + // stack: kexit_info, offset, value + DUP2 %increment + // stack: expanded_num_bytes, kexit_info, offset, value + %update_mem_bytes // stack: kexit_info, offset, value %stack (kexit_info, offset, value) -> (offset, value, kexit_info) %mstore_current(@SEGMENT_MAIN_MEMORY) diff --git a/evm/src/cpu/kernel/asm/util/basic_macros.asm b/evm/src/cpu/kernel/asm/util/basic_macros.asm index e81993b0..50857eaa 100644 --- a/evm/src/cpu/kernel/asm/util/basic_macros.asm +++ b/evm/src/cpu/kernel/asm/util/basic_macros.asm @@ -347,22 +347,26 @@ %endmacro // Charge gas. -// Arguments: -// stack[0]: gas to be charged -// stack[1]: syscall info -// Returns: -// new syscall info %macro charge_gas + // stack: gas, kexit_info %shl_const(192) ADD + // stack: kexit_info' +%endmacro + +// Charge a constant amount of gas. +%macro charge_gas_const(gas) + // stack: kexit_info + PUSH $gas + // stack: gas, kexit_info + %charge_gas + // stack: kexit_info' %endmacro // Charge gas and exit kernel code. -// Arguments: -// stack[0]: gas to be charged -// stack[1]: syscall info -// Returns: nothing %macro charge_gas_and_exit + // stack: gas, kexit_info %charge_gas + // stack: kexit_info' EXIT_KERNEL %endmacro diff --git a/evm/src/cpu/kernel/constants/context_metadata.rs b/evm/src/cpu/kernel/constants/context_metadata.rs index 4e869661..32af6e35 100644 --- a/evm/src/cpu/kernel/constants/context_metadata.rs +++ b/evm/src/cpu/kernel/constants/context_metadata.rs @@ -23,8 +23,8 @@ pub(crate) enum ContextMetadata { /// Pointer to the initial version of the state trie, at the creation of this context. Used when /// we need to revert a context. StateTrieCheckpointPointer = 9, - /// Size of the active main memory. - MSize = 10, + /// Size of the active main memory, in (32 byte) words. + MemWords = 10, StackSize = 11, /// The gas limit for this call (not the entire transaction). GasLimit = 12, @@ -45,7 +45,7 @@ impl ContextMetadata { Self::CallValue, Self::Static, Self::StateTrieCheckpointPointer, - Self::MSize, + Self::MemWords, Self::StackSize, Self::GasLimit, ] @@ -64,7 +64,7 @@ impl ContextMetadata { ContextMetadata::CallValue => "CTX_METADATA_CALL_VALUE", ContextMetadata::Static => "CTX_METADATA_STATIC", ContextMetadata::StateTrieCheckpointPointer => "CTX_METADATA_STATE_TRIE_CHECKPOINT_PTR", - ContextMetadata::MSize => "CTX_METADATA_MSIZE", + ContextMetadata::MemWords => "CTX_METADATA_MEM_WORDS", ContextMetadata::StackSize => "CTX_METADATA_STACK_SIZE", ContextMetadata::GasLimit => "CTX_METADATA_GAS_LIMIT", } diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 79c4ba93..7d30d7f2 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -709,7 +709,7 @@ impl<'a> Interpreter<'a> { self.push( self.generation_state.memory.contexts[self.context].segments [Segment::ContextMetadata as usize] - .get(ContextMetadata::MSize as usize), + .get(ContextMetadata::MemWords as usize), ) }