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

Stop reverting on precompiles #803

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 65 additions & 2 deletions src/kakarot/errors.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@
assert [error + 24] = 108; // l
assert [error + 25] = 101; // e
assert [error + 26] = 32; // " "
assert [error + 27] = address; //
assert [error + 27] = '0' + address; // convert uint address to str
return (28, error);
}

Expand Down Expand Up @@ -393,7 +393,7 @@
assert [error + 31] = 108; // l
assert [error + 32] = 101; // e
assert [error + 33] = 32; //
assert [error + 34] = address; //
assert [error + 34] = '0' + address; //
return (35, error);
}

Expand Down Expand Up @@ -499,4 +499,67 @@
dw 'a';
dw 's';
}

func precompileInputError() -> (error_len: felt, error: felt*) {
greged93 marked this conversation as resolved.
Show resolved Hide resolved
let (error) = get_label_location(precompile_input_error_message);
return (27, error);

precompile_input_error_message:
dw 'P';
dw 'r';
dw 'e';
dw 'c';
dw 'o';
dw 'm';
dw 'p';
dw 'i';
dw 'l';
dw 'e';
dw ':';
dw ' ';
dw 'w';
dw 'r';
dw 'o';
dw 'n';
dw 'g';
dw ' ';
dw 'i';
dw 'n';
dw 'p';
dw 'u';
dw 't';
dw '_';
dw 'l';
dw 'e';
dw 'n';

Check warning on line 534 in src/kakarot/errors.cairo

View check run for this annotation

Codecov / codecov/patch

src/kakarot/errors.cairo#L508-L534

Added lines #L508 - L534 were not covered by tests
}

func precompileFlagError() -> (error_len: felt, error: felt*) {
greged93 marked this conversation as resolved.
Show resolved Hide resolved
let (error) = get_label_location(precompile_flag_error);
return (22, error);

precompile_flag_error:
dw 'P';
dw 'r';
dw 'e';
dw 'c';
dw 'o';
dw 'm';
dw 'p';
dw 'i';
dw 'l';
dw 'e';
dw ':';
dw ' ';
dw 'f';
dw 'l';
dw 'a';
dw 'g';
dw ' ';
dw 'e';
dw 'r';
dw 'r';
dw 'o';
dw 'r';

Check warning on line 563 in src/kakarot/errors.cairo

View check run for this annotation

Codecov / codecov/patch

src/kakarot/errors.cairo#L542-L563

Added lines #L542 - L563 were not covered by tests
}
}
17 changes: 9 additions & 8 deletions src/kakarot/precompiles/blake2f.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ from starkware.cairo.common.math_cmp import is_nn, is_le
from starkware.cairo.common.bool import FALSE

// Internal dependencies
from kakarot.errors import Errors
from utils.utils import Helpers

// @title Blake2f Precompile related functions.
Expand All @@ -34,7 +35,7 @@ namespace PrecompileBlake2f {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
alloc_locals;
local rounds_bytes_len = 4;
Expand All @@ -45,16 +46,16 @@ namespace PrecompileBlake2f {
local f_bytes_offset = 212;

// Check input length
with_attr error_message(
"Kakarot: blake2f failed with incorrect input_len: {input_len} instead of 213") {
assert input_len = 213;
if (input_len != 213) {
let (revert_reason_len, revert_reason) = Errors.precompileInputError();
return (revert_reason_len, revert_reason, 0, 1);
}

// Check the flag
tempvar f = input[f_bytes_offset];
with_attr error_message(
"Kakarot: blake2f failed with incorrect flag: {f} instead of 0 or 1") {
assert f = f * f;
if (f != f * f) {
let (revert_reason_len, revert_reason) = Errors.precompileFlagError();
return (revert_reason_len, revert_reason, 0, 1);
}

let rounds = Helpers.load_word(rounds_bytes_len, input);
Expand All @@ -81,7 +82,7 @@ namespace PrecompileBlake2f {
Helpers.split_word_little(compressed[6], word_bytes_len, output + 6 * word_bytes_len);
Helpers.split_word_little(compressed[7], word_bytes_len, output + 7 * word_bytes_len);

return (word_bytes_len * 8, output, rounds);
return (word_bytes_len * 8, output, rounds, 0);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/kakarot/precompiles/datacopy.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ namespace PrecompileDataCopy {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
let (minimum_word_size) = Helpers.minimum_word_count(input_len);
return (input_len, input, 3 * minimum_word_size + GAS_COST_DATACOPY);
return (input_len, input, 3 * minimum_word_size + GAS_COST_DATACOPY, 0);
}
}
16 changes: 9 additions & 7 deletions src/kakarot/precompiles/ec_recover.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ from starkware.cairo.common.cairo_secp.signature import (

// Internal dependencies
from utils.utils import Helpers
from kakarot.errors import Errors

// @title EcRecover Precompile related functions.
// @notice This file contains the logic required to run the ec_recover precompile
Expand All @@ -35,21 +36,22 @@ namespace PrecompileEcRecover {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
alloc_locals;

with_attr error_message(
"EcRecover: received wrong number of bytes in input: {input_len} instead of 4*32") {
assert input_len = 4 * 32;
if (input_len != 4 * 32) {
let (revert_reason_len, revert_reason) = Errors.precompileInputError();
return (revert_reason_len, revert_reason, 0, 1);
}

let hash = Helpers.bytes32_to_bigint(input);
let v_uint256 = Helpers.bytes32_to_uint256(input + 32);
let v = Helpers.uint256_to_felt(v_uint256);

with_attr error_message("EcRecover: Recovery identifier should be either 27 or 28") {
assert (v - 27) * (v - 28) = 0;
if ((v - 27) * (v - 28) != 0) {
let (revert_reason_len, revert_reason) = Errors.precompileFlagError();
return (revert_reason_len, revert_reason, 0, 1);
}

let r = Helpers.bytes32_to_bigint(input + 32 * 2);
Expand All @@ -68,6 +70,6 @@ namespace PrecompileEcRecover {
let (output) = alloc();
Helpers.split_word(public_address, 32, output);

return (32, output, GAS_COST_EC_RECOVER);
return (32, output, GAS_COST_EC_RECOVER, 0);
}
}
4 changes: 2 additions & 2 deletions src/kakarot/precompiles/ecadd.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace PrecompileEcAdd {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
alloc_locals;

Expand All @@ -53,6 +53,6 @@ namespace PrecompileEcAdd {
// We fill `output + bytes_x_len` ptr with `bytes_y` elements
Helpers.fill_array(bytes_y_len, bytes_y, output + bytes_x_len);

return (G1POINT_BYTES_LEN * 2, output, GAS_COST_EC_ADD);
return (G1POINT_BYTES_LEN * 2, output, GAS_COST_EC_ADD, 0);
}
}
4 changes: 2 additions & 2 deletions src/kakarot/precompiles/ecmul.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace PrecompileEcMul {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
alloc_locals;

Expand All @@ -50,6 +50,6 @@ namespace PrecompileEcMul {
// We fill `output + bytes_x_len` ptr with `bytes_y` elements
Helpers.fill_array(bytes_y_len, bytes_y, output + bytes_x_len);

return (G1POINT_BYTES_LEN * 2, output, GAS_COST_EC_MUL);
return (G1POINT_BYTES_LEN * 2, output, GAS_COST_EC_MUL, 0);
}
}
4 changes: 2 additions & 2 deletions src/kakarot/precompiles/modexp.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace PrecompileModExpUint256 {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
alloc_locals;

Expand Down Expand Up @@ -63,6 +63,6 @@ namespace PrecompileModExpUint256 {
b_size, m_size, e_size, b, e, m
);

return (output_len=bytes_len, output=bytes, gas_used=gas_cost);
return (bytes_len, bytes, gas_cost, 0);
}
}
44 changes: 24 additions & 20 deletions src/kakarot/precompiles/precompiles.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ from starkware.cairo.common.math_cmp import is_le, is_not_zero
// Internal dependencies
from kakarot.constants import Constants
from kakarot.execution_context import ExecutionContext
from kakarot.errors import Errors
from kakarot.memory import Memory
from kakarot.model import model
from kakarot.precompiles.blake2f import PrecompileBlake2f
Expand Down Expand Up @@ -48,9 +49,6 @@ namespace Precompiles {
) -> model.ExecutionContext* {
alloc_locals;

// Execute the precompile at a given evm_address
let (output_len, output, gas_used) = _exec_precompile(evm_address, calldata_len, calldata);

// Build returned execution context
let stack = Stack.init();
let memory = Memory.init();
Expand All @@ -71,7 +69,12 @@ namespace Precompiles {
);
let sub_ctx = ExecutionContext.init(call_context);
let sub_ctx = ExecutionContext.update_state(sub_ctx, calling_context.state);
let sub_ctx = ExecutionContext.stop(sub_ctx, output_len, output, FALSE);

// Execute the precompile at a given evm_address
let (output_len, output, gas_used, reverted) = _exec_precompile(
evm_address, calldata_len, calldata
);
let sub_ctx = ExecutionContext.stop(sub_ctx, output_len, output, reverted);

return sub_ctx;
}
Expand All @@ -88,13 +91,14 @@ namespace Precompiles {
// @return output_len The output length.
// @return output The output array.
// @return gas_used The gas usage of precompile.
// @return reverted Whether the precompile ran successfully or not
func _exec_precompile{
syscall_ptr: felt*,
pedersen_ptr: HashBuiltin*,
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(evm_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
// Compute the corresponding offset in the jump table:
// count 1 for "next line" and 3 steps per precompile evm_address: call, precompile, ret
Expand Down Expand Up @@ -143,11 +147,11 @@ namespace Precompiles {
pedersen_ptr: HashBuiltin*,
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(evm_address: felt, _input_len: felt, _input: felt*) {
with_attr error_message("Kakarot: UnknownPrecompile {evm_address}") {
assert 0 = 1;
}
return ();
}(evm_address: felt, _input_len: felt, _input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
let (revert_reason_len, revert_reason) = Errors.unknownPrecompile(evm_address);
return (revert_reason_len, revert_reason, 0, 1);
}

// @notice A placeholder for precompile that are not implemented yet.
Expand All @@ -160,11 +164,11 @@ namespace Precompiles {
pedersen_ptr: HashBuiltin*,
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(evm_address: felt, _input_len: felt, _input: felt*) {
with_attr error_message("Kakarot: NotImplementedPrecompile {evm_address}") {
assert 0 = 1;
}
return ();
}(evm_address: felt, _input_len: felt, _input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
let (revert_reason_len, revert_reason) = Errors.notImplementedPrecompile(evm_address);
return (revert_reason_len, revert_reason, 0, 1);
}

// @notice A placeholder for precompile that are not implemented yet.
Expand All @@ -177,10 +181,10 @@ namespace Precompiles {
pedersen_ptr: HashBuiltin*,
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(evm_address: felt, _input_len: felt, _input: felt*) {
with_attr error_message("Kakarot: NotWhitelistedPrecompile {evm_address}") {
assert 0 = 1;
}
return ();
}(evm_address: felt, _input_len: felt, _input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
let (revert_reason_len, revert_reason) = Errors.notImplementedPrecompile(evm_address);
return (revert_reason_len, revert_reason, 0, 1);
}
}
4 changes: 2 additions & 2 deletions src/kakarot/precompiles/ripemd160.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace PrecompileRIPEMD160 {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
alloc_locals;
let (local buf: felt*) = alloc();
Expand Down Expand Up @@ -76,7 +76,7 @@ namespace PrecompileRIPEMD160 {

// 5. return bytes hash code.
let (minimum_word_size) = Helpers.minimum_word_count(input_len);
return (32, arr_x - 12, 120 * minimum_word_size + GAS_COST_RIPEMD160);
return (32, arr_x - 12, 120 * minimum_word_size + GAS_COST_RIPEMD160, 0);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/kakarot/precompiles/sha256.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace PrecompileSHA256 {
range_check_ptr,
bitwise_ptr: BitwiseBuiltin*,
}(_address: felt, input_len: felt, input: felt*) -> (
output_len: felt, output: felt*, gas_used: felt
output_len: felt, output: felt*, gas_used: felt, reverted: felt
) {
alloc_locals;

Expand Down Expand Up @@ -82,7 +82,7 @@ namespace PrecompileSHA256 {
8, hash, 0, hash_bytes_array
);
let (minimum_word_size) = Helpers.minimum_word_count(input_len);
return (32, hash_bytes_array, 12 * minimum_word_size + GAS_COST_SHA256);
return (32, hash_bytes_array, 12 * minimum_word_size + GAS_COST_SHA256, 0);
}
}

Expand Down
Loading
Loading