Skip to content

Commit

Permalink
Split BlockHeaderPartial to encoded and decoded part
Browse files Browse the repository at this point in the history
  • Loading branch information
akonior committed Feb 14, 2024
1 parent c2fa58e commit 417459b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 24 deletions.
34 changes: 21 additions & 13 deletions ethereum_history_api/circuits/lib/src/get_header.nr
Original file line number Diff line number Diff line change
Expand Up @@ -12,53 +12,61 @@ global TRANSACTIONS_ROOT_INDEX = 4;
global RECEIPTS_ROOT_INDEX = 5;
global BLOCK_NUMBER_INDEX = 8;

struct BlockHeaderFromOracle {
partial: BlockHeaderPartial,
encoded: BlockHeaderEncoded
}

struct BlockHeaderPartial {
state_root: [u8; HASH_LENGTH],
transactions_root: [u8; HASH_LENGTH],
receipts_root: [u8; HASH_LENGTH],
number: Field,
hash: [u8; HASH_LENGTH],
hash: [u8; HASH_LENGTH]
}

struct BlockHeaderEncoded {
encoded_len: Field,
encoded: [u8; MAX_HEADER_RLP_SIZE]
}

#[oracle(get_header)]
unconstrained fn get_header_oracle(_block_no: Field) -> BlockHeaderPartial {}
unconstrained fn get_header_oracle(_block_no: Field) -> BlockHeaderFromOracle {}

unconstrained fn get_header_unconstrained(block_no: Field) -> BlockHeaderPartial {
unconstrained fn get_header_unconstrained(block_no: Field) -> BlockHeaderFromOracle {
get_header_oracle(block_no)
}

pub(crate) fn verify_header(block_no: Field) -> BlockHeaderPartial {
let header = get_header_unconstrained(block_no);
let rlp_list:RLP_List<HEADER_FIELDS_COUNT> = decode1(header.encoded);
let rlp_list:RLP_List<HEADER_FIELDS_COUNT> = decode1(header.encoded.encoded);
assert(
sub_array_equals(
header.state_root,
header.encoded,
header.partial.state_root,
header.encoded.encoded,
rlp_list.offset[STATE_ROOT_INDEX]
), "state_root does not match"
);
assert(
sub_array_equals(
header.transactions_root,
header.encoded,
header.partial.transactions_root,
header.encoded.encoded,
rlp_list.offset[TRANSACTIONS_ROOT_INDEX]
), "transactions_root does not match"
);
assert(
sub_array_equals(
header.receipts_root,
header.encoded,
header.partial.receipts_root,
header.encoded.encoded,
rlp_list.offset[RECEIPTS_ROOT_INDEX]
), "receipts_root does not match"
);
assert(
sub_array_equals(
keccak256(header.encoded, header.encoded_len as u32),
header.hash,
keccak256(header.encoded.encoded, header.encoded.encoded_len as u32),
header.partial.hash,
0
), "hash does not match"
);
header
header.partial
}
23 changes: 12 additions & 11 deletions ethereum_history_api/circuits/lib/src/get_header_test.nr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use dep::std::test::OracleMock;
use crate::get_header::{verify_header, BlockHeaderPartial};
use crate::get_header::{verify_header, BlockHeaderPartial, BlockHeaderEncoded, BlockHeaderFromOracle};
use crate::arrays::alter_array;

global state_root = [
Expand Down Expand Up @@ -29,42 +29,43 @@ global hash = [

global encoded_len: Field = 515;

global blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash, encoded_len, encoded };
global blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash };
global blockEncoded = BlockHeaderEncoded { encoded, encoded_len };

#[test]
fn test_get_header_success() {
let _ = OracleMock::mock("get_header").returns(blockPartial);
let _ = OracleMock::mock("get_header").returns(BlockHeaderFromOracle { partial: blockPartial, encoded: blockEncoded });
assert(verify_header(0).state_root == state_root);
}

#[test(should_fail_with = "state_root does not match")]
fn test_get_header_invalid_state_root() {
let state_root = alter_array(state_root);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash, encoded_len, encoded };
let _ = OracleMock::mock("get_header").returns(blockPartial);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash };
let _ = OracleMock::mock("get_header").returns(BlockHeaderFromOracle { partial: blockPartial, encoded: blockEncoded });
assert(verify_header(0).state_root == state_root);
}

#[test(should_fail_with = "transactions_root does not match")]
fn test_get_header_invalid_transactions_root() {
let transactions_root = alter_array(transactions_root);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash, encoded_len, encoded };
let _ = OracleMock::mock("get_header").returns(blockPartial);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash };
let _ = OracleMock::mock("get_header").returns(BlockHeaderFromOracle { partial: blockPartial, encoded: blockEncoded });
assert(verify_header(0).state_root == state_root);
}

#[test(should_fail_with = "receipts_root does not match")]
fn test_get_header_invalid_receipt_root() {
let receipts_root = alter_array(receipts_root);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash, encoded_len, encoded };
let _ = OracleMock::mock("get_header").returns(blockPartial);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash };
let _ = OracleMock::mock("get_header").returns(BlockHeaderFromOracle { partial: blockPartial, encoded: blockEncoded });
assert(verify_header(0).state_root == state_root);
}

#[test(should_fail_with = "hash does not match")]
fn test_get_header_invalid_hash() {
let hash = alter_array(hash);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash, encoded_len, encoded };
let _ = OracleMock::mock("get_header").returns(blockPartial);
let blockPartial = BlockHeaderPartial { state_root, transactions_root, receipts_root, number, hash };
let _ = OracleMock::mock("get_header").returns(BlockHeaderFromOracle { partial: blockPartial, encoded: blockEncoded });
assert(verify_header(0).state_root == state_root);
}

0 comments on commit 417459b

Please sign in to comment.