Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
29ba730
fix: add array overflow composer error
Maddiaa0 Jun 6, 2023
0e4ed78
fix: add negative test case for array overflow
Maddiaa0 Jun 6, 2023
67beb49
fix: update ts tests
Maddiaa0 Jun 6, 2023
8c597f7
fix: snapshot
Maddiaa0 Jun 6, 2023
2fc0721
feat: add new_commitments aggregation to public kernel
Maddiaa0 Jun 5, 2023
855d7c8
fix: update ts gen
Maddiaa0 Jun 5, 2023
2d6dd13
fix: update snapshot
Maddiaa0 Jun 5, 2023
4f1807b
fix: hack cbind compiler output
Maddiaa0 Jun 6, 2023
53db311
fix: lint bindings a posteriori
Maddiaa0 Jun 6, 2023
21a712d
feat(): include l2 to l1 message propagation
Maddiaa0 Jun 6, 2023
ea6d959
fix: reduce init number of l2 to l1 messages in test prev kernel test
Maddiaa0 Jun 6, 2023
1fcde70
fix: lint
Maddiaa0 Jun 6, 2023
829c0a4
fix: dont create full public circuits for the tests
Maddiaa0 Jun 6, 2023
5364b22
fix: we appease the linter
Maddiaa0 Jun 6, 2023
34d0742
fix: update snapshot to be half full
Maddiaa0 Jun 6, 2023
2038413
fix: review nits
Maddiaa0 Jun 6, 2023
5c1606c
cleanup
Maddiaa0 Jun 7, 2023
caa9527
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Maddiaa0 Jun 7, 2023
4ed27be
fix: update merge snapshots
Maddiaa0 Jun 7, 2023
ff13b71
Merge branch 'md/array-push-assertions' into md/new-commitments-public
Maddiaa0 Jun 7, 2023
0faef39
Merge branch 'master' of github.com:AztecProtocol/aztec-packages into…
Maddiaa0 Jun 7, 2023
288748f
lint
Maddiaa0 Jun 7, 2023
314cd67
Merge branch 'master' into md/new-commitments-public
Maddiaa0 Jun 7, 2023
a609186
fix: drop stack from l2 to l1 messages
Maddiaa0 Jun 7, 2023
b58ee32
fix: add nullifiers
Maddiaa0 Jun 7, 2023
e2853f8
feat: add test for static call nullifier | commitment creation
Maddiaa0 Jun 7, 2023
cba25a1
fix: re-run generator
Maddiaa0 Jun 7, 2023
4d6c8ed
fix: update snapshot with new nullifiers
Maddiaa0 Jun 7, 2023
9a9eee1
fix: update private call stack item value
Maddiaa0 Jun 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ template <typename NCT> struct PublicCircuitPublicInputs {
std::array<ContractStorageRead<NCT>, KERNEL_PUBLIC_DATA_READS_LENGTH> contract_storage_reads{};

std::array<fr, PUBLIC_CALL_STACK_LENGTH> public_call_stack = zero_array<fr, PUBLIC_CALL_STACK_LENGTH>();
std::array<fr, NEW_L2_TO_L1_MSGS_LENGTH> new_l2_to_l1_msgs = zero_array<fr, NEW_L2_TO_L1_MSGS_LENGTH>();
std::array<fr, KERNEL_NEW_COMMITMENTS_LENGTH> new_commitments = zero_array<fr, KERNEL_NEW_COMMITMENTS_LENGTH>();
std::array<fr, KERNEL_NEW_NULLIFIERS_LENGTH> new_nullifiers = zero_array<fr, KERNEL_NEW_NULLIFIERS_LENGTH>();
std::array<fr, KERNEL_NEW_L2_TO_L1_MSGS_LENGTH> new_l2_to_l1_msgs =
zero_array<fr, KERNEL_NEW_L2_TO_L1_MSGS_LENGTH>();

fr historic_public_data_tree_root = 0;

Expand All @@ -47,9 +50,12 @@ template <typename NCT> struct PublicCircuitPublicInputs {
contract_storage_update_requests,
contract_storage_reads,
public_call_stack,
new_commitments,
new_nullifiers,
new_l2_to_l1_msgs,
historic_public_data_tree_root,
prover_address);

boolean operator==(PublicCircuitPublicInputs<NCT> const& other) const
{
return msgpack_derived_equals<boolean>(*this, other);
Expand All @@ -74,6 +80,8 @@ template <typename NCT> struct PublicCircuitPublicInputs {
.contract_storage_reads = map(contract_storage_reads, to_circuit_type),

.public_call_stack = to_ct(public_call_stack),
.new_commitments = to_ct(new_commitments),
.new_nullifiers = to_ct(new_nullifiers),
.new_l2_to_l1_msgs = to_ct(new_l2_to_l1_msgs),

.historic_public_data_tree_root = to_ct(historic_public_data_tree_root),
Expand Down Expand Up @@ -101,6 +109,8 @@ template <typename NCT> struct PublicCircuitPublicInputs {
spread_arr_into_vec(map(contract_storage_reads, to_hashes), inputs);

spread_arr_into_vec(public_call_stack, inputs);
spread_arr_into_vec(new_commitments, inputs);
spread_arr_into_vec(new_nullifiers, inputs);
spread_arr_into_vec(new_l2_to_l1_msgs, inputs);

inputs.push_back(historic_public_data_tree_root);
Expand Down Expand Up @@ -128,6 +138,8 @@ template <typename NCT> void read(uint8_t const*& it, PublicCircuitPublicInputs<
read(it, pis.contract_storage_reads);

read(it, pis.public_call_stack);
read(it, pis.new_commitments);
read(it, pis.new_nullifiers);
read(it, pis.new_l2_to_l1_msgs);

read(it, pis.historic_public_data_tree_root);
Expand All @@ -150,6 +162,8 @@ void write(std::vector<uint8_t>& buf, PublicCircuitPublicInputs<NCT> const& publ
write(buf, pis.contract_storage_reads);

write(buf, pis.public_call_stack);
write(buf, pis.new_commitments);
write(buf, pis.new_nullifiers);
write(buf, pis.new_l2_to_l1_msgs);

write(buf, pis.historic_public_data_tree_root);
Expand Down
187 changes: 169 additions & 18 deletions circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp

Large diffs are not rendered by default.

121 changes: 121 additions & 0 deletions circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,26 @@ void common_validate_inputs(DummyComposer& composer, KernelInput const& public_k
CircuitErrorCode::PUBLIC_KERNEL__BYTECODE_HASH_INVALID);
}

template <typename KernelInput, typename Composer>
void perform_static_call_checks(Composer& composer, KernelInput const& public_kernel_inputs)
{
// If the call is a static call, there should be no new commitments or nullifiers.
const auto& public_call_public_inputs = public_kernel_inputs.public_call.call_stack_item.public_inputs;

const auto& is_static_call = public_call_public_inputs.call_context.is_static_call;
const auto& new_commitments = public_call_public_inputs.new_commitments;
const auto& new_nullifiers = public_call_public_inputs.new_nullifiers;

if (is_static_call) {
composer.do_assert(utils::is_array_empty(new_commitments) == true,
"perform_static_call_checks in static call new commitments must be empty",
CircuitErrorCode::PUBLIC_KERNEL__NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL);
composer.do_assert(utils::is_array_empty(new_nullifiers) == true,
"perform_static_call_checks in static call new nullifiers must be empty",
CircuitErrorCode::PUBLIC_KERNEL__NEW_NULLIFIERS_PROHIBITED_IN_STATIC_CALL);
}
}

/**
* @brief Proagates valid (i.e. non-empty) update requests from this iteration to the circuit output
* @tparam The type of kernel input
Expand Down Expand Up @@ -250,6 +270,99 @@ void propagate_valid_public_data_reads(Composer& composer,
}
}

/**
* @brief Propagates new commitments from this iteration to the circuit output.
*
* @tparam The type of the kernel input
* @tparam The composer type
* @param public_kernel_inputs The inputs to this iteration to the kernel circuit.
* @param circuit_outputs The circuit outputs to be populated
*/
template <typename KernelInput, typename Composer>
void propagate_new_commitments(Composer& composer,
KernelInput const& public_kernel_inputs,
KernelCircuitPublicInputs<NT>& circuit_outputs)
{
// Get the new commitments
const auto& public_call_public_inputs = public_kernel_inputs.public_call.call_stack_item.public_inputs;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

in the private kernel, we have a check here to see if the call is static, since no changes are allowed. Is this also true for public?

https://github.com/AztecProtocol/aztec3-packages/blob/c6b68f7f05ba97d41d32d0eb3b016aa9ce670d04/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp#L101

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Great catch this looks like it should be here too!

const auto& new_commitments = public_call_public_inputs.new_commitments;
const auto& storage_contract_address = public_call_public_inputs.call_context.storage_contract_address;

std::array<NT::fr, KERNEL_NEW_COMMITMENTS_LENGTH> siloed_new_commitments{};
for (size_t i = 0; i < new_commitments.size(); ++i) {
Comment thread
LHerskind marked this conversation as resolved.
if (!new_commitments[i].is_zero()) {
siloed_new_commitments[i] = silo_commitment<NT>(storage_contract_address, new_commitments[i]);
}
}

push_array_to_array(composer, siloed_new_commitments, circuit_outputs.end.new_commitments);
}

/**
* @brief Propagates new nullifiers from this iteration to the circuit output.
*
* @tparam The type of the kernel input
* @tparam The composer type
* @param public_kernel_inputs The inputs to this iteration to the kernel circuit.
* @param circuit_outputs The circuit outputs to be populated
*/
template <typename KernelInput, typename Composer>
void propagate_new_nullifiers(Composer& composer,
KernelInput const& public_kernel_inputs,
KernelCircuitPublicInputs<NT>& circuit_outputs)
{
// Get the new commitments
const auto& public_call_public_inputs = public_kernel_inputs.public_call.call_stack_item.public_inputs;

const auto& new_nullifiers = public_call_public_inputs.new_nullifiers;
const auto& storage_contract_address = public_call_public_inputs.call_context.storage_contract_address;

std::array<NT::fr, KERNEL_NEW_NULLIFIERS_LENGTH> siloed_new_nullifiers{};
for (size_t i = 0; i < new_nullifiers.size(); ++i) {
if (!new_nullifiers[i].is_zero()) {
siloed_new_nullifiers[i] = silo_nullifier<NT>(storage_contract_address, new_nullifiers[i]);
}
}

push_array_to_array(composer, siloed_new_nullifiers, circuit_outputs.end.new_nullifiers);
}

/**
* @brief Propagates new l2 to l1 messages from this iteration to the circuit output.
*
* @tparam The type of the kernel input
* @param public_kernel_inputs The inputs to this iteration to the kernel circuit.
* @param circuit_outputs The circuit outputs to be populated
*/
template <typename KernelInput, typename Composer>
void propagate_new_l2_to_l1_messages(Composer& composer,
KernelInput const& public_kernel_inputs,
KernelCircuitPublicInputs<NT>& circuit_outputs)
{
// Get the new l2 messages
const auto& public_call_public_inputs = public_kernel_inputs.public_call.call_stack_item.public_inputs;

const auto& portal_contract_address = public_kernel_inputs.public_call.portal_contract_address;
const auto& storage_contract_address = public_call_public_inputs.call_context.storage_contract_address;
const auto& new_l2_to_l1_msgs = public_call_public_inputs.new_l2_to_l1_msgs;

std::array<NT::fr, NEW_L2_TO_L1_MSGS_LENGTH> new_l2_to_l1_msgs_to_insert{};
for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) {
if (!new_l2_to_l1_msgs[i].is_zero()) {
// @todo @lherskind chain-ids and rollup version id should be added here. right now, just hard coded.
// @todo @lherskind chain-id is hardcoded for foundry
const auto chain_id = fr(31337);
new_l2_to_l1_msgs_to_insert[i] = compute_l2_to_l1_hash<NT>(storage_contract_address,
fr(1), // rollup version id
portal_contract_address,
chain_id,
new_l2_to_l1_msgs[i]);
}
}
push_array_to_array(composer, new_l2_to_l1_msgs_to_insert, circuit_outputs.end.new_l2_to_l1_msgs);
}

/**
* @brief Propagates valid (i.e. non-empty) public data reads from this iteration to the circuit output
* @tparam The type of kernel input
Expand All @@ -265,9 +378,17 @@ void common_update_public_end_values(Composer& composer,
// Updates the circuit outputs with new state changes, call stack etc
circuit_outputs.is_private = false;

// If this call is a static call, certain operations are disallowed, such as creating new state.
perform_static_call_checks(composer, public_kernel_inputs);

const auto& stack = public_kernel_inputs.public_call.call_stack_item.public_inputs.public_call_stack;
push_array_to_array(composer, stack, circuit_outputs.end.public_call_stack);

propagate_new_commitments(composer, public_kernel_inputs, circuit_outputs);
propagate_new_nullifiers(composer, public_kernel_inputs, circuit_outputs);

propagate_new_l2_to_l1_messages(composer, public_kernel_inputs, circuit_outputs);

propagate_valid_public_data_update_requests(composer, public_kernel_inputs, circuit_outputs);

propagate_valid_public_data_reads(composer, public_kernel_inputs, circuit_outputs);
Expand Down
2 changes: 2 additions & 0 deletions circuits/cpp/src/aztec3/utils/circuit_errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ enum CircuitErrorCode : uint16_t {
PUBLIC_KERNEL__CALL_CONTEXT_INVALID_STORAGE_ADDRESS_FOR_DELEGATE_CALL = 3023,
PUBLIC_KERNEL__CALL_CONTEXT_CONTRACT_STORAGE_UPDATE_REQUESTS_PROHIBITED_FOR_STATIC_CALL = 3024,
PUBLIC_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_IN_FIRST_ITERATION = 3025,
PUBLIC_KERNEL__NEW_COMMITMENTS_PROHIBITED_IN_STATIC_CALL = 3026,
PUBLIC_KERNEL__NEW_NULLIFIERS_PROHIBITED_IN_STATIC_CALL = 3027,

BASE_FAILED = 4000,
BASE__KERNEL_PROOF_VERIFICATION_FAILED = 4001,
Expand Down
2 changes: 1 addition & 1 deletion yarn-project/circuits.js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"clean": "rm -rf ./dest .tsbuildinfo",
"formatting": "run -T prettier --check ./src && run -T eslint ./src",
"formatting:fix": "run -T prettier -w ./src",
"remake-bindings": "DEBUG=wasm ts-node-esm src/cbind/circuits.in.ts && prettier -w src/cbind/circuits.gen.ts",
"remake-bindings": "DEBUG=wasm ts-node-esm src/cbind/circuits.in.ts && sed -i 's/CallStackItem/PublicCallStackItem/g' src/cbind/circuits.gen.ts && prettier -w src/cbind/circuits.gen.ts ",
Comment thread
LHerskind marked this conversation as resolved.
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests"
},
"inherits": [
Expand Down
18 changes: 18 additions & 0 deletions yarn-project/circuits.js/src/cbind/circuits.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1006,6 +1006,8 @@ interface MsgpackPublicCircuitPublicInputs {
contract_storage_update_requests: Tuple<MsgpackContractStorageUpdateRequest, 4>;
contract_storage_reads: Tuple<MsgpackContractStorageRead, 4>;
public_call_stack: Tuple<Buffer, 4>;
new_commitments: Tuple<Buffer, 4>;
new_nullifiers: Tuple<Buffer, 4>;
new_l2_to_l1_msgs: Tuple<Buffer, 2>;
historic_public_data_tree_root: Buffer;
prover_address: Buffer;
Expand All @@ -1030,6 +1032,12 @@ export function toPublicCircuitPublicInputs(o: MsgpackPublicCircuitPublicInputs)
if (o.public_call_stack === undefined) {
throw new Error('Expected public_call_stack in PublicCircuitPublicInputs deserialization');
}
if (o.new_commitments === undefined) {
throw new Error('Expected new_commitments in PublicCircuitPublicInputs deserialization');
}
if (o.new_nullifiers === undefined) {
throw new Error('Expected new_nullifiers in PublicCircuitPublicInputs deserialization');
}
if (o.new_l2_to_l1_msgs === undefined) {
throw new Error('Expected new_l2_to_l1_msgs in PublicCircuitPublicInputs deserialization');
}
Expand All @@ -1048,6 +1056,8 @@ export function toPublicCircuitPublicInputs(o: MsgpackPublicCircuitPublicInputs)
),
mapTuple(o.contract_storage_reads, (v: MsgpackContractStorageRead) => toContractStorageRead(v)),
mapTuple(o.public_call_stack, (v: Buffer) => Fr.fromBuffer(v)),
mapTuple(o.new_commitments, (v: Buffer) => Fr.fromBuffer(v)),
mapTuple(o.new_nullifiers, (v: Buffer) => Fr.fromBuffer(v)),
mapTuple(o.new_l2_to_l1_msgs, (v: Buffer) => Fr.fromBuffer(v)),
Fr.fromBuffer(o.historic_public_data_tree_root),
Address.fromBuffer(o.prover_address),
Expand All @@ -1073,6 +1083,12 @@ export function fromPublicCircuitPublicInputs(o: PublicCircuitPublicInputs): Msg
if (o.publicCallStack === undefined) {
throw new Error('Expected publicCallStack in PublicCircuitPublicInputs serialization');
}
if (o.newCommitments === undefined) {
throw new Error('Expected newCommitments in PublicCircuitPublicInputs serialization');
}
if (o.newNullifiers === undefined) {
throw new Error('Expected newNullifiers in PublicCircuitPublicInputs serialization');
}
if (o.newL2ToL1Msgs === undefined) {
throw new Error('Expected newL2ToL1Msgs in PublicCircuitPublicInputs serialization');
}
Expand All @@ -1091,6 +1107,8 @@ export function fromPublicCircuitPublicInputs(o: PublicCircuitPublicInputs): Msg
),
contract_storage_reads: mapTuple(o.contractStorageReads, (v: ContractStorageRead) => fromContractStorageRead(v)),
public_call_stack: mapTuple(o.publicCallStack, (v: Fr) => v.toBuffer()),
new_commitments: mapTuple(o.newCommitments, (v: Fr) => v.toBuffer()),
new_nullifiers: mapTuple(o.newNullifiers, (v: Fr) => v.toBuffer()),
new_l2_to_l1_msgs: mapTuple(o.newL2ToL1Msgs, (v: Fr) => v.toBuffer()),
historic_public_data_tree_root: o.historicPublicDataTreeRoot.toBuffer(),
prover_address: o.proverAddress.toBuffer(),
Expand Down
Loading