Skip to content

Commit

Permalink
fix: create finalization on REVERT opcode (#979)
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:

## 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. -->

- Fixes the finalization of a parent context in a CREATE execution. We
need to handle the case where the EVM has errored (exceptional or
classic revert) before anything else.
-
-

<!-- 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/979)
<!-- Reviewable:end -->
  • Loading branch information
enitrat authored Feb 14, 2024
1 parent 9ffc23c commit 96f7a89
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 43 deletions.
15 changes: 0 additions & 15 deletions blockchain-tests-skip.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ testname:
stChainId:
- chainId_d0g0v0_Shanghai
stCreate2:
- Create2OOGafterInitCodeReturndataSize_d0g0v0_Shanghai
- Create2OOGafterInitCodeRevert_d0g0v0_Shanghai
- RevertOpcodeCreate_d0g0v0_Shanghai
- create2callPrecompiles_d6g0v0_Shanghai
- create2callPrecompiles_d7g0v0_Shanghai
- create2collisionBalance_d0g0v0_Shanghai
Expand All @@ -62,25 +59,13 @@ testname:
- CreateAddressWarmAfterFail_d3g0v1_Shanghai
- CreateCollisionToEmpty_d0g0v0_Shanghai
- CreateCollisionToEmpty_d0g0v1_Shanghai
- CreateOOGafterInitCodeReturndataSize_d0g0v0_Shanghai
- CreateOOGafterInitCodeRevert_d0g0v0_Shanghai
- CreateOOGafterMaxCodesize_d2g0v0_Shanghai
- CreateOOGafterMaxCodesize_d3g0v0_Shanghai
- CreateOOGafterMaxCodesize_d5g0v0_Shanghai
- CreateResults_d8g0v0_Shanghai
- CreateResults_d9g0v0_Shanghai
- CreateTransactionHighNonce_d0g0v0_Shanghai
- CreateTransactionHighNonce_d0g0v1_Shanghai
- TransactionCollisionToEmpty_d0g0v0_Shanghai
- TransactionCollisionToEmpty_d0g0v1_Shanghai
- createLargeResult_d10g0v0_Shanghai
- createLargeResult_d11g0v0_Shanghai
- createLargeResult_d14g0v0_Shanghai
- createLargeResult_d15g0v0_Shanghai
- createLargeResult_d2g0v0_Shanghai
- createLargeResult_d3g0v0_Shanghai
- createLargeResult_d6g0v0_Shanghai
- createLargeResult_d7g0v0_Shanghai
stCallCreateCallCodeTest:
- Call1024BalanceTooLow_d0g0v0_Shanghai
- Call1024PreCalls_d0g0v0_Shanghai
Expand Down
60 changes: 32 additions & 28 deletions src/kakarot/instructions/system_operations.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -878,28 +878,17 @@ namespace CallHelper {
let is_reverted = is_not_zero(evm.reverted);
Stack.push_uint128(1 - is_reverted);

// Gas not used is returned when evm is not reverted
local gas_left;
local gas_refund;
if (evm.reverted == FALSE) {
assert gas_left = evm.message.parent.evm.gas_left + evm.gas_left;
assert gas_refund = evm.message.parent.evm.gas_refund + evm.gas_refund;
} else {
assert gas_left = evm.message.parent.evm.gas_left;
assert gas_refund = evm.message.parent.evm.gas_refund;
}

// If the call has halted exceptionnaly, the return_data is empty
// and nothing is copied to memory.
if (evm.reverted == Errors.EXCEPTIONAL_HALT) {
// If the call has halted exceptionnaly, the return_data is empty
// and nothing is copied to memory, and the gas is not returned;
tempvar evm = new model.EVM(
message=evm.message.parent.evm.message,
return_data_len=0,
return_data=evm.return_data,
program_counter=evm.message.parent.evm.program_counter + 1,
stopped=evm.message.parent.evm.stopped,
gas_left=gas_left,
gas_refund=gas_refund,
gas_left=evm.message.parent.evm.gas_left,
gas_refund=evm.message.parent.evm.gas_refund,
reverted=evm.message.parent.evm.reverted,
);
return evm;
Expand All @@ -917,8 +906,8 @@ namespace CallHelper {
return_data=evm.return_data,
program_counter=evm.message.parent.evm.program_counter + 1,
stopped=evm.message.parent.evm.stopped,
gas_left=gas_left,
gas_refund=gas_refund,
gas_left=evm.message.parent.evm.gas_left + evm.gas_left,
gas_refund=evm.message.parent.evm.gas_refund + evm.gas_refund,
reverted=evm.message.parent.evm.reverted,
);

Expand Down Expand Up @@ -1074,6 +1063,30 @@ namespace CreateHelper {
}(evm: model.EVM*) -> model.EVM* {
alloc_locals;

// Reverted during execution - either REVERT or exceptional
if (evm.reverted != FALSE) {
let is_exceptional_revert = is_not_zero(Errors.REVERT - evm.reverted);
let return_data_len = (1 - is_exceptional_revert) * evm.return_data_len;
let gas_left = evm.message.parent.evm.gas_left + (1 - is_exceptional_revert) *
evm.gas_left;
let gas_refund = evm.message.parent.evm.gas_refund + (1 - is_exceptional_revert) *
evm.gas_refund;
tempvar stack_code = new Uint256(low=0, high=0);
Stack.push(stack_code);
tempvar evm = new model.EVM(
message=evm.message.parent.evm.message,
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,
gas_left=gas_left,
gas_refund=gas_refund,
reverted=evm.message.parent.evm.reverted,
);
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;
Expand All @@ -1086,26 +1099,17 @@ namespace CreateHelper {
tempvar is_prefix_not_0xef = is_not_zero(0xef - [evm.return_data]);
}

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

// 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);
tempvar address = new Uint256(low=address_low, high=address_high);

Stack.push(address);

if (success == FALSE) {
// 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=return_data_len,
return_data_len=0,
return_data=evm.return_data,
program_counter=evm.message.parent.evm.program_counter + 1,
stopped=evm.message.parent.evm.stopped,
Expand Down

0 comments on commit 96f7a89

Please sign in to comment.