Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(blocks_tree): compute block hashes within root rollup circuit #1214

Merged
merged 24 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8553fa0
feat: add blocks tree data to l2 block
Maddiaa0 Jul 25, 2023
4580093
feat: use constants to represent offsets
Maddiaa0 Jul 25, 2023
1991a57
chore: forge fmt
Maddiaa0 Jul 25, 2023
e0808b8
fix: linter
Maddiaa0 Jul 25, 2023
98692dd
fix: stub circuit output for the meantime
Maddiaa0 Jul 26, 2023
2942f95
feat: add naive block hash calculations to root rollup circuit
Maddiaa0 Jul 26, 2023
e8f9fbc
Merge branch 'master' into md/blocks-tree-circuits
Maddiaa0 Jul 27, 2023
376e71a
temp
Maddiaa0 Jul 27, 2023
9403830
Merge branch 'master' into md/blocks-tree-circuits
Maddiaa0 Jul 31, 2023
7520217
fix: update snapshot
Maddiaa0 Jul 31, 2023
3c9422c
feat: include block hash calcs in sequencer
Maddiaa0 Jul 31, 2023
de68edd
fix: make calculate block hash a cbind
Maddiaa0 Jul 31, 2023
520b9a6
Merge branch 'master' into md/blocks-tree-circuits
Maddiaa0 Jul 31, 2023
55fbd5f
feat: add block tree checking in ts
Maddiaa0 Aug 1, 2023
f1d9fc7
clean
Maddiaa0 Aug 1, 2023
3ae5a4d
lint
Maddiaa0 Aug 1, 2023
011a150
review comments
Maddiaa0 Aug 1, 2023
830721f
Merge branch 'master' into md/blocks-tree-circuits
Maddiaa0 Aug 1, 2023
035c41f
fix: include generator indices
Maddiaa0 Aug 1, 2023
5340a79
lint
Maddiaa0 Aug 1, 2023
d9bda7b
update snapshot
Maddiaa0 Aug 1, 2023
455058a
fix: remove references to block num in factories
Maddiaa0 Aug 2, 2023
515bb60
Merge branch 'master' into md/blocks-tree-circuits
Maddiaa0 Aug 2, 2023
613e8be
Merge branch 'master' into md/blocks-tree-circuits
Maddiaa0 Aug 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,11 @@ CBIND(abis__silo_commitment, aztec3::circuits::silo_commitment<NT>);
*/
CBIND(abis__silo_nullifier, aztec3::circuits::silo_nullifier<NT>);

/**
* @brief Computes the block hash from the block information.
*/
CBIND(abis__compute_block_hash, aztec3::circuits::compute_block_hash<NT>);

/**
* @brief Generates a signed tx request hash from it's pre-image
* This is a WASM-export that can be called from Typescript.
Expand Down
1 change: 1 addition & 0 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ CBIND_DECL(abis__compute_commitment_nonce);
CBIND_DECL(abis__compute_unique_commitment);
CBIND_DECL(abis__silo_commitment);
CBIND_DECL(abis__silo_nullifier);
CBIND_DECL(abis__compute_block_hash);

WASM_EXPORT void abis__compute_message_secret_hash(uint8_t const* secret, uint8_t* output);
WASM_EXPORT void abis__compute_contract_leaf(uint8_t const* contract_leaf_preimage_buf, uint8_t* output);
Expand Down
2 changes: 2 additions & 0 deletions circuits/cpp/src/aztec3/circuits/abis/global_variables.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ template <typename NCT> struct GlobalVariables {
fr block_number = 0;
fr timestamp = 0;

MSGPACK_FIELDS(chain_id, version, block_number, timestamp);

boolean operator==(GlobalVariables<NCT> const& other) const
{
return chain_id == other.chain_id && version == other.version && block_number == other.block_number &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@ template <typename NCT> struct RootRollupInputs {
using fr = typename NCT::fr;

// All below are shared between the base and merge rollups
std::array<PreviousRollupData<NCT>, 2> previous_rollup_data;
std::array<PreviousRollupData<NCT>, 2> previous_rollup_data{};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2zo1ki


std::array<fr, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT> new_historic_private_data_tree_root_sibling_path;
std::array<fr, CONTRACT_TREE_ROOTS_TREE_HEIGHT> new_historic_contract_tree_root_sibling_path;
std::array<fr, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT> new_historic_private_data_tree_root_sibling_path{};
std::array<fr, CONTRACT_TREE_ROOTS_TREE_HEIGHT> new_historic_contract_tree_root_sibling_path{};

// inputs required to process l1 to l2 messages
std::array<fr, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP> l1_to_l2_messages;
std::array<fr, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH> new_l1_to_l2_message_tree_root_sibling_path;
std::array<fr, L1_TO_L2_MSG_TREE_ROOTS_TREE_HEIGHT> new_historic_l1_to_l2_message_roots_tree_sibling_path;
std::array<fr, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP> l1_to_l2_messages{};
std::array<fr, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH> new_l1_to_l2_message_tree_root_sibling_path{};
std::array<fr, L1_TO_L2_MSG_TREE_ROOTS_TREE_HEIGHT> new_historic_l1_to_l2_message_roots_tree_sibling_path{};

AppendOnlyTreeSnapshot<NCT> start_l1_to_l2_message_tree_snapshot;
AppendOnlyTreeSnapshot<NCT> start_historic_tree_l1_to_l2_message_tree_roots_snapshot;
AppendOnlyTreeSnapshot<NCT> start_l1_to_l2_message_tree_snapshot{};
AppendOnlyTreeSnapshot<NCT> start_historic_tree_l1_to_l2_message_tree_roots_snapshot{};

// inputs required to add the block hash
AppendOnlyTreeSnapshot<NCT> start_historic_blocks_tree_snapshot{};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we not have to add start_historic_blocks_tree_snapshot and end_historic_blocks_tree_snapshot into the root rollup PublicInputs?

Edit: just realised it was always there in that file lol

std::array<fr, HISTORIC_BLOCKS_TREE_HEIGHT> new_historic_blocks_tree_sibling_path{};

bool operator==(RootRollupInputs<NCT> const&) const = default;
};
Expand All @@ -44,6 +48,8 @@ template <typename NCT> void read(uint8_t const*& it, RootRollupInputs<NCT>& obj
read(it, obj.new_historic_l1_to_l2_message_roots_tree_sibling_path);
read(it, obj.start_l1_to_l2_message_tree_snapshot);
read(it, obj.start_historic_tree_l1_to_l2_message_tree_roots_snapshot);
read(it, obj.start_historic_blocks_tree_snapshot);
read(it, obj.new_historic_blocks_tree_sibling_path);
};

template <typename NCT> void write(std::vector<uint8_t>& buf, RootRollupInputs<NCT> const& obj)
Expand All @@ -58,6 +64,8 @@ template <typename NCT> void write(std::vector<uint8_t>& buf, RootRollupInputs<N
write(buf, obj.new_historic_l1_to_l2_message_roots_tree_sibling_path);
write(buf, obj.start_l1_to_l2_message_tree_snapshot);
write(buf, obj.start_historic_tree_l1_to_l2_message_tree_roots_snapshot);
write(buf, obj.start_historic_blocks_tree_snapshot);
write(buf, obj.new_historic_blocks_tree_sibling_path);
};

template <typename NCT> std::ostream& operator<<(std::ostream& os, RootRollupInputs<NCT> const& obj)
Expand All @@ -73,7 +81,9 @@ template <typename NCT> std::ostream& operator<<(std::ostream& os, RootRollupInp
<< obj.new_historic_l1_to_l2_message_roots_tree_sibling_path << "\n"
<< "start_l1_to_l2_message_tree_snapshot: " << obj.start_l1_to_l2_message_tree_snapshot << "\n"
<< "start_historic_tree_l1_to_l2_message_tree_roots_snapshot: "
<< obj.start_historic_tree_l1_to_l2_message_tree_roots_snapshot << "\n";
<< obj.start_historic_tree_l1_to_l2_message_tree_roots_snapshot << "\n"
<< "start_historic_blocks_tree_snapshot: " << obj.start_historic_blocks_tree_snapshot << "\n"
<< "new_historic_blocks_tree_sibling_path: " << obj.new_historic_blocks_tree_sibling_path << "\n";
}

} // namespace aztec3::circuits::abis
19 changes: 19 additions & 0 deletions circuits/cpp/src/aztec3/circuits/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "aztec3/circuits/abis/function_data.hpp"
#include "aztec3/circuits/abis/function_leaf_preimage.hpp"
#include "aztec3/circuits/abis/global_variables.hpp"
#include "aztec3/circuits/abis/new_contract_data.hpp"
#include "aztec3/circuits/abis/point.hpp"
#include "aztec3/constants.hpp"
Expand Down Expand Up @@ -137,6 +138,24 @@ typename NCT::fr silo_nullifier(typename NCT::address contract_address, typename
return NCT::compress(inputs, aztec3::GeneratorIndex::OUTER_NULLIFIER);
}

template <typename NCT> typename NCT::fr compute_block_hash(typename abis::GlobalVariables<NCT> globals,
typename NCT::fr private_data_tree_root,
typename NCT::fr nullifier_tree_root,
typename NCT::fr contract_tree_root,
typename NCT::fr l1_to_l2_data_tree_root,
typename NCT::fr public_data_tree_root)
{
using fr = typename NCT::fr;

std::vector<fr> const inputs = {
globals.hash(), private_data_tree_root, nullifier_tree_root,
contract_tree_root, l1_to_l2_data_tree_root, public_data_tree_root,
};

// TODO(Maddiaa): does this need an index?
Maddiaa0 marked this conversation as resolved.
Show resolved Hide resolved
return NCT::compress(inputs);
}

/**
* @brief Calculate the Merkle tree root from the sibling path and leaf.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp"
#include "aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp"
#include "aztec3/circuits/hash.hpp"
#include "aztec3/circuits/rollup/components/components.hpp"
#include "aztec3/constants.hpp"

Expand Down Expand Up @@ -115,7 +116,7 @@ RootRollupPublicInputs root_rollup_circuit(DummyBuilder& builder, RootRollupInpu
// Compute subtree inserting l1 to l2 messages
auto l1_to_l2_subtree_root = calculate_subtree(rootRollupInputs.l1_to_l2_messages);

// // Insert subtree into the l1 to l2 data tree
// Insert subtree into the l1 to l2 data tree
const auto empty_l1_to_l2_subtree_root = components::calculate_empty_tree_root(L1_TO_L2_MSG_SUBTREE_HEIGHT);
auto new_l1_to_l2_messages_tree_snapshot = components::insert_subtree_to_snapshot_tree(
builder,
Expand All @@ -138,6 +139,27 @@ RootRollupPublicInputs root_rollup_circuit(DummyBuilder& builder, RootRollupInpu
format(ROOT_CIRCUIT_ERROR_MESSAGE_BEGINNING,
"historic l1 to l2 message tree roots not empty at location where subtree would be inserted"));

// Build the block hash for this iteration from the tree roots and global variables
// Then insert the block into the historic blocks tree
auto block_hash = compute_block_hash(left.constants.global_variables,
right.end_private_data_tree_snapshot.root,
right.end_nullifier_tree_snapshot.root,
right.end_contract_tree_snapshot.root,
new_l1_to_l2_messages_tree_snapshot.root,
right.end_public_data_tree_root);

// Update the historic blocks tree
auto end_historic_blocks_tree_snapshot = components::insert_subtree_to_snapshot_tree(
builder,
rootRollupInputs.start_historic_blocks_tree_snapshot,
rootRollupInputs.new_historic_blocks_tree_sibling_path,
fr::zero(),
block_hash,
0,
format(ROOT_CIRCUIT_ERROR_MESSAGE_BEGINNING,
"historic blocks tree roots not empty at location where subtree would be inserted"));


RootRollupPublicInputs public_inputs = {
.end_aggregation_object = aggregation_object,
.globalVariables = left.constants.global_variables,
Expand All @@ -160,6 +182,8 @@ RootRollupPublicInputs root_rollup_circuit(DummyBuilder& builder, RootRollupInpu
.start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot =
rootRollupInputs.start_historic_tree_l1_to_l2_message_tree_roots_snapshot,
.end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot = end_l1_to_l2_data_roots_tree_snapshot,
.start_historic_blocks_tree_snapshot = rootRollupInputs.start_historic_blocks_tree_snapshot,
.end_historic_blocks_tree_snapshot = end_historic_blocks_tree_snapshot,
.calldata_hash = components::compute_calldata_hash(rootRollupInputs.previous_rollup_data),
.l1_to_l2_messages_hash = compute_messages_hash(rootRollupInputs.l1_to_l2_messages)
};
Expand Down
16 changes: 15 additions & 1 deletion circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder,
MemoryStore historic_l1_to_l2_msg_tree_store;
MerkleTree historic_l1_to_l2_msg_tree(historic_l1_to_l2_msg_tree_store, L1_TO_L2_MSG_TREE_ROOTS_TREE_HEIGHT);


MemoryStore private_data_store;
const MerkleTree private_data_tree(private_data_store, PRIVATE_DATA_TREE_HEIGHT);

Expand All @@ -351,6 +350,9 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder,
MemoryStore l1_to_l2_msg_tree_store;
MerkleTree l1_to_l2_msg_tree(l1_to_l2_msg_tree_store, L1_TO_L2_MSG_TREE_HEIGHT);

MemoryStore historic_blocks_tree_store;
MerkleTree historic_blocks_tree(historic_blocks_tree_store, HISTORIC_BLOCKS_TREE_HEIGHT);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably be initialised with empty root for position 0 like we were doing with the others.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixing in follow up


// Historic trees are initialised with an empty root at position 0.
historic_private_data_tree.update_element(0, private_data_tree.root());
Expand All @@ -364,6 +366,7 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder,
get_sibling_path<CONTRACT_TREE_ROOTS_TREE_HEIGHT>(historic_contract_tree, 1, 0);
auto historic_l1_to_l2_msg_sibling_path =
get_sibling_path<L1_TO_L2_MSG_TREE_ROOTS_TREE_HEIGHT>(historic_l1_to_l2_msg_tree, 1, 0);

// l1 to l2 tree
auto l1_to_l2_tree_sibling_path =
get_sibling_path<L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH>(l1_to_l2_msg_tree, 0, L1_TO_L2_MSG_SUBTREE_HEIGHT);
Expand All @@ -378,6 +381,15 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder,
.next_available_leaf_index = 1,
};

// Blocks tree
auto blocks_tree_sibling_path = get_sibling_path<HISTORIC_BLOCKS_TREE_HEIGHT>(historic_blocks_tree, 0, 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Naming wise would add the historic to the name here for clarity. Should probably also be for index 1? As our historic starts there instead of at 0 where the initial was inserted?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixing in followup


// Blocks tree snapshots
AppendOnlyTreeSnapshot const start_historic_blocks_tree_snapshot = {
.root = historic_blocks_tree.root(),
.next_available_leaf_index = 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next available should probably be one here similarly to how the other historic trees are handled now?

Copy link
Member Author

@Maddiaa0 Maddiaa0 Aug 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixing in follow up

};

RootRollupInputs rootRollupInputs = {
.previous_rollup_data = get_previous_rollup_data(builder, std::move(kernel_data)),
.new_historic_private_data_tree_root_sibling_path = historic_data_sibling_path,
Expand All @@ -388,6 +400,8 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder,
.start_l1_to_l2_message_tree_snapshot = start_l1_to_l2_msg_tree_snapshot,
.start_historic_tree_l1_to_l2_message_tree_roots_snapshot =
start_historic_tree_l1_to_l2_message_tree_roots_snapshot,
.start_historic_blocks_tree_snapshot = start_historic_blocks_tree_snapshot,
.new_historic_blocks_tree_sibling_path = blocks_tree_sibling_path,
};
return rootRollupInputs;
}
Expand Down
31 changes: 31 additions & 0 deletions yarn-project/circuits.js/src/abis/abis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Buffer } from 'buffer';
import chunk from 'lodash.chunk';

import {
abisComputeBlockHash,
abisComputeCommitmentNonce,
abisComputeUniqueCommitment,
abisSiloCommitment,
Expand All @@ -16,6 +17,7 @@ import {
Fr,
FunctionData,
FunctionLeafPreimage,
GlobalVariables,
NewContractData,
PrivateCallStackItem,
PublicCallStackItem,
Expand Down Expand Up @@ -298,6 +300,35 @@ export function siloNullifier(wasm: IWasmModule, contract: AztecAddress, innerNu
return abisSiloNullifier(wasm, contract, innerNullifier);
}

/**
* Computes the block hash given the blocks globals and roots.
* A siloed nullifier effectively namespaces a nullifier to a specific contract.
* @param wasm - A module providing low-level wasm access.
* @param contract - The contract address.
* @param innerNullifier - The nullifier to silo.
* @returns A siloed nullifier.
*/
export function computeBlockHash(
wasm: IWasmModule,
globals: GlobalVariables,
privateDataTreeRoot: Fr,
nullifierTreeRoot: Fr,
contractTreeRoot: Fr,
l1ToL2DataTreeRoot: Fr,
publicDataTreeRoot: Fr,
): Fr {
wasm.call('pedersen__init');
return abisComputeBlockHash(
wasm,
globals,
privateDataTreeRoot,
nullifierTreeRoot,
contractTreeRoot,
l1ToL2DataTreeRoot,
publicDataTreeRoot,
);
}

const ARGS_HASH_CHUNK_SIZE = 32;
const ARGS_HASH_CHUNK_COUNT = 16;

Expand Down
70 changes: 70 additions & 0 deletions yarn-project/circuits.js/src/cbind/circuits.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
Fr,
FunctionData,
G1AffineElement,
GlobalVariables,
KernelCircuitPublicInputs,
NativeAggregationState,
NewContractData,
Expand All @@ -42,6 +43,55 @@ import {
toBuffer,
} from './types.js';

interface MsgpackGlobalVariables {
chain_id: Buffer;
version: Buffer;
block_number: Buffer;
timestamp: Buffer;
}

export function toGlobalVariables(o: MsgpackGlobalVariables): GlobalVariables {
if (o.chain_id === undefined) {
throw new Error('Expected chain_id in GlobalVariables deserialization');
}
if (o.version === undefined) {
throw new Error('Expected version in GlobalVariables deserialization');
}
if (o.block_number === undefined) {
throw new Error('Expected block_number in GlobalVariables deserialization');
}
if (o.timestamp === undefined) {
throw new Error('Expected timestamp in GlobalVariables deserialization');
}
return new GlobalVariables(
Fr.fromBuffer(o.chain_id),
Fr.fromBuffer(o.version),
Fr.fromBuffer(o.block_number),
Fr.fromBuffer(o.timestamp),
);
}

export function fromGlobalVariables(o: GlobalVariables): MsgpackGlobalVariables {
if (o.chainId === undefined) {
throw new Error('Expected chainId in GlobalVariables serialization');
}
if (o.version === undefined) {
throw new Error('Expected version in GlobalVariables serialization');
}
if (o.blockNumber === undefined) {
throw new Error('Expected blockNumber in GlobalVariables serialization');
}
if (o.timestamp === undefined) {
throw new Error('Expected timestamp in GlobalVariables serialization');
}
return {
chain_id: toBuffer(o.chainId),
version: toBuffer(o.version),
block_number: toBuffer(o.blockNumber),
timestamp: toBuffer(o.timestamp),
};
}

interface MsgpackG1AffineElement {
x: Buffer;
y: Buffer;
Expand Down Expand Up @@ -1458,6 +1508,26 @@ export function abisSiloCommitment(wasm: IWasmModule, arg0: Address, arg1: Fr):
export function abisSiloNullifier(wasm: IWasmModule, arg0: Address, arg1: Fr): Fr {
return Fr.fromBuffer(callCbind(wasm, 'abis__silo_nullifier', [toBuffer(arg0), toBuffer(arg1)]));
}
export function abisComputeBlockHash(
wasm: IWasmModule,
arg0: GlobalVariables,
arg1: Fr,
arg2: Fr,
arg3: Fr,
arg4: Fr,
arg5: Fr,
): Fr {
return Fr.fromBuffer(
callCbind(wasm, 'abis__compute_block_hash', [
fromGlobalVariables(arg0),
toBuffer(arg1),
toBuffer(arg2),
toBuffer(arg3),
toBuffer(arg4),
toBuffer(arg5),
]),
);
}
export function privateKernelDummyPreviousKernel(wasm: IWasmModule): PreviousKernelData {
return toPreviousKernelData(callCbind(wasm, 'private_kernel__dummy_previous_kernel', []));
}
Expand Down
1 change: 1 addition & 0 deletions yarn-project/circuits.js/src/cbind/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export {
CircuitError,
Point,
Coordinate,
GlobalVariables,
} from '../structs/index.js';

/**
Expand Down
Loading