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: Minimal globals in constant rollup data #882

Merged
merged 12 commits into from
Jun 22, 2023
91 changes: 91 additions & 0 deletions circuits/cpp/src/aztec3/circuits/abis/global_variables.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
#pragma once
#include "function_data.hpp"
#include "tx_context.hpp"

#include "aztec3/utils/array.hpp"
#include "aztec3/utils/types/circuit_types.hpp"
#include "aztec3/utils/types/convert.hpp"
#include "aztec3/utils/types/native_types.hpp"

#include <barretenberg/barretenberg.hpp>

namespace aztec3::circuits::abis {

using aztec3::utils::types::CircuitTypes;
using aztec3::utils::types::NativeTypes;

template <typename NCT> struct GlobalVariables {
using address = typename NCT::address;
using fr = typename NCT::fr;
using boolean = typename NCT::boolean;

fr chain_id = 0;
fr version = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

can we rename version to aztecVersion and chainId to baseChainID to make it more clear what these are. Otherwise, especially for noir devs this will be super super confusing

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Technically they are both chainIds, so could also be baseChainId and rollupChainId 🤷. Version mainly chosen just to be different to chainId to make it clear it was not the same thing.

Copy link
Contributor

Choose a reason for hiding this comment

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

yea I am fine with baseChainId and rollupChainId!

fr block_number = 0;
fr timestamp = 0;

boolean operator==(GlobalVariables<NCT> const& other) const
{
return chain_id == other.chain_id && version == other.version && block_number == other.block_number &&
timestamp == other.timestamp;
};

template <typename Composer> GlobalVariables<CircuitTypes<Composer>> to_circuit_type(Composer& composer) const
{
static_assert((std::is_same<NativeTypes, NCT>::value));

// Capture the composer:
auto to_ct = [&](auto& e) { return aztec3::utils::types::to_ct(composer, e); };
auto to_circuit_type = [&](auto& e) { return e.to_circuit_type(composer); };

GlobalVariables<CircuitTypes<Composer>> globals = {
to_ct(chain_id),
to_ct(version),
to_ct(block_number),
to_ct(timestamp),
};

return globals;
};

fr hash() const
{
std::vector<fr> inputs;
inputs.push_back(chain_id);
inputs.push_back(version);
inputs.push_back(block_number);
inputs.push_back(timestamp);

return NCT::compress(inputs, GeneratorIndex::GLOBAL_VARIABLES);
}
};

template <typename NCT> void read(uint8_t const*& it, GlobalVariables<NCT>& globals)
{
using serialize::read;

read(it, globals.chain_id);
read(it, globals.version);
read(it, globals.block_number);
read(it, globals.timestamp);
};

template <typename NCT> void write(std::vector<uint8_t>& buf, GlobalVariables<NCT> const& globals)
{
using serialize::write;

write(buf, globals.chain_id);
write(buf, globals.version);
write(buf, globals.block_number);
write(buf, globals.timestamp);
};

template <typename NCT> std::ostream& operator<<(std::ostream& os, GlobalVariables<NCT> const& globals)
{
return os << "chain_id: " << globals.chain_id << "\n"
<< "version: " << globals.version << "\n"
<< "block_number: " << globals.block_number << "\n"
<< "timestamp: " << globals.timestamp << "\n";
}

} // namespace aztec3::circuits::abis
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma once

#include "../append_only_tree_snapshot.hpp"
#include "../global_variables.hpp"

#include "barretenberg/common/serialize.hpp"
#include <barretenberg/barretenberg.hpp>

namespace aztec3::circuits::abis {
Expand All @@ -20,13 +22,16 @@ template <typename NCT> struct ConstantRollupData {
fr base_rollup_vk_hash = 0;
fr merge_rollup_vk_hash = 0;

GlobalVariables<NCT> global_variables{};

MSGPACK_FIELDS(start_tree_of_historic_private_data_tree_roots_snapshot,
start_tree_of_historic_contract_tree_roots_snapshot,
start_tree_of_historic_l1_to_l2_msg_tree_roots_snapshot,
private_kernel_vk_tree_root,
public_kernel_vk_tree_root,
base_rollup_vk_hash,
merge_rollup_vk_hash);
merge_rollup_vk_hash,
global_variables);

bool operator==(ConstantRollupData<NCT> const&) const = default;
};
Expand All @@ -42,6 +47,7 @@ template <typename NCT> void read(uint8_t const*& it, ConstantRollupData<NCT>& o
read(it, obj.public_kernel_vk_tree_root);
read(it, obj.base_rollup_vk_hash);
read(it, obj.merge_rollup_vk_hash);
read(it, obj.global_variables);
};

template <typename NCT> void write(std::vector<uint8_t>& buf, ConstantRollupData<NCT> const& obj)
Expand All @@ -55,6 +61,7 @@ template <typename NCT> void write(std::vector<uint8_t>& buf, ConstantRollupData
write(buf, obj.public_kernel_vk_tree_root);
write(buf, obj.base_rollup_vk_hash);
write(buf, obj.merge_rollup_vk_hash);
write(buf, obj.global_variables);
};

template <typename NCT> std::ostream& operator<<(std::ostream& os, ConstantRollupData<NCT> const& obj)
Expand All @@ -68,7 +75,8 @@ template <typename NCT> std::ostream& operator<<(std::ostream& os, ConstantRollu
<< "private_kernel_vk_tree_root: " << obj.private_kernel_vk_tree_root << "\n"
<< "public_kernel_vk_tree_root: " << obj.public_kernel_vk_tree_root << "\n"
<< "base_rollup_vk_hash: " << obj.base_rollup_vk_hash << "\n"
<< "merge_rollup_vk_hash: " << obj.merge_rollup_vk_hash << "\n";
<< "merge_rollup_vk_hash: " << obj.merge_rollup_vk_hash << "\n"
<< "global_variables: " << obj.global_variables << "\n";
}

} // namespace aztec3::circuits::abis
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "aztec3/circuits/abis/append_only_tree_snapshot.hpp"
#include "aztec3/circuits/abis/global_variables.hpp"
#include "aztec3/constants.hpp"
#include "aztec3/utils/types/circuit_types.hpp"
#include "aztec3/utils/types/convert.hpp"
Expand All @@ -19,6 +20,8 @@ template <typename NCT> struct RootRollupPublicInputs {
// All below are shared between the base and merge rollups
AggregationObject end_aggregation_object;

GlobalVariables<NCT> globalVariables;

AppendOnlyTreeSnapshot<NCT> start_private_data_tree_snapshot;
AppendOnlyTreeSnapshot<NCT> end_private_data_tree_snapshot;

Expand Down Expand Up @@ -52,6 +55,7 @@ template <typename NCT> struct RootRollupPublicInputs {
{
std::vector<uint8_t> buf;

write(&buf, globalVariables);
write(buf, start_private_data_tree_snapshot);
write(buf, start_nullifier_tree_snapshot);
write(buf, start_contract_tree_snapshot);
Expand Down Expand Up @@ -100,6 +104,7 @@ template <typename NCT> void read(uint8_t const*& it, RootRollupPublicInputs<NCT
using serialize::read;

read(it, obj.end_aggregation_object);
read(it, obj.globalVariables);
read(it, obj.start_private_data_tree_snapshot);
read(it, obj.end_private_data_tree_snapshot);
read(it, obj.start_nullifier_tree_snapshot);
Expand All @@ -125,6 +130,7 @@ template <typename NCT> void write(std::vector<uint8_t>& buf, RootRollupPublicIn
using serialize::write;

write(buf, obj.end_aggregation_object);
write(buf, obj.globalVariables);
write(buf, obj.start_private_data_tree_snapshot);
write(buf, obj.end_private_data_tree_snapshot);
write(buf, obj.start_nullifier_tree_snapshot);
Expand All @@ -148,6 +154,7 @@ template <typename NCT> void write(std::vector<uint8_t>& buf, RootRollupPublicIn
template <typename NCT> std::ostream& operator<<(std::ostream& os, RootRollupPublicInputs<NCT> const& obj)
{
return os << "end_aggregation_object: " << obj.end_aggregation_object << "\n"
<< "global_variables: " << obj.globalVariables << "\n"
<< "start_private_data_tree_snapshot: " << obj.start_private_data_tree_snapshot << "\n"
<< "end_private_data_tree_snapshot: " << obj.end_private_data_tree_snapshot << "\n"
<< "start_nullifier_tree_snapshot: " << obj.start_nullifier_tree_snapshot << "\n"
Expand Down
40 changes: 31 additions & 9 deletions circuits/cpp/src/aztec3/circuits/abis/tx_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "aztec3/utils/types/convert.hpp"
#include "aztec3/utils/types/native_types.hpp"

#include "barretenberg/common/serialize.hpp"
#include <barretenberg/barretenberg.hpp>

namespace aztec3::circuits::abis {
Expand All @@ -24,13 +25,22 @@ template <typename NCT> struct TxContext {

ContractDeploymentData<NCT> contract_deployment_data{};

fr chain_id = 0;
fr version = 0;

// for serialization: update up with new fields
MSGPACK_FIELDS(is_fee_payment_tx, is_rebate_payment_tx, is_contract_deployment_tx, contract_deployment_data);
MSGPACK_FIELDS(is_fee_payment_tx,
is_rebate_payment_tx,
is_contract_deployment_tx,
contract_deployment_data,
chain_id,
version);
boolean operator==(TxContext<NCT> const& other) const
{
return is_fee_payment_tx == other.is_fee_payment_tx && is_rebate_payment_tx == other.is_rebate_payment_tx &&
is_contract_deployment_tx == other.is_contract_deployment_tx &&
contract_deployment_data == other.contract_deployment_data;
contract_deployment_data == other.contract_deployment_data && chain_id == other.chain_id &&
version == other.version;
};

template <typename Composer> TxContext<CircuitTypes<Composer>> to_circuit_type(Composer& composer) const
Expand All @@ -46,6 +56,8 @@ template <typename NCT> struct TxContext {
to_ct(is_rebate_payment_tx),
to_ct(is_contract_deployment_tx),
contract_deployment_data.to_circuit_type(composer),
to_ct(chain_id),
to_ct(version),
};

return tx_context;
Expand All @@ -57,12 +69,12 @@ template <typename NCT> struct TxContext {
auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt<Composer>(e); };
auto to_native_type = []<typename T>(T& e) { return e.template to_native_type<Composer>(); };

TxContext<NativeTypes> tx_context = {
to_nt(is_fee_payment_tx),
to_nt(is_rebate_payment_tx),
to_nt(is_contract_deployment_tx),
to_native_type(contract_deployment_data),
};
TxContext<NativeTypes> tx_context = { to_nt(is_fee_payment_tx),
to_nt(is_rebate_payment_tx),
to_nt(is_contract_deployment_tx),
to_native_type(contract_deployment_data),
to_nt(chain_id),
to_nt(version) };

return tx_context;
};
Expand All @@ -75,6 +87,8 @@ template <typename NCT> struct TxContext {
fr(is_rebate_payment_tx).set_public();
fr(is_contract_deployment_tx).set_public();
contract_deployment_data.set_public();
chain_id.set_public();
version.set_public();
}

fr hash() const
Expand All @@ -84,6 +98,8 @@ template <typename NCT> struct TxContext {
fr(is_rebate_payment_tx),
fr(is_contract_deployment_tx),
contract_deployment_data.hash(),
chain_id,
version,
};

return NCT::compress(inputs, GeneratorIndex::TX_CONTEXT);
Expand All @@ -98,6 +114,8 @@ template <typename NCT> void read(uint8_t const*& it, TxContext<NCT>& tx_context
read(it, tx_context.is_rebate_payment_tx);
read(it, tx_context.is_contract_deployment_tx);
read(it, tx_context.contract_deployment_data);
read(it, tx_context.chain_id);
read(it, tx_context.version);
};

template <typename NCT> void write(std::vector<uint8_t>& buf, TxContext<NCT> const& tx_context)
Expand All @@ -108,6 +126,8 @@ template <typename NCT> void write(std::vector<uint8_t>& buf, TxContext<NCT> con
write(buf, tx_context.is_rebate_payment_tx);
write(buf, tx_context.is_contract_deployment_tx);
write(buf, tx_context.contract_deployment_data);
write(buf, tx_context.chain_id);
write(buf, tx_context.version);
};

template <typename NCT> std::ostream& operator<<(std::ostream& os, TxContext<NCT> const& tx_context)
Expand All @@ -117,7 +137,9 @@ template <typename NCT> std::ostream& operator<<(std::ostream& os, TxContext<NCT
<< "is_contract_deployment_tx: " << tx_context.is_contract_deployment_tx << "\n"
<< "contract_deployment_data: "
<< "\n"
<< tx_context.contract_deployment_data;
<< tx_context.contract_deployment_data << "\n"
<< "chain_id: " << tx_context.chain_id << "\n"
<< "version: " << tx_context.version << "\n";
}

} // namespace aztec3::circuits::abis
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ PrivateKernelInputsInit<NT> do_private_call_get_kernel_inputs_init(
.is_rebate_payment_tx = false,
.is_contract_deployment_tx = is_constructor,
.contract_deployment_data = contract_deployment_data,
.chain_id = 1,
} };

//***************************************************************************
Expand Down
1 change: 1 addition & 0 deletions circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ PublicKernelInputs<NT> get_kernel_inputs_with_previous_kernel(NT::boolean privat
.is_rebate_payment_tx = false,
.is_contract_deployment_tx = false,
.contract_deployment_data = {},
.chain_id = 1,
} };

std::array<PublicCallStackItem, PUBLIC_CALL_STACK_LENGTH> child_call_stacks;
Expand Down
24 changes: 24 additions & 0 deletions circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,30 @@ TEST_F(base_rollup_tests, native_constants_dont_change)
run_cbind(inputs, outputs);
}

TEST_F(base_rollup_tests, native_constants_dont_match_kernels_chain_id)
{
DummyComposer composer = DummyComposer("base_rollup_tests__native_constants_dont_change");
BaseRollupInputs inputs = base_rollup_inputs_from_kernels({ get_empty_kernel(), get_empty_kernel() });
inputs.constants.global_variables.chain_id = 3;
BaseOrMergeRollupPublicInputs const outputs =
aztec3::circuits::rollup::native_base_rollup::base_rollup_circuit(composer, inputs);
ASSERT_EQ(inputs.constants, outputs.constants);
EXPECT_TRUE(composer.failed());
ASSERT_EQ(composer.get_first_failure().message, "kernel chain_id does not match the rollup chain_id");
}

TEST_F(base_rollup_tests, native_constants_dont_match_kernels_version)
{
DummyComposer composer = DummyComposer("base_rollup_tests__native_constants_dont_change");
BaseRollupInputs inputs = base_rollup_inputs_from_kernels({ get_empty_kernel(), get_empty_kernel() });
inputs.constants.global_variables.version = 3;
BaseOrMergeRollupPublicInputs const outputs =
aztec3::circuits::rollup::native_base_rollup::base_rollup_circuit(composer, inputs);
ASSERT_EQ(inputs.constants, outputs.constants);
EXPECT_TRUE(composer.failed());
ASSERT_EQ(composer.get_first_failure().message, "kernel version does not match the rollup version");
}

TEST_F(base_rollup_tests, native_aggregate)
{
// TODO(rahul): Fix this when aggregation works
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,18 @@ BaseOrMergeRollupPublicInputs base_rollup_circuit(DummyComposer& composer, BaseR
CircuitErrorCode::BASE__KERNEL_PROOF_VERIFICATION_FAILED);
}

// Verify the kernel chain_id and versions
for (size_t i = 0; i < 2; i++) {
composer.do_assert(baseRollupInputs.kernel_data[i].public_inputs.constants.tx_context.chain_id ==
baseRollupInputs.constants.global_variables.chain_id,
"kernel chain_id does not match the rollup chain_id",
CircuitErrorCode::BASE__INVALID_CHAIN_ID);
composer.do_assert(baseRollupInputs.kernel_data[i].public_inputs.constants.tx_context.version ==
baseRollupInputs.constants.global_variables.version,
"kernel version does not match the rollup version",
CircuitErrorCode::BASE__INVALID_VERSION);
}

// First we compute the contract tree leaves
std::vector<NT::fr> const contract_leaves = calculate_contract_leaves(baseRollupInputs);

Expand Down
14 changes: 14 additions & 0 deletions circuits/cpp/src/aztec3/circuits/rollup/merge/.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ TEST_F(merge_rollup_tests, native_constants_different_failure)
ASSERT_EQ(composer.get_first_failure().message, "input proofs have different constants");
}

TEST_F(merge_rollup_tests, native_constants_different_chain_id_failure)
{
DummyComposer composer = DummyComposer("merge_rollup_tests__native_constants_different_failure");
std::array<KernelData, 4> const kernels = {
get_empty_kernel(), get_empty_kernel(), get_empty_kernel(), get_empty_kernel()
};
MergeRollupInputs inputs = get_merge_rollup_inputs(composer, kernels);
inputs.previous_rollup_data[0].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = fr(1);
inputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.constants.global_variables.chain_id = fr(0);
merge_rollup_circuit(composer, inputs);
ASSERT_TRUE(composer.failed());
ASSERT_EQ(composer.get_first_failure().message, "input proofs have different constants");
}

TEST_F(merge_rollup_tests, native_fail_if_previous_rollups_dont_follow_on)
{
DummyComposer composerA = DummyComposer("merge_rollup_tests__native_fail_if_previous_rollups_dont_follow_on_A");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ RootRollupPublicInputs root_rollup_circuit(DummyComposer& composer, RootRollupIn

RootRollupPublicInputs public_inputs = {
.end_aggregation_object = aggregation_object,
.globalVariables = left.constants.global_variables,
.start_private_data_tree_snapshot = left.start_private_data_tree_snapshot,
.end_private_data_tree_snapshot = right.end_private_data_tree_snapshot,
.start_nullifier_tree_snapshot = left.start_nullifier_tree_snapshot,
Expand Down
Loading