From dc0da4c1cb68a921cc43e9a35aa6a9961fc8462d Mon Sep 17 00:00:00 2001 From: PhilWindle <60546371+PhilWindle@users.noreply.github.com> Date: Thu, 20 Apr 2023 14:23:23 +0100 Subject: [PATCH] Update circuits structs for public functions (#304) * WIP * Add public data to base rollup inputs * Add public data tree snapshots to base and merge rollup public inputs * Fixed build * Build fixed * New kernel circuit input types * Update base rollup inputs and public inputs in ts * Rename PrivateKernelPublicInputs to include both kernel circuits * Fix factory method * Add missing callContext to public circuit public inputs serialization * Update ts structs to match changes in cpp * Move makeEmpty helper functions to static methods * Update test snapshot * Update kernel serialization test * Rename some factory and empty methods * Fix base rollup inputs created from circuit block builder * Fix the most annoying bug ever * Vertical whitespace * Update snapshots * Update hash constructor snapshot * Restructure circuits.js structs * Rename old to historic in new structs --------- Co-authored-by: Santiago Palladino --- .../cpp/src/aztec3/circuits/abis/.test.cpp | 2 +- .../cpp/src/aztec3/circuits/abis/c_bind.cpp | 19 +- .../src/aztec3/circuits/abis/c_bind.test.cpp | 4 +- .../aztec3/circuits/abis/call_stack_item.hpp | 30 +- ...data.hpp => combined_accumulated_data.hpp} | 80 +++- ...nt_data.hpp => combined_constant_data.hpp} | 28 +- .../abis/combined_historic_tree_roots.hpp | 89 ++++ ...s.hpp => kernel_circuit_public_inputs.hpp} | 32 +- .../new_contract_data.hpp | 4 +- .../previous_kernel_data.hpp | 8 +- ...ts.hpp => private_historic_tree_roots.hpp} | 22 +- .../abis/private_kernel/private_call_data.hpp | 9 +- .../abis/private_kernel/private_inputs.hpp | 6 +- .../abis/public_circuit_public_inputs.hpp | 35 +- .../abis/public_kernel/public_call_data.hpp | 122 +++++ .../public_kernel/public_kernel_inputs.hpp | 67 +++ ...ublic_kernel_inputs_no_previous_kernel.hpp | 71 +++ .../witnessed_public_call_data.hpp | 86 ++++ .../base_or_merge_rollup_public_inputs.hpp | 13 + .../abis/rollup/base/base_rollup_inputs.hpp | 15 +- .../src/aztec3/circuits/abis/state_read.hpp | 24 +- .../aztec3/circuits/abis/state_transition.hpp | 26 +- .../cpp/src/aztec3/circuits/abis/types.hpp | 25 ++ .../apps/function_execution_context.hpp | 15 +- circuits/cpp/src/aztec3/circuits/hash.hpp | 4 +- .../aztec3/circuits/kernel/private/.test.cpp | 42 +- .../aztec3/circuits/kernel/private/c_bind.cpp | 24 +- .../private/native_private_kernel_circuit.cpp | 25 +- .../private/native_private_kernel_circuit.hpp | 7 +- .../kernel/private/private_kernel_circuit.cpp | 16 +- .../kernel/private/private_kernel_circuit.hpp | 8 +- .../aztec3/circuits/kernel/private/utils.cpp | 4 +- .../aztec3/circuits/kernel/private/utils.hpp | 2 +- .../aztec3/circuits/kernel/public/.test.cpp | 23 + .../aztec3/circuits/kernel/public/init.hpp | 35 ++ .../public/native_public_kernel_circuit.cpp | 324 ++++++++++++++ .../public/native_public_kernel_circuit.hpp | 22 + .../circuits/mock/mock_kernel_circuit.hpp | 7 +- .../src/aztec3/circuits/rollup/base/.test.cpp | 28 +- .../aztec3/circuits/rollup/base/c_bind.cpp | 2 +- .../base/native_base_rollup_circuit.cpp | 6 +- .../src/aztec3/circuits/rollup/base/utils.cpp | 4 +- .../aztec3/circuits/rollup/merge/utils.cpp | 2 +- .../src/aztec3/circuits/rollup/root/.test.cpp | 27 +- .../aztec3/circuits/rollup/root/c_bind.cpp | 2 +- circuits/cpp/src/aztec3/constants.hpp | 1 + .../acir-simulator/src/acvm/serialize.ts | 4 +- yarn-project/acir-simulator/src/execution.ts | 4 +- yarn-project/acir-simulator/src/index.test.ts | 14 +- .../src/public/state_actions.ts | 20 +- yarn-project/acir-simulator/src/simulator.ts | 4 +- .../src/account_state/account_state.ts | 4 +- .../src/contract_tree/contract_tree.ts | 2 +- yarn-project/circuits.js/src/kernel/kernel.ts | 4 +- ...x.test.ts.snap => tx_context.test.ts.snap} | 0 .../src/structs/aggregation_object.ts | 46 ++ ..._call_stack_item.ts => call_stack_item.ts} | 21 + yarn-project/circuits.js/src/structs/index.ts | 26 +- .../__snapshots__/private_kernel.test.ts.snap | 87 +++- .../kernel/combined_accumulated_data.ts | 198 +++++++++ .../structs/kernel/combined_constant_data.ts | 75 ++++ .../structs/kernel/previous_kernel_data.ts | 77 ++++ .../{ => kernel}/private_kernel.test.ts | 8 +- .../src/structs/kernel/private_kernel.ts | 83 ++++ .../src/structs/kernel/public_inputs.ts | 38 ++ .../src/structs/{ => kernel}/public_kernel.ts | 46 +- .../src/structs/membership_witness.ts | 47 ++ .../circuits.js/src/structs/merge_rollup.ts | 30 -- .../structs/private_circuit_public_inputs.ts | 2 +- .../circuits.js/src/structs/private_kernel.ts | 416 ------------------ .../structs/public_circuit_public_inputs.ts | 72 ++- .../__snapshots__/base_rollup.test.ts.snap | 88 +++- .../__snapshots__/root_rollup.test.ts.snap | 16 + .../rollup/append_only_tree_snapshot.ts | 20 + .../base_or_merge_rollup_public_inputs.ts | 84 ++++ .../structs/{ => rollup}/base_rollup.test.ts | 6 +- .../src/structs/{ => rollup}/base_rollup.ts | 101 +---- .../src/structs/rollup/merge_rollup.ts | 10 + .../structs/rollup/previous_rollup_data.ts | 23 + .../structs/{ => rollup}/root_rollup.test.ts | 4 +- .../src/structs/{ => rollup}/root_rollup.ts | 12 +- .../circuits.js/src/structs/shared.ts | 89 +--- .../{tx.test.ts => tx_context.test.ts} | 0 .../src/structs/{tx.ts => tx_context.ts} | 61 +-- .../circuits.js/src/structs/tx_request.ts | 62 +++ .../circuits.js/src/tests/factories.ts | 98 +++-- yarn-project/foundation/src/fields/fields.ts | 8 + .../kernel-prover/src/kernel_prover.test.ts | 4 +- .../kernel-prover/src/kernel_prover.ts | 4 +- .../kernel-prover/src/proof_creator.ts | 4 +- yarn-project/p2p/src/client/mocks.ts | 4 +- .../circuit_block_builder.test.ts | 8 +- .../block_builder/circuit_block_builder.ts | 19 +- yarn-project/sequencer-client/src/mocks/tx.ts | 8 +- .../src/simulator/fake_public.ts | 8 +- yarn-project/types/src/tx.ts | 10 +- 96 files changed, 2452 insertions(+), 1074 deletions(-) rename circuits/cpp/src/aztec3/circuits/abis/{private_kernel/accumulated_data.hpp => combined_accumulated_data.hpp} (68%) rename circuits/cpp/src/aztec3/circuits/abis/{private_kernel/constant_data.hpp => combined_constant_data.hpp} (68%) create mode 100644 circuits/cpp/src/aztec3/circuits/abis/combined_historic_tree_roots.hpp rename circuits/cpp/src/aztec3/circuits/abis/{private_kernel/public_inputs.hpp => kernel_circuit_public_inputs.hpp} (68%) rename circuits/cpp/src/aztec3/circuits/abis/{private_kernel => }/new_contract_data.hpp (97%) rename circuits/cpp/src/aztec3/circuits/abis/{private_kernel => }/previous_kernel_data.hpp (93%) rename circuits/cpp/src/aztec3/circuits/abis/{private_kernel/historic_tree_roots.hpp => private_historic_tree_roots.hpp} (77%) create mode 100644 circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_call_data.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs_no_previous_kernel.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/abis/public_kernel/witnessed_public_call_data.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/abis/types.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/public/init.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.cpp create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.hpp rename yarn-project/circuits.js/src/structs/__snapshots__/{tx.test.ts.snap => tx_context.test.ts.snap} (100%) create mode 100644 yarn-project/circuits.js/src/structs/aggregation_object.ts rename yarn-project/circuits.js/src/structs/{private_call_stack_item.ts => call_stack_item.ts} (55%) rename yarn-project/circuits.js/src/structs/{ => kernel}/__snapshots__/private_kernel.test.ts.snap (89%) create mode 100644 yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts create mode 100644 yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts create mode 100644 yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts rename yarn-project/circuits.js/src/structs/{ => kernel}/private_kernel.test.ts (70%) create mode 100644 yarn-project/circuits.js/src/structs/kernel/private_kernel.ts create mode 100644 yarn-project/circuits.js/src/structs/kernel/public_inputs.ts rename yarn-project/circuits.js/src/structs/{ => kernel}/public_kernel.ts (70%) create mode 100644 yarn-project/circuits.js/src/structs/membership_witness.ts delete mode 100644 yarn-project/circuits.js/src/structs/merge_rollup.ts delete mode 100644 yarn-project/circuits.js/src/structs/private_kernel.ts rename yarn-project/circuits.js/src/structs/{ => rollup}/__snapshots__/base_rollup.test.ts.snap (72%) rename yarn-project/circuits.js/src/structs/{ => rollup}/__snapshots__/root_rollup.test.ts.snap (93%) create mode 100644 yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts create mode 100644 yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts rename yarn-project/circuits.js/src/structs/{ => rollup}/base_rollup.test.ts (86%) rename yarn-project/circuits.js/src/structs/{ => rollup}/base_rollup.ts (64%) create mode 100644 yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts create mode 100644 yarn-project/circuits.js/src/structs/rollup/previous_rollup_data.ts rename yarn-project/circuits.js/src/structs/{ => rollup}/root_rollup.test.ts (92%) rename yarn-project/circuits.js/src/structs/{ => rollup}/root_rollup.ts (91%) rename yarn-project/circuits.js/src/structs/{tx.test.ts => tx_context.test.ts} (100%) rename yarn-project/circuits.js/src/structs/{tx.ts => tx_context.ts} (59%) create mode 100644 yarn-project/circuits.js/src/structs/tx_request.ts diff --git a/circuits/cpp/src/aztec3/circuits/abis/.test.cpp b/circuits/cpp/src/aztec3/circuits/abis/.test.cpp index a81da1e62b0..86492c81d63 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/.test.cpp @@ -4,7 +4,7 @@ #include "index.hpp" #include -#include "private_kernel/previous_kernel_data.hpp" +#include "previous_kernel_data.hpp" #include "private_kernel/private_inputs.hpp" namespace aztec3::circuits::abis { diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp index 58161210b13..a26bb2e03c8 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp @@ -2,7 +2,7 @@ #include "barretenberg/srs/reference_string/mem_reference_string.hpp" #include "aztec3/circuits/abis/function_data.hpp" #include "aztec3/circuits/abis/function_leaf_preimage.hpp" -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" #include "private_circuit_public_inputs.hpp" #include "tx_request.hpp" #include "tx_context.hpp" @@ -12,9 +12,9 @@ #include "rollup/base/base_or_merge_rollup_public_inputs.hpp" #include "rollup/root/root_rollup_public_inputs.hpp" #include "rollup/root/root_rollup_inputs.hpp" -#include "private_kernel/previous_kernel_data.hpp" +#include "previous_kernel_data.hpp" #include "private_kernel/private_inputs.hpp" -#include "private_kernel/public_inputs.hpp" +#include "kernel_circuit_public_inputs.hpp" #include #include @@ -31,9 +31,9 @@ using aztec3::circuits::compute_constructor_hash; using aztec3::circuits::compute_contract_address; using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::FunctionLeafPreimage; +using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::TxContext; using aztec3::circuits::abis::TxRequest; -using aztec3::circuits::abis::private_kernel::NewContractData; using NT = aztec3::utils::types::NativeTypes; // Cbind helper functions @@ -403,7 +403,7 @@ WASM_EXPORT const char* abis__test_roundtrip_serialize_base_rollup_inputs(uint8_ WASM_EXPORT const char* abis__test_roundtrip_serialize_previous_kernel_data(uint8_t const* kernel_data_buf, uint32_t* size) { - return as_string_output>(kernel_data_buf, size); + return as_string_output>(kernel_data_buf, size); } WASM_EXPORT const char* abis__test_roundtrip_serialize_base_or_merge_rollup_public_inputs( @@ -441,17 +441,16 @@ WASM_EXPORT const char* abis__test_roundtrip_serialize_private_kernel_inputs(uin return as_string_output>(input, size); } -WASM_EXPORT const char* abis__test_roundtrip_serialize_private_kernel_public_inputs(uint8_t const* input, +WASM_EXPORT const char* abis__test_roundtrip_serialize_kernel_circuit_public_inputs(uint8_t const* input, uint32_t* size) { - return as_string_output>(input, size); + return as_string_output>(input, size); } - -WASM_EXPORT const char* abis__test_roundtrip_serialize_function_leaf_preimage(uint8_t const* function_leaf_preimage_buf, uint32_t* size) +WASM_EXPORT const char* abis__test_roundtrip_serialize_function_leaf_preimage(uint8_t const* function_leaf_preimage_buf, + uint32_t* size) { return as_string_output>(function_leaf_preimage_buf, size); } - } // extern "C" diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp index 1ee832d871e..a050e9d2c7f 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp @@ -2,7 +2,7 @@ #include "tx_request.hpp" #include "function_leaf_preimage.hpp" -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" #include #include @@ -13,7 +13,7 @@ namespace { using NT = aztec3::utils::types::NativeTypes; -using aztec3::circuits::abis::private_kernel::NewContractData; +using aztec3::circuits::abis::NewContractData; auto& engine = numeric::random::get_debug_engine(); diff --git a/circuits/cpp/src/aztec3/circuits/abis/call_stack_item.hpp b/circuits/cpp/src/aztec3/circuits/abis/call_stack_item.hpp index e1b77bd1eb5..e87bfdeb2ae 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/call_stack_item.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/call_stack_item.hpp @@ -2,6 +2,7 @@ #include "function_data.hpp" #include "private_circuit_public_inputs.hpp" #include "public_circuit_public_inputs.hpp" +#include "kernel_circuit_public_inputs.hpp" #include #include @@ -15,20 +16,11 @@ using aztec3::utils::types::NativeTypes; using std::conditional; using std::is_same; -enum class CallType { - Public, - Private, -}; - -template struct CallStackItem { +template typename PrivatePublic> struct CallStackItem { typedef typename NCT::address address; typedef typename NCT::boolean boolean; typedef typename NCT::fr fr; - template - using PublicInputs = typename std:: - conditional, PrivateCircuitPublicInputs>::type; - // This is the _actual_ contract address relating to where this function's code resides in the // contract tree. Regardless of whether this is a call or delegatecall, this // `contract_address` _does not change_. Amongst other things, it's used as a lookup for @@ -36,7 +28,7 @@ template struct CallStackItem { // within a CallStackItem which varies depending on whether this is a call or delegatecall. address contract_address = 0; FunctionData function_data{}; - PublicInputs public_inputs{}; + typename PrivatePublic::AppCircuitPublicInputs public_inputs{}; boolean operator==(CallContext const& other) const { @@ -45,14 +37,14 @@ template struct CallStackItem { }; template - CallStackItem, call_type> to_circuit_type(Composer& composer) const + CallStackItem, PrivatePublic> to_circuit_type(Composer& composer) const { static_assert((std::is_same::value)); // Capture the composer: auto to_ct = [&](auto& e) { return aztec3::utils::types::to_ct(composer, e); }; - CallStackItem, call_type> call_stack_item = { + CallStackItem, PrivatePublic> call_stack_item = { to_ct(contract_address), function_data.to_circuit_type(composer), public_inputs.to_circuit_type(composer), @@ -75,8 +67,8 @@ template struct CallStackItem { } }; // namespace aztec3::circuits::abis -template -void read(uint8_t const*& it, CallStackItem& call_stack_item) +template typename PrivatePublic> +void read(uint8_t const*& it, CallStackItem& call_stack_item) { using serialize::read; @@ -85,8 +77,8 @@ void read(uint8_t const*& it, CallStackItem& call_stack_item) read(it, call_stack_item.public_inputs); }; -template -void write(std::vector& buf, CallStackItem const& call_stack_item) +template typename PrivatePublic> +void write(std::vector& buf, CallStackItem const& call_stack_item) { using serialize::write; @@ -95,8 +87,8 @@ void write(std::vector& buf, CallStackItem const& call_ write(buf, call_stack_item.public_inputs); }; -template -std::ostream& operator<<(std::ostream& os, CallStackItem const& call_stack_item) +template typename PrivatePublic> +std::ostream& operator<<(std::ostream& os, CallStackItem const& call_stack_item) { return os << "contract_address: " << call_stack_item.contract_address << "\n" << "function_data: " << call_stack_item.function_data << "\n" diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/accumulated_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/combined_accumulated_data.hpp similarity index 68% rename from circuits/cpp/src/aztec3/circuits/abis/private_kernel/accumulated_data.hpp rename to circuits/cpp/src/aztec3/circuits/abis/combined_accumulated_data.hpp index f089eb98cc8..0493445bebd 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/accumulated_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/combined_accumulated_data.hpp @@ -1,6 +1,8 @@ #pragma once -#include "../optionally_revealed_data.hpp" -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" +#include "optionally_revealed_data.hpp" +#include "new_contract_data.hpp" +#include "state_transition.hpp" +#include "state_read.hpp" #include "aztec3/constants.hpp" #include #include @@ -10,14 +12,14 @@ #include #include -namespace aztec3::circuits::abis::private_kernel { +namespace aztec3::circuits::abis { using aztec3::utils::zero_array; using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; using std::is_same; -template struct AccumulatedData { +template struct CombinedAccumulatedData { typedef typename NCT::fr fr; typedef typename NCT::boolean boolean; typedef typename NCT::AggregationObject AggregationObject; @@ -25,6 +27,7 @@ template struct AccumulatedData { AggregationObject aggregation_object{}; fr private_call_count = 0; + fr public_call_count = 0; std::array new_commitments = zero_array(); std::array new_nullifiers = zero_array(); @@ -39,16 +42,21 @@ template struct AccumulatedData { std::array, KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH> optionally_revealed_data{}; - boolean operator==(AccumulatedData const& other) const + std::array, STATE_TRANSITIONS_LENGTH> state_transitions{}; + std::array, STATE_READS_LENGTH> state_reads{}; + + boolean operator==(CombinedAccumulatedData const& other) const { return aggregation_object == other.aggregation_object && private_call_count == other.private_call_count && - new_commitments == other.new_commitments && new_nullifiers == other.new_nullifiers && - private_call_stack == other.private_call_stack && public_call_stack == other.public_call_stack && - l1_msg_stack == other.l1_msg_stack && new_contracts == other.new_contracts && - optionally_revealed_data == other.optionally_revealed_data; + public_call_count == other.public_call_count && new_commitments == other.new_commitments && + new_nullifiers == other.new_nullifiers && private_call_stack == other.private_call_stack && + public_call_stack == other.public_call_stack && l1_msg_stack == other.l1_msg_stack && + new_contracts == other.new_contracts && optionally_revealed_data == other.optionally_revealed_data && + state_transitions == other.state_transitions && state_reads == other.state_reads; }; - template AccumulatedData> to_circuit_type(Composer& composer) const + template + CombinedAccumulatedData> to_circuit_type(Composer& composer) const { typedef CircuitTypes CT; static_assert((std::is_same::value)); @@ -57,7 +65,7 @@ template struct AccumulatedData { 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); }; - AccumulatedData acc_data = { + CombinedAccumulatedData acc_data = { typename CT::AggregationObject{ to_ct(aggregation_object.P0), to_ct(aggregation_object.P1), @@ -67,6 +75,7 @@ template struct AccumulatedData { }, to_ct(private_call_count), + to_ct(public_call_count), to_ct(new_commitments), to_ct(new_nullifiers), @@ -77,18 +86,20 @@ template struct AccumulatedData { map(new_contracts, to_circuit_type), map(optionally_revealed_data, to_circuit_type), + map(state_transitions, to_circuit_type), + map(state_reads, to_circuit_type), }; return acc_data; }; - template AccumulatedData to_native_type() const + template CombinedAccumulatedData to_native_type() const { static_assert(std::is_same, NCT>::value); auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; auto to_native_type = [](T& e) { return e.template to_native_type(); }; - AccumulatedData acc_data = { + CombinedAccumulatedData acc_data = { typename NativeTypes::AggregationObject{ to_nt(aggregation_object.P0), to_nt(aggregation_object.P1), @@ -98,6 +109,7 @@ template struct AccumulatedData { }, to_nt(private_call_count), + to_nt(public_call_count), to_nt(new_commitments), to_nt(new_nullifiers), @@ -108,6 +120,8 @@ template struct AccumulatedData { map(new_contracts, to_native_type), map(optionally_revealed_data, to_native_type), + map(state_transitions, to_native_type), + map(state_reads, to_native_type), }; return acc_data; @@ -120,6 +134,7 @@ template struct AccumulatedData { aggregation_object.add_proof_outputs_as_public_inputs(); private_call_count.set_public(); + public_call_count.set_public(); set_array_public(new_commitments); set_array_public(new_nullifiers); @@ -130,6 +145,8 @@ template struct AccumulatedData { set_array_public(new_contracts); set_array_public(optionally_revealed_data); + set_array_public(state_transitions); + set_array_public(state_reads); } template void set_array_public(std::array& arr) @@ -155,14 +172,31 @@ template struct AccumulatedData { e.set_public(); } } + + template void set_array_public(std::array, SIZE>& arr) + { + static_assert(!(std::is_same::value)); + for (auto& e : arr) { + e.set_public(); + } + } + + template void set_array_public(std::array, SIZE>& arr) + { + static_assert(!(std::is_same::value)); + for (auto& e : arr) { + e.set_public(); + } + } }; -template void read(uint8_t const*& it, AccumulatedData& accum_data) +template void read(uint8_t const*& it, CombinedAccumulatedData& accum_data) { using serialize::read; read(it, accum_data.aggregation_object); read(it, accum_data.private_call_count); + read(it, accum_data.public_call_count); read(it, accum_data.new_commitments); read(it, accum_data.new_nullifiers); read(it, accum_data.private_call_stack); @@ -170,14 +204,17 @@ template void read(uint8_t const*& it, AccumulatedData& accu read(it, accum_data.l1_msg_stack); read(it, accum_data.new_contracts); read(it, accum_data.optionally_revealed_data); + read(it, accum_data.state_transitions); + read(it, accum_data.state_reads); }; -template void write(std::vector& buf, AccumulatedData const& accum_data) +template void write(std::vector& buf, CombinedAccumulatedData const& accum_data) { using serialize::write; write(buf, accum_data.aggregation_object); write(buf, accum_data.private_call_count); + write(buf, accum_data.public_call_count); write(buf, accum_data.new_commitments); write(buf, accum_data.new_nullifiers); write(buf, accum_data.private_call_stack); @@ -185,13 +222,16 @@ template void write(std::vector& buf, AccumulatedData std::ostream& operator<<(std::ostream& os, AccumulatedData const& accum_data) +template std::ostream& operator<<(std::ostream& os, CombinedAccumulatedData const& accum_data) { return os << "aggregation_object:\n" << accum_data.aggregation_object << "\n" << "private_call_count: " << accum_data.private_call_count << "\n" + << "public_call_count: " << accum_data.public_call_count << "\n" << "new_commitments:\n" << accum_data.new_commitments << "\n" << "new_nullifiers:\n" @@ -205,7 +245,11 @@ template std::ostream& operator<<(std::ostream& os, AccumulatedDa << "new_contracts:\n" << accum_data.new_contracts << "\n" << "optionally_revealed_data:\n" - << accum_data.optionally_revealed_data << "\n"; + << accum_data.optionally_revealed_data << "\n" + << "state_transitions:\n" + << accum_data.state_transitions << "\n" + << "state_reads:\n" + << accum_data.state_reads << "\n"; } -} // namespace aztec3::circuits::abis::private_kernel \ No newline at end of file +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/constant_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/combined_constant_data.hpp similarity index 68% rename from circuits/cpp/src/aztec3/circuits/abis/private_kernel/constant_data.hpp rename to circuits/cpp/src/aztec3/circuits/abis/combined_constant_data.hpp index fbd748a5054..e4465ed49e5 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/constant_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/combined_constant_data.hpp @@ -1,37 +1,37 @@ #pragma once -#include "historic_tree_roots.hpp" -#include "../tx_context.hpp" +#include "combined_historic_tree_roots.hpp" +#include "tx_context.hpp" #include #include #include #include -namespace aztec3::circuits::abis::private_kernel { +namespace aztec3::circuits::abis { using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; using plonk::stdlib::witness_t; using std::is_same; -template struct ConstantData { +template struct CombinedConstantData { typedef typename NCT::fr fr; typedef typename NCT::boolean boolean; - HistoricTreeRoots historic_tree_roots{}; + CombinedHistoricTreeRoots historic_tree_roots{}; TxContext tx_context{}; - boolean operator==(ConstantData const& other) const + boolean operator==(CombinedConstantData const& other) const { return historic_tree_roots == other.historic_tree_roots && tx_context == other.tx_context; }; - template ConstantData> to_circuit_type(Composer& composer) const + template CombinedConstantData> to_circuit_type(Composer& composer) const { static_assert((std::is_same::value)); - ConstantData> constant_data = { + CombinedConstantData> constant_data = { historic_tree_roots.to_circuit_type(composer), tx_context.to_circuit_type(composer), }; @@ -39,13 +39,13 @@ template struct ConstantData { return constant_data; }; - template ConstantData to_native_type() const + template CombinedConstantData to_native_type() const { static_assert(std::is_same, NCT>::value); auto to_native_type = [](T& e) { return e.template to_native_type(); }; - ConstantData constant_data = { + CombinedConstantData constant_data = { to_native_type(historic_tree_roots), to_native_type(tx_context), }; @@ -62,7 +62,7 @@ template struct ConstantData { } }; -template void read(uint8_t const*& it, ConstantData& constant_data) +template void read(uint8_t const*& it, CombinedConstantData& constant_data) { using serialize::read; @@ -70,7 +70,7 @@ template void read(uint8_t const*& it, ConstantData& constan read(it, constant_data.tx_context); }; -template void write(std::vector& buf, ConstantData const& constant_data) +template void write(std::vector& buf, CombinedConstantData const& constant_data) { using serialize::write; @@ -78,10 +78,10 @@ template void write(std::vector& buf, ConstantData write(buf, constant_data.tx_context); }; -template std::ostream& operator<<(std::ostream& os, ConstantData const& constant_data) +template std::ostream& operator<<(std::ostream& os, CombinedConstantData const& constant_data) { return os << "historic_tree_roots: " << constant_data.historic_tree_roots << "\n" << "tx_context: " << constant_data.tx_context << "\n"; } -} // namespace aztec3::circuits::abis::private_kernel \ No newline at end of file +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/combined_historic_tree_roots.hpp b/circuits/cpp/src/aztec3/circuits/abis/combined_historic_tree_roots.hpp new file mode 100644 index 00000000000..0218218e12e --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/abis/combined_historic_tree_roots.hpp @@ -0,0 +1,89 @@ +#pragma once +#include +#include +#include +#include +#include "private_historic_tree_roots.hpp" + +namespace aztec3::circuits::abis { + +using aztec3::utils::types::CircuitTypes; +using aztec3::utils::types::NativeTypes; +using plonk::stdlib::witness_t; +using std::is_same; + +template struct CombinedHistoricTreeRoots { + typedef typename NCT::fr fr; + typedef typename NCT::boolean boolean; + + PrivateHistoricTreeRoots private_historic_tree_roots; + fr public_data_tree_root = 0; + + boolean operator==(CombinedHistoricTreeRoots const& other) const + { + return private_historic_tree_roots == other.private_historic_tree_roots && + public_data_tree_root == other.public_data_tree_root; + }; + + template CombinedHistoricTreeRoots> to_circuit_type(Composer& composer) const + { + static_assert((std::is_same::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); }; + + CombinedHistoricTreeRoots> data = { + to_circuit_type(private_historic_tree_roots), + to_ct(public_data_tree_root), + }; + + return data; + }; + + template CombinedHistoricTreeRoots to_native_type() const + { + static_assert(std::is_same, NCT>::value); + auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; + auto to_native_type = [&](T& e) { return e.template to_native_type(); }; + + CombinedHistoricTreeRoots data = { + to_native_type(private_historic_tree_roots), + to_nt(public_data_tree_root), + }; + + return data; + }; + + void set_public() + { + static_assert(!(std::is_same::value)); + + private_historic_tree_roots.set_public(); + public_data_tree_root.set_public(); + } +}; + +template void read(uint8_t const*& it, CombinedHistoricTreeRoots& historic_tree_roots) +{ + using serialize::read; + + read(it, historic_tree_roots.private_historic_tree_roots); + read(it, historic_tree_roots.public_data_tree_root); +}; + +template void write(std::vector& buf, CombinedHistoricTreeRoots const& historic_tree_roots) +{ + using serialize::write; + + write(buf, historic_tree_roots.private_historic_tree_roots); + write(buf, historic_tree_roots.public_data_tree_root); +}; + +template std::ostream& operator<<(std::ostream& os, CombinedHistoricTreeRoots const& historic_tree_roots) +{ + return os << "private_historic_tree_roots: " << historic_tree_roots.private_historic_tree_roots << "\n" + << "public_data_tree_root: " << historic_tree_roots.public_data_tree_root << "\n"; +} + +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/public_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/kernel_circuit_public_inputs.hpp similarity index 68% rename from circuits/cpp/src/aztec3/circuits/abis/private_kernel/public_inputs.hpp rename to circuits/cpp/src/aztec3/circuits/abis/kernel_circuit_public_inputs.hpp index 7006f493491..043d8908842 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/public_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/kernel_circuit_public_inputs.hpp @@ -1,40 +1,42 @@ #pragma once -#include "accumulated_data.hpp" -#include "constant_data.hpp" +#include "combined_accumulated_data.hpp" +#include "combined_constant_data.hpp" #include #include #include #include -namespace aztec3::circuits::abis::private_kernel { +namespace aztec3::circuits::abis { using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; using plonk::stdlib::witness_t; +using std::conditional; using std::is_same; -template struct PublicInputs { +template struct KernelCircuitPublicInputs { typedef typename NCT::fr fr; typedef typename NCT::boolean boolean; - AccumulatedData end{}; - ConstantData constants{}; + CombinedAccumulatedData end{}; + CombinedConstantData constants{}; boolean is_private = true; // TODO: might need to instantiate from witness! - boolean operator==(PublicInputs const& other) const + boolean operator==(KernelCircuitPublicInputs const& other) const { return end == other.end && constants == other.constants && is_private == other.is_private; }; - template PublicInputs> to_circuit_type(Composer& composer) const + template + KernelCircuitPublicInputs> to_circuit_type(Composer& composer) const { static_assert((std::is_same::value)); // Capture the composer: auto to_ct = [&](auto& e) { return aztec3::utils::types::to_ct(composer, e); }; - PublicInputs> private_inputs = { + KernelCircuitPublicInputs> private_inputs = { end.to_circuit_type(composer), constants.to_circuit_type(composer), @@ -44,13 +46,13 @@ template struct PublicInputs { return private_inputs; }; - template PublicInputs to_native_type() const + template KernelCircuitPublicInputs to_native_type() const { static_assert(std::is_same, NCT>::value); auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; auto to_native_type = [](T& e) { return e.template to_native_type(); }; - PublicInputs pis = { + KernelCircuitPublicInputs pis = { to_native_type(end), to_native_type(constants), @@ -71,7 +73,7 @@ template struct PublicInputs { } }; -template void read(uint8_t const*& it, PublicInputs& public_inputs) +template void read(uint8_t const*& it, KernelCircuitPublicInputs& public_inputs) { using serialize::read; @@ -80,7 +82,7 @@ template void read(uint8_t const*& it, PublicInputs& public_ read(it, public_inputs.is_private); }; -template void write(std::vector& buf, PublicInputs const& public_inputs) +template void write(std::vector& buf, KernelCircuitPublicInputs const& public_inputs) { using serialize::write; @@ -89,7 +91,7 @@ template void write(std::vector& buf, PublicInputs write(buf, public_inputs.is_private); }; -template std::ostream& operator<<(std::ostream& os, PublicInputs const& public_inputs) +template std::ostream& operator<<(std::ostream& os, KernelCircuitPublicInputs const& public_inputs) { return os << "end:\n" << public_inputs.end << "\n" @@ -98,4 +100,4 @@ template std::ostream& operator<<(std::ostream& os, PublicInputs< << "is_private: " << public_inputs.is_private << "\n"; } -} // namespace aztec3::circuits::abis::private_kernel \ No newline at end of file +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/new_contract_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/new_contract_data.hpp similarity index 97% rename from circuits/cpp/src/aztec3/circuits/abis/private_kernel/new_contract_data.hpp rename to circuits/cpp/src/aztec3/circuits/abis/new_contract_data.hpp index eb9ba995ce9..9790d606123 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/new_contract_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/new_contract_data.hpp @@ -4,7 +4,7 @@ #include "aztec3/utils/types/circuit_types.hpp" #include "aztec3/utils/types/convert.hpp" #include "barretenberg/stdlib/primitives/witness/witness.hpp" -namespace aztec3::circuits::abis::private_kernel { +namespace aztec3::circuits::abis { using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; @@ -114,4 +114,4 @@ template std::ostream& operator<<(std::ostream& os, NewContractDa template using ContractLeafPreimage = NewContractData; -} // namespace aztec3::circuits::abis::private_kernel \ No newline at end of file +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/previous_kernel_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/previous_kernel_data.hpp similarity index 93% rename from circuits/cpp/src/aztec3/circuits/abis/private_kernel/previous_kernel_data.hpp rename to circuits/cpp/src/aztec3/circuits/abis/previous_kernel_data.hpp index 74fce6048f7..42f697bacdc 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/previous_kernel_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/previous_kernel_data.hpp @@ -1,5 +1,5 @@ #pragma once -#include "aztec3/circuits/abis/private_kernel/public_inputs.hpp" +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" #include #include #include @@ -7,7 +7,7 @@ #include #include -namespace aztec3::circuits::abis::private_kernel { +namespace aztec3::circuits::abis { using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; @@ -20,7 +20,7 @@ template struct PreviousKernelData { typedef typename NCT::VK VK; typedef typename NCT::uint32 uint32; - PublicInputs public_inputs{}; // TODO: not needed as already contained in proof? + KernelCircuitPublicInputs public_inputs{}; // TODO: not needed as already contained in proof? NativeTypes::Proof proof{}; // TODO: how to express proof as native/circuit type when it gets used as a buffer? std::shared_ptr vk; @@ -103,4 +103,4 @@ template std::ostream& operator<<(std::ostream& os, PreviousKerne << "vk_path: " << kernel_data.vk_path << "\n"; } -} // namespace aztec3::circuits::abis::private_kernel \ No newline at end of file +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/historic_tree_roots.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_historic_tree_roots.hpp similarity index 77% rename from circuits/cpp/src/aztec3/circuits/abis/private_kernel/historic_tree_roots.hpp rename to circuits/cpp/src/aztec3/circuits/abis/private_historic_tree_roots.hpp index dea1a37d9ae..a509148ad98 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/historic_tree_roots.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_historic_tree_roots.hpp @@ -4,14 +4,14 @@ #include #include -namespace aztec3::circuits::abis::private_kernel { +namespace aztec3::circuits::abis { using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; using plonk::stdlib::witness_t; using std::is_same; -template struct HistoricTreeRoots { +template struct PrivateHistoricTreeRoots { typedef typename NCT::fr fr; typedef typename NCT::boolean boolean; @@ -20,21 +20,21 @@ template struct HistoricTreeRoots { fr contract_tree_root = 0; fr private_kernel_vk_tree_root = 0; // TODO: future enhancement - boolean operator==(HistoricTreeRoots const& other) const + boolean operator==(PrivateHistoricTreeRoots const& other) const { return private_data_tree_root == other.private_data_tree_root && nullifier_tree_root == other.nullifier_tree_root && contract_tree_root == other.contract_tree_root && private_kernel_vk_tree_root == other.private_kernel_vk_tree_root; }; - template HistoricTreeRoots> to_circuit_type(Composer& composer) const + template PrivateHistoricTreeRoots> to_circuit_type(Composer& composer) const { static_assert((std::is_same::value)); // Capture the composer: auto to_ct = [&](auto& e) { return aztec3::utils::types::to_ct(composer, e); }; - HistoricTreeRoots> data = { + PrivateHistoricTreeRoots> data = { to_ct(private_data_tree_root), to_ct(nullifier_tree_root), to_ct(contract_tree_root), @@ -44,12 +44,12 @@ template struct HistoricTreeRoots { return data; }; - template HistoricTreeRoots to_native_type() const + template PrivateHistoricTreeRoots to_native_type() const { static_assert(std::is_same, NCT>::value); auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; - HistoricTreeRoots data = { + PrivateHistoricTreeRoots data = { to_nt(private_data_tree_root), to_nt(nullifier_tree_root), to_nt(contract_tree_root), @@ -70,7 +70,7 @@ template struct HistoricTreeRoots { } }; -template void read(uint8_t const*& it, HistoricTreeRoots& historic_tree_roots) +template void read(uint8_t const*& it, PrivateHistoricTreeRoots& historic_tree_roots) { using serialize::read; @@ -80,7 +80,7 @@ template void read(uint8_t const*& it, HistoricTreeRoots& hi read(it, historic_tree_roots.private_kernel_vk_tree_root); }; -template void write(std::vector& buf, HistoricTreeRoots const& historic_tree_roots) +template void write(std::vector& buf, PrivateHistoricTreeRoots const& historic_tree_roots) { using serialize::write; @@ -90,7 +90,7 @@ template void write(std::vector& buf, HistoricTreeRoots< write(buf, historic_tree_roots.private_kernel_vk_tree_root); }; -template std::ostream& operator<<(std::ostream& os, HistoricTreeRoots const& historic_tree_roots) +template std::ostream& operator<<(std::ostream& os, PrivateHistoricTreeRoots const& historic_tree_roots) { return os << "private_data_tree_root: " << historic_tree_roots.private_data_tree_root << "\n" << "nullifier_tree_root: " << historic_tree_roots.nullifier_tree_root << "\n" @@ -98,4 +98,4 @@ template std::ostream& operator<<(std::ostream& os, HistoricTreeR << "private_kernel_vk_tree_root: " << historic_tree_roots.private_kernel_vk_tree_root << "\n"; } -} // namespace aztec3::circuits::abis::private_kernel \ No newline at end of file +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_call_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_call_data.hpp index 37dcbe58a3e..c37646d008f 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_call_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_call_data.hpp @@ -5,6 +5,7 @@ #include "call_context_reconciliation_data.hpp" #include "../call_stack_item.hpp" #include "../membership_witness.hpp" +#include "../types.hpp" #include #include @@ -25,9 +26,9 @@ template struct PrivateCallData { typedef typename NCT::boolean boolean; typedef typename NCT::VK VK; - CallStackItem call_stack_item{}; + CallStackItem call_stack_item{}; - std::array, PRIVATE_CALL_STACK_LENGTH> private_call_stack_preimages{}; + std::array, PRIVATE_CALL_STACK_LENGTH> private_call_stack_preimages{}; // std::array, PUBLIC_CALL_STACK_LENGTH> public_call_stack_preimages; @@ -62,7 +63,7 @@ template struct PrivateCallData { auto to_circuit_type = [&](auto& e) { return e.to_circuit_type(composer); }; PrivateCallData> data = { - call_stack_item.to_circuit_type(composer), + to_circuit_type(call_stack_item), map(private_call_stack_preimages, to_circuit_type), @@ -79,7 +80,7 @@ template struct PrivateCallData { return data; }; -}; +}; // namespace aztec3::circuits::abis::private_kernel template void read(uint8_t const*& it, PrivateCallData& obj) { diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_inputs.hpp index e5fa856686b..f978830e127 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_inputs.hpp @@ -1,7 +1,7 @@ #pragma once -#include "accumulated_data.hpp" -#include "previous_kernel_data.hpp" +#include "../combined_accumulated_data.hpp" +#include "../previous_kernel_data.hpp" #include "private_call_data.hpp" #include "../signed_tx_request.hpp" @@ -24,7 +24,7 @@ template struct PrivateInputs { PreviousKernelData previous_kernel{}; PrivateCallData private_call{}; - boolean operator==(PublicInputs const& other) const + boolean operator==(PrivateInputs const& other) const { return signed_tx_request == other.signed_tx_request && previous_kernel == other.previous_kernel && private_call == other.private_call; diff --git a/circuits/cpp/src/aztec3/circuits/abis/public_circuit_public_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/public_circuit_public_inputs.hpp index 0e58caca152..e98985112cf 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/public_circuit_public_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/public_circuit_public_inputs.hpp @@ -35,7 +35,7 @@ template struct PublicCircuitPublicInputs { std::array public_call_stack = zero_array(); std::array l1_msg_stack = zero_array(); - fr historic_private_data_tree_root; + fr historic_public_data_tree_root; address prover_address; @@ -45,7 +45,7 @@ template struct PublicCircuitPublicInputs { emitted_events == other.emitted_events && state_transitions == other.state_transitions && state_reads == other.state_reads && public_call_stack == other.public_call_stack && l1_msg_stack == other.l1_msg_stack && - historic_private_data_tree_root == other.historic_private_data_tree_root && + historic_public_data_tree_root == other.historic_public_data_tree_root && prover_address == other.prover_address; }; @@ -72,7 +72,7 @@ template struct PublicCircuitPublicInputs { .public_call_stack = to_ct(public_call_stack), .l1_msg_stack = to_ct(l1_msg_stack), - .historic_private_data_tree_root = to_ct(historic_private_data_tree_root), + .historic_public_data_tree_root = to_ct(historic_public_data_tree_root), .prover_address = to_ct(prover_address), }; @@ -101,9 +101,9 @@ template struct PublicCircuitPublicInputs { spread_arr_into_vec(public_call_stack, inputs); spread_arr_into_vec(l1_msg_stack, inputs); - inputs.push_back(historic_private_data_tree_root); + inputs.push_back(historic_public_data_tree_root); - return NCT::compress(inputs, GeneratorIndex::PRIVATE_CIRCUIT_PUBLIC_INPUTS); + return NCT::compress(inputs, GeneratorIndex::PUBLIC_CIRCUIT_PUBLIC_INPUTS); } template void spread_arr_into_vec(std::array const& arr, std::vector& vec) const @@ -113,15 +113,15 @@ template struct PublicCircuitPublicInputs { } }; // namespace aztec3::circuits::abis -template void read(uint8_t const*& it, PublicCircuitPublicInputs& private_circuit_public_inputs) +template void read(uint8_t const*& it, PublicCircuitPublicInputs& public_circuit_public_inputs) { using serialize::read; - PublicCircuitPublicInputs& pis = private_circuit_public_inputs; + PublicCircuitPublicInputs& pis = public_circuit_public_inputs; + read(it, pis.call_context); read(it, pis.args); read(it, pis.return_values); read(it, pis.emitted_events); - read(it, pis.emitted_ouputs); read(it, pis.state_transitions); read(it, pis.state_reads); @@ -129,22 +129,22 @@ template void read(uint8_t const*& it, PublicCircuitPublicInputs< read(it, pis.public_call_stack); read(it, pis.l1_msg_stack); - read(it, pis.historic_private_data_tree_root); + read(it, pis.historic_public_data_tree_root); read(it, pis.prover_address); }; template -void write(std::vector& buf, PublicCircuitPublicInputs const& private_circuit_public_inputs) +void write(std::vector& buf, PublicCircuitPublicInputs const& public_circuit_public_inputs) { using serialize::write; - PublicCircuitPublicInputs const& pis = private_circuit_public_inputs; + PublicCircuitPublicInputs const& pis = public_circuit_public_inputs; + write(buf, pis.call_context); write(buf, pis.args); write(buf, pis.return_values); write(buf, pis.emitted_events); - write(buf, pis.emitted_ouputs); write(buf, pis.state_transitions); write(buf, pis.state_reads); @@ -152,17 +152,18 @@ void write(std::vector& buf, PublicCircuitPublicInputs const& priv write(buf, pis.public_call_stack); write(buf, pis.l1_msg_stack); - write(buf, pis.historic_private_data_tree_root); + write(buf, pis.historic_public_data_tree_root); write(buf, pis.prover_address); }; template -std::ostream& operator<<(std::ostream& os, PublicCircuitPublicInputs const& private_circuit_public_inputs) +std::ostream& operator<<(std::ostream& os, PublicCircuitPublicInputs const& public_circuit_public_inputs) { - PublicCircuitPublicInputs const& pis = private_circuit_public_inputs; - return os << "args: " << pis.args << "\n" + PublicCircuitPublicInputs const& pis = public_circuit_public_inputs; + return os << "call_context: " << pis.call_context << "\n" + << "args: " << pis.args << "\n" << "return_values: " << pis.return_values << "\n" << "emitted_events: " << pis.emitted_events << "\n" @@ -172,7 +173,7 @@ std::ostream& operator<<(std::ostream& os, PublicCircuitPublicInputs const& << "public_call_stack: " << pis.public_call_stack << "\n" << "l1_msg_stack: " << pis.l1_msg_stack << "\n" - << "historic_private_data_tree_root: " << pis.historic_private_data_tree_root << "\n" + << "historic_public_data_tree_root: " << pis.historic_public_data_tree_root << "\n" << "prover_address: " << pis.prover_address << "\n"; } diff --git a/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_call_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_call_data.hpp new file mode 100644 index 00000000000..8dc2f28638f --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_call_data.hpp @@ -0,0 +1,122 @@ +#pragma once + +#include "aztec3/constants.hpp" +#include "aztec3/utils/array.hpp" +#include "../call_stack_item.hpp" +#include "../types.hpp" + +#include +#include +#include +#include +#include + +namespace aztec3::circuits::abis::public_kernel { + +using aztec3::utils::types::CircuitTypes; +using aztec3::utils::types::NativeTypes; +using plonk::stdlib::witness_t; +using std::is_same; + +template struct PublicCallData { + typedef typename NCT::address address; + typedef typename NCT::fr fr; + typedef typename NCT::boolean boolean; + typedef typename NCT::VK VK; + + CallStackItem call_stack_item{}; + + std::array, PUBLIC_CALL_STACK_LENGTH> public_call_stack_preimages{}; + + NativeTypes::Proof proof{}; // TODO: how to express proof as native/circuit type when it gets used as a buffer? + + fr portal_contract_address = 0; // an ETH address + fr bytecode_hash = 0; + + boolean operator==(PublicCallData const& other) const + { + // WARNING: proof skipped! + return call_stack_item == other.call_stack_item && + public_call_stack_preimages == other.public_call_stack_preimages && + portal_contract_address == other.portal_contract_address && bytecode_hash == other.bytecode_hash; + }; + + // WARNING: the `proof` does NOT get converted! (because the current implementation of `verify_proof` takes a proof + // of native bytes; any conversion to circuit types happens within the `verify_proof` function) + template PublicCallData> to_circuit_type(Composer& composer) const + { + // typedef CircuitTypes CT; + static_assert((std::is_same::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); }; + + PublicCallData> data = { + call_stack_item.to_circuit_type(composer), + + map(public_call_stack_preimages, to_circuit_type), + + proof, // Notice: not converted! Stays as native. This is because of how the verify_proof function + // currently works. + // CT::VK::from_witness(&composer, vk), + + // to_circuit_type(function_leaf_membership_witness), + // to_circuit_type(contract_leaf_membership_witness), + + to_ct(portal_contract_address), + to_ct(bytecode_hash), + }; + + return data; + }; +}; + +template void read(uint8_t const*& it, PublicCallData& obj) +{ + using serialize::read; + + read(it, obj.call_stack_item); + read(it, obj.private_call_stack_preimages); + read(it, obj.proof); + read(it, obj.vk); + read(it, obj.function_leaf_membership_witness); + read(it, obj.contract_leaf_membership_witness); + read(it, obj.portal_contract_address); + read(it, obj.acir_hash); +}; + +template void write(std::vector& buf, PublicCallData const& obj) +{ + using serialize::write; + + write(buf, obj.call_stack_item); + write(buf, obj.private_call_stack_preimages); + write(buf, obj.proof); + write(buf, *obj.vk); + write(buf, obj.function_leaf_membership_witness); + write(buf, obj.contract_leaf_membership_witness); + write(buf, obj.portal_contract_address); + write(buf, obj.acir_hash); +}; + +template std::ostream& operator<<(std::ostream& os, PublicCallData const& obj) +{ + return os << "call_stack_item:\n" + << obj.call_stack_item << "\n" + << "public_call_stack_preimages:\n" + << obj.public_call_stack_preimages << "\n" + << "proof:\n" + << obj.proof + << "\n" + //<< "vk:\n" + //<< *(obj.vk) << "\n" + //<< "function_leaf_membership_witness:\n" + //<< obj.function_leaf_membership_witness << "\n" + //<< "contract_leaf_membership_witness:\n" + //<< obj.contract_leaf_membership_witness << "\n" + << "portal_contract_address: " << obj.portal_contract_address << "\n" + << "bytecode_hash: " << obj.bytecode_hash << "\n"; +} + +} // namespace aztec3::circuits::abis::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs.hpp new file mode 100644 index 00000000000..c783de20d97 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include "../previous_kernel_data.hpp" +#include "public_call_data.hpp" +#include "../signed_tx_request.hpp" + +#include +#include +#include +#include + +namespace aztec3::circuits::abis::public_kernel { + +using aztec3::utils::types::CircuitTypes; +using aztec3::utils::types::NativeTypes; +using std::is_same; + +template struct PublicKernelInputs { + typedef typename NCT::fr fr; + typedef typename NCT::boolean boolean; + + PreviousKernelData previous_kernel{}; + PublicCallData public_call{}; + + boolean operator==(PublicKernelInputs const& other) const + { + return previous_kernel == other.previous_kernel && public_call == other.public_call; + }; + + template PublicKernelInputs> to_circuit_type(Composer& composer) const + { + static_assert((std::is_same::value)); + + PublicKernelInputs> public_kernel_inputs = { + previous_kernel.to_circuit_type(composer), + public_call.to_circuit_type(composer), + }; + + return public_kernel_inputs; + }; +}; + +template void read(uint8_t const*& it, PublicKernelInputs& public_kernel_inputs) +{ + using serialize::read; + + read(it, public_kernel_inputs.previous_kernel); + read(it, public_kernel_inputs.public_call); +}; + +template void write(std::vector& buf, PublicKernelInputs const& public_kernel_inputs) +{ + using serialize::write; + + write(buf, public_kernel_inputs.previous_kernel); + write(buf, public_kernel_inputs.public_call); +}; + +template std::ostream& operator<<(std::ostream& os, PublicKernelInputs const& public_kernel_inputs) +{ + return os << "previous_kernel:\n" + << public_kernel_inputs.previous_kernel << "\n" + << "public_call:\n" + << public_kernel_inputs.public_call << "\n"; +} + +} // namespace aztec3::circuits::abis::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs_no_previous_kernel.hpp b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs_no_previous_kernel.hpp new file mode 100644 index 00000000000..eb0ce7c1d3c --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/public_kernel_inputs_no_previous_kernel.hpp @@ -0,0 +1,71 @@ +#pragma once + +#include "../previous_kernel_data.hpp" +#include "public_call_data.hpp" +#include "witnessed_public_call_data.hpp" + +#include +#include +#include +#include + +namespace aztec3::circuits::abis::public_kernel { + +using aztec3::utils::types::CircuitTypes; +using aztec3::utils::types::NativeTypes; +using std::is_same; + +template struct PublicKernelInputsNoKernelInput { + typedef typename NCT::fr fr; + typedef typename NCT::boolean boolean; + + SignedTxRequest signed_tx_request{}; + WitnessedPublicCallData public_call{}; + + boolean operator==(PublicKernelInputsNoKernelInput const& other) const + { + return signed_tx_request == other.signed_tx_request && public_call == other.public_call; + }; + + template + PublicKernelInputsNoKernelInput> to_circuit_type(Composer& composer) const + { + static_assert((std::is_same::value)); + + PublicKernelInputsNoKernelInput> public_kernel_inputs = { + // TODO to_ct(signature), + signed_tx_request.to_circuit_type(composer), + public_call.to_circuit_type(composer), + }; + + return public_kernel_inputs; + }; +}; + +template void read(uint8_t const*& it, PublicKernelInputsNoKernelInput& public_kernel_inputs) +{ + using serialize::read; + + read(it, public_kernel_inputs.signed_tx_request); + read(it, public_kernel_inputs.public_call); +}; + +template +void write(std::vector& buf, PublicKernelInputsNoKernelInput const& public_kernel_inputs) +{ + using serialize::write; + + write(buf, public_kernel_inputs.signed_tx_request); + write(buf, public_kernel_inputs.public_call); +}; + +template +std::ostream& operator<<(std::ostream& os, PublicKernelInputsNoKernelInput const& public_kernel_inputs) +{ + return os << "signed_tx_request:\n" + << public_kernel_inputs.signed_tx_request << "\n" + << "public_call:\n" + << public_kernel_inputs.public_call << "\n"; +} + +} // namespace aztec3::circuits::abis::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/public_kernel/witnessed_public_call_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/witnessed_public_call_data.hpp new file mode 100644 index 00000000000..4be78a959b5 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/abis/public_kernel/witnessed_public_call_data.hpp @@ -0,0 +1,86 @@ +#pragma once + +#include "../previous_kernel_data.hpp" +#include "public_call_data.hpp" +#include "../signed_tx_request.hpp" +#include "../membership_witness.hpp" + +#include +#include +#include +#include + +namespace aztec3::circuits::abis::public_kernel { + +using aztec3::utils::types::CircuitTypes; +using aztec3::utils::types::NativeTypes; +using std::is_same; + +template struct WitnessedPublicCallData { + typedef typename NCT::fr fr; + typedef typename NCT::boolean boolean; + + PublicCallData public_call_data; + std::array, STATE_TRANSITIONS_LENGTH> + state_transitions_sibling_paths; + std::array, STATE_READS_LENGTH> state_reads_sibling_paths; + fr public_data_tree_root; + + boolean operator==(WitnessedPublicCallData const& other) const + { + return public_call_data == other.public_call_data && + state_transitions_sibling_paths == other.state_transitions_sibling_paths && + state_reads_sibling_paths == other.state_reads_sibling_paths && + public_data_tree_root == other.public_data_tree_root; + }; + + template + WitnessedPublicCallData> to_circuit_type(Composer& composer) const + { + static_assert((std::is_same::value)); + + WitnessedPublicCallData> witnessed_call_data = { + // TODO to_ct(signature), + public_call_data.to_circuit_type(composer), + state_transitions_sibling_paths.to_circuit_type(composer), + state_reads_sibling_paths.to_circuit_type(composer), + public_data_tree_root.to_circuit_type(composer), + }; + + return witnessed_call_data; + }; +}; + +template void read(uint8_t const*& it, WitnessedPublicCallData& witnessed_call_data) +{ + using serialize::read; + + read(it, witnessed_call_data.public_call_data); + read(it, witnessed_call_data.state_transitions_sibling_paths); + read(it, witnessed_call_data.state_reads_sibling_paths); + read(it, witnessed_call_data.public_data_tree_root); +}; + +template void write(std::vector& buf, WitnessedPublicCallData& witnessed_call_data) +{ + using serialize::write; + + write(buf, witnessed_call_data.public_call_data); + write(buf, witnessed_call_data.state_transitions_sibling_paths); + write(buf, witnessed_call_data.state_reads_sibling_paths); + write(buf, witnessed_call_data.public_data_tree_root); +}; + +template std::ostream& operator<<(std::ostream& os, WitnessedPublicCallData& witnessed_call_data) +{ + return os << "public_call_data:\n" + << witnessed_call_data.public_call_data << "\n" + << "state_transitions_sibling_paths:\n" + << witnessed_call_data.state_transitions_sibling_paths << "\n" + << "state_reads_sibling_paths:\n" + << witnessed_call_data.state_reads_sibling_paths << "\n" + << "public_data_tree_root:\n" + << public_kernel_inputs.public_data_tree_root << "\n"; +} + +} // namespace aztec3::circuits::abis::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_or_merge_rollup_public_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_or_merge_rollup_public_inputs.hpp index 88923618111..c86ecc37273 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_or_merge_rollup_public_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_or_merge_rollup_public_inputs.hpp @@ -37,6 +37,9 @@ template struct BaseOrMergeRollupPublicInputs { AppendOnlyTreeSnapshot start_contract_tree_snapshot; AppendOnlyTreeSnapshot end_contract_tree_snapshot; + AppendOnlyTreeSnapshot start_public_data_tree_snapshot; + AppendOnlyTreeSnapshot end_public_data_tree_snapshot; + // Hashes (probably sha256) to make public inputs constant-sized (to then be unpacked on-chain) // Needs to be two fields to accomodate all 256-bits of the hash std::array calldata_hash; @@ -58,6 +61,8 @@ template void read(uint8_t const*& it, BaseOrMergeRollupPublicInp read(it, obj.end_nullifier_tree_snapshot); read(it, obj.start_contract_tree_snapshot); read(it, obj.end_contract_tree_snapshot); + read(it, obj.start_public_data_tree_snapshot); + read(it, obj.end_public_data_tree_snapshot); read(it, obj.calldata_hash); }; @@ -75,6 +80,8 @@ template void write(std::vector& buf, BaseOrMergeRollupP write(buf, obj.end_nullifier_tree_snapshot); write(buf, obj.start_contract_tree_snapshot); write(buf, obj.end_contract_tree_snapshot); + write(buf, obj.start_public_data_tree_snapshot); + write(buf, obj.end_public_data_tree_snapshot); write(buf, obj.calldata_hash); }; @@ -107,6 +114,12 @@ template std::ostream& operator<<(std::ostream& os, BaseOrMergeRo << "\n" "end_contract_tree_snapshot:\n" << obj.end_contract_tree_snapshot + << "\n" + "start_public_data_tree_snapshot:\n" + << obj.start_public_data_tree_snapshot + << "\n" + "end_public_data_tree_snapshot:\n" + << obj.end_public_data_tree_snapshot << "\n" "calldata_hash: " << obj.calldata_hash << "\n"; diff --git a/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_rollup_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_rollup_inputs.hpp index bdaf8e88ac6..93fbe8f7f43 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_rollup_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/rollup/base/base_rollup_inputs.hpp @@ -1,6 +1,6 @@ #pragma once #include "../../append_only_tree_snapshot.hpp" -#include "../../private_kernel/previous_kernel_data.hpp" +#include "../../previous_kernel_data.hpp" #include "../../membership_witness.hpp" #include "../nullifier_leaf_preimage.hpp" #include "../constant_rollup_data.hpp" @@ -17,11 +17,12 @@ template struct BaseRollupInputs { typedef typename NCT::fr fr; - std::array, 2> kernel_data; + std::array, 2> kernel_data; AppendOnlyTreeSnapshot start_private_data_tree_snapshot; AppendOnlyTreeSnapshot start_nullifier_tree_snapshot; AppendOnlyTreeSnapshot start_contract_tree_snapshot; + AppendOnlyTreeSnapshot start_public_data_tree_snapshot; std::array, 2 * KERNEL_NEW_NULLIFIERS_LENGTH> low_nullifier_leaf_preimages; std::array, 2 * KERNEL_NEW_NULLIFIERS_LENGTH> @@ -32,6 +33,8 @@ template struct BaseRollupInputs { std::array new_commitments_subtree_sibling_path; std::array new_nullifiers_subtree_sibling_path; std::array new_contracts_subtree_sibling_path; + std::array, 2 * STATE_TRANSITIONS_LENGTH> + new_state_transitions_sibling_paths; std::array, 2> historic_private_data_tree_root_membership_witnesses; @@ -51,11 +54,13 @@ template void read(uint8_t const*& it, BaseRollupInputs& obj read(it, obj.start_private_data_tree_snapshot); read(it, obj.start_nullifier_tree_snapshot); read(it, obj.start_contract_tree_snapshot); + read(it, obj.start_public_data_tree_snapshot); read(it, obj.low_nullifier_leaf_preimages); read(it, obj.low_nullifier_membership_witness); read(it, obj.new_commitments_subtree_sibling_path); read(it, obj.new_nullifiers_subtree_sibling_path); read(it, obj.new_contracts_subtree_sibling_path); + read(it, obj.new_state_transitions_sibling_paths); read(it, obj.historic_private_data_tree_root_membership_witnesses); read(it, obj.historic_contract_tree_root_membership_witnesses); read(it, obj.constants); @@ -69,11 +74,13 @@ template void write(std::vector& buf, BaseRollupInputs std::ostream& operator<<(std::ostream& os, BaseRollupInp << obj.start_nullifier_tree_snapshot << "\n" << "start_contract_tree_snapshot:\n" << obj.start_contract_tree_snapshot << "\n" + << "start_public_data_tree_snapshot:\n" + << obj.start_public_data_tree_snapshot << "\n" << "low_nullifier_leaf_preimages:\n" << obj.low_nullifier_leaf_preimages << "\n" << "low_nullifier_membership_witness:\n" @@ -99,6 +108,8 @@ template std::ostream& operator<<(std::ostream& os, BaseRollupInp << obj.new_nullifiers_subtree_sibling_path << "\n" << "new_contracts_subtree_sibling_path:\n" << obj.new_contracts_subtree_sibling_path << "\n" + << "new_state_transitions_sibling_paths:\n" + << obj.new_state_transitions_sibling_paths << "\n" << "historic_private_data_tree_root_membership_witnesses:\n" << obj.historic_private_data_tree_root_membership_witnesses << "\n" << "historic_contract_tree_root_membership_witnesses:\n" diff --git a/circuits/cpp/src/aztec3/circuits/abis/state_read.hpp b/circuits/cpp/src/aztec3/circuits/abis/state_read.hpp index 8c9bd74b5d5..e512cc99f5c 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/state_read.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/state_read.hpp @@ -33,6 +33,20 @@ template struct StateRead { return state_read; }; + template StateRead to_native_type() const + { + static_assert((std::is_same, NCT>::value)); + + auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; + + StateRead state_read = { + to_nt(storage_slot), + to_nt(current_value), + }; + + return state_read; + }; + fr hash() const { std::vector inputs = { @@ -42,13 +56,21 @@ template struct StateRead { return NCT::compress(inputs, GeneratorIndex::STATE_READ); } + + void set_public() + { + static_assert(!(std::is_same::value)); + + storage_slot.set_public(); + current_value.set_public(); + } }; template void read(uint8_t const*& it, StateRead& state_read) { using serialize::read; - read(it, state_read.l1_result_hash); + read(it, state_read.storage_slot); read(it, state_read.current_value); }; diff --git a/circuits/cpp/src/aztec3/circuits/abis/state_transition.hpp b/circuits/cpp/src/aztec3/circuits/abis/state_transition.hpp index 576fe719d3e..29c72967c15 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/state_transition.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/state_transition.hpp @@ -35,6 +35,21 @@ template struct StateTransition { return state_transition; }; + template StateTransition to_native_type() const + { + static_assert((std::is_same, NCT>::value)); + + auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; + + StateTransition state_transition = { + to_nt(storage_slot), + to_nt(old_value), + to_nt(new_value), + }; + + return state_transition; + }; + fr hash() const { std::vector inputs = { @@ -45,13 +60,22 @@ template struct StateTransition { return NCT::compress(inputs, GeneratorIndex::STATE_TRANSITION); } + + void set_public() + { + static_assert(!(std::is_same::value)); + + storage_slot.set_public(); + old_value.set_public(); + new_value.set_public(); + } }; template void read(uint8_t const*& it, StateTransition& state_transition) { using serialize::read; - read(it, state_transition.l1_result_hash); + read(it, state_transition.storage_slot); read(it, state_transition.old_value); read(it, state_transition.new_value); }; diff --git a/circuits/cpp/src/aztec3/circuits/abis/types.hpp b/circuits/cpp/src/aztec3/circuits/abis/types.hpp new file mode 100644 index 00000000000..c349f07dfa8 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/abis/types.hpp @@ -0,0 +1,25 @@ +#pragma once +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "private_circuit_public_inputs.hpp" +#include "public_circuit_public_inputs.hpp" + +namespace aztec3::circuits::abis { + +template struct PrivateTypes { + typedef PrivateCircuitPublicInputs AppCircuitPublicInputs; +}; + +template struct PublicTypes { + typedef PublicCircuitPublicInputs AppCircuitPublicInputs; +}; +} // namespace aztec3::circuits::abis \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/apps/function_execution_context.hpp b/circuits/cpp/src/aztec3/circuits/apps/function_execution_context.hpp index 26413df1a19..7d28615ca32 100644 --- a/circuits/cpp/src/aztec3/circuits/apps/function_execution_context.hpp +++ b/circuits/cpp/src/aztec3/circuits/apps/function_execution_context.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include @@ -22,10 +23,10 @@ namespace aztec3::circuits::apps { using aztec3::circuits::abis::CallStackItem; -using aztec3::circuits::abis::CallType; using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::OptionalPrivateCircuitPublicInputs; using aztec3::circuits::abis::PrivateCircuitPublicInputs; +using aztec3::circuits::abis::PrivateTypes; using aztec3::circuits::apps::notes::NoteInterface; using aztec3::circuits::apps::opcodes::Opcodes; @@ -113,12 +114,12 @@ template class FunctionExecutionContext { /** * @brief Get the call_stack_item representing `this` exec_ctx's function call. */ - CallStackItem get_call_stack_item() + CallStackItem get_call_stack_item() { const NT::address& actual_contract_address = oracle.native_oracle.get_actual_contract_address(); const FunctionData& function_data = oracle.native_oracle.get_function_data(); - return CallStackItem{ + return CallStackItem{ .contract_address = actual_contract_address, .function_data = function_data, .public_inputs = get_final_private_circuit_public_inputs(), @@ -128,9 +129,9 @@ template class FunctionExecutionContext { /** * @brief Get the call_stack_items of any nested function calls made by this exec_ctx's function. */ - std::array, PRIVATE_CALL_STACK_LENGTH> get_private_call_stack_items() + std::array, PRIVATE_CALL_STACK_LENGTH> get_private_call_stack_items() { - std::array, PRIVATE_CALL_STACK_LENGTH> result; + std::array, PRIVATE_CALL_STACK_LENGTH> result; for (size_t i = 0; i < result.size(); ++i) { auto& nested_exec_ctx = nested_private_call_exec_ctxs[i]; @@ -139,7 +140,7 @@ template class FunctionExecutionContext { nested_exec_ctx->oracle.native_oracle.get_actual_contract_address(); const FunctionData& function_data = nested_exec_ctx->oracle.native_oracle.get_function_data(); - result[i] = CallStackItem{ + result[i] = CallStackItem{ .contract_address = actual_contract_address, .function_data = function_data, .public_inputs = nested_exec_ctx->get_final_private_circuit_public_inputs(), @@ -239,7 +240,7 @@ template class FunctionExecutionContext { args[i].assert_equal(f_public_inputs_ct.args[i]); } - CallStackItem f_call_stack_item_ct{ + CallStackItem f_call_stack_item_ct{ .contract_address = f_contract_address, .function_data = f_function_data_ct, .public_inputs = f_public_inputs_ct, diff --git a/circuits/cpp/src/aztec3/circuits/hash.hpp b/circuits/cpp/src/aztec3/circuits/hash.hpp index fcfde09f174..08de69fd07e 100644 --- a/circuits/cpp/src/aztec3/circuits/hash.hpp +++ b/circuits/cpp/src/aztec3/circuits/hash.hpp @@ -1,14 +1,14 @@ #include #include #include "aztec3/circuits/abis/function_leaf_preimage.hpp" -#include +#include #include namespace aztec3::circuits { using abis::FunctionData; +using aztec3::circuits::abis::ContractLeafPreimage; using aztec3::circuits::abis::FunctionLeafPreimage; -using aztec3::circuits::abis::private_kernel::ContractLeafPreimage; template typename NCT::fr compute_args_hash(std::array args) { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 05458edd504..a08979f53e4 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -18,11 +18,12 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include +#include #include "aztec3/circuits/kernel/private/utils.hpp" #include @@ -37,24 +38,25 @@ namespace { using aztec3::circuits::compute_empty_sibling_path; using aztec3::circuits::abis::CallContext; using aztec3::circuits::abis::CallStackItem; -using aztec3::circuits::abis::CallType; using aztec3::circuits::abis::ContractDeploymentData; using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::FunctionLeafPreimage; +using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::OptionalPrivateCircuitPublicInputs; using aztec3::circuits::abis::PrivateCircuitPublicInputs; +using aztec3::circuits::abis::PrivateTypes; using aztec3::circuits::abis::SignedTxRequest; using aztec3::circuits::abis::TxContext; using aztec3::circuits::abis::TxRequest; -using aztec3::circuits::abis::private_kernel::NewContractData; -using aztec3::circuits::abis::private_kernel::AccumulatedData; -using aztec3::circuits::abis::private_kernel::ConstantData; -using aztec3::circuits::abis::private_kernel::HistoricTreeRoots; -using aztec3::circuits::abis::private_kernel::PreviousKernelData; +using aztec3::circuits::abis::CombinedAccumulatedData; +using aztec3::circuits::abis::CombinedConstantData; +using aztec3::circuits::abis::CombinedHistoricTreeRoots; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::PreviousKernelData; +using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::PrivateCallData; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; using aztec3::circuits::apps::test_apps::basic_contract_deployment::constructor; using aztec3::circuits::apps::test_apps::escrow::deposit; @@ -322,7 +324,7 @@ PrivateInputs do_private_call_get_kernel_inputs(bool const is_constructor, // verify in the first round of recursion, OR, we have some fiddly conditional logic in the circuit to ignore // certain checks if we're handling the 'base case' of the recursion. // I've chosen the former, for now. - const CallStackItem call_stack_item{ + const CallStackItem call_stack_item{ .contract_address = tx_request.to, .function_data = tx_request.function_data, .public_inputs = private_circuit_public_inputs, @@ -335,13 +337,14 @@ PrivateInputs do_private_call_get_kernel_inputs(bool const is_constructor, auto mock_previous_kernel = utils::dummy_previous_kernel(real_kernel_circuit); // Fill in some important fields in public inputs mock_previous_kernel.public_inputs.end.private_call_stack = initial_kernel_private_call_stack; - mock_previous_kernel.public_inputs.constants = ConstantData{ + mock_previous_kernel.public_inputs.constants = CombinedConstantData{ .historic_tree_roots = - HistoricTreeRoots{ - .private_data_tree_root = private_circuit_public_inputs.historic_private_data_tree_root, - // .nullifier_tree_root = - .contract_tree_root = private_circuit_public_inputs.historic_contract_tree_root, - // .private_kernel_vk_tree_root = + CombinedHistoricTreeRoots { + .private_historic_tree_roots = + PrivateHistoricTreeRoots{ + .private_data_tree_root = private_circuit_public_inputs.historic_private_data_tree_root, + .contract_tree_root = private_circuit_public_inputs.historic_contract_tree_root, + }, }, .tx_context = tx_request.tx_context, }; @@ -389,7 +392,8 @@ PrivateInputs do_private_call_get_kernel_inputs(bool const is_constructor, * @param private_inputs to be used in manual computation * @param public_inputs that contain the expected new contract address */ -void validate_deployed_contract_address(PrivateInputs const& private_inputs, PublicInputs const& public_inputs) +void validate_deployed_contract_address(PrivateInputs const& private_inputs, + KernelCircuitPublicInputs const& public_inputs) { auto tx_request = private_inputs.signed_tx_request.tx_request; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index 7db4b9d83cb..fbbf2b90f7f 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -9,7 +9,7 @@ #include "aztec3/circuits/abis/signed_tx_request.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include -#include +#include #include "aztec3/circuits/kernel/private/utils.hpp" #include @@ -21,15 +21,15 @@ namespace { using NT = aztec3::utils::types::NativeTypes; using DummyComposer = aztec3::utils::DummyComposer; +using aztec3::circuits::abis::CombinedAccumulatedData; +using aztec3::circuits::abis::CombinedConstantData; +using aztec3::circuits::abis::CombinedHistoricTreeRoots; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::PreviousKernelData; using aztec3::circuits::abis::SignedTxRequest; using aztec3::circuits::abis::TxContext; -using aztec3::circuits::abis::private_kernel::AccumulatedData; -using aztec3::circuits::abis::private_kernel::ConstantData; -using aztec3::circuits::abis::private_kernel::HistoricTreeRoots; -using aztec3::circuits::abis::private_kernel::PreviousKernelData; using aztec3::circuits::abis::private_kernel::PrivateCallData; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::utils::dummy_previous_kernel; @@ -108,10 +108,10 @@ WASM_EXPORT size_t private_kernel__sim(uint8_t const* signed_tx_request_buf, previous_kernel = dummy_previous_kernel(); previous_kernel.public_inputs.end.private_call_stack[0] = private_call_data.call_stack_item.hash(); - previous_kernel.public_inputs.constants.historic_tree_roots.private_data_tree_root = + previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.private_data_tree_root = private_call_data.call_stack_item.public_inputs.historic_private_data_tree_root; // previous_kernel.public_inputs.constants.historic_tree_roots.nullifier_tree_root = - previous_kernel.public_inputs.constants.historic_tree_roots.contract_tree_root = + previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.contract_tree_root = private_call_data.call_stack_item.public_inputs.historic_contract_tree_root; // previous_kernel.public_inputs.constants.historic_tree_roots.private_kernel_vk_tree_root = previous_kernel.public_inputs.constants.tx_context = signed_tx_request.tx_request.tx_context; @@ -126,7 +126,7 @@ WASM_EXPORT size_t private_kernel__sim(uint8_t const* signed_tx_request_buf, .private_call = private_call_data, }; - PublicInputs public_inputs = native_private_kernel_circuit(composer, private_inputs); + KernelCircuitPublicInputs public_inputs = native_private_kernel_circuit(composer, private_inputs); // serialize public inputs to bytes vec std::vector public_inputs_vec; @@ -163,9 +163,9 @@ WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, previous_kernel = dummy_previous_kernel(true); previous_kernel.public_inputs.end.private_call_stack[0] = private_call_data.call_stack_item.hash(); - previous_kernel.public_inputs.constants.historic_tree_roots.private_data_tree_root = + previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.private_data_tree_root = private_call_data.call_stack_item.public_inputs.historic_private_data_tree_root; - previous_kernel.public_inputs.constants.historic_tree_roots.contract_tree_root = + previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.contract_tree_root = private_call_data.call_stack_item.public_inputs.historic_contract_tree_root; previous_kernel.public_inputs.constants.tx_context = signed_tx_request.tx_request.tx_context; previous_kernel.public_inputs.is_private = true; @@ -181,7 +181,7 @@ WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, Composer private_kernel_composer = Composer(crs_factory); plonk::stdlib::types::Prover private_kernel_prover = private_kernel_composer.create_prover(); - PublicInputs public_inputs; + KernelCircuitPublicInputs public_inputs; public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); NT::Proof private_kernel_proof; private_kernel_proof = private_kernel_prover.construct_proof(); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 5e5e1a68c7a..a599dc474cd 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -2,8 +2,8 @@ #include "aztec3/circuits/abis/function_leaf_preimage.hpp" #include -#include -#include +#include +#include #include #include @@ -14,10 +14,10 @@ namespace aztec3::circuits::kernel::private_kernel { -using aztec3::circuits::abis::private_kernel::ContractLeafPreimage; -using aztec3::circuits::abis::private_kernel::NewContractData; +using aztec3::circuits::abis::ContractLeafPreimage; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; using aztec3::utils::array_length; using aztec3::utils::array_pop; @@ -53,7 +53,7 @@ using aztec3::circuits::function_tree_root_from_siblings; // return aggregation_object; // } -void initialise_end_values(PrivateInputs const& private_inputs, PublicInputs& public_inputs) +void initialise_end_values(PrivateInputs const& private_inputs, KernelCircuitPublicInputs& public_inputs) { public_inputs.constants = private_inputs.previous_kernel.public_inputs.constants; @@ -72,7 +72,9 @@ void initialise_end_values(PrivateInputs const& private_inputs, PublicInputs end.optionally_revealed_data = start.optionally_revealed_data; } -void contract_logic(DummyComposer& composer, PrivateInputs const& private_inputs, PublicInputs& public_inputs) +void contract_logic(DummyComposer& composer, + PrivateInputs const& private_inputs, + KernelCircuitPublicInputs& public_inputs) { const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; @@ -142,7 +144,7 @@ void contract_logic(DummyComposer& composer, PrivateInputs const& private_in auto const& purported_contract_tree_root = private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; auto const& previous_kernel_contract_tree_root = - private_inputs.previous_kernel.public_inputs.constants.historic_tree_roots.contract_tree_root; + private_inputs.previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.contract_tree_root; composer.do_assert(purported_contract_tree_root == previous_kernel_contract_tree_root, "purported_contract_tree_root doesn't match previous_kernel_contract_tree_root"); @@ -170,7 +172,7 @@ void contract_logic(DummyComposer& composer, PrivateInputs const& private_in void update_end_values(DummyComposer& composer, PrivateInputs const& private_inputs, - PublicInputs& public_inputs) + KernelCircuitPublicInputs& public_inputs) { const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; @@ -325,10 +327,11 @@ void validate_inputs(DummyComposer& composer, PrivateInputs const& private_i // TODO: decide what to return. // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. -PublicInputs native_private_kernel_circuit(DummyComposer& composer, PrivateInputs const& private_inputs) +KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, + PrivateInputs const& private_inputs) { // We'll be pushing data to this during execution of this circuit. - PublicInputs public_inputs{}; + KernelCircuitPublicInputs public_inputs{}; // Do this before any functions can modify the inputs. initialise_end_values(private_inputs, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp index 819370ea8cb..56c00ddcbc6 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp @@ -3,17 +3,18 @@ #include "init.hpp" #include -#include +#include #include namespace aztec3::circuits::kernel::private_kernel { +using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; // using abis::private_kernel::PublicInputs; using DummyComposer = aztec3::utils::DummyComposer; // TODO: decide what to return. -PublicInputs native_private_kernel_circuit(DummyComposer& composer, PrivateInputs const& _private_inputs); +KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, + PrivateInputs const& _private_inputs); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp index e17c4dbbcc6..a7148faad66 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp @@ -4,16 +4,16 @@ #include #include -#include -#include +#include +#include #include namespace aztec3::circuits::kernel::private_kernel { -using aztec3::circuits::abis::private_kernel::NewContractData; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; using plonk::stdlib::array_length; using plonk::stdlib::array_pop; @@ -56,7 +56,7 @@ CT::AggregationObject verify_proofs(Composer& composer, * as well as signed TX request and the private call information * @param public_inputs should be empty here since it is being initialized in this call */ -void initialise_end_values(PrivateInputs const& private_inputs, PublicInputs& public_inputs) +void initialise_end_values(PrivateInputs const& private_inputs, KernelCircuitPublicInputs& public_inputs) { // TODO: Ensure public inputs is empty here public_inputs.constants = private_inputs.previous_kernel.public_inputs.constants; @@ -90,7 +90,7 @@ void initialise_end_values(PrivateInputs const& private_inputs, PublicInputs * and update its running callstack with all items in the current private-circuit/function's * callstack. */ -void update_end_values(PrivateInputs const& private_inputs, PublicInputs& public_inputs) +void update_end_values(PrivateInputs const& private_inputs, KernelCircuitPublicInputs& public_inputs) { const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; @@ -321,12 +321,12 @@ void validate_inputs(PrivateInputs const& private_inputs) // TODO: decide what to return. // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. -PublicInputs private_kernel_circuit(Composer& composer, PrivateInputs const& _private_inputs) +KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, PrivateInputs const& _private_inputs) { const PrivateInputs private_inputs = _private_inputs.to_circuit_type(composer); // We'll be pushing data to this during execution of this circuit. - PublicInputs public_inputs = PublicInputs{}.to_circuit_type(composer); + KernelCircuitPublicInputs public_inputs = KernelCircuitPublicInputs{}.to_circuit_type(composer); // Do this before any functions can modify the inputs. initialise_end_values(private_inputs, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp index 6ebc21650d7..80a33b30036 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp @@ -3,14 +3,14 @@ #include "init.hpp" #include -#include +#include namespace aztec3::circuits::kernel::private_kernel { +using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; -PublicInputs private_kernel_circuit(Composer& composer, PrivateInputs const& _private_inputs); -PublicInputs private_kernel_native(PrivateInputs const& private_inputs); +KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, PrivateInputs const& _private_inputs); +KernelCircuitPublicInputs private_kernel_native(PrivateInputs const& private_inputs); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp index a12a03913c2..41f06be4fa1 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp @@ -3,12 +3,12 @@ #include "barretenberg/proof_system/types/composer_type.hpp" #include -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" namespace { using NT = aztec3::utils::types::NativeTypes; using AggregationObject = aztec3::utils::types::NativeTypes::AggregationObject; -using aztec3::circuits::abis::private_kernel::PreviousKernelData; +using aztec3::circuits::abis::PreviousKernelData; using aztec3::circuits::mock::mock_kernel_circuit; } // namespace diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/utils.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/utils.hpp index 87733c01306..fed871f7873 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/utils.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/utils.hpp @@ -4,7 +4,7 @@ namespace { using NT = aztec3::utils::types::NativeTypes; -using aztec3::circuits::abis::private_kernel::PreviousKernelData; +using aztec3::circuits::abis::PreviousKernelData; } // namespace namespace aztec3::circuits::kernel::private_kernel::utils { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp new file mode 100644 index 00000000000..6fed95c3789 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp @@ -0,0 +1,23 @@ +#include "init.hpp" +#include "native_public_kernel_circuit.hpp" +#include +#include +#include + +using DummyComposer = aztec3::utils::DummyComposer; +using aztec3::circuits::abis::public_kernel::PublicKernelInputs; +using NT = aztec3::utils::types::NativeTypes; + +namespace aztec3::circuits::kernel::public_kernel { +/** + * @brief Some private circuit proof (`constructor`, in this case) + */ +TEST(public_kernel_tests, end_values_are_initialised) +{ + DummyComposer dc; + PublicKernelInputs inputs; + auto public_inputs = native_public_kernel_circuit(dc, inputs); + + ASSERT_EQ(public_inputs.end, inputs.previous_kernel.public_inputs.end); +} +} // namespace aztec3::circuits::kernel::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/init.hpp b/circuits/cpp/src/aztec3/circuits/kernel/public/init.hpp new file mode 100644 index 00000000000..75604e97e44 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/init.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +namespace aztec3::circuits::kernel::public_kernel { + +// Turbo specific, at the moment: +using Composer = plonk::stdlib::types::Composer; +using plonk::stdlib::types::Prover; + +using Aggregator = aztec3::circuits::recursion::Aggregator; + +// Generic: +using CT = aztec3::utils::types::CircuitTypes; +using NT = aztec3::utils::types::NativeTypes; +using aztec3::utils::types::to_ct; + +using DB = oracle::FakeDB; +using oracle::NativeOracle; +using OracleWrapper = aztec3::circuits::apps::OracleWrapperInterface; + +using FunctionExecutionContext = aztec3::circuits::apps::FunctionExecutionContext; + +} // namespace aztec3::circuits::kernel::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.cpp new file mode 100644 index 00000000000..47eaa060c55 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.cpp @@ -0,0 +1,324 @@ +#include "init.hpp" + +#include +#include + +#include +#include +#include +#include "aztec3/constants.hpp" + +#include + +namespace aztec3::circuits::kernel::public_kernel { + +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::public_kernel::PublicKernelInputs; +using aztec3::utils::array_length; + +using DummyComposer = aztec3::utils::DummyComposer; + +void initialise_end_values(PublicKernelInputs const& public_kernel_inputs, + KernelCircuitPublicInputs& public_inputs) +{ + public_inputs.constants = public_kernel_inputs.previous_kernel.public_inputs.constants; + + // Ensure the arrays are the same as previously, before we start pushing more data onto them in other functions + // within this circuit: + auto& end = public_inputs.end; + const auto& start = public_kernel_inputs.previous_kernel.public_inputs.end; + + end.public_call_stack = start.public_call_stack; + end.state_transitions = start.state_transitions; +} + +// void contract_logic(DummyComposer& composer, PrivateInputs const& private_inputs, PublicInputs& +// public_inputs) +// { +// const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; +// const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; +// const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; +// const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; +// const auto& contract_deployment_data = +// private_inputs.signed_tx_request.tx_request.tx_context.contract_deployment_data; + +// // contract deployment + +// // input storage contract address must be 0 if its a constructor call and non-zero otherwise +// auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; + +// auto private_call_vk_hash = stdlib::recursion::verification_key::compress_native( +// private_inputs.private_call.vk, GeneratorIndex::VK); + +// auto constructor_hash = compute_constructor_hash(private_inputs.signed_tx_request.tx_request.function_data, +// private_call_public_inputs.args, +// private_call_vk_hash); + +// if (is_contract_deployment) { +// composer.do_assert(contract_deployment_data.constructor_vk_hash == private_call_vk_hash, +// "constructor_vk_hash doesn't match private_call_vk_hash"); +// } + +// auto const new_contract_address = compute_contract_address(deployer_address, +// contract_deployment_data.contract_address_salt, +// contract_deployment_data.function_tree_root, +// constructor_hash); + +// if (is_contract_deployment) { +// // must imply == derived address +// composer.do_assert(storage_contract_address == new_contract_address, +// "contract address supplied doesn't match derived address"); +// } else { +// // non-contract deployments must specify contract address being interacted with +// composer.do_assert(storage_contract_address != 0, +// "contract address can't be 0 for non-contract deployment related transactions"); +// } + +// // compute contract address nullifier +// auto const blake_input = new_contract_address.to_field().to_buffer(); +// auto const new_contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); + +// // push the contract address nullifier to nullifier vector +// if (is_contract_deployment) { +// array_push(public_inputs.end.new_nullifiers, new_contract_address_nullifier); +// } + +// // Add new contract data if its a contract deployment function +// NewContractData native_new_contract_data{ new_contract_address, +// portal_contract_address, +// contract_deployment_data.function_tree_root }; + +// array_push, KERNEL_NEW_CONTRACTS_LENGTH>(public_inputs.end.new_contracts, +// native_new_contract_data); + +// /* We need to compute the root of the contract tree, starting from the function's VK: +// * - Compute the vk_hash (done above) +// * - Compute the function_leaf: hash(function_selector, is_private, vk_hash, acir_hash) +// * - Hash the function_leaf with the function_leaf's sibling_path to get the function_tree_root +// * - Compute the contract_leaf: hash(contract_address, portal_contract_address, function_tree_root) +// * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root +// */ + +// // ensure that historic/purported contract tree root matches the one in previous kernel +// auto const& purported_contract_tree_root = +// private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; +// auto const& previous_kernel_contract_tree_root = +// private_inputs.previous_kernel.public_inputs.constants.historic_tree_roots.contract_tree_root; +// composer.do_assert(purported_contract_tree_root == previous_kernel_contract_tree_root, +// "purported_contract_tree_root doesn't match previous_kernel_contract_tree_root"); + +// // The logic below ensures that the contract exists in the contracts tree +// if (!is_contract_deployment) { +// auto const& computed_function_tree_root = function_tree_root_from_siblings( +// private_inputs.private_call.call_stack_item.function_data.function_selector, +// true, // is_private +// private_call_vk_hash, +// private_inputs.private_call.acir_hash, +// private_inputs.private_call.function_leaf_membership_witness.leaf_index, +// private_inputs.private_call.function_leaf_membership_witness.sibling_path); + +// auto const& computed_contract_tree_root = contract_tree_root_from_siblings( +// computed_function_tree_root, +// storage_contract_address, +// portal_contract_address, +// private_inputs.private_call.contract_leaf_membership_witness.leaf_index, +// private_inputs.private_call.contract_leaf_membership_witness.sibling_path); + +// composer.do_assert(computed_contract_tree_root == purported_contract_tree_root, +// "computed_contract_tree_root doesn't match purported_contract_tree_root"); +// } +// } + +// void update_end_values(DummyComposer& composer, +// PrivateInputs const& private_inputs, +// PublicInputs& public_inputs) +// { +// const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; + +// const auto& new_commitments = private_call_public_inputs.new_commitments; +// const auto& new_nullifiers = private_call_public_inputs.new_nullifiers; + +// const auto& is_static_call = private_call_public_inputs.call_context.is_static_call; + +// if (is_static_call) { +// // No state changes are allowed for static calls: +// composer.do_assert(is_array_empty(new_commitments) == true, "new_commitments must be empty for static +// calls"); composer.do_assert(is_array_empty(new_nullifiers) == true, "new_nullifiers must be empty for static +// calls"); +// } + +// const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; + +// { +// // Nonce nullifier +// // DANGER: This is terrible. This should not be part of the protocol. This is an intentional bodge to reach a +// // milestone. This must not be the way we derive nonce nullifiers in production. It can be front-run by other +// // users. It is not domain separated. Naughty. +// array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); +// } + +// { // commitments & nullifiers +// std::array siloed_new_commitments; +// for (size_t i = 0; i < new_commitments.size(); ++i) { +// siloed_new_commitments[i] = +// new_commitments[i] == 0 +// ? 0 +// : add_contract_address_to_commitment(storage_contract_address, new_commitments[i]); +// } + +// std::array siloed_new_nullifiers; +// for (size_t i = 0; i < new_nullifiers.size(); ++i) { +// siloed_new_nullifiers[i] = +// new_nullifiers[i] == 0 +// ? 0 +// : add_contract_address_to_nullifier(storage_contract_address, new_nullifiers[i]); +// } + +// push_array_to_array(siloed_new_commitments, public_inputs.end.new_commitments); +// push_array_to_array(siloed_new_nullifiers, public_inputs.end.new_nullifiers); +// } + +// { // call stacks +// auto& this_private_call_stack = private_call_public_inputs.private_call_stack; +// push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); +// } + +// // const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; + +// // { +// // const auto& l1_msg_stack = private_call_public_inputs.l1_msg_stack; +// // std::array l1_call_stack; + +// // for (size_t i = 0; i < l1_msg_stack.size(); ++i) { +// // l1_call_stack[i] = CT::fr::conditional_assign( +// // l1_msg_stack[i] == 0, +// // 0, +// // CT::compress({ portal_contract_address, l1_msg_stack[i] }, GeneratorIndex::L1_MSG_STACK_ITEM)); +// // } +// // } +// } + +// void validate_this_private_call_hash(DummyComposer& composer, PrivateInputs const& private_inputs) +// { +// const auto& start = private_inputs.previous_kernel.public_inputs.end; +// // TODO: this logic might need to change to accommodate the weird edge 3 initial txs (the 'main' tx, the 'fee' +// tx, +// // and the 'gas rebate' tx). +// const auto popped_private_call_hash = array_pop(start.private_call_stack); +// const auto calculated_this_private_call_hash = private_inputs.private_call.call_stack_item.hash(); + +// composer.do_assert( +// popped_private_call_hash == calculated_this_private_call_hash, +// "calculated private_call_hash does not match provided private_call_hash at the top of the call stack"); +// }; + +// void validate_this_private_call_stack(DummyComposer& composer, PrivateInputs const& private_inputs) +// { +// auto& stack = private_inputs.private_call.call_stack_item.public_inputs.private_call_stack; +// auto& preimages = private_inputs.private_call.private_call_stack_preimages; +// for (size_t i = 0; i < stack.size(); ++i) { +// const auto& hash = stack[i]; +// const auto& preimage = preimages[i]; + +// // Note: this assumes it's computationally infeasible to have `0` as a valid call_stack_item_hash. +// // Assumes `hash == 0` means "this stack item is empty". +// const auto calculated_hash = hash == 0 ? 0 : preimage.hash(); +// composer.do_assert(hash != calculated_hash, +// format("private_call_stack[", i, "] = ", hash, "; does not reconcile")); +// } +// }; + +void validate_inputs(DummyComposer& composer, PublicKernelInputs const& public_kernel_inputs) +{ + const auto& this_call_stack_item = public_kernel_inputs.public_call.call_stack_item; + + composer.do_assert(this_call_stack_item.function_data.is_private == false, + "Cannot execute a private function with the public kernel circuit"); + + const auto& start = public_kernel_inputs.previous_kernel.public_inputs.end; + + const NT::boolean is_base_case = start.public_call_count == 0; + + // TODO: we might want to range-constrain the call_count to prevent some kind of overflow errors. Having said that, + // iterating 2^254 times isn't feasible. + + NT::fr start_public_call_stack_length = array_length(start.public_call_stack); + // NT::fr start_state_transitions_length = array_length(start.state_transitions); + + // Base Case + if (is_base_case) { + // TODO: change to allow 3 initial calls on the private call stack, so a fee can be paid and a gas + // rebate can be paid. + + composer.do_assert(start_public_call_stack_length == 1, "Public call stack must be length 1"); + + // composer.do_assert(start_state_transitions_length == 0, "State transition length must be 0"); + + composer.do_assert(this_call_stack_item.public_inputs.call_context.is_delegate_call == false, + "Users cannot make a delegatecall"); + composer.do_assert(this_call_stack_item.public_inputs.call_context.is_static_call == false, + "Users cannot make a static call"); + + // The below also prevents delegatecall/staticcall in the base case + composer.do_assert(this_call_stack_item.public_inputs.call_context.storage_contract_address == + this_call_stack_item.contract_address, + "Storage contract address must be that of the called contract"); + + composer.do_assert(public_kernel_inputs.previous_kernel.vk->contains_recursive_proof == false, + "Mock kernel proof must not contain a recursive proof"); + + // TODO: Assert that the previous kernel data is empty. (Or rather, the verify_proof() function needs a valid + // dummy proof and vk to complete execution, so actually what we want is for that mockvk to be + // hard-coded into the circuit and assert that that is the one which has been used in the base case). + } else { + // is_recursive_case + + composer.do_assert(public_kernel_inputs.previous_kernel.public_inputs.is_private == true, + "Cannot verify a non-private kernel snark in the private kernel circuit"); + composer.do_assert(this_call_stack_item.function_data.is_constructor == false, + "A constructor must be executed as the first tx in the recursion"); + composer.do_assert(start_public_call_stack_length != 0, + "Cannot execute public kernel circuit with an empty public call stack"); + } +} + +// NOTE: THIS IS A VERY UNFINISHED WORK IN PROGRESS. +// TODO: decide what to return. +// TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely +// ensure we're constraining everything. +KernelCircuitPublicInputs native_public_kernel_circuit(DummyComposer& composer, + PublicKernelInputs const& public_kernel_inputs) +{ + // We'll be pushing data to this during execution of this circuit. + (void)composer; + KernelCircuitPublicInputs public_inputs{}; + + // Do this before any functions can modify the inputs. + initialise_end_values(public_kernel_inputs, public_inputs); + + // validate_inputs(composer, private_inputs); + + // validate_this_private_call_hash(composer, private_inputs); + + // validate_this_private_call_stack(composer, private_inputs); + + // update_end_values(composer, private_inputs, public_inputs); + + // contract_logic(composer, private_inputs, public_inputs); + + // We'll skip any verification in this native implementation, because for a Local Developer Testnet, there won't + // _be_ a valid proof to verify!!! auto aggregation_object = verify_proofs(composer, + // private_inputs, + // _private_inputs.private_call.vk->num_public_inputs, + // _private_inputs.previous_kernel.vk->num_public_inputs); + + // TODO: kernel vk membership check! + + // Note: given that we skipped the verify_proof function, the aggregation object we get at the end will just be the + // same as we had at the start. public_inputs.end.aggregation_object = aggregation_object; + public_inputs.end.aggregation_object = public_kernel_inputs.previous_kernel.public_inputs.end.aggregation_object; + + return public_inputs; +}; + +} // namespace aztec3::circuits::kernel::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.hpp new file mode 100644 index 00000000000..4e818d39937 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "init.hpp" + +#include +#include +#include + +namespace aztec3::circuits::kernel::public_kernel { + +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::public_kernel::PublicKernelInputs; +// using abis::private_kernel::PublicInputs; +using DummyComposer = aztec3::utils::DummyComposer; + +// TODO: decide what to return. +KernelCircuitPublicInputs native_public_kernel_circuit(DummyComposer& composer, + PublicKernelInputs const& _public_kernel_inputs); + +void validate_inputs(DummyComposer& composer, PublicKernelInputs const& public_kernel_inputs); + +} // namespace aztec3::circuits::kernel::public_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/mock/mock_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/mock/mock_kernel_circuit.hpp index 03ec3461ec4..6b1f68aef26 100644 --- a/circuits/cpp/src/aztec3/circuits/mock/mock_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/mock/mock_kernel_circuit.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include // #include namespace { @@ -15,14 +15,15 @@ auto& engine = numeric::random::get_debug_engine(); namespace aztec3::circuits::mock { -using aztec3::circuits::abis::private_kernel::PublicInputs; +using aztec3::circuits::abis::KernelCircuitPublicInputs; using NT = aztec3::utils::types::NativeTypes; using aztec3::utils::types::CircuitTypes; using plonk::stdlib::pedersen_commitment; using plonk::stdlib::witness_t; template -PublicInputs mock_kernel_circuit(Composer& composer, PublicInputs const& _public_inputs) +KernelCircuitPublicInputs mock_kernel_circuit(Composer& composer, + KernelCircuitPublicInputs const& _public_inputs) { typedef CircuitTypes CT; typedef typename CT::fr fr; diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp index 9c16a565b91..145e2b0f159 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -1,7 +1,7 @@ #include "aztec3/circuits/abis/append_only_tree_snapshot.hpp" #include "aztec3/circuits/abis/membership_witness.hpp" -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" -#include "aztec3/circuits/abis/private_kernel/previous_kernel_data.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/abis/previous_kernel_data.hpp" #include "aztec3/circuits/kernel/private/utils.hpp" #include "aztec3/circuits/abis/rollup/nullifier_leaf_preimage.hpp" #include "aztec3/constants.hpp" @@ -26,10 +26,11 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include @@ -57,7 +58,6 @@ namespace { using aztec3::circuits::abis::CallContext; using aztec3::circuits::abis::CallStackItem; -using aztec3::circuits::abis::CallType; using aztec3::circuits::abis::ContractDeploymentData; using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::OptionalPrivateCircuitPublicInputs; @@ -66,14 +66,14 @@ using aztec3::circuits::abis::SignedTxRequest; using aztec3::circuits::abis::TxContext; using aztec3::circuits::abis::TxRequest; -using aztec3::circuits::abis::private_kernel::AccumulatedData; -using aztec3::circuits::abis::private_kernel::ConstantData; +using aztec3::circuits::abis::CombinedAccumulatedData; +using aztec3::circuits::abis::CombinedConstantData; +using aztec3::circuits::abis::CombinedHistoricTreeRoots; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::PreviousKernelData; using aztec3::circuits::abis::private_kernel::Globals; -using aztec3::circuits::abis::private_kernel::HistoricTreeRoots; -using aztec3::circuits::abis::private_kernel::PreviousKernelData; using aztec3::circuits::abis::private_kernel::PrivateCallData; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; using aztec3::circuits::apps::test_apps::basic_contract_deployment::constructor; using aztec3::circuits::apps::test_apps::escrow::deposit; @@ -94,8 +94,8 @@ using aztec3::circuits::rollup::native_base_rollup::ConstantRollupData; using aztec3::circuits::rollup::native_base_rollup::NT; using aztec3::circuits::abis::FunctionData; +using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::OptionallyRevealedData; -using aztec3::circuits::abis::private_kernel::NewContractData; using DummyComposer = aztec3::utils::DummyComposer; } // namespace @@ -693,7 +693,7 @@ TEST_F(base_rollup_tests, native_compute_membership_historic_private_data) .root = tree.root(), .next_available_leaf_index = 0, }; - inputs.kernel_data[0].public_inputs.constants.historic_tree_roots.private_data_tree_root = fr(0); + inputs.kernel_data[0].public_inputs.constants.historic_tree_roots.private_historic_tree_roots.private_data_tree_root = fr(0); // fetch sibling path from hash path (only get the second half of the hash path) auto hash_path = tree.get_hash_path(0); diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp index 4e502fa4d82..ab9557ffee3 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp @@ -10,7 +10,7 @@ #include "aztec3/circuits/abis/signed_tx_request.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include -#include +#include #include #include "barretenberg/srs/reference_string/env_reference_string.hpp" diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp index b93e47eb16c..ab4f77b84b4 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/native_base_rollup_circuit.cpp @@ -201,7 +201,8 @@ void perform_historical_private_data_tree_membership_checks(DummyComposer& compo auto historic_root = baseRollupInputs.constants.start_tree_of_historic_private_data_tree_roots_snapshot.root; for (size_t i = 0; i < 2; i++) { - NT::fr leaf = baseRollupInputs.kernel_data[i].public_inputs.constants.historic_tree_roots.private_data_tree_root; + NT::fr leaf = baseRollupInputs.kernel_data[i] + .public_inputs.constants.historic_tree_roots.private_historic_tree_roots.private_data_tree_root; abis::MembershipWitness historic_root_witness = baseRollupInputs.historic_private_data_tree_root_membership_witnesses[i]; @@ -216,7 +217,8 @@ void perform_historical_contract_data_tree_membership_checks(DummyComposer& comp auto historic_root = baseRollupInputs.constants.start_tree_of_historic_contract_tree_roots_snapshot.root; for (size_t i = 0; i < 2; i++) { - NT::fr leaf = baseRollupInputs.kernel_data[i].public_inputs.constants.historic_tree_roots.contract_tree_root; + NT::fr leaf = baseRollupInputs.kernel_data[i] + .public_inputs.constants.historic_tree_roots.private_historic_tree_roots.contract_tree_root; abis::MembershipWitness historic_root_witness = baseRollupInputs.historic_contract_tree_root_membership_witnesses[i]; diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/utils.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/utils.cpp index 9c7a059a333..4e6d6993367 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/utils.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/utils.cpp @@ -6,7 +6,7 @@ #include #include -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" namespace { using NT = aztec3::utils::types::NativeTypes; @@ -38,7 +38,7 @@ BaseRollupInputs dummy_base_rollup_inputs() // constantRollupData.tree_of_historic_l1_to_l2_msg_tree_roots_snapshot = // Kernels - std::array, 2> kernel_data; + std::array, 2> kernel_data; // grab mocked previous kernel (need a valid vk, proof, aggobj) kernel_data[0] = dummy_previous_kernel(); kernel_data[1] = dummy_previous_kernel(); diff --git a/circuits/cpp/src/aztec3/circuits/rollup/merge/utils.cpp b/circuits/cpp/src/aztec3/circuits/rollup/merge/utils.cpp index 5e30ce02b08..fd9b6798a29 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/merge/utils.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/merge/utils.cpp @@ -10,7 +10,7 @@ #include #include -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/rollup/base/utils.hpp" // #include "aztec3/circuits/abis/rollup/base/previous_rollup_data.hpp" diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp index 4f00f39b1b4..c216f54322e 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp @@ -1,7 +1,7 @@ #include "aztec3/circuits/abis/append_only_tree_snapshot.hpp" #include "aztec3/circuits/abis/membership_witness.hpp" -#include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" -#include "aztec3/circuits/abis/private_kernel/previous_kernel_data.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/abis/previous_kernel_data.hpp" #include "aztec3/circuits/abis/rollup/merge/previous_rollup_data.hpp" #include "aztec3/circuits/abis/rollup/nullifier_leaf_preimage.hpp" #include "aztec3/circuits/rollup/base/init.hpp" @@ -29,10 +29,11 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include @@ -51,7 +52,6 @@ namespace { using aztec3::circuits::abis::CallContext; using aztec3::circuits::abis::CallStackItem; -using aztec3::circuits::abis::CallType; using aztec3::circuits::abis::ContractDeploymentData; using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::OptionalPrivateCircuitPublicInputs; @@ -60,14 +60,15 @@ using aztec3::circuits::abis::SignedTxRequest; using aztec3::circuits::abis::TxContext; using aztec3::circuits::abis::TxRequest; -using aztec3::circuits::abis::private_kernel::AccumulatedData; -using aztec3::circuits::abis::private_kernel::ConstantData; +using aztec3::circuits::abis::CombinedAccumulatedData; +using aztec3::circuits::abis::CombinedConstantData; +using aztec3::circuits::abis::CombinedHistoricTreeRoots; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::PreviousKernelData; +using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::Globals; -using aztec3::circuits::abis::private_kernel::HistoricTreeRoots; -using aztec3::circuits::abis::private_kernel::PreviousKernelData; using aztec3::circuits::abis::private_kernel::PrivateCallData; using aztec3::circuits::abis::private_kernel::PrivateInputs; -using aztec3::circuits::abis::private_kernel::PublicInputs; using aztec3::circuits::apps::test_apps::basic_contract_deployment::constructor; using aztec3::circuits::apps::test_apps::escrow::deposit; @@ -93,8 +94,8 @@ using aztec3::circuits::rollup::native_root_rollup::RootRollupInputs; using aztec3::circuits::rollup::native_root_rollup::RootRollupPublicInputs; using aztec3::circuits::abis::FunctionData; +using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::OptionallyRevealedData; -using aztec3::circuits::abis::private_kernel::NewContractData; using MemoryTree = proof_system::plonk::stdlib::merkle_tree::MemoryTree; diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp index 92114351c0c..91a992fe9c3 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp @@ -7,7 +7,7 @@ #include "aztec3/circuits/abis/signed_tx_request.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include -#include +#include #include #include "barretenberg/srs/reference_string/env_reference_string.hpp" diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index f07866f69da..aa03741daa4 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -31,6 +31,7 @@ constexpr size_t FUNCTION_TREE_HEIGHT = 4; constexpr size_t CONTRACT_TREE_HEIGHT = 4; constexpr size_t PRIVATE_DATA_TREE_HEIGHT = 8; constexpr size_t NULLIFIER_TREE_HEIGHT = 8; +constexpr size_t PUBLIC_DATA_TREE_HEIGHT = 32; constexpr size_t CONTRACT_SUBTREE_DEPTH = 1; constexpr size_t CONTRACT_SUBTREE_INCLUSION_CHECK_DEPTH = CONTRACT_TREE_HEIGHT - CONTRACT_SUBTREE_DEPTH; diff --git a/yarn-project/acir-simulator/src/acvm/serialize.ts b/yarn-project/acir-simulator/src/acvm/serialize.ts index 1a53d4f57c0..bc46a2c885e 100644 --- a/yarn-project/acir-simulator/src/acvm/serialize.ts +++ b/yarn-project/acir-simulator/src/acvm/serialize.ts @@ -4,7 +4,7 @@ import { CallContext, ContractDeploymentData, FunctionData, - HistoricTreeRoots, + PrivateHistoricTreeRoots, PrivateCallStackItem, PrivateCircuitPublicInputs, TxContext, @@ -89,7 +89,7 @@ export function writeInputs( args: Fr[], callContext: CallContext, txContext: TxContext, - historicRoots: HistoricTreeRoots, + historicRoots: PrivateHistoricTreeRoots, witnessStartIndex = 1, ) { const fields = [ diff --git a/yarn-project/acir-simulator/src/execution.ts b/yarn-project/acir-simulator/src/execution.ts index 4e4fae7d183..df63804a662 100644 --- a/yarn-project/acir-simulator/src/execution.ts +++ b/yarn-project/acir-simulator/src/execution.ts @@ -12,7 +12,7 @@ import { import { AztecAddress, EthAddress, Fr } from '@aztec/foundation'; import { CallContext, - HistoricTreeRoots, + PrivateHistoricTreeRoots, TxRequest, PrivateCallStackItem, FunctionData, @@ -58,7 +58,7 @@ export class Execution { // Global to the tx private db: DBOracle, private request: TxRequest, - private historicRoots: HistoricTreeRoots, + private historicRoots: PrivateHistoricTreeRoots, // Concrete to this execution private abi: FunctionAbi, private contractAddress: AztecAddress, diff --git a/yarn-project/acir-simulator/src/index.test.ts b/yarn-project/acir-simulator/src/index.test.ts index a5345d4908b..8b93b926938 100644 --- a/yarn-project/acir-simulator/src/index.test.ts +++ b/yarn-project/acir-simulator/src/index.test.ts @@ -5,7 +5,7 @@ import { ContractDeploymentData, FunctionData, NEW_COMMITMENTS_LENGTH, - HistoricTreeRoots, + PrivateHistoricTreeRoots, PRIVATE_DATA_TREE_HEIGHT, TxContext, TxRequest, @@ -39,7 +39,7 @@ describe('ACIR simulator', () => { }); describe('empty constructor', () => { - const historicRoots = new HistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); + const historicRoots = new PrivateHistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); const contractDeploymentData = new ContractDeploymentData(Fr.random(), Fr.random(), Fr.random(), EthAddress.ZERO); const txContext = new TxContext(false, false, true, contractDeploymentData); @@ -92,7 +92,7 @@ describe('ACIR simulator', () => { }); it('should a constructor with arguments that creates notes', async () => { - const historicRoots = new HistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); + const historicRoots = new PrivateHistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); const contractAddress = AztecAddress.random(); const abi = ZkTokenContractAbi.functions.find(f => f.name === 'constructor') as unknown as FunctionAbi; @@ -119,7 +119,7 @@ describe('ACIR simulator', () => { }); it('should run the mint function', async () => { - const historicRoots = new HistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); + const historicRoots = new PrivateHistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); const contractAddress = AztecAddress.random(); const abi = ZkTokenContractAbi.functions.find(f => f.name === 'mint') as unknown as FunctionAbi; @@ -158,7 +158,7 @@ describe('ACIR simulator', () => { // TODO for this we need that noir siloes the commitment the same way as the kernel does, to do merkle membership await tree.appendLeaves(preimages.map(preimage => acirSimulator.computeNoteHash(preimage, bbWasm))); - const historicRoots = new HistoricTreeRoots( + const historicRoots = new PrivateHistoricTreeRoots( Fr.fromBuffer(tree.getRoot(false)), new Fr(0n), new Fr(0n), @@ -229,7 +229,7 @@ describe('ACIR simulator', () => { // TODO for this we need that noir siloes the commitment the same way as the kernel does, to do merkle membership await tree.appendLeaves(preimages.map(preimage => acirSimulator.computeNoteHash(preimage, bbWasm))); - const historicRoots = new HistoricTreeRoots( + const historicRoots = new PrivateHistoricTreeRoots( Fr.fromBuffer(tree.getRoot(false)), new Fr(0n), new Fr(0n), @@ -273,7 +273,7 @@ describe('ACIR simulator', () => { }); describe('nested calls', () => { - const historicRoots = new HistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); + const historicRoots = new PrivateHistoricTreeRoots(new Fr(0n), new Fr(0n), new Fr(0n), new Fr(0n)); const contractDeploymentData = new ContractDeploymentData(Fr.random(), Fr.random(), Fr.random(), EthAddress.ZERO); const txContext = new TxContext(false, false, true, contractDeploymentData); diff --git a/yarn-project/acir-simulator/src/public/state_actions.ts b/yarn-project/acir-simulator/src/public/state_actions.ts index 33688fad987..e6289d0bceb 100644 --- a/yarn-project/acir-simulator/src/public/state_actions.ts +++ b/yarn-project/acir-simulator/src/public/state_actions.ts @@ -65,15 +65,19 @@ export class StateActionsCollector { * @returns all state read and transitions */ public collect(): [StateRead[], StateTransition[]] { - const reads = Array.from(this.stateReads.entries()).map(([slot, value]) => ({ - storageSlot: new Fr(slot), - ...value, - })); + const reads = Array.from(this.stateReads.entries()).map(([slot, value]) => + StateRead.from({ + storageSlot: new Fr(slot), + ...value, + }), + ); - const transitions = Array.from(this.stateTransitions.entries()).map(([slot, values]) => ({ - storageSlot: new Fr(slot), - ...values, - })); + const transitions = Array.from(this.stateTransitions.entries()).map(([slot, values]) => + StateTransition.from({ + storageSlot: new Fr(slot), + ...values, + }), + ); return [reads, transitions]; } diff --git a/yarn-project/acir-simulator/src/simulator.ts b/yarn-project/acir-simulator/src/simulator.ts index 79ac7851b3f..db52bc2b95c 100644 --- a/yarn-project/acir-simulator/src/simulator.ts +++ b/yarn-project/acir-simulator/src/simulator.ts @@ -1,5 +1,5 @@ import { AztecAddress, EthAddress, Fr } from '@aztec/foundation'; -import { CallContext, HistoricTreeRoots, TxRequest } from '@aztec/circuits.js'; +import { CallContext, PrivateHistoricTreeRoots, TxRequest } from '@aztec/circuits.js'; import { FunctionAbi } from '@aztec/noir-contracts'; import { DBOracle } from './db_oracle.js'; import { Execution, ExecutionResult } from './execution.js'; @@ -20,7 +20,7 @@ export class AcirSimulator { entryPointABI: FunctionAbi, contractAddress: AztecAddress, portalContractAddress: EthAddress, - historicRoots: HistoricTreeRoots, + historicRoots: PrivateHistoricTreeRoots, ): Promise { const callContext = new CallContext( request.from, diff --git a/yarn-project/aztec-rpc/src/account_state/account_state.ts b/yarn-project/aztec-rpc/src/account_state/account_state.ts index f944d0ed8b7..5932c05d173 100644 --- a/yarn-project/aztec-rpc/src/account_state/account_state.ts +++ b/yarn-project/aztec-rpc/src/account_state/account_state.ts @@ -1,7 +1,7 @@ import { AcirSimulator } from '@aztec/acir-simulator'; import { AztecNode } from '@aztec/aztec-node'; import { Grumpkin } from '@aztec/barretenberg.js/crypto'; -import { EcdsaSignature, KERNEL_NEW_COMMITMENTS_LENGTH, HistoricTreeRoots, TxRequest } from '@aztec/circuits.js'; +import { EcdsaSignature, KERNEL_NEW_COMMITMENTS_LENGTH, PrivateHistoricTreeRoots, TxRequest } from '@aztec/circuits.js'; import { AztecAddress, Fr, Point, createDebugLogger } from '@aztec/foundation'; import { KernelProver, OutputNoteData } from '@aztec/kernel-prover'; import { INITIAL_L2_BLOCK_NUM } from '@aztec/l1-contracts'; @@ -69,7 +69,7 @@ export class AccountState { txRequest.functionData.functionSelector, ); const portalContract = await contractDataOracle.getPortalContractAddress(contractAddress); - const historicRoots = new HistoricTreeRoots(Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO); // TODO - get old roots from the database/node + const historicRoots = new PrivateHistoricTreeRoots(Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO); // TODO - get old roots from the database/node const simulatorOracle = new SimulatorOracle(contractDataOracle, this.db, this.keyPair, this.node); const simulator = new AcirSimulator(simulatorOracle); diff --git a/yarn-project/aztec-rpc/src/contract_tree/contract_tree.ts b/yarn-project/aztec-rpc/src/contract_tree/contract_tree.ts index c09bed156cc..cde2b9ebeb0 100644 --- a/yarn-project/aztec-rpc/src/contract_tree/contract_tree.ts +++ b/yarn-project/aztec-rpc/src/contract_tree/contract_tree.ts @@ -166,7 +166,7 @@ export class ContractTree { const targetFunctions = this.contract.functions.filter(isConstrained); const functionIndex = targetFunctions.findIndex(f => f.selector.equals(functionSelector)); if (functionIndex < 0) { - return MembershipWitness.makeEmpty(FUNCTION_TREE_HEIGHT, 0); + return MembershipWitness.empty(FUNCTION_TREE_HEIGHT, 0); } if (!this.functionTree) { diff --git a/yarn-project/circuits.js/src/kernel/kernel.ts b/yarn-project/circuits.js/src/kernel/kernel.ts index 72d1de31763..e8225f69991 100644 --- a/yarn-project/circuits.js/src/kernel/kernel.ts +++ b/yarn-project/circuits.js/src/kernel/kernel.ts @@ -5,7 +5,7 @@ import { FUNCTION_TREE_HEIGHT, PreviousKernelData, PrivateCallData, - PrivateKernelPublicInputs, + KernelCircuitPublicInputs, SignedTxRequest, } from '../index.js'; import { boolToBuffer, serializeToBuffer, uint8ArrayToNum } from '../utils/serialize.js'; @@ -117,5 +117,5 @@ export async function privateKernelSim( const publicInputBuffer = Buffer.from(wasm.getMemorySlice(address, address + outputSize)); wasm.call('bbfree', publicInputOutputAddressPtr); wasm.call('bbfree', address); - return PrivateKernelPublicInputs.fromBuffer(publicInputBuffer); + return KernelCircuitPublicInputs.fromBuffer(publicInputBuffer); } diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/tx.test.ts.snap b/yarn-project/circuits.js/src/structs/__snapshots__/tx_context.test.ts.snap similarity index 100% rename from yarn-project/circuits.js/src/structs/__snapshots__/tx.test.ts.snap rename to yarn-project/circuits.js/src/structs/__snapshots__/tx_context.test.ts.snap diff --git a/yarn-project/circuits.js/src/structs/aggregation_object.ts b/yarn-project/circuits.js/src/structs/aggregation_object.ts new file mode 100644 index 00000000000..7b24f17c0a9 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/aggregation_object.ts @@ -0,0 +1,46 @@ +import { BufferReader } from '@aztec/foundation'; +import { Fq, Fr } from '@aztec/foundation/fields'; +import { serializeToBuffer } from '../utils/serialize.js'; +import times from 'lodash.times'; +import { Vector, UInt32, AffineElement } from './shared.js'; + +export class AggregationObject { + public publicInputs: Vector; + public proofWitnessIndices: Vector; + + constructor( + public p0: AffineElement, + public p1: AffineElement, + publicInputsData: Fr[], + proofWitnessIndicesData: UInt32[], + public hasData = false, + ) { + this.publicInputs = new Vector(publicInputsData); + this.proofWitnessIndices = new Vector(proofWitnessIndicesData); + } + + toBuffer() { + return serializeToBuffer(this.p0, this.p1, this.publicInputs, this.proofWitnessIndices, this.hasData); + } + + static fromBuffer(buffer: Buffer | BufferReader): AggregationObject { + const reader = BufferReader.asReader(buffer); + return new AggregationObject( + reader.readObject(AffineElement), + reader.readObject(AffineElement), + reader.readVector(Fr), + reader.readNumberVector(), + reader.readBoolean(), + ); + } + + static makeFake() { + return new AggregationObject( + new AffineElement(new Fq(1n), new Fq(2n)), + new AffineElement(new Fq(1n), new Fq(2n)), + [], + times(16, i => 3027 + i), + false, + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts b/yarn-project/circuits.js/src/structs/call_stack_item.ts similarity index 55% rename from yarn-project/circuits.js/src/structs/private_call_stack_item.ts rename to yarn-project/circuits.js/src/structs/call_stack_item.ts index 56f5b06f5fe..252e834b1ed 100644 --- a/yarn-project/circuits.js/src/structs/private_call_stack_item.ts +++ b/yarn-project/circuits.js/src/structs/call_stack_item.ts @@ -2,6 +2,7 @@ import { AztecAddress } from '@aztec/foundation'; import { serializeToBuffer } from '../utils/serialize.js'; import { FunctionData } from './function_data.js'; import { PrivateCircuitPublicInputs } from './private_circuit_public_inputs.js'; +import { PublicCircuitPublicInputs } from './public_circuit_public_inputs.js'; /** * Call stack item on a private call. @@ -22,3 +23,23 @@ export class PrivateCallStackItem { return new PrivateCallStackItem(AztecAddress.ZERO, FunctionData.empty(), PrivateCircuitPublicInputs.empty()); } } + +/** + * Call stack item on a public call. + * @see cpp/src/aztec3/circuits/abis/call_stack_item.hpp. + */ +export class PublicCallStackItem { + constructor( + public contractAddress: AztecAddress, + public functionData: FunctionData, + public publicInputs: PublicCircuitPublicInputs, + ) {} + + toBuffer() { + return serializeToBuffer(this.contractAddress, this.functionData, this.publicInputs); + } + + public static empty() { + return new PublicCallStackItem(AztecAddress.ZERO, FunctionData.empty(), PublicCircuitPublicInputs.empty()); + } +} diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index e7dafe19a36..58dbceea16f 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -1,17 +1,27 @@ -export * from './base_rollup.js'; +export * from './rollup/base_rollup.js'; +export * from './rollup/merge_rollup.js'; +export * from './rollup/root_rollup.js'; +export * from './rollup/append_only_tree_snapshot.js'; +export * from './rollup/base_or_merge_rollup_public_inputs.js'; +export * from './rollup/previous_rollup_data.js'; export * from './call_context.js'; export * from './constants.js'; export * from './function_data.js'; -export * from './private_kernel.js'; -export * from './public_kernel.js'; -export * from './merge_rollup.js'; +export * from './kernel/private_kernel.js'; +export * from './kernel/public_kernel.js'; +export * from './kernel/combined_accumulated_data.js'; +export * from './kernel/combined_constant_data.js'; +export * from './kernel/previous_kernel_data.js'; +export * from './kernel/public_inputs.js'; export * from './private_circuit_public_inputs.js'; export * from './public_circuit_public_inputs.js'; -export * from './private_call_stack_item.js'; -export * from './root_rollup.js'; +export * from './call_stack_item.js'; export * from './shared.js'; -export * from './tx.js'; +export * from './tx_request.js'; +export * from './tx_context.js'; export * from './verification_key.js'; -export * from './private_call_stack_item.js'; +export * from './call_stack_item.js'; export * from './function_leaf_preimage.js'; +export * from './aggregation_object.js'; +export * from './membership_witness.js'; export { Fr, Fq, AztecAddress, EthAddress } from '@aztec/foundation'; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/private_kernel.test.ts.snap b/yarn-project/circuits.js/src/structs/kernel/__snapshots__/private_kernel.test.ts.snap similarity index 89% rename from yarn-project/circuits.js/src/structs/__snapshots__/private_kernel.test.ts.snap rename to yarn-project/circuits.js/src/structs/kernel/__snapshots__/private_kernel.test.ts.snap index 5a88b65611a..3e4857fad65 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/private_kernel.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/kernel/__snapshots__/private_kernel.test.ts.snap @@ -15,6 +15,7 @@ proof_witness_indices: [ 7 8 9 10 11 12 ] has_data: 0 private_call_count: 0xd +public_call_count: 0xe new_commitments: [ 0x101 0x102 0x103 0x104 ] new_nullifiers: @@ -88,13 +89,39 @@ pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 ] +state_transitions: +[ storage_slot: 0x801 +old_value: 0x802 +new_value: 0x803 + storage_slot: 0x802 +old_value: 0x803 +new_value: 0x804 + storage_slot: 0x803 +old_value: 0x804 +new_value: 0x805 + storage_slot: 0x804 +old_value: 0x805 +new_value: 0x806 + ] +state_reads: +[ storage_slot: 0x901 +current_value: 0x902 + storage_slot: 0x902 +current_value: 0x903 + storage_slot: 0x903 +current_value: 0x904 + storage_slot: 0x904 +current_value: 0x905 + ] constants: -historic_tree_roots: private_data_tree_root: 0x101 +historic_tree_roots: private_historic_tree_roots: private_data_tree_root: 0x101 nullifier_tree_root: 0x102 contract_tree_root: 0x103 private_kernel_vk_tree_root: 0x104 +public_data_tree_root: 0x105 + tx_context: is_fee_payment_tx: 0 is_rebate_payment_tx: 0 is_contract_deployment_tx: 1 @@ -162,6 +189,7 @@ proof_witness_indices: [ 4103 4104 4105 4106 4107 4108 ] has_data: 0 private_call_count: 0x100d +public_call_count: 0x100e new_commitments: [ 0x1101 0x1102 0x1103 0x1104 ] new_nullifiers: @@ -235,13 +263,39 @@ pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 ] +state_transitions: +[ storage_slot: 0x1801 +old_value: 0x1802 +new_value: 0x1803 + storage_slot: 0x1802 +old_value: 0x1803 +new_value: 0x1804 + storage_slot: 0x1803 +old_value: 0x1804 +new_value: 0x1805 + storage_slot: 0x1804 +old_value: 0x1805 +new_value: 0x1806 + ] +state_reads: +[ storage_slot: 0x1901 +current_value: 0x1902 + storage_slot: 0x1902 +current_value: 0x1903 + storage_slot: 0x1903 +current_value: 0x1904 + storage_slot: 0x1904 +current_value: 0x1905 + ] constants: -historic_tree_roots: private_data_tree_root: 0x1101 +historic_tree_roots: private_historic_tree_roots: private_data_tree_root: 0x1101 nullifier_tree_root: 0x1102 contract_tree_root: 0x1103 private_kernel_vk_tree_root: 0x1104 +public_data_tree_root: 0x1105 + tx_context: is_fee_payment_tx: 0 is_rebate_payment_tx: 0 is_contract_deployment_tx: 1 @@ -479,6 +533,7 @@ proof_witness_indices: [ 7 8 9 10 11 12 ] has_data: 0 private_call_count: 0xd +public_call_count: 0xe new_commitments: [ 0x101 0x102 0x103 0x104 ] new_nullifiers: @@ -552,13 +607,39 @@ pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 ] +state_transitions: +[ storage_slot: 0x801 +old_value: 0x802 +new_value: 0x803 + storage_slot: 0x802 +old_value: 0x803 +new_value: 0x804 + storage_slot: 0x803 +old_value: 0x804 +new_value: 0x805 + storage_slot: 0x804 +old_value: 0x805 +new_value: 0x806 + ] +state_reads: +[ storage_slot: 0x901 +current_value: 0x902 + storage_slot: 0x902 +current_value: 0x903 + storage_slot: 0x903 +current_value: 0x904 + storage_slot: 0x904 +current_value: 0x905 + ] constants: -historic_tree_roots: private_data_tree_root: 0x101 +historic_tree_roots: private_historic_tree_roots: private_data_tree_root: 0x101 nullifier_tree_root: 0x102 contract_tree_root: 0x103 private_kernel_vk_tree_root: 0x104 +public_data_tree_root: 0x105 + tx_context: is_fee_payment_tx: 0 is_rebate_payment_tx: 0 is_contract_deployment_tx: 1 diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts new file mode 100644 index 00000000000..946c1d771c2 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -0,0 +1,198 @@ +import { AztecAddress, BufferReader, EthAddress, Fr } from '@aztec/foundation'; +import times from 'lodash.times'; +import { StateRead, StateTransition } from '../../index.js'; +import { assertLength } from '../../utils/jsUtils.js'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { AggregationObject } from '../aggregation_object.js'; +import { + EMITTED_EVENTS_LENGTH, + KERNEL_L1_MSG_STACK_LENGTH, + KERNEL_NEW_COMMITMENTS_LENGTH, + KERNEL_NEW_CONTRACTS_LENGTH, + KERNEL_NEW_NULLIFIERS_LENGTH, + KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, + KERNEL_PRIVATE_CALL_STACK_LENGTH, + KERNEL_PUBLIC_CALL_STACK_LENGTH, + STATE_READS_LENGTH, + STATE_TRANSITIONS_LENGTH, +} from '../constants.js'; +import { FunctionData } from '../function_data.js'; + +// Not to be confused with ContractDeploymentData (maybe think of better names) + +export class NewContractData { + constructor( + public contractAddress: AztecAddress, + public portalContractAddress: EthAddress, + public functionTreeRoot: Fr, + ) {} + + toBuffer() { + return serializeToBuffer(this.contractAddress, this.portalContractAddress, this.functionTreeRoot); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): NewContractData { + const reader = BufferReader.asReader(buffer); + return new NewContractData(reader.readObject(AztecAddress), new EthAddress(reader.readBytes(32)), reader.readFr()); + } + + static empty() { + return new NewContractData(AztecAddress.ZERO, EthAddress.ZERO, Fr.ZERO); + } +} + +export class OptionallyRevealedData { + constructor( + public callStackItemHash: Fr, + public functionData: FunctionData, + public emittedEvents: Fr[], + public vkHash: Fr, + public portalContractAddress: EthAddress, + public payFeeFromL1: boolean, + public payFeeFromPublicL2: boolean, + public calledFromL1: boolean, + public calledFromPublicL2: boolean, + ) { + assertLength(this, 'emittedEvents', EMITTED_EVENTS_LENGTH); + } + + toBuffer() { + return serializeToBuffer( + this.callStackItemHash, + this.functionData, + this.emittedEvents, + this.vkHash, + this.portalContractAddress, + this.payFeeFromL1, + this.payFeeFromPublicL2, + this.calledFromL1, + this.calledFromPublicL2, + ); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): OptionallyRevealedData { + const reader = BufferReader.asReader(buffer); + return new OptionallyRevealedData( + reader.readFr(), + reader.readObject(FunctionData), + reader.readArray(EMITTED_EVENTS_LENGTH, Fr), + reader.readFr(), + new EthAddress(reader.readBytes(32)), + reader.readBoolean(), + reader.readBoolean(), + reader.readBoolean(), + reader.readBoolean(), + ); + } + + static empty() { + return new OptionallyRevealedData( + Fr.ZERO, + FunctionData.empty(), + times(EMITTED_EVENTS_LENGTH, Fr.zero), + Fr.ZERO, + EthAddress.ZERO, + false, + false, + false, + false, + ); + } +} + +export class CombinedAccumulatedData { + constructor( + public aggregationObject: AggregationObject, + + public privateCallCount: Fr, + public publicCallCount: Fr, + + public newCommitments: Fr[], + public newNullifiers: Fr[], + + public privateCallStack: Fr[], + public publicCallStack: Fr[], + public l1MsgStack: Fr[], + + public newContracts: NewContractData[], + + public optionallyRevealedData: OptionallyRevealedData[], + + public stateTransitions: StateTransition[], + public stateReads: StateRead[], + ) { + assertLength(this, 'newCommitments', KERNEL_NEW_COMMITMENTS_LENGTH); + assertLength(this, 'newNullifiers', KERNEL_NEW_NULLIFIERS_LENGTH); + assertLength(this, 'privateCallStack', KERNEL_PRIVATE_CALL_STACK_LENGTH); + assertLength(this, 'publicCallStack', KERNEL_PUBLIC_CALL_STACK_LENGTH); + assertLength(this, 'l1MsgStack', KERNEL_L1_MSG_STACK_LENGTH); + assertLength(this, 'newContracts', KERNEL_NEW_CONTRACTS_LENGTH); + assertLength(this, 'optionallyRevealedData', KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH); + assertLength(this, 'stateTransitions', STATE_TRANSITIONS_LENGTH); + assertLength(this, 'stateReads', STATE_READS_LENGTH); + } + + toBuffer() { + return serializeToBuffer( + this.aggregationObject, + this.privateCallCount, + this.publicCallCount, + this.newCommitments, + this.newNullifiers, + this.privateCallStack, + this.publicCallStack, + this.l1MsgStack, + this.newContracts, + this.optionallyRevealedData, + this.stateTransitions, + this.stateReads, + ); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): CombinedAccumulatedData { + const reader = BufferReader.asReader(buffer); + return new CombinedAccumulatedData( + reader.readObject(AggregationObject), + reader.readFr(), + reader.readFr(), + reader.readArray(KERNEL_NEW_COMMITMENTS_LENGTH, Fr), + reader.readArray(KERNEL_NEW_NULLIFIERS_LENGTH, Fr), + reader.readArray(KERNEL_PRIVATE_CALL_STACK_LENGTH, Fr), + reader.readArray(KERNEL_PUBLIC_CALL_STACK_LENGTH, Fr), + reader.readArray(KERNEL_L1_MSG_STACK_LENGTH, Fr), + reader.readArray(KERNEL_NEW_CONTRACTS_LENGTH, NewContractData), + reader.readArray(KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, OptionallyRevealedData), + reader.readArray(STATE_TRANSITIONS_LENGTH, StateTransition), + reader.readArray(STATE_READS_LENGTH, StateRead), + ); + } + + static empty() { + return new CombinedAccumulatedData( + AggregationObject.makeFake(), + Fr.ZERO, + Fr.ZERO, + times(KERNEL_NEW_COMMITMENTS_LENGTH, Fr.zero), + times(KERNEL_NEW_NULLIFIERS_LENGTH, Fr.zero), + times(KERNEL_PRIVATE_CALL_STACK_LENGTH, Fr.zero), + times(KERNEL_PUBLIC_CALL_STACK_LENGTH, Fr.zero), + times(KERNEL_L1_MSG_STACK_LENGTH, Fr.zero), + times(KERNEL_NEW_CONTRACTS_LENGTH, NewContractData.empty), + times(KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, OptionallyRevealedData.empty), + times(STATE_TRANSITIONS_LENGTH, StateTransition.empty), + times(STATE_READS_LENGTH, StateRead.empty), + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts b/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts new file mode 100644 index 00000000000..a1b0e5b1116 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts @@ -0,0 +1,75 @@ +import { BufferReader, Fr } from '@aztec/foundation'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { TxContext } from '../tx_context.js'; + +export class PrivateHistoricTreeRoots { + constructor( + public privateDataTreeRoot: Fr, + public nullifierTreeRoot: Fr, + public contractTreeRoot: Fr, + public privateKernelVkTreeRoot: Fr, // future enhancement + ) {} + + toBuffer() { + return serializeToBuffer( + this.privateDataTreeRoot, + this.nullifierTreeRoot, + this.contractTreeRoot, + this.privateKernelVkTreeRoot, + ); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): PrivateHistoricTreeRoots { + const reader = BufferReader.asReader(buffer); + return new PrivateHistoricTreeRoots(reader.readFr(), reader.readFr(), reader.readFr(), reader.readFr()); + } + + static empty() { + return new PrivateHistoricTreeRoots(Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO); + } +} + +export class CombinedHistoricTreeRoots { + constructor( + public readonly privateHistoricTreeRoots: PrivateHistoricTreeRoots, + public readonly publicDataTreeRoot: Fr, + ) {} + + toBuffer() { + return serializeToBuffer(this.privateHistoricTreeRoots, this.publicDataTreeRoot); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new CombinedHistoricTreeRoots(reader.readObject(PrivateHistoricTreeRoots), reader.readFr()); + } + + static empty() { + return new CombinedHistoricTreeRoots(PrivateHistoricTreeRoots.empty(), Fr.ZERO); + } +} + +export class CombinedConstantData { + constructor(public historicTreeRoots: CombinedHistoricTreeRoots, public txContext: TxContext) {} + + toBuffer() { + return serializeToBuffer(this.historicTreeRoots, this.txContext); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): CombinedConstantData { + const reader = BufferReader.asReader(buffer); + return new CombinedConstantData(reader.readObject(CombinedHistoricTreeRoots), reader.readObject(TxContext)); + } + + static empty() { + return new CombinedConstantData(CombinedHistoricTreeRoots.empty(), TxContext.empty()); + } +} diff --git a/yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts b/yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts new file mode 100644 index 00000000000..0f55e442798 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/previous_kernel_data.ts @@ -0,0 +1,77 @@ +import { BufferReader, Fr } from '@aztec/foundation'; +import times from 'lodash.times'; +import { CircuitsWasm, getDummyPreviousKernelData } from '../../index.js'; +import { assertLength } from '../../utils/jsUtils.js'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { VK_TREE_HEIGHT } from '../constants.js'; +import { UInt32, UInt8Vector } from '../shared.js'; +import { VerificationKey } from '../verification_key.js'; +import { KernelCircuitPublicInputs } from './public_inputs.js'; +import { makeEmptyProof } from './private_kernel.js'; + +export class PreviousKernelData { + constructor( + public publicInputs: KernelCircuitPublicInputs, + public proof: UInt8Vector, + public vk: VerificationKey, + public vkIndex: UInt32, + public vkSiblingPath: Fr[], + ) { + assertLength(this, 'vkSiblingPath', VK_TREE_HEIGHT); + } + + /** + * Serialize this as a buffer. + * @returns The buffer. + */ + toBuffer() { + return serializeToBuffer(this.publicInputs, this.proof, this.vk, this.vkIndex, this.vkSiblingPath); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): PreviousKernelData { + const reader = BufferReader.asReader(buffer); + return new PreviousKernelData( + reader.readObject(KernelCircuitPublicInputs), + reader.readObject(UInt8Vector), + reader.readObject(VerificationKey), + reader.readNumber(), + reader.readArray(VK_TREE_HEIGHT, Fr), + ); + } + + /** + * Creates an empty instance, valid enough to be accepted by circuits + */ + static empty() { + return new PreviousKernelData( + KernelCircuitPublicInputs.empty(), + makeEmptyProof(), + VerificationKey.makeFake(), + 0, + times(VK_TREE_HEIGHT, Fr.zero), + ); + } +} + +export class DummyPreviousKernelData { + private static instance: DummyPreviousKernelData; + + private constructor(private data: PreviousKernelData) {} + + public static async getDummyPreviousKernelData(wasm: CircuitsWasm) { + if (!DummyPreviousKernelData.instance) { + const data = await getDummyPreviousKernelData(wasm); + DummyPreviousKernelData.instance = new DummyPreviousKernelData(data); + } + + return DummyPreviousKernelData.instance.getData(); + } + + public getData() { + return this.data; + } +} diff --git a/yarn-project/circuits.js/src/structs/private_kernel.test.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel.test.ts similarity index 70% rename from yarn-project/circuits.js/src/structs/private_kernel.test.ts rename to yarn-project/circuits.js/src/structs/kernel/private_kernel.test.ts index d1082873a8d..1fe00e29fe8 100644 --- a/yarn-project/circuits.js/src/structs/private_kernel.test.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel.test.ts @@ -1,5 +1,5 @@ -import { expectSerializeToMatchSnapshot } from '../tests/expectSerialize.js'; -import { makePreviousKernelData, makePrivateKernelInputs, makePrivateKernelPublicInputs } from '../tests/factories.js'; +import { expectSerializeToMatchSnapshot } from '../../tests/expectSerialize.js'; +import { makePreviousKernelData, makePrivateKernelInputs, makeKernelPublicInputs } from '../../tests/factories.js'; describe('structs/kernel', () => { it(`serializes and prints previous_kernel_data`, async () => { @@ -19,10 +19,10 @@ describe('structs/kernel', () => { }); it(`serializes and prints private_kernel_public_inputs`, async () => { - const kernelInputs = makePrivateKernelPublicInputs(); + const kernelInputs = makeKernelPublicInputs(); await expectSerializeToMatchSnapshot( kernelInputs.toBuffer(), - 'abis__test_roundtrip_serialize_private_kernel_public_inputs', + 'abis__test_roundtrip_serialize_kernel_circuit_public_inputs', ); }); }); diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts new file mode 100644 index 00000000000..b4f7ed6fded --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts @@ -0,0 +1,83 @@ +import { EthAddress, Fr } from '@aztec/foundation'; +import { FieldsOf, assertLength } from '../../utils/jsUtils.js'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { PrivateCallStackItem } from '../call_stack_item.js'; +import { CONTRACT_TREE_HEIGHT, FUNCTION_TREE_HEIGHT, PRIVATE_CALL_STACK_LENGTH } from '../constants.js'; +import { MembershipWitness } from '../membership_witness.js'; +import { UInt8Vector } from '../shared.js'; +import { SignedTxRequest } from '../tx_request.js'; +import { VerificationKey } from '../verification_key.js'; +import { PreviousKernelData } from './previous_kernel_data.js'; + +/** + * Private call data. + * @see circuits/cpp/src/aztec3/circuits/abis/call_stack_item.hpp + */ +export class PrivateCallData { + constructor( + public callStackItem: PrivateCallStackItem, + public privateCallStackPreimages: PrivateCallStackItem[], + public proof: UInt8Vector, + public vk: VerificationKey, + public functionLeafMembershipWitness: MembershipWitness, + public contractLeafMembershipWitness: MembershipWitness, + public portalContractAddress: EthAddress, + public acirHash: Fr, + ) { + assertLength(this, 'privateCallStackPreimages', PRIVATE_CALL_STACK_LENGTH); + } + + /** + * Serialize into a field array. Low-level utility. + * @param fields - Object with fields. + * @returns The array. + */ + static getFields(fields: FieldsOf) { + return [ + // NOTE: Must have same order as CPP. + fields.callStackItem, + fields.privateCallStackPreimages, + fields.proof, + fields.vk, + fields.functionLeafMembershipWitness, + fields.contractLeafMembershipWitness, + fields.portalContractAddress, + fields.acirHash, + ] as const; + } + + static from(fields: FieldsOf): PrivateCallData { + return new PrivateCallData(...PrivateCallData.getFields(fields)); + } + + /** + * Serialize this as a buffer. + * @returns The buffer. + */ + toBuffer(): Buffer { + return serializeToBuffer(...PrivateCallData.getFields(this)); + } +} + +/** + * Input to the private kernel circuit. + */ +export class PrivateKernelInputs { + constructor( + public signedTxRequest: SignedTxRequest, + public previousKernel: PreviousKernelData, + public privateCall: PrivateCallData, + ) {} + + /** + * Serialize this as a buffer. + * @returns The buffer. + */ + toBuffer() { + return serializeToBuffer(this.signedTxRequest, this.previousKernel, this.privateCall); + } +} + +export function makeEmptyProof() { + return new UInt8Vector(Buffer.alloc(0)); +} diff --git a/yarn-project/circuits.js/src/structs/kernel/public_inputs.ts b/yarn-project/circuits.js/src/structs/kernel/public_inputs.ts new file mode 100644 index 00000000000..20f32f52e21 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/public_inputs.ts @@ -0,0 +1,38 @@ +import { BufferReader } from '@aztec/foundation'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { CombinedAccumulatedData } from './combined_accumulated_data.js'; +import { CombinedConstantData } from './combined_constant_data.js'; + +/** + * Public inputs of the public and private kernel circuits. + * @see circuits/cpp/src/aztec3/circuits/abis/kernel_circuit_public_inputs.hpp + */ + +export class KernelCircuitPublicInputs { + constructor( + public end: CombinedAccumulatedData, + public constants: CombinedConstantData, + public isPrivateKernel: boolean, + ) {} + + toBuffer() { + return serializeToBuffer(this.end, this.constants, this.isPrivateKernel); + } + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param buffer - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): KernelCircuitPublicInputs { + const reader = BufferReader.asReader(buffer); + return new KernelCircuitPublicInputs( + reader.readObject(CombinedAccumulatedData), + reader.readObject(CombinedConstantData), + reader.readBoolean(), + ); + } + + static empty() { + return new KernelCircuitPublicInputs(CombinedAccumulatedData.empty(), CombinedConstantData.empty(), true); + } +} diff --git a/yarn-project/circuits.js/src/structs/public_kernel.ts b/yarn-project/circuits.js/src/structs/kernel/public_kernel.ts similarity index 70% rename from yarn-project/circuits.js/src/structs/public_kernel.ts rename to yarn-project/circuits.js/src/structs/kernel/public_kernel.ts index 900f0d0bbc7..3a696951948 100644 --- a/yarn-project/circuits.js/src/structs/public_kernel.ts +++ b/yarn-project/circuits.js/src/structs/kernel/public_kernel.ts @@ -1,17 +1,19 @@ -import { AztecAddress, Fr } from '@aztec/foundation'; -import { PreviousKernelData as PreviousPrivateKernelData } from './private_kernel.js'; -import { MembershipWitness, UInt8Vector } from './shared.js'; -import { SignedTxRequest } from './tx.js'; -import { VerificationKey } from './verification_key.js'; +import { Fr } from '@aztec/foundation'; +import { assertLength } from '../../utils/jsUtils.js'; +import { PublicCallStackItem } from '../call_stack_item.js'; import { PUBLIC_CALL_STACK_LENGTH, PUBLIC_DATA_TREE_HEIGHT, STATE_READS_LENGTH, STATE_TRANSITIONS_LENGTH, -} from './constants.js'; -import { assertLength } from '../utils/jsUtils.js'; -import { FunctionData } from './function_data.js'; -import { PublicCircuitPublicInputs } from './public_circuit_public_inputs.js'; +} from '../constants.js'; +import { PreviousKernelData as PreviousPrivateKernelData } from './previous_kernel_data.js'; +import { CombinedConstantData } from './combined_constant_data.js'; +import { CombinedAccumulatedData } from './combined_accumulated_data.js'; +import { UInt8Vector } from '../shared.js'; +import { MembershipWitness } from '../membership_witness.js'; +import { SignedTxRequest } from '../tx_request.js'; +import { VerificationKey } from '../verification_key.js'; export type PublicKernelInputs = | PublicKernelInputsNonFirstIteration @@ -70,18 +72,6 @@ export class PublicCallData { } } -export class PublicCallStackItem { - constructor( - public readonly contractAddress: AztecAddress, - public readonly functionSignature: FunctionData, - public readonly publicInputs: PublicCircuitPublicInputs, - ) {} - - static empty() { - return new this(AztecAddress.ZERO, FunctionData.empty(), PublicCircuitPublicInputs.empty()); - } -} - export class PreviousPublicKernelData { constructor( public readonly publicInputs: PublicKernelPublicInputs, @@ -95,18 +85,6 @@ export class PublicKernelPublicInputs { constructor(public readonly end: CombinedAccumulatedData, public readonly constants: CombinedConstantData) {} static empty() { - return new this(CombinedAccumulatedData.empty(), CombinedConstantData.empty()); - } -} - -class CombinedAccumulatedData { - static empty() { - return new this(); - } -} - -class CombinedConstantData { - static empty() { - return new this(); + return new PublicKernelPublicInputs(CombinedAccumulatedData.empty(), CombinedConstantData.empty()); } } diff --git a/yarn-project/circuits.js/src/structs/membership_witness.ts b/yarn-project/circuits.js/src/structs/membership_witness.ts new file mode 100644 index 00000000000..43dc1dcda36 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/membership_witness.ts @@ -0,0 +1,47 @@ +import { Fr } from '@aztec/foundation/fields'; +import { assertLength, range } from '../utils/jsUtils.js'; +import { serializeToBuffer } from '../utils/serialize.js'; +import { UInt32 } from './shared.js'; + +export class MembershipWitness { + constructor(pathSize: N, public leafIndex: UInt32, public siblingPath: Fr[]) { + assertLength(this, 'siblingPath', pathSize); + } + + toBuffer() { + return serializeToBuffer(this.leafIndex, ...this.siblingPath); + } + + static mock(size: number, start: number) { + return new MembershipWitness( + size, + start, + range(size, start).map(x => new Fr(BigInt(x))), + ); + } + + public static random(pathSize: N) { + return new MembershipWitness( + pathSize, + 0, + Array(pathSize) + .fill(0) + .map(() => Fr.random()), + ); + } + + public static empty(pathSize: N, leafIndex: UInt32) { + const arr = Array(pathSize) + .fill(0) + .map(() => Fr.ZERO); + return new MembershipWitness(pathSize, leafIndex, arr); + } + + static fromBufferArray(leafIndex: number, siblingPath: Buffer[]) { + return new MembershipWitness( + siblingPath.length, + leafIndex, + siblingPath.map(x => Fr.fromBuffer(x)), + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/merge_rollup.ts b/yarn-project/circuits.js/src/structs/merge_rollup.ts deleted file mode 100644 index 01f1ec4b009..00000000000 --- a/yarn-project/circuits.js/src/structs/merge_rollup.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { serializeToBuffer } from '../utils/serialize.js'; -import { BaseOrMergeRollupPublicInputs } from './base_rollup.js'; -import { ROLLUP_VK_TREE_HEIGHT } from './constants.js'; -import { MembershipWitness, UInt32, UInt8Vector } from './shared.js'; -import { VerificationKey } from './verification_key.js'; - -export class PreviousRollupData { - constructor( - public publicInputs: BaseOrMergeRollupPublicInputs, - public proof: UInt8Vector, - public vk: VerificationKey, - /** - * The index of the rollup circuit's vk in a big tree of rollup circuit vks. - */ - public vkIndex: UInt32, - public vkSiblingPath: MembershipWitness, - ) {} - - toBuffer() { - return serializeToBuffer(this.publicInputs, this.proof, this.vk, this.vkIndex, this.vkSiblingPath); - } -} - -export class MergeRollupInputs { - constructor(public previousRollupData: [PreviousRollupData, PreviousRollupData]) {} - - toBuffer() { - return serializeToBuffer(this.previousRollupData); - } -} diff --git a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts index ff76fe67a1c..a8acd64909f 100644 --- a/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/private_circuit_public_inputs.ts @@ -12,7 +12,7 @@ import { PUBLIC_CALL_STACK_LENGTH, RETURN_VALUES_LENGTH, } from './constants.js'; -import { ContractDeploymentData } from './tx.js'; +import { ContractDeploymentData } from './tx_context.js'; /** * Public inputs to a private circuit. diff --git a/yarn-project/circuits.js/src/structs/private_kernel.ts b/yarn-project/circuits.js/src/structs/private_kernel.ts deleted file mode 100644 index 8b44688abf8..00000000000 --- a/yarn-project/circuits.js/src/structs/private_kernel.ts +++ /dev/null @@ -1,416 +0,0 @@ -import { CircuitsWasm, getDummyPreviousKernelData } from '../index.js'; -import { assertLength, FieldsOf } from '../utils/jsUtils.js'; -import { serializeToBuffer } from '../utils/serialize.js'; -import { - CONTRACT_TREE_HEIGHT, - EMITTED_EVENTS_LENGTH, - FUNCTION_TREE_HEIGHT, - KERNEL_L1_MSG_STACK_LENGTH, - KERNEL_NEW_COMMITMENTS_LENGTH, - KERNEL_NEW_CONTRACTS_LENGTH, - KERNEL_NEW_NULLIFIERS_LENGTH, - KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, - KERNEL_PRIVATE_CALL_STACK_LENGTH, - KERNEL_PUBLIC_CALL_STACK_LENGTH, - PRIVATE_CALL_STACK_LENGTH, - VK_TREE_HEIGHT, -} from './constants.js'; -import { FunctionData } from './function_data.js'; -import { PrivateCallStackItem } from './private_call_stack_item.js'; -import { AggregationObject, MembershipWitness, UInt32, UInt8Vector } from './shared.js'; -import { ContractDeploymentData, SignedTxRequest, TxContext } from './tx.js'; -import { VerificationKey } from './verification_key.js'; -import { AztecAddress, EthAddress, Fr, BufferReader } from '@aztec/foundation'; -import times from 'lodash.times'; - -export class HistoricTreeRoots { - constructor( - public privateDataTreeRoot: Fr, - public nullifierTreeRoot: Fr, - public contractTreeRoot: Fr, - public privateKernelVkTreeRoot: Fr, // future enhancement - ) {} - - toBuffer() { - return serializeToBuffer( - this.privateDataTreeRoot, - this.nullifierTreeRoot, - this.contractTreeRoot, - this.privateKernelVkTreeRoot, - ); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): HistoricTreeRoots { - const reader = BufferReader.asReader(buffer); - return new HistoricTreeRoots(reader.readFr(), reader.readFr(), reader.readFr(), reader.readFr()); - } -} - -export class ConstantData { - constructor(public historicTreeRoots: HistoricTreeRoots, public txContext: TxContext) {} - - toBuffer() { - return serializeToBuffer(this.historicTreeRoots, this.txContext); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): ConstantData { - const reader = BufferReader.asReader(buffer); - return new ConstantData(reader.readObject(HistoricTreeRoots), reader.readObject(TxContext)); - } -} - -// Not to be confused with ContractDeploymentData (maybe think of better names) -export class NewContractData { - constructor( - public contractAddress: AztecAddress, - public portalContractAddress: EthAddress, - public functionTreeRoot: Fr, - ) {} - - toBuffer() { - return serializeToBuffer(this.contractAddress, this.portalContractAddress, this.functionTreeRoot); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): NewContractData { - const reader = BufferReader.asReader(buffer); - return new NewContractData(reader.readObject(AztecAddress), new EthAddress(reader.readBytes(32)), reader.readFr()); - } -} - -export class OptionallyRevealedData { - constructor( - public callStackItemHash: Fr, - public functionData: FunctionData, - public emittedEvents: Fr[], - public vkHash: Fr, - public portalContractAddress: EthAddress, - public payFeeFromL1: boolean, - public payFeeFromPublicL2: boolean, - public calledFromL1: boolean, - public calledFromPublicL2: boolean, - ) { - assertLength(this, 'emittedEvents', EMITTED_EVENTS_LENGTH); - } - - toBuffer() { - return serializeToBuffer( - this.callStackItemHash, - this.functionData, - this.emittedEvents, - this.vkHash, - this.portalContractAddress, - this.payFeeFromL1, - this.payFeeFromPublicL2, - this.calledFromL1, - this.calledFromPublicL2, - ); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): OptionallyRevealedData { - const reader = BufferReader.asReader(buffer); - return new OptionallyRevealedData( - reader.readFr(), - reader.readObject(FunctionData), - reader.readArray(EMITTED_EVENTS_LENGTH, Fr), - reader.readFr(), - new EthAddress(reader.readBytes(32)), - reader.readBoolean(), - reader.readBoolean(), - reader.readBoolean(), - reader.readBoolean(), - ); - } -} - -export class AccumulatedData { - constructor( - public aggregationObject: AggregationObject, // Contains the aggregated proof of all previous kernel iterations - - public privateCallCount: Fr, - - public newCommitments: Fr[], - public newNullifiers: Fr[], - - public privateCallStack: Fr[], - public publicCallStack: Fr[], - public l1MsgStack: Fr[], - - public newContracts: NewContractData[], - - public optionallyRevealedData: OptionallyRevealedData[], - ) { - assertLength(this, 'newCommitments', KERNEL_NEW_COMMITMENTS_LENGTH); - assertLength(this, 'newNullifiers', KERNEL_NEW_NULLIFIERS_LENGTH); - assertLength(this, 'privateCallStack', KERNEL_PRIVATE_CALL_STACK_LENGTH); - assertLength(this, 'publicCallStack', KERNEL_PUBLIC_CALL_STACK_LENGTH); - assertLength(this, 'l1MsgStack', KERNEL_L1_MSG_STACK_LENGTH); - assertLength(this, 'newContracts', KERNEL_NEW_CONTRACTS_LENGTH); - assertLength(this, 'optionallyRevealedData', KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH); - } - - toBuffer() { - return serializeToBuffer( - this.aggregationObject, - this.privateCallCount, - this.newCommitments, - this.newNullifiers, - this.privateCallStack, - this.publicCallStack, - this.l1MsgStack, - this.newContracts, - this.optionallyRevealedData, - ); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): AccumulatedData { - const reader = BufferReader.asReader(buffer); - return new AccumulatedData( - reader.readObject(AggregationObject), - reader.readFr(), - reader.readArray(KERNEL_NEW_COMMITMENTS_LENGTH, Fr), - reader.readArray(KERNEL_NEW_NULLIFIERS_LENGTH, Fr), - reader.readArray(KERNEL_PRIVATE_CALL_STACK_LENGTH, Fr), - reader.readArray(KERNEL_PUBLIC_CALL_STACK_LENGTH, Fr), - reader.readArray(KERNEL_L1_MSG_STACK_LENGTH, Fr), - reader.readArray(KERNEL_NEW_CONTRACTS_LENGTH, NewContractData), - reader.readArray(KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, OptionallyRevealedData), - ); - } -} - -export class PrivateKernelPublicInputs { - constructor(public end: AccumulatedData, public constants: ConstantData, public isPrivateKernel: true) {} - - toBuffer() { - return serializeToBuffer(this.end, this.constants, this.isPrivateKernel); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): PrivateKernelPublicInputs { - const reader = BufferReader.asReader(buffer); - return new PrivateKernelPublicInputs(reader.readObject(AccumulatedData), reader.readObject(ConstantData), true); - } - - static makeEmpty() { - return new PrivateKernelPublicInputs(makeEmptyAccumulatedData(), makeEmptyConstantData(), true); - } -} - -export class PreviousKernelData { - constructor( - public publicInputs: PrivateKernelPublicInputs, - public proof: UInt8Vector, - public vk: VerificationKey, - public vkIndex: UInt32, // the index of the kernel circuit's vk in a big tree of kernel circuit vks - public vkSiblingPath: Fr[], - ) { - assertLength(this, 'vkSiblingPath', VK_TREE_HEIGHT); - } - - /** - * Serialize this as a buffer. - * @returns The buffer. - */ - toBuffer() { - return serializeToBuffer(this.publicInputs, this.proof, this.vk, this.vkIndex, this.vkSiblingPath); - } - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param buffer - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): PreviousKernelData { - const reader = BufferReader.asReader(buffer); - return new PreviousKernelData( - reader.readObject(PrivateKernelPublicInputs), - reader.readObject(UInt8Vector), - reader.readObject(VerificationKey), - reader.readNumber(), - reader.readArray(VK_TREE_HEIGHT, Fr), - ); - } - - /** - * Creates an empty instance, valid enough to be accepted by circuits - */ - static makeEmpty() { - return new PreviousKernelData( - PrivateKernelPublicInputs.makeEmpty(), - makeEmptyProof(), - VerificationKey.makeFake(), - 0, - Array(VK_TREE_HEIGHT).fill(frZero()), - ); - } -} - -export class DummyPreviousKernelData { - private static instance: DummyPreviousKernelData; - - private constructor(private data: PreviousKernelData) {} - - public static async getDummyPreviousKernelData(wasm: CircuitsWasm) { - if (!DummyPreviousKernelData.instance) { - const data = await getDummyPreviousKernelData(wasm); - DummyPreviousKernelData.instance = new DummyPreviousKernelData(data); - } - - return DummyPreviousKernelData.instance.getData(); - } - - public getData() { - return this.data; - } -} - -/** - * Private call data. - * @see cpp/src/aztec3/circuits/abis/call_stack_item.hpp. - */ -export class PrivateCallData { - constructor( - public callStackItem: PrivateCallStackItem, - public privateCallStackPreimages: PrivateCallStackItem[], - public proof: UInt8Vector, - public vk: VerificationKey, - public functionLeafMembershipWitness: MembershipWitness, - public contractLeafMembershipWitness: MembershipWitness, - public portalContractAddress: EthAddress, - public acirHash: Fr, - ) { - assertLength(this, 'privateCallStackPreimages', PRIVATE_CALL_STACK_LENGTH); - } - - /** - * Serialize into a field array. Low-level utility. - * @param fields - Object with fields. - * @returns The array. - */ - static getFields(fields: FieldsOf) { - return [ - // NOTE: Must have same order as CPP. - fields.callStackItem, - fields.privateCallStackPreimages, - fields.proof, - fields.vk, - fields.functionLeafMembershipWitness, - fields.contractLeafMembershipWitness, - fields.portalContractAddress, - fields.acirHash, - ] as const; - } - - static from(fields: FieldsOf): PrivateCallData { - return new PrivateCallData(...PrivateCallData.getFields(fields)); - } - - /** - * Serialize this as a buffer. - * @returns The buffer. - */ - toBuffer(): Buffer { - return serializeToBuffer(...PrivateCallData.getFields(this)); - } -} - -/** - * Input to the private kernel circuit. - */ -export class PrivateKernelInputs { - constructor( - public signedTxRequest: SignedTxRequest, - public previousKernel: PreviousKernelData, - public privateCall: PrivateCallData, - ) {} - - /** - * Serialize this as a buffer. - * @returns The buffer. - */ - toBuffer() { - return serializeToBuffer(this.signedTxRequest, this.previousKernel, this.privateCall); - } -} - -// Helper functions for making empty structs (delete them eventually to use real data or factories instances) -// or move them somewhere generic, or within each struct - -function frZero() { - return Fr.fromBuffer(Buffer.alloc(32, 0)); -} - -function makeEmptyEthAddress() { - return new EthAddress(Buffer.alloc(20, 0)); -} - -function makeEmptyNewContractData(): NewContractData { - return new NewContractData(AztecAddress.ZERO, makeEmptyEthAddress(), frZero()); -} - -function makeEmptyTxContext(): TxContext { - const deploymentData = new ContractDeploymentData(frZero(), frZero(), frZero(), makeEmptyEthAddress()); - return new TxContext(false, false, true, deploymentData); -} - -function makeEmptyHistoricTreeRoots(): HistoricTreeRoots { - return new HistoricTreeRoots(frZero(), frZero(), frZero(), frZero()); -} - -function makeEmptyConstantData(): ConstantData { - return new ConstantData(makeEmptyHistoricTreeRoots(), makeEmptyTxContext()); -} - -function makeEmptyOptionallyRevealedData(): OptionallyRevealedData { - return new OptionallyRevealedData( - frZero(), - new FunctionData(Buffer.alloc(4), true, true), - times(EMITTED_EVENTS_LENGTH, frZero), - frZero(), - makeEmptyEthAddress(), - false, - false, - false, - false, - ); -} - -function makeEmptyAccumulatedData(): AccumulatedData { - return new AccumulatedData( - AggregationObject.makeFake(), - frZero(), - times(KERNEL_NEW_COMMITMENTS_LENGTH, frZero), - times(KERNEL_NEW_NULLIFIERS_LENGTH, frZero), - times(KERNEL_PRIVATE_CALL_STACK_LENGTH, frZero), - times(KERNEL_PUBLIC_CALL_STACK_LENGTH, frZero), - times(KERNEL_L1_MSG_STACK_LENGTH, frZero), - times(KERNEL_NEW_CONTRACTS_LENGTH, makeEmptyNewContractData), - times(KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, makeEmptyOptionallyRevealedData), - ); -} - -export function makeEmptyProof() { - return new UInt8Vector(Buffer.alloc(0)); -} diff --git a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts index 83e86cda779..e227de5dea6 100644 --- a/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts +++ b/yarn-project/circuits.js/src/structs/public_circuit_public_inputs.ts @@ -1,4 +1,4 @@ -import { AztecAddress, Fr } from '@aztec/foundation'; +import { AztecAddress, BufferReader, Fr } from '@aztec/foundation'; import times from 'lodash.times'; import { FieldsOf, assertLength } from '../utils/jsUtils.js'; import { CallContext } from './call_context.js'; @@ -11,22 +11,54 @@ import { STATE_READS_LENGTH, STATE_TRANSITIONS_LENGTH, } from './constants.js'; +import { serializeToBuffer } from '../utils/serialize.js'; /** * Read operations from the public state tree. */ -export interface StateRead { - storageSlot: Fr; - value: Fr; +export class StateRead { + constructor(public readonly storageSlot: Fr, public readonly value: Fr) {} + + static from(args: { storageSlot: Fr; value: Fr }) { + return new StateRead(args.storageSlot, args.value); + } + + toBuffer() { + return serializeToBuffer(this.storageSlot, this.value); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new StateRead(reader.readFr(), reader.readFr()); + } + + static empty() { + return new StateRead(Fr.ZERO, Fr.ZERO); + } } /** * Write operations on the public state tree. */ -export interface StateTransition { - storageSlot: Fr; - oldValue: Fr; - newValue: Fr; +export class StateTransition { + constructor(public readonly storageSlot: Fr, public readonly oldValue: Fr, public readonly newValue: Fr) {} + + static from(args: { storageSlot: Fr; oldValue: Fr; newValue: Fr }) { + return new StateTransition(args.storageSlot, args.oldValue, args.newValue); + } + + toBuffer() { + return serializeToBuffer(this.storageSlot, this.oldValue, this.newValue); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new StateTransition(reader.readFr(), reader.readFr(), reader.readFr()); + } + + static empty() { + return new StateTransition(Fr.ZERO, Fr.ZERO, Fr.ZERO); + } } /** @@ -38,10 +70,11 @@ export class PublicCircuitPublicInputs { public args: Fr[], public returnValues: Fr[], public emittedEvents: Fr[], - public publicCallStack: Fr[], - public l1MsgStack: Fr[], public stateTransitions: StateTransition[], public stateReads: StateRead[], + public publicCallStack: Fr[], + public l1MsgStack: Fr[], + public historicPublicDataTreeRoot: Fr, public proverAddress: AztecAddress, ) { assertLength(this, 'args', ARGS_LENGTH); @@ -52,6 +85,7 @@ export class PublicCircuitPublicInputs { assertLength(this, 'stateTransitions', STATE_TRANSITIONS_LENGTH); assertLength(this, 'stateReads', STATE_READS_LENGTH); } + /** * Create PublicCircuitPublicInputs from a fields dictionary. * @param fields - The dictionary. @@ -72,10 +106,11 @@ export class PublicCircuitPublicInputs { frArray(ARGS_LENGTH), frArray(RETURN_VALUES_LENGTH), frArray(EMITTED_EVENTS_LENGTH), + times(STATE_TRANSITIONS_LENGTH, StateTransition.empty), + times(STATE_READS_LENGTH, StateRead.empty), frArray(PUBLIC_CALL_STACK_LENGTH), frArray(L1_MSG_STACK_LENGTH), - times(STATE_TRANSITIONS_LENGTH, () => ({ storageSlot: Fr.ZERO, oldValue: Fr.ZERO, newValue: Fr.ZERO })), - times(STATE_READS_LENGTH, () => ({ storageSlot: Fr.ZERO, value: Fr.ZERO })), + Fr.ZERO, AztecAddress.ZERO, ); } @@ -90,11 +125,20 @@ export class PublicCircuitPublicInputs { fields.args, fields.returnValues, fields.emittedEvents, - fields.publicCallStack, - fields.l1MsgStack, fields.stateTransitions, fields.stateReads, + fields.publicCallStack, + fields.l1MsgStack, + fields.historicPublicDataTreeRoot, fields.proverAddress, ] as const; } + + /** + * Serialize this as a buffer. + * @returns The buffer. + */ + toBuffer(): Buffer { + return serializeToBuffer(...PublicCircuitPublicInputs.getFields(this)); + } } diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/base_rollup.test.ts.snap b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/base_rollup.test.ts.snap similarity index 72% rename from yarn-project/circuits.js/src/structs/__snapshots__/base_rollup.test.ts.snap rename to yarn-project/circuits.js/src/structs/rollup/__snapshots__/base_rollup.test.ts.snap index 19347cc3e14..21e12d43f56 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/base_rollup.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/base_rollup.test.ts.snap @@ -16,6 +16,7 @@ proof_witness_indices: [ 106 107 108 109 10a 10b ] has_data: 0 private_call_count: 0x10c +public_call_count: 0x10d new_commitments: [ 0x200 0x201 0x202 0x203 ] new_nullifiers: @@ -89,13 +90,39 @@ pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 ] +state_transitions: +[ storage_slot: 0x900 +old_value: 0x901 +new_value: 0x902 + storage_slot: 0x901 +old_value: 0x902 +new_value: 0x903 + storage_slot: 0x902 +old_value: 0x903 +new_value: 0x904 + storage_slot: 0x903 +old_value: 0x904 +new_value: 0x905 + ] +state_reads: +[ storage_slot: 0xa00 +current_value: 0xa01 + storage_slot: 0xa01 +current_value: 0xa02 + storage_slot: 0xa02 +current_value: 0xa03 + storage_slot: 0xa03 +current_value: 0xa04 + ] constants: -historic_tree_roots: private_data_tree_root: 0x200 +historic_tree_roots: private_historic_tree_roots: private_data_tree_root: 0x200 nullifier_tree_root: 0x201 contract_tree_root: 0x202 private_kernel_vk_tree_root: 0x203 +public_data_tree_root: 0x204 + tx_context: is_fee_payment_tx: 0 is_rebate_payment_tx: 0 is_contract_deployment_tx: 1 @@ -135,6 +162,7 @@ proof_witness_indices: [ 206 207 208 209 20a 20b ] has_data: 0 private_call_count: 0x20c +public_call_count: 0x20d new_commitments: [ 0x300 0x301 0x302 0x303 ] new_nullifiers: @@ -208,13 +236,39 @@ pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 ] +state_transitions: +[ storage_slot: 0xa00 +old_value: 0xa01 +new_value: 0xa02 + storage_slot: 0xa01 +old_value: 0xa02 +new_value: 0xa03 + storage_slot: 0xa02 +old_value: 0xa03 +new_value: 0xa04 + storage_slot: 0xa03 +old_value: 0xa04 +new_value: 0xa05 + ] +state_reads: +[ storage_slot: 0xb00 +current_value: 0xb01 + storage_slot: 0xb01 +current_value: 0xb02 + storage_slot: 0xb02 +current_value: 0xb03 + storage_slot: 0xb03 +current_value: 0xb04 + ] constants: -historic_tree_roots: private_data_tree_root: 0x300 +historic_tree_roots: private_historic_tree_roots: private_data_tree_root: 0x300 nullifier_tree_root: 0x301 contract_tree_root: 0x302 private_kernel_vk_tree_root: 0x303 +public_data_tree_root: 0x304 + tx_context: is_fee_payment_tx: 0 is_rebate_payment_tx: 0 is_contract_deployment_tx: 1 @@ -253,6 +307,10 @@ start_contract_tree_snapshot: root: 0x300 next_available_leaf_index: 768 +start_public_data_tree_snapshot: +root: 0x400 +next_available_leaf_index: 1024 + low_nullifier_leaf_preimages: [ leaf_value: 0x1000 next_value: 0x1100 @@ -303,6 +361,24 @@ new_nullifiers_subtree_sibling_path: [ 0x4000 0x4001 0x4002 0x4003 0x4004 ] new_contracts_subtree_sibling_path: [ 0x5000 0x5001 0x5002 ] +new_state_transitions_sibling_paths: +[ leaf_index: 6000 +sibling_path: [ 0x6000 0x6001 0x6002 0x6003 0x6004 0x6005 0x6006 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f ] + leaf_index: 6001 +sibling_path: [ 0x6001 0x6002 0x6003 0x6004 0x6005 0x6006 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f 0x6020 ] + leaf_index: 6002 +sibling_path: [ 0x6002 0x6003 0x6004 0x6005 0x6006 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f 0x6020 0x6021 ] + leaf_index: 6003 +sibling_path: [ 0x6003 0x6004 0x6005 0x6006 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f 0x6020 0x6021 0x6022 ] + leaf_index: 6004 +sibling_path: [ 0x6004 0x6005 0x6006 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f 0x6020 0x6021 0x6022 0x6023 ] + leaf_index: 6005 +sibling_path: [ 0x6005 0x6006 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f 0x6020 0x6021 0x6022 0x6023 0x6024 ] + leaf_index: 6006 +sibling_path: [ 0x6006 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f 0x6020 0x6021 0x6022 0x6023 0x6024 0x6025 ] + leaf_index: 6007 +sibling_path: [ 0x6007 0x6008 0x6009 0x600a 0x600b 0x600c 0x600d 0x600e 0x600f 0x6010 0x6011 0x6012 0x6013 0x6014 0x6015 0x6016 0x6017 0x6018 0x6019 0x601a 0x601b 0x601c 0x601d 0x601e 0x601f 0x6020 0x6021 0x6022 0x6023 0x6024 0x6025 0x6026 ] + ] historic_private_data_tree_root_membership_witnesses: [ leaf_index: 6000 sibling_path: [ 0x6000 0x6001 0x6002 0x6003 0x6004 0x6005 0x6006 0x6007 ] @@ -395,6 +471,14 @@ end_contract_tree_snapshot: root: 0x800 next_available_leaf_index: 2048 +start_public_data_tree_snapshot: +root: 0x900 +next_available_leaf_index: 2304 + +end_public_data_tree_snapshot: +root: 0x1000 +next_available_leaf_index: 4096 + calldata_hash: [ 0x901 0x902 ] " `; diff --git a/yarn-project/circuits.js/src/structs/__snapshots__/root_rollup.test.ts.snap b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/root_rollup.test.ts.snap similarity index 93% rename from yarn-project/circuits.js/src/structs/__snapshots__/root_rollup.test.ts.snap rename to yarn-project/circuits.js/src/structs/rollup/__snapshots__/root_rollup.test.ts.snap index 062996f05b0..03cc84369b1 100644 --- a/yarn-project/circuits.js/src/structs/__snapshots__/root_rollup.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/rollup/__snapshots__/root_rollup.test.ts.snap @@ -59,6 +59,14 @@ end_contract_tree_snapshot: root: 0x800 next_available_leaf_index: 800 +start_public_data_tree_snapshot: +root: 0x900 +next_available_leaf_index: 900 + +end_public_data_tree_snapshot: +root: 0x1000 +next_available_leaf_index: 1000 + calldata_hash: [ 0x901 0x902 ] proof: [ 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 ] @@ -133,6 +141,14 @@ end_contract_tree_snapshot: root: 0x1800 next_available_leaf_index: 1800 +start_public_data_tree_snapshot: +root: 0x1900 +next_available_leaf_index: 1900 + +end_public_data_tree_snapshot: +root: 0x2000 +next_available_leaf_index: 2000 + calldata_hash: [ 0x1901 0x1902 ] proof: [ 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 50 ] diff --git a/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts b/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts new file mode 100644 index 00000000000..78c64f35e31 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/rollup/append_only_tree_snapshot.ts @@ -0,0 +1,20 @@ +import { BufferReader, Fr } from '@aztec/foundation'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { UInt32 } from '../shared.js'; + +export class AppendOnlyTreeSnapshot { + constructor(public root: Fr, public nextAvailableLeafIndex: UInt32) {} + + toBuffer() { + return serializeToBuffer(this.root, this.nextAvailableLeafIndex); + } + + static fromBuffer(buffer: Buffer | BufferReader): AppendOnlyTreeSnapshot { + const reader = BufferReader.asReader(buffer); + return new AppendOnlyTreeSnapshot(reader.readFr(), reader.readNumber()); + } + + static empty() { + return new AppendOnlyTreeSnapshot(Fr.ZERO, 0); + } +} diff --git a/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts new file mode 100644 index 00000000000..4304f43b446 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/rollup/base_or_merge_rollup_public_inputs.ts @@ -0,0 +1,84 @@ +import { BufferReader, Fr } from '@aztec/foundation'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { RollupTypes } from '../shared.js'; +import { AggregationObject } from '../aggregation_object.js'; +import { AppendOnlyTreeSnapshot } from './append_only_tree_snapshot.js'; +import { ConstantBaseRollupData } from './base_rollup.js'; + +/** + * Output of the base rollup circuit + */ + +export class BaseOrMergeRollupPublicInputs { + constructor( + public rollupType: RollupTypes, + public rollupSubTreeHeight: Fr, + public endAggregationObject: AggregationObject, + public constants: ConstantBaseRollupData, + + public startPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot, + public endPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot, + + public startNullifierTreeSnapshot: AppendOnlyTreeSnapshot, + public endNullifierTreeSnapshot: AppendOnlyTreeSnapshot, + + public startContractTreeSnapshot: AppendOnlyTreeSnapshot, + public endContractTreeSnapshot: AppendOnlyTreeSnapshot, + + public startPublicDataTreeTreeSnapshot: AppendOnlyTreeSnapshot, + public endPublicDataTreeTreeSnapshot: AppendOnlyTreeSnapshot, + + // Hashes (sha256), to make public inputs constant-sized (to then be unpacked on-chain). Length 2 for high and low + public calldataHash: [Fr, Fr], + ) {} + + /** + * Deserializes from a buffer or reader, corresponding to a write in cpp. + * @param bufferReader - Buffer to read from. + */ + static fromBuffer(buffer: Buffer | BufferReader): BaseOrMergeRollupPublicInputs { + const reader = BufferReader.asReader(buffer); + return new BaseOrMergeRollupPublicInputs( + reader.readNumber(), + reader.readFr(), + reader.readObject(AggregationObject), + reader.readObject(ConstantBaseRollupData), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readObject(AppendOnlyTreeSnapshot), + reader.readArray(2, Fr) as [Fr, Fr], + ); + } + + /** + * Serialize this as a buffer. + * @returns The buffer. + */ + toBuffer() { + return serializeToBuffer( + this.rollupType, + this.rollupSubTreeHeight, + this.endAggregationObject, + this.constants, + + this.startPrivateDataTreeSnapshot, + this.endPrivateDataTreeSnapshot, + + this.startNullifierTreeSnapshot, + this.endNullifierTreeSnapshot, + + this.startContractTreeSnapshot, + this.endContractTreeSnapshot, + + this.startPublicDataTreeTreeSnapshot, + this.endPublicDataTreeTreeSnapshot, + + this.calldataHash, + ); + } +} diff --git a/yarn-project/circuits.js/src/structs/base_rollup.test.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup.test.ts similarity index 86% rename from yarn-project/circuits.js/src/structs/base_rollup.test.ts rename to yarn-project/circuits.js/src/structs/rollup/base_rollup.test.ts index 1b41c07071b..3ea37664bcb 100644 --- a/yarn-project/circuits.js/src/structs/base_rollup.test.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup.test.ts @@ -1,6 +1,6 @@ -import { expectReserializeToMatchObject, expectSerializeToMatchSnapshot } from '../tests/expectSerialize.js'; -import { makeBaseRollupInputs, makeBaseRollupPublicInputs } from '../tests/factories.js'; -import { BaseOrMergeRollupPublicInputs } from './base_rollup.js'; +import { expectReserializeToMatchObject, expectSerializeToMatchSnapshot } from '../../tests/expectSerialize.js'; +import { makeBaseRollupInputs, makeBaseRollupPublicInputs } from '../../tests/factories.js'; +import { BaseOrMergeRollupPublicInputs } from './base_or_merge_rollup_public_inputs.js'; describe('structs/base_rollup', () => { it(`serializes and prints BaseRollupInputs`, async () => { diff --git a/yarn-project/circuits.js/src/structs/base_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts similarity index 64% rename from yarn-project/circuits.js/src/structs/base_rollup.ts rename to yarn-project/circuits.js/src/structs/rollup/base_rollup.ts index 9ddde8a7a8a..eda5f3d3214 100644 --- a/yarn-project/circuits.js/src/structs/base_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts @@ -1,6 +1,6 @@ import { BufferReader, Fr } from '@aztec/foundation'; -import { assertLength, FieldsOf } from '../utils/jsUtils.js'; -import { serializeToBuffer } from '../utils/serialize.js'; +import { assertLength, FieldsOf } from '../../utils/jsUtils.js'; +import { serializeToBuffer } from '../../utils/serialize.js'; import { CONTRACT_TREE_HEIGHT, CONTRACT_TREE_ROOTS_TREE_HEIGHT, @@ -10,9 +10,13 @@ import { NULLIFIER_TREE_HEIGHT, PRIVATE_DATA_TREE_HEIGHT, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, -} from './constants.js'; -import { PreviousKernelData } from './private_kernel.js'; -import { AggregationObject, MembershipWitness, RollupTypes, UInt32 } from './shared.js'; + PUBLIC_DATA_TREE_HEIGHT, + STATE_TRANSITIONS_LENGTH, +} from '../constants.js'; +import { PreviousKernelData } from '../kernel/previous_kernel_data.js'; +import { UInt32 } from '../shared.js'; +import { MembershipWitness } from '../membership_witness.js'; +import { AppendOnlyTreeSnapshot } from './append_only_tree_snapshot.js'; export class NullifierLeafPreimage { constructor(public leafValue: Fr, public nextValue: Fr, public nextIndex: UInt32) {} @@ -26,19 +30,6 @@ export class NullifierLeafPreimage { } } -export class AppendOnlyTreeSnapshot { - constructor(public root: Fr, public nextAvailableLeafIndex: UInt32) {} - - toBuffer() { - return serializeToBuffer(this.root, this.nextAvailableLeafIndex); - } - - static fromBuffer(buffer: Buffer | BufferReader): AppendOnlyTreeSnapshot { - const reader = BufferReader.asReader(buffer); - return new AppendOnlyTreeSnapshot(reader.readFr(), reader.readNumber()); - } -} - export class ConstantBaseRollupData { constructor( // The very latest roots as at the very beginning of the entire rollup: @@ -101,6 +92,7 @@ export class BaseRollupInputs { public startPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot, public startNullifierTreeSnapshot: AppendOnlyTreeSnapshot, public startContractTreeSnapshot: AppendOnlyTreeSnapshot, + public startPublicDataTreeSnapshot: AppendOnlyTreeSnapshot, public lowNullifierLeafPreimages: NullifierLeafPreimage[], public lowNullifierMembershipWitness: MembershipWitness[], @@ -108,6 +100,7 @@ export class BaseRollupInputs { public newCommitmentsSubtreeSiblingPath: Fr[], public newNullifiersSubtreeSiblingPath: Fr[], public newContractsSubtreeSiblingPath: Fr[], + public newStateTransitionsSiblingPath: MembershipWitness[], public historicPrivateDataTreeRootMembershipWitnesses: [ MembershipWitness, @@ -137,6 +130,7 @@ export class BaseRollupInputs { 'newContractsSubtreeSiblingPath', CONTRACT_TREE_HEIGHT - BaseRollupInputs.CONTRACT_SUBTREE_HEIGHT, ); + assertLength(this, 'newStateTransitionsSiblingPath', 2 * STATE_TRANSITIONS_LENGTH); } static from(fields: FieldsOf): BaseRollupInputs { @@ -149,11 +143,13 @@ export class BaseRollupInputs { fields.startPrivateDataTreeSnapshot, fields.startNullifierTreeSnapshot, fields.startContractTreeSnapshot, + fields.startPublicDataTreeSnapshot, fields.lowNullifierLeafPreimages, fields.lowNullifierMembershipWitness, fields.newCommitmentsSubtreeSiblingPath, fields.newNullifiersSubtreeSiblingPath, fields.newContractsSubtreeSiblingPath, + fields.newStateTransitionsSiblingPath, fields.historicPrivateDataTreeRootMembershipWitnesses, fields.historicContractsTreeRootMembershipWitnesses, fields.constants, @@ -164,72 +160,3 @@ export class BaseRollupInputs { return serializeToBuffer(...BaseRollupInputs.getFields(this)); } } - -/** - * Output of the base rollup circuit - */ -export class BaseOrMergeRollupPublicInputs { - constructor( - public rollupType: RollupTypes, - public rollupSubTreeHeight: Fr, - public endAggregationObject: AggregationObject, - public constants: ConstantBaseRollupData, - - public startPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot, - public endPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot, - - public startNullifierTreeSnapshot: AppendOnlyTreeSnapshot, - public endNullifierTreeSnapshot: AppendOnlyTreeSnapshot, - - public startContractTreeSnapshot: AppendOnlyTreeSnapshot, - public endContractTreeSnapshot: AppendOnlyTreeSnapshot, - - // Hashes (sha256), to make public inputs constant-sized (to then be unpacked on-chain). Length 2 for high and low - public calldataHash: [Fr, Fr], - ) {} - - /** - * Deserializes from a buffer or reader, corresponding to a write in cpp. - * @param bufferReader - Buffer to read from. - */ - static fromBuffer(buffer: Buffer | BufferReader): BaseOrMergeRollupPublicInputs { - const reader = BufferReader.asReader(buffer); - return new BaseOrMergeRollupPublicInputs( - reader.readNumber(), - reader.readFr(), - reader.readObject(AggregationObject), - reader.readObject(ConstantBaseRollupData), - reader.readObject(AppendOnlyTreeSnapshot), - reader.readObject(AppendOnlyTreeSnapshot), - reader.readObject(AppendOnlyTreeSnapshot), - reader.readObject(AppendOnlyTreeSnapshot), - reader.readObject(AppendOnlyTreeSnapshot), - reader.readObject(AppendOnlyTreeSnapshot), - reader.readArray(2, Fr) as [Fr, Fr], - ); - } - - /** - * Serialize this as a buffer. - * @returns The buffer. - */ - toBuffer() { - return serializeToBuffer( - this.rollupType, - this.rollupSubTreeHeight, - this.endAggregationObject, - this.constants, - - this.startPrivateDataTreeSnapshot, - this.endPrivateDataTreeSnapshot, - - this.startNullifierTreeSnapshot, - this.endNullifierTreeSnapshot, - - this.startContractTreeSnapshot, - this.endContractTreeSnapshot, - - this.calldataHash, - ); - } -} diff --git a/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts new file mode 100644 index 00000000000..a4e32abe719 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/rollup/merge_rollup.ts @@ -0,0 +1,10 @@ +import { serializeToBuffer } from '../../utils/serialize.js'; +import { PreviousRollupData } from './previous_rollup_data.js'; + +export class MergeRollupInputs { + constructor(public previousRollupData: [PreviousRollupData, PreviousRollupData]) {} + + toBuffer() { + return serializeToBuffer(this.previousRollupData); + } +} diff --git a/yarn-project/circuits.js/src/structs/rollup/previous_rollup_data.ts b/yarn-project/circuits.js/src/structs/rollup/previous_rollup_data.ts new file mode 100644 index 00000000000..ed88f0bc953 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/rollup/previous_rollup_data.ts @@ -0,0 +1,23 @@ +import { serializeToBuffer } from '../../utils/serialize.js'; +import { BaseOrMergeRollupPublicInputs } from './base_or_merge_rollup_public_inputs.js'; +import { ROLLUP_VK_TREE_HEIGHT } from '../constants.js'; +import { UInt32, UInt8Vector } from '../shared.js'; +import { MembershipWitness } from '../membership_witness.js'; +import { VerificationKey } from '../verification_key.js'; + +export class PreviousRollupData { + constructor( + public publicInputs: BaseOrMergeRollupPublicInputs, + public proof: UInt8Vector, + public vk: VerificationKey, + /** + * The index of the rollup circuit's vk in a big tree of rollup circuit vks. + */ + public vkIndex: UInt32, + public vkSiblingPath: MembershipWitness, + ) {} + + toBuffer() { + return serializeToBuffer(this.publicInputs, this.proof, this.vk, this.vkIndex, this.vkSiblingPath); + } +} diff --git a/yarn-project/circuits.js/src/structs/root_rollup.test.ts b/yarn-project/circuits.js/src/structs/rollup/root_rollup.test.ts similarity index 92% rename from yarn-project/circuits.js/src/structs/root_rollup.test.ts rename to yarn-project/circuits.js/src/structs/rollup/root_rollup.test.ts index 7e1102e1950..bb99f7fba60 100644 --- a/yarn-project/circuits.js/src/structs/root_rollup.test.ts +++ b/yarn-project/circuits.js/src/structs/rollup/root_rollup.test.ts @@ -1,5 +1,5 @@ -import { expectReserializeToMatchObject, expectSerializeToMatchSnapshot } from '../tests/expectSerialize.js'; -import { makeRootRollupInputs, makeRootRollupPublicInputs } from '../tests/factories.js'; +import { expectReserializeToMatchObject, expectSerializeToMatchSnapshot } from '../../tests/expectSerialize.js'; +import { makeRootRollupInputs, makeRootRollupPublicInputs } from '../../tests/factories.js'; import { RootRollupPublicInputs } from './root_rollup.js'; describe('structs/root_rollup', () => { diff --git a/yarn-project/circuits.js/src/structs/root_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts similarity index 91% rename from yarn-project/circuits.js/src/structs/root_rollup.ts rename to yarn-project/circuits.js/src/structs/rollup/root_rollup.ts index 3af96eef1bd..9f826e17b40 100644 --- a/yarn-project/circuits.js/src/structs/root_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts @@ -1,10 +1,10 @@ import { BufferReader, Fr } from '@aztec/foundation'; -import { assertLength, FieldsOf } from '../utils/jsUtils.js'; -import { serializeToBuffer } from '../utils/serialize.js'; -import { AppendOnlyTreeSnapshot } from './base_rollup.js'; -import { CONTRACT_TREE_ROOTS_TREE_HEIGHT, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT } from './constants.js'; -import { PreviousRollupData } from './merge_rollup.js'; -import { AggregationObject } from './shared.js'; +import { assertLength, FieldsOf } from '../../utils/jsUtils.js'; +import { serializeToBuffer } from '../../utils/serialize.js'; +import { AppendOnlyTreeSnapshot } from './append_only_tree_snapshot.js'; +import { CONTRACT_TREE_ROOTS_TREE_HEIGHT, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT } from '../constants.js'; +import { PreviousRollupData } from './previous_rollup_data.js'; +import { AggregationObject } from '../aggregation_object.js'; export class RootRollupInputs { constructor( diff --git a/yarn-project/circuits.js/src/structs/shared.ts b/yarn-project/circuits.js/src/structs/shared.ts index 8f28b8f5ed8..d753bb179c6 100644 --- a/yarn-project/circuits.js/src/structs/shared.ts +++ b/yarn-project/circuits.js/src/structs/shared.ts @@ -1,92 +1,7 @@ import { BufferReader, randomBytes } from '@aztec/foundation'; -import { Fq, Fr } from '@aztec/foundation/fields'; -import { assertLength, range } from '../utils/jsUtils.js'; +import { Fq } from '@aztec/foundation/fields'; +import { assertLength } from '../utils/jsUtils.js'; import { Bufferable, serializeToBuffer } from '../utils/serialize.js'; -import times from 'lodash.times'; - -export class MembershipWitness { - constructor(pathSize: N, public leafIndex: UInt32, public siblingPath: Fr[]) { - assertLength(this, 'siblingPath', pathSize); - } - - toBuffer() { - return serializeToBuffer(this.leafIndex, ...this.siblingPath); - } - - static mock(size: number, start: number) { - return new MembershipWitness( - size, - start, - range(size, start).map(x => new Fr(BigInt(x))), - ); - } - - public static random(pathSize: N) { - return new MembershipWitness( - pathSize, - 0, - Array(pathSize) - .fill(0) - .map(() => Fr.random()), - ); - } - - public static makeEmpty(pathSize: N, leafIndex: UInt32) { - const arr = Array(pathSize) - .fill(0) - .map(() => Fr.ZERO); - return new MembershipWitness(pathSize, leafIndex, arr); - } - - static fromBufferArray(leafIndex: number, siblingPath: Buffer[]) { - return new MembershipWitness( - siblingPath.length, - leafIndex, - siblingPath.map(x => Fr.fromBuffer(x)), - ); - } -} - -export class AggregationObject { - public publicInputs: Vector; - public proofWitnessIndices: Vector; - - constructor( - public p0: AffineElement, - public p1: AffineElement, - publicInputsData: Fr[], - proofWitnessIndicesData: UInt32[], - public hasData = false, - ) { - this.publicInputs = new Vector(publicInputsData); - this.proofWitnessIndices = new Vector(proofWitnessIndicesData); - } - - toBuffer() { - return serializeToBuffer(this.p0, this.p1, this.publicInputs, this.proofWitnessIndices, this.hasData); - } - - static fromBuffer(buffer: Buffer | BufferReader): AggregationObject { - const reader = BufferReader.asReader(buffer); - return new AggregationObject( - reader.readObject(AffineElement), - reader.readObject(AffineElement), - reader.readVector(Fr), - reader.readNumberVector(), - reader.readBoolean(), - ); - } - - static makeFake() { - return new AggregationObject( - new AffineElement(new Fq(1n), new Fq(2n)), - new AffineElement(new Fq(1n), new Fq(2n)), - [], - times(16, i => 3027 + i), - false, - ); - } -} export class Vector { constructor(public items: T[]) {} diff --git a/yarn-project/circuits.js/src/structs/tx.test.ts b/yarn-project/circuits.js/src/structs/tx_context.test.ts similarity index 100% rename from yarn-project/circuits.js/src/structs/tx.test.ts rename to yarn-project/circuits.js/src/structs/tx_context.test.ts diff --git a/yarn-project/circuits.js/src/structs/tx.ts b/yarn-project/circuits.js/src/structs/tx_context.ts similarity index 59% rename from yarn-project/circuits.js/src/structs/tx.ts rename to yarn-project/circuits.js/src/structs/tx_context.ts index 8ba40b87caa..9a16148da0e 100644 --- a/yarn-project/circuits.js/src/structs/tx.ts +++ b/yarn-project/circuits.js/src/structs/tx_context.ts @@ -1,8 +1,5 @@ -import { AztecAddress, BufferReader, EthAddress, Fr } from '@aztec/foundation'; -import { FieldsOf } from '../utils/jsUtils.js'; +import { BufferReader, EthAddress, Fr } from '@aztec/foundation'; import { serializeToBuffer } from '../utils/serialize.js'; -import { FunctionData } from './function_data.js'; -import { EcdsaSignature } from './shared.js'; /** * Contract deployment data in a TxContext @@ -81,60 +78,8 @@ export class TxContext { reader.readObject(ContractDeploymentData), ); } -} - -/** - * Signed transaction request. - * @see cpp/src/aztec3/circuits/abis/signed_tx_request.hpp. - */ -export class SignedTxRequest { - constructor(public txRequest: TxRequest, public signature: EcdsaSignature) {} - - /** - * Serialize as a buffer. - * @returns The buffer. - */ - toBuffer() { - return serializeToBuffer(this.txRequest, this.signature); - } -} - -/** - * Transaction request. - * @see cpp/src/aztec3/circuits/abis/tx_request.hpp. - */ -export class TxRequest { - constructor( - public from: AztecAddress, - public to: AztecAddress, - public functionData: FunctionData, - public args: Fr[], - public nonce: Fr, - public txContext: TxContext, - public chainId: Fr, - ) {} - static getFields(fields: FieldsOf) { - return [ - fields.from, - fields.to, - fields.functionData, - fields.args, - fields.nonce, - fields.txContext, - fields.chainId, - ] as const; - } - - static from(fields: FieldsOf): TxRequest { - return new TxRequest(...TxRequest.getFields(fields)); - } - - /** - * Serialize as a buffer. - * @returns The buffer. - */ - toBuffer() { - return serializeToBuffer(...TxRequest.getFields(this)); + static empty() { + return new TxContext(false, false, true, ContractDeploymentData.empty()); } } diff --git a/yarn-project/circuits.js/src/structs/tx_request.ts b/yarn-project/circuits.js/src/structs/tx_request.ts new file mode 100644 index 00000000000..3434bf672dd --- /dev/null +++ b/yarn-project/circuits.js/src/structs/tx_request.ts @@ -0,0 +1,62 @@ +import { AztecAddress, Fr } from '@aztec/foundation'; +import { FieldsOf } from '../utils/jsUtils.js'; +import { serializeToBuffer } from '../utils/serialize.js'; +import { FunctionData } from './function_data.js'; +import { EcdsaSignature } from './shared.js'; +import { TxContext } from './tx_context.js'; + +/** + * Signed transaction request. + * @see cpp/src/aztec3/circuits/abis/signed_tx_request.hpp. + */ +export class SignedTxRequest { + constructor(public txRequest: TxRequest, public signature: EcdsaSignature) {} + + /** + * Serialize as a buffer. + * @returns The buffer. + */ + toBuffer() { + return serializeToBuffer(this.txRequest, this.signature); + } +} + +/** + * Transaction request. + * @see cpp/src/aztec3/circuits/abis/tx_request.hpp. + */ +export class TxRequest { + constructor( + public from: AztecAddress, + public to: AztecAddress, + public functionData: FunctionData, + public args: Fr[], + public nonce: Fr, + public txContext: TxContext, + public chainId: Fr, + ) {} + + static getFields(fields: FieldsOf) { + return [ + fields.from, + fields.to, + fields.functionData, + fields.args, + fields.nonce, + fields.txContext, + fields.chainId, + ] as const; + } + + static from(fields: FieldsOf): TxRequest { + return new TxRequest(...TxRequest.getFields(fields)); + } + + /** + * Serialize as a buffer. + * @returns The buffer. + */ + toBuffer() { + return serializeToBuffer(...TxRequest.getFields(this)); + } +} diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 24db7212d24..a1840d61ca7 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -1,19 +1,30 @@ import { AztecAddress, EthAddress, Fq, Fr } from '@aztec/foundation'; import { + BaseOrMergeRollupPublicInputs, + BaseRollupInputs, CallContext, + CombinedAccumulatedData, + CombinedConstantData, + CombinedHistoricTreeRoots, + ConstantBaseRollupData, + KernelCircuitPublicInputs, MergeRollupInputs, + NewContractData, + NullifierLeafPreimage, + OptionallyRevealedData, + PreviousKernelData, PreviousRollupData, + PrivateCallData, PrivateCircuitPublicInputs, + PrivateKernelInputs, + PrivateHistoricTreeRoots, RootRollupInputs, RootRollupPublicInputs, + StateRead, + StateTransition, } from '../index.js'; -import { - AppendOnlyTreeSnapshot, - BaseRollupInputs, - BaseOrMergeRollupPublicInputs, - ConstantBaseRollupData, - NullifierLeafPreimage, -} from '../structs/base_rollup.js'; +import { AggregationObject } from '../structs/aggregation_object.js'; +import { PrivateCallStackItem } from '../structs/call_stack_item.js'; import { ARGS_LENGTH, CONTRACT_TREE_HEIGHT, @@ -35,33 +46,19 @@ import { PRIVATE_DATA_TREE_HEIGHT, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, PUBLIC_CALL_STACK_LENGTH, + PUBLIC_DATA_TREE_HEIGHT, RETURN_VALUES_LENGTH, ROLLUP_VK_TREE_HEIGHT, + STATE_READS_LENGTH, + STATE_TRANSITIONS_LENGTH, VK_TREE_HEIGHT, } from '../structs/constants.js'; import { FunctionData } from '../structs/function_data.js'; -import { - AccumulatedData, - ConstantData, - NewContractData, - HistoricTreeRoots, - OptionallyRevealedData, - PreviousKernelData, - PrivateCallData, - PrivateKernelInputs, - PrivateKernelPublicInputs, -} from '../structs/private_kernel.js'; -import { PrivateCallStackItem } from '../structs/private_call_stack_item.js'; -import { - AffineElement, - AggregationObject, - ComposerType, - EcdsaSignature, - MembershipWitness, - RollupTypes, - UInt8Vector, -} from '../structs/shared.js'; -import { ContractDeploymentData, SignedTxRequest, TxContext, TxRequest } from '../structs/tx.js'; +import { MembershipWitness } from '../structs/membership_witness.js'; +import { AppendOnlyTreeSnapshot } from '../structs/rollup/append_only_tree_snapshot.js'; +import { AffineElement, ComposerType, EcdsaSignature, RollupTypes, UInt8Vector } from '../structs/shared.js'; +import { ContractDeploymentData, TxContext } from '../structs/tx_context.js'; +import { SignedTxRequest, TxRequest } from '../structs/tx_request.js'; import { CommitmentMap, G1AffineElement, VerificationKey } from '../structs/verification_key.js'; import { range } from '../utils/jsUtils.js'; import { numToUInt32BE } from '../utils/serialize.js'; @@ -71,12 +68,16 @@ export function makeTxContext(seed: number): TxContext { return new TxContext(false, false, true, deploymentData); } -export function makeHistoricTreeRoots(seed: number): HistoricTreeRoots { - return new HistoricTreeRoots(fr(seed), fr(seed + 1), fr(seed + 2), fr(seed + 3)); +export function makePrivateHistoricTreeRoots(seed: number): PrivateHistoricTreeRoots { + return new PrivateHistoricTreeRoots(fr(seed), fr(seed + 1), fr(seed + 2), fr(seed + 3)); +} + +export function makeCombinedHistoricTreeRoots(seed: number): CombinedHistoricTreeRoots { + return new CombinedHistoricTreeRoots(makePrivateHistoricTreeRoots(seed), fr(seed + 4)); } -export function makeConstantData(seed = 1): ConstantData { - return new ConstantData(makeHistoricTreeRoots(seed), makeTxContext(seed + 4)); +export function makeConstantData(seed = 1): CombinedConstantData { + return new CombinedConstantData(makeCombinedHistoricTreeRoots(seed), makeTxContext(seed + 4)); } export function makeSelector(seed: number) { @@ -85,10 +86,19 @@ export function makeSelector(seed: number) { return buffer; } -export function makeAccumulatedData(seed = 1): AccumulatedData { - return new AccumulatedData( +export function makeStateTransition(seed = 1) { + return new StateTransition(fr(seed), fr(seed + 1), fr(seed + 2)); +} + +export function makeStateRead(seed = 1) { + return new StateRead(fr(seed), fr(seed + 1)); +} + +export function makeAccumulatedData(seed = 1): CombinedAccumulatedData { + return new CombinedAccumulatedData( makeAggregationObject(seed), fr(seed + 12), + fr(seed + 13), range(KERNEL_NEW_COMMITMENTS_LENGTH, seed + 0x100).map(fr), range(KERNEL_NEW_NULLIFIERS_LENGTH, seed + 0x200).map(fr), range(KERNEL_PRIVATE_CALL_STACK_LENGTH, seed + 0x300).map(fr), @@ -96,6 +106,8 @@ export function makeAccumulatedData(seed = 1): AccumulatedData { range(KERNEL_L1_MSG_STACK_LENGTH, seed + 0x500).map(fr), range(KERNEL_NEW_CONTRACTS_LENGTH, seed + 0x600).map(makeNewContractData), range(KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH, seed + 0x700).map(makeOptionallyRevealedData), + range(STATE_TRANSITIONS_LENGTH, seed + 0x800).map(makeStateTransition), + range(STATE_READS_LENGTH, seed + 0x900).map(makeStateRead), ); } @@ -126,8 +138,8 @@ export function makeAggregationObject(seed = 1): AggregationObject { ); } -export function makePrivateKernelPublicInputs(seed = 1): PrivateKernelPublicInputs { - return new PrivateKernelPublicInputs(makeAccumulatedData(seed), makeConstantData(seed + 0x100), true); +export function makeKernelPublicInputs(seed = 1): KernelCircuitPublicInputs { + return new KernelCircuitPublicInputs(makeAccumulatedData(seed), makeConstantData(seed + 0x100), true); } export function makeDynamicSizeBuffer(size: number, fill: number) { @@ -150,9 +162,10 @@ export function makeVerificationKey(): VerificationKey { range(5, 400), ); } + export function makePreviousKernelData(seed = 1): PreviousKernelData { return new PreviousKernelData( - makePrivateKernelPublicInputs(seed), + makeKernelPublicInputs(seed), makeDynamicSizeBuffer(16, seed + 0x80), makeVerificationKey(), 0x42, @@ -278,6 +291,8 @@ export function makeBaseRollupPublicInputs(seed = 0) { makeAppendOnlyTreeSnapshot(seed + 0x600), makeAppendOnlyTreeSnapshot(seed + 0x700), makeAppendOnlyTreeSnapshot(seed + 0x800), + makeAppendOnlyTreeSnapshot(seed + 0x900), + makeAppendOnlyTreeSnapshot(seed + 0x1000), [fr(seed + 0x901), fr(seed + 0x902)], ); } @@ -330,6 +345,7 @@ export function makeBaseRollupInputs(seed = 0) { const startPrivateDataTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x100); const startNullifierTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x200); const startContractTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x300); + const startPublicDataTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x400); const lowNullifierLeafPreimages = range(2 * KERNEL_NEW_NULLIFIERS_LENGTH, seed + 0x1000).map( x => new NullifierLeafPreimage(fr(x), fr(x + 0x100), x + 0x200), @@ -354,6 +370,10 @@ export function makeBaseRollupInputs(seed = 0) { seed + 0x5000, ).map(x => fr(x)); + const newStateTransitionsSiblingPath = range(2 * STATE_TRANSITIONS_LENGTH, seed + 0x6000).map(x => + makeMembershipWitness(PUBLIC_DATA_TREE_HEIGHT, x), + ); + const historicPrivateDataTreeRootMembershipWitnesses: BaseRollupInputs['historicPrivateDataTreeRootMembershipWitnesses'] = [ makeMembershipWitness(PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, seed + 0x6000), @@ -373,11 +393,13 @@ export function makeBaseRollupInputs(seed = 0) { startPrivateDataTreeSnapshot, startNullifierTreeSnapshot, startContractTreeSnapshot, + startPublicDataTreeSnapshot, lowNullifierLeafPreimages, lowNullifierMembershipWitness, newCommitmentsSubtreeSiblingPath, newNullifiersSubtreeSiblingPath, newContractsSubtreeSiblingPath, + newStateTransitionsSiblingPath, historicPrivateDataTreeRootMembershipWitnesses, historicContractsTreeRootMembershipWitnesses, constants, diff --git a/yarn-project/foundation/src/fields/fields.ts b/yarn-project/foundation/src/fields/fields.ts index e41db257de1..25fc74c6e64 100644 --- a/yarn-project/foundation/src/fields/fields.ts +++ b/yarn-project/foundation/src/fields/fields.ts @@ -39,6 +39,14 @@ export class Fr { return new Fr(r); } + /** + * Returns a new zero-value field. + * @returns A new zero-value field. + */ + static zero() { + return new Fr(0n); + } + /** * Create an instance of the corresponding class (Fr or Fq) from a Buffer or a BufferReader. * Reads 'SIZE_IN_BYTES' bytes from the given Buffer or BufferReader and constructs an instance with the decoded value. diff --git a/yarn-project/kernel-prover/src/kernel_prover.test.ts b/yarn-project/kernel-prover/src/kernel_prover.test.ts index 16284b816e5..4c022f1261a 100644 --- a/yarn-project/kernel-prover/src/kernel_prover.test.ts +++ b/yarn-project/kernel-prover/src/kernel_prover.test.ts @@ -5,7 +5,7 @@ import { PRIVATE_CALL_STACK_LENGTH, PrivateCallStackItem, PrivateCircuitPublicInputs, - PrivateKernelPublicInputs, + KernelCircuitPublicInputs, TxRequest, VK_TREE_HEIGHT, VerificationKey, @@ -53,7 +53,7 @@ describe('Kernel Prover', () => { }; const createProofOutput = (newNoteIndices: number[]) => { - const publicInputs = PrivateKernelPublicInputs.makeEmpty(); + const publicInputs = KernelCircuitPublicInputs.empty(); publicInputs.end.newCommitments = newNoteIndices.map(idx => generateFakeSiloedCommitment(notes[idx])); return { publicInputs, diff --git a/yarn-project/kernel-prover/src/kernel_prover.ts b/yarn-project/kernel-prover/src/kernel_prover.ts index 5a253e175a7..e6d89b31b8d 100644 --- a/yarn-project/kernel-prover/src/kernel_prover.ts +++ b/yarn-project/kernel-prover/src/kernel_prover.ts @@ -7,7 +7,7 @@ import { PreviousKernelData, PrivateCallData, PrivateCallStackItem, - PrivateKernelPublicInputs, + KernelCircuitPublicInputs, SignedTxRequest, TxRequest, VK_TREE_HEIGHT, @@ -42,7 +42,7 @@ export class KernelProver { let firstIteration = true; let previousVerificationKey = VerificationKey.makeFake(); let output: ProofOutput = { - publicInputs: PrivateKernelPublicInputs.makeEmpty(), + publicInputs: KernelCircuitPublicInputs.empty(), proof: makeEmptyProof(), }; while (executionStack.length) { diff --git a/yarn-project/kernel-prover/src/proof_creator.ts b/yarn-project/kernel-prover/src/proof_creator.ts index afb05c64c43..abec47054dd 100644 --- a/yarn-project/kernel-prover/src/proof_creator.ts +++ b/yarn-project/kernel-prover/src/proof_creator.ts @@ -5,7 +5,7 @@ import { PreviousKernelData, PrivateCallData, PrivateCircuitPublicInputs, - PrivateKernelPublicInputs, + KernelCircuitPublicInputs, SignedTxRequest, UInt8Vector, makeEmptyProof, @@ -15,7 +15,7 @@ import { Fr } from '@aztec/foundation'; import { createDebugLogger } from '@aztec/foundation/log'; export interface ProofOutput { - publicInputs: PrivateKernelPublicInputs; + publicInputs: KernelCircuitPublicInputs; proof: UInt8Vector; } diff --git a/yarn-project/p2p/src/client/mocks.ts b/yarn-project/p2p/src/client/mocks.ts index 97990a29b4d..e3799f383b8 100644 --- a/yarn-project/p2p/src/client/mocks.ts +++ b/yarn-project/p2p/src/client/mocks.ts @@ -1,12 +1,12 @@ import { UInt8Vector } from '@aztec/circuits.js'; -import { makePrivateKernelPublicInputs } from '@aztec/circuits.js/factories'; +import { makeKernelPublicInputs } from '@aztec/circuits.js/factories'; import { AztecAddress } from '@aztec/foundation'; import { ContractData, L2Block, L2BlockSource } from '@aztec/types'; import { Tx } from '@aztec/types'; import { UnverifiedData } from '@aztec/types'; export const MockTx = () => { - return Tx.createPrivate(makePrivateKernelPublicInputs(), new UInt8Vector(Buffer.alloc(0)), UnverifiedData.random(8)); + return Tx.createPrivate(makeKernelPublicInputs(), new UInt8Vector(Buffer.alloc(0)), UnverifiedData.random(8)); }; export class MockBlockSource implements L2BlockSource { diff --git a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts index d54812c1d20..10e3d8e0e76 100644 --- a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.test.ts @@ -10,7 +10,7 @@ import { import { makeBaseRollupPublicInputs, makeNewContractData, - makePrivateKernelPublicInputs, + makeKernelPublicInputs, makeRootRollupPublicInputs, } from '@aztec/circuits.js/factories'; import { PrivateTx, Tx } from '@aztec/types'; @@ -114,7 +114,9 @@ describe('sequencer/circuit_block_builder', () => { ['contractTreeRoot', MerkleTreeId.CONTRACT_TREE], ['nullifierTreeRoot', MerkleTreeId.NULLIFIER_TREE], ] as const) { - tx.data.constants.historicTreeRoots[name] = Fr.fromBuffer((await builderDb.getTreeInfo(id)).root); + tx.data.constants.historicTreeRoots.privateHistoricTreeRoots[name] = Fr.fromBuffer( + (await builderDb.getTreeInfo(id)).root, + ); } }; @@ -125,7 +127,7 @@ describe('sequencer/circuit_block_builder', () => { await builder.updateRootTrees(); // Assemble a fake transaction, we'll tweak some fields below - const tx = Tx.createPrivate(makePrivateKernelPublicInputs(), emptyProof, makeEmptyUnverifiedData()); + const tx = Tx.createPrivate(makeKernelPublicInputs(), emptyProof, makeEmptyUnverifiedData()); const txsLeft = [tx, makeEmptyPrivateTx()]; const txsRight = [makeEmptyPrivateTx(), makeEmptyPrivateTx()]; diff --git a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts index 8eb3f00d89e..ec3b448e722 100644 --- a/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/circuit_block_builder.ts @@ -10,12 +10,14 @@ import { NULLIFIER_TREE_HEIGHT, NullifierLeafPreimage, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, + PUBLIC_DATA_TREE_HEIGHT, PreviousKernelData, PreviousRollupData, ROLLUP_VK_TREE_HEIGHT, RollupTypes, RootRollupInputs, RootRollupPublicInputs, + STATE_TRANSITIONS_LENGTH, UInt8Vector, VK_TREE_HEIGHT, VerificationKey, @@ -391,7 +393,7 @@ export class CircuitBlockBuilder implements BlockBuilder { protected getContractMembershipWitnessFor(tx: PrivateTx) { return this.getMembershipWitnessFor( - tx.data.constants.historicTreeRoots.contractTreeRoot, + tx.data.constants.historicTreeRoots.privateHistoricTreeRoots.contractTreeRoot, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, CONTRACT_TREE_ROOTS_TREE_HEIGHT, ); @@ -399,7 +401,7 @@ export class CircuitBlockBuilder implements BlockBuilder { protected getDataMembershipWitnessFor(tx: PrivateTx) { return this.getMembershipWitnessFor( - tx.data.constants.historicTreeRoots.privateDataTreeRoot, + tx.data.constants.historicTreeRoots.privateHistoricTreeRoots.privateDataTreeRoot, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, PRIVATE_DATA_TREE_ROOTS_TREE_HEIGHT, ); @@ -691,6 +693,10 @@ export class CircuitBlockBuilder implements BlockBuilder { const startContractTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); const startPrivateDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); + // TODO: Uncomment once the public data tree gets merged + // const startPublicDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE); + const startPublicDataTreeSnapshot = AppendOnlyTreeSnapshot.empty(); + // Update the contract and data trees with the new items being inserted to get the new roots // that will be used by the next iteration of the base rollup circuit, skipping the empty ones const wasm = await CircuitsWasm.get(); @@ -729,14 +735,21 @@ export class CircuitBlockBuilder implements BlockBuilder { BaseRollupInputs.NULLIFIER_SUBTREE_HEIGHT, ); + // TODO: Implement based on public tx data + const newStateTransitionsSiblingPath = times(2 * STATE_TRANSITIONS_LENGTH, () => + MembershipWitness.empty(PUBLIC_DATA_TREE_HEIGHT, 0), + ); + return BaseRollupInputs.from({ constants, startNullifierTreeSnapshot, startContractTreeSnapshot, startPrivateDataTreeSnapshot, + startPublicDataTreeSnapshot, newCommitmentsSubtreeSiblingPath, newContractsSubtreeSiblingPath, newNullifiersSubtreeSiblingPath, + newStateTransitionsSiblingPath, lowNullifierLeafPreimages: nullifierWitnesses.map((w: LowNullifierWitnessData) => w.preimage), lowNullifierMembershipWitness: lowNullifierMembershipWitnesses, kernelData: [this.getKernelDataFor(tx1), this.getKernelDataFor(tx2)], @@ -748,7 +761,7 @@ export class CircuitBlockBuilder implements BlockBuilder { await this.getDataMembershipWitnessFor(tx1), await this.getDataMembershipWitnessFor(tx2), ], - } as BaseRollupInputs); + }); } protected makeEmptyMembershipWitness(height: N) { diff --git a/yarn-project/sequencer-client/src/mocks/tx.ts b/yarn-project/sequencer-client/src/mocks/tx.ts index fdd92ccf5a3..6678b15bea8 100644 --- a/yarn-project/sequencer-client/src/mocks/tx.ts +++ b/yarn-project/sequencer-client/src/mocks/tx.ts @@ -1,5 +1,5 @@ -import { PrivateKernelPublicInputs, UInt8Vector } from '@aztec/circuits.js'; -import { makePrivateKernelPublicInputs } from '@aztec/circuits.js/factories'; +import { KernelCircuitPublicInputs, UInt8Vector } from '@aztec/circuits.js'; +import { makeKernelPublicInputs } from '@aztec/circuits.js/factories'; import { PrivateTx, Tx, UnverifiedData } from '@aztec/types'; function makeEmptyProof() { @@ -12,9 +12,9 @@ export function makeEmptyUnverifiedData(): UnverifiedData { } export function makeEmptyPrivateTx(): PrivateTx { - return Tx.createPrivate(PrivateKernelPublicInputs.makeEmpty(), makeEmptyProof(), makeEmptyUnverifiedData()); + return Tx.createPrivate(KernelCircuitPublicInputs.empty(), makeEmptyProof(), makeEmptyUnverifiedData()); } export function makePrivateTx(seed = 0): PrivateTx { - return Tx.createPrivate(makePrivateKernelPublicInputs(seed), makeEmptyProof(), UnverifiedData.random(2)); + return Tx.createPrivate(makeKernelPublicInputs(seed), makeEmptyProof(), UnverifiedData.random(2)); } diff --git a/yarn-project/sequencer-client/src/simulator/fake_public.ts b/yarn-project/sequencer-client/src/simulator/fake_public.ts index 18b1a237007..9bdde663203 100644 --- a/yarn-project/sequencer-client/src/simulator/fake_public.ts +++ b/yarn-project/sequencer-client/src/simulator/fake_public.ts @@ -8,14 +8,17 @@ import { PublicCircuitSimulator } from './index.js'; export class FakePublicCircuitSimulator implements PublicCircuitSimulator { public readonly db: WorldStatePublicDB; - constructor(merkleTree: MerkleTreeOperations) { - this.db = new WorldStatePublicDB(merkleTree); + constructor(private readonly merkleTree: MerkleTreeOperations) { + this.db = new WorldStatePublicDB(this.merkleTree); } public async publicCircuit(tx: TxRequest): Promise { const functionAbi: FunctionAbi = undefined as any; const portalAddress: EthAddress = undefined as any; + const publicDataTreeInfo = await this.merkleTree.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE); + const historicPublicDataTreeRoot = Fr.fromBuffer(publicDataTreeInfo.root); + const execution = PublicExecution.fromTransactionRequest(this.db, tx, functionAbi, portalAddress); const result = await execution.run(); return PublicCircuitPublicInputs.from({ @@ -28,6 +31,7 @@ export class FakePublicCircuitSimulator implements PublicCircuitSimulator { returnValues: result.returnValues, stateReads: result.stateReads, stateTransitions: result.stateTransitions, + historicPublicDataTreeRoot, }); } } diff --git a/yarn-project/types/src/tx.ts b/yarn-project/types/src/tx.ts index bf6e977fd93..f03f55075c5 100644 --- a/yarn-project/types/src/tx.ts +++ b/yarn-project/types/src/tx.ts @@ -1,4 +1,4 @@ -import { CircuitsWasm, PrivateKernelPublicInputs, SignedTxRequest, UInt8Vector } from '@aztec/circuits.js'; +import { CircuitsWasm, KernelCircuitPublicInputs, SignedTxRequest, UInt8Vector } from '@aztec/circuits.js'; import { computeContractLeaf } from '@aztec/circuits.js/abis'; import { createTxHash } from './create_tx_hash.js'; import { TxHash } from './tx_hash.js'; @@ -23,7 +23,7 @@ export class Tx { private hashPromise?: Promise; public static createPrivate( - data: PrivateKernelPublicInputs, + data: KernelCircuitPublicInputs, proof: UInt8Vector, unverifiedData: UnverifiedData, ): PrivateTx { @@ -35,7 +35,7 @@ export class Tx { } public static createPrivatePublic( - data: PrivateKernelPublicInputs, + data: KernelCircuitPublicInputs, proof: UInt8Vector, unverifiedData: UnverifiedData, txRequest: SignedTxRequest, @@ -44,7 +44,7 @@ export class Tx { } public static create( - data?: PrivateKernelPublicInputs, + data?: KernelCircuitPublicInputs, proof?: UInt8Vector, unverifiedData?: UnverifiedData, txRequest?: SignedTxRequest, @@ -72,7 +72,7 @@ export class Tx { * @param txRequest - Signed public function call data. */ protected constructor( - public readonly data?: PrivateKernelPublicInputs, + public readonly data?: KernelCircuitPublicInputs, public readonly proof?: UInt8Vector, public readonly unverifiedData?: UnverifiedData, public readonly txRequest?: SignedTxRequest,