Skip to content

Commit

Permalink
feat: improve rust bindings compat (#395)
Browse files Browse the repository at this point in the history
improve rust bindings compat, enabling syntaxes like
- segments.memory.get(idx)
or 
- dict_trackers[idx] = X

based on a custom fork of the cairo vm in which I unbotherly created a
special `DictKey` type which is an
enum

```rust
#[derive(
    Eq, Ord, Hash, PartialEq, PartialOrd, Clone, Debug,
)]
pub enum DictKey {
    Simple(MaybeRelocatable),
    Compound(Vec<MaybeRelocatable>),
}
```

Which allows a Vec of Felts / Relocatable to be used as dict keys. For
us this is important because we need to track preimages that might not
fit in a felt inside the dict tracker.

This was implemented in a "dumb" way that is unconsidering of external
side effects to the Cairo-VM - once synced with LC we will want to
revisit the approach. see
https://github.com/kkrt-labs/cairo-vm/tree/kkrt-compat
  • Loading branch information
enitrat authored Jan 13, 2025
1 parent 9cb4ba4 commit 2802ec7
Show file tree
Hide file tree
Showing 26 changed files with 198 additions and 93 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ cairo-vm = { git = "https://github.com/lambdaclass/cairo-vm.git", tag = "v2.0.0-
] }

[patch."https://github.com/lambdaclass/cairo-vm.git"]
cairo-vm = { git = "https://github.com/ClementWalter/cairo-rs" }
cairo-vm = { git = "https://github.com/kkrt-labs/cairo-vm", rev = "dd3d3f6e76248fc02395b31cbefe5fe8183222f1" }
3 changes: 0 additions & 3 deletions cairo/tests/ethereum/cancun/utils/test_address.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from typing import Union

import pytest
from ethereum_types.bytes import Bytes32
from ethereum_types.numeric import U256, Uint
from hypothesis import given
Expand All @@ -12,8 +11,6 @@
to_address,
)

pytestmark = pytest.mark.python_vm


class TestAddress:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
from tests.utils.args_gen import Evm
from tests.utils.evm_builder import EvmBuilder

pytestmark = pytest.mark.python_vm


class TestArithmetic:
@given(evm=EvmBuilder().with_stack().with_gas_left().build())
Expand Down
2 changes: 0 additions & 2 deletions cairo/tests/ethereum/cancun/vm/instructions/test_bitwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
from tests.utils.args_gen import Evm
from tests.utils.evm_builder import EvmBuilder

pytestmark = pytest.mark.python_vm


class TestBitwise:
@given(evm=EvmBuilder().with_stack().with_gas_left().build())
Expand Down
3 changes: 0 additions & 3 deletions cairo/tests/ethereum/cancun/vm/instructions/test_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@
uint256,
)

pytestmark = pytest.mark.python_vm


# Specific environment strategy with minimal items:
# block_hashes, coinbase, number, gas_limit, time, prev_randao, chain_id are
# strategies, the rest:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
from tests.utils.args_gen import Evm
from tests.utils.strategies import evm_lite

pytestmark = pytest.mark.python_vm


class TestComparison:
@given(evm=evm_lite)
Expand Down
2 changes: 0 additions & 2 deletions cairo/tests/ethereum/cancun/vm/instructions/test_keccak.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
from tests.utils.args_gen import Evm
from tests.utils.strategies import evm_lite, memory_access_size, memory_start_position

pytestmark = pytest.mark.python_vm


class TestKeccak:
@given(
Expand Down
2 changes: 0 additions & 2 deletions cairo/tests/ethereum/cancun/vm/instructions/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
from tests.utils.args_gen import Evm
from tests.utils.strategies import evm_lite, memory_access_size, memory_start_position

pytestmark = pytest.mark.python_vm


class TestLog:
@given(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
from tests.utils.args_gen import Evm
from tests.utils.strategies import evm_lite

pytestmark = pytest.mark.python_vm


class TestMemory:
@given(evm=evm_lite)
Expand Down
4 changes: 0 additions & 4 deletions cairo/tests/ethereum/cancun/vm/test_memory.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import pytest
from ethereum_types.bytes import Bytes
from ethereum_types.numeric import U256
from hypothesis import given
Expand Down Expand Up @@ -38,9 +37,6 @@ def memory_read_strategy(draw):
return memory, start_position, size


pytestmark = pytest.mark.python_vm


class TestMemory:
@given(memory_write_strategy())
def test_memory_write(self, cairo_run, params):
Expand Down
3 changes: 0 additions & 3 deletions cairo/tests/ethereum/cancun/vm/test_runtime.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import pytest
from ethereum_types.bytes import Bytes
from hypothesis import given

from ethereum.cancun.vm.runtime import get_valid_jump_destinations

pytestmark = pytest.mark.python_vm


class TestRuntime:
@given(code=...)
Expand Down
2 changes: 0 additions & 2 deletions cairo/tests/ethereum/cancun/vm/test_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
from ethereum.cancun.vm.exceptions import StackOverflowError, StackUnderflowError
from ethereum.cancun.vm.stack import pop, push

pytestmark = pytest.mark.python_vm


class TestStack:
def test_pop_underflow(self, cairo_run):
Expand Down
3 changes: 0 additions & 3 deletions cairo/tests/ethereum/crypto/test_hash.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import pytest
from ethereum_types.bytes import Bytes
from hypothesis import assume, given

from ethereum.crypto.hash import keccak256

pytestmark = pytest.mark.python_vm


class TestHash:

Expand Down
2 changes: 0 additions & 2 deletions cairo/tests/ethereum/test_rlp.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
)
from tests.utils.errors import cairo_error

pytestmark = pytest.mark.python_vm


class TestRlp:
class TestEncode:
Expand Down
5 changes: 0 additions & 5 deletions cairo/tests/src/test_stack.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
import pytest

pytestmark = pytest.mark.python_vm


class TestStack:
class TestPeek:
def test_should_return_stack_at_given_index__when_value_is_0(self, cairo_run):
Expand Down
3 changes: 0 additions & 3 deletions cairo/tests/test_serde.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,6 @@ def single_evm_parent(b: Union[Message, Evm]) -> bool:
return True


pytestmark = pytest.mark.python_vm


class TestSerde:
@given(b=...)
# 20 examples per type
Expand Down
40 changes: 22 additions & 18 deletions cairo/tests/utils/args_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
)

from cairo_addons.vm import DictTracker as RustDictTracker
from cairo_addons.vm import MemorySegmentManager as RustMemorySegmentManager
from cairo_addons.vm import Relocatable as RustRelocatable
from ethereum_types.bytes import (
Bytes,
Expand All @@ -100,6 +101,7 @@
from starkware.cairo.lang.compiler.program import Program
from starkware.cairo.lang.compiler.scoped_name import ScopedName
from starkware.cairo.lang.vm.crypto import poseidon_hash_many
from starkware.cairo.lang.vm.memory_segments import MemorySegmentManager
from starkware.cairo.lang.vm.relocatable import RelocatableValue

from ethereum.cancun.blocks import Header, Log, Receipt, Withdrawal
Expand Down Expand Up @@ -374,7 +376,7 @@ def gen_arg(dict_manager, segments):

def _gen_arg(
dict_manager,
segments,
segments: Union[MemorySegmentManager, RustMemorySegmentManager],
arg_type: Type,
arg: Any,
annotations: Optional[Any] = None,
Expand Down Expand Up @@ -545,19 +547,15 @@ def _gen_arg(
data=data, current_ptr=current_ptr
)
else:
dict_manager.insert(
dict_ptr.segment_index,
RustDictTracker(
keys=list(data.keys()),
values=list(data.values()),
current_ptr=current_ptr,
default_value=(
data.default_factory()
if isinstance(data, defaultdict)
else None
),
),
default_value = (
data.default_factory() if isinstance(data, defaultdict) else None
)
dict_manager.trackers[dict_ptr.segment_index] = RustDictTracker(
data=data,
current_ptr=current_ptr,
default_value=default_value,
)

base = segments.add()

# The last element is the original_segment_stop pointer.
Expand Down Expand Up @@ -598,11 +596,17 @@ def _gen_arg(

if arg_type_origin is Trie:
# In case of a Trie, we need the dict to be a defaultdict with the trie.default as the default value.
dict_ptr = segments.memory[data[2]]
dict_manager.trackers[dict_ptr.segment_index].data = defaultdict(
lambda: data[1], dict_manager.trackers[dict_ptr.segment_index].data
)

dict_ptr = segments.memory.get(data[2])
if isinstance(dict_manager, DictManager):
dict_manager.trackers[dict_ptr.segment_index].data = defaultdict(
lambda: data[1], dict_manager.trackers[dict_ptr.segment_index].data
)
else:
dict_manager.trackers[dict_ptr.segment_index] = RustDictTracker(
data=dict_manager.trackers[dict_ptr.segment_index].data,
current_ptr=dict_ptr,
default_value=data[1],
)
return struct_ptr

if arg_type in (U256, Hash32, Bytes32, Bytes256):
Expand Down
4 changes: 1 addition & 3 deletions cairo/tests/utils/serde.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ def __init__(
cairo_file=None,
):
self.segments = segments
self.memory = (
segments.memory if isinstance(segments, MemorySegmentManager) else segments
)
self.memory = segments.memory
self.program = program
self.dict_manager = dict_manager
self.cairo_file = cairo_file or Path()
Expand Down
Loading

0 comments on commit 2802ec7

Please sign in to comment.