diff --git a/circuits/cpp/src/aztec3/circuits/abis/combined_accumulated_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/combined_accumulated_data.hpp index 083dd054fb9..d88ff6d8982 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/combined_accumulated_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/combined_accumulated_data.hpp @@ -1,7 +1,7 @@ #pragma once #include "optionally_revealed_data.hpp" #include "new_contract_data.hpp" -#include "public_data_write.hpp" +#include "public_data_transition.hpp" #include "public_data_read.hpp" #include "aztec3/constants.hpp" #include @@ -42,7 +42,7 @@ template struct CombinedAccumulatedData { std::array, KERNEL_OPTIONALLY_REVEALED_DATA_LENGTH> optionally_revealed_data{}; - std::array, STATE_TRANSITIONS_LENGTH> state_transitions{}; + std::array, STATE_TRANSITIONS_LENGTH> state_transitions{}; std::array, STATE_READS_LENGTH> state_reads{}; boolean operator==(CombinedAccumulatedData const& other) const @@ -172,7 +172,7 @@ template struct CombinedAccumulatedData { } } - template void set_array_public(std::array, SIZE>& arr) + template void set_array_public(std::array, SIZE>& arr) { static_assert(!(std::is_same::value)); for (auto& e : arr) { diff --git a/circuits/cpp/src/aztec3/circuits/abis/public_data_write.hpp b/circuits/cpp/src/aztec3/circuits/abis/public_data_transition.hpp similarity index 80% rename from circuits/cpp/src/aztec3/circuits/abis/public_data_write.hpp rename to circuits/cpp/src/aztec3/circuits/abis/public_data_transition.hpp index 772cff49721..954aac0c6cf 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/public_data_write.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/public_data_transition.hpp @@ -11,7 +11,7 @@ using aztec3::GeneratorIndex; using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; -template struct PublicDataWrite { +template struct PublicDataTransition { typedef typename NCT::fr fr; typedef typename NCT::boolean boolean; @@ -19,16 +19,16 @@ template struct PublicDataWrite { fr old_value = 0; fr new_value = 0; - bool operator==(PublicDataWrite const&) const = default; + bool operator==(PublicDataTransition const&) const = default; - template PublicDataWrite> to_circuit_type(Composer& composer) const + template PublicDataTransition> 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); }; - PublicDataWrite> state_transition = { + PublicDataTransition> state_transition = { to_ct(leaf_index), to_ct(old_value), to_ct(new_value), @@ -37,13 +37,13 @@ template struct PublicDataWrite { return state_transition; }; - template PublicDataWrite to_native_type() const + template PublicDataTransition to_native_type() const { static_assert((std::is_same, NCT>::value)); auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; - PublicDataWrite state_transition = { + PublicDataTransition state_transition = { to_nt(leaf_index), to_nt(old_value), to_nt(new_value), @@ -75,7 +75,7 @@ template struct PublicDataWrite { boolean is_empty() const { return leaf_index == 0; } }; -template void read(uint8_t const*& it, PublicDataWrite& state_transition) +template void read(uint8_t const*& it, PublicDataTransition& state_transition) { using serialize::read; @@ -84,7 +84,7 @@ template void read(uint8_t const*& it, PublicDataWrite& stat read(it, state_transition.new_value); }; -template void write(std::vector& buf, PublicDataWrite const& state_transition) +template void write(std::vector& buf, PublicDataTransition const& state_transition) { using serialize::write; @@ -93,7 +93,7 @@ template void write(std::vector& buf, PublicDataWrite std::ostream& operator<<(std::ostream& os, PublicDataWrite const& state_transition) +template std::ostream& operator<<(std::ostream& os, PublicDataTransition const& state_transition) { return os << "leaf_index: " << state_transition.leaf_index << "\n" << "old_value: " << state_transition.old_value << "\n" diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp index d0984dbeb94..2d54b5e9fe8 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp @@ -271,7 +271,7 @@ TEST(public_kernel_tests, circuit_outputs_should_be_correctly_populated) const auto contract_address = inputs.public_call.call_stack_item.contract_address; for (size_t i = 0; i < STATE_TRANSITIONS_LENGTH; i++) { const auto& st = inputs.public_call.call_stack_item.public_inputs.state_transitions[i]; - const auto public_write = PublicDataWrite{ + const auto public_write = PublicDataTransition{ .leaf_index = compute_public_data_tree_index(contract_address, st.storage_slot), .new_value = compute_public_data_tree_value(st.new_value), }; @@ -369,11 +369,11 @@ TEST(public_kernel_tests, only_valid_state_transitions_should_be_propagated) // only the 2 valid transitions should have been propagated const auto contract_address = inputs.public_call.call_stack_item.contract_address; - const auto public_write_1 = PublicDataWrite{ + const auto public_write_1 = PublicDataTransition{ .leaf_index = compute_public_data_tree_index(contract_address, first_valid.storage_slot), .new_value = compute_public_data_tree_value(first_valid.new_value), }; - const auto public_write_2 = PublicDataWrite{ + const auto public_write_2 = PublicDataTransition{ .leaf_index = compute_public_data_tree_index(contract_address, second_valid.storage_slot), .new_value = compute_public_data_tree_value(second_valid.new_value), }; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp index 874aae1357b..44bc771bcbb 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -15,7 +15,7 @@ using NT = aztec3::utils::types::NativeTypes; using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::PublicDataRead; -using aztec3::circuits::abis::PublicDataWrite; +using aztec3::circuits::abis::PublicDataTransition; using aztec3::circuits::abis::StateRead; using aztec3::circuits::abis::StateTransition; using aztec3::circuits::abis::public_kernel::PublicKernelInputs; @@ -132,7 +132,7 @@ void propagate_valid_state_transitions(KernelInput const& public_kernel_inputs, if (state_transition.is_empty()) { continue; } - const auto new_write = PublicDataWrite{ + const auto new_write = PublicDataTransition{ .leaf_index = compute_public_data_tree_index(contract_address, state_transition.storage_slot), .new_value = compute_public_data_tree_value(state_transition.new_value), }; diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp index 07a20532413..b21d76e0620 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -803,7 +803,7 @@ TEST_F(base_rollup_tests, native_single_public_state_write) stdlib::merkle_tree::MemoryStore public_data_tree_store; native_base_rollup::SparseTree public_data_tree(public_data_tree_store, PUBLIC_DATA_TREE_HEIGHT); - auto data_write = abis::PublicDataWrite{ + auto data_write = abis::PublicDataTransition{ .leaf_index = fr(1), .old_value = fr(2), .new_value = fr(42), 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 10ba6ad70af..ff97efb4e57 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 @@ -1,6 +1,6 @@ #include "aztec3/circuits/abis/membership_witness.hpp" #include "aztec3/circuits/abis/public_data_read.hpp" -#include "aztec3/circuits/abis/public_data_write.hpp" +#include "aztec3/circuits/abis/public_data_transition.hpp" #include "aztec3/circuits/hash.hpp" #include "aztec3/constants.hpp" #include "aztec3/utils/circuit_errors.hpp" @@ -434,7 +434,7 @@ AppendOnlySnapshot check_nullifier_tree_non_membership_and_insert_to_tree(DummyC fr insert_state_transitions( DummyComposer& composer, fr tree_root, - std::array, STATE_TRANSITIONS_LENGTH> const& state_transitions, + std::array, STATE_TRANSITIONS_LENGTH> const& state_transitions, size_t witnesses_offset, std::array, 2 * STATE_TRANSITIONS_LENGTH> const& witnesses) { diff --git a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp index b1a23748752..97d55314129 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.hpp @@ -1,5 +1,5 @@ #pragma once -#include "aztec3/circuits/abis/public_data_write.hpp" +#include "aztec3/circuits/abis/public_data_transition.hpp" #include "barretenberg/numeric/uint256/uint256.hpp" #include "nullifier_tree_testing_harness.hpp" #include "init.hpp" @@ -101,9 +101,9 @@ void set_kernel_nullifiers(KernelData& kernel_data, std::array kernel_data); -inline abis::PublicDataWrite make_public_write(fr leaf_index, fr old_value, fr new_value) +inline abis::PublicDataTransition make_public_write(fr leaf_index, fr old_value, fr new_value) { - return abis::PublicDataWrite{ + return abis::PublicDataTransition{ .leaf_index = leaf_index, .old_value = old_value, .new_value = new_value, 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 index 34df6cb3ea1..d94017445e5 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_accumulated_data.ts @@ -132,13 +132,13 @@ export class PublicDataRead { } /** - * Write operations on the public state tree. + * Write operations on the public state tree including the previous value. */ -export class PublicDataWrite { +export class PublicDataTransition { constructor(public readonly leafIndex: Fr, public readonly oldValue: Fr, public readonly newValue: Fr) {} static from(args: { leafIndex: Fr; oldValue: Fr; newValue: Fr }) { - return new PublicDataWrite(args.leafIndex, args.oldValue, args.newValue); + return new PublicDataTransition(args.leafIndex, args.oldValue, args.newValue); } toBuffer() { @@ -147,11 +147,11 @@ export class PublicDataWrite { static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new PublicDataWrite(reader.readFr(), reader.readFr(), reader.readFr()); + return new PublicDataTransition(reader.readFr(), reader.readFr(), reader.readFr()); } static empty() { - return new PublicDataWrite(Fr.ZERO, Fr.ZERO, Fr.ZERO); + return new PublicDataTransition(Fr.ZERO, Fr.ZERO, Fr.ZERO); } } @@ -173,7 +173,7 @@ export class CombinedAccumulatedData { public optionallyRevealedData: OptionallyRevealedData[], - public stateTransitions: PublicDataWrite[], + public stateTransitions: PublicDataTransition[], public stateReads: PublicDataRead[], ) { assertLength(this, 'newCommitments', KERNEL_NEW_COMMITMENTS_LENGTH); @@ -221,7 +221,7 @@ export class CombinedAccumulatedData { 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, PublicDataWrite), + reader.readArray(STATE_TRANSITIONS_LENGTH, PublicDataTransition), reader.readArray(STATE_READS_LENGTH, PublicDataRead), ); } @@ -238,7 +238,7 @@ export class CombinedAccumulatedData { 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, PublicDataWrite.empty), + times(STATE_TRANSITIONS_LENGTH, PublicDataTransition.empty), times(STATE_READS_LENGTH, PublicDataRead.empty), ); } 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 index 78c64f35e31..8858726e46f 100644 --- 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 @@ -3,6 +3,16 @@ import { serializeToBuffer } from '../../utils/serialize.js'; import { UInt32 } from '../shared.js'; export class AppendOnlyTreeSnapshot { + /** + * Constructs a new append only tree snapshot. + * @param root - Root of the append only tree. + * @param nextAvailableLeafIndex - Index of the next available leaf in the append only tree. + * Note: We include the next available leaf index in the snapshot so that the snapshot can be used to verify that + * the insertion was performed at the correct place. If we only verified tree root then it could happen that + * some leaves would get overwritten and the tree root check would still pass. + * TLDR: We need to store the next available leaf index to ensure that the "append only" property was + * preserved when verifying state transitions. + */ constructor(public root: Fr, public nextAvailableLeafIndex: UInt32) {} toBuffer() { diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 73231ffbc74..e0db4eaefd3 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -21,7 +21,7 @@ import { PublicCallData, PublicCircuitPublicInputs, PublicDataRead, - PublicDataWrite, + PublicDataTransition, PublicKernelInputs, PublicKernelInputsNoPreviousKernel, RootRollupInputs, @@ -93,8 +93,8 @@ export function makeSelector(seed: number) { return buffer; } -export function makePublicDataWrite(seed = 1) { - return new PublicDataWrite(fr(seed), fr(seed + 1), fr(seed + 2)); +export function makePublicDataTransition(seed = 1) { + return new PublicDataTransition(fr(seed), fr(seed + 1), fr(seed + 2)); } export function makePublicDataRead(seed = 1) { @@ -121,7 +121,7 @@ export function makeAccumulatedData(seed = 1): CombinedAccumulatedData { 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(makePublicDataWrite), + range(STATE_TRANSITIONS_LENGTH, seed + 0x800).map(makePublicDataTransition), range(STATE_READS_LENGTH, seed + 0x900).map(makePublicDataRead), ); } diff --git a/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts b/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts index 6396d9f3037..76f69eb86ce 100644 --- a/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts +++ b/yarn-project/l1-contracts/src/ethereumjs-contracts/Rollup.ts @@ -35,7 +35,7 @@ export class Rollup extends Contract { } deploy(): TxSend { return super.deployBytecode( - '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610cd583390190565b608051610c5c61007960003960008181604b015261016b0152610c5c6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af3660046108bb565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b60408051600180825281830190925260009160208083019080368337019050509050818160008151811061014957610149610996565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b9085906004016109d0565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610a4a565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610a89565b6004888861027d565b92506102668460b8888861027d565b91506102728686610327565b905092959194509250565b6040805160b880825260e082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360b485850160248301376002816040516102dd9190610a9c565b602060405180830381855afa1580156102fa573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061031d9190610ab8565b9695505050505050565b6040805161018c8082526101c082019092526000919082908260208201818036833701905050905081602086016020830137600061036586866103cd565b90508061016c6020018301526002826040516103819190610a9c565b602060405180830381855afa15801561039e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103c19190610ab8565b93505050505b92915050565b60006103f360405180606001604052806000815260200160008152602001600081525090565b61016c84013560e01c80825261040a600482610ad1565b6020830152600061041c600480610af3565b836020015161042b9190610b06565b610436906020610b06565b8601610174013560e01c60408401525050602081015160009061045b90600290610ad1565b67ffffffffffffffff8111156104735761047361085c565b60405190808252806020026020018201604052801561049c578160200160208202803683370190505b50905060006104ad60046020610b06565b6104b8906002610b06565b905060006104c860046020610b06565b6104d3906002610b06565b6104dd9083610af3565b8451909150610170906000906104f4906020610b06565b61050090610174610af3565b9050600061050f600480610af3565b865161051c906002610b06565b6105269190610b06565b610531906020610b06565b61053d90610178610af3565b90506000876040015160206105529190610b06565b61055c9083610af3565b905060005b87518110156106cb57604080516102c08082526102e082019092526000916020820181803683370190505090506101008d860160208301376101008d8701828a016020013760408d85018289016020013760208d84018289016060013760148d8401602001828901608c013760208d840160340182890160a0013760148d840160540182890160cc01376105f760046002610b06565b610602906020610b06565b61060c9087610af3565b955061061a60046002610b06565b610625906020610b06565b61062f9086610af3565b945061063c604085610af3565b9350610649606884610af3565b925060028160405161065b9190610a9c565b602060405180830381855afa158015610678573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061069b9190610ab8565b8983815181106106ad576106ad610996565b602090810291909101015250806106c381610b1d565b915050610561565b506106d5876106e4565b9b9a5050505050505050505050565b6000805b82516106f5826002610c1a565b101561070d578061070581610b1d565b9150506106e8565b600061071a826002610c1a565b905080845260005b828110156108375760005b8281101561082457600286828151811061074957610749610996565b60200260200101518783600161075f9190610af3565b8151811061076f5761076f610996565b6020026020010151604051602001610791929190918252602082015260400190565b60408051601f19818403018152908290526107ab91610a9c565b602060405180830381855afa1580156107c8573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906107eb9190610ab8565b866107f7600284610ad1565b8151811061080757610807610996565b602090810291909101015261081d600282610af3565b905061072d565b508061082f81610b1d565b915050610722565b508360008151811061084b5761084b610996565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261088457600080fd5b50813567ffffffffffffffff81111561089c57600080fd5b6020830191508360208285010111156108b457600080fd5b9250929050565b6000806000604084860312156108d057600080fd5b833567ffffffffffffffff808211156108e857600080fd5b818601915086601f8301126108fc57600080fd5b81358181111561090e5761090e61085c565b604051601f8201601f19908116603f011681019083821181831017156109365761093661085c565b8160405282815289602084870101111561094f57600080fd5b82602086016020830137600060208483010152809750505050602086013591508082111561097c57600080fd5b5061098986828701610872565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b838110156109c75781810151838201526020016109af565b50506000910152565b604081526000835180604084015260206109f082606086018389016109ac565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610a3e5784518252938301936001929092019190830190610a1e565b50979650505050505050565b600060208284031215610a5c57600080fd5b81518015158114610a6c57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156103c7576103c7610a73565b60008251610aae8184602087016109ac565b9190910192915050565b600060208284031215610aca57600080fd5b5051919050565b600082610aee57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156103c7576103c7610a73565b80820281158282048414176103c7576103c7610a73565b600060018201610b2f57610b2f610a73565b5060010190565b600181815b80851115610b71578160001904821115610b5757610b57610a73565b80851615610b6457918102915b93841c9390800290610b3b565b509250929050565b600082610b88575060016103c7565b81610b95575060006103c7565b8160018114610bab5760028114610bb557610bd1565b60019150506103c7565b60ff841115610bc657610bc6610a73565b50506001821b6103c7565b5060208310610133831016604e8410600b8410161715610bf4575081810a6103c7565b610bfe8383610b36565b8060001904821115610c1257610c12610a73565b029392505050565b6000610a6c8383610b7956fea264697066735822122021b575358201f510292304dee8ff0dab00e9e7f61e6648f118612b5aa4418aca64736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea26469706673582212201cde3efc6f22394dee1d1854704dd42002ec8d4ff26954e8a2709bbb37c4b5ad64736f6c63430008120033', + '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d806102cf83390190565b60805161025d6100726000396000604b015261025d6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461014c565b6100b6565b005b604051823560e01c9081907f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf390600090a250505050565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261011557600080fd5b50813567ffffffffffffffff81111561012d57600080fd5b60208301915083602082850101111561014557600080fd5b9250929050565b60008060006040848603121561016157600080fd5b833567ffffffffffffffff8082111561017957600080fd5b818601915086601f83011261018d57600080fd5b81358181111561019f5761019f6100ed565b604051601f8201601f19908116603f011681019083821181831017156101c7576101c76100ed565b816040528281528960208487010111156101e057600080fd5b82602086016020830137600060208483010152809750505050602086013591508082111561020d57600080fd5b5061021a86828701610103565b949790965093945050505056fea264697066735822122063bf5f2228c31f0838547369bdc2b91bb35be32ee80fa5c2eb53cd176b575a3464736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033', ) as any; } } diff --git a/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts b/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts index 81beb2ae74b..859977a1294 100644 --- a/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts +++ b/yarn-project/l1-contracts/src/viem-contracts/Rollup.ts @@ -88,4 +88,4 @@ export const RollupAbi = [ ] as const; export const RollupBytecode = - '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d80610cd583390190565b608051610c5c61007960003960008181604b015261016b0152610c5c6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af3660046108bb565b6100b6565b005b6000806000806100c68686610237565b60005493975091955093509150158015906100e357508260005414155b1561011357600054604051632d2ef59f60e11b815260048101919091526024810184905260440160405180910390fd5b60408051600180825281830190925260009160208083019080368337019050509050818160008151811061014957610149610996565b6020908102919091010152604051633a94343960e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ea50d0e4906101a2908b9085906004016109d0565b602060405180830381865afa1580156101bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101e39190610a4a565b610200576040516309bde33960e01b815260040160405180910390fd5b600083815560405186917f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf391a25050505050505050565b813560e01c6000808061025761024e600186610a89565b6004888861027d565b92506102668460b8888861027d565b91506102728686610327565b905092959194509250565b6040805160b880825260e082019092526000918291906020820181803683370190505090508560181c60208201538560101c60218201538560081c602282015385602382015360b485850160248301376002816040516102dd9190610a9c565b602060405180830381855afa1580156102fa573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061031d9190610ab8565b9695505050505050565b6040805161018c8082526101c082019092526000919082908260208201818036833701905050905081602086016020830137600061036586866103cd565b90508061016c6020018301526002826040516103819190610a9c565b602060405180830381855afa15801561039e573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906103c19190610ab8565b93505050505b92915050565b60006103f360405180606001604052806000815260200160008152602001600081525090565b61016c84013560e01c80825261040a600482610ad1565b6020830152600061041c600480610af3565b836020015161042b9190610b06565b610436906020610b06565b8601610174013560e01c60408401525050602081015160009061045b90600290610ad1565b67ffffffffffffffff8111156104735761047361085c565b60405190808252806020026020018201604052801561049c578160200160208202803683370190505b50905060006104ad60046020610b06565b6104b8906002610b06565b905060006104c860046020610b06565b6104d3906002610b06565b6104dd9083610af3565b8451909150610170906000906104f4906020610b06565b61050090610174610af3565b9050600061050f600480610af3565b865161051c906002610b06565b6105269190610b06565b610531906020610b06565b61053d90610178610af3565b90506000876040015160206105529190610b06565b61055c9083610af3565b905060005b87518110156106cb57604080516102c08082526102e082019092526000916020820181803683370190505090506101008d860160208301376101008d8701828a016020013760408d85018289016020013760208d84018289016060013760148d8401602001828901608c013760208d840160340182890160a0013760148d840160540182890160cc01376105f760046002610b06565b610602906020610b06565b61060c9087610af3565b955061061a60046002610b06565b610625906020610b06565b61062f9086610af3565b945061063c604085610af3565b9350610649606884610af3565b925060028160405161065b9190610a9c565b602060405180830381855afa158015610678573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019061069b9190610ab8565b8983815181106106ad576106ad610996565b602090810291909101015250806106c381610b1d565b915050610561565b506106d5876106e4565b9b9a5050505050505050505050565b6000805b82516106f5826002610c1a565b101561070d578061070581610b1d565b9150506106e8565b600061071a826002610c1a565b905080845260005b828110156108375760005b8281101561082457600286828151811061074957610749610996565b60200260200101518783600161075f9190610af3565b8151811061076f5761076f610996565b6020026020010151604051602001610791929190918252602082015260400190565b60408051601f19818403018152908290526107ab91610a9c565b602060405180830381855afa1580156107c8573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906107eb9190610ab8565b866107f7600284610ad1565b8151811061080757610807610996565b602090810291909101015261081d600282610af3565b905061072d565b508061082f81610b1d565b915050610722565b508360008151811061084b5761084b610996565b602002602001015192505050919050565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261088457600080fd5b50813567ffffffffffffffff81111561089c57600080fd5b6020830191508360208285010111156108b457600080fd5b9250929050565b6000806000604084860312156108d057600080fd5b833567ffffffffffffffff808211156108e857600080fd5b818601915086601f8301126108fc57600080fd5b81358181111561090e5761090e61085c565b604051601f8201601f19908116603f011681019083821181831017156109365761093661085c565b8160405282815289602084870101111561094f57600080fd5b82602086016020830137600060208483010152809750505050602086013591508082111561097c57600080fd5b5061098986828701610872565b9497909650939450505050565b634e487b7160e01b600052603260045260246000fd5b60005b838110156109c75781810151838201526020016109af565b50506000910152565b604081526000835180604084015260206109f082606086018389016109ac565b6060601f19601f93909301929092168401848103830185830152855192810183905285820192600091608001905b80831015610a3e5784518252938301936001929092019190830190610a1e565b50979650505050505050565b600060208284031215610a5c57600080fd5b81518015158114610a6c57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b818103818111156103c7576103c7610a73565b60008251610aae8184602087016109ac565b9190910192915050565b600060208284031215610aca57600080fd5b5051919050565b600082610aee57634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156103c7576103c7610a73565b80820281158282048414176103c7576103c7610a73565b600060018201610b2f57610b2f610a73565b5060010190565b600181815b80851115610b71578160001904821115610b5757610b57610a73565b80851615610b6457918102915b93841c9390800290610b3b565b509250929050565b600082610b88575060016103c7565b81610b95575060006103c7565b8160018114610bab5760028114610bb557610bd1565b60019150506103c7565b60ff841115610bc657610bc6610a73565b50506001821b6103c7565b5060208310610133831016604e8410600b8410161715610bf4575081810a6103c7565b610bfe8383610b36565b8060001904821115610c1257610c12610a73565b029392505050565b6000610a6c8383610b7956fea264697066735822122021b575358201f510292304dee8ff0dab00e9e7f61e6648f118612b5aa4418aca64736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea26469706673582212201cde3efc6f22394dee1d1854704dd42002ec8d4ff26954e8a2709bbb37c4b5ad64736f6c63430008120033'; + '0x60a060405234801561001057600080fd5b5060405161001d9061004b565b604051809103906000f080158015610039573d6000803e3d6000fd5b506001600160a01b0316608052610058565b61019d806102cf83390190565b60805161025d6100726000396000604b015261025d6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806308c84e70146100465780631ab9c6031461008a5780637c39d130146100a1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009360005481565b604051908152602001610081565b6100b46100af36600461014c565b6100b6565b005b604051823560e01c9081907f655779015b9b95c7fd18f01ea4619ab4c31289bbe134ba85c5b20bcdeb1dabf390600090a250505050565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261011557600080fd5b50813567ffffffffffffffff81111561012d57600080fd5b60208301915083602082850101111561014557600080fd5b9250929050565b60008060006040848603121561016157600080fd5b833567ffffffffffffffff8082111561017957600080fd5b818601915086601f83011261018d57600080fd5b81358181111561019f5761019f6100ed565b604051601f8201601f19908116603f011681019083821181831017156101c7576101c76100ed565b816040528281528960208487010111156101e057600080fd5b82602086016020830137600060208483010152809750505050602086013591508082111561020d57600080fd5b5061021a86828701610103565b949790965093945050505056fea264697066735822122063bf5f2228c31f0838547369bdc2b91bb35be32ee80fa5c2eb53cd176b575a3464736f6c63430008120033608060405234801561001057600080fd5b5061017d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063937f6a101461003b578063ea50d0e41461005a575b600080fd5b60405168496d2061206d6f636b60b81b81526020015b60405180910390f35b610072610068366004610082565b6001949350505050565b6040519015158152602001610051565b6000806000806040858703121561009857600080fd5b843567ffffffffffffffff808211156100b057600080fd5b818701915087601f8301126100c457600080fd5b8135818111156100d357600080fd5b8860208285010111156100e557600080fd5b60209283019650945090860135908082111561010057600080fd5b818701915087601f83011261011457600080fd5b81358181111561012357600080fd5b8860208260051b850101111561013857600080fd5b9598949750506020019450505056fea264697066735822122079065ece8684a52b261c9ab9f34e06d3a4e53f346b36185587fd3fe29e5c9cc764736f6c63430008120033'; 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 f55806304c8..1e6d7d7980d 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 @@ -5,7 +5,7 @@ import { CircuitsWasm, Fr, PublicDataRead, - PublicDataWrite, + PublicDataTransition, RootRollupPublicInputs, UInt8Vector, } from '@aztec/circuits.js'; @@ -19,7 +19,7 @@ import { makeRootRollupPublicInputs, } from '@aztec/circuits.js/factories'; import { toBufferBE } from '@aztec/foundation'; -import { Tx } from '@aztec/types'; +import { PublicDataWrite, Tx } from '@aztec/types'; import { MerkleTreeId, MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; import { MockProxy, mock } from 'jest-mock-extended'; import { default as levelup } from 'levelup'; @@ -219,7 +219,7 @@ describe('sequencer/circuit_block_builder', () => { const tx = await makeProcessedTx(publicTx, makeKernelPublicInputs(seed), makeProof()); await setTxHistoricTreeRoots(tx); tx.data.end.stateReads[0] = new PublicDataRead(fr(1), fr(0)); - tx.data.end.stateTransitions[0] = new PublicDataWrite(fr(2), fr(0), fr(12)); + tx.data.end.stateTransitions[0] = new PublicDataTransition(fr(2), fr(0), fr(12)); return tx; }; @@ -258,18 +258,15 @@ describe('sequencer/circuit_block_builder', () => { it('builds an L2 block with private and public txs', async () => { const txs = await Promise.all([ - makeContractDeployProcessedTx(), makePublicCallProcessedTx(), + makeContractDeployProcessedTx(), makeEmptyProcessedTx(), makeEmptyProcessedTx(), ]); const [l2Block] = await builder.buildL2Block(blockNumber, txs); expect(l2Block.number).toEqual(blockNumber); - - // TODO: Check that l2 block got the new state transitions once we merge - // https://github.com/AztecProtocol/aztec3-packages/pull/360 - + expect(l2Block.newPublicDataWrites[0]).toEqual(new PublicDataWrite(fr(2), fr(12))); await updateExpectedTreesFromTxs(txs); }); 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 953bca2abb9..c26e37d4b03 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 @@ -24,7 +24,7 @@ import { import { computeContractLeaf } from '@aztec/circuits.js/abis'; import { Fr, createDebugLogger, toBigIntBE, toBufferBE } from '@aztec/foundation'; import { LeafData, SiblingPath } from '@aztec/merkle-tree'; -import { ContractData, L2Block } from '@aztec/types'; +import { ContractData, L2Block, PublicDataWrite } from '@aztec/types'; import { MerkleTreeId, MerkleTreeOperations } from '@aztec/world-state'; import chunk from 'lodash.chunk'; import flatMap from 'lodash.flatmap'; @@ -87,6 +87,7 @@ export class CircuitBlockBuilder implements BlockBuilder { startPrivateDataTreeSnapshot, startNullifierTreeSnapshot, startContractTreeSnapshot, + startPublicDataTreeSnapshot, startTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, ] = await Promise.all( @@ -94,6 +95,7 @@ export class CircuitBlockBuilder implements BlockBuilder { MerkleTreeId.PRIVATE_DATA_TREE, MerkleTreeId.NULLIFIER_TREE, MerkleTreeId.CONTRACT_TREE, + MerkleTreeId.PUBLIC_DATA_TREE, MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, MerkleTreeId.CONTRACT_TREE_ROOTS_TREE, ].map(tree => this.getTreeSnapshot(tree)), @@ -106,6 +108,7 @@ export class CircuitBlockBuilder implements BlockBuilder { endPrivateDataTreeSnapshot, endNullifierTreeSnapshot, endContractTreeSnapshot, + endPublicDataTreeSnapshot, endTreeOfHistoricPrivateDataTreeRootsSnapshot, endTreeOfHistoricContractTreeRootsSnapshot, } = circuitsOutput; @@ -118,6 +121,9 @@ export class CircuitBlockBuilder implements BlockBuilder { const newContractData = flatMap(txs, tx => tx.data.end.newContracts).map( n => new ContractData(n.contractAddress, n.portalContractAddress), ); + const newPublicDataWrites = flatMap(txs, tx => + tx.data.end.stateTransitions.map(t => new PublicDataWrite(t.leafIndex, t.newValue)), + ); const l2Block = L2Block.fromFields({ number: blockNumber, @@ -127,6 +133,8 @@ export class CircuitBlockBuilder implements BlockBuilder { endNullifierTreeSnapshot, startContractTreeSnapshot, endContractTreeSnapshot, + startPublicDataTreeRoot: startPublicDataTreeSnapshot.root, + endPublicDataTreeRoot: endPublicDataTreeSnapshot.root, startTreeOfHistoricPrivateDataTreeRootsSnapshot, endTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, @@ -135,6 +143,7 @@ export class CircuitBlockBuilder implements BlockBuilder { newNullifiers, newContracts, newContractData, + newPublicDataWrites, }); return [l2Block, proof]; diff --git a/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts index 39d805a764c..f103d029a3e 100644 --- a/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/standalone_block_builder.ts @@ -9,7 +9,7 @@ import { } from '@aztec/circuits.js'; import { computeContractLeaf } from '@aztec/circuits.js/abis'; import { AztecAddress, Fr, createDebugLogger } from '@aztec/foundation'; -import { ContractData, L2Block } from '@aztec/types'; +import { ContractData, L2Block, PublicDataWrite } from '@aztec/types'; import { MerkleTreeId, MerkleTreeOperations } from '@aztec/world-state'; import { Proof } from '../prover/index.js'; import { ProcessedTx } from '../sequencer/processed_tx.js'; @@ -35,6 +35,7 @@ export class StandaloneBlockBuilder implements BlockBuilder { const startPrivateDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); const startNullifierTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); const startContractTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + const startPublicDataTreeRoot = Fr.fromBuffer((await this.db.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE)).root); const startTreeOfHistoricPrivateDataTreeRootsSnapshot = await this.getTreeSnapshot( MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, ); @@ -51,6 +52,7 @@ export class StandaloneBlockBuilder implements BlockBuilder { const endPrivateDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PRIVATE_DATA_TREE); const endNullifierTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.NULLIFIER_TREE); const endContractTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); + const endPublicDataTreeRoot = Fr.fromBuffer((await this.db.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE)).root); const endTreeOfHistoricPrivateDataTreeRootsSnapshot = await this.getTreeSnapshot( MerkleTreeId.PRIVATE_DATA_TREE_ROOTS_TREE, ); @@ -66,6 +68,8 @@ export class StandaloneBlockBuilder implements BlockBuilder { endNullifierTreeSnapshot, startContractTreeSnapshot, endContractTreeSnapshot, + startPublicDataTreeRoot, + endPublicDataTreeRoot, startTreeOfHistoricPrivateDataTreeRootsSnapshot, endTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, @@ -74,6 +78,9 @@ export class StandaloneBlockBuilder implements BlockBuilder { newNullifiers: this.nullifierTreeLeaves.map(b => Fr.fromBuffer(b)), newContracts: this.contractTreeLeaves.map(b => Fr.fromBuffer(b)), newContractData: txs.flatMap(tx => tx.data.end.newContracts.map(mapContractData)), + newPublicDataWrites: txs.flatMap(tx => + tx.data.end.stateTransitions.map(t => new PublicDataWrite(t.leafIndex, t.newValue)), + ), }); return [l2Block, makeEmptyProof()]; } diff --git a/yarn-project/types/package.json b/yarn-project/types/package.json index bb5c08f9e7a..9585cb6fb34 100644 --- a/yarn-project/types/package.json +++ b/yarn-project/types/package.json @@ -39,12 +39,14 @@ "@aztec/circuits.js": "workspace:^", "@aztec/foundation": "workspace:^", "@aztec/l1-contracts": "workspace:^", + "lodash.times": "^4.3.2", "tslib": "^2.5.0" }, "devDependencies": { "@jest/globals": "^29.5.0", "@rushstack/eslint-patch": "^1.1.4", "@types/jest": "^29.5.0", + "@types/lodash.times": "^4.3.7", "@types/node": "^18.7.23", "jest": "^29.5.0", "jest-mock-extended": "^3.0.3", diff --git a/yarn-project/types/src/create_tx_hash.ts b/yarn-project/types/src/create_tx_hash.ts index aec641596ed..ded181c1546 100644 --- a/yarn-project/types/src/create_tx_hash.ts +++ b/yarn-project/types/src/create_tx_hash.ts @@ -13,6 +13,8 @@ interface TxData { * @returns A hash of the tx data that identifies the tx. */ export function createTxHash({ newCommitments, newNullifiers, newContracts }: TxData) { + // TODO: This will not calculate the correct hash when public function calls are involved + // See https://github.com/AztecProtocol/aztec3-packages/issues/361 const data = Buffer.concat( [ newCommitments.map(x => x.toBuffer()), diff --git a/yarn-project/types/src/index.ts b/yarn-project/types/src/index.ts index a7096571fb4..7266fac35aa 100644 --- a/yarn-project/types/src/index.ts +++ b/yarn-project/types/src/index.ts @@ -5,5 +5,6 @@ export * from './contract_data.js'; export * from './l2_block.js'; export * from './l2_block_context.js'; export * from './l2_block_source.js'; +export * from './public_data_write.js'; export * from './unverified_data.js'; export * from './unverified_data_source.js'; diff --git a/yarn-project/types/src/l2_block.ts b/yarn-project/types/src/l2_block.ts index ab8a3f0284f..7d65c2acae1 100644 --- a/yarn-project/types/src/l2_block.ts +++ b/yarn-project/types/src/l2_block.ts @@ -3,12 +3,15 @@ import { KERNEL_NEW_COMMITMENTS_LENGTH, KERNEL_NEW_CONTRACTS_LENGTH, KERNEL_NEW_NULLIFIERS_LENGTH, + STATE_TRANSITIONS_LENGTH, } from '@aztec/circuits.js'; import { makeAppendOnlyTreeSnapshot } from '@aztec/circuits.js/factories'; import { BufferReader, serializeToBuffer } from '@aztec/circuits.js/utils'; import { Fr } from '@aztec/foundation'; +import times from 'lodash.times'; import { ContractData } from './contract_data.js'; import { L2Tx } from './l2_tx.js'; +import { PublicDataWrite } from './public_data_write.js'; /** * The data that makes up the rollup proof, with encoder decoder functions. @@ -24,13 +27,16 @@ export class L2Block { * @param startContractTreeSnapshot - The tree snapshot of the contract tree at the start of the rollup. * @param startTreeOfHistoricPrivateDataTreeRootsSnapshot - The tree snapshot of the historic private data tree roots at the start of the rollup. * @param startTreeOfHistoricContractTreeRootsSnapshot - The tree snapshot of the historic contract tree roots at the start of the rollup. + * @param startPublicDataTreeRoot - The tree root of the public data tree at the start of the rollup. * @param endPrivateDataTreeSnapshot - The tree snapshot of the private data tree at the end of the rollup. * @param endNullifierTreeSnapshot - The tree snapshot of the nullifier tree at the end of the rollup. * @param endContractTreeSnapshot - The tree snapshot of the contract tree at the end of the rollup. * @param endTreeOfHistoricPrivateDataTreeRootsSnapshot - The tree snapshot of the historic private data tree roots at the end of the rollup. * @param endTreeOfHistoricContractTreeRootsSnapshot - The tree snapshot of the historic contract tree roots at the end of the rollup. + * @param endPublicDataTreeRoot - The tree root of the public data tree at the end of the rollup. * @param newCommitments - The commitments to be inserted into the private data tree. * @param newNullifiers - The nullifiers to be inserted into the nullifier tree. + * @param newPublicDataWrites - The public data writes to be inserted into the public data tree. * @param newContracts - The contracts leafs to be inserted into the contract tree. * @param newContractData - The aztec_address and eth_address for the deployed contract and its portal contract. */ @@ -41,48 +47,47 @@ export class L2Block { public startContractTreeSnapshot: AppendOnlyTreeSnapshot, public startTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot, public startTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public startPublicDataTreeRoot: Fr, public endPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot, public endNullifierTreeSnapshot: AppendOnlyTreeSnapshot, public endContractTreeSnapshot: AppendOnlyTreeSnapshot, public endTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot, public endTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public endPublicDataTreeRoot: Fr, public newCommitments: Fr[], public newNullifiers: Fr[], + public newPublicDataWrites: PublicDataWrite[], public newContracts: Fr[], public newContractData: ContractData[], ) {} static random(l2BlockNum: number, txsPerBlock = 1) { - const newNullifiers = Array(KERNEL_NEW_NULLIFIERS_LENGTH * txsPerBlock) - .fill(0) - .map(() => Fr.random()); - const newCommitments = Array(KERNEL_NEW_COMMITMENTS_LENGTH * txsPerBlock) - .fill(0) - .map(() => Fr.random()); - const newContracts = Array(KERNEL_NEW_CONTRACTS_LENGTH * txsPerBlock) - .fill(0) - .map(() => Fr.random()); - const newContractsData = Array(KERNEL_NEW_CONTRACTS_LENGTH * txsPerBlock) - .fill(0) - .map(() => ContractData.random()); + const newNullifiers = times(KERNEL_NEW_NULLIFIERS_LENGTH * txsPerBlock, Fr.random); + const newCommitments = times(KERNEL_NEW_COMMITMENTS_LENGTH * txsPerBlock, Fr.random); + const newContracts = times(KERNEL_NEW_CONTRACTS_LENGTH * txsPerBlock, Fr.random); + const newContractData = times(KERNEL_NEW_CONTRACTS_LENGTH * txsPerBlock, ContractData.random); + const newPublicDataWrites = times(STATE_TRANSITIONS_LENGTH * txsPerBlock, PublicDataWrite.random); - return new L2Block( - l2BlockNum, - makeAppendOnlyTreeSnapshot(0), - makeAppendOnlyTreeSnapshot(0), - makeAppendOnlyTreeSnapshot(0), - makeAppendOnlyTreeSnapshot(0), - makeAppendOnlyTreeSnapshot(0), - makeAppendOnlyTreeSnapshot(newCommitments.length), - makeAppendOnlyTreeSnapshot(newNullifiers.length), - makeAppendOnlyTreeSnapshot(newContracts.length), - makeAppendOnlyTreeSnapshot(1), - makeAppendOnlyTreeSnapshot(1), + return L2Block.fromFields({ + number: l2BlockNum, + startPrivateDataTreeSnapshot: makeAppendOnlyTreeSnapshot(0), + startNullifierTreeSnapshot: makeAppendOnlyTreeSnapshot(0), + startContractTreeSnapshot: makeAppendOnlyTreeSnapshot(0), + startPublicDataTreeRoot: Fr.random(), + startTreeOfHistoricPrivateDataTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(0), + startTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(0), + endPrivateDataTreeSnapshot: makeAppendOnlyTreeSnapshot(newCommitments.length), + endNullifierTreeSnapshot: makeAppendOnlyTreeSnapshot(newNullifiers.length), + endContractTreeSnapshot: makeAppendOnlyTreeSnapshot(newContracts.length), + endPublicDataTreeRoot: Fr.random(), + endTreeOfHistoricPrivateDataTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(1), + endTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(1), newCommitments, newNullifiers, newContracts, - newContractsData, - ); + newContractData, + newPublicDataWrites, + }); } /** @@ -97,13 +102,16 @@ export class L2Block { startContractTreeSnapshot: AppendOnlyTreeSnapshot; startTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot; startTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot; + startPublicDataTreeRoot: Fr; endPrivateDataTreeSnapshot: AppendOnlyTreeSnapshot; endNullifierTreeSnapshot: AppendOnlyTreeSnapshot; endContractTreeSnapshot: AppendOnlyTreeSnapshot; endTreeOfHistoricPrivateDataTreeRootsSnapshot: AppendOnlyTreeSnapshot; endTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot; + endPublicDataTreeRoot: Fr; newCommitments: Fr[]; newNullifiers: Fr[]; + newPublicDataWrites: PublicDataWrite[]; newContracts: Fr[]; newContractData: ContractData[]; }) { @@ -114,13 +122,16 @@ export class L2Block { fields.startContractTreeSnapshot, fields.startTreeOfHistoricPrivateDataTreeRootsSnapshot, fields.startTreeOfHistoricContractTreeRootsSnapshot, + fields.startPublicDataTreeRoot, fields.endPrivateDataTreeSnapshot, fields.endNullifierTreeSnapshot, fields.endContractTreeSnapshot, fields.endTreeOfHistoricPrivateDataTreeRootsSnapshot, fields.endTreeOfHistoricContractTreeRootsSnapshot, + fields.endPublicDataTreeRoot, fields.newCommitments, fields.newNullifiers, + fields.newPublicDataWrites, fields.newContracts, fields.newContractData, ); @@ -138,15 +149,19 @@ export class L2Block { this.startContractTreeSnapshot, this.startTreeOfHistoricPrivateDataTreeRootsSnapshot, this.startTreeOfHistoricContractTreeRootsSnapshot, + this.startPublicDataTreeRoot, this.endPrivateDataTreeSnapshot, this.endNullifierTreeSnapshot, this.endContractTreeSnapshot, this.endTreeOfHistoricPrivateDataTreeRootsSnapshot, this.endTreeOfHistoricContractTreeRootsSnapshot, + this.endPublicDataTreeRoot, this.newCommitments.length, this.newCommitments, this.newNullifiers.length, this.newNullifiers, + this.newPublicDataWrites.length, + this.newPublicDataWrites, this.newContracts.length, this.newContracts, this.newContractData, @@ -174,33 +189,39 @@ export class L2Block { const startContractTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const startTreeOfHistoricPrivateDataTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const startTreeOfHistoricContractTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); + const startPublicDataTreeRoot = reader.readObject(Fr); const endPrivateDataTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endNullifierTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endContractTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endTreeOfHistoricPrivateDataTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endTreeOfHistoricContractTreeRootsSnapshot = reader.readObject(AppendOnlyTreeSnapshot); + const endPublicDataTreeRoot = reader.readObject(Fr); const newCommitments = reader.readVector(Fr); const newNullifiers = reader.readVector(Fr); + const newPublicDataWrites = reader.readVector(PublicDataWrite); const newContracts = reader.readVector(Fr); const newContractData = reader.readArray(newContracts.length, ContractData); - return new L2Block( + return L2Block.fromFields({ number, startPrivateDataTreeSnapshot, startNullifierTreeSnapshot, startContractTreeSnapshot, startTreeOfHistoricPrivateDataTreeRootsSnapshot, startTreeOfHistoricContractTreeRootsSnapshot, + startPublicDataTreeRoot, endPrivateDataTreeSnapshot, endNullifierTreeSnapshot, endContractTreeSnapshot, endTreeOfHistoricPrivateDataTreeRootsSnapshot, endTreeOfHistoricContractTreeRootsSnapshot, + endPublicDataTreeRoot, newCommitments, newNullifiers, + newPublicDataWrites, newContracts, newContractData, - ); + }); } /** @@ -222,6 +243,10 @@ export class L2Block { KERNEL_NEW_NULLIFIERS_LENGTH * txIndex, KERNEL_NEW_NULLIFIERS_LENGTH * (txIndex + 1), ); + const newPublicDataWrites = this.newPublicDataWrites.slice( + STATE_TRANSITIONS_LENGTH * txIndex, + STATE_TRANSITIONS_LENGTH * (txIndex + 1), + ); const newContracts = this.newContracts.slice( KERNEL_NEW_CONTRACTS_LENGTH * txIndex, KERNEL_NEW_CONTRACTS_LENGTH * (txIndex + 1), @@ -230,7 +255,8 @@ export class L2Block { KERNEL_NEW_CONTRACTS_LENGTH * txIndex, KERNEL_NEW_CONTRACTS_LENGTH * (txIndex + 1), ); - return new L2Tx(newCommitments, newNullifiers, newContracts, newContractData); + + return new L2Tx(newCommitments, newNullifiers, newPublicDataWrites, newContracts, newContractData); } /** @@ -239,22 +265,18 @@ export class L2Block { * @returns A human-friendly string representation of the l2Block. */ inspect(maxBufferSize = 4): string { + const inspectHex = (fr: { toBuffer: () => Buffer }): string => + `0x${fr.toBuffer().subarray(0, maxBufferSize).toString('hex')}`; + const inspectArray = (arr: T[], inspector: (t: T) => string) => '[' + arr.map(inspector).join(', ') + ']'; + const inspectTreeSnapshot = (s: AppendOnlyTreeSnapshot): string => - `(${s.nextAvailableLeafIndex}, 0x${s.root.toBuffer().subarray(0, maxBufferSize).toString('hex')})`; - const inspectFrArray = (arr: Fr[]): string => - '[' + arr.map(fr => '0x' + fr.toBuffer().subarray(0, maxBufferSize).toString('hex')).join(', ') + ']'; + `(${s.nextAvailableLeafIndex}, ${inspectHex(s.root)})`; + const inspectFrArray = (arr: Fr[]): string => inspectArray(arr, inspectHex); const inspectContractDataArray = (arr: ContractData[]): string => - '[' + - arr - .map( - cd => - `(0x${cd.contractAddress - .toBuffer() - .subarray(0, maxBufferSize) - .toString('hex')}, 0x${cd.portalContractAddress.toBuffer().subarray(0, maxBufferSize).toString('hex')})`, - ) - .join(', ') + - ']'; + inspectArray(arr, cd => `(${inspectHex(cd.contractAddress)}, ${inspectHex(cd.portalContractAddress)})`); + const inspectPublicDataWriteArray = (arr: PublicDataWrite[]): string => + inspectArray(arr, pdw => `(${inspectHex(pdw.leafIndex)}, ${inspectHex(pdw.newValue)})`); + return [ `L2Block`, `number: ${this.number}`, @@ -267,6 +289,7 @@ export class L2Block { `startTreeOfHistoricContractTreeRootsSnapshot: ${inspectTreeSnapshot( this.startTreeOfHistoricContractTreeRootsSnapshot, )}`, + `startPublicDataTreeRoot: ${this.startPublicDataTreeRoot.toString()}`, `endPrivateDataTreeSnapshot: ${inspectTreeSnapshot(this.endPrivateDataTreeSnapshot)}`, `endNullifierTreeSnapshot: ${inspectTreeSnapshot(this.endNullifierTreeSnapshot)}`, `endContractTreeSnapshot: ${inspectTreeSnapshot(this.endContractTreeSnapshot)}`, @@ -276,8 +299,10 @@ export class L2Block { `endTreeOfHistoricContractTreeRootsSnapshot: ${inspectTreeSnapshot( this.endTreeOfHistoricContractTreeRootsSnapshot, )}`, + `endPublicDataTreeRoot: ${this.endPublicDataTreeRoot.toString()}`, `newCommitments: ${inspectFrArray(this.newCommitments)}`, `newNullifiers: ${inspectFrArray(this.newNullifiers)}`, + `newPublicDataWrite: ${inspectPublicDataWriteArray(this.newPublicDataWrites)}`, `newContracts: ${inspectFrArray(this.newContracts)}`, `newContractData: ${inspectContractDataArray(this.newContractData)}`, ].join('\n'); diff --git a/yarn-project/types/src/l2_tx.ts b/yarn-project/types/src/l2_tx.ts index fed27ef3cdd..7cc215976ef 100644 --- a/yarn-project/types/src/l2_tx.ts +++ b/yarn-project/types/src/l2_tx.ts @@ -2,11 +2,13 @@ import { Fr } from '@aztec/foundation'; import { ContractData } from './contract_data.js'; import { TxHash } from './tx_hash.js'; import { createTxHash } from './create_tx_hash.js'; +import { PublicDataWrite } from './public_data_write.js'; export class L2Tx { constructor( public newCommitments: Fr[], public newNullifiers: Fr[], + public newPublicDataWrites: PublicDataWrite[], public newContracts: Fr[], public newContractData: ContractData[], private hash?: TxHash, diff --git a/yarn-project/types/src/public_data_write.ts b/yarn-project/types/src/public_data_write.ts new file mode 100644 index 00000000000..547a9ebd52d --- /dev/null +++ b/yarn-project/types/src/public_data_write.ts @@ -0,0 +1,30 @@ +import { serializeToBuffer } from '@aztec/circuits.js/utils'; +import { BufferReader, Fr } from '@aztec/foundation'; + +/** + * Write operations on the public state tree. + */ +export class PublicDataWrite { + constructor(public readonly leafIndex: Fr, public readonly newValue: Fr) {} + + static from(args: { leafIndex: Fr; newValue: Fr }) { + return new PublicDataWrite(args.leafIndex, args.newValue); + } + + toBuffer() { + return serializeToBuffer(this.leafIndex, this.newValue); + } + + static fromBuffer(buffer: Buffer | BufferReader) { + const reader = BufferReader.asReader(buffer); + return new PublicDataWrite(reader.readFr(), reader.readFr()); + } + + static empty() { + return new PublicDataWrite(Fr.ZERO, Fr.ZERO); + } + + static random() { + return new PublicDataWrite(Fr.random(), Fr.random()); + } +} diff --git a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts index 882e0315add..373d2c86bfa 100644 --- a/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts +++ b/yarn-project/world-state/src/synchroniser/server_world_state_synchroniser.test.ts @@ -1,5 +1,5 @@ import { ServerWorldStateSynchroniser } from './server_world_state_synchroniser.js'; -import { L2BlockSource, L2Block, ContractData } from '@aztec/types'; +import { L2BlockSource, L2Block, ContractData, PublicDataWrite } from '@aztec/types'; import { WorldStateRunningState } from './world_state_synchroniser.js'; import { INITIAL_LEAF, Pedersen, SiblingPath } from '@aztec/merkle-tree'; import { sleep } from '@aztec/foundation'; @@ -34,23 +34,26 @@ const getMockContractData = () => { }; const getMockBlock = (blockNumber: number, newContractsCommitments?: Buffer[]) => { - const block = new L2Block( - blockNumber, - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - getMockTreeSnapshot(), - [Fr.random()], - [Fr.random()], - newContractsCommitments?.map(x => Fr.fromBuffer(x)) ?? [Fr.random()], - [getMockContractData()], - ); + const block = L2Block.fromFields({ + number: blockNumber, + startPrivateDataTreeSnapshot: getMockTreeSnapshot(), + startNullifierTreeSnapshot: getMockTreeSnapshot(), + startContractTreeSnapshot: getMockTreeSnapshot(), + startTreeOfHistoricPrivateDataTreeRootsSnapshot: getMockTreeSnapshot(), + startTreeOfHistoricContractTreeRootsSnapshot: getMockTreeSnapshot(), + startPublicDataTreeRoot: Fr.random(), + endPrivateDataTreeSnapshot: getMockTreeSnapshot(), + endNullifierTreeSnapshot: getMockTreeSnapshot(), + endContractTreeSnapshot: getMockTreeSnapshot(), + endTreeOfHistoricPrivateDataTreeRootsSnapshot: getMockTreeSnapshot(), + endTreeOfHistoricContractTreeRootsSnapshot: getMockTreeSnapshot(), + endPublicDataTreeRoot: Fr.random(), + newCommitments: [Fr.random()], + newNullifiers: [Fr.random()], + newContracts: newContractsCommitments?.map(x => Fr.fromBuffer(x)) ?? [Fr.random()], + newContractData: [getMockContractData()], + newPublicDataWrites: [PublicDataWrite.random()], + }); return block; }; diff --git a/yarn-project/yarn.lock b/yarn-project/yarn.lock index ecd3184de72..076014e929a 100644 --- a/yarn-project/yarn.lock +++ b/yarn-project/yarn.lock @@ -553,9 +553,11 @@ __metadata: "@jest/globals": ^29.5.0 "@rushstack/eslint-patch": ^1.1.4 "@types/jest": ^29.5.0 + "@types/lodash.times": ^4.3.7 "@types/node": ^18.7.23 jest: ^29.5.0 jest-mock-extended: ^3.0.3 + lodash.times: ^4.3.2 ts-jest: ^29.1.0 ts-node: ^10.9.1 tslib: ^2.5.0