Skip to content

Commit

Permalink
Add rlp.encode_bytes
Browse files Browse the repository at this point in the history
  • Loading branch information
ClementWalter committed Nov 12, 2024
1 parent d963259 commit bb21950
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 2 deletions.
49 changes: 49 additions & 0 deletions cairo/ethereum/rlp.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from starkware.cairo.common.math_cmp import is_le, is_not_zero
from starkware.cairo.common.alloc import alloc
from starkware.cairo.common.memcpy import memcpy
from ethereum.base_types import Bytes, BytesStruct
from ethereum.utils.numeric import is_zero
from src.utils.bytes import felt_to_bytes

func encode_bytes{range_check_ptr}(raw_bytes: Bytes) -> Bytes {
alloc_locals;

let len_raw_data = raw_bytes.value.len;

if (len_raw_data == 0) {
let (data) = alloc();
assert [data] = 0x80;
tempvar value = new BytesStruct(data, 1);
let encoded_bytes = Bytes(value);
return encoded_bytes;
}

let cond_1 = is_le(raw_bytes.value.data[0], 0x80 - 1);
let cond_2 = is_zero(len_raw_data - 1);
if (cond_1 * cond_2 != 0) {
return raw_bytes;
}

let cond = is_le(len_raw_data, 0x38 - 1);
if (cond != 0) {
let (data) = alloc();
assert [data] = 0x80 + len_raw_data;
memcpy(data + 1, raw_bytes.value.data, len_raw_data);
tempvar value = new BytesStruct(data, len_raw_data + 1);
let encoded_bytes = Bytes(value);
return encoded_bytes;
}

// len_raw_data > 0x38
let (data) = alloc();

let len_raw_data_as_be = felt_to_bytes(data + 1, len_raw_data);
assert [data] = 0xB7 + len_raw_data_as_be;

memcpy(data + 1 + len_raw_data_as_be, raw_bytes.value.data, raw_bytes.value.len);
tempvar value = new BytesStruct(data, 1 + len_raw_data_as_be + raw_bytes.value.len);
let encoded_bytes = Bytes(value);

return encoded_bytes;
}
9 changes: 9 additions & 0 deletions cairo/ethereum/utils/numeric.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ func min{range_check_ptr}(a: felt, b: felt) -> felt {
return b;
}

@known_ap_change
func is_zero(value) -> felt {
if (value == 0) {
return 1;
}

return 0;
}

// @dev Inlined version of unsigned_div_rem
// Returns q and r such that:
// 0 <= q < rc_bound, 0 <= r < div and value = q * div + r.
Expand Down
9 changes: 9 additions & 0 deletions cairo/tests/ethereum/test_rlp.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from ethereum.rlp import encode_bytes
from ethereum.base_types import Bytes

func test_encode_bytes{range_check_ptr}() -> Bytes {
tempvar raw_bytes: Bytes;
%{ memory[ap - 1] = gen_arg(program_input["raw_bytes"]) %}
let encoded_bytes = encode_bytes(raw_bytes);
return encoded_bytes;
}
12 changes: 12 additions & 0 deletions cairo/tests/ethereum/test_rlp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import hypothesis.strategies as st
from hypothesis import given

from ethereum.rlp import encode_bytes


class TestRlp:
@given(raw_bytes=st.binary())
def test_encode_bytes(self, cairo_run, raw_bytes):
assert encode_bytes(raw_bytes) == cairo_run(
"test_encode_bytes", raw_bytes=raw_bytes
)
8 changes: 7 additions & 1 deletion cairo/tests/ethereum/utils/test_numeric.cairo
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from ethereum.utils.numeric import min, divmod
from ethereum.utils.numeric import min, divmod, is_zero

func test_min{range_check_ptr}() -> felt {
tempvar a;
Expand All @@ -20,3 +20,9 @@ func test_divmod{range_check_ptr}() -> (q: felt, r: felt) {
%}
return divmod(value, div);
}

func test_is_zero() -> felt {
tempvar value;
%{ ids.value = program_input["value"] %}
return is_zero(value);
}
6 changes: 5 additions & 1 deletion cairo/tests/ethereum/utils/test_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from hypothesis import strategies as st
from starkware.cairo.lang.instances import PRIME

from tests.utils.strategies import uint128
from tests.utils.strategies import felt, uint128


class TestNumeric:
Expand All @@ -18,3 +18,7 @@ def test_divmod(self, cairo_run, value, div):
assert list(divmod(value, div)) == cairo_run(
"test_divmod", value=value, div=div
)

@given(value=felt)
def test_is_zero(self, cairo_run, value):
assert (value == 0) == cairo_run("test_is_zero", value=value)

0 comments on commit bb21950

Please sign in to comment.