-
Notifications
You must be signed in to change notification settings - Fork 40
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add transient storage * Add basic tests and fix bugs * Add more tests fix more bugs * [WIP] Add revert test * [WIP] expanding macro below global label * Fix revert test bugs * Fix revert test bugs * Add missing files * Apply suggestions from code review Co-authored-by: Robin Salen <30937548+Nashtare@users.noreply.github.com> * Address reviews * chore: fix broken tests after merge * Apply suggestions from code review Co-authored-by: Robin Salen <30937548+Nashtare@users.noreply.github.com> * Add kernel_mode false to exit kernel in tests * Fix problem with modified kernel * Clippy --------- Co-authored-by: Robin Salen <30937548+Nashtare@users.noreply.github.com> Co-authored-by: David <dvdplm@gmail.com>
- Loading branch information
1 parent
23b7a28
commit e6b137c
Showing
17 changed files
with
730 additions
and
181 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
evm_arithmetization/src/cpu/kernel/asm/journal/transient_storage_change.asm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// struct StorageChange { address, slot, prev_value } | ||
|
||
%macro journal_add_transient_storage_change | ||
%journal_add_3(@JOURNAL_ENTRY_TRANSIENT_STORAGE_CHANGE) | ||
%endmacro | ||
|
||
global revert_transient_storage_change: | ||
// stack: entry_type, ptr, retdest | ||
POP | ||
%journal_load_3 | ||
// We will always write 0 for deletions as it makes no difference. | ||
// stack: address, slot, prev_value, retdest | ||
%search_transient_storage | ||
// The value must have been stored | ||
%assert_nonzero | ||
// stack: pos, addr, value, key, prev_value, retdest | ||
%add_const(2) | ||
DUP5 | ||
MSTORE_GENERAL | ||
%pop4 | ||
JUMP |
158 changes: 158 additions & 0 deletions
158
evm_arithmetization/src/cpu/kernel/asm/memory/transient_storage.asm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
// Transient data storage | ||
|
||
|
||
/// The transient storage is stored in an array. The length of the array is stored in the global metadata. | ||
/// For storage keys, the address and key are stored as two consecutive elements. | ||
/// The array is stored in the SEGMENT_TRANSIENT_STORAGE segment in the kernel memory (context=0). | ||
/// Searching and inserting is done by doing a linear search through the array. | ||
/// If the key isn't found in the array, it is inserted at the end. | ||
/// TODO: Look into using a more efficient data structure. | ||
|
||
%macro search_transient_storage | ||
%stack (addr, key) -> (addr, key, %%after) | ||
%jump(search_transient_storage) | ||
%%after: | ||
// stack: (is_present, pos, addr, key, val) | ||
%endmacro | ||
|
||
/// Looks for an address, key pair into the transient storage. Returns 1 and the position in @SEGMENT_TRANSIENT_STORAGE | ||
/// if present or 0 and @GLOBAL_METADATA_TRANSIENT_STORAGE_LEN if not. | ||
global search_transient_storage: | ||
// stack: addr, key, retdest | ||
%mload_global_metadata(@GLOBAL_METADATA_TRANSIENT_STORAGE_LEN) | ||
// stack: len, addr, key, retdest | ||
PUSH @SEGMENT_TRANSIENT_STORAGE ADD | ||
PUSH @SEGMENT_TRANSIENT_STORAGE | ||
search_transient_storage_loop: | ||
// `i` and `len` are both scaled by SEGMENT_TRANSIENT_STORAGE | ||
%stack (i, len, addr, key, retdest) -> (i, len, i, len, addr, key, retdest) | ||
EQ %jumpi(search_transient_storage_not_found) | ||
// stack: i, len, addr, key, retdest | ||
DUP1 | ||
MLOAD_GENERAL | ||
// stack: loaded_addr, i, len, addr, key, retdest | ||
DUP4 | ||
// stack: addr, loaded_addr, i, len, addr, key, retdest | ||
SUB // functions as NEQ | ||
// stack: addr != loaded_addr, i, len, addr, key, retdest | ||
%jumpi(increment_and_loop) | ||
|
||
// Addresses match, but we need to check for keys as well | ||
DUP1 | ||
%increment | ||
MLOAD_GENERAL | ||
// stack: loaded_key, i, len, addr, key, retdest | ||
DUP5 | ||
// stack: key, loaded_key, i, len, addr, key, retdest | ||
EQ | ||
%jumpi(search_transient_storage_found) | ||
increment_and_loop: | ||
// stack: i, len, addr, key, retdest | ||
%increment | ||
%jump(search_transient_storage_loop) | ||
|
||
search_transient_storage_not_found: | ||
%stack (i, len, addr, key, retdest) -> (retdest, 0, i, addr, 0, key) // Return 0 to indicate that the address, key was not found. | ||
JUMP | ||
|
||
search_transient_storage_found: | ||
DUP1 %add_const(2) | ||
MLOAD_GENERAL | ||
%stack (val, i, len, addr, key, retdest) -> (retdest, 1, i, addr, val, key) // Return 1 to indicate that the address was already present. | ||
JUMP | ||
|
||
%macro tload_current | ||
%stack (slot) -> (slot, %%after) | ||
%jump(tload_current) | ||
%%after: | ||
%endmacro | ||
|
||
global tload_current: | ||
%address | ||
// stack: addr, slot, retdest | ||
%search_transient_storage | ||
// stack: found, pos, addr, val, slot, retdest | ||
%jumpi(tload_found) | ||
// The value is not in memory so we return 0 | ||
%stack (pos, addr, val, slot, retdest) -> (retdest, 0) | ||
JUMP | ||
tload_found: | ||
// stack: pos, addr, val, slot, retdest | ||
%stack (pos, addr, val, slot, retdest) -> (retdest, val) | ||
JUMP | ||
|
||
// Read a word from the current account's transient storage list | ||
// | ||
// Pre stack: kexit_info, slot | ||
// Post stack: value | ||
global sys_tload: | ||
// stack: kexit_info, slot | ||
SWAP1 | ||
// stack: slot, kexit_info | ||
%tload_current | ||
SWAP1 | ||
|
||
%charge_gas_const(@GAS_WARMACCESS) | ||
// stack: kexit_info, value | ||
EXIT_KERNEL | ||
|
||
// Write a word to the current account's transient storage. | ||
// | ||
// Pre stack: kexit_info, slot, value | ||
// Post stack: (empty) | ||
|
||
global sys_tstore: | ||
%check_static | ||
%charge_gas_const(@GAS_WARMACCESS) | ||
%stack (kexit_info, slot, value) -> (slot, value, kexit_info) | ||
%address | ||
%search_transient_storage | ||
// stack: found, pos, addr, original_value, slot, value, kexit_info | ||
POP | ||
// If the address and slot pair was not present pos will be pointing to the end of the array. | ||
DUP1 DUP3 | ||
// stack: addr, pos, pos, addr, original_value, slot, value, kexit_info | ||
MSTORE_GENERAL | ||
%increment DUP1 | ||
DUP5 | ||
// stack: slot, pos', pos', addr, original_value, slot, value, kexit_info | ||
MSTORE_GENERAL | ||
%increment DUP1 | ||
DUP6 | ||
MSTORE_GENERAL | ||
// stack: pos'', addr, original_value, slot, value, kexit_info | ||
// If pos'' > @GLOBAL_METADATA_TRANSIENT_STORAGE_LEN we need to also store the new @GLOBAL_METADATA_TRANSIENT_STORAGE_LEN | ||
%mload_global_metadata(@GLOBAL_METADATA_TRANSIENT_STORAGE_LEN) | ||
DUP2 | ||
GT | ||
%jumpi(new_transient_storage_len) | ||
POP | ||
sys_tstore_charge_gas: | ||
// stack: addr, original_value, slot, value, kexit_info | ||
// Check if `value` is equal to `current_value`, and if so exit the kernel early. | ||
%stack | ||
(addr, original_value, slot, value, kexit_info) -> | ||
(value, original_value, addr, slot, original_value, kexit_info) | ||
EQ %jumpi(sstore_noop) | ||
|
||
// stack: addr, slot, original_value, kexit_info | ||
global debug_journal: | ||
%journal_add_transient_storage_change | ||
|
||
// stack: kexit_info | ||
EXIT_KERNEL | ||
|
||
new_transient_storage_len: | ||
// Store the new (unscaled) length. | ||
// stack: addr, original_value, slot, value, kexit_info | ||
PUSH @SEGMENT_TRANSIENT_STORAGE | ||
PUSH 1 | ||
SUB // 1 - seg | ||
ADD // new_len = (addr - seg) + 1 | ||
%mstore_global_metadata(@GLOBAL_METADATA_TRANSIENT_STORAGE_LEN) | ||
%jump(sys_tstore_charge_gas) | ||
|
||
sstore_noop: | ||
// stack: current_value, slot, value, kexit_info | ||
%pop3 | ||
EXIT_KERNEL |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 5 additions & 0 deletions
5
evm_arithmetization/src/cpu/kernel/tests/checkpoint_label.asm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
global checkpoint: | ||
// stack: (empty) | ||
%checkpoint | ||
// stack: (empty) | ||
JUMP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.