Skip to content

Commit

Permalink
dev: migrate to use ethereum-types (#231)
Browse files Browse the repository at this point in the history
Closes #230

@ClementWalter: do you want to migrate the cairo files to a
`ethereum_types.{numeric | bytes}` module?
if so - what about the compound types - do we create a third file ?

---------

Co-authored-by: Clément Walter <clement0walter@gmail.com>
  • Loading branch information
enitrat and ClementWalter authored Dec 11, 2024
1 parent 54912a7 commit 668f927
Show file tree
Hide file tree
Showing 34 changed files with 1,298 additions and 1,134 deletions.
13 changes: 2 additions & 11 deletions cairo/ethereum/cancun/blocks.cairo
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
from ethereum.base_types import (
U64,
U256,
Bytes,
Bytes8,
Bytes32,
Uint,
TupleBytes32,
bool,
TupleBytes,
)
from ethereum_types.numeric import U64, U256, Uint, bool
from ethereum_types.bytes import Bytes, Bytes8, Bytes32, TupleBytes, TupleBytes32
from ethereum.cancun.fork_types import Address, Bloom, Root
from ethereum.crypto.hash import Hash32

Expand Down
3 changes: 2 additions & 1 deletion cairo/ethereum/cancun/fork.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from starkware.cairo.common.bool import TRUE, FALSE
from starkware.cairo.common.math_cmp import is_le
from starkware.cairo.common.math import assert_not_zero
from ethereum.base_types import Uint, Bytes, Bytes0, bool
from ethereum_types.numeric import Uint, bool
from ethereum_types.bytes import Bytes, Bytes0
from ethereum.utils.numeric import divmod
from ethereum.cancun.blocks import Header
from ethereum.cancun.transactions import (
Expand Down
3 changes: 2 additions & 1 deletion cairo/ethereum/cancun/fork_types.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin
from starkware.cairo.common.memcpy import memcpy
from src.utils.bytes import felt_to_bytes_little, uint256_to_bytes32_little, felt_to_bytes20_little
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.base_types import Bytes20, Bytes256, Uint, U256, Bytes, BytesStruct
from ethereum_types.bytes import Bytes20, Bytes256, Bytes, BytesStruct
from ethereum_types.numeric import Uint, U256
using Address = Bytes20;
using Root = Hash32;

Expand Down
3 changes: 2 additions & 1 deletion cairo/ethereum/cancun/transactions.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from ethereum.base_types import BytesStruct, Bytes, Bytes0, Uint, U256, TupleBytes32, U64
from ethereum_types.bytes import BytesStruct, Bytes, Bytes0, TupleBytes32
from ethereum_types.numeric import Uint, U256, U64
from ethereum.cancun.fork_types import Address, TupleVersionedHash

const TX_BASE_COST = 21000;
Expand Down
6 changes: 2 additions & 4 deletions cairo/ethereum/cancun/trie.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,10 @@ from src.utils.bytes import uint256_to_bytes32_little
from ethereum.crypto.hash import keccak256
from ethereum.utils.numeric import min
from ethereum.rlp import encode, _encode_bytes, _encode
from ethereum.base_types import (
U256,
from ethereum_types.numeric import U256, Uint, bool
from ethereum_types.bytes import (
Bytes,
Uint,
BytesStruct,
bool,
StringStruct,
String,
MappingBytesBytes,
Expand Down
2 changes: 1 addition & 1 deletion cairo/ethereum/cancun/vm/gas.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ethereum.base_types import U256, Uint, U64
from ethereum_types.numeric import U256, Uint, U64
from ethereum.utils.numeric import is_zero, divmod, taylor_exponential, min, ceil32
from ethereum.cancun.blocks import Header
from ethereum.cancun.transactions import Transaction
Expand Down
3 changes: 2 additions & 1 deletion cairo/ethereum/crypto/hash.cairo
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from ethereum.base_types import Bytes32, Bytes, Uint256
from ethereum_types.bytes import Bytes32, Bytes
from src.utils.bytes import bytes_to_bytes8_little_endian
from starkware.cairo.common.builtin_keccak.keccak import keccak
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.alloc import alloc

using Hash32 = Bytes32;
Expand Down
6 changes: 2 additions & 4 deletions cairo/ethereum/rlp.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ from starkware.cairo.common.math_cmp import is_le, is_not_zero
from starkware.cairo.common.math import assert_not_zero
from starkware.cairo.common.memcpy import memcpy

from ethereum.base_types import (
Bool,
from ethereum_types.numeric import Bool, U256, Uint
from ethereum_types.bytes import (
Bytes,
BytesStruct,
Bytes32,
TupleBytes,
TupleBytesStruct,
Uint,
U256,
String,
StringStruct,
TupleBytes32,
Expand Down
2 changes: 1 addition & 1 deletion cairo/ethereum/utils/numeric.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from starkware.cairo.common.math_cmp import is_le, is_not_zero
from ethereum.base_types import Uint
from ethereum_types.numeric import Uint

func min{range_check_ptr}(a: felt, b: felt) -> felt {
if (a == b) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,6 @@
from starkware.cairo.common.dict_access import DictAccess
from starkware.cairo.common.uint256 import Uint256

// None values are just null pointers generally speaking (i.e. cast(my_var, felt) == 0)
// but we need to explicitly define None to be able to serialize/deserialize None
struct None {
value: felt*,
}

// Int types
struct bool {
value: felt,
}
using Bool = bool;
struct U64 {
value: felt,
}
struct U128 {
value: felt,
}
struct Uint {
value: felt,
}
struct U256 {
value: Uint256*,
}
from ethereum_types.numeric import U128

// Bytes types
struct Bytes0 {
Expand Down
19 changes: 19 additions & 0 deletions cairo/ethereum_types/numeric.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from starkware.cairo.common.uint256 import Uint256

// Int types
struct bool {
value: felt,
}
using Bool = bool;
struct U64 {
value: felt,
}
struct U128 {
value: felt,
}
struct Uint {
value: felt,
}
struct U256 {
value: Uint256*,
}
5 changes: 5 additions & 0 deletions cairo/ethereum_types/others.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// None values are just null pointers generally speaking (i.e. cast(my_var, felt) == 0)
// but we need to explicitly define None to be able to serialize/deserialize None
struct None {
value: felt*,
}
2 changes: 1 addition & 1 deletion cairo/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ profile = "black"
src_paths = ["src", "tests"]

[tool.uv.sources]
ethereum = { git = "https://github.com/ethereum/execution-specs.git" }
ethereum = { git = "https://github.com/ethereum/execution-specs.git", rev = "1adcc1bfe774798bcacc685aebc17bd9935078c3" }

[build-system]
requires = ["hatchling"]
Expand Down
6 changes: 4 additions & 2 deletions cairo/scripts/generate_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,10 @@ def _add_type_imports(self, node: ast.AST) -> None:
"""Add imports needed for type annotations"""
if isinstance(node, ast.Name):
# Add basic types to imports if they're from ethereum
if node.id in {"U256", "U64", "Uint", "Bytes", "Bytes32"}:
self.imports.add("from ethereum.base_types import " + node.id)
if node.id in {"U256", "U64", "Uint"}:
self.imports.add("from ethereum_types.numeric import " + node.id)
elif node.id in {"Bytes", "Bytes32"}:
self.imports.add("from ethereum_types.bytes import " + node.id)
elif isinstance(node, ast.Subscript):
# Handle generic types
if isinstance(node.value, ast.Name):
Expand Down
6 changes: 3 additions & 3 deletions cairo/tests/ethereum/cancun/test_fork.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ethereum_types.numeric import Uint
from hypothesis import assume, given

from ethereum.base_types import Uint
from ethereum.cancun.blocks import Header
from ethereum.cancun.fork import (
GAS_LIMIT_ADJUSTMENT_FACTOR,
Expand Down Expand Up @@ -78,8 +78,8 @@ def test_calculate_intrinsic_cost(self, cairo_run, tx: Transaction):
@given(gas_limit=..., parent_gas_limit=...)
def test_check_gas_limit(self, cairo_run, gas_limit: Uint, parent_gas_limit: Uint):
assume(
int(parent_gas_limit) + int(parent_gas_limit) // GAS_LIMIT_ADJUSTMENT_FACTOR
< 2**64
parent_gas_limit + parent_gas_limit // GAS_LIMIT_ADJUSTMENT_FACTOR
< Uint(2**64)
)
assert check_gas_limit(gas_limit, parent_gas_limit) == cairo_run(
"check_gas_limit", gas_limit, parent_gas_limit
Expand Down
3 changes: 2 additions & 1 deletion cairo/tests/ethereum/cancun/test_trie.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from typing import Mapping, Optional

import pytest
from ethereum_types.bytes import Bytes
from ethereum_types.numeric import Uint
from hypothesis import assume, given
from hypothesis import strategies as st

from ethereum.base_types import Bytes, Uint
from ethereum.cancun.fork_types import Account
from ethereum.cancun.trie import (
InternalNode,
Expand Down
2 changes: 1 addition & 1 deletion cairo/tests/ethereum/cancun/vm/test_gas.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ethereum_types.numeric import U256, Uint
from hypothesis import assume, given
from hypothesis import strategies as st

from ethereum.base_types import U256, Uint
from ethereum.cancun.blocks import Header
from ethereum.cancun.transactions import BlobTransaction
from ethereum.cancun.vm.gas import (
Expand Down
2 changes: 1 addition & 1 deletion cairo/tests/ethereum/crypto/test_hash.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ethereum_types.bytes import Bytes
from hypothesis import assume, given

from ethereum.base_types import Bytes
from ethereum.crypto.hash import keccak256


Expand Down
3 changes: 2 additions & 1 deletion cairo/tests/ethereum/test_rlp.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from typing import Sequence, Tuple, Union

import pytest
from ethereum_types.bytes import Bytes, Bytes0, Bytes32
from ethereum_types.numeric import U256, Uint
from hypothesis import assume, given

from ethereum.base_types import U256, Bytes, Bytes0, Bytes32, Uint
from ethereum.cancun.blocks import Log, Receipt, Withdrawal
from ethereum.cancun.fork_types import Account, Address, Bloom, encode_account
from ethereum.cancun.transactions import LegacyTransaction
Expand Down
4 changes: 2 additions & 2 deletions cairo/tests/ethereum/utils/test_numeric.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from ethereum_types.numeric import Uint
from hypothesis import given
from hypothesis import strategies as st
from starkware.cairo.lang.instances import PRIME

from ethereum.base_types import Uint
from ethereum.cancun.vm.gas import BLOB_GASPRICE_UPDATE_FRACTION, MIN_BLOB_GASPRICE
from ethereum.utils.numeric import ceil32, taylor_exponential
from tests.utils.strategies import felt, uint128
Expand Down Expand Up @@ -34,7 +34,7 @@ def test_ceil32(self, cairo_run, value: Uint):

@given(
factor=st.just(MIN_BLOB_GASPRICE),
numerator=st.integers(min_value=1, max_value=100_000),
numerator=st.integers(min_value=1, max_value=100_000).map(Uint),
denominator=st.just(BLOB_GASPRICE_UPDATE_FRACTION),
)
def test_taylor_exponential(
Expand Down
7 changes: 6 additions & 1 deletion cairo/tests/programs/test_os.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from eth_abi import encode
from ethereum_types.numeric import U256
from hypothesis import given
from hypothesis.strategies import integers

Expand Down Expand Up @@ -127,7 +128,11 @@ def test_block_hint(self, cairo_run):
),
]

@given(s_value=integers(min_value=SECP256K1N // 2 + 1, max_value=SECP256K1N))
@given(
s_value=integers(
min_value=SECP256K1N // U256(2) + U256(1), max_value=SECP256K1N
)
)
def test_should_raise_on_invalid_s_value(self, cairo_run, s_value):
initial_state = {
OWNER: {
Expand Down
14 changes: 7 additions & 7 deletions cairo/tests/src/precompiles/test_ec_recover.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import pytest
from ethereum_types.numeric import U256
from hypothesis import given
from hypothesis import strategies as st

from ethereum.base_types import U256
from ethereum.crypto.elliptic_curve import SECP256K1N, secp256k1_recover
from ethereum.crypto.hash import Hash32, keccak256
from ethereum.utils.byte import left_pad_zero_bytes
Expand All @@ -16,15 +16,15 @@ def ecrecover(data):
r = U256.from_be_bytes(data[64:96])
s = U256.from_be_bytes(data[96:128])

if v != 27 and v != 28:
if v != U256(27) and v != U256(28):
return []
if 0 >= r or r >= SECP256K1N:
if U256(0) >= r or r >= SECP256K1N:
return []
if 0 >= s or s >= SECP256K1N:
if U256(0) >= s or s >= SECP256K1N:
return []

try:
public_key = secp256k1_recover(r, s, v - 27, message_hash)
public_key = secp256k1_recover(r, s, v - U256(27), message_hash)
except ValueError:
# unable to extract public key
return []
Expand Down Expand Up @@ -64,8 +64,8 @@ def test_invalid_input_length(self, input_length, cairo_run):
@given(
v=st.integers(min_value=0, max_value=26) | st.integers(min_value=29),
msg=st.binary(min_size=32, max_size=32),
r=st.integers(min_value=1, max_value=SECP256K1N - 1),
s=st.integers(min_value=1, max_value=SECP256K1N - 1),
r=st.integers(min_value=U256(1), max_value=SECP256K1N - U256(1)),
s=st.integers(min_value=U256(1), max_value=SECP256K1N - U256(1)),
)
def test_invalid_v(self, v, msg, r, s, cairo_run):
"""Test with invalid v values."""
Expand Down
Loading

0 comments on commit 668f927

Please sign in to comment.