Charge for memory expansion

This commit is contained in:
Daniel Lubarov 2023-03-19 20:17:30 -07:00
parent de246e227d
commit f717a40b85
8 changed files with 110 additions and 52 deletions

View File

@ -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

View File

@ -35,8 +35,6 @@ global sys_returndatasize:
PANIC
global sys_returndatacopy:
PANIC
global sys_extcodehash:
PANIC
global sys_blockhash:
PANIC
global sys_coinbase:

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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",
}

View File

@ -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),
)
}