Skip to content

Commit

Permalink
dev: add encode tuple access list and encode access list (#590)
Browse files Browse the repository at this point in the history
closes #589

this prepares #588 as encoding type 2 and 3 of transactions requires
encoding tuple access list
  • Loading branch information
Eikix authored Jan 28, 2025
1 parent efc13b9 commit 39d077b
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
76 changes: 75 additions & 1 deletion cairo/ethereum_rlp/rlp.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,14 @@ from ethereum_types.bytes import (
)
from ethereum.cancun.blocks import Log, TupleLog, Receipt, Withdrawal
from ethereum.cancun.fork_types import Address, Account, Bloom
from ethereum.cancun.transactions import LegacyTransaction, To
from ethereum.cancun.transactions import (
LegacyTransaction,
To,
AccessList,
AccessListStruct,
TupleAccessList,
AccessListTransaction,
)
from ethereum.crypto.hash import keccak256, Hash32
from ethereum.utils.numeric import is_zero
from src.utils.array import reverse
Expand Down Expand Up @@ -427,6 +434,32 @@ func encode_withdrawal{range_check_ptr}(raw_withdrawal: Withdrawal) -> Bytes {
return result;
}

func encode_tuple_access_list{range_check_ptr}(raw_tuple_access_list: TupleAccessList) -> Bytes {
alloc_locals;
let (local dst) = alloc();
let len = _encode_tuple_access_list(dst, raw_tuple_access_list);
tempvar result = Bytes(new BytesStruct(dst, len));
return result;
}

func encode_access_list{range_check_ptr}(raw_access_list: AccessList) -> Bytes {
alloc_locals;
let (local dst) = alloc();
let body_ptr = dst + PREFIX_LEN_MAX;

let address_len = _encode_address(body_ptr, raw_access_list.value.address);
let body_ptr = body_ptr + address_len;
let storage_keys_len = _encode_tuple_bytes32(body_ptr, raw_access_list.value.storage_keys);
let body_ptr = body_ptr + storage_keys_len;

let body_len = body_ptr - dst - PREFIX_LEN_MAX;
let body_ptr = dst + PREFIX_LEN_MAX;
let prefix_len = _encode_prefix_len(body_ptr, body_len);

tempvar result = Bytes(new BytesStruct(body_ptr - prefix_len, prefix_len + body_len));
return result;
}

//
// RLP Decode
//
Expand Down Expand Up @@ -833,6 +866,47 @@ func _encode_tuple_log_inner{range_check_ptr}(dst: felt*, len: felt, raw_tuple_l
return log_encoded.value.len + remaining_len;
}

func _encode_tuple_access_list_inner{range_check_ptr}(
dst: felt*, len: felt, raw_tuple_access_list: AccessList*
) -> felt {
alloc_locals;
if (len == 0) {
return 0;
}

// Encode current item
let access_list_encoded = encode_access_list(raw_tuple_access_list[0]);
memcpy(dst, access_list_encoded.value.data, access_list_encoded.value.len);

// Recursively encode remaining items
let remaining_len = _encode_tuple_access_list_inner(
dst + access_list_encoded.value.len, len - 1, raw_tuple_access_list + 1
);

return access_list_encoded.value.len + remaining_len;
}

func _encode_tuple_access_list{range_check_ptr}(
dst: felt*, tuple_access_list: TupleAccessList
) -> felt {
alloc_locals;
if (tuple_access_list.value.len == 0) {
assert [dst] = 0xc0;
return 1;
}

let (local tmp) = alloc();
let body_ptr = tmp + PREFIX_LEN_MAX;
let body_len = _encode_tuple_access_list_inner(
body_ptr, tuple_access_list.value.len, tuple_access_list.value.data
);
let prefix_len = _encode_prefix_len(body_ptr, body_len);

memcpy(dst, body_ptr - prefix_len, prefix_len + body_len);

return prefix_len + body_len;
}

func _encode_bloom{range_check_ptr}(dst: felt*, raw_bloom: Bloom) -> felt {
alloc_locals;
// Bloom is 256 bytes, so the prefix is [0xb7 + 2, 0x01, 0x00]
Expand Down
16 changes: 16 additions & 0 deletions cairo/tests/ethereum_rlp/test_rlp.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ def test_encode_receipt(self, cairo_run, receipt: Receipt):
def test_encode_withdrawal(self, cairo_run, withdrawal: Withdrawal):
assert encode(withdrawal) == cairo_run("encode_withdrawal", withdrawal)

@given(tuple_access_list=...)
def test_encode_tuple_access_list(
self,
cairo_run,
tuple_access_list: Tuple[Tuple[Address, Tuple[Bytes32, ...]], ...],
):
assert encode(tuple_access_list) == cairo_run(
"encode_tuple_access_list", tuple_access_list
)

@given(access_list=...)
def test_encode_access_list(
self, cairo_run, access_list: Tuple[Address, Tuple[Bytes32, ...]]
):
assert encode(access_list) == cairo_run("encode_access_list", access_list)

class TestDecode:
@given(raw_data=...)
def test_decode(self, cairo_run, raw_data: Extended):
Expand Down

0 comments on commit 39d077b

Please sign in to comment.