Skip to content
This repository has been archived by the owner on Jan 9, 2025. It is now read-only.

Commit

Permalink
fix: create opcodes gas and jumpdest execution (#971)
Browse files Browse the repository at this point in the history
<!--- Please provide a general summary of your changes in the title
above -->

<!-- Give an estimate of the time you spent on this PR in terms of work
days.
Did you spend 0.5 days on this PR or rather 2 days?  -->

Time spent on this PR: 0.3d

## Pull request type

<!-- Please try to limit your pull request to one type,
submit multiple pull requests if needed. -->

Please check the type of change your PR introduces:

- [ ] Bugfix
- [ ] Feature
- [ ] Code style update (formatting, renaming)
- [ ] Refactoring (no functional changes, no api changes)
- [ ] Build related changes
- [ ] Documentation content changes
- [ ] Other (please describe):

## What is the current behavior?

<!-- Please describe the current behavior that you are modifying,
or link to a relevant issue. -->

Resolves #<Issue number>

## What is the new behavior?

<!-- Please describe the behavior or changes that are being added by
this PR. -->

-
- fixed calldata word count
-

<!-- Reviewable:start -->
- - -
This change is [<img src="https://reviewable.io/review_button.svg"
height="34" align="absmiddle"
alt="Reviewable"/>](https://reviewable.io/reviews/kkrt-labs/kakarot/971)
<!-- Reviewable:end -->
  • Loading branch information
enitrat authored Feb 13, 2024
1 parent 3c04951 commit 37907b3
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ jobs:
with:
cache-on-failure: "true"
- name: setup
run: make setup setup-kakarot-v1
run: mkdir -p build/common && make setup setup-kakarot-v1
- uses: taiki-e/install-action@nextest

- name: Download Kakarot build artifacts in v0
Expand Down
3 changes: 0 additions & 3 deletions blockchain-tests-skip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ filename:

# List of specific tests names to be skipped with folder
testname:
stEIP3860-limitmeterinitcode:
- create2InitCodeSizeLimit_d0g0v0_Shanghai
- createInitCodeSizeLimit_d0g0v0_Shanghai
vmTests:
- blockInfo_d1g0v0_Shanghai
- blockInfo_d2g0v0_Shanghai
Expand Down
3 changes: 3 additions & 0 deletions src/kakarot/instructions/memory_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ namespace MemoryOperations {
// If skip_condition is 0, then don't jump
let (skip_condition_is_zero) = uint256_eq(Uint256(0, 0), skip_condition);
if (skip_condition_is_zero != FALSE) {
// Return with a PC incremented by one - as JUMP and JUMPi increments
// are skipped in the main `execute_opcode` loop
let evm = EVM.increment_program_counter(evm, 1);
return evm;
}

Expand Down
22 changes: 15 additions & 7 deletions src/kakarot/instructions/system_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace SystemOperations {
let memory_expansion_cost = Gas.memory_expansion_cost_saturated(
memory.words_len, offset, size
);
let (calldata_words, _) = unsigned_div_rem(size.low + 31, 31);
let (calldata_words, _) = unsigned_div_rem(size.low + 31, 32);
let init_code_gas_low = Gas.INIT_CODE_WORD_COST * calldata_words;
tempvar init_code_gas_high = is_not_zero(size.high) * 2 ** 128;
let calldata_word_gas = is_create2 * Gas.KECCAK256_WORD * calldata_words;
Expand Down Expand Up @@ -1079,8 +1079,16 @@ namespace CreateHelper {
let code_deposit_cost = Gas.CODE_DEPOSIT * evm.return_data_len;
let remaining_gas = evm.gas_left - code_deposit_cost;
let enough_gas = is_nn(remaining_gas);
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3540.md
if (evm.return_data_len == 0) {
tempvar is_prefix_not_0xef = TRUE;
} else {
tempvar is_prefix_not_0xef = is_not_zero(0xef - [evm.return_data]);
}

let is_reverted = is_not_zero(evm.reverted);
let success = (1 - is_reverted) * enough_gas * code_size_limit;
let checks_success = enough_gas * code_size_limit * is_prefix_not_0xef;
let success = (1 - is_reverted) * checks_success;

// Stack output: the address of the deployed contract, 0 if the deployment failed.
let (address_high, address_low) = split_felt(evm.message.address.evm * success);
Expand All @@ -1089,15 +1097,15 @@ namespace CreateHelper {
Stack.push(address);

if (success == FALSE) {
// On revert, return the previous evm with an empty
// return data if the revert is an exceptional halt (type 2),
// otherwise return with the return data.
tempvar is_exceptional_revert = is_not_zero(Errors.REVERT - evm.reverted);
// The only case where a create opcode has returndata is if it reverted with the REVERT opcode.
tempvar is_exceptional_revert = is_not_zero(Errors.REVERT - evm.reverted) + (
1 - checks_success
);
let return_data_len = (1 - is_exceptional_revert) * evm.return_data_len;
tempvar evm = new model.EVM(
message=evm.message.parent.evm.message,
return_data_len=evm.return_data_len,
return_data_len=return_data_len,
return_data=evm.return_data,
program_counter=evm.message.parent.evm.program_counter + 1,
stopped=evm.message.parent.evm.stopped,
Expand Down
31 changes: 27 additions & 4 deletions src/kakarot/interpreter.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,9 @@ namespace Interpreter {
call MemoryOperations.exec_sstore; // 0x55
jmp end;
call MemoryOperations.exec_jump; // 0x56
jmp end;
jmp end_no_pc_increment;
call MemoryOperations.exec_jumpi; // 0x57
jmp end;
jmp end_no_pc_increment;
call MemoryOperations.exec_pc; // 0x58
jmp end;
call MemoryOperations.exec_msize; // 0x59
Expand Down Expand Up @@ -659,6 +659,18 @@ namespace Interpreter {
} else {
return evm;
}

end_no_pc_increment:
let syscall_ptr = cast([ap - 8], felt*);
let pedersen_ptr = cast([ap - 7], HashBuiltin*);
let range_check_ptr = [ap - 6];
let bitwise_ptr = cast([ap - 5], BitwiseBuiltin*);
let stack = cast([ap - 4], model.Stack*);
let memory = cast([ap - 3], model.Memory*);
let state = cast([ap - 2], model.State*);
let evm = cast([ap - 1], model.EVM*);

return evm;
}

// @notice Iteratively decode and execute the bytecode of an EVM
Expand Down Expand Up @@ -917,12 +929,23 @@ namespace Internals {
syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr, state: model.State*
}(evm: model.EVM*) -> model.EVM* {
alloc_locals;
let is_reverted = is_not_zero(evm.reverted);
if (is_reverted != 0) {
return evm;
}

// Charge final deposit gas
let code_size_limit = is_le(evm.return_data_len, Constants.MAX_CODE_SIZE);
let code_deposit_cost = Gas.CODE_DEPOSIT * evm.return_data_len;
let enough_gas = is_nn(evm.gas_left - code_deposit_cost);
let is_reverted = is_not_zero(evm.reverted);
let success = (1 - is_reverted) * enough_gas * code_size_limit;
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-3540.md
if (evm.return_data_len == 0) {
tempvar is_prefix_not_0xef = TRUE;
} else {
tempvar is_prefix_not_0xef = is_not_zero(0xef - [evm.return_data]);
}

let success = enough_gas * code_size_limit * is_prefix_not_0xef;

if (success == 0) {
// Reverts and burn all gas
Expand Down
10 changes: 10 additions & 0 deletions src/utils/utils.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ from utils.bytes import uint256_to_bytes32
// @title Helper Functions
// @notice This file contains a selection of helper function that simplify tasks such as type conversion and bit manipulation
namespace Helpers {
// Returns 1 if value == 0. Returns 0 otherwise.
@known_ap_change
func is_zero(value) -> felt {
if (value == 0) {
return 1;
}

return 0;
}

func to_uint256{range_check_ptr}(val: felt) -> Uint256* {
let (high, low) = split_felt(val);
tempvar res = new Uint256(low, high);
Expand Down

0 comments on commit 37907b3

Please sign in to comment.