From 2e1f58378c70e0ead3d50d638c602dc19033dfbb Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 12:07:03 +0200 Subject: [PATCH 01/14] Add storage values to fixtures --- .../lib/src/account_with_storage_int_test.nr | 45 +++++++++++-------- .../paris/bored_ape_yacht_club/storage.nr | 6 +++ .../mainnet/paris/usdc_circle/storage.nr | 6 +++ .../mainnet/paris/usdc_uniswap/storage.nr | 6 +++ .../circuits/lib/src/serialize_test.nr | 5 +-- .../src/script/noir_fixtures/storage.ts | 8 ++++ 6 files changed, 54 insertions(+), 22 deletions(-) diff --git a/ethereum_history_api/circuits/lib/src/account_with_storage_int_test.nr b/ethereum_history_api/circuits/lib/src/account_with_storage_int_test.nr index 24ee277b8..612058481 100644 --- a/ethereum_history_api/circuits/lib/src/account_with_storage_int_test.nr +++ b/ethereum_history_api/circuits/lib/src/account_with_storage_int_test.nr @@ -4,10 +4,10 @@ use crate::account_with_storage::{StorageProof, get_account_with_storage}; use crate::fixtures::mainnet::{ paris::{ usdc_circle::{ - header::{number, state_root, block_header_partial, block_header_rlp}, account::account, - state_proof::state_proof, storage_proof::proofs + header::{number, block_header_partial, block_header_rlp}, account::{account, address}, + state_proof::state_proof, storage_proof::proofs, storage::{values, keys as storage_keys} }, - usdc_uniswap::{storage_proof::proofs as usdc_uniswap_proofs} + usdc_uniswap::{storage::keys as usdc_uniswap_storage_keys} }, london::{ crypto_punks::{ @@ -15,7 +15,8 @@ use crate::fixtures::mainnet::{ block_header_partial as crypto_punks_block_header_partial, block_header_rlp as crypto_punks_block_header_rlp, number as crypto_punks_number }, - account::account as crypto_punks_account, state_proof::state_proof as crypto_punks_state_proof + account::{address as crypto_punks_address, account as crypto_punks_account}, + state_proof::state_proof as crypto_punks_state_proof } } }; @@ -26,9 +27,7 @@ fn test_get_account_with_storage_success() { let _ = OracleMock::mock("get_header").returns((block_header_partial, block_header_rlp)); let _ = OracleMock::mock("get_proof").returns((account, state_proof, proofs[0])); - let address = state_proof.key; - let storage_key = proofs[0].key; - let account_with_storage = get_account_with_storage(ETHEREUM_MAINNET_ID, number, address, storage_key); + let account_with_storage = get_account_with_storage(ETHEREUM_MAINNET_ID, number, address, storage_keys[0]); assert_eq(block_header_partial.hash, account_with_storage.block_hash); @@ -37,18 +36,20 @@ fn test_get_account_with_storage_success() { assert_eq(account.code_hash, account_with_storage.account.code_hash); assert_eq(account.storage_root, account_with_storage.account.storage_root); - assert_eq(proofs[0].value, account_with_storage.values[0]); + assert_eq(values[0], account_with_storage.values[0]); } -// TODO: Add a failure message for the tests once the enhancements in PR https://github.com/aragonzkresearch/noir-trie-proofs/pull/15 are integrated. -#[test(should_fail)] +#[test(should_fail_with = "Internal node hash does not match the hash extracted from the preceding node")] fn test_get_account_with_storage_invalid_state_root() { let _ = OracleMock::mock("get_header").returns((crypto_punks_block_header_partial, crypto_punks_block_header_rlp)); let _ = OracleMock::mock("get_proof").returns((account, state_proof, proofs[0])); - let address = state_proof.key; - let storage_key = proofs[0].key; - let _ = get_account_with_storage(ETHEREUM_MAINNET_ID, crypto_punks_number, address, storage_key); + let _ = get_account_with_storage( + ETHEREUM_MAINNET_ID, + crypto_punks_number, + address, + storage_keys[0] + ); } #[test(should_fail_with = "Internal node hash does not match the hash extracted from the preceding node")] @@ -56,9 +57,12 @@ fn test_get_account_with_storage_invalid_storage_root() { let _ = OracleMock::mock("get_header").returns((crypto_punks_block_header_partial, crypto_punks_block_header_rlp)); let _ = OracleMock::mock("get_proof").returns((crypto_punks_account, crypto_punks_state_proof, proofs[0])); - let address = crypto_punks_state_proof.key; - let storage_key = proofs[0].key; - let _ = get_account_with_storage(ETHEREUM_MAINNET_ID, crypto_punks_number, address, storage_key); + let _ = get_account_with_storage( + ETHEREUM_MAINNET_ID, + crypto_punks_number, + crypto_punks_address, + storage_keys[0] + ); } #[test(should_fail_with = "Storage key does not match the argument")] @@ -66,7 +70,10 @@ fn test_get_account_with_storage_storage_key_does_not_match_the_argument() { let _ = OracleMock::mock("get_header").returns((block_header_partial, block_header_rlp)); let _ = OracleMock::mock("get_proof").returns((account, state_proof, proofs[0])); - let address = state_proof.key; - let storage_key = usdc_uniswap_proofs[0].key; - let _ = get_account_with_storage(ETHEREUM_MAINNET_ID, number, address, storage_key); + let _ = get_account_with_storage( + ETHEREUM_MAINNET_ID, + number, + address, + usdc_uniswap_storage_keys[0] + ); } diff --git a/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/bored_ape_yacht_club/storage.nr b/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/bored_ape_yacht_club/storage.nr index 333d31454..404715024 100644 --- a/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/bored_ape_yacht_club/storage.nr +++ b/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/bored_ape_yacht_club/storage.nr @@ -3,3 +3,9 @@ global keys = [ 0x40, 0x57, 0x87, 0xfa, 0x12, 0xa8, 0x23, 0xe0, 0xf2, 0xb7, 0x63, 0x1c, 0xc4, 0x1b, 0x3b, 0xa8, 0x82, 0x8b, 0x33, 0x21, 0xca, 0x81, 0x11, 0x11, 0xfa, 0x75, 0xcd, 0x3a, 0xa3, 0xbb, 0x5a, 0xdd ] ]; + +global values = [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x70, 0x24, 0xfc, 0xa6, 0xcd, 0x54, 0x2e, 0x95, 0x97, 0xd5, 0xa5, 0x51, 0xeb, 0xb1, 0xbd, 0x12, 0xdc, 0xc7, 0x03 + ] +]; diff --git a/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_circle/storage.nr b/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_circle/storage.nr index 719c855d9..697f0b12d 100644 --- a/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_circle/storage.nr +++ b/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_circle/storage.nr @@ -3,3 +3,9 @@ global keys = [ 0x57, 0xd1, 0x8a, 0xf7, 0x93, 0xd7, 0x30, 0x0c, 0x4b, 0xa4, 0x6d, 0x19, 0x2e, 0xc7, 0xaa, 0x09, 0x50, 0x70, 0xdd, 0xe6, 0xc5, 0x2c, 0x68, 0x7c, 0x6d, 0x0d, 0x92, 0xfb, 0x85, 0x32, 0xb3, 0x05 ] ]; + +global values = [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x61, 0x31, 0xeb, 0x27, 0x10 + ] +]; diff --git a/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_uniswap/storage.nr b/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_uniswap/storage.nr index accead94c..521d29784 100644 --- a/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_uniswap/storage.nr +++ b/ethereum_history_api/circuits/lib/src/fixtures/mainnet/paris/usdc_uniswap/storage.nr @@ -3,3 +3,9 @@ global keys = [ 0x1f, 0x21, 0xa6, 0x2c, 0x45, 0x38, 0xba, 0xcf, 0x2a, 0xab, 0xec, 0xa4, 0x10, 0xf0, 0xfe, 0x63, 0x15, 0x18, 0x69, 0xf1, 0x72, 0xe0, 0x3c, 0x0e, 0x00, 0x35, 0x7b, 0xa2, 0x6a, 0x34, 0x1e, 0xff ] ]; + +global values = [ + [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x3c, 0x74, 0x1c, 0x54, 0x68 + ] +]; diff --git a/ethereum_history_api/circuits/lib/src/serialize_test.nr b/ethereum_history_api/circuits/lib/src/serialize_test.nr index be3a3e641..07908992a 100644 --- a/ethereum_history_api/circuits/lib/src/serialize_test.nr +++ b/ethereum_history_api/circuits/lib/src/serialize_test.nr @@ -78,13 +78,12 @@ mod account_within_block { mod storage_within_block { use crate::serialize::{STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; use crate::account_with_storage::StorageWithinBlock; - use crate::fixtures::mainnet::paris::usdc_circle::{account::account, header::hash, storage_proof_new::proofs}; + use crate::fixtures::mainnet::paris::usdc_circle::{account::account, header::hash, storage_proof_new::proofs, storage::values}; use crate::misc::{types::BYTES32_LENGTH, arrays::sub_array_equals}; #[test] fn simple() { - let value = proofs[0].value; - let storage_within_block = StorageWithinBlock { block_hash: hash, account, values: [value] }; + let storage_within_block = StorageWithinBlock { block_hash: hash, account, values }; let serialized: [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN] = storage_within_block.serialize(); assert(sub_array_equals(storage_within_block.block_hash.serialize(), serialized, 0)); diff --git a/ethereum_history_api/oracles/src/script/noir_fixtures/storage.ts b/ethereum_history_api/oracles/src/script/noir_fixtures/storage.ts index 090569b0a..7ed6e2c1e 100644 --- a/ethereum_history_api/oracles/src/script/noir_fixtures/storage.ts +++ b/ethereum_history_api/oracles/src/script/noir_fixtures/storage.ts @@ -1,11 +1,19 @@ import { GetProofReturnType } from 'viem'; import { encodeHexString, joinArray, joinArrayVertical } from '../../noir/noir_js/encode.js'; +import { encodeBytes32 } from '../../noir/oracles/common/encode.js'; export function createStorageFixture(stateProof: GetProofReturnType): string { + const values = stateProof.storageProof.map((storageProof) => { + return joinArray(encodeBytes32(storageProof.value)); + }); + const keys = stateProof.storageProof.map((storageProof) => { return joinArray(encodeHexString(storageProof.key)); }); + const storageFixture = `global keys = ${joinArrayVertical(keys)}; + +global values = ${joinArrayVertical(values)}; `; return storageFixture; } From 2a64556910c6509ed583bcf829916c889fd66b76 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 12:07:24 +0200 Subject: [PATCH 02/14] Use map in Serialize of Bytes32 & Address --- ethereum_history_api/circuits/lib/src/serialize.nr | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ethereum_history_api/circuits/lib/src/serialize.nr b/ethereum_history_api/circuits/lib/src/serialize.nr index 7ab3d3a1d..0cb14cb42 100644 --- a/ethereum_history_api/circuits/lib/src/serialize.nr +++ b/ethereum_history_api/circuits/lib/src/serialize.nr @@ -17,21 +17,13 @@ impl Serialize for U128 { impl Serialize for Bytes32 { fn serialize(self) -> [Field; BYTES32_LENGTH] { - let mut data: [Field; BYTES32_LENGTH] = zeroed(); - for i in 0..BYTES32_LENGTH { - data[i] = self[i] as Field; - } - data + self.map(|x: u8| x as Field) } } impl Serialize for Address { fn serialize(self) -> [Field; ADDRESS_LENGTH] { - let mut data: [Field; ADDRESS_LENGTH] = zeroed(); - for i in 0..ADDRESS_LENGTH { - data[i] = self[i] as Field; - } - data + self.map(|x: u8| x as Field) } } From 5eabaee03677dfce1a0bca181fd275ad5f53e585 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 12:13:06 +0200 Subject: [PATCH 03/14] Add assertion messages to tests --- ethereum_history_api/circuits/lib/src/verifiers/header_test.nr | 3 +-- .../circuits/lib/src/verifiers/receipt/rlp_test.nr | 3 +-- .../circuits/lib/src/verifiers/transaction/rlp_test.nr | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/ethereum_history_api/circuits/lib/src/verifiers/header_test.nr b/ethereum_history_api/circuits/lib/src/verifiers/header_test.nr index 4c65aeeb5..561a6515a 100644 --- a/ethereum_history_api/circuits/lib/src/verifiers/header_test.nr +++ b/ethereum_history_api/circuits/lib/src/verifiers/header_test.nr @@ -155,8 +155,7 @@ fn test_verify_header_invalid_receipt_root() { global RLP_SHORT_STRING_TYPE = 0x80; -// TODO: Add correct assertion message when noir-trie-proofs is updated -#[test(should_fail)] +#[test(should_fail_with="Expected a list")] fn test_verify_header_invalid_rlp() { let mut rlp_empty_string_encoding = [0; MAX_HEADER_RLP_LEN]; rlp_empty_string_encoding[0] = RLP_SHORT_STRING_TYPE; diff --git a/ethereum_history_api/circuits/lib/src/verifiers/receipt/rlp_test.nr b/ethereum_history_api/circuits/lib/src/verifiers/receipt/rlp_test.nr index 5ef296a30..10a02a031 100644 --- a/ethereum_history_api/circuits/lib/src/verifiers/receipt/rlp_test.nr +++ b/ethereum_history_api/circuits/lib/src/verifiers/receipt/rlp_test.nr @@ -16,8 +16,7 @@ fn test_post_byzantium() { assert_receipt_rlp_equals(false, receipt_rlp, receipt); } -// TODO: Add correct assertion message when noir-trie-proofs is updated -#[test(should_fail)] +#[test(should_fail_with="Expected a list")] fn test_assert_receipt_rlp_equals_invalid_rlp_type() { let empty_string_rlp = [0x80]; // "" assert_receipt_rlp_equals(false, resize(empty_string_rlp), receipt); diff --git a/ethereum_history_api/circuits/lib/src/verifiers/transaction/rlp_test.nr b/ethereum_history_api/circuits/lib/src/verifiers/transaction/rlp_test.nr index 4c5554564..f707a688f 100644 --- a/ethereum_history_api/circuits/lib/src/verifiers/transaction/rlp_test.nr +++ b/ethereum_history_api/circuits/lib/src/verifiers/transaction/rlp_test.nr @@ -16,8 +16,7 @@ fn eip1559() { assert_tx_rlp_equals(eip1559_tx_rlp, eip1559_tx_type, eip1559_tx); } -// TODO: Add correct assertion message when noir-trie-proofs is updated -#[test(should_fail)] +#[test(should_fail_with="Expected a list")] fn invalid_rlp_type() { let empty_string_rlp = [0x80]; // "" assert_tx_rlp_equals(resize(empty_string_rlp), eip1559_tx_type, eip1559_tx); From a6cdddf2c9a90e8f0c04605ecedccd07f4bcdd52 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 12:45:08 +0200 Subject: [PATCH 04/14] Move serialize into serde subfolder --- ethereum_history_api/circuits/lib/src/lib.nr | 3 +-- ethereum_history_api/circuits/lib/src/serde.nr | 2 ++ .../circuits/lib/src/{ => serde}/serialize.nr | 0 .../circuits/lib/src/{ => serde}/serialize_test.nr | 8 ++++---- 4 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 ethereum_history_api/circuits/lib/src/serde.nr rename ethereum_history_api/circuits/lib/src/{ => serde}/serialize.nr (100%) rename ethereum_history_api/circuits/lib/src/{ => serde}/serialize_test.nr (91%) diff --git a/ethereum_history_api/circuits/lib/src/lib.nr b/ethereum_history_api/circuits/lib/src/lib.nr index d1cb6f86b..72d976f62 100644 --- a/ethereum_history_api/circuits/lib/src/lib.nr +++ b/ethereum_history_api/circuits/lib/src/lib.nr @@ -9,8 +9,7 @@ mod log; mod transaction; mod misc; mod chain; -mod serialize; -mod serialize_test; +mod serde; mod fixtures; mod verifiers; diff --git a/ethereum_history_api/circuits/lib/src/serde.nr b/ethereum_history_api/circuits/lib/src/serde.nr new file mode 100644 index 000000000..bd1f5f6cc --- /dev/null +++ b/ethereum_history_api/circuits/lib/src/serde.nr @@ -0,0 +1,2 @@ +mod serialize; +mod serialize_test; \ No newline at end of file diff --git a/ethereum_history_api/circuits/lib/src/serialize.nr b/ethereum_history_api/circuits/lib/src/serde/serialize.nr similarity index 100% rename from ethereum_history_api/circuits/lib/src/serialize.nr rename to ethereum_history_api/circuits/lib/src/serde/serialize.nr diff --git a/ethereum_history_api/circuits/lib/src/serialize_test.nr b/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr similarity index 91% rename from ethereum_history_api/circuits/lib/src/serialize_test.nr rename to ethereum_history_api/circuits/lib/src/serde/serialize_test.nr index 07908992a..ad1b0328f 100644 --- a/ethereum_history_api/circuits/lib/src/serialize_test.nr +++ b/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr @@ -1,6 +1,6 @@ mod U128_ { - use crate::serialize::U128_SERIALIZED_LEN; + use crate::serde::serialize::U128_SERIALIZED_LEN; #[test] fn simple() { @@ -38,7 +38,7 @@ mod address { mod account { use crate::account_with_storage::Account; - use crate::serialize::ACCOUNT_SERIALIZED_LEN; + use crate::serde::serialize::ACCOUNT_SERIALIZED_LEN; use crate::misc::arrays::sub_array_equals; use crate::fixtures::mainnet::london::vitalik_balance::account::account; @@ -54,7 +54,7 @@ mod account { } mod account_within_block { - use crate::serialize::{ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; + use crate::serde::serialize::{ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; use crate::account::AccountWithinBlock; use crate::fixtures::mainnet::london::vitalik_balance::{account::account, header::hash}; use crate::misc::arrays::sub_array_equals; @@ -76,7 +76,7 @@ mod account_within_block { } mod storage_within_block { - use crate::serialize::{STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; + use crate::serde::serialize::{STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; use crate::account_with_storage::StorageWithinBlock; use crate::fixtures::mainnet::paris::usdc_circle::{account::account, header::hash, storage_proof_new::proofs, storage::values}; use crate::misc::{types::BYTES32_LENGTH, arrays::sub_array_equals}; From 9ed6e3a764d4452ca25a039db03bf065f5ed6fdd Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 13:23:20 +0200 Subject: [PATCH 05/14] Add Fragment.pop_front_array --- .../circuits/lib/src/misc/fragment.nr | 5 +++++ .../circuits/lib/src/misc/fragment_test.nr | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/ethereum_history_api/circuits/lib/src/misc/fragment.nr b/ethereum_history_api/circuits/lib/src/misc/fragment.nr index 88fde4bd4..b59f7a0ea 100644 --- a/ethereum_history_api/circuits/lib/src/misc/fragment.nr +++ b/ethereum_history_api/circuits/lib/src/misc/fragment.nr @@ -80,6 +80,11 @@ impl Fragment { self.data[self.offset - 1] } + pub fn pop_front_array(&mut self) -> [T; LEN] { + let mut res: [T; LEN] = zeroed(); + res.map(|_| self.pop_front()) + } + pub fn push_back(&mut self, value: T) { assert(self.offset + self.length + 1 <= MAX_DATA_LEN, "Cannot push: fragment is full"); self.data[self.offset + self.length] = value; diff --git a/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr b/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr index 0ec4e680f..cf6134939 100644 --- a/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr +++ b/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr @@ -185,6 +185,26 @@ mod pop_front { } } +mod pop_front_array { + + use crate::misc::fragment::Fragment; + + #[test] + fn success() { + let mut fragment = Fragment::new(1, 2, [1, 2, 3]); + assert(fragment.pop_front_array() == [2, 3]); + assert(fragment.length == 0); + } + + #[test(should_fail_with="Cannot pop from an empty fragment")] + fn fail() { + let mut fragment = Fragment::new(1, 1, [1, 2, 3]); + assert(fragment.pop_front_array() == [2]); + assert(fragment.pop_front_array() == [3]); + } +} + + mod push_back { use crate::misc::fragment::Fragment; From 680fb41fc2be076aa0134d7deef21718e04d997d Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 13:23:53 +0200 Subject: [PATCH 06/14] Add Eq for Account, AccountWithinBlock & StorageWithinBlock<1> --- ethereum_history_api/circuits/lib/src/account.nr | 6 ++++++ .../circuits/lib/src/account_with_storage.nr | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/ethereum_history_api/circuits/lib/src/account.nr b/ethereum_history_api/circuits/lib/src/account.nr index 9458edaca..07e4fe4dc 100644 --- a/ethereum_history_api/circuits/lib/src/account.nr +++ b/ethereum_history_api/circuits/lib/src/account.nr @@ -8,6 +8,12 @@ struct AccountWithinBlock { block_hash: Bytes32, } +impl Eq for AccountWithinBlock { + fn eq(self, other: Self) -> bool { + (self.account == other.account) & (self.block_hash == other.block_hash) + } +} + type AccountWithStateProof = (Account, StateProof); pub fn get_account(chain_id: Field, block_no: u64, address: Address) -> AccountWithinBlock { diff --git a/ethereum_history_api/circuits/lib/src/account_with_storage.nr b/ethereum_history_api/circuits/lib/src/account_with_storage.nr index fbb19290b..c5bb2b219 100644 --- a/ethereum_history_api/circuits/lib/src/account_with_storage.nr +++ b/ethereum_history_api/circuits/lib/src/account_with_storage.nr @@ -15,6 +15,12 @@ struct Account { code_hash: Bytes32, } +impl Eq for Account { + fn eq(self, other: Self) -> bool { + (self.nonce == other.nonce) & (self.balance == other.balance) & (self.storage_root == other.storage_root) & (self.code_hash == other.code_hash) + } +} + struct StateProof { key: Address, value: [u8; MAX_ACCOUNT_STATE_LENGTH], @@ -43,6 +49,12 @@ struct StorageWithinBlock { values: [Bytes32; N], } +impl Eq for StorageWithinBlock<1> { + fn eq(self, other: Self) -> bool { + (self.block_hash == other.block_hash) & (self.account == other.account) & (self.values[0] == other.values[0]) + } +} + pub fn get_account_with_storage( chain_id: Field, block_number: u64, From 3513489e28fb3c5323f2a930e9425538e1ab03b5 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 13:24:28 +0200 Subject: [PATCH 07/14] Implement deserialize with tests --- .../circuits/lib/src/serde/serialize.nr | 63 ++++++++++++++++--- .../circuits/lib/src/serde/serialize_test.nr | 6 ++ 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/ethereum_history_api/circuits/lib/src/serde/serialize.nr b/ethereum_history_api/circuits/lib/src/serde/serialize.nr index 0cb14cb42..1751679bd 100644 --- a/ethereum_history_api/circuits/lib/src/serde/serialize.nr +++ b/ethereum_history_api/circuits/lib/src/serde/serialize.nr @@ -3,33 +3,46 @@ use crate::account_with_storage::{StorageWithinBlock, Account}; use crate::misc::{fragment::Fragment, types::{BYTES32_LENGTH, Bytes32, ADDRESS_LENGTH, Address}}; use dep::std::unsafe::zeroed; -trait Serialize { +trait Serde { fn serialize(self) -> [Field; LEN]; + fn deserialize(data: [Field; LEN]) -> Self; } global U128_SERIALIZED_LEN = 2; -impl Serialize for U128 { +impl Serde for U128 { fn serialize(self) -> [Field; U128_SERIALIZED_LEN] { [self.lo, self.hi] } + + fn deserialize(data: [Field; U128_SERIALIZED_LEN]) -> Self { + U128 { lo: data[0], hi: data[1] } + } } -impl Serialize for Bytes32 { +impl Serde for Bytes32 { fn serialize(self) -> [Field; BYTES32_LENGTH] { self.map(|x: u8| x as Field) } + + fn deserialize(data: [Field; BYTES32_LENGTH]) -> Self { + data.map(|x: Field| x as u8) + } } -impl Serialize for Address { +impl Serde for Address { fn serialize(self) -> [Field; ADDRESS_LENGTH] { self.map(|x: u8| x as Field) } + + fn deserialize(data: [Field; ADDRESS_LENGTH]) -> Self { + data.map(|x: Field| x as u8) + } } global ACCOUNT_SERIALIZED_LEN = 1 + 1 + BYTES32_LENGTH + BYTES32_LENGTH; -impl Serialize for Account { +impl Serde for Account { fn serialize(self) -> [Field; ACCOUNT_SERIALIZED_LEN] { let mut data: Fragment = Fragment::empty(); data.push_back(self.nonce as Field); @@ -38,22 +51,46 @@ impl Serialize for Account { data.extend_back(self.code_hash.serialize()); data.to_array() } + + fn deserialize(data: [Field; ACCOUNT_SERIALIZED_LEN]) -> Self { + let mut fragment = Fragment::new_focused(data); + let nonce = fragment.pop_front() as u64; + let balance = fragment.pop_front(); + let storage_root = fragment.pop_front_array().deserialize(); + let code_hash = fragment.pop_front_array().deserialize(); + Account { + nonce, + balance, + storage_root, + code_hash, + } + } } global ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN = ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; -impl Serialize for AccountWithinBlock { +impl Serde for AccountWithinBlock { fn serialize(self) -> [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN] { let mut data: Fragment = Fragment::empty(); data.extend_back(self.account.serialize()); data.extend_back(self.block_hash.serialize()); data.to_array() } + + fn deserialize(data: [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN]) -> Self { + let mut fragment = Fragment::new_focused(data); + let account: Account = Account::deserialize(fragment.pop_front_array()); + let block_hash = fragment.pop_front_array().deserialize(); + AccountWithinBlock { + account, + block_hash, + } + } } global STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN = BYTES32_LENGTH + ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; -impl Serialize for StorageWithinBlock<1> { +impl Serde for StorageWithinBlock<1> { fn serialize(self) -> [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN] { let mut data: Fragment = Fragment::empty(); data.extend_back(self.block_hash.serialize()); @@ -61,4 +98,16 @@ impl Serialize for StorageWithinBlock<1> data.extend_back(self.values[0].serialize()); data.to_array() } + + fn deserialize(data: [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN]) -> Self { + let mut fragment = Fragment::new_focused(data); + let block_hash = fragment.pop_front_array().deserialize(); + let account = Account::deserialize(fragment.pop_front_array()); + let values = [fragment.pop_front_array().deserialize()]; + StorageWithinBlock { + block_hash, + account, + values, + } + } } diff --git a/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr b/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr index ad1b0328f..344a2b01a 100644 --- a/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr +++ b/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr @@ -9,6 +9,7 @@ mod U128_ { assert_eq(serialized[0], value.lo); assert_eq(serialized[1], value.hi); + assert_eq(U128::deserialize(serialized), value); } } @@ -21,6 +22,7 @@ mod bytes32 { let serialized: [Field; BYTES32_LENGTH] = bytes.serialize(); let expected: [Field; BYTES32_LENGTH] = [1; BYTES32_LENGTH]; assert_eq(serialized, expected); + assert_eq(serialized.deserialize(), bytes); } } @@ -33,6 +35,7 @@ mod address { let serialized: [Field; ADDRESS_LENGTH] = address.serialize(); let expected: [Field; ADDRESS_LENGTH] = [1; ADDRESS_LENGTH]; assert_eq(serialized, expected); + assert_eq(serialized.deserialize(), address); } } @@ -50,6 +53,7 @@ mod account { assert_eq(serialized[1], account.balance); assert(sub_array_equals(account.storage_root.serialize(), serialized, 2)); assert(sub_array_equals(account.code_hash.serialize(), serialized, 34)); + assert_eq(Account::deserialize(serialized), account); } } @@ -72,6 +76,7 @@ mod account_within_block { ACCOUNT_SERIALIZED_LEN ) ); + assert_eq(AccountWithinBlock::deserialize(serialized), account_within_block); } } @@ -101,5 +106,6 @@ mod storage_within_block { BYTES32_LENGTH + ACCOUNT_SERIALIZED_LEN ) ); + assert_eq(StorageWithinBlock::deserialize(serialized), storage_within_block); } } From e431917edb891c9f1530f9f66ade730d17b9aaba Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 13:26:00 +0200 Subject: [PATCH 08/14] Move serde module back to top level --- .../circuits/lib/src/serde.nr | 115 +++++++++++++++++- .../circuits/lib/src/serde/serialize.nr | 113 ----------------- .../serialize_test.nr => serde_test.nr} | 8 +- 3 files changed, 117 insertions(+), 119 deletions(-) delete mode 100644 ethereum_history_api/circuits/lib/src/serde/serialize.nr rename ethereum_history_api/circuits/lib/src/{serde/serialize_test.nr => serde_test.nr} (92%) diff --git a/ethereum_history_api/circuits/lib/src/serde.nr b/ethereum_history_api/circuits/lib/src/serde.nr index bd1f5f6cc..1751679bd 100644 --- a/ethereum_history_api/circuits/lib/src/serde.nr +++ b/ethereum_history_api/circuits/lib/src/serde.nr @@ -1,2 +1,113 @@ -mod serialize; -mod serialize_test; \ No newline at end of file +use crate::account::AccountWithinBlock; +use crate::account_with_storage::{StorageWithinBlock, Account}; +use crate::misc::{fragment::Fragment, types::{BYTES32_LENGTH, Bytes32, ADDRESS_LENGTH, Address}}; +use dep::std::unsafe::zeroed; + +trait Serde { + fn serialize(self) -> [Field; LEN]; + fn deserialize(data: [Field; LEN]) -> Self; +} + +global U128_SERIALIZED_LEN = 2; + +impl Serde for U128 { + fn serialize(self) -> [Field; U128_SERIALIZED_LEN] { + [self.lo, self.hi] + } + + fn deserialize(data: [Field; U128_SERIALIZED_LEN]) -> Self { + U128 { lo: data[0], hi: data[1] } + } +} + +impl Serde for Bytes32 { + fn serialize(self) -> [Field; BYTES32_LENGTH] { + self.map(|x: u8| x as Field) + } + + fn deserialize(data: [Field; BYTES32_LENGTH]) -> Self { + data.map(|x: Field| x as u8) + } +} + +impl Serde for Address { + fn serialize(self) -> [Field; ADDRESS_LENGTH] { + self.map(|x: u8| x as Field) + } + + fn deserialize(data: [Field; ADDRESS_LENGTH]) -> Self { + data.map(|x: Field| x as u8) + } +} + +global ACCOUNT_SERIALIZED_LEN = 1 + 1 + BYTES32_LENGTH + BYTES32_LENGTH; + +impl Serde for Account { + fn serialize(self) -> [Field; ACCOUNT_SERIALIZED_LEN] { + let mut data: Fragment = Fragment::empty(); + data.push_back(self.nonce as Field); + data.push_back(self.balance); + data.extend_back(self.storage_root.serialize()); + data.extend_back(self.code_hash.serialize()); + data.to_array() + } + + fn deserialize(data: [Field; ACCOUNT_SERIALIZED_LEN]) -> Self { + let mut fragment = Fragment::new_focused(data); + let nonce = fragment.pop_front() as u64; + let balance = fragment.pop_front(); + let storage_root = fragment.pop_front_array().deserialize(); + let code_hash = fragment.pop_front_array().deserialize(); + Account { + nonce, + balance, + storage_root, + code_hash, + } + } +} + +global ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN = ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; + +impl Serde for AccountWithinBlock { + fn serialize(self) -> [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN] { + let mut data: Fragment = Fragment::empty(); + data.extend_back(self.account.serialize()); + data.extend_back(self.block_hash.serialize()); + data.to_array() + } + + fn deserialize(data: [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN]) -> Self { + let mut fragment = Fragment::new_focused(data); + let account: Account = Account::deserialize(fragment.pop_front_array()); + let block_hash = fragment.pop_front_array().deserialize(); + AccountWithinBlock { + account, + block_hash, + } + } +} + +global STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN = BYTES32_LENGTH + ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; + +impl Serde for StorageWithinBlock<1> { + fn serialize(self) -> [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN] { + let mut data: Fragment = Fragment::empty(); + data.extend_back(self.block_hash.serialize()); + data.extend_back(self.account.serialize()); + data.extend_back(self.values[0].serialize()); + data.to_array() + } + + fn deserialize(data: [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN]) -> Self { + let mut fragment = Fragment::new_focused(data); + let block_hash = fragment.pop_front_array().deserialize(); + let account = Account::deserialize(fragment.pop_front_array()); + let values = [fragment.pop_front_array().deserialize()]; + StorageWithinBlock { + block_hash, + account, + values, + } + } +} diff --git a/ethereum_history_api/circuits/lib/src/serde/serialize.nr b/ethereum_history_api/circuits/lib/src/serde/serialize.nr deleted file mode 100644 index 1751679bd..000000000 --- a/ethereum_history_api/circuits/lib/src/serde/serialize.nr +++ /dev/null @@ -1,113 +0,0 @@ -use crate::account::AccountWithinBlock; -use crate::account_with_storage::{StorageWithinBlock, Account}; -use crate::misc::{fragment::Fragment, types::{BYTES32_LENGTH, Bytes32, ADDRESS_LENGTH, Address}}; -use dep::std::unsafe::zeroed; - -trait Serde { - fn serialize(self) -> [Field; LEN]; - fn deserialize(data: [Field; LEN]) -> Self; -} - -global U128_SERIALIZED_LEN = 2; - -impl Serde for U128 { - fn serialize(self) -> [Field; U128_SERIALIZED_LEN] { - [self.lo, self.hi] - } - - fn deserialize(data: [Field; U128_SERIALIZED_LEN]) -> Self { - U128 { lo: data[0], hi: data[1] } - } -} - -impl Serde for Bytes32 { - fn serialize(self) -> [Field; BYTES32_LENGTH] { - self.map(|x: u8| x as Field) - } - - fn deserialize(data: [Field; BYTES32_LENGTH]) -> Self { - data.map(|x: Field| x as u8) - } -} - -impl Serde for Address { - fn serialize(self) -> [Field; ADDRESS_LENGTH] { - self.map(|x: u8| x as Field) - } - - fn deserialize(data: [Field; ADDRESS_LENGTH]) -> Self { - data.map(|x: Field| x as u8) - } -} - -global ACCOUNT_SERIALIZED_LEN = 1 + 1 + BYTES32_LENGTH + BYTES32_LENGTH; - -impl Serde for Account { - fn serialize(self) -> [Field; ACCOUNT_SERIALIZED_LEN] { - let mut data: Fragment = Fragment::empty(); - data.push_back(self.nonce as Field); - data.push_back(self.balance); - data.extend_back(self.storage_root.serialize()); - data.extend_back(self.code_hash.serialize()); - data.to_array() - } - - fn deserialize(data: [Field; ACCOUNT_SERIALIZED_LEN]) -> Self { - let mut fragment = Fragment::new_focused(data); - let nonce = fragment.pop_front() as u64; - let balance = fragment.pop_front(); - let storage_root = fragment.pop_front_array().deserialize(); - let code_hash = fragment.pop_front_array().deserialize(); - Account { - nonce, - balance, - storage_root, - code_hash, - } - } -} - -global ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN = ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; - -impl Serde for AccountWithinBlock { - fn serialize(self) -> [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN] { - let mut data: Fragment = Fragment::empty(); - data.extend_back(self.account.serialize()); - data.extend_back(self.block_hash.serialize()); - data.to_array() - } - - fn deserialize(data: [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN]) -> Self { - let mut fragment = Fragment::new_focused(data); - let account: Account = Account::deserialize(fragment.pop_front_array()); - let block_hash = fragment.pop_front_array().deserialize(); - AccountWithinBlock { - account, - block_hash, - } - } -} - -global STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN = BYTES32_LENGTH + ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; - -impl Serde for StorageWithinBlock<1> { - fn serialize(self) -> [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN] { - let mut data: Fragment = Fragment::empty(); - data.extend_back(self.block_hash.serialize()); - data.extend_back(self.account.serialize()); - data.extend_back(self.values[0].serialize()); - data.to_array() - } - - fn deserialize(data: [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN]) -> Self { - let mut fragment = Fragment::new_focused(data); - let block_hash = fragment.pop_front_array().deserialize(); - let account = Account::deserialize(fragment.pop_front_array()); - let values = [fragment.pop_front_array().deserialize()]; - StorageWithinBlock { - block_hash, - account, - values, - } - } -} diff --git a/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr b/ethereum_history_api/circuits/lib/src/serde_test.nr similarity index 92% rename from ethereum_history_api/circuits/lib/src/serde/serialize_test.nr rename to ethereum_history_api/circuits/lib/src/serde_test.nr index 344a2b01a..95cf5e360 100644 --- a/ethereum_history_api/circuits/lib/src/serde/serialize_test.nr +++ b/ethereum_history_api/circuits/lib/src/serde_test.nr @@ -1,6 +1,6 @@ mod U128_ { - use crate::serde::serialize::U128_SERIALIZED_LEN; + use crate::serde::U128_SERIALIZED_LEN; #[test] fn simple() { @@ -41,7 +41,7 @@ mod address { mod account { use crate::account_with_storage::Account; - use crate::serde::serialize::ACCOUNT_SERIALIZED_LEN; + use crate::serde::ACCOUNT_SERIALIZED_LEN; use crate::misc::arrays::sub_array_equals; use crate::fixtures::mainnet::london::vitalik_balance::account::account; @@ -58,7 +58,7 @@ mod account { } mod account_within_block { - use crate::serde::serialize::{ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; + use crate::serde::{ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; use crate::account::AccountWithinBlock; use crate::fixtures::mainnet::london::vitalik_balance::{account::account, header::hash}; use crate::misc::arrays::sub_array_equals; @@ -81,7 +81,7 @@ mod account_within_block { } mod storage_within_block { - use crate::serde::serialize::{STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; + use crate::serde::{STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; use crate::account_with_storage::StorageWithinBlock; use crate::fixtures::mainnet::paris::usdc_circle::{account::account, header::hash, storage_proof_new::proofs, storage::values}; use crate::misc::{types::BYTES32_LENGTH, arrays::sub_array_equals}; From 34ccd59910219c4c74205e05f7297ddcf0f88b3f Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 13:50:23 +0200 Subject: [PATCH 09/14] Nargo fmt --- ethereum_history_api/circuits/lib/src/misc/fragment_test.nr | 1 - 1 file changed, 1 deletion(-) diff --git a/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr b/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr index cf6134939..5bd1510b4 100644 --- a/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr +++ b/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr @@ -204,7 +204,6 @@ mod pop_front_array { } } - mod push_back { use crate::misc::fragment::Fragment; From 4872e528fd9d126f44d566c17dc5cf70f9c0a3ec Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 16:14:06 +0200 Subject: [PATCH 10/14] Add better error message for fragment.pop_front_array --- ethereum_history_api/circuits/lib/src/misc/fragment.nr | 1 + .../circuits/lib/src/misc/fragment_test.nr | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ethereum_history_api/circuits/lib/src/misc/fragment.nr b/ethereum_history_api/circuits/lib/src/misc/fragment.nr index b59f7a0ea..4361f2c7e 100644 --- a/ethereum_history_api/circuits/lib/src/misc/fragment.nr +++ b/ethereum_history_api/circuits/lib/src/misc/fragment.nr @@ -81,6 +81,7 @@ impl Fragment { } pub fn pop_front_array(&mut self) -> [T; LEN] { + assert(self.length >= LEN as u64, "Cannot pop array: fragment is too short"); let mut res: [T; LEN] = zeroed(); res.map(|_| self.pop_front()) } diff --git a/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr b/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr index 5bd1510b4..1b10cc341 100644 --- a/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr +++ b/ethereum_history_api/circuits/lib/src/misc/fragment_test.nr @@ -196,12 +196,18 @@ mod pop_front_array { assert(fragment.length == 0); } - #[test(should_fail_with="Cannot pop from an empty fragment")] + #[test(should_fail_with="Cannot pop array: fragment is too short")] fn fail() { let mut fragment = Fragment::new(1, 1, [1, 2, 3]); assert(fragment.pop_front_array() == [2]); assert(fragment.pop_front_array() == [3]); } + + #[test(should_fail_with="Cannot pop array: fragment is too short")] + fn partial_fail() { + let mut fragment = Fragment::new(1, 1, [1, 2, 3]); + assert(fragment.pop_front_array() == [2, 3]); + } } mod push_back { From b68836f6d769cf8d078314f05955ff462d2d1bbe Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 16:15:14 +0200 Subject: [PATCH 11/14] Remove unnecesary type annotation --- ethereum_history_api/circuits/lib/src/serde.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereum_history_api/circuits/lib/src/serde.nr b/ethereum_history_api/circuits/lib/src/serde.nr index 1751679bd..d59875ae7 100644 --- a/ethereum_history_api/circuits/lib/src/serde.nr +++ b/ethereum_history_api/circuits/lib/src/serde.nr @@ -79,7 +79,7 @@ impl Serde for AccountWithinBlock { fn deserialize(data: [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN]) -> Self { let mut fragment = Fragment::new_focused(data); - let account: Account = Account::deserialize(fragment.pop_front_array()); + let account = Account::deserialize(fragment.pop_front_array()); let block_hash = fragment.pop_front_array().deserialize(); AccountWithinBlock { account, From 61f6b7700c4591e1b2efb9f4dba1fbecea04bb3f Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Thu, 9 May 2024 16:17:33 +0200 Subject: [PATCH 12/14] Add missing serde_test declaration --- ethereum_history_api/circuits/lib/src/lib.nr | 1 + 1 file changed, 1 insertion(+) diff --git a/ethereum_history_api/circuits/lib/src/lib.nr b/ethereum_history_api/circuits/lib/src/lib.nr index 72d976f62..d124aef61 100644 --- a/ethereum_history_api/circuits/lib/src/lib.nr +++ b/ethereum_history_api/circuits/lib/src/lib.nr @@ -10,6 +10,7 @@ mod transaction; mod misc; mod chain; mod serde; +mod serde_test; mod fixtures; mod verifiers; From e5791fb0b5639f20c125b5b3b732e64d109c70d4 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 10 May 2024 11:41:31 +0200 Subject: [PATCH 13/14] Use shorter names for serialize consts --- .../circuits/lib/src/serde.nr | 30 +++++++++---------- .../circuits/lib/src/serde_test.nr | 16 +++++----- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ethereum_history_api/circuits/lib/src/serde.nr b/ethereum_history_api/circuits/lib/src/serde.nr index d59875ae7..b527ac739 100644 --- a/ethereum_history_api/circuits/lib/src/serde.nr +++ b/ethereum_history_api/circuits/lib/src/serde.nr @@ -40,11 +40,11 @@ impl Serde for Address { } } -global ACCOUNT_SERIALIZED_LEN = 1 + 1 + BYTES32_LENGTH + BYTES32_LENGTH; +global ACCOUNT_LEN = 1 + 1 + BYTES32_LENGTH + BYTES32_LENGTH; -impl Serde for Account { - fn serialize(self) -> [Field; ACCOUNT_SERIALIZED_LEN] { - let mut data: Fragment = Fragment::empty(); +impl Serde for Account { + fn serialize(self) -> [Field; ACCOUNT_LEN] { + let mut data: Fragment = Fragment::empty(); data.push_back(self.nonce as Field); data.push_back(self.balance); data.extend_back(self.storage_root.serialize()); @@ -52,7 +52,7 @@ impl Serde for Account { data.to_array() } - fn deserialize(data: [Field; ACCOUNT_SERIALIZED_LEN]) -> Self { + fn deserialize(data: [Field; ACCOUNT_LEN]) -> Self { let mut fragment = Fragment::new_focused(data); let nonce = fragment.pop_front() as u64; let balance = fragment.pop_front(); @@ -67,17 +67,17 @@ impl Serde for Account { } } -global ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN = ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; +global ACCOUNT_BLOCK_LEN = ACCOUNT_LEN + BYTES32_LENGTH; -impl Serde for AccountWithinBlock { - fn serialize(self) -> [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN] { - let mut data: Fragment = Fragment::empty(); +impl Serde for AccountWithinBlock { + fn serialize(self) -> [Field; ACCOUNT_BLOCK_LEN] { + let mut data: Fragment = Fragment::empty(); data.extend_back(self.account.serialize()); data.extend_back(self.block_hash.serialize()); data.to_array() } - fn deserialize(data: [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN]) -> Self { + fn deserialize(data: [Field; ACCOUNT_BLOCK_LEN]) -> Self { let mut fragment = Fragment::new_focused(data); let account = Account::deserialize(fragment.pop_front_array()); let block_hash = fragment.pop_front_array().deserialize(); @@ -88,18 +88,18 @@ impl Serde for AccountWithinBlock { } } -global STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN = BYTES32_LENGTH + ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH; +global STORAGE_BLOCK_LEN = BYTES32_LENGTH + ACCOUNT_LEN + BYTES32_LENGTH; -impl Serde for StorageWithinBlock<1> { - fn serialize(self) -> [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN] { - let mut data: Fragment = Fragment::empty(); +impl Serde for StorageWithinBlock<1> { + fn serialize(self) -> [Field; STORAGE_BLOCK_LEN] { + let mut data: Fragment = Fragment::empty(); data.extend_back(self.block_hash.serialize()); data.extend_back(self.account.serialize()); data.extend_back(self.values[0].serialize()); data.to_array() } - fn deserialize(data: [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN]) -> Self { + fn deserialize(data: [Field; STORAGE_BLOCK_LEN]) -> Self { let mut fragment = Fragment::new_focused(data); let block_hash = fragment.pop_front_array().deserialize(); let account = Account::deserialize(fragment.pop_front_array()); diff --git a/ethereum_history_api/circuits/lib/src/serde_test.nr b/ethereum_history_api/circuits/lib/src/serde_test.nr index 95cf5e360..7514632d3 100644 --- a/ethereum_history_api/circuits/lib/src/serde_test.nr +++ b/ethereum_history_api/circuits/lib/src/serde_test.nr @@ -41,13 +41,13 @@ mod address { mod account { use crate::account_with_storage::Account; - use crate::serde::ACCOUNT_SERIALIZED_LEN; + use crate::serde::ACCOUNT_LEN; use crate::misc::arrays::sub_array_equals; use crate::fixtures::mainnet::london::vitalik_balance::account::account; #[test] fn simple() { - let serialized: [Field; ACCOUNT_SERIALIZED_LEN] = account.serialize(); + let serialized: [Field; ACCOUNT_LEN] = account.serialize(); assert_eq(serialized[0], account.nonce as Field); assert_eq(serialized[1], account.balance); @@ -58,7 +58,7 @@ mod account { } mod account_within_block { - use crate::serde::{ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; + use crate::serde::{ACCOUNT_BLOCK_LEN, ACCOUNT_LEN}; use crate::account::AccountWithinBlock; use crate::fixtures::mainnet::london::vitalik_balance::{account::account, header::hash}; use crate::misc::arrays::sub_array_equals; @@ -66,14 +66,14 @@ mod account_within_block { #[test] fn simple() { let account_within_block = AccountWithinBlock { account, block_hash: hash }; - let serialized: [Field; ACCOUNT_WITHIN_BLOCK_SERIALIZED_LEN] = account_within_block.serialize(); + let serialized: [Field; ACCOUNT_BLOCK_LEN] = account_within_block.serialize(); assert(sub_array_equals(account_within_block.account.serialize(), serialized, 0)); assert( sub_array_equals( account_within_block.block_hash.serialize(), serialized, - ACCOUNT_SERIALIZED_LEN + ACCOUNT_LEN ) ); assert_eq(AccountWithinBlock::deserialize(serialized), account_within_block); @@ -81,7 +81,7 @@ mod account_within_block { } mod storage_within_block { - use crate::serde::{STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN, ACCOUNT_SERIALIZED_LEN}; + use crate::serde::{STORAGE_BLOCK_LEN, ACCOUNT_LEN}; use crate::account_with_storage::StorageWithinBlock; use crate::fixtures::mainnet::paris::usdc_circle::{account::account, header::hash, storage_proof_new::proofs, storage::values}; use crate::misc::{types::BYTES32_LENGTH, arrays::sub_array_equals}; @@ -89,7 +89,7 @@ mod storage_within_block { #[test] fn simple() { let storage_within_block = StorageWithinBlock { block_hash: hash, account, values }; - let serialized: [Field; STORAGE_WITHIN_BLOCK_1_SERIALIZED_LEN] = storage_within_block.serialize(); + let serialized: [Field; STORAGE_BLOCK_LEN] = storage_within_block.serialize(); assert(sub_array_equals(storage_within_block.block_hash.serialize(), serialized, 0)); assert( @@ -103,7 +103,7 @@ mod storage_within_block { sub_array_equals( storage_within_block.values[0].serialize(), serialized, - BYTES32_LENGTH + ACCOUNT_SERIALIZED_LEN + BYTES32_LENGTH + ACCOUNT_LEN ) ); assert_eq(StorageWithinBlock::deserialize(serialized), storage_within_block); From 207570b71a3ee4d3b61450ffe7275b1d5ed5b56b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov Date: Fri, 10 May 2024 11:49:33 +0200 Subject: [PATCH 14/14] Use BoundedVec instead of Fragment to in serialize code --- .../circuits/lib/src/serde.nr | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/ethereum_history_api/circuits/lib/src/serde.nr b/ethereum_history_api/circuits/lib/src/serde.nr index b527ac739..487cbcfac 100644 --- a/ethereum_history_api/circuits/lib/src/serde.nr +++ b/ethereum_history_api/circuits/lib/src/serde.nr @@ -44,12 +44,12 @@ global ACCOUNT_LEN = 1 + 1 + BYTES32_LENGTH + BYTES32_LENGTH; impl Serde for Account { fn serialize(self) -> [Field; ACCOUNT_LEN] { - let mut data: Fragment = Fragment::empty(); - data.push_back(self.nonce as Field); - data.push_back(self.balance); - data.extend_back(self.storage_root.serialize()); - data.extend_back(self.code_hash.serialize()); - data.to_array() + let mut data: BoundedVec = BoundedVec::new(); + data.push(self.nonce as Field); + data.push(self.balance); + data.extend_from_array(self.storage_root.serialize()); + data.extend_from_array(self.code_hash.serialize()); + data.storage } fn deserialize(data: [Field; ACCOUNT_LEN]) -> Self { @@ -71,10 +71,10 @@ global ACCOUNT_BLOCK_LEN = ACCOUNT_LEN + BYTES32_LENGTH; impl Serde for AccountWithinBlock { fn serialize(self) -> [Field; ACCOUNT_BLOCK_LEN] { - let mut data: Fragment = Fragment::empty(); - data.extend_back(self.account.serialize()); - data.extend_back(self.block_hash.serialize()); - data.to_array() + let mut data: BoundedVec = BoundedVec::new(); + data.extend_from_array(self.account.serialize()); + data.extend_from_array(self.block_hash.serialize()); + data.storage } fn deserialize(data: [Field; ACCOUNT_BLOCK_LEN]) -> Self { @@ -92,11 +92,11 @@ global STORAGE_BLOCK_LEN = BYTES32_LENGTH + ACCOUNT_LEN + BYTES32_LENGTH; impl Serde for StorageWithinBlock<1> { fn serialize(self) -> [Field; STORAGE_BLOCK_LEN] { - let mut data: Fragment = Fragment::empty(); - data.extend_back(self.block_hash.serialize()); - data.extend_back(self.account.serialize()); - data.extend_back(self.values[0].serialize()); - data.to_array() + let mut data: BoundedVec = BoundedVec::new(); + data.extend_from_array(self.block_hash.serialize()); + data.extend_from_array(self.account.serialize()); + data.extend_from_array(self.values[0].serialize()); + data.storage } fn deserialize(data: [Field; STORAGE_BLOCK_LEN]) -> Self {