From 7f842a3aee24ca83885df197c19e4aa6e6c01079 Mon Sep 17 00:00:00 2001 From: Pia Date: Fri, 10 May 2024 13:48:43 +0900 Subject: [PATCH] rm un necessary dependencies --- tests/cairo_programs/account_decoder.cairo | 92 --- .../cairo_programs/aggregate_functions.cairo | 213 ------- .../block_sampled_datalake.cairo | 77 --- tests/cairo_programs/computational_task.cairo | 181 ------ tests/cairo_programs/header_decoder.cairo | 36 -- tests/cairo_programs/merkle.cairo | 136 ---- tests/cairo_programs/rlp.cairo | 602 ------------------ tests/cairo_programs/test_vectors.cairo | 354 ---------- tests/cairo_programs/tx_decoder.cairo | 55 -- .../txs_in_block_datalake.cairo | 119 ---- tests/fuzzing/header_decode.cairo | 34 - tests/fuzzing/tx_decode.cairo | 52 -- tests/python/test_header_decoding.py | 118 ---- tests/python/test_poseidon_hash_block.py | 50 -- tests/python/test_tx_decoding.py | 160 ----- tests/python/test_verify_getproof.py | 164 ----- tests/utils/header.cairo | 290 --------- tests/utils/tx.cairo | 272 -------- tools/js/merkle.js | 24 - tools/js/package.json | 16 - tools/make/README.md | 135 ---- tools/make/build.sh | 30 - tools/make/cairo_format_check.sh | 27 - tools/make/cairo_tests.sh | 39 -- tools/make/ci_local.sh | 31 - tools/make/format_cairo_files.sh | 27 - tools/make/full_flow_test.sh | 63 -- tools/make/fuzzer.sh | 62 -- tools/make/launch_cairo_files.py | 205 ------ tools/make/python_format_check.sh | 2 - tools/make/requirements.txt | 9 - tools/make/setup.sh | 53 -- tools/py/block_header.py | 219 ------- tools/py/fetch_block_headers.py | 80 --- tools/py/fetch_tx.py | 54 -- tools/py/transaction.py | 404 ------------ 36 files changed, 4485 deletions(-) delete mode 100644 tests/cairo_programs/account_decoder.cairo delete mode 100644 tests/cairo_programs/aggregate_functions.cairo delete mode 100644 tests/cairo_programs/block_sampled_datalake.cairo delete mode 100644 tests/cairo_programs/computational_task.cairo delete mode 100644 tests/cairo_programs/header_decoder.cairo delete mode 100644 tests/cairo_programs/merkle.cairo delete mode 100644 tests/cairo_programs/rlp.cairo delete mode 100644 tests/cairo_programs/test_vectors.cairo delete mode 100644 tests/cairo_programs/tx_decoder.cairo delete mode 100644 tests/cairo_programs/txs_in_block_datalake.cairo delete mode 100644 tests/fuzzing/header_decode.cairo delete mode 100644 tests/fuzzing/tx_decode.cairo delete mode 100644 tests/python/test_header_decoding.py delete mode 100644 tests/python/test_poseidon_hash_block.py delete mode 100644 tests/python/test_tx_decoding.py delete mode 100644 tests/python/test_verify_getproof.py delete mode 100644 tests/utils/header.cairo delete mode 100644 tests/utils/tx.cairo delete mode 100644 tools/js/merkle.js delete mode 100644 tools/js/package.json delete mode 100644 tools/make/README.md delete mode 100755 tools/make/build.sh delete mode 100755 tools/make/cairo_format_check.sh delete mode 100755 tools/make/cairo_tests.sh delete mode 100755 tools/make/ci_local.sh delete mode 100755 tools/make/format_cairo_files.sh delete mode 100755 tools/make/full_flow_test.sh delete mode 100755 tools/make/fuzzer.sh delete mode 100755 tools/make/launch_cairo_files.py delete mode 100755 tools/make/python_format_check.sh delete mode 100644 tools/make/requirements.txt delete mode 100755 tools/make/setup.sh delete mode 100644 tools/py/block_header.py delete mode 100644 tools/py/fetch_block_headers.py delete mode 100644 tools/py/fetch_tx.py delete mode 100644 tools/py/transaction.py diff --git a/tests/cairo_programs/account_decoder.cairo b/tests/cairo_programs/account_decoder.cairo deleted file mode 100644 index fef08ef..0000000 --- a/tests/cairo_programs/account_decoder.cairo +++ /dev/null @@ -1,92 +0,0 @@ -%builtins range_check bitwise -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256, uint256_reverse_endian - -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin -from src.decoders.account_decoder import AccountDecoder, AccountField -from packages.eth_essentials.lib.utils import pow2alloc128 - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { - alloc_locals; - let pow2_array: felt* = pow2alloc128(); - - let (account_one: felt*) = alloc(); - let (account_two: felt*) = alloc(); - %{ - from tools.py.utils import ( - bytes_to_8_bytes_chunks_little, - ) - account_one_bytes = bytes.fromhex("f8440180a0b08d8d9b22ac1cc11aa964f398cab09d79a498de101033ee0d82b406e7622e20a0cafbd9135200b24454a9ffcac5a8db40947a17f8a8a542062d0f1fb48bd8b269") - account_one_chunks = bytes_to_8_bytes_chunks_little(account_one_bytes) - - account_two_bytes = bytes.fromhex("f84c358820e9ce1cd62eef86a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") - account_two_chunks = bytes_to_8_bytes_chunks_little(account_two_bytes) - - segments.write_arg(ids.account_one, account_one_chunks) - segments.write_arg(ids.account_two, account_two_chunks) - %} - - // ACCOUNT ONE - let nonce_le = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_one, field=AccountField.NONCE); - let (nonce) = uint256_reverse_endian(nonce_le); - - assert nonce.low = 1; - assert nonce.high = 0; - - let balance_le = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_one, field=AccountField.BALANCE); - - let (balance) = uint256_reverse_endian(balance_le); - assert balance.low = 0; - assert balance.high = 0; - - let state_root = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_one, field=AccountField.STATE_ROOT); - - assert state_root.low = 0x9DB0CA98F364A91AC11CAC229B8D8DB0; - assert state_root.high = 0x202E62E706B4820DEE331010DE98A479; - - let code_hash = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_one, field=AccountField.CODE_HASH); - - assert code_hash.low = 0x40DBA8C5CAFFA95444B2005213D9FBCA; - assert code_hash.high = 0x69B2D88BB41F0F2D0642A5A8F8177A94; - - // ACCOUNT TWO - let nonce_le = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_two, field=AccountField.NONCE); - let (nonce) = uint256_reverse_endian(nonce_le); - - assert nonce.low = 0x35; - assert nonce.high = 0; - - let balance_le = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_two, field=AccountField.BALANCE); - let (balance) = uint256_reverse_endian(balance_le); - - assert balance.low = 0x20e9ce1cd62eef86; - assert balance.high = 0; - - let state_root = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_two, field=AccountField.STATE_ROOT); - - assert state_root.low = 0x6EF8C092E64583FFA655CC1B171FE856; - assert state_root.high = 0x21B463E3B52F6201C0AD6C991BE0485B; - - let code_hash = AccountDecoder.get_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(rlp=account_two, field=AccountField.CODE_HASH); - - assert code_hash.low = 0xC003C7DCB27D7E923C23F7860146D2C5; - assert code_hash.high = 0x70A4855D04D8FA7B3B2782CA53B600E5; - - return (); -} diff --git a/tests/cairo_programs/aggregate_functions.cairo b/tests/cairo_programs/aggregate_functions.cairo deleted file mode 100644 index 1af171c..0000000 --- a/tests/cairo_programs/aggregate_functions.cairo +++ /dev/null @@ -1,213 +0,0 @@ -%builtins range_check bitwise -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin - -from src.tasks.aggregate_functions.sum import compute_sum -from src.tasks.aggregate_functions.avg import compute_avg -from src.tasks.aggregate_functions.min_max import ( - uint256_min_be, - uint256_max_be, - uint256_min_le, - uint256_max_le, -) -from src.tasks.aggregate_functions.count_if import count_if - -from starkware.cairo.common.uint256 import Uint256, uint256_eq, uint256_reverse_endian -from starkware.cairo.common.alloc import alloc - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { - avg_sum{range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr}(); - min_max{range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr}(); - count_if_main{range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr}(); - return (); -} - -func avg_sum{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { - alloc_locals; - let (round_down_values_le: Uint256*) = alloc(); - let (v0) = uint256_reverse_endian(Uint256(low=2, high=0)); - let (v1) = uint256_reverse_endian(Uint256(low=2, high=0)); - let (v2) = uint256_reverse_endian(Uint256(low=3, high=0)); - - assert round_down_values_le[0] = v0; - assert round_down_values_le[1] = v1; - assert round_down_values_le[2] = v2; - - let expected_sum = Uint256(low=7, high=0); - let expected_avg = Uint256(low=2, high=0); // sum is 7, avg is 7/3 = 2.333 -> 2 - - let sum = compute_sum(values_le=round_down_values_le, values_len=3); - let (eq) = uint256_eq(a=sum, b=expected_sum); - assert eq = 1; - - let avg_round_down = compute_avg(values=round_down_values_le, values_len=3); - let (eq) = uint256_eq(a=avg_round_down, b=expected_avg); - assert eq = 1; - - let (round_up_values_le: Uint256*) = alloc(); - - let (v0) = uint256_reverse_endian(Uint256(low=2, high=0)); - let (v1) = uint256_reverse_endian(Uint256(low=2, high=0)); - let (v2) = uint256_reverse_endian(Uint256(low=3, high=0)); - let (v3) = uint256_reverse_endian(Uint256(low=3, high=0)); - - assert round_up_values_le[0] = v0; - assert round_up_values_le[1] = v1; - assert round_up_values_le[2] = v2; - assert round_up_values_le[3] = v3; - - let expected_avg_up = Uint256(low=3, high=0); // sum is 10, avg is 10/4 = 2.5 -> 3 - let avg_round_up = compute_avg(values=round_up_values_le, values_len=4); - let (eq) = uint256_eq(a=avg_round_up, b=expected_avg_up); - assert eq = 1; - - return (); -} - -func min_max{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { - alloc_locals; - let (local arr_be: felt*) = alloc(); - local res_min: Uint256; - local res_max: Uint256; - local len; - - %{ - from tools.py.utils import uint256_reverse_endian, from_uint256, split_128 - import random - arr = [random.randint(0, 2**256-1) for _ in range(3)] - arr.append(min(arr)+1) - arr.append(max(arr)-1) - res_min = split_128(min(arr)) - res_max = split_128(max(arr)) - arr_be = [split_128(x) for x in arr] - def write_uint256_array(ptr, array): - counter = 0 - for uint in array: - memory[ptr+counter] = uint[0] - memory[ptr+counter+1] = uint[1] - counter += 2 - - write_uint256_array(ids.arr_be, arr_be) - ids.len = len(arr_be) - %} - let res = uint256_min_be(cast(arr_be, Uint256*), len); - assert res.low = res_min.low; - assert res.high = res_min.high; - - let res = uint256_max_be(cast(arr_be, Uint256*), len); - assert res.low = res_max.low; - assert res.high = res_max.high; - - let (local arr_le: felt*) = alloc(); - - %{ - arr_le = [split_128(uint256_reverse_endian(from_uint256(x))) for x in arr_be] - write_uint256_array(ids.arr_le, arr_le) - %} - - let res = uint256_min_le(cast(arr_le, Uint256*), len); - assert res.low = res_min.low; - assert res.high = res_min.high; - - let res = uint256_max_le(cast(arr_le, Uint256*), len); - assert res.low = res_max.low; - assert res.high = res_max.high; - - return (); -} - -const TEST_ARRAY_SIZE = 16; -const N_TESTS = 1000; -func count_if_main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { - alloc_locals; - let (local arrs: felt**) = alloc(); - let (local ops: felt*) = alloc(); - let (local values: felt*) = alloc(); - let (local expected: felt*) = alloc(); - %{ - from tools.py.utils import uint256_reverse_endian, from_uint256, split_128, flatten - import random - from enum import Enum, auto - random.seed(0) - - class COUNTIFOP(Enum): - EQ = 1 - NEQ = 2 - GT = 3 - GE = 4 - LT = 5 - LE = 6 - - def count_if(array:list, op:COUNTIFOP, value) -> int: - counter = 0 - for uint in array: - if op == COUNTIFOP.EQ: - if uint == value: - counter += 1 - elif op == COUNTIFOP.NEQ: - if uint != value: - counter += 1 - elif op == COUNTIFOP.GT: - if uint > value: - counter += 1 - elif op == COUNTIFOP.GE: - if uint >= value: - counter += 1 - elif op == COUNTIFOP.LT: - if uint < value: - counter += 1 - elif op == COUNTIFOP.LE: - if uint <= value: - counter += 1 - return counter - - arrs = [] - ops = [] - values = [] - expected = [] - for i in range(ids.N_TESTS): - op = random.choice(list(COUNTIFOP)) - ops.append(op.value) - if i % 2 == 0: - arr=[random.randint(0, 8) for _ in range(ids.TEST_ARRAY_SIZE)] - value = random.randint(0, 8) - - else: - if i % 3 == 0: - arr=[random.randint(2**128, 2**256-1) for _ in range(ids.TEST_ARRAY_SIZE)] - value = random.randint(2**128, 2**256-1) - else: - arr=[random.randint(0, 2**256-1) for _ in range(ids.TEST_ARRAY_SIZE)] - value = random.choice(arr) - - arrs.append(flatten([split_128(uint256_reverse_endian(x)) for x in arr])) - values.extend(split_128(value)) - expected.append(count_if(arr, op, value)) - - segments.write_arg(ids.arrs, arrs) - segments.write_arg(ids.ops, ops) - segments.write_arg(ids.values, values) - segments.write_arg(ids.expected, expected) - %} - test_count_if(cast(arrs, Uint256**), ops, cast(values, Uint256*), expected, 0, N_TESTS); - return (); -} - -func test_count_if{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}( - arrs: Uint256**, ops: felt*, values: Uint256*, expected: felt*, index: felt, len: felt -) { - if (index == len) { - return (); - } else { - test_count_if_inner(arrs[index], ops[index], values[index], expected[index]); - return test_count_if(arrs, ops, values, expected, index + 1, len); - } -} - -func test_count_if_inner{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}( - arr: Uint256*, op: felt, value: Uint256, expected: felt -) { - let (res) = count_if(arr, TEST_ARRAY_SIZE, op, value); - // %{ print(f"{ids.res=}, {ids.expected=}") %} - assert res = expected; - return (); -} diff --git a/tests/cairo_programs/block_sampled_datalake.cairo b/tests/cairo_programs/block_sampled_datalake.cairo deleted file mode 100644 index b1a8efa..0000000 --- a/tests/cairo_programs/block_sampled_datalake.cairo +++ /dev/null @@ -1,77 +0,0 @@ -%builtins range_check bitwise keccak -from starkware.cairo.common.cairo_builtins import PoseidonBuiltin, BitwiseBuiltin, KeccakBuiltin -from packages.eth_essentials.lib.utils import pow2alloc128 -from src.datalakes.block_sampled_datalake import init_block_sampled -from tests.cairo_programs.test_vectors import BlockSampledDataLakeMocker -from src.types import BlockSampledDataLake - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}() { - let pow2_array: felt* = pow2alloc128(); - - test_block_sampled_datalake_decoding{ - range_check_ptr=range_check_ptr, - bitwise_ptr=bitwise_ptr, - keccak_ptr=keccak_ptr, - pow2_array=pow2_array, - }(); - - return (); -} - -func test_block_sampled_datalake_decoding{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*, pow2_array: felt* -}() { - alloc_locals; - - let ( - header_input, header_input_bytes_len, header_expected_datalake, header_property_type - ) = BlockSampledDataLakeMocker.get_header_property(); - let (header_datalake) = init_block_sampled(header_input, header_input_bytes_len); - block_sampled_datalake_eq(header_datalake, header_expected_datalake, header_property_type); - - let ( - account_input, account_input_bytes_len, account_expected_datalake, account_property_type - ) = BlockSampledDataLakeMocker.get_account_property(); - let (account_datalake) = init_block_sampled(account_input, account_input_bytes_len); - block_sampled_datalake_eq(account_datalake, account_expected_datalake, account_property_type); - - let ( - storage_input, storage_input_bytes_len, storage_expected_datalake, storage_property_type - ) = BlockSampledDataLakeMocker.get_storage_property(); - let (storage_datalake) = init_block_sampled(storage_input, storage_input_bytes_len); - block_sampled_datalake_eq(storage_datalake, storage_expected_datalake, storage_property_type); - - return (); -} - -func block_sampled_datalake_eq( - a: BlockSampledDataLake, b: BlockSampledDataLake, property_type: felt -) { - assert a.block_range_start = b.block_range_start; - assert a.block_range_end = b.block_range_end; - assert a.increment = b.increment; - assert a.property_type = b.property_type; - - if (property_type == 1) { - assert a.properties[0] = b.properties[0]; - } - - if (property_type == 2) { - assert a.properties[0] = b.properties[0]; - assert a.properties[1] = b.properties[1]; - assert a.properties[2] = b.properties[2]; - assert a.properties[3] = b.properties[3]; - } - - if (property_type == 3) { - assert a.properties[0] = b.properties[0]; - assert a.properties[1] = b.properties[1]; - assert a.properties[2] = b.properties[2]; - assert a.properties[3] = b.properties[3]; - assert a.properties[4] = b.properties[4]; - assert a.properties[5] = b.properties[5]; - assert a.properties[6] = b.properties[6]; - } - - return (); -} diff --git a/tests/cairo_programs/computational_task.cairo b/tests/cairo_programs/computational_task.cairo deleted file mode 100644 index 1ce276a..0000000 --- a/tests/cairo_programs/computational_task.cairo +++ /dev/null @@ -1,181 +0,0 @@ -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256 -from starkware.cairo.common.cairo_builtins import PoseidonBuiltin, BitwiseBuiltin, KeccakBuiltin -from starkware.cairo.common.registers import get_fp_and_pc - -from tests.cairo_programs.block_sampled_datalake import block_sampled_datalake_eq -from tests.cairo_programs.test_vectors import BlockSampledTaskMocker - -from src.tasks.computational import Task, extract_params_and_construct_task, AGGREGATE_FN -from src.decoders.header_decoder import HeaderField -from src.datalakes.datalake import DatalakeType -from src.datalakes.block_sampled_datalake import BlockSampledProperty -from src.types import BlockSampledDataLake, ComputationalTask -from src.merkle import compute_tasks_root -from packages.eth_essentials.lib.utils import pow2alloc128 - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}() { - let pow2_array: felt* = pow2alloc128(); - - test_computational_task_init{ - range_check_ptr=range_check_ptr, - bitwise_ptr=bitwise_ptr, - keccak_ptr=keccak_ptr, - pow2_array=pow2_array, - }(); - - test_computational_task_param_decoding{ - range_check_ptr=range_check_ptr, - bitwise_ptr=bitwise_ptr, - keccak_ptr=keccak_ptr, - pow2_array=pow2_array, - }(); - - return (); -} - -func test_computational_task_init{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*, pow2_array: felt* -}() { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - let (tasks: ComputationalTask*) = alloc(); - - local tasks_len: felt; - - %{ - def hex_to_int(x): - return int(x, 16) - - def hex_to_int_array(hex_array): - return [int(x, 16) for x in hex_array] - - program_input["tasks"] = [{ - "task_bytes_len": 128, - "encoded_task": ["0x25ca8521ba63d557", "0xc9f9f40f48f31e27", "0x739b20c59ba605a5", "0x813cc91cdc15ae0e", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0"], - "datalake_bytes_len": 224, - "encoded_datalake": ["0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0x0", "0xf826540000000000", "0x0", "0x0", "0x0", "0x1527540000000000", "0x0", "0x0", "0x0", "0x100000000000000", "0x0", "0x0", "0x0", "0xa000000000000000", "0x0", "0x0", "0x0", "0x200000000000000", "0x1101", "0x0", "0x0", "0x0"], - "datalake_type": 0, - "property_type": 1 - }] - - ids.tasks_len = len(program_input["tasks"]) - %} - - let (properties) = alloc(); - %{ segments.write_arg(ids.properties, [ids.HeaderField.BLOB_GAS_USED]) %} - - local expected_datalake: BlockSampledDataLake; - - assert expected_datalake = BlockSampledDataLake( - block_range_start=5515000, - block_range_end=5515029, - increment=1, - property_type=BlockSampledProperty.HEADER, - properties=properties, - ); - - let datalake_ptr: felt* = cast(&expected_datalake, felt*); - - local expected_task: ComputationalTask; - - assert expected_task = ComputationalTask( - hash=Uint256(0xB85414EBA86F94BAC1CA653D3D3CF014, 0x212F54CE9F4342F21C5D865F1641AABC), - datalake_ptr=datalake_ptr, - datalake_type=DatalakeType.BLOCK_SAMPLED, - aggregate_fn_id=AGGREGATE_FN.AVG, - ctx_operator=0, - ctx_value=Uint256(low=0, high=0), - ); - - Task.init{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, keccak_ptr=keccak_ptr, tasks=tasks - }(tasks_len, 0); - - let task = tasks[0]; - assert task.hash.low = expected_task.hash.low; - assert task.hash.high = expected_task.hash.high; - assert task.datalake_type = expected_task.datalake_type; - assert task.aggregate_fn_id = expected_task.aggregate_fn_id; - assert task.ctx_operator = expected_task.ctx_operator; - assert task.ctx_value.low = expected_task.ctx_value.low; - assert task.ctx_value.high = expected_task.ctx_value.high; - - let datalake: BlockSampledDataLake = [cast(task.datalake_ptr, BlockSampledDataLake*)]; - block_sampled_datalake_eq(datalake, expected_datalake, datalake.property_type); - - assert task.aggregate_fn_id = expected_task.aggregate_fn_id; - - return (); -} - -func test_computational_task_param_decoding{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*, pow2_array: felt* -}() { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - // AVG: - let ( - exp_avg_task, avg_input, avg_bytes_len, avg_datalake, hash - ) = BlockSampledTaskMocker.get_avg_task(); - - let (avg_task) = extract_params_and_construct_task( - avg_input, avg_bytes_len, hash, exp_avg_task.datalake_ptr, exp_avg_task.datalake_type - ); - task_eq(avg_task, exp_avg_task); - - // SUM: - let ( - exp_sum_task, sum_input, sum_bytes_len, sum_datalake, hash - ) = BlockSampledTaskMocker.get_sum_task(); - let (sum_task) = extract_params_and_construct_task( - sum_input, sum_bytes_len, hash, exp_sum_task.datalake_ptr, exp_sum_task.datalake_type - ); - task_eq(sum_task, exp_sum_task); - - // MIN: - let ( - exp_min_task, min_input, min_bytes_len, min_datalake, hash - ) = BlockSampledTaskMocker.get_min_task(); - let (min_task) = extract_params_and_construct_task( - min_input, min_bytes_len, hash, exp_min_task.datalake_ptr, exp_min_task.datalake_type - ); - task_eq(min_task, exp_min_task); - - // MAX: - let ( - exp_max_task, max_input, max_bytes_len, max_datalake, hash - ) = BlockSampledTaskMocker.get_max_task(); - let (max_task) = extract_params_and_construct_task( - max_input, max_bytes_len, hash, exp_max_task.datalake_ptr, exp_max_task.datalake_type - ); - task_eq(max_task, exp_max_task); - - // COUNT_IF: - let ( - exp_count_if_task, count_if_input, count_if_bytes_len, _, hash - ) = BlockSampledTaskMocker.get_count_if_task(); - let (count_if_task) = extract_params_and_construct_task( - count_if_input, - count_if_bytes_len, - hash, - exp_count_if_task.datalake_ptr, - exp_count_if_task.datalake_type, - ); - task_eq(count_if_task, exp_count_if_task); - - return (); -} - -func task_eq(a: ComputationalTask, b: ComputationalTask) { - assert a.hash.low = b.hash.low; - assert a.hash.high = b.hash.high; - assert a.aggregate_fn_id = b.aggregate_fn_id; - assert a.ctx_operator = b.ctx_operator; - assert a.ctx_value.high = b.ctx_value.high; - assert a.ctx_value.low = b.ctx_value.low; - - return (); -} diff --git a/tests/cairo_programs/header_decoder.cairo b/tests/cairo_programs/header_decoder.cairo deleted file mode 100644 index ab6e039..0000000 --- a/tests/cairo_programs/header_decoder.cairo +++ /dev/null @@ -1,36 +0,0 @@ -%builtins range_check bitwise -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256, uint256_reverse_endian - -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin -from src.decoders.header_decoder import HeaderDecoder, HeaderField -from packages.eth_essentials.lib.utils import pow2alloc128 -from tests.utils.header import test_header_decoding - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { - alloc_locals; - let pow2_array: felt* = pow2alloc128(); - local block_numbers_len: felt; - - %{ - block_numbers = [ - 150001, # Homestead - 12965001, # London (EIP-1559) - 17034871, # Shanghai - 19427930, # Dencun - # random block numbers - 3549319, - 6374469, - 18603628, - 7244939 - ] - - ids.block_numbers_len = len(block_numbers) - %} - - test_header_decoding{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(block_numbers_len, 0); - - return (); -} diff --git a/tests/cairo_programs/merkle.cairo b/tests/cairo_programs/merkle.cairo deleted file mode 100644 index f0e6ccf..0000000 --- a/tests/cairo_programs/merkle.cairo +++ /dev/null @@ -1,136 +0,0 @@ -%builtins range_check bitwise keccak -from starkware.cairo.common.uint256 import Uint256 -from starkware.cairo.common.cairo_builtins import PoseidonBuiltin, BitwiseBuiltin, KeccakBuiltin -from starkware.cairo.common.alloc import alloc -from tests.cairo_programs.test_vectors import BlockSampledTaskMocker -from src.merkle import compute_tasks_root, compute_results_root, hash_pair, compute_merkle_root -from src.utils import compute_results_entry -from src.types import ComputationalTask - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}() { - computes_output_roots{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, keccak_ptr=keccak_ptr - }(); - hash_pair_sorting{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, keccak_ptr=keccak_ptr - }(); - - compute_merkle_root_test{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, keccak_ptr=keccak_ptr - }(); - - return (); -} - -func computes_output_roots{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin* -}() { - alloc_locals; - - let (task, _, _, _, _, _, tasks_len) = BlockSampledTaskMocker.get_init_data(); - let (tasks: ComputationalTask*) = alloc(); - assert tasks[0] = task; - - let tasks_root = compute_tasks_root{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, keccak_ptr=keccak_ptr - }(tasks, tasks_len); - - assert tasks_root.low = 114514345207152648761622449186187146395; - assert tasks_root.high = 250820143348695721067706216954199270384; - - let result = Uint256(low=100, high=0); - let results_entry = compute_results_entry(tasks_root, result); - - assert results_entry.low = 2004459135957517006232490669995341918; - assert results_entry.high = 17938436372202772873742223991112862737; - - let (results: Uint256*) = alloc(); - assert [results] = result; - - let results_root = compute_results_root(tasks, results, 1); - - assert results_root.low = 519486554900734574573258899619310091; - assert results_root.high = 259887999216688164462131972375059079258; - - return (); -} - -func hash_pair_sorting{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}( - ) { - alloc_locals; - - let a = Uint256(low=100, high=0); - let b = Uint256(low=101, high=0); - - let c = Uint256(low=0, high=100); - let d = Uint256(low=0, high=101); - - let hash_ab = hash_pair(a, b); - - // H(0x6400000000000000000000000000000000, 0x6500000000000000000000000000000000) - assert hash_ab.low = 163291149559542241309179326071480931191; - assert hash_ab.high = 295863837414419920236646088726537045337; - - // H(0x64, 0x65) - let hash_cd = hash_pair(c, d); - assert hash_cd.low = 13032766405138684239100038106974674315; - assert hash_cd.high = 98233670034630048064327498362998938186; - - return (); -} - -func compute_merkle_root_test{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin* -}() { - alloc_locals; - - let (leafs: Uint256*) = alloc(); - - %{ - from tools.py.utils import ( - split_128, - uint256_reverse_endian, - ) - - # converts values to little endian and writes them to memory. - def write_vals(ptr, values): - for (i, value) in enumerate(values): - reversed_value = uint256_reverse_endian(value) - (low, high) = split_128(reversed_value) - memory[ptr._reference_value + i * 2] = low - memory[ptr._reference_value + i * 2 + 1] = high - - test_values =[ - 0x0000000000000000000000000000000000000000000000000000000000000001, - 0x0000000000000000000000000000000000000000000000000000000000000002, - 0x000000000000000000000000000000000000000000000000000000000000007a, - 0x0000000000000000000000000000000000000000000000000000000000000004, - 0x0000000000000000000000000000000000000000000000000000000000000001 - ] - - write_vals(ids.leafs, test_values) - %} - - // Values can be generated using the official OpenZepplin implementation in tools/js/merkle.js - let root_one = compute_merkle_root(leafs, 1); - assert root_one.high = 0xb5d9d894133a730aa651ef62d26b0ffa; - assert root_one.low = 0x846233c74177a591a4a896adfda97d22; - - let root_two = compute_merkle_root(leafs, 2); - assert root_two.high = 0xe685571b7e25a4a0391fb8daa09dc8d3; - assert root_two.low = 0xfbb3382504525f89a2334fbbf8f8e92c; - - let root_three = compute_merkle_root(leafs, 3); - assert root_three.high = 0x22a9fa23ace0a643334709a15031f455; - assert root_three.low = 0x653508baac1e2f3aeb34494420d3926d; - - let root_four = compute_merkle_root(leafs, 4); - assert root_four.high = 0x04a658c32b0f14901050b3649930b07c; - assert root_four.low = 0xcb19e12ee6121c59fae29dbd2639d643; - - let root_five = compute_merkle_root(leafs, 5); - assert root_five.high = 0x76a558f4880fd37907a3c306516dcb3e; - assert root_five.low = 0x680616d84e8950d8050923bdd6ee51a7; - - return (); -} diff --git a/tests/cairo_programs/rlp.cairo b/tests/cairo_programs/rlp.cairo deleted file mode 100644 index a99afb0..0000000 --- a/tests/cairo_programs/rlp.cairo +++ /dev/null @@ -1,602 +0,0 @@ -%builtins range_check bitwise keccak -from starkware.cairo.common.alloc import alloc - -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin -from starkware.cairo.common.uint256 import Uint256, uint256_eq, uint256_reverse_endian -from starkware.cairo.common.keccak_utils.keccak_utils import keccak_add_uint256 -from src.rlp import ( - le_chunks_to_uint256, - decode_rlp_word_to_uint256, - rlp_list_retrieve, - chunk_to_felt_be, - right_shift_le_chunks, - prepend_le_chunks, - append_be_chunk, -) -from packages.eth_essentials.lib.utils import pow2alloc127 - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}() { - alloc_locals; - let pow2_array: felt* = pow2alloc127(); - - %{ - from tools.py.utils import ( - bytes_to_8_bytes_chunks_little, - uint256_reverse_endian, - split_128, - reverse_endian, - bytes_to_8_bytes_chunks, - ) - import rlp - %} - - test_decode_rlp_word_to_uint256{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(); - test_rlp_list_retrieve{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(); - test_chunk_to_felt_be{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(); - test_right_shift_le_chunks{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(); - test_prepend_le_chunks{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(); - test_append_be_chunk{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(); - - return (); -} - -func test_append_be_chunk{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}() { - alloc_locals; - - local elements_len: felt; - local item_len: felt; - - %{ - rlp_elements = [ - ([0x11223344], 4), - ([0x1122334455667788], 8), - ([0x0011223344556677], 8), - ([0x0011223344556677, 0x1122], 10), - ([0x1122334455667788, 0x1122334455667788, 0x112233], 19) - ] - ids.elements_len = len(rlp_elements) - - prepend_items = [ - (0x01, 1), - (0x1122, 2), - (0x1122334455, 5), - (0x1122334455667788, 8) - ] - ids.item_len = len(prepend_items) - - expected_values = [ - [ - [0x0111223344], - [0x221111223344], - [0x4433221111223344, 0x55], - [0x4433221111223344, 0x88776655], - ], - [ - [0x1122334455667788, 0x01], - [0x1122334455667788, 0x2211], - [0x1122334455667788, 0x5544332211], - [0x1122334455667788, 0x8877665544332211] - ], - [ - [0x0011223344556677, 0x01], - [0x0011223344556677, 0x2211], - [0x0011223344556677, 0x5544332211], - [0x0011223344556677, 0x8877665544332211] - ], - [ - [0x0011223344556677, 0x011122], - [0x0011223344556677, 0x22111122], - [0x0011223344556677, 0x55443322111122], - [0x0011223344556677, 0x6655443322111122, 0x8877] - ], - [ - [0x1122334455667788, 0x1122334455667788, 0x01112233], - [0x1122334455667788, 0x1122334455667788, 0x2211112233], - [0x1122334455667788, 0x1122334455667788, 0x5544332211112233], - [0x1122334455667788, 0x1122334455667788, 0x5544332211112233, 0x887766] - ] - ] - %} - - return test_append_be_chunk_inner(elements_len, 0, item_len); -} - -func test_append_be_chunk_inner{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}( - elements_len: felt, elements_index: felt, item_len: felt -) { - alloc_locals; - - if (elements_len == elements_index) { - return (); - } - - test_append_be_chunk_inner_inner(elements_index, item_len, 0); - - return test_append_be_chunk_inner(elements_len, elements_index + 1, item_len); -} - -func test_append_be_chunk_inner_inner{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt* -}(elements_index: felt, item_len: felt, item_index: felt) { - alloc_locals; - - if (item_len == item_index) { - return (); - } - local expected_bytes_len: felt; - local item_bytes_len: felt; - local item: felt; - let (rlp) = alloc(); - local rlp_bytes_len: felt; - local rlp_len: felt; - - %{ - ids.item = prepend_items[ids.item_index][0] - ids.item_bytes_len = prepend_items[ids.item_index][1] - segments.write_arg(ids.rlp, rlp_elements[ids.elements_index][0]) - ids.rlp_len = len(rlp_elements[ids.elements_index][0]) - ids.rlp_bytes_len = rlp_elements[ids.elements_index][1] - ids.expected_bytes_len = ids.item_bytes_len + ids.rlp_bytes_len - %} - - let (encoded, encoded_len, encoded_bytes_len) = append_be_chunk( - rlp, rlp_bytes_len, item, item_bytes_len - ); - - %{ - assert len(expected_values[ids.elements_index][ids.item_index]) == ids.encoded_len, "Invalid Results Length" - assert ids.encoded_bytes_len == ids.expected_bytes_len, "Invalid Results Bytes Length" - for i in range(ids.encoded_len): - assert memory[ids.encoded + i] == expected_values[ids.elements_index][ids.item_index][i], f"Invalid Result at index {i}" - %} - - return test_append_be_chunk_inner_inner(elements_index, item_len, item_index + 1); -} - -func test_prepend_le_chunks{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}() { - alloc_locals; - - local elements_len: felt; - local item_len: felt; - - %{ - rlp_elements = [ - ([0x11223344], 4), - ([0x1122334455667788], 8), - ([0x0011223344556677], 8), - ([0x0011223344556677, 0x1122], 10), - ([0x1122334455667788, 0x1122334455667788, 0x112233], 19) - ] - ids.elements_len = len(rlp_elements) - - prepend_items = [ - (0x01, 1), - (0x1122, 2), - (0x1122334455, 5), - (0x1122334455667788, 8) - ] - ids.item_len = len(prepend_items) - - expected_values = [ - [ - [0x1122334401], - [0x112233441122], - [0x2233441122334455, 0x11], - [0x1122334455667788, 0x11223344] - ], - [ - [0x2233445566778801, 0x11], - [0x3344556677881122, 0x1122], - [0x6677881122334455, 0x1122334455], - [0x1122334455667788, 0x1122334455667788] - ], - [ - [0x1122334455667701, 0x00], - [0x2233445566771122, 0x0011], - [0x5566771122334455, 0x0011223344], - [0x1122334455667788, 0x0011223344556677] - ], - [ - [0x1122334455667701, 0x112200], - [0x2233445566771122, 0x11220011], - [0x5566771122334455, 0x11220011223344], - [0x1122334455667788, 0x0011223344556677, 0x1122] - ], - [ - [0x2233445566778801, 0x2233445566778811, 0x11223311], - [0x3344556677881122, 0x3344556677881122, 0x1122331122], - [0x6677881122334455, 0x6677881122334455, 0x1122331122334455], - [0x1122334455667788, 0x1122334455667788, 0x1122334455667788, 0x112233] - ] - ] - %} - return test_prepend_le_chunks_inner(elements_len, 0, item_len); -} - -func test_prepend_le_chunks_inner{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}( - elements_len: felt, elements_index: felt, item_len: felt -) { - alloc_locals; - - if (elements_len == elements_index) { - return (); - } - - test_prepend_le_chunks_inner_inner(elements_index, item_len, 0); - - return test_prepend_le_chunks_inner(elements_len, elements_index + 1, item_len); -} - -func test_prepend_le_chunks_inner_inner{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt* -}(elements_index: felt, item_len: felt, item_index: felt) { - alloc_locals; - - if (item_len == item_index) { - return (); - } - - local item_bytes_len: felt; - local item: felt; - local expected_bytes_len: felt; - let (rlp) = alloc(); - local rlp_len: felt; - - %{ - ids.item = prepend_items[ids.item_index][0] - ids.item_bytes_len = prepend_items[ids.item_index][1] - segments.write_arg(ids.rlp, rlp_elements[ids.elements_index][0]) - ids.rlp_len = len(rlp_elements[ids.elements_index][0]) - ids.expected_bytes_len = prepend_items[ids.item_index][1] + rlp_elements[ids.elements_index][1] - %} - - let (encoded, encoded_len) = prepend_le_chunks( - item_bytes_len, item, rlp, rlp_len, expected_bytes_len - ); - - %{ - for i in range(ids.encoded_len): - assert memory[ids.encoded + i] == expected_values[ids.elements_index][ids.item_index][i], f"Invalid Result at index {i}" - %} - - return test_prepend_le_chunks_inner_inner(elements_index, item_len, item_index + 1); -} - -func test_right_shift_le_chunks{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}( - ) { - alloc_locals; - local elements_len: felt; - - %{ - input_values = [ - [0x1122334455667788, 0x11], - [0x1122334455667788, 0x1122], - [0x1122334455667788, 0x112233], - [0x1122334455667788, 0x11223344], - [0x1122334455667788, 0x1122334455], - [0x1122334455667788, 0x112233445566], - [0x1122334455667788, 0x11223344556677], - [0x1122334455667788, 0x1122334455667788], - [0x1122334455667788, 0x1122334455667788, 0x11], - ] - ids.elements_len = len(input_values) - output_values = [ - [0x8800000000000000, 0x1111223344556677], - [0x7788000000000000, 0x1122112233445566], - [0x6677880000000000, 0x1122331122334455], - [0x5566778800000000, 0x1122334411223344], - [0x4455667788000000, 0x1122334455112233], - [0x3344556677880000, 0x1122334455661122], - [0x2233445566778800, 0x1122334455667711], - [0x1122334455667788, 0x1122334455667788], - [0x8800000000000000, 0x8811223344556677, 0x1111223344556677], - ] - %} - - test_test_right_shift_le_chunks(elements_len, 0); - - return (); -} - -func test_test_right_shift_le_chunks{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt* -}(elements_len: felt, index: felt) { - alloc_locals; - - if (elements_len == index) { - return (); - } - - let (inputs: felt*) = alloc(); - local inputs_len: felt; - local offset: felt; - - %{ - ids.offset = (9 + ids.index) % 8 - ids.inputs_len = len(input_values[ids.index]) - segments.write_arg(ids.inputs, input_values[ids.index]) - %} - - let (shifted) = right_shift_le_chunks(inputs, inputs_len, offset); - - %{ - for i in range(ids.inputs_len): - assert memory[ids.shifted + i] == output_values[ids.index][i], f"Invalid Result at index {i}" - %} - - return test_test_right_shift_le_chunks(elements_len=elements_len, index=index + 1); -} - -func test_chunk_to_felt_be{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}() { - alloc_locals; - - local elements_len: felt; - - %{ - values = [ - 0xf, - 0xff, - 0xfff, - 0xffff, - 0xfffff, - 0xffffff, - 0xfffffff, - 0xffffffff, - 0xfffffffff, - 0xffffffffff, - 0xfffffffffff, - 0xffffffffffff, - 0xfffffffffffff, - 0xffffffffffffff, - ] - - encoded_values = [rlp.encode(value) for value in values] - chunks = [bytes_to_8_bytes_chunks_little(encoded_value) for encoded_value in encoded_values] - - ids.elements_len = len(values) - %} - - return test_chunk_to_felt_be_inner(elements_len, 0); -} - -func test_chunk_to_felt_be_inner{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}( - elements_len: felt, index: felt -) { - alloc_locals; - - if (elements_len == index) { - return (); - } - - local value: felt; - local expected: felt; - %{ - ids.value = chunks[ids.index][0] - ids.expected = values[ids.index] - %} - - let result = chunk_to_felt_be(value); - assert result = expected; - - return test_chunk_to_felt_be_inner(elements_len=elements_len, index=index + 1); -} - -func test_rlp_list_retrieve{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}() { - alloc_locals; - - local elements_len: felt; - let (input_chunks: felt*) = alloc(); - local item_starts_at_byte: felt; - - %{ - # the list retrieve function selects elements by index, and then unpacks the element that is selected. This function mocks this - def generate_encoded_results(elements): - expected_results = [] - for element in elements: - # Handle lists of elements (e.g., nested lists) - if isinstance(element, list): - if len(element) == 0: - expected_results.append(b'\x00') - else: - # Encode each sub_element in the list using RLP and concatenate - encoded_concat = b''.join([rlp.encode(sub_element.to_bytes((sub_element.bit_length() + 7) // 8, byteorder='big')) for sub_element in element]) - expected_results.append(encoded_concat) - # Special handling for empty string or zero - elif element == "" or element == 0: - expected_results.append(b'\x00') - # Convert integers and large numbers to bytes - else: - # Ensure integers are properly converted to bytes - num_bytes = (element.bit_length() + 7) // 8 - element_bytes = element.to_bytes(num_bytes, byteorder='big') - # Append the result after encoding if needed - expected_results.append(element_bytes) - return expected_results - - elements = [ - # empty - '', - # zero - 0x0, - #one byte - 1, - 0x7f, - # short string - 0x80, - 0xabcdef, - 0x55FE002aefF02F77364de339a1292923A15844B8, - 0xc84ed1f6941cc0826996633d523ccbf62c9a4417f377706d12d422f9def4ba6d, - # long string - 0xc84ed1f6941cc0826996633d523ccbf62c9a4417f377706d12d422f9def4ba6dc84ed1f6941cc0826996633d523ccbf62c9a4417f377706d12d422f9def4ba6d, - # empty list - [], - # short list - [0x0, 0x1], - [0x55FE002aefF02F77364de339a1292923A15844B8, 0x55FE002aefF02F77364de339a1292923A15844B8, 0x55FE002aefF02F77364de3], # 55 bytes (with elements prefix) - # long list - [0xc84ed1f6941cc0826996633d523ccbf62c9a4417f377706d12d422f9def4ba6d, 0xc84ed1f6941cc0826996633d523ccbf62c9a4417f377706d12d422f9def4ba6d], - ] - - # raw encoded element - encoded_blob = rlp.encode(elements) - - input_chunks = bytes_to_8_bytes_chunks_little(encoded_blob) - segments.write_arg(ids.input_chunks, input_chunks) - ids.item_starts_at_byte = 3 # the first 3 bytes are the list prefix, which we want to skip - ids.elements_len = len(elements) - - encoded_elements = generate_encoded_results(elements) - expected_bytes_len = [len(element) for element in encoded_elements] - expected_results = [bytes_to_8_bytes_chunks_little(result) for result in encoded_elements] - expected_len = [len(element) for element in expected_results] - %} - - test_rlp_list_retrieve_inner{ - range_check_ptr=range_check_ptr, - bitwise_ptr=bitwise_ptr, - pow2_array=pow2_array, - input_chunks=input_chunks, - item_starts_at_byte=item_starts_at_byte, - }(elements_len, 0); - - return (); -} - -func test_rlp_list_retrieve_inner{ - range_check_ptr, - bitwise_ptr: BitwiseBuiltin*, - pow2_array: felt*, - input_chunks: felt*, - item_starts_at_byte: felt, -}(elements_len: felt, index: felt) { - alloc_locals; - - if (elements_len == index) { - return (); - } - - let (result, result_len, result_bytes_len) = rlp_list_retrieve( - input_chunks, index, item_starts_at_byte, 0 - ); - - %{ - assert ids.result_len == expected_len[ids.index], "Invalid Results Length" - assert ids.result_bytes_len == expected_bytes_len[ids.index], "Invalid Results Bytes Length" - - for i in range(ids.result_len): - assert memory[ids.result + i] == expected_results[ids.index][i], f"Invalid Result at index {i}" - %} - - return test_rlp_list_retrieve_inner(elements_len=elements_len, index=index + 1); -} - -func test_decode_rlp_word_to_uint256{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt* -}() { - alloc_locals; - - local case_len: felt; - %{ - # Test cases for decode_rlp_word_to_uint256 at every byte length - decode_rlp_word_to_uint256 = [ - 0x66, - 0x9388, - 0xae5e8a, - 0x4e98ca05, - 0x61cb9c7ce6, - 0x7211a2516f35, - 0x58b5d8b3f67446, - 0x7519e8621ea1a3ee, - 0x9ee2e781a323050f12, - 0xae45d19ed5310e62f4f3, - 0xf3fc1e528b85432aab4d45, - 0x43bc24aed589d97fae233712, - 0x97f3eab6553c2f284d04e314bd, - 0xb5f421d6740127fafbb0a89a8bc3, - 0x59309a988582ff574bd3ed9a4bd6ce, - 0x696b085c5dc084660c1903ed46d07456, - 0x895613670f5cedbba5d22dc9dc9e47fe1d, - 0xc33d466640180017ddeb18aacde8790775fd, - 0x4e6184f5eae2a03db9aeb583ec012b310894fc, - 0x183311ee3de03a9fdf7e30da707cea7842344095, - 0xa5a0abe55971873d59c8eacc1b0e3dc75d041a0560, - 0x8966bfd6beb8ad6f93bdaf78b87d8e0b7a0d55cb6608, - 0x65f51a126b8b9168089697ad4a978861a1df6ac779d8f2, - 0x719a99b4d93f830e3a12d8b21d8406bf673ededb3d74f835, - 0x7fb90265c0558fda3544677e3ac6bee21be6b0666686e8e886, - 0xd485c055420d72665e38f63657eeff26ea7a4cf658ad90ec433a, - 0xf427f5d9e55db2ca6cbc480c58ef030f1f9f3989e99b35c8ae176e, - 0xb39e496e6b029417ae37d000b3b86427e5bb366a738c3b1268ea15ff, - 0x938f32171b29d0e29d347e283edb0749d43dafcbff79cafc08f6e936c4, - 0x5a8fdd9d1017e051bda2cf1d27518c38714f0659dd8c362840f0aacf0b46, - 0x85bdc29d6de8c62e3c3a7789448dfa47cc2ad137791dcb6f7413fc1e347734, - 0x66ba7c97a8d86016687269a255b6557ae499a417222aede48aca47e8a34fccc8 - ] - - ids.case_len = len(decode_rlp_word_to_uint256) - %} - - test_decode_rlp_word_to_uint256_inner{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(case_len, 0); - - return (); -} - -func test_decode_rlp_word_to_uint256_inner{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt* -}(case_len: felt, index: felt) { - alloc_locals; - - if (index == case_len) { - return (); - } - - let (chunks: felt*) = alloc(); - local expected_le: Uint256; - local expected_be: Uint256; - local bytes_len: felt; - - %{ - # Writes input and expected value to cairo - def write_case_values(value): - (low_be, high_be) = split_128(value) - ids.expected_be.low = low_be - ids.expected_be.high = high_be - - reversed_value = uint256_reverse_endian(value) - (low_le, high_le) = split_128(reversed_value) - ids.expected_le.low = low_le - ids.expected_le.high = high_le - - rlp_value = rlp.encode(value) - ids.bytes_len = len(rlp_value) - chunks = bytes_to_8_bytes_chunks_little(rlp_value) - segments.write_arg(ids.chunks, chunks) - - write_case_values(decode_rlp_word_to_uint256[ids.index]) - %} - - let result_le = decode_rlp_word_to_uint256(chunks, bytes_len); - let (local result_be) = uint256_reverse_endian(result_le); - - assert expected_le.low = result_le.low; - assert expected_le.high = result_le.high; - - assert expected_be.low = result_be.low; - assert expected_be.high = result_be.high; - - return test_decode_rlp_word_to_uint256_inner(case_len=case_len, index=index + 1); -} diff --git a/tests/cairo_programs/test_vectors.cairo b/tests/cairo_programs/test_vectors.cairo deleted file mode 100644 index 371653a..0000000 --- a/tests/cairo_programs/test_vectors.cairo +++ /dev/null @@ -1,354 +0,0 @@ -from starkware.cairo.common.uint256 import Uint256 -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.registers import get_fp_and_pc -from starkware.cairo.common.builtin_keccak.keccak import keccak -from src.types import BlockSampledDataLake, ComputationalTask -from src.tasks.computational import AGGREGATE_FN -from starkware.cairo.common.cairo_builtins import PoseidonBuiltin, BitwiseBuiltin, KeccakBuiltin - -from src.datalakes.datalake import DatalakeType -namespace BlockSampledDataLakeMocker { - func get_header_property() -> ( - datalake_input: felt*, - datalake_input_bytes_len: felt, - datalake: BlockSampledDataLake, - property_type: felt, - ) { - alloc_locals; - - let (datalake_input: felt*) = alloc(); - local datalake: BlockSampledDataLake; - local datalake_bytes_len: felt; - - %{ - ids.datalake.block_range_start = 5382810 - ids.datalake.block_range_end = 5382815 - ids.datalake.increment = 1 - ids.datalake.property_type = 1 - ids.datalake.properties = segments.gen_arg([8]) - - datalake_input = [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9a22520000000000, 0x0, 0x0, 0x0, 0x9f22520000000000, 0x0, 0x0, 0x0, 0x100000000000000, 0x0, 0x0, 0x0, 0xa000000000000000, 0x0, 0x0, 0x0, 0x200000000000000, 0x801, 0x0, 0x0, 0x0] - ids.datalake_bytes_len = 224 - segments.write_arg(ids.datalake_input, datalake_input) - %} - - return (datalake_input, datalake_bytes_len, datalake, 1); - } - - func get_account_property() -> ( - datalake_input: felt*, - datalake_input_bytes_len: felt, - datalake: BlockSampledDataLake, - property_type: felt, - ) { - alloc_locals; - - let (datalake_input) = alloc(); - local datalake: BlockSampledDataLake; - local datalake_bytes_len: felt; - - %{ - ids.datalake.block_range_start = 4952100 - ids.datalake.block_range_end = 4952120 - ids.datalake.increment = 1 - ids.datalake.property_type = 2 - ids.datalake.properties = segments.gen_arg([0x1, 0xaad30603936f2c7f, 0x12f5986a6c3a6b73, 0xd43640f7]) - - datalake_input = [0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x24904b0000000000,0x0,0x0,0x0,0x38904b0000000000,0x0,0x0,0x0,0x100000000000000,0x0,0x0,0x0,0xa000000000000000,0x0,0x0,0x0,0x1600000000000000,0xd30603936f2c7f02,0xf5986a6c3a6b73aa,0x1d43640f712,0x0] - ids.datalake_bytes_len = 224 - segments.write_arg(ids.datalake_input, datalake_input) - %} - - return (datalake_input, datalake_bytes_len, datalake, 2); - } - - func get_storage_property() -> ( - datalake_input: felt*, - datalake_input_bytes_len: felt, - datalake: BlockSampledDataLake, - property_type: felt, - ) { - alloc_locals; - - let (datalake_input) = alloc(); - local datalake: BlockSampledDataLake; - local datalake_bytes_len: felt; - - %{ - ids.datalake.block_range_start = 5382810 - ids.datalake.block_range_end = 5382815 - ids.datalake.increment = 1 - ids.datalake.property_type = 3 - ids.datalake.properties = segments.gen_arg([0x3b7ce9ddbc1ce75, 0x8568f69565aa0e20, 0x20b962c9, 0x0, 0x0, 0x0, 0x200000000000000]) - - datalake_input = [0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x9a22520000000000,0x0,0x0,0x0,0x9f22520000000000,0x0,0x0,0x0,0x100000000000000,0x0,0x0,0x0,0xa000000000000000,0x0,0x0,0x0,0x3500000000000000,0xb7ce9ddbc1ce7503,0x68f69565aa0e2003,0x20b962c985,0x0,0x0,0x0,0x200000000,0x0] - ids.datalake_bytes_len = 256 - segments.write_arg(ids.datalake_input, datalake_input) - %} - - return (datalake_input, datalake_bytes_len, datalake, 3); - } -} - -namespace BlockSampledTaskMocker { - func get_init_data() -> ( - task: ComputationalTask, - tasks_inputs: felt**, - tasks_bytes_len: felt*, - datalake: BlockSampledDataLake, - datalakes_inputs: felt**, - datalakes_bytes_len: felt*, - tasks_len: felt, - ) { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - let ( - datalake_input, datalake_bytes_len, local datalake, prop_id - ) = BlockSampledDataLakeMocker.get_header_property(); - let (task_input) = alloc(); - let (tasks_bytes_len) = alloc(); - - %{ - from tools.py.utils import bytes_to_8_bytes_chunks_little - # mocks python params that are available during full flow - block_sampled_tasks = [{'property_type': 1 }] - task_bytes = bytes.fromhex("22B4DA4CC94620C9DFCC5AE7429AD350AC86587E6D9925A6209587EF17967F20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - segments.write_arg(ids.tasks_bytes_len, [len(task_bytes)]) - segments.write_arg(ids.task_input, bytes_to_8_bytes_chunks_little(task_bytes)) - %} - - let task = ComputationalTask( - hash=Uint256( - low=0x407E98D423A7BB2DBF09B0E42601FC9B, high=0xEF8B01F35B404615F0339EEFAE7719A2 - ), - datalake_ptr=cast(&datalake, felt*), - datalake_type=0, - aggregate_fn_id=AGGREGATE_FN.AVG, - ctx_operator=0, - ctx_value=Uint256(low=0, high=0), - ); - - let (tasks_inputs: felt**) = alloc(); - let (datalakes_inputs: felt**) = alloc(); - let (datalakes_bytes_len: felt*) = alloc(); - assert tasks_inputs[0] = task_input; - assert datalakes_inputs[0] = datalake_input; - assert datalakes_bytes_len[0] = datalake_bytes_len; - - return ( - task, tasks_inputs, tasks_bytes_len, datalake, datalakes_inputs, datalakes_bytes_len, 1 - ); - } - - func get_avg_task{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}( - ) -> ( - task: ComputationalTask, - tasks_inputs: felt*, - tasks_bytes_len: felt, - datalake: BlockSampledDataLake, - datalake_hash: Uint256, - ) { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - let ( - datalake_input, datalake_bytes_len, local datalake, _ - ) = BlockSampledDataLakeMocker.get_header_property(); - let (task_input) = alloc(); - local tasks_bytes_len: felt; - - %{ - from tools.py.utils import bytes_to_8_bytes_chunks_little - - task_bytes = bytes.fromhex("22B4DA4CC94620C9DFCC5AE7429AD350AC86587E6D9925A6209587EF17967F20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - ids.tasks_bytes_len = len(task_bytes) - segments.write_arg(ids.task_input, bytes_to_8_bytes_chunks_little(task_bytes)) - %} - - let (datalake_hash) = keccak(datalake_input, datalake_bytes_len); - - let datalake_ptr: felt* = cast(&datalake, felt*); - - let task = ComputationalTask( - hash=Uint256( - low=0x407E98D423A7BB2DBF09B0E42601FC9B, high=0xEF8B01F35B404615F0339EEFAE7719A2 - ), - datalake_ptr=datalake_ptr, - datalake_type=DatalakeType.BLOCK_SAMPLED, - aggregate_fn_id=AGGREGATE_FN.AVG, - ctx_operator=0, - ctx_value=Uint256(low=0, high=0), - ); - - return (task, task_input, tasks_bytes_len, datalake, datalake_hash); - } - - func get_sum_task{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}( - ) -> ( - task: ComputationalTask, - tasks_inputs: felt*, - tasks_bytes_len: felt, - datalake: BlockSampledDataLake, - datalake_hash: Uint256, - ) { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - let ( - datalake_input, datalake_bytes_len, local datalake, _ - ) = BlockSampledDataLakeMocker.get_header_property(); - let (task_input) = alloc(); - local tasks_bytes_len: felt; - - %{ - from tools.py.utils import bytes_to_8_bytes_chunks_little - task_bytes = bytes.fromhex("22B4DA4CC94620C9DFCC5AE7429AD350AC86587E6D9925A6209587EF17967F20000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - ids.tasks_bytes_len = len(task_bytes) - segments.write_arg(ids.task_input, bytes_to_8_bytes_chunks_little(task_bytes)) - %} - - let datalake_ptr: felt* = cast(&datalake, felt*); - - let task = ComputationalTask( - hash=Uint256( - low=0x3CB6684D1B4B7FDEA3FBACAEA422C944, high=0x02F8516E3F7BE7FCCFDE22FB4A98DF37 - ), - datalake_ptr=datalake_ptr, - datalake_type=DatalakeType.BLOCK_SAMPLED, - aggregate_fn_id=AGGREGATE_FN.SUM, - ctx_operator=0, - ctx_value=Uint256(low=0, high=0), - ); - - let (datalake_hash) = keccak(datalake_input, datalake_bytes_len); - - return (task, task_input, tasks_bytes_len, datalake, datalake_hash); - } - - func get_min_task{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}( - ) -> ( - task: ComputationalTask, - tasks_inputs: felt*, - tasks_bytes_len: felt, - datalake: BlockSampledDataLake, - datalake_hash: Uint256, - ) { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - let ( - datalake_input, datalake_bytes_len, local datalake, _ - ) = BlockSampledDataLakeMocker.get_header_property(); - let (task_input) = alloc(); - local tasks_bytes_len: felt; - - %{ - from tools.py.utils import bytes_to_8_bytes_chunks_little - task_bytes = bytes.fromhex("22B4DA4CC94620C9DFCC5AE7429AD350AC86587E6D9925A6209587EF17967F20000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - ids.tasks_bytes_len = len(task_bytes) - segments.write_arg(ids.task_input, bytes_to_8_bytes_chunks_little(task_bytes)) - %} - - let datalake_ptr: felt* = cast(&datalake, felt*); - - let task = ComputationalTask( - hash=Uint256( - low=0x9F439795EE0CA868B463479E5A905BF0, high=0x72CEFA1188B199ECEEAB39767CD32605 - ), - datalake_ptr=datalake_ptr, - datalake_type=DatalakeType.BLOCK_SAMPLED, - aggregate_fn_id=AGGREGATE_FN.MIN, - ctx_operator=0, - ctx_value=Uint256(low=0, high=0), - ); - - let (datalake_hash) = keccak(datalake_input, datalake_bytes_len); - - return (task, task_input, tasks_bytes_len, datalake, datalake_hash); - } - - func get_max_task{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}( - ) -> ( - task: ComputationalTask, - tasks_inputs: felt*, - tasks_bytes_len: felt, - datalake: BlockSampledDataLake, - datalake_hash: Uint256, - ) { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - let ( - datalake_input, datalake_bytes_len, local datalake, _ - ) = BlockSampledDataLakeMocker.get_header_property(); - let (task_input) = alloc(); - local tasks_bytes_len: felt; - - %{ - from tools.py.utils import bytes_to_8_bytes_chunks_little - task_bytes = bytes.fromhex("22B4DA4CC94620C9DFCC5AE7429AD350AC86587E6D9925A6209587EF17967F20000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") - ids.tasks_bytes_len = len(task_bytes) - segments.write_arg(ids.task_input, bytes_to_8_bytes_chunks_little(task_bytes)) - %} - - let datalake_ptr: felt* = cast(&datalake, felt*); - - let task = ComputationalTask( - hash=Uint256( - low=0x1CD2E160D860B4D1BD1E327B6AA209BD, high=0xCABA4809710EB228D6A31DE1B852DFB7 - ), - datalake_ptr=datalake_ptr, - datalake_type=DatalakeType.BLOCK_SAMPLED, - aggregate_fn_id=AGGREGATE_FN.MAX, - ctx_operator=0, - ctx_value=Uint256(low=0, high=0), - ); - - let (datalake_hash) = keccak(datalake_input, datalake_bytes_len); - - return (task, task_input, tasks_bytes_len, datalake, datalake_hash); - } - - func get_count_if_task{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin* - }() -> ( - task: ComputationalTask, - tasks_inputs: felt*, - tasks_bytes_len: felt, - datalake: BlockSampledDataLake, - datalake_hash: Uint256, - ) { - alloc_locals; - let (__fp__, _) = get_fp_and_pc(); - - let ( - datalake_input, datalake_bytes_len, local datalake, _ - ) = BlockSampledDataLakeMocker.get_header_property(); - let (task_input) = alloc(); - local tasks_bytes_len: felt; - - %{ - from tools.py.utils import bytes_to_8_bytes_chunks_little - task_bytes = bytes.fromhex("22B4DA4CC94620C9DFCC5AE7429AD350AC86587E6D9925A6209587EF17967F200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000186a0") - ids.tasks_bytes_len = len(task_bytes) - segments.write_arg(ids.task_input, bytes_to_8_bytes_chunks_little(task_bytes)) - %} - let datalake_ptr: felt* = cast(&datalake, felt*); - - let task = ComputationalTask( - hash=Uint256( - low=0xAE5641FEA9032C936D7E54D7CF36E2C3, high=0xA53CFAB970F9780B3C39CFAC1DD3D425 - ), - datalake_ptr=datalake_ptr, - datalake_type=DatalakeType.BLOCK_SAMPLED, - aggregate_fn_id=AGGREGATE_FN.COUNT, - ctx_operator=1, - ctx_value=Uint256(low=0x186a0, high=0), - ); - - let (datalake_hash) = keccak(datalake_input, datalake_bytes_len); - - return (task, task_input, tasks_bytes_len, datalake, datalake_hash); - } -} diff --git a/tests/cairo_programs/tx_decoder.cairo b/tests/cairo_programs/tx_decoder.cairo deleted file mode 100644 index 787022d..0000000 --- a/tests/cairo_programs/tx_decoder.cairo +++ /dev/null @@ -1,55 +0,0 @@ -%builtins range_check bitwise keccak poseidon -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256 - -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin, PoseidonBuiltin -from src.decoders.header_decoder import HeaderDecoder -from packages.eth_essentials.lib.utils import pow2alloc128 -from src.types import Transaction, ChainInfo -from src.decoders.transaction_decoder import TransactionDecoder, TransactionSender, TransactionField -from src.verifiers.transaction_verifier import init_tx_stuct -from src.chain_info import fetch_chain_info -from tests.utils.tx import test_tx_decoding_inner -func main{ - range_check_ptr, - bitwise_ptr: BitwiseBuiltin*, - keccak_ptr: KeccakBuiltin*, - poseidon_ptr: PoseidonBuiltin*, -}() { - alloc_locals; - let pow2_array: felt* = pow2alloc128(); - let (local chain_info) = fetch_chain_info(1); - - local n_test_txs: felt; - - %{ - tx_array = [ - "0x2e923a6f09ba38f63ff9b722afd14b9e850432860b77df9011e92c1bf0eecf6b", # Type 0 - "0x237f99e622d67413956b8674cf16ea56b0ba0a18a9f68a5e254f4ac8d2050b51", # Type 0 (eip155) - "0x423d6dfdeae9967847fb226e138ea5fad6279c12bf3343eae4d32c2477be3021", # Type 1 - "0x0d19225fe9ec3044d16008c3aceb0b9059cc22d66cd3ab847f6bd1e454342b4b", # Type 2 - "0x4b0070defa33cbc85f558323bf60132f600212cec3f4ab9e57260d40ff8949d9", # Type 3 - # Other edge cases that have failed before - "0x15306e5f15afc5d178d705155bd38d70504795686f5f75f3d759ff3fb7fcb61d", - "0x371882ee00ff668ca6bf9b1ec37fda5e1fa3a4d0b0f2fb4ef26611f1b1603d3e", - "0xa10d0d5a82894137f33b85e8f40a028eb740acc3dd3b98ed85c16e8d5d57a803", - "0xd675eaa76156b865c8d0aa1556dd08b0ed0bc2dc6531fc168f3d623aaa093230", - "0x66319691b7c3a1773496c14f68164aef3988ecfdde04081c771c1930369a48e8", - "0xf7635229a06e479acce3f9e9a4bdf7b34ecbfac735c21bf7f0300c292c6ff188" - ] - - ids.n_test_txs = len(tx_array) - %} - - // run default tests first - test_tx_decoding_inner{ - range_check_ptr=range_check_ptr, - bitwise_ptr=bitwise_ptr, - pow2_array=pow2_array, - keccak_ptr=keccak_ptr, - poseidon_ptr=poseidon_ptr, - chain_info=chain_info, - }(n_test_txs, 0); - - return (); -} diff --git a/tests/cairo_programs/txs_in_block_datalake.cairo b/tests/cairo_programs/txs_in_block_datalake.cairo deleted file mode 100644 index 08d4f8d..0000000 --- a/tests/cairo_programs/txs_in_block_datalake.cairo +++ /dev/null @@ -1,119 +0,0 @@ -%builtins range_check bitwise keccak -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin, PoseidonBuiltin -from starkware.cairo.common.alloc import alloc - -from packages.eth_essentials.lib.utils import pow2alloc128 -from src.datalakes.txs_in_block_datalake import init_txs_in_block - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*}() { - alloc_locals; - let pow2_array: felt* = pow2alloc128(); - - let (input: felt*) = alloc(); - local input_bytes_len: felt; - - %{ - encoded_datalakes = [ - "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000005595f50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020100000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000005595f50000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000005c0000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020104000000000000000000000000000000000000000000000000000000000000", - "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000005595f50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000101010100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020104000000000000000000000000000000000000000000000000000000000000" - ] - - expected_datalakes = [ - { - "target_block": 5608949, - "start_index": 0, - "end_index": 92, - "increment": 1, - "included_types": [1, 1, 0, 0], - "sampled_property": 0, - "type": 1, - - }, - { - "target_block": 5608949, - "start_index": 5, - "end_index": 92, - "increment": 3, - "included_types":[0,0,1,1], - "sampled_property": 4, - "type": 1, - }, - { - "target_block": 5608949, - "start_index": 0, - "end_index": 90, - "increment": 10, - "included_types":[1,1,1,1], - "sampled_property": 4, - "type": 1, - } - ] - %} - - eval{ - range_check_ptr=range_check_ptr, - bitwise_ptr=bitwise_ptr, - keccak_ptr=keccak_ptr, - pow2_array=pow2_array, - }(count=3, index=0); - - return (); -} - -func eval{ - range_check_ptr, bitwise_ptr: BitwiseBuiltin*, keccak_ptr: KeccakBuiltin*, pow2_array: felt* -}(count: felt, index: felt) { - alloc_locals; - if (count == index) { - return (); - } - - let (input_chunks) = alloc(); - local input_bytes_len: felt; - local target_block: felt; - local start_index: felt; - local end_index: felt; - local increment: felt; - local sampled_property: felt; - local type: felt; - - %{ - from tools.py.utils import ( - bytes_to_8_bytes_chunks_little, - ) - - input_bytes = bytes.fromhex(encoded_datalakes[ids.index]) - ids.input_bytes_len = len(input_bytes) - - input_chunks = bytes_to_8_bytes_chunks_little(input_bytes) - segments.write_arg(ids.input_chunks, input_chunks) - - ids.target_block = expected_datalakes[ids.index]["target_block"] - ids.start_index = expected_datalakes[ids.index]["start_index"] - ids.end_index = expected_datalakes[ids.index]["end_index"] - ids.increment = expected_datalakes[ids.index]["increment"] - ids.type = expected_datalakes[ids.index]["type"] - ids.sampled_property = expected_datalakes[ids.index]["sampled_property"] - %} - - let (result) = init_txs_in_block{pow2_array=pow2_array}( - input=input_chunks, input_bytes_len=input_bytes_len - ); - - assert result.target_block = target_block; - assert result.start_index = start_index; - assert result.end_index = end_index; - assert result.increment = increment; - assert result.type = type; - assert result.sampled_property = sampled_property; - - %{ - assert memory[ids.result.included_types] == expected_datalakes[ids.index]["included_types"][0] - assert memory[ids.result.included_types + 1] == expected_datalakes[ids.index]["included_types"][1] - assert memory[ids.result.included_types + 2] == expected_datalakes[ids.index]["included_types"][2] - assert memory[ids.result.included_types + 3] == expected_datalakes[ids.index]["included_types"][3] - %} - - return eval(count=count, index=index + 1); -} diff --git a/tests/fuzzing/header_decode.cairo b/tests/fuzzing/header_decode.cairo deleted file mode 100644 index 052df81..0000000 --- a/tests/fuzzing/header_decode.cairo +++ /dev/null @@ -1,34 +0,0 @@ -%builtins range_check bitwise -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256, uint256_reverse_endian - -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin -from src.decoders.header_decoder import HeaderDecoder, HeaderField -from packages.eth_essentials.lib.utils import pow2alloc128 -from tests.utils.header import test_header_decoding - -func main{range_check_ptr, bitwise_ptr: BitwiseBuiltin*}() { - alloc_locals; - let pow2_array: felt* = pow2alloc128(); - local block_numbers_len: felt; - - %{ - from tests.python.test_tx_decoding import fetch_latest_block_height - import random - - sample_size = 25 - max_block_height = fetch_latest_block_height() - - block_numbers = [] - while len(block_numbers) < sample_size: - block_numbers.append(random.randrange(1, max_block_height)) - - ids.block_numbers_len = len(block_numbers) - %} - - test_header_decoding{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(block_numbers_len, 0); - - return (); -} diff --git a/tests/fuzzing/tx_decode.cairo b/tests/fuzzing/tx_decode.cairo deleted file mode 100644 index ad172a8..0000000 --- a/tests/fuzzing/tx_decode.cairo +++ /dev/null @@ -1,52 +0,0 @@ -%builtins range_check bitwise keccak poseidon -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256 - -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin, PoseidonBuiltin -from src.decoders.header_decoder import HeaderDecoder -from packages.eth_essentials.lib.utils import pow2alloc128 -from src.types import Transaction, ChainInfo -from src.decoders.transaction_decoder import TransactionDecoder, TransactionSender, TransactionField -from src.verifiers.transaction_verifier import init_tx_stuct -from src.chain_info import fetch_chain_info -from tests.utils.tx import test_tx_decoding_inner - -func main{ - range_check_ptr, - bitwise_ptr: BitwiseBuiltin*, - keccak_ptr: KeccakBuiltin*, - poseidon_ptr: PoseidonBuiltin*, -}() { - alloc_locals; - let pow2_array: felt* = pow2alloc128(); - let (local chain_info) = fetch_chain_info(1); - - local n_test_txs: felt; - - %{ - from tests.python.test_tx_decoding import fetch_block_tx_ids, fetch_latest_block_height - import random - block_sample = 10 - latest_height = fetch_latest_block_height() - selected_block = random.randrange(1, latest_height) - print("Selected Block:", selected_block) - tx_array = fetch_block_tx_ids(selected_block) - - if(len(tx_array) >= block_sample): - tx_array = random.sample(tx_array, 10) - - ids.n_test_txs = len(tx_array) - %} - - // run default tests first - test_tx_decoding_inner{ - range_check_ptr=range_check_ptr, - bitwise_ptr=bitwise_ptr, - pow2_array=pow2_array, - keccak_ptr=keccak_ptr, - poseidon_ptr=poseidon_ptr, - chain_info=chain_info, - }(n_test_txs, 0); - - return (); -} diff --git a/tests/python/test_header_decoding.py b/tests/python/test_header_decoding.py deleted file mode 100644 index 513d526..0000000 --- a/tests/python/test_header_decoding.py +++ /dev/null @@ -1,118 +0,0 @@ -from tools.py.fetch_block_headers import fetch_blocks_from_rpc_no_async -from tools.py.block_header import ( - BlockHeader, - BlockHeaderEIP1559, - BlockHeaderShangai, - BlockHeaderDencun, -) - -from tools.py.fetch_tx import ( - fetch_latest_block_height_from_rpc, -) - -from tools.py.utils import ( - bytes_to_8_bytes_chunks_little, - reverse_and_split_256_bytes, -) -from dotenv import load_dotenv -import os -import math - - -GOERLI = "goerli" -MAINNET = "mainnet" - -NETWORK = MAINNET -load_dotenv() -RPC_URL = ( - os.getenv("RPC_URL_GOERLI") if NETWORK == GOERLI else os.getenv("RPC_URL_MAINNET") -) - - -def fetch_latest_block_height(): - return fetch_latest_block_height_from_rpc(RPC_URL) - - -def fetch_header(block_number): - blocks = fetch_blocks_from_rpc_no_async(block_number + 1, block_number - 1, RPC_URL) - block = blocks[1] - assert ( - block.number == block_number - ), f"Block number mismatch {block.number} != {block_number}" - return block - - -def fetch_header_dict(block_number): - block = fetch_header(block_number) - rlp = bytes_to_8_bytes_chunks_little(block.raw_rlp()) - bloom = bytes_to_8_bytes_chunks_little(block.logsBloom.to_bytes(256, "big")) - - block_dict = { - "rlp": rlp, - "bloom": bloom, - "hash": block.hash, - } - - # LE - (low, high) = reverse_and_split_256_bytes(block.parentHash) - block_dict["parent_hash"] = {"low": low, "high": high} - - (low, high) = reverse_and_split_256_bytes(block.unclesHash) - block_dict["uncles_hash"] = {"low": low, "high": high} - - (low, high) = reverse_and_split_256_bytes(block.stateRoot) - block_dict["state_root"] = {"low": low, "high": high} - - (low, high) = reverse_and_split_256_bytes(block.transactionsRoot) - block_dict["tx_root"] = {"low": low, "high": high} - - (low, high) = reverse_and_split_256_bytes(block.receiptsRoot) - block_dict["receipts_root"] = {"low": low, "high": high} - - coinbase = bytes_to_8_bytes_chunks_little(block.coinbase) - block_dict["coinbase"] = coinbase - - block_dict["difficulty"] = block.difficulty - block_dict["number"] = block.number - block_dict["gas_limit"] = block.gasLimit - block_dict["gas_used"] = block.gasUsed - block_dict["timestamp"] = block.timestamp - - # Special case for empty extra data - if len(block.extraData) == 0: - block_dict["extra_data"] = {"bytes": [0], "bytes_len": 1, "len": 1} - else: - block_dict["extra_data"] = { - "bytes": bytes_to_8_bytes_chunks_little(block.extraData), - "bytes_len": len(block.extraData), - "len": math.ceil(len(block.extraData) / 8), - } - - (low, high) = reverse_and_split_256_bytes(block.mixHash) - block_dict["mix_hash"] = {"low": low, "high": high} - - block_dict["nonce"] = int.from_bytes(block.nonce, "big") - - if type(block) is BlockHeader: - block_dict["type"] = 0 - elif type(block) is BlockHeaderEIP1559: - block_dict["type"] = 1 - elif type(block) is BlockHeaderShangai: - block_dict["type"] = 2 - elif type(block) is BlockHeaderDencun: - block_dict["type"] = 3 - - if block_dict["type"] >= 1: - block_dict["base_fee_per_gas"] = block.baseFeePerGas - - if block_dict["type"] >= 2: - (low, high) = reverse_and_split_256_bytes(block.withdrawalsRoot) - block_dict["withdrawls_root"] = {"low": low, "high": high} - - if block_dict["type"] >= 3: - block_dict["blob_gas_used"] = block.blobGasUsed - block_dict["excess_blob_gas"] = block.excessBlobGas - (low, high) = reverse_and_split_256_bytes(block.parentBeaconBlockRoot) - block_dict["parent_beacon_block_root"] = {"low": low, "high": high} - - return block_dict diff --git a/tests/python/test_poseidon_hash_block.py b/tests/python/test_poseidon_hash_block.py deleted file mode 100644 index 1a27665..0000000 --- a/tests/python/test_poseidon_hash_block.py +++ /dev/null @@ -1,50 +0,0 @@ -from tools.py.fetch_block_headers import fetch_blocks_from_rpc_no_async -from starkware.cairo.common.poseidon_hash import poseidon_hash_many, poseidon_hash -from tools.py.utils import bytes_to_8_bytes_chunks, bytes_to_8_bytes_chunks_little -from dotenv import load_dotenv -import os - - -GOERLI = "goerli" -MAINNET = "mainnet" - -NETWORK = GOERLI -load_dotenv() -RPC_URL = ( - os.getenv("RPC_URL_GOERLI") if NETWORK == GOERLI else os.getenv("RPC_URL_MAINNET") -) -RPC_URL = "https://ethereum-rpc.publicnode.com" - -block_n = 1150001 - - -def get_block_header(number: int): - blocks = fetch_blocks_from_rpc_no_async(number + 1, number - 1, RPC_URL) - block = blocks[1] - print(block) - assert block.number == number, f"Block number mismatch {block.number} != {number}" - return block - - -def get_block_header_raw(number: int): - block = get_block_header(number) - print(block.raw_rlp().hex()) - return block.raw_rlp() - - -def get_poseidon_hash_block(block_header_raw: bytes): - chunks = bytes_to_8_bytes_chunks(block_header_raw) - print(chunks, len(chunks)) - return poseidon_hash_many(chunks) - - -def get_poseidon_hash_block_little(block_header_raw: bytes): - chunks = bytes_to_8_bytes_chunks_little(block_header_raw) - print([hex(chunk) for chunk in chunks], len(chunks)) - return poseidon_hash_many(chunks) - - -test = get_block_header_raw(block_n) -# test_big = get_poseidon_hash_block(test) -test_little = get_poseidon_hash_block_little(test) -print(hex(test_little)) diff --git a/tests/python/test_tx_decoding.py b/tests/python/test_tx_decoding.py deleted file mode 100644 index c587f53..0000000 --- a/tests/python/test_tx_decoding.py +++ /dev/null @@ -1,160 +0,0 @@ -from tools.py.fetch_tx import ( - fetch_tx_from_rpc, - fetch_block_tx_ids_from_rpc, - fetch_latest_block_height_from_rpc, -) -from tools.py.transaction import LegacyTx -from rlp import encode, decode -from tools.py.utils import ( - bytes_to_8_bytes_chunks_little, - reverse_and_split_256_bytes, -) -from dotenv import load_dotenv -import os -import math - -GOERLI = "goerli" -MAINNET = "mainnet" - -NETWORK = MAINNET -load_dotenv() -RPC_URL = ( - os.getenv("RPC_URL_GOERLI") if NETWORK == GOERLI else os.getenv("RPC_URL_MAINNET") -) - - -def fetch_latest_block_height(): - return fetch_latest_block_height_from_rpc(RPC_URL) - - -def fetch_block_tx_ids(block_number): - return fetch_block_tx_ids_from_rpc(block_number, RPC_URL) - - -def fetch_tx(tx_hash): - return fetch_tx_from_rpc(tx_hash, RPC_URL) - - -def fetch_transaction_dict(tx_hash): - tx = fetch_tx(tx_hash) - assert tx_hash == tx.hash().hex(), "TX hashes do not match!" - rlp = bytes_to_8_bytes_chunks_little(tx.raw_rlp()) - - tx_dict = { - "rlp": rlp, - "rlp_bytes_len": len(tx.raw_rlp()), - "block_number": tx.block_number, - } - - # LE - (low, high) = reverse_and_split_256_bytes(tx.nonce.to_bytes(32, "big")) - tx_dict["nonce"] = {"low": low, "high": high} - - (low, high) = reverse_and_split_256_bytes(tx.gas_limit.to_bytes(32, "big")) - tx_dict["gas_limit"] = {"low": low, "high": high} - - to = bytes_to_8_bytes_chunks_little(tx.to) - tx_dict["receiver"] = to - - (low, high) = reverse_and_split_256_bytes(tx.value.to_bytes(32, "big")) - tx_dict["value"] = {"low": low, "high": high} - - data = bytes_to_8_bytes_chunks_little(tx.data) - tx_dict["data"] = data - - (low, high) = reverse_and_split_256_bytes(tx.v.to_bytes(32, "big")) - tx_dict["v"] = {"low": low, "high": high} - - # dirty af, but it works - (low, high) = reverse_and_split_256_bytes( - int.from_bytes(tx.r, "big").to_bytes(32, "big") - ) - tx_dict["r"] = {"low": low, "high": high} - - (low, high) = reverse_and_split_256_bytes( - int.from_bytes(tx.s, "big").to_bytes(32, "big") - ) - tx_dict["s"] = {"low": low, "high": high} - - input_bytes = tx.data - if tx.data == b"": - tx_dict["input"] = { - "chunks": [0], - "bytes_len": 1, - } - else: - tx_dict["input"] = { - "chunks": bytes_to_8_bytes_chunks_little(tx.data), - "bytes_len": len(tx.data), - } - - tx_dict["type"] = tx.type - tx_dict["sender"] = int(tx.sender.hex(), 16) - - if type(tx) != LegacyTx: - tx_dict["chain_id"] = tx.chain_id - - if tx.type <= 1: - (low, high) = reverse_and_split_256_bytes(tx.gas_price.to_bytes(32, "big")) - tx_dict["gas_price"] = {"low": low, "high": high} - else: - (low, high) = reverse_and_split_256_bytes( - tx.max_priority_fee_per_gas.to_bytes(32, "big") - ) - tx_dict["max_priority_fee_per_gas"] = {"low": low, "high": high} - - (low, high) = reverse_and_split_256_bytes( - tx.max_fee_per_gas.to_bytes(32, "big") - ) - tx_dict["max_fee_per_gas"] = {"low": low, "high": high} - - if tx.type >= 1: - if len(tx.access_list) == 0: - tx_dict["access_list"] = { - "chunks": [0], - "bytes_len": 1, - } - else: - encoded = encode_array_elements(tx.access_list) - tx_dict["access_list"] = { - "chunks": bytes_to_8_bytes_chunks_little(encoded), - "bytes_len": len(encoded), - } - - if tx.type == 3: - (low, high) = reverse_and_split_256_bytes( - tx.max_fee_per_blob_gas.to_bytes(32, "big") - ) - tx_dict["max_fee_per_blob_gas"] = {"low": low, "high": high} - - if len(tx.blob_versioned_hashes) == 0: - tx_dict["blob_versioned_hashes"] = { - "chunks": [0], - "bytes_len": 1, - } - else: - tx_dict["blob_versioned_hashes"] = { - "chunks": bytes_to_8_bytes_chunks_little( - encode_array_elements(tx.blob_versioned_hashes) - ), - "bytes_len": len(encode_array_elements(tx.blob_versioned_hashes)), - } - - return tx_dict - - -# encode an the elements of an array in RLP. This returns the encoded data, without the array prefix -def encode_array_elements(hex_array): - res = b"" - for element in hex_array: - res += encode(element) - - return res - - -## Test TX encoding: -# assert fetch_tx("0x423d6dfdeae9967847fb226e138ea5fad6279c12bf3343eae4d32c2477be3021").hash().hex() == "0x423d6dfdeae9967847fb226e138ea5fad6279c12bf3343eae4d32c2477be3021" -# assert fetch_tx("0x237f99e622d67413956b8674cf16ea56b0ba0a18a9f68a5e254f4ac8d2050b51").hash().hex() == "0x237f99e622d67413956b8674cf16ea56b0ba0a18a9f68a5e254f4ac8d2050b51" -# assert fetch_tx("0x2e923a6f09ba38f63ff9b722afd14b9e850432860b77df9011e92c1bf0eecf6b").hash().hex() == "0x2e923a6f09ba38f63ff9b722afd14b9e850432860b77df9011e92c1bf0eecf6b" -# assert fetch_tx("0x0d19225fe9ec3044d16008c3aceb0b9059cc22d66cd3ab847f6bd1e454342b4b").hash().hex() == "0x0d19225fe9ec3044d16008c3aceb0b9059cc22d66cd3ab847f6bd1e454342b4b" -# assert fetch_tx("0x4b0070defa33cbc85f558323bf60132f600212cec3f4ab9e57260d40ff8949d9").hash().hex() == "0x4b0070defa33cbc85f558323bf60132f600212cec3f4ab9e57260d40ff8949d9" diff --git a/tests/python/test_verify_getproof.py b/tests/python/test_verify_getproof.py deleted file mode 100644 index b917831..0000000 --- a/tests/python/test_verify_getproof.py +++ /dev/null @@ -1,164 +0,0 @@ -import web3 -from web3 import Web3 -from eth_utils import ( - keccak, -) -import rlp -from rlp.codec import consume_length_prefix -from rlp.sedes import ( - Binary, - big_endian_int, -) -from trie import ( - HexaryTrie, -) -from web3._utils.encoding import ( - pad_bytes, -) -from tools.py.utils import ( - bytes_to_8_bytes_chunks, - bytes_to_8_bytes_chunks_little, -) -from trie.utils.nodes import ( - decode_node, - get_node_type, - extract_key, - compute_leaf_key, - compute_extension_key, - is_blank_node, - is_extension_node, - is_leaf_node, - consume_common_prefix, - key_starts_with, -) - -from trie.utils.nibbles import bytes_to_nibbles - -import pickle - -offline = False - -RPC_URL = "https://eth-mainnet.g.alchemy.com/v2/3QG7M_ZxG-uvZrfVE6y824aEvT67QdTr" - -zero = 0x0000000000000000000000000000000000000000000000000000000000000000 -w3 = Web3(Web3.HTTPProvider(RPC_URL)) - - -def format_proof_nodes(proof): - trie_proof = [] - for rlp_node in proof: - trie_proof.append(rlp.decode(bytes(rlp_node))) - return trie_proof - - -def verify_eth_get_proof(proof, root): - trie_root = Binary.fixed_length(32, allow_empty=True) - hash32 = Binary.fixed_length(32) - - class _Account(rlp.Serializable): - fields = [ - ("nonce", big_endian_int), - ("balance", big_endian_int), - ("storage", trie_root), - ("code_hash", hash32), - ] - - acc = _Account(proof.nonce, proof.balance, proof.storageHash, proof.codeHash) - print(acc) - rlp_account = rlp.encode(acc) - trie_key = keccak(bytes.fromhex(proof.address[2:])) - print(f"trie_key: {trie_key.hex()}") - assert rlp_account == HexaryTrie.get_from_proof( - root, trie_key, format_proof_nodes(proof.accountProof) - ), f"Failed to verify account proof {proof.address}" - - for storage_proof in proof.storageProof: - trie_key = keccak(pad_bytes(b"\x00", 32, storage_proof.key)) - root = proof.storageHash - if storage_proof.value == b"\x00": - rlp_value = b"" - else: - rlp_value = rlp.encode(storage_proof.value) - - assert rlp_value == HexaryTrie.get_from_proof( - root, trie_key, format_proof_nodes(storage_proof.proof) - ), f"Failed to verify storage proof {storage_proof.key}" - - return True - - -address = 0xD3CDA913DEB6F67967B99D67ACDFA1712C293601 -trie_key = keccak(bytes.fromhex(hex(address)[2:])) - - -if not offline: - block = w3.eth.get_block(81326) - proof = w3.eth.get_proof( - w3.toChecksumAddress(hex(address)), - [zero], - 81326, - ) - assert verify_eth_get_proof(proof, block.stateRoot) - ap = proof.accountProof - pickle.dump(ap, open("account_proof.ap", "wb")) - - -elif offline: - ap = pickle.load(open("account_proof.ap", "rb")) - - -consume_length_prefix(ap[0], 0) -consume_length_prefix(ap[1], 0) -consume_length_prefix(ap[2], 0) -consume_length_prefix(ap[3], 0) -consume_length_prefix(ap[4], 0) - - -def extract_n_bytes_from_word(word, pos, n): - """ - Extracts n bytes from a 64-bit word starting at position pos. - - :param word: 64-bit word as an integer. - :param pos: Position to start extraction (0-indexed). - :param n: Number of bytes to extract. - :return: Extracted bytes as an integer. - """ - # Mask to extract the desired bytes - mask = (1 << (n * 8)) - 1 - - # Shift the word right to align the desired bytes at the end, then apply the mask - extracted_bytes = (word >> (pos * 8)) & mask - - return extracted_bytes - - -# Example -word = int.from_bytes([0xB7, 0xB6, 0xB5, 0xB4, 0xB3, 0xB2, 0xB1, 0xB0], byteorder="big") -pos = 1 -n = 2 -extracted = extract_n_bytes_from_word(word, pos, n) -extracted - - -def merge_integers_to_bytes(int_array): - # Initialize an empty byte array - merged_bytes = bytearray() - # Process all integers except the last one - for number in int_array[:-1]: - # Convert each integer to a byte array of fixed 8 bytes and append - merged_bytes.extend(number.to_bytes(8, "big")) - # Process the last integer - if int_array: - last_number = int_array[-1] - num_bytes = (last_number.bit_length() + 7) // 8 # Minimum bytes needed - merged_bytes.extend(last_number.to_bytes(num_bytes, "big")) - return bytes(merged_bytes) - - -def extract_n_bytes_from_array( - bytes_array, start_word, start_offset, n_bytes_to_extract -): - start_byte = start_word * 8 + start_offset - end_byte = start_byte + n_bytes_to_extract - res_bytes = bytes_array[start_byte:end_byte] - return res_bytes diff --git a/tests/utils/header.cairo b/tests/utils/header.cairo deleted file mode 100644 index 8033531..0000000 --- a/tests/utils/header.cairo +++ /dev/null @@ -1,290 +0,0 @@ -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256, uint256_reverse_endian - -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin -from src.decoders.header_decoder import HeaderDecoder, HeaderField - -func test_header_decoding{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}( - header_len: felt, index: felt -) { - alloc_locals; - - if (header_len == index) { - return (); - } - - let (rlp) = alloc(); - local header_type: felt; - local expected_parent_hash: Uint256; - local expected_uncles_hash: Uint256; - let (expected_coinbase) = alloc(); - local expected_state_root: Uint256; - local expected_tx_root: Uint256; - local expected_receipts_root: Uint256; - let (expected_bloom_filter) = alloc(); - local expected_difficulty: Uint256; - local expected_number: Uint256; - local expected_gas_limit: Uint256; - local expected_gas_used: Uint256; - local expected_timestamp: Uint256; - - let (expected_extra_data) = alloc(); - local expected_extra_data_len: felt; - local expected_extra_data_bytes_len: felt; - local expected_mix_hash: Uint256; - - local expected_nonce: Uint256; - local expected_base_fee_per_gas: Uint256; - local expected_withdrawls_root: Uint256; - - local expected_blob_gas_used: Uint256; - local expected_excess_blob_gas: Uint256; - local expected_parent_beacon_root: Uint256; - - %{ - from tests.python.test_header_decoding import fetch_header_dict - header = fetch_header_dict(block_numbers[ids.index]) - print("Running Block #", block_numbers[ids.index]) - segments.write_arg(ids.rlp, header['rlp']) - - ids.expected_parent_hash.low = header['parent_hash']["low"] - ids.expected_parent_hash.high = header['parent_hash']["high"] - ids.expected_uncles_hash.low = header['uncles_hash']["low"] - ids.expected_uncles_hash.high = header['uncles_hash']["high"] - segments.write_arg(ids.expected_coinbase, header['coinbase']) - ids.expected_state_root.low = header['state_root']["low"] - ids.expected_state_root.high = header['state_root']["high"] - ids.expected_tx_root.low = header['tx_root']["low"] - ids.expected_tx_root.high = header['tx_root']["high"] - ids.expected_receipts_root.low = header['receipts_root']["low"] - ids.expected_receipts_root.high = header['receipts_root']["high"] - segments.write_arg(ids.expected_bloom_filter, header['bloom']) - ids.expected_difficulty.low = header['difficulty'] - ids.expected_number.low = header['number'] - ids.expected_number.high = 0 - ids.expected_gas_limit.low = header['gas_limit'] - ids.expected_gas_limit.high = 0 - ids.expected_gas_used.low = header['gas_used'] - ids.expected_gas_used.high = 0 - ids.expected_timestamp.low = header['timestamp'] - ids.expected_timestamp.high = 0 - segments.write_arg(ids.expected_extra_data, header['extra_data']['bytes']) - ids.expected_extra_data_len = header['extra_data']['len'] - ids.expected_extra_data_bytes_len = header['extra_data']['bytes_len'] - - ids.expected_mix_hash.low = header['mix_hash']["low"] - ids.expected_mix_hash.high = header['mix_hash']["high"] - - ids.expected_nonce.low = header['nonce'] - ids.expected_nonce.high = 0 - ids.header_type = header["type"] - - if ids.header_type >=1 : - ids.expected_base_fee_per_gas.low = header['base_fee_per_gas'] - - if ids.header_type >= 2: - ids.expected_withdrawls_root.low = header['withdrawls_root']["low"] - ids.expected_withdrawls_root.high = header['withdrawls_root']["high"] - - if ids.header_type >= 3: - ids.expected_blob_gas_used.low = header['blob_gas_used'] - ids.expected_excess_blob_gas.low = header['excess_blob_gas'] - ids.expected_parent_beacon_root.low = header['parent_beacon_block_root']["low"] - ids.expected_parent_beacon_root.high = header['parent_beacon_block_root']["high"] - %} - - let parent_hash = HeaderDecoder.get_field(rlp, HeaderField.PARENT); - - assert parent_hash.low = expected_parent_hash.low; - assert parent_hash.high = expected_parent_hash.high; - - let uncles_hash = HeaderDecoder.get_field(rlp, HeaderField.UNCLE); - assert uncles_hash.low = expected_uncles_hash.low; - assert uncles_hash.high = expected_uncles_hash.high; - - let (coinbase, _, _) = HeaderDecoder.get_field_felt(rlp, HeaderField.COINBASE); - assert coinbase[0] = expected_coinbase[0]; - assert coinbase[1] = expected_coinbase[1]; - assert coinbase[2] = expected_coinbase[2]; - - let state_root = HeaderDecoder.get_field(rlp, HeaderField.STATE_ROOT); - assert state_root.low = expected_state_root.low; - assert state_root.high = expected_state_root.high; - - let tx_root = HeaderDecoder.get_field(rlp, HeaderField.TRANSACTION_ROOT); - assert tx_root.low = expected_tx_root.low; - assert tx_root.high = expected_tx_root.high; - - let receipts_root = HeaderDecoder.get_field(rlp, HeaderField.RECEIPT_ROOT); - assert receipts_root.low = expected_receipts_root.low; - assert receipts_root.high = expected_receipts_root.high; - - let (bloom_filter, value_len, bytes_len) = HeaderDecoder.get_field_felt(rlp, HeaderField.BLOOM); - compare_bloom_filter( - expected_bloom_filter=expected_bloom_filter, - bloom_filter=bloom_filter, - value_len=value_len, - bytes_len=bytes_len, - ); - - let difficulty_le = HeaderDecoder.get_field(rlp, HeaderField.DIFFICULTY); - let (local difficulty) = uint256_reverse_endian(difficulty_le); - assert difficulty.low = expected_difficulty.low; - assert difficulty.high = expected_difficulty.high; - - let number_le = HeaderDecoder.get_field(rlp, HeaderField.NUMBER); - let (local number) = uint256_reverse_endian(number_le); - - assert number.low = expected_number.low; - assert number.high = expected_number.high; - - let gas_limit_le = HeaderDecoder.get_field(rlp, HeaderField.GAS_LIMIT); - let (local gas_limit) = uint256_reverse_endian(gas_limit_le); - assert gas_limit.low = expected_gas_limit.low; - assert gas_limit.high = expected_gas_limit.high; - - let gas_used_le = HeaderDecoder.get_field(rlp, HeaderField.GAS_USED); - let (local gas_used) = uint256_reverse_endian(gas_used_le); - assert gas_used.low = expected_gas_used.low; - assert gas_used.high = expected_gas_used.high; - - let timestamp_le = HeaderDecoder.get_field(rlp, HeaderField.TIMESTAMP); - let (local timestamp) = uint256_reverse_endian(timestamp_le); - assert timestamp.low = expected_timestamp.low; - assert timestamp.high = expected_timestamp.high; - - let (extra_data, extra_data_len, extra_data_bytes_len) = HeaderDecoder.get_field_felt( - rlp, HeaderField.EXTRA_DATA - ); - - compare_extra_data( - expected_extra_data=expected_extra_data, - expected_extra_data_len=expected_extra_data_len, - expected_extra_data_bytes_len=expected_extra_data_bytes_len, - extra_data=extra_data, - extra_data_len=extra_data_len, - extra_data_bytes_len=extra_data_bytes_len, - ); - - let mix_hash = HeaderDecoder.get_field(rlp, HeaderField.MIX_HASH); - assert mix_hash.low = expected_mix_hash.low; - assert mix_hash.high = expected_mix_hash.high; - - let nonce_le = HeaderDecoder.get_field(rlp, HeaderField.NONCE); - let (local nonce) = uint256_reverse_endian(nonce_le); - assert nonce.low = expected_nonce.low; - assert nonce.high = expected_nonce.high; - - local impl_london: felt; - %{ ids.impl_london = 1 if ids.header_type >= 1 else 0 %} - - if (impl_london == 1) { - let base_fee_per_gas_le = HeaderDecoder.get_field(rlp, HeaderField.BASE_FEE_PER_GAS); - let (local base_fee_per_gas) = uint256_reverse_endian(base_fee_per_gas_le); - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - assert base_fee_per_gas.low = expected_base_fee_per_gas.low; - assert base_fee_per_gas.high = expected_base_fee_per_gas.high; - } else { - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } - - local impl_shanghai: felt; - %{ ids.impl_shanghai = 1 if ids.header_type >= 2 else 0 %} - if (impl_shanghai == 1) { - let withdrawls_root = HeaderDecoder.get_field(rlp, HeaderField.WITHDRAWALS_ROOT); - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - assert withdrawls_root.low = expected_withdrawls_root.low; - assert withdrawls_root.high = expected_withdrawls_root.high; - } else { - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } - - local impl_dencun: felt; - %{ ids.impl_dencun = 1 if ids.header_type >= 3 else 0 %} - - if (impl_dencun == 1) { - let blob_gas_used_le = HeaderDecoder.get_field(rlp, HeaderField.BLOB_GAS_USED); - let (local blob_gas_used) = uint256_reverse_endian(blob_gas_used_le); - assert blob_gas_used.low = expected_blob_gas_used.low; - assert blob_gas_used.high = expected_blob_gas_used.high; - - let excess_blob_gas_le = HeaderDecoder.get_field(rlp, HeaderField.EXCESS_BLOB_GAS); - let (local excess_blob_gas) = uint256_reverse_endian(excess_blob_gas_le); - assert excess_blob_gas.low = expected_excess_blob_gas.low; - assert excess_blob_gas.high = expected_excess_blob_gas.high; - - let parent_beacon_root = HeaderDecoder.get_field(rlp, HeaderField.PARENT_BEACON_BLOCK_ROOT); - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - assert parent_beacon_root.low = expected_parent_beacon_root.low; - assert parent_beacon_root.high = expected_parent_beacon_root.high; - } else { - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } - - return test_header_decoding(header_len=header_len, index=index + 1); -} - -func compare_bloom_filter( - expected_bloom_filter: felt*, bloom_filter: felt*, value_len: felt, bytes_len: felt -) { - alloc_locals; - - assert value_len = 32; - assert bytes_len = 256; - - tempvar i = 0; - - assert_loop: - let i = [ap - 1]; - if (i == 32) { - jmp end_loop; - } - - assert expected_bloom_filter[i] = bloom_filter[i]; - [ap] = i + 1, ap++; - jmp assert_loop; - - end_loop: - return (); -} - -func compare_extra_data( - expected_extra_data: felt*, - expected_extra_data_len: felt, - expected_extra_data_bytes_len: felt, - extra_data: felt*, - extra_data_len: felt, - extra_data_bytes_len: felt, -) { - alloc_locals; - - assert expected_extra_data_len = extra_data_len; - assert expected_extra_data_bytes_len = extra_data_bytes_len; - - tempvar i = 0; - - assert_loop: - let i = [ap - 1]; - if (i == expected_extra_data_len) { - jmp end_loop; - } - - assert expected_extra_data[i] = extra_data[i]; - [ap] = i + 1, ap++; - jmp assert_loop; - - end_loop: - return (); -} diff --git a/tests/utils/tx.cairo b/tests/utils/tx.cairo deleted file mode 100644 index e97bf17..0000000 --- a/tests/utils/tx.cairo +++ /dev/null @@ -1,272 +0,0 @@ -from starkware.cairo.common.alloc import alloc -from starkware.cairo.common.uint256 import Uint256 -from starkware.cairo.common.cairo_builtins import BitwiseBuiltin, KeccakBuiltin, PoseidonBuiltin - -from src.types import Transaction, ChainInfo -from src.decoders.transaction_decoder import TransactionDecoder, TransactionSender, TransactionField -from src.verifiers.transaction_verifier import init_tx_stuct - -func test_tx_decoding_inner{ - range_check_ptr, - bitwise_ptr: BitwiseBuiltin*, - pow2_array: felt*, - keccak_ptr: KeccakBuiltin*, - poseidon_ptr: PoseidonBuiltin*, - chain_info: ChainInfo, -}(txs: felt, index: felt) { - alloc_locals; - - if (txs == index) { - return (); - } - - let (rlp) = alloc(); - local rlp_len: felt; - local rlp_bytes_len: felt; - local block_number: felt; - - local expected_nonce: Uint256; - local expected_gas_limit: Uint256; - let (expected_receiver) = alloc(); - local expected_value: Uint256; - local expected_v: Uint256; - local expected_r: Uint256; - local expected_s: Uint256; - - let (expected_input) = alloc(); - local expected_input_len: felt; - local expected_input_bytes_len: felt; - - local expected_gas_price: Uint256; - local expected_max_prio_fee_per_gas: Uint256; - local expected_max_fee_per_gas: Uint256; - - let (expected_access_list) = alloc(); - local expected_access_list_len: felt; - local expected_access_list_bytes_len: felt; - - local expected_max_fee_per_blob_gas: Uint256; - let (expected_blob_versioned_hashes) = alloc(); - local expected_blob_versioned_hashes_len: felt; - local expected_blob_versioned_hashes_bytes_len: felt; - - local expected_sender: felt; - - %{ - from tools.py.utils import ( - bytes_to_8_bytes_chunks_little, - ) - from tests.python.test_tx_decoding import fetch_transaction_dict - print("Running TX:", tx_array[ids.index]) - tx_dict = fetch_transaction_dict(tx_array[ids.index]) - - ids.block_number = tx_dict["block_number"] - - segments.write_arg(ids.rlp, tx_dict["rlp"]) - ids.rlp_len = len(tx_dict["rlp"]) - ids.rlp_bytes_len = tx_dict["rlp_bytes_len"] - - ids.expected_nonce.low = tx_dict["nonce"]["low"] - ids.expected_nonce.high = tx_dict["nonce"]["high"] - - ids.expected_gas_limit.low = tx_dict["gas_limit"]["low"] - ids.expected_gas_limit.high = tx_dict["gas_limit"]["high"] - - segments.write_arg(ids.expected_receiver, tx_dict["receiver"]) - - ids.expected_value.low = tx_dict["value"]["low"] - ids.expected_value.high = tx_dict["value"]["high"] - - segments.write_arg(ids.expected_input, tx_dict["input"]["chunks"]) - ids.expected_input_len = len(tx_dict["input"]["chunks"]) - ids.expected_input_bytes_len = tx_dict["input"]["bytes_len"] - - ids.expected_v.low = tx_dict["v"]["low"] - ids.expected_v.high = tx_dict["v"]["high"] - - ids.expected_r.low = tx_dict["r"]["low"] - ids.expected_r.high = tx_dict["r"]["high"] - - ids.expected_s.low = tx_dict["s"]["low"] - ids.expected_s.high = tx_dict["s"]["high"] - - ids.expected_sender = tx_dict["sender"] - - if tx_dict["type"] <= 1: - ids.expected_gas_price.low = tx_dict["gas_price"]["low"] - ids.expected_gas_price.high = tx_dict["gas_price"]["high"] - else: - ids.expected_max_prio_fee_per_gas.low = tx_dict["max_priority_fee_per_gas"]["low"] - ids.expected_max_prio_fee_per_gas.high = tx_dict["max_priority_fee_per_gas"]["high"] - - ids.expected_max_fee_per_gas.low = tx_dict["max_fee_per_gas"]["low"] - ids.expected_max_fee_per_gas.high = tx_dict["max_fee_per_gas"]["high"] - - if tx_dict["type"] >= 1: - segments.write_arg(ids.expected_access_list, tx_dict["access_list"]["chunks"]) - ids.expected_access_list_len = len(tx_dict["access_list"]["chunks"]) - ids.expected_access_list_bytes_len = tx_dict["access_list"]["bytes_len"] - - if tx_dict["type"] == 3: - segments.write_arg(ids.expected_blob_versioned_hashes, tx_dict["blob_versioned_hashes"]["chunks"]) - ids.expected_blob_versioned_hashes_len = len(tx_dict["blob_versioned_hashes"]["chunks"]) - ids.expected_blob_versioned_hashes_bytes_len = tx_dict["blob_versioned_hashes"]["bytes_len"] - - ids.expected_max_fee_per_blob_gas.low = tx_dict["max_fee_per_blob_gas"]["low"] - ids.expected_max_fee_per_blob_gas.high = tx_dict["max_fee_per_blob_gas"]["high"] - %} - - let tx = init_tx_stuct(rlp, rlp_bytes_len, block_number); - - let nonce = TransactionDecoder.get_field(tx, TransactionField.NONCE); - assert expected_nonce.low = nonce.low; - assert expected_nonce.high = nonce.high; - - let gas_limit = TransactionDecoder.get_field(tx, TransactionField.GAS_LIMIT); - assert expected_gas_limit.low = gas_limit.low; - assert expected_gas_limit.high = gas_limit.high; - - let (receiver, receiver_len, _) = TransactionDecoder.get_felt_field( - tx, TransactionField.RECEIVER - ); - assert expected_receiver[0] = receiver[0]; - - // prevent failing checks for contract creation transactions - if (receiver_len == 3) { - assert expected_receiver[1] = receiver[1]; - assert expected_receiver[2] = receiver[2]; - } - let value = TransactionDecoder.get_field(tx, TransactionField.VALUE); - assert expected_value.low = value.low; - assert expected_value.high = value.high; - - eval_felt_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }(expected_input, expected_input_len, expected_input_bytes_len, tx, TransactionField.INPUT); - - let v = TransactionDecoder.get_field(tx, TransactionField.V); - assert expected_v.low = v.low; - assert expected_v.high = v.high; - - let r = TransactionDecoder.get_field(tx, TransactionField.R); - assert expected_r.low = r.low; - assert expected_r.high = r.high; - - let s = TransactionDecoder.get_field(tx, TransactionField.S); - assert expected_s.low = s.low; - assert expected_s.high = s.high; - - local has_legacy: felt; - %{ ids.has_legacy = 1 if ids.tx.type <= 1 else 0 %} - if (has_legacy == 1) { - let gas_price = TransactionDecoder.get_field(tx, TransactionField.GAS_PRICE); - assert expected_gas_price.low = gas_price.low; - assert expected_gas_price.high = gas_price.high; - - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } else { - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } - - local has_eip2930: felt; - %{ ids.has_eip2930 = 1 if ids.tx.type >= 2 else 0 %} - if (has_eip2930 == 1) { - eval_felt_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }( - expected_access_list, - expected_access_list_len, - expected_access_list_bytes_len, - tx, - TransactionField.ACCESS_LIST, - ); - - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } else { - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } - - local has_eip1559: felt; - %{ ids.has_eip1559 = 1 if ids.tx.type >= 3 else 0 %} - if (has_eip1559 == 1) { - let max_prio_fee_per_gas = TransactionDecoder.get_field( - tx, TransactionField.MAX_PRIORITY_FEE_PER_GAS - ); - assert expected_max_prio_fee_per_gas.low = max_prio_fee_per_gas.low; - assert expected_max_prio_fee_per_gas.high = max_prio_fee_per_gas.high; - - let max_fee_per_gas = TransactionDecoder.get_field(tx, TransactionField.MAX_FEE_PER_GAS); - assert max_fee_per_gas.low = expected_max_fee_per_gas.low; - assert max_fee_per_gas.high = expected_max_fee_per_gas.high; - - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } else { - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } - - local has_blob_versioned_hashes: felt; - %{ ids.has_blob_versioned_hashes = 1 if ids.tx.type == 4 else 0 %} - if (has_blob_versioned_hashes == 1) { - eval_felt_field{ - range_check_ptr=range_check_ptr, bitwise_ptr=bitwise_ptr, pow2_array=pow2_array - }( - expected_blob_versioned_hashes, - expected_blob_versioned_hashes_len, - expected_blob_versioned_hashes_bytes_len, - tx, - TransactionField.BLOB_VERSIONED_HASHES, - ); - - let max_fee_per_blob_gas = TransactionDecoder.get_field( - tx, TransactionField.MAX_FEE_PER_BLOB_GAS - ); - assert max_fee_per_blob_gas.low = expected_max_fee_per_blob_gas.low; - assert max_fee_per_blob_gas.high = expected_max_fee_per_blob_gas.high; - - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } else { - tempvar range_check_ptr = range_check_ptr; - tempvar bitwise_ptr = bitwise_ptr; - tempvar pow2_array = pow2_array; - } - - let sender = TransactionSender.derive(tx); - assert sender = expected_sender; - - return test_tx_decoding_inner(txs, index + 1); -} - -func eval_felt_field{range_check_ptr, bitwise_ptr: BitwiseBuiltin*, pow2_array: felt*}( - expected: felt*, expected_len: felt, expected_bytes_len: felt, tx: Transaction, field: felt -) { - alloc_locals; - - let (res, res_len, res_bytes_len) = TransactionDecoder.get_felt_field(tx, field); - - %{ - i = 0 - while(i < ids.res_len): - #print("Expected:", hex(memory[ids.expected + i]), "Got:",hex(memory[ids.res + i])) - assert memory[ids.res + i] == memory[ids.expected + i], f"Value Missmatch for field: {ids.field} at index: {i}" - i += 1 - %} - - assert expected_len = res_len; - assert expected_bytes_len = res_bytes_len; - - return (); -} diff --git a/tools/js/merkle.js b/tools/js/merkle.js deleted file mode 100644 index 46cf6ba..0000000 --- a/tools/js/merkle.js +++ /dev/null @@ -1,24 +0,0 @@ -import { StandardMerkleTree } from "@openzeppelin/merkle-tree"; -import { create } from "domain"; -import fs from "fs"; - -function createMerkleTreeValues() { - const values = [ - ["0x0000000000000000000000000000000000000000000000000000000000000001"], - ["0x0000000000000000000000000000000000000000000000000000000000000002"], - ["0x000000000000000000000000000000000000000000000000000000000000007a"], - ["0x0000000000000000000000000000000000000000000000000000000000000004"], - ["0x0000000000000000000000000000000000000000000000000000000000000001"], - ]; - - let roots = []; - for(let i = 0; i < values.length; i++) { - const subset = values.slice(0, i + 1); - const tree = StandardMerkleTree.of(subset, ["bytes32"], {sortLeaves: false}); - roots.push(tree.root); - } - - console.log(roots); -} - -// createMerkleTreeValues(); \ No newline at end of file diff --git a/tools/js/package.json b/tools/js/package.json deleted file mode 100644 index 5d4b448..0000000 --- a/tools/js/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "tools", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "type": "module", - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@openzeppelin/merkle-tree": "^1.0.6" - } -} diff --git a/tools/make/README.md b/tools/make/README.md deleted file mode 100644 index 49dfdbe..0000000 --- a/tools/make/README.md +++ /dev/null @@ -1,135 +0,0 @@ -# Utility Scripts - - -## `setup.sh` -### Usage : `make setup` - -This script sets up a virtual environment within the `venv/` directory and installs all the necessary Python packages for this repository. -All scripts should be run after activating the environment using `source venv/bin/activate`. - - Additionally, it updates the environment variable PYTHONPATH to ensure Python scripts within the tools/ directory can be executed from any location. -It also [patches](poseidon_utils.patch) the poseidon implementation of cairo-lang to make it 7x faster. - -## `build.sh` - -### Usage : `make build` - -This script compiles all Cairo files located in: -- `src/` -- `tests/cairo_programs/` - -The compiled outputs are stored in `build/compiled_cairo_files/`. - -## `launch_cairo_files.py` - -### Usage : `make run`, `make run-profile` or `make test` - -- `make run` : -This script provides an option to choose a Cairo file for execution from: - - `src/single_chunk_processor/chunk_processor.cairo` - - All the Cairo files within `tests/cairo_programs/` - - After selection, the script compiles the chosen file and runs it, using input from a corresponding file located in the same directory. The input file should have the same name as the Cairo file but with the `_input.json` extension in place of `.cairo.` - - For the `chunk_processor.cairo` file, an additional prompt allows selection from input files ending in `_input.json` within the `src/single_chunk_processor/data` directory. See `prepare_inputs_api.py` section. - - -- `make run-profile`: - Has the same logic as `make run` except that the Cairo file is executed with profiling enabled. The resultant profile graph is saved to `build/profiling/`. - -- `make test`: -Simply runs all the files inside `tests/cairo_programs/`. - -## `db.py` - -### Usage : `make db-update` - -A script that creates or updates a local sqlite database containing the block numbers and their corresponding block headers. The database is stored at the root of the repository under the name `blocks.db`. - -You will need to store the RPC urls for Mainnet and/or Goerli by creating a `.env` file in the root directory of the repository and adding the following lines to it: - -```plaintext -RPC_URL_MAINNET= -RPC_URL_GOERLI= -``` - -It will update the database up until the block `HIGH_BLOCK_NUMBER` specified at the top of the script. Other parameters at the top the script can be modified if needed. - -## `prepare_inputs_api.py` - -### Usage : `make prepare-processor-input` - -This Python script prepares inputs for the chunk processor and precomputes the expected outputs. It is using the data from a local sqlite database containing the block numbers and their corresponding block headers. - -To specify which inputs to prepare, modify the main function at the end of the file. - -The `prepare_full_chain_inputs` function parameters include: - - - `from_block_number_high` (int) : Highest block number to include in the input. - - `to_block_number_low` (int) : Lowest block number to include in the input. - - `batch_size` (int) : Fixed number of blocks to include in each batch. - - `dynamic` (bool) : If set to `True`, bypasses the number set in `batch_size` and precomputes a dynamic batch size so that the execution resources are exactly under the limits set in [MAX_RESOURCES_PER_JOB](sharp_submit_params.py) - - (Optional) `initial_params` (dict) : A dictionary containing an initial MMR state, having the following structure : -```JSON -{ - - "mmr_peaks": { - "poseidon":[peak0 (int), peak1 (int), ..., peakn (int)], - "keccak": [peak0 (int), peak1 (int), ..., peakn (int)] - }, - "mmr_size": last_mmr_size (int), - "mmr_roots": { - "poseidon": poseidon_root (int), - "keccak": keccak_root (int) - }}, - -} -``` -If `initial_params` is not provided, the initial MMR state is set to the following: -```JSON -{ - - "mmr_peaks": { - "poseidon":[968420142673072399148736368629862114747721166432438466378474074601992041181], - "keccak": [93435818137180840214006077901347441834554899062844693462640230920378475721064] - }, - - "mmr_size": 1, - "mmr_roots": { - "poseidon": 2921600461849179232597610084551483949436449163481908169507355734771418934190, - "keccak": 42314464114191397424730009642010999497079411585549645511398238200244040012667 - } -} - -``` - -The initial peak values correspond to the Poseidon and Keccak hashes of the string `b'brave new world'`. -The roots are computed accordingly to the [get_root() function.](../py/mmr.py). - - - -The inputs and expected outputs are written to `src/single_chunk_processor/data/`. Those can be used later by the chunk processor and the script `sharp_submit.py` or with `make run`. -The function returns the MMR state after the last chunk, ready to be used as `initial_params` for the next iteration. - - - - - - -## `sharp_submit.py` - -### Usages : -1) `make batch-cairo-pie`: - Runs the chunk processor on all the inputs files under `src/single_chunk_processor/data/` and create PIE objects for each of them in the same directory. - It also checks that the output of each run matches the precomputed output in the same directory. -2) `make batch-pie-multicore`: - Same as 1) but uses multiple cores to create the PIE objects in parallel. -3) `make batch-sharp-submit`: - Submits all the PIE objects under `src/single_chunk_processor/data/` to SHARP. Results, including job keys and facts, are saved to `src/single_chunk_processor/data/sharp_submit_results.json`. -4) `make batch-run-and-submit`: - Combines the processes of 1) and 3) into a single command. - - -Note : This is configured to be sent with the goerli public SHARP. It will work with small chunks of ~10 blocks at most. - - diff --git a/tools/make/build.sh b/tools/make/build.sh deleted file mode 100755 index 92c225d..0000000 --- a/tools/make/build.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -process_cairo_file() { - local cairo_file="$1" - local filename=$(basename "$cairo_file" .cairo) - local first_line=$(head -n 1 "$cairo_file") - - echo "Compiling $cairo_file using cairo-compile ..." - cairo-compile --cairo_path="packages/eth_essentials" "$cairo_file" --output "build/compiled_cairo_files/$filename.json" - - local status=$? - if [ $status -eq 0 ]; then - echo "$(date '+%Y-%m-%d %H:%M:%S') - Successfully compiled $1" - else - echo "$(date '+%Y-%m-%d %H:%M:%S') - Failed to compile $1" - return $status - fi -} - -export -f process_cairo_file - -# Use --halt now,fail=1 to return non-zero if any task fails -find ./src ./tests/cairo_programs -name "*.cairo" | parallel --halt now,fail=1 process_cairo_file - -# Capture the exit status of parallel -exit_status=$? - -# Exit with the captured status -echo "Parallel execution exited with status: $exit_status" -exit $exit_status diff --git a/tools/make/cairo_format_check.sh b/tools/make/cairo_format_check.sh deleted file mode 100755 index 3068772..0000000 --- a/tools/make/cairo_format_check.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Function to check a file formatting and print a message based on the outcome -format_file() { - cairo-format -c "$1" - local status=$? - if [ $status -eq 0 ]; then - echo "$(date '+%Y-%m-%d %H:%M:%S') - File $1 is formatted correctly" - else - echo "$(date '+%Y-%m-%d %H:%M:%S') - File $1 is not formatted correctly" - return $status - fi -} - -# Export the function so it's available in subshells -export -f format_file - -# Find all .cairo files under src/ and tests/ directories and format them in parallel -# Using --halt soon,fail=1 to stop at the first failure -find ./src ./tests -name '*.cairo' | parallel --halt soon,fail=1 format_file - -# Capture the exit status of parallel -exit_status=$? - -# Exit with the captured status -echo "Parallel execution exited with status: $exit_status" -exit $exit_status diff --git a/tools/make/cairo_tests.sh b/tools/make/cairo_tests.sh deleted file mode 100755 index f30e22c..0000000 --- a/tools/make/cairo_tests.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash - -run_tests() { - local cairo_file="$1" - local filename=$(basename "$cairo_file" .cairo) - local temp_output=$(mktemp) - - # Redirecting output to temp file for potential error capture - cairo-compile --cairo_path="packages/eth_essentials" "$cairo_file" --output "build/compiled_cairo_files/$filename.json" > "$temp_output" 2>&1 - cairo-run --program="build/compiled_cairo_files/$filename.json" --layout=starknet_with_keccak >> "$temp_output" 2>&1 - local status=$? - - if [ $status -eq 0 ]; then - echo "$(date '+%Y-%m-%d %H:%M:%S') - Test Successful $1" - else - echo "$(date '+%Y-%m-%d %H:%M:%S') - Test Failed $1" - cat "$temp_output" # Display the captured output on failure - rm -f "$temp_output" - return $status - fi - - rm -f "$temp_output" -} - -source venv/bin/activate - -# Export the function so it's available in subshells -export -f run_tests - -# Find all .cairo files under src/ and tests/ directories and format them in parallel -# Using --halt soon,fail=1 to stop at the first failure -find ./tests/cairo_programs -name '*.cairo' ! -name 'test_vectors.cairo' | parallel --halt soon,fail=1 run_tests - -# Capture the exit status of parallel -exit_status=$? - -# Exit with the captured status -echo "Parallel execution exited with status: $exit_status" -exit $exit_status \ No newline at end of file diff --git a/tools/make/ci_local.sh b/tools/make/ci_local.sh deleted file mode 100755 index 6de3273..0000000 --- a/tools/make/ci_local.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash -set -e - -# Start time -start_time=$SECONDS - -echo "Running CI Locally..." - -echo "Run Build Check..." -(source ./tools/make/build.sh) - -echo "Run Cairo Format Check..." -(source ./tools/make/cairo_format_check.sh) - -echo "Run Python Format Check..." -(source ./tools/make/python_format_check.sh) - -echo "Run Cairo Unit Tests..." -(source ./tools/make/cairo_tests.sh) - -echo "Run full flow test..." -(source ./tools/make/full_flow_test.sh) - -# End time -end_time=$SECONDS - -echo "All checks passed successfully!" - -# Calculate and print the total runtime -runtime=$((end_time - start_time)) -echo "Total local CI Runtime: $runtime seconds." \ No newline at end of file diff --git a/tools/make/format_cairo_files.sh b/tools/make/format_cairo_files.sh deleted file mode 100755 index a5ef56e..0000000 --- a/tools/make/format_cairo_files.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/bash - -# Function to format a file and print a message based on the outcome -format_file() { - cairo-format -i "$1" - local status=$? - if [ $status -eq 0 ]; then - echo "$(date '+%Y-%m-%d %H:%M:%S') - Successfully formatted $1" - else - echo "$(date '+%Y-%m-%d %H:%M:%S') - Failed to format $1" - return $status - fi -} - -# Export the function so it's available in subshells -export -f format_file - -# Find all .cairo files under src/ and tests/ directories and format them in parallel -# Using --halt soon,fail=1 to stop at the first failure -find ./src ./tests -name '*.cairo' | parallel --halt soon,fail=1 format_file - -# Capture the exit status of parallel -exit_status=$? - -# Exit with the captured status -echo "Parallel execution exited with status: $exit_status" -exit $exit_status diff --git a/tools/make/full_flow_test.sh b/tools/make/full_flow_test.sh deleted file mode 100755 index 1357983..0000000 --- a/tools/make/full_flow_test.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash - -# Activate virtual environment -source venv/bin/activate - -# Get the Cairo file from the command line argument -cairo_file="$1" -filename=$(basename "$cairo_file" .cairo) - -# Define the log file path incorporating the filename -LOG_FILE="full_flow_${filename}.log" - -# Ensure the log file exists, otherwise create it -touch "$LOG_FILE" - -# Export the log file path to be available in subshells -export LOG_FILE -export filename - -# Function to run tests on a given Cairo file -run_tests() { - local input_file="$1" - local temp_output=$(mktemp) - - # Attempt to run the compiled program and capture output - local start_time=$(date +%s) - cairo-run --program="build/compiled_cairo_files/hdp.json" --program_input=$input_file --layout=starknet_with_keccak >> "$temp_output" 2>&1 - local status=$? - local end_time=$(date +%s) - local duration=$((end_time - start_time)) - - if [ $status -eq 0 ]; then - echo "$(date '+%Y-%m-%d %H:%M:%S') - Successful $input_file: Duration ${duration} seconds" - else - echo "$(date '+%Y-%m-%d %H:%M:%S') - Failed: $input_file" - fi - - cat "$temp_output" >> "$LOG_FILE" - rm -f "$temp_output" # Clean up temporary file - return $status -} - -export -f run_tests - - -# Ensure the Cairo file is compiled before running parallel tests -echo "Compiling HDP Cairo file..." -cairo-compile --cairo_path="packages/eth_essentials" "src/hdp.cairo" --output "build/compiled_cairo_files/hdp.json" - -# Clone the repository if the directory doesn't exist -if [ ! -d "hdp-test" ]; then - git clone https://github.com/HerodotusDev/hdp-test -fi - -echo "Starting tests..." -find ./hdp-test/fixtures -name "input.json" | parallel run_tests $filename - -# Capture the exit status of parallel -exit_status=$? - -# Exit with the captured status -echo "Parallel execution exited with status: $exit_status" -exit $exit_status diff --git a/tools/make/fuzzer.sh b/tools/make/fuzzer.sh deleted file mode 100755 index 0095c00..0000000 --- a/tools/make/fuzzer.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash - -# Activate virtual environment -source venv/bin/activate - -# Get the Cairo file from the command line argument -cairo_file="$1" -filename=$(basename "$cairo_file" .cairo) - -# Define the log file path incorporating the filename -LOG_FILE="test_results_${filename}.log" - -# Ensure the log file exists, otherwise create it -touch "$LOG_FILE" - -# Export the log file path to be available in subshells -export LOG_FILE -export filenname - -# Function to run tests on a given Cairo file -run_tests() { - cairo_file="$1" - filename=$(basename "$cairo_file" .cairo) - local temp_output=$(mktemp) - - # Attempt to run the compiled program and capture output - local start_time=$(date +%s) - cairo-run --program="build/compiled_cairo_files/$filename.json" --layout=starknet_with_keccak >> "$temp_output" 2>&1 - local status=$? - local end_time=$(date +%s) - local duration=$((end_time - start_time)) - - # Handle output based on success or failure - if [ $status -eq 0 ]; then - echo "$(date '+%Y-%m-%d %H:%M:%S') - Test Successful: Duration ${duration} seconds" - else - echo "$(date '+%Y-%m-%d %H:%M:%S') - Test Failed: Duration ${duration} seconds" - cat "$temp_output" # Output the error to the console - fi - - cat "$temp_output" >> "$LOG_FILE" - rm -f "$temp_output" # Clean up temporary file - return $status -} - -# Ensure the Cairo file is compiled before running parallel tests -cairo-compile --cairo_path="packages/eth_essentials" "$cairo_file" --output "build/compiled_cairo_files/$filename.json" - -# Export the function so it's accessible to subshells spawned by parallel -export -f run_tests - -# Determine the number of available cores -N=6 -echo "Using $N cores for parallel execution." - -# Run the same test file repeatedly, maintaining N parallel instances -seq inf | parallel -j$N --halt soon,fail=1 run_tests $cairo_file - -# Capture and return the exit status of parallel -exit_status=$? -echo "Parallel execution exited with status: $exit_status" -exit $exit_status diff --git a/tools/make/launch_cairo_files.py b/tools/make/launch_cairo_files.py deleted file mode 100755 index 822f566..0000000 --- a/tools/make/launch_cairo_files.py +++ /dev/null @@ -1,205 +0,0 @@ -#!venv/bin/python3 -import os -import readline -import argparse -import inquirer -from tools.py.utils import create_directory, get_files_from_folders - -# Constants -CAIRO_PROGRAMS_FOLDERS = ["tests/cairo_programs/", "src/"] - -BUILD_DIR = "build" -PROFILING_DIR = os.path.join(BUILD_DIR, "profiling") -COMPILED_FILES_DIR = os.path.join(BUILD_DIR, "compiled_cairo_files") - - -class CairoRunner: - def __init__(self): - self.cairo_programs = get_files_from_folders(CAIRO_PROGRAMS_FOLDERS, ".cairo") - self.filename_dot_cairo_path = "" - self.filename_dot_cairo = "" - self.json_input_path = "" - self.filename = "" - self.args = self.parse_arguments() - create_directory(BUILD_DIR) - create_directory(COMPILED_FILES_DIR) - create_directory(PROFILING_DIR) - - @staticmethod - def parse_arguments(): - parser = argparse.ArgumentParser( - description="A tool for running cairo programs." - ) - parser.add_argument( - "-profile", action="store_true", help="Enable pprof profile" - ) - parser.add_argument("-pie", action="store_true", help="Create PIE object") - parser.add_argument("-test", action="store_true", help="Run all tests") - parser.add_argument("-test_hdp", action="store_true", help="Run hdp tests") - parser.add_argument("-run_hdp", action="store_true", help="Run HDP") - return parser.parse_args() - - def setup_autocomplete(self): - """Set up readline autocomplete with available Cairo program names.""" - # Splitting paths and basenames for easier searching. - base_names = [os.path.basename(x) for x in self.cairo_programs] - - def completer(text, state): - suggestions = [name for name in base_names if name.startswith(text)] - try: - suggestion = suggestions[state] - return suggestion - except IndexError: - return None - - readline.parse_and_bind("tab: complete") - readline.set_completer(completer) - - def prompt_for_cairo_file(self): - """Prompt the user to select a Cairo file to run.""" - self.setup_autocomplete() - - while True: - self.filename_dot_cairo = input( - "\n>>> Enter .cairo file name or press for suggestions:\n\n" - ) - - if self._is_cairo_file_valid(): - self._handle_special_file_cases() - self.filename = self.filename_dot_cairo.removesuffix(".cairo") - return - else: - print( - f"### File '{self.filename_dot_cairo}' not found in the Cairo programs folders." - ) - - def _is_cairo_file_valid(self): - """Check if the provided Cairo file name is valid.""" - for cairo_path in self.cairo_programs: - if cairo_path.endswith(self.filename_dot_cairo): - self.filename_dot_cairo_path = cairo_path - return True - return False - - def _handle_special_file_cases(self): - """Set specific JSON input paths for special Cairo file cases.""" - - if self.filename_dot_cairo == "chunk_processor.cairo": - self._select_input_file("src/single_chunk_processor/data") - else: - self._set_default_json_input_path() - - print(f"Selected JSON file: {self.json_input_path}") - - def _select_input_file(self, json_files_dir): - """Allow the user to select an input JSON file for the chunk processor.""" - json_files = [ - f for f in os.listdir(json_files_dir) if f.endswith("_input.json") - ] - - if not json_files: - print("### No JSON files found.") - return - - questions = [inquirer.List("file", message="Choose a file", choices=json_files)] - selected_file = inquirer.prompt(questions)["file"] - self.json_input_path = os.path.join(json_files_dir, selected_file) - - def _set_default_json_input_path(self): - """Set the default JSON input path based on the Cairo file name.""" - self.json_input_path = self.filename_dot_cairo_path.replace( - ".cairo", "_input.json" - ) - - def compile_cairo_file(self): - while True: - print(f"Compiling {self.filename_dot_cairo} ... ") - compiled_path = os.path.join(COMPILED_FILES_DIR, f"{self.filename}.json") - return_code = os.system( - f"cairo-compile --cairo_path='packages/eth_essentials' {self.filename_dot_cairo_path} --output {compiled_path} --proof_mode" - ) - - if return_code == 0: - return compiled_path - print(f"### Compilation failed. Please fix the errors and try again.") - self.prompt_for_cairo_file() - - def construct_run_command(self, compiled_path): - cmd_base = f"cairo-run --program={compiled_path} --layout=starknet_with_keccak" - input_flag = ( - f" --program_input={self.json_input_path} --print_output" - if os.path.exists(self.json_input_path) - else "" - ) - profile_flag = ( - f" --profile_output {PROFILING_DIR}/{self.filename}/profile.pb.gz" - if self.args.profile - else " --print_info" - ) - pie_flag = ( - f" --cairo_pie_output {PROFILING_DIR}/{self.filename}/{self.filename}_pie.zip" - if self.args.pie - else "" - ) - return f"{cmd_base}{input_flag}{profile_flag}{pie_flag}" - - def run_hdp(self): - self.filename_dot_cairo_path = "src/hdp.cairo" - compiled_path = self.compile_cairo_file() - cmd_base = f"cairo-run --program={compiled_path} --layout=starknet_with_keccak --program_input=src/hdp_input.json --print_output" - os.system(cmd_base) - - def run(self): - self.prompt_for_cairo_file() - print(f"Selected Cairo file: {self.filename_dot_cairo_path}") - create_directory(f"{PROFILING_DIR}/{self.filename}") - - compiled_path = self.compile_cairo_file() - run_command = self.construct_run_command(compiled_path) - os.system(run_command) - - if self.args.profile: - self.run_profiling_tool() - - def test(self): - """Run all tests.""" - tests_files = get_files_from_folders(["tests/cairo_programs"], ".cairo") - for test_file in tests_files: - if test_file == "tests/cairo_programs/test_vectors.cairo": - continue - - # if test_file != "tests/cairo_programs/txs_in_block_datalake.cairo": - # continue - - self.filename_dot_cairo_path = test_file - self.filename_dot_cairo = os.path.basename(test_file) - self.filename = self.filename_dot_cairo.removesuffix(".cairo") - self.compile_cairo_file() - run_command = self.construct_run_command( - os.path.join(COMPILED_FILES_DIR, f"{self.filename}.json") - ) - return_code = os.system(run_command) - if return_code != 0: - print(f"### Test {self.filename_dot_cairo} failed.") - print(f"### Aborting tests.") - return - else: - print(f"Test {self.filename_dot_cairo} passed.") - print(f"All tests passed.") - - def run_profiling_tool(self): - """Run the profiling tool for the selected Cairo file.""" - print(f"Running profiling tool for {self.filename_dot_cairo} ... ") - os.system( - f"cd {PROFILING_DIR}/{self.filename} && go tool pprof -png profile.pb.gz" - ) - - -if __name__ == "__main__": - x = CairoRunner() - if x.args.test: - x.test() - elif x.args.run_hdp: - x.run_hdp() - else: - x.run() diff --git a/tools/make/python_format_check.sh b/tools/make/python_format_check.sh deleted file mode 100755 index b423be3..0000000 --- a/tools/make/python_format_check.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -black --check . \ No newline at end of file diff --git a/tools/make/requirements.txt b/tools/make/requirements.txt deleted file mode 100644 index 3cbefb4..0000000 --- a/tools/make/requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -cairo-lang==0.13.1 -typeguard==2.13.3 -protobuf==3.20.3 -inquirer -python-dotenv -pysha3 -web3 -trie -black \ No newline at end of file diff --git a/tools/make/setup.sh b/tools/make/setup.sh deleted file mode 100755 index cae354a..0000000 --- a/tools/make/setup.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/bash - -VENV_PATH=${1:-venv} - -echo "Setting up virtual environment at $VENV_PATH" - -# Function to install GNU parallel -install_parallel() { - case "$OSTYPE" in - linux-gnu*) - # Linux - if command -v apt-get >/dev/null; then - # Debian/Ubuntu - sudo apt-get update && sudo apt-get install -y parallel - elif command -v dnf >/dev/null; then - # Fedora - sudo dnf install -y parallel - else - echo "Unsupported Linux distribution for automatic parallel installation." - exit 1 - fi - ;; - darwin*) - # macOS - if command -v brew >/dev/null; then - brew install parallel - else - echo "Homebrew is not installed. Please install Homebrew and try again." - exit 1 - fi - ;; - *) - echo "Unsupported operating system for automatic parallel installation." - exit 1 - ;; - esac -} - -# Check if parallel is installed, if not, attempt to install it -if ! command -v parallel >/dev/null; then - echo "GNU parallel not found. Attempting to install..." - install_parallel -else - echo "GNU parallel is already installed." -fi - -# Your existing setup script continues here... -python3.9 -m venv "$VENV_PATH" -echo 'export PYTHONPATH="$PWD:$PYTHONPATH"' >> "$VENV_PATH/bin/activate" -source "$VENV_PATH/bin/activate" -pip install -r tools/make/requirements.txt -git submodule init -git submodule update \ No newline at end of file diff --git a/tools/py/block_header.py b/tools/py/block_header.py deleted file mode 100644 index f567ff1..0000000 --- a/tools/py/block_header.py +++ /dev/null @@ -1,219 +0,0 @@ -from hexbytes.main import HexBytes -from rlp import Serializable, encode -from web3.types import BlockData -from rlp.sedes import ( - BigEndianInt, - big_endian_int, - Binary, - binary, -) -from web3 import Web3 -from typing import Union - - -address = Binary.fixed_length(20, allow_empty=True) -hash32 = Binary.fixed_length(32) -int256 = BigEndianInt(256) -trie_root = Binary.fixed_length(32, allow_empty=True) - - -class BlockHeader(Serializable): - fields = ( - ("parentHash", hash32), - ("unclesHash", hash32), - ("coinbase", address), - ("stateRoot", trie_root), - ("transactionsRoot", trie_root), - ("receiptsRoot", trie_root), - ("logsBloom", int256), - ("difficulty", big_endian_int), - ("number", big_endian_int), - ("gasLimit", big_endian_int), - ("gasUsed", big_endian_int), - ("timestamp", big_endian_int), - ("extraData", binary), - ("mixHash", binary), - ("nonce", Binary(8, allow_empty=True)), - ) - - def hash(self) -> HexBytes: - _rlp = encode(self) - return Web3.keccak(_rlp) - - def raw_rlp(self) -> bytes: - return encode(self) - - -class BlockHeaderEIP1559(Serializable): - fields = ( - ("parentHash", hash32), - ("unclesHash", hash32), - ("coinbase", address), - ("stateRoot", trie_root), - ("transactionsRoot", trie_root), - ("receiptsRoot", trie_root), - ("logsBloom", int256), - ("difficulty", big_endian_int), - ("number", big_endian_int), - ("gasLimit", big_endian_int), - ("gasUsed", big_endian_int), - ("timestamp", big_endian_int), - ("extraData", binary), - ("mixHash", binary), - ("nonce", Binary(8, allow_empty=True)), - ("baseFeePerGas", big_endian_int), - ) - - def hash(self) -> HexBytes: - _rlp = encode(self) - return Web3.keccak(_rlp) - - def raw_rlp(self) -> bytes: - return encode(self) - - -class BlockHeaderShangai(Serializable): - fields = ( - ("parentHash", hash32), - ("unclesHash", hash32), - ("coinbase", address), - ("stateRoot", trie_root), - ("transactionsRoot", trie_root), - ("receiptsRoot", trie_root), - ("logsBloom", int256), - ("difficulty", big_endian_int), - ("number", big_endian_int), - ("gasLimit", big_endian_int), - ("gasUsed", big_endian_int), - ("timestamp", big_endian_int), - ("extraData", binary), - ("mixHash", binary), - ("nonce", Binary(8, allow_empty=True)), - ("baseFeePerGas", big_endian_int), - ("withdrawalsRoot", trie_root), - ) - - def hash(self) -> HexBytes: - _rlp = encode(self) - return Web3.keccak(_rlp) - - def raw_rlp(self) -> bytes: - return encode(self) - - -class BlockHeaderDencun(Serializable): - fields = ( - ("parentHash", hash32), - ("unclesHash", hash32), - ("coinbase", address), - ("stateRoot", trie_root), - ("transactionsRoot", trie_root), - ("receiptsRoot", trie_root), - ("logsBloom", int256), - ("difficulty", big_endian_int), - ("number", big_endian_int), - ("gasLimit", big_endian_int), - ("gasUsed", big_endian_int), - ("timestamp", big_endian_int), - ("extraData", binary), - ("mixHash", binary), - ("nonce", Binary(8, allow_empty=True)), - ("baseFeePerGas", big_endian_int), - ("withdrawalsRoot", trie_root), - ("blobGasUsed", big_endian_int), - ("excessBlobGas", big_endian_int), - ("parentBeaconBlockRoot", binary), - ) - - def hash(self) -> HexBytes: - _rlp = encode(self) - return Web3.keccak(_rlp) - - def raw_rlp(self) -> bytes: - return encode(self) - - -def build_block_header( - block: BlockData, -) -> Union[BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai]: - if "excessBlobGas" in block.keys(): - header = BlockHeaderDencun( - HexBytes(block["parentHash"]), - HexBytes(block["sha3Uncles"]), - bytearray.fromhex(block["miner"][2:]), - HexBytes(block["stateRoot"]), - HexBytes(block["transactionsRoot"]), - HexBytes(block["receiptsRoot"]), - int.from_bytes(HexBytes(block["logsBloom"]), "big"), - int(block["difficulty"], 16), - int(block["number"], 16), - int(block["gasLimit"], 16), - int(block["gasUsed"], 16), - int(block["timestamp"], 16), - HexBytes(block["extraData"]), - HexBytes(block["mixHash"]), - HexBytes(block["nonce"]), - int(block["baseFeePerGas"], 16), - HexBytes(block["withdrawalsRoot"]), - int(block["blobGasUsed"], 16), - int(block["excessBlobGas"], 16), - HexBytes(block["parentBeaconBlockRoot"]), - ) - elif "withdrawalsRoot" in block.keys(): - header = BlockHeaderShangai( - HexBytes(block["parentHash"]), - HexBytes(block["sha3Uncles"]), - bytearray.fromhex(block["miner"][2:]), - HexBytes(block["stateRoot"]), - HexBytes(block["transactionsRoot"]), - HexBytes(block["receiptsRoot"]), - int.from_bytes(HexBytes(block["logsBloom"]), "big"), - int(block["difficulty"], 16), - int(block["number"], 16), - int(block["gasLimit"], 16), - int(block["gasUsed"], 16), - int(block["timestamp"], 16), - HexBytes(block["extraData"]), - HexBytes(block["mixHash"]), - HexBytes(block["nonce"]), - int(block["baseFeePerGas"], 16), - HexBytes(block["withdrawalsRoot"]), - ) - elif "baseFeePerGas" in block.keys(): - header = BlockHeaderEIP1559( - HexBytes(block["parentHash"]), - HexBytes(block["sha3Uncles"]), - bytearray.fromhex(block["miner"][2:]), - HexBytes(block["stateRoot"]), - HexBytes(block["transactionsRoot"]), - HexBytes(block["receiptsRoot"]), - int.from_bytes(HexBytes(block["logsBloom"]), "big"), - int(block["difficulty"], 16), - int(block["number"], 16), - int(block["gasLimit"], 16), - int(block["gasUsed"], 16), - int(block["timestamp"], 16), - HexBytes(block["extraData"]), - HexBytes(block["mixHash"]), - HexBytes(block["nonce"]), - int(block["baseFeePerGas"], 16), - ) - else: - header = BlockHeader( - HexBytes(block["parentHash"]), - HexBytes(block["sha3Uncles"]), - bytearray.fromhex(block["miner"][2:]), - HexBytes(block["stateRoot"]), - HexBytes(block["transactionsRoot"]), - HexBytes(block["receiptsRoot"]), - int.from_bytes(HexBytes(block["logsBloom"]), "big"), - int(block["difficulty"], 16), - int(block["number"], 16), - int(block["gasLimit"], 16), - int(block["gasUsed"], 16), - int(block["timestamp"], 16), - HexBytes(block["extraData"]), - HexBytes(block["mixHash"]), - HexBytes(block["nonce"]), - ) - return header diff --git a/tools/py/fetch_block_headers.py b/tools/py/fetch_block_headers.py deleted file mode 100644 index 62946d8..0000000 --- a/tools/py/fetch_block_headers.py +++ /dev/null @@ -1,80 +0,0 @@ -import time -import math -import json -from typing import Union, List -from tools.py.utils import rpc_request - -from tools.py.block_header import ( - build_block_header, - BlockHeader, - BlockHeaderEIP1559, - BlockHeaderShangai, - BlockHeaderDencun, -) - -RPC_BATCH_MAX_SIZE = 1450 - - -def fetch_blocks_from_rpc_no_async( - range_from: int, range_till: int, rpc_url: str, delay=0.1 -) -> List[ - Union[BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai, BlockHeaderDencun] -]: - """ - # Fetches blocks from RPC in batches of RPC_BATCH_MAX_SIZE - # Returns a list of block headers - # Params: - # range_from: int - the block number to start fetching from - # range_till: int - the block number to stop fetching at - # rpc_url: str - the RPC url to fetch from - # delay: float - delay between RPC requests (in seconds) - # Returns: - # list - a list of block headers of type BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai or BlockHeaderDencun - """ - assert range_from > range_till, "Invalid range" - number_of_blocks = range_from - range_till - rpc_batches_amount = math.ceil(number_of_blocks / RPC_BATCH_MAX_SIZE) - last_batch_size = number_of_blocks % RPC_BATCH_MAX_SIZE - - all_results = [] - - for i in range(1, rpc_batches_amount + 1): - current_batch_size = ( - last_batch_size - if (i == rpc_batches_amount and last_batch_size) - else RPC_BATCH_MAX_SIZE - ) - requests = list( - map( - lambda j: { - "jsonrpc": "2.0", - "method": "eth_getBlockByNumber", - "params": [ - hex(range_from - (i - 1) * RPC_BATCH_MAX_SIZE - j), - False, - ], - "id": str(j), - }, - range(0, current_batch_size), - ) - ) - - # Send all requests in the current batch in a single HTTP request - results = rpc_request(rpc_url, requests) - # print(results) - for result in results: - block_header: Union[ - BlockHeader, BlockHeaderEIP1559, BlockHeaderShangai, BlockHeaderDencun - ] = build_block_header(result["result"]) - all_results.append(block_header) - - time.sleep(delay) # Add delay - time.sleep(delay) # Add delay - return all_results - - -def get_block_header(number: int, RPC_URL: str): - blocks = fetch_blocks_from_rpc_no_async(number + 1, number - 1, RPC_URL) - block = blocks[1] - assert block.number == number, f"Block number mismatch {block.number} != {number}" - return block diff --git a/tools/py/fetch_tx.py b/tools/py/fetch_tx.py deleted file mode 100644 index 3ad9f35..0000000 --- a/tools/py/fetch_tx.py +++ /dev/null @@ -1,54 +0,0 @@ -import time -import math -import json -from typing import Union, List -from tools.py.utils import rpc_request - -from tools.py.transaction import LegacyTx, Eip155, Eip1559, Eip2930, Eip4844, build_tx - - -def fetch_block_tx_ids_from_rpc(block_number: int, rpc_url: str) -> List[str]: - result = rpc_request( - rpc_url, - { - "jsonrpc": "2.0", - "id": 1, - "method": "eth_getBlockByNumber", - "params": [hex(block_number), False], - }, - ) - - tx_ids = [tx for tx in result["result"]["transactions"]] - return tx_ids - - -def fetch_latest_block_height_from_rpc(rpc_url: str) -> int: - result = rpc_request( - rpc_url, - { - "jsonrpc": "2.0", - "id": 1, - "method": "eth_blockNumber", - "params": [], - }, - ) - - return int(result["result"], 16) - - -def fetch_tx_from_rpc( - tx_hash: str, rpc_url: str -) -> Union[LegacyTx, Eip155, Eip1559, Eip2930, Eip4844]: - result = rpc_request( - rpc_url, - { - "jsonrpc": "2.0", - "id": 1, - "method": "eth_getTransactionByHash", - "params": [tx_hash], - }, - ) - - tx: Union[LegacyTx, Eip155, Eip1559, Eip2930, Eip4844] = build_tx(result["result"]) - # print(tx.raw_rlp().hex()) - return tx diff --git a/tools/py/transaction.py b/tools/py/transaction.py deleted file mode 100644 index a1fa1ea..0000000 --- a/tools/py/transaction.py +++ /dev/null @@ -1,404 +0,0 @@ -from hexbytes.main import HexBytes -from rlp import Serializable, encode -from web3.types import BlockData, SignedTx -from rlp.sedes import BigEndianInt, big_endian_int, Binary, binary, lists, CountableList -from web3 import Web3 -from typing import Union - - -address = Binary.fixed_length(20, allow_empty=True) -hash32 = Binary.fixed_length(32) -int256 = BigEndianInt(256) -trie_root = Binary.fixed_length(32, allow_empty=True) - - -class LegacyTx(Serializable): - fields = ( - ("nonce", big_endian_int), - ("gas_price", big_endian_int), - ("gas_limit", big_endian_int), - ("to", address), - ("value", big_endian_int), - ("data", binary), - ("v", big_endian_int), - ("r", hash32), - ("s", hash32), - ("sender", address), - ("type", big_endian_int), - ("block_number", big_endian_int), - ) - - def hash(self) -> HexBytes: - return Web3.keccak(self.raw_rlp()) - - def raw_rlp(self) -> bytes: - return encode( - [ - self.nonce, - self.gas_price, - self.gas_limit, - self.to, - self.value, - self.data, - self.v, - self.r, - self.s, - ] - ) - - def signed_rlp(self) -> bytes: - return encode( - [self.nonce, self.gas_price, self.gas_limit, self.to, self.value, self.data] - ) - - -class Eip155(Serializable): - fields = ( - ("nonce", big_endian_int), - ("gas_price", big_endian_int), - ("gas_limit", big_endian_int), - ("to", address), - ("value", big_endian_int), - ("data", binary), - ("v", big_endian_int), - ("r", hash32), - ("s", hash32), - ("chain_id", big_endian_int), - ("sender", address), - ("type", big_endian_int), - ("block_number", big_endian_int), - ) - - def hash(self) -> HexBytes: - return Web3.keccak(self.raw_rlp()) - - def raw_rlp(self) -> bytes: - return encode( - [ - self.nonce, - self.gas_price, - self.gas_limit, - self.to, - self.value, - self.data, - self.v, - self.r, - self.s, - ] - ) - - def signed_rlp(self) -> bytes: - return encode( - [ - self.nonce, - self.gas_price, - self.gas_limit, - self.to, - self.value, - self.data, - self.chain_id, - 0, - 0, - ] - ) - - -# Define a Serializable class for an Access List entry -class AccessListEntry(Serializable): - fields = [("address", address), ("storage_keys", CountableList(hash32))] - - -# Define the access list using CountableList of AccessListEntry -access_list_type = CountableList(AccessListEntry) - - -class Eip2930(Serializable): - fields = ( - ("chain_id", big_endian_int), - ("nonce", big_endian_int), - ("gas_price", big_endian_int), - ("gas_limit", big_endian_int), - ("to", address), - ("value", big_endian_int), - ("data", binary), - ("access_list", access_list_type), - ("v", big_endian_int), - ("r", hash32), - ("s", hash32), - ("sender", address), - ("type", big_endian_int), - ("block_number", big_endian_int), - ) - - def hash(self) -> HexBytes: - return Web3.keccak(self.raw_rlp()) - - def raw_rlp(self) -> bytes: - return bytes.fromhex("01") + encode( - [ - self.chain_id, - self.nonce, - self.gas_price, - self.gas_limit, - self.to, - self.value, - self.data, - self.access_list, - self.v, - self.r, - self.s, - ] - ) - - def signed_rlp(self) -> bytes: - return encode( - [ - self.chain_id, - self.nonce, - self.gas_price, - self.gas_limit, - self.to, - self.value, - self.data, - self.access_list, - ] - ) - - -class Eip1559(Serializable): - fields = ( - ("chain_id", big_endian_int), - ("nonce", big_endian_int), - ("max_priority_fee_per_gas", big_endian_int), - ("max_fee_per_gas", big_endian_int), - ("gas_limit", big_endian_int), - ("to", address), - ("value", big_endian_int), - ("data", binary), - ("access_list", access_list_type), - ("v", big_endian_int), - ("r", hash32), - ("s", hash32), - ("sender", address), - ("type", big_endian_int), - ("block_number", big_endian_int), - ) - - def hash(self) -> HexBytes: - return Web3.keccak(self.raw_rlp()) - - def raw_rlp(self) -> bytes: - return bytes.fromhex("02") + encode( - [ - self.chain_id, - self.nonce, - self.max_priority_fee_per_gas, - self.max_fee_per_gas, - self.gas_limit, - self.to, - self.value, - self.data, - self.access_list, - self.v, - self.r, - self.s, - ] - ) - - def signed_rlp(self) -> bytes: - return encode( - [ - self.chain_id, - self.nonce, - self.max_priority_fee_per_gas, - self.max_fee_per_gas, - self.gas_limit, - self.to, - self.value, - self.data, - self.access_list, - ] - ) - - -class Eip4844(Serializable): - fields = ( - ("chain_id", big_endian_int), - ("nonce", big_endian_int), - ("max_priority_fee_per_gas", big_endian_int), - ("max_fee_per_gas", big_endian_int), - ("gas_limit", big_endian_int), - ("to", address), - ("value", big_endian_int), - ("data", binary), - ("access_list", access_list_type), - ("max_fee_per_blob_gas", big_endian_int), - ("blob_versioned_hashes", lists.CountableList(hash32)), - ("v", big_endian_int), - ("r", hash32), - ("s", hash32), - ("sender", address), - ("type", big_endian_int), - ("block_number", big_endian_int), - ) - - def hash(self) -> HexBytes: - return Web3.keccak(self.raw_rlp()) - - def raw_rlp(self) -> bytes: - return bytes.fromhex("03") + encode( - [ - self.chain_id, - self.nonce, - self.max_priority_fee_per_gas, - self.max_fee_per_gas, - self.gas_limit, - self.to, - self.value, - self.data, - self.access_list, - self.max_fee_per_blob_gas, - self.blob_versioned_hashes, - self.v, - self.r, - self.s, - ] - ) - - def signed_rlp(self) -> bytes: - return encode( - [ - self.chain_id, - self.nonce, - self.max_priority_fee_per_gas, - self.max_fee_per_gas, - self.gas_limit, - self.to, - self.value, - self.data, - self.access_list, - self.max_fee_per_blob_gas, - self.blob_versioned_hashes, - ] - ) - - -def build_tx(tx: SignedTx) -> Union[LegacyTx]: - # print(tx) - receiver = "" if tx["to"] is None else tx["to"] # for contract creation txs - tx_type = ( - "0x0" if "type" not in tx else tx["type"] - ) # for some TXs RPC doesnt return type - if tx_type == "0x0": - if int(tx["blockNumber"], 16) < 2675000: - return LegacyTx( - int(tx["nonce"], 16), - int(tx["gasPrice"], 16), - int(tx["gas"], 16), - HexBytes(receiver), - int(tx["value"], 16), - HexBytes(tx["input"]), - int(tx["v"], 16), - HexBytes(tx["r"]), - HexBytes(tx["s"]), - HexBytes(tx["from"]), - int(tx_type, 16), - int(tx["blockNumber"], 16), - ) - else: - # EIP-155 tx - return Eip155( - int(tx["nonce"], 16), - int(tx["gasPrice"], 16), - int(tx["gas"], 16), - HexBytes(receiver), - int(tx["value"], 16), - HexBytes(tx["input"]), - int(tx["v"], 16), - HexBytes(tx["r"]), - HexBytes(tx["s"]), - 1, - HexBytes(tx["from"]), - int(tx_type, 16), - int(tx["blockNumber"], 16), - ) - elif tx_type == "0x1": - # EIP-2930 tx - access_list = [ - AccessListEntry( - address=HexBytes(entry["address"]), - storage_keys=[HexBytes(key) for key in entry["storageKeys"]], - ) - for entry in tx["accessList"] - ] - return Eip2930( - int(tx["chainId"], 16), - int(tx["nonce"], 16), - int(tx["gasPrice"], 16), - int(tx["gas"], 16), - HexBytes(receiver), - int(tx["value"], 16), - HexBytes(tx["input"]), - access_list, - int(tx["v"], 16), - HexBytes(tx["r"]), - HexBytes(tx["s"]), - HexBytes(tx["from"]), - int(tx_type, 16), - int(tx["blockNumber"], 16), - ) - elif tx_type == "0x2": - # print("1559") - access_list = [ - AccessListEntry( - address=HexBytes(entry["address"]), - storage_keys=[HexBytes(key) for key in entry["storageKeys"]], - ) - for entry in tx["accessList"] - ] - # EIP-1559 tx - return Eip1559( - int(tx["chainId"], 16), - int(tx["nonce"], 16), - int(tx["maxPriorityFeePerGas"], 16), - int(tx["maxFeePerGas"], 16), - int(tx["gas"], 16), - HexBytes(receiver), - int(tx["value"], 16), - HexBytes(tx["input"]), - access_list, - int(tx["v"], 16), - HexBytes(tx["r"]), - HexBytes(tx["s"]), - HexBytes(tx["from"]), - int(tx_type, 16), - int(tx["blockNumber"], 16), - ) - else: - # EIP-4844 tx - access_list = [ - AccessListEntry( - address=HexBytes(entry["address"]), - storage_keys=[HexBytes(key) for key in entry["storageKeys"]], - ) - for entry in tx["accessList"] - ] - return Eip4844( - int(tx["chainId"], 16), - int(tx["nonce"], 16), - int(tx["maxPriorityFeePerGas"], 16), - int(tx["maxFeePerGas"], 16), - int(tx["gas"], 16), - HexBytes(receiver), - int(tx["value"], 16), - HexBytes(tx["input"]), - access_list, - int(tx["maxFeePerBlobGas"], 16), - [HexBytes(hash32) for hash32 in tx["blobVersionedHashes"]], - int(tx["v"], 16), - HexBytes(tx["r"]), - HexBytes(tx["s"]), - HexBytes(tx["from"]), - int(tx_type, 16), - int(tx["blockNumber"], 16), - )