From 44bf30b0af5a546e375d068790e9fa7e94d6ca52 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 29 Nov 2023 18:22:53 -0300 Subject: [PATCH 01/37] docs: Add transaction section to yellow paper (#3418) Fixes #3089 Adds TODOs for #3417 --- .../kernel/combined_accumulated_data.ts | 1 + .../src/structs/public_call_request.ts | 2 + .../circuits.js/src/structs/tx_context.ts | 1 + yarn-project/types/src/tx/tx.ts | 1 + .../types/src/tx_execution_request.ts | 1 + yellow-paper/docs/transactions/index.md | 15 ++++ .../docs/transactions/local-execution.md | 31 +++++++ .../docs/transactions/public-execution.md | 16 ++++ yellow-paper/docs/transactions/tx-object.md | 85 +++++++++++++++++++ yellow-paper/docs/transactions/validity.md | 18 ++++ 10 files changed, 171 insertions(+) create mode 100644 yellow-paper/docs/transactions/index.md create mode 100644 yellow-paper/docs/transactions/local-execution.md create mode 100644 yellow-paper/docs/transactions/public-execution.md create mode 100644 yellow-paper/docs/transactions/tx-object.md create mode 100644 yellow-paper/docs/transactions/validity.md 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 4f84c10ff550..f77a3d910c44 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 @@ -491,6 +491,7 @@ export class FinalAccumulatedData { public nullifiedCommitments: Tuple, /** * Current private call stack. + * TODO(#3417): Given this field must empty, should we just remove it? */ public privateCallStack: Tuple, /** diff --git a/yarn-project/circuits.js/src/structs/public_call_request.ts b/yarn-project/circuits.js/src/structs/public_call_request.ts index b8cb2cacd501..70556f079ebb 100644 --- a/yarn-project/circuits.js/src/structs/public_call_request.ts +++ b/yarn-project/circuits.js/src/structs/public_call_request.ts @@ -27,10 +27,12 @@ export class PublicCallRequest { public contractAddress: AztecAddress, /** * Data identifying the function being called. + * TODO(#3417): Remove this since the only useful data is the function selector, which is already part of the call context. */ public functionData: FunctionData, /** * Context of the public call. + * TODO(#3417): Check if all fields of CallContext are actually needed. */ public callContext: CallContext, /** diff --git a/yarn-project/circuits.js/src/structs/tx_context.ts b/yarn-project/circuits.js/src/structs/tx_context.ts index 644c88126900..adab6ff8031a 100644 --- a/yarn-project/circuits.js/src/structs/tx_context.ts +++ b/yarn-project/circuits.js/src/structs/tx_context.ts @@ -85,6 +85,7 @@ export class TxContext { constructor( /** * Whether this is a fee paying tx. If not other tx in a bundle will pay the fee. + * TODO(#3417): Remove fee and rebate payment fields. */ public isFeePaymentTx: boolean, /** diff --git a/yarn-project/types/src/tx/tx.ts b/yarn-project/types/src/tx/tx.ts index 6d49a50912ae..381d0a7f7829 100644 --- a/yarn-project/types/src/tx/tx.ts +++ b/yarn-project/types/src/tx/tx.ts @@ -45,6 +45,7 @@ export class Tx { /** * Contracts deployed in this tx. * Note: Portal address is always set to zero in the tx's new contracts. + * TODO(#3417): Check if portal addresses are still always set to zero */ public readonly newContracts: Tuple, ) { diff --git a/yarn-project/types/src/tx_execution_request.ts b/yarn-project/types/src/tx_execution_request.ts index b944b423af64..7cfbd9aab78d 100644 --- a/yarn-project/types/src/tx_execution_request.ts +++ b/yarn-project/types/src/tx_execution_request.ts @@ -15,6 +15,7 @@ export class TxExecutionRequest { public origin: AztecAddress, /** * Function data representing the function to call. + * TODO(#3417): Remove this field and replace with a function selector. */ public functionData: FunctionData, /** diff --git a/yellow-paper/docs/transactions/index.md b/yellow-paper/docs/transactions/index.md new file mode 100644 index 000000000000..6f72811501b0 --- /dev/null +++ b/yellow-paper/docs/transactions/index.md @@ -0,0 +1,15 @@ +--- +title: Transactions +--- + +# Transactions + +A transaction is the minimal action that changes the state of the network. Transactions in Aztec have a private and a public component, where the former is executed in the user's private execution environment (PXE) and the latter by the sequencer. + +A transaction is also split into three phases to [support authorization abstraction and fee payments](../gas-and-fees/gas-and-fees.md#fees): a validation and fee preparation phase, a main execution phase, and fee distribution phase. + +Users initiate a transaction by sending a _transaction request_ to their local PXE, which [locally simulates and proves the transaction](./local-execution.md) and returns a [_transaction_ object](./tx-object.md) identified by a [_transaction hash_](./tx-hash.md). This transaction object is then broadcasted to the network via an Aztec Node, which checks its [validity](./validity.md), and eventually picked up by a sequencer who [executes the public component of the transaction](./public-execution.md) and includes it in a block. + +import DocCardList from '@theme/DocCardList'; + + diff --git a/yellow-paper/docs/transactions/local-execution.md b/yellow-paper/docs/transactions/local-execution.md new file mode 100644 index 000000000000..154655706d54 --- /dev/null +++ b/yellow-paper/docs/transactions/local-execution.md @@ -0,0 +1,31 @@ +# Local Execution + +Transactions are initiated via a _transaction execution request_ sent from the user to their local _private execution environment_ (PXE). The PXE first executes the transaction locally in a _simulation_ step, and then generates a _zero-knowledge proof_ of correct execution. The PXE is then responsible for converting a _transaction execution request_ into a [_transaction_](./tx-object.md) ready to be broadcasted to the network. + +## Execution request + +A transaction execution request has the following structure. Note that, since Aztec uses full native account abstraction where every account is backed by a contract, a transaction execution request only needs to provide the contract address, function, and arguments of the initial call; nonces and signatures are arguments to the call, and thus opaque to the protocol. + +| Field | Type | Description | +|----------|----------|----------| +| origin | AztecAddress | Address of the contract where the transaction is initiated. | +| functionSelector | Field | Selector (identifier) of the function to be called as entrypoint in the origin contract. | +| argsHash | Field | Hash of the arguments to be used for calling the entrypoint function. | +| txContext | TxContext | Includes contract deployment data (if this tx is used to deploy a contract), chain id, and protocol version. | +| packedArguments | PackedArguments[] | Preimages for argument hashes. When executing a function call with the hash of the arguments, the PXE will look for the preimage of that hash in this list, and expand the arguments to execute the call. | +| authWitnesses | AuthWitness[] | Authorization witnesses. When authorizing an action identified by a hash, the PXE will look for the authorization witness identified by that hash and provide that value to the account contract. | + +## Simulation step + +Upon receiving a transaction execution request to _simulate_, the PXE will locally execute the function identified by the given `functionSelector` in the given `origin` contract with the arguments committed to by `argsHash`. We refer to this function as the _entrypoint_. During execution, contracts may request authorization witnesses or expanded arguments from the _execution oracle_, which are answered with the `packedArguments` and `authWitnesses` from the request. + +The _entrypoint_ may enqueue additional function calls, either private or public, and so forth. The simulation step will always execute all private functions in the call stack until emptied. The result of the simulation is a [_transaction_](./tx-object.md) object without an associated _proof_ which is returned to the application that requested the simulation. + +In terms of circuitry, the simulation step must execute all application circuits that correspond to private function calls, and then execute the private kernel circuit until the private call stack is empty. Note that circuits are only executed, there is no witness generation or proving involved. + +## Proving step + +The proving step is similar to the simulation step, though witnesses are generated for all circuits and proven. Note that it is not necessary to execute the simulation step before the proving step, though it is desirable in order to provide the user with info on their transaction and catch any failed assertions early. + +The output of the proving step is a [_transaction_](./tx-object.md) object with a valid _proof_ associated, ready to be broadcasted to the network. + diff --git a/yellow-paper/docs/transactions/public-execution.md b/yellow-paper/docs/transactions/public-execution.md new file mode 100644 index 000000000000..e281acad277d --- /dev/null +++ b/yellow-paper/docs/transactions/public-execution.md @@ -0,0 +1,16 @@ +# Public execution + +Transactions have a _public execution_ component. Once a transaction is picked up by a sequencer to be included in a block, the sequencer is responsible for executing all enqueued public function calls in the transaction. These are defined by the `data.accumulatedData.publicCallStack` field of the [transaction object](./tx-object.md), which are commitments to the preimages of the `enqueuedPublicFunctionCalls` in the transaction. The sequencer pops function calls from the stack, and pushes new ones as needed, until the public call stack is empty. + +## Bytecode + +Unlike private functions, which are native circuits, public functions in the Aztec Network are specified in Brillig, a zkVM-friendly bytecode. This bytecode is executed and proven in the Brillig public virtual machine. Each function call is a run of the virtual machine, and a _public kernel circuit_ aggregates these calls and produces a final proof for the transaction, which also includes the _private kernel circuit_ proof of the transaction generated during [local execution](./local-execution.md). + +## State + +Since public execution is run by the sequencer, it is run on the state of the chain as it is when the transaction is included in the block. Public functions operate on _public state_, an updateable key-value mapping, instead of notes. + +## Reverts + +Note that, unlike local private execution, public execution can _revert_ due to a failed assertion, running out of gas, trying to call a non-existing function, or other failures. If this happens, the sequencer halts execution and discards all side effects from the [transaction payload phase](../gas-and-fees/gas-and-fees.md#transaction-payload). The transaction is still included in the block and pays fees, but is flagged as reverted. + diff --git a/yellow-paper/docs/transactions/tx-object.md b/yellow-paper/docs/transactions/tx-object.md new file mode 100644 index 000000000000..38123b6ffb90 --- /dev/null +++ b/yellow-paper/docs/transactions/tx-object.md @@ -0,0 +1,85 @@ +# Transaction object + +The transaction object is the struct broadcasted to the p2p network, generated by [_local execution_](./local-execution.md) by the user's PXE. Sequencers pick up transactions from the p2p network to include in a block. + +## Transaction object struct + +The fields of a transaction object are the following: + +| Field | Type | Description | +|----------|----------|----------| +| data | PrivateKernelPublicInputsFinal | Public inputs (ie output) of the last iteration of the private kernel circuit for this transaction. | +| proof | Buffer | Zero-knowledge honk proof for the last iteration of the private kernel circuit for this transaction. | +| encryptedLogs | Buffer[][] | Encrypted logs emitted per function in this transaction. Position `i` contains the encrypted logs emitted by the `i`-th function execution. | +| unencryptedLogs | Buffer[][] | Equivalent to the above but for unencrypted logs. | +| enqueuedPublicFunctionCalls | PublicCallRequest[] | List of public function calls to run during public execution. | +| newContracts | ExtendedContractData[] | List of new contracts to be deployed as part of this transaction. | + +### Private kernel public inputs final + +Output of the last iteration of the private kernel circuit. Includes _accumulated data_ after recursing through all private function calls, as well as _constant data_ composed of _historic block data_ reflecting the state of the chain when such functions were executed, and the global _transaction context_. Refer to the circuits section for more info. + +**Accumulated data** + +| Field | Type | Description | +|-------|------|-------------| +| aggregationObject | AggregationObject | Aggregated proof of all the previous kernel iterations. | +| newCommitments | Field[] | The new commitments made in this transaction. | +| newNullifiers | Field[] | The new nullifiers made in this transaction. | +| nullifiedCommitments | Field[] | The commitments which are nullified by a nullifier in the above list. | +| privateCallStack | Field[] | Current private call stack. | +| publicCallStack | Field[] | Current public call stack. | +| newL2ToL1Msgs | Field[] | All the new L2 to L1 messages created in this transaction. | +| encryptedLogsHash | Field[] | Accumulated encrypted logs hash from all the previous kernel iterations. | +| unencryptedLogsHash | Field[] | Accumulated unencrypted logs hash from all the previous kernel iterations. | +| encryptedLogPreimagesLength | Field | Total accumulated length of the encrypted log preimages emitted in all the previous kernel iterations. | +| unencryptedLogPreimagesLength | Field | Total accumulated length of the unencrypted log preimages emitted in all the previous kernel iterations. | +| newContracts | NewContractData[] | All the new contracts deployed in this transaction. | +| maxBlockNum | Field | Maximum block number (inclusive) for inclusion of this transaction in a block. | + +**Historic block data** + +| Field | Type | Description | +|-------|------|-------------| +| noteHashTreeRoot | Field | Root of the note hash tree at the time of when this information was assembled. | +| nullifierTreeRoot | Field | Root of the nullifier tree at the time of when this information was assembled. | +| contractTreeRoot | Field | Root of the contract tree at the time of when this information was assembled. | +| l1ToL2MessagesTreeRoot | Field | Root of the L1 to L2 messages tree at the time of when this information was assembled. | +| blocksTreeRoot | Field | Root of the historic blocks tree at the time of when this information was assembled. | +| privateKernelVkTreeRoot | Field | Root of the private kernel VK tree at the time of when this information was assembled (future enhancement). | +| publicDataTreeRoot | Field | Current public state tree hash. | +| globalVariablesHash | Field | Previous globals hash, this value is used to recalculate the block hash. | + +### Public call request + +Each _public call request_ is the preimage of a public call stack item in the transaction's `data`, and has the following fields: + +| Field | Type | Description | +|----------|----------|----------| +| contractAddress | AztecAddress | Address of the contract on which the function is invoked. | +| callContext | CallContext | Includes function selector and caller. | +| args | Field[] | Arguments to the function call. | +| sideEffectCounter | number? | Optional counter for ordering side effects of this function call. | + +### Extended contract data + +Each _extended contract data_ corresponds to a contract being deployed by the transaction, and has the following fields: + +| Field | Type | Description | +|----------|----------|----------| +| address | AztecAddress | Address where the contract is to be deployed. | +| portalAddress | EthereumAddress | Portal address on L1 for this contract (zero if none). | +| bytecode | Buffer | Encoded Brillig bytecode for all public functions in the contract. | +| publicKey | PublicKey | Master public encryption key for this contract (zero if none). | +| partialAddress | Field | Hash of the constructor arguments, salt, and bytecode. | + +## Transaction hash + +A transaction is identified by its _transaction hash_. In order to be able to identify a transaction before it has been locally executed, the hash is computed from its [_transaction execution request_](./local-execution.md#execution-request) by hashing: + +- `origin` +- `functionSelector` +- `argsHash` +- `txContent` + +The resulting transaction hash is always emitted during local execution as the first nullifier of the transaction, in order to prevent replay attacks. This is enforced by the private kernel circuit. \ No newline at end of file diff --git a/yellow-paper/docs/transactions/validity.md b/yellow-paper/docs/transactions/validity.md new file mode 100644 index 000000000000..f4121e6faade --- /dev/null +++ b/yellow-paper/docs/transactions/validity.md @@ -0,0 +1,18 @@ +# Validity conditions + +The _validity conditions_ of a transaction define when a [_transaction object_](./tx-object.md) is valid. Nodes should check the validity of a transaction when they receive it either directly or through the p2p pool, and if they found it invalid, should drop it immediately and not broadcast it. + +In addition to being well-formed, the transaction object needs to pass the following checks: + +- **Proof is valid**: The `proof` for the given public `data` should be valid according to a protocol-wide verification key for the final private kernel circuit. +- **No double-spends**: No `nullifier` in the transaction `data` should be already present in the nullifier tree. +- **No pending private function calls**: The `data` private call stack should be empty. +- **Valid historic data**: The tree roots in the historic block data of `data` must match the tree roots of a block in the chain. +- **Maximum block number not exceeded**: The transaction must be included in a block with height no greater than the value specified in `maxBlockNum` within the transaction's `data`. +- **Preimages must match commitments in `data`**: The expanded fields in the transaction object should match the commitments (hashes) to them in the public `data`. + - The `encryptedLogs` should match the `encryptedLogsHash` and `encryptedLogPreimagesLength` in the transaction `data`. + - The `unencryptedLogs` should match the `unencryptedLogsHash` and `unencryptedLogPreimagesLength` in the transaction `data`. + - Each public call stack item in the transaction `data` should have a corresponding preimage in the `enqueuedPublicFunctionCalls`. + - Each new contract data in transaction `data` should have a corresponding preimage in the `newContracts`. + +Note that all checks but the last one are enforced by the base rollup circuit when the transaction is included in a block. \ No newline at end of file From 11f754d256cc164ca2d50b9923aeba1612e7f48b Mon Sep 17 00:00:00 2001 From: PhilWindle <60546371+PhilWindle@users.noreply.github.com> Date: Thu, 30 Nov 2023 09:37:43 +0000 Subject: [PATCH 02/37] docs: Yellow paper updates (#3478) This PR contains further updates to the yellow paper # Checklist: Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge. - [ ] If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag. - [ ] I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - [ ] Every change is related to the PR description. - [ ] I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist). --- yellow-paper/docs/gas-and-fees/gas-and-fees.md | 5 ++++- yellow-paper/docs/private-message-delivery/note-discovery.md | 4 ++-- .../private-message-delivery/private-message-delivery.md | 4 ++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/yellow-paper/docs/gas-and-fees/gas-and-fees.md b/yellow-paper/docs/gas-and-fees/gas-and-fees.md index 7626094a15bf..6c70c3a5d82a 100644 --- a/yellow-paper/docs/gas-and-fees/gas-and-fees.md +++ b/yellow-paper/docs/gas-and-fees/gas-and-fees.md @@ -158,7 +158,7 @@ This would appear to introduce a circular dependency whereby an appropriate fee Initially, the values of transaction gas limits can be set to a very high number, the base gas limits set to values corresponding to the user's chosen amortization level and the fees aet to 0. The transaction can be simulated under these conditions and simulation will provide actual gas consumption figures. Simulation can then be repeated with more realistic values of gas limits and the updated gas consumption figures will be reported. A few iterations of this process will enable the user to establish and prepare an appropriate fee. -Simulation of the transaction will provide feedback as to it's gas consumption, this can then be repeated to converge on the optimum fee to be prepared. The private portion of the transaction will be proven via the private kernel circuit resulting in a number of fee related public inputs: +Simulation of the transaction will provide feedback as to it's gas consumption, this can be repeated to converge on the optimum fee to be prepared. The private portion of the transaction will be proven via the private kernel circuit resulting in a number of fee related public inputs: - **feeCommitments** - New commitments generated as part of fee preparation - **feeNullifiers** - New nullifiers generated as part of fee preparation @@ -255,6 +255,9 @@ This next example differs in that the refund is performed privately using partia ![Private Refund](../gas-and-fees/images/gas-and-fees/private-refund.jpg) +In both of these examples the fee is effectively escrowed as part of the private portion of fee preparation. The enqueued public function is simply an instruction to increase the balance of the payment asset held by the fee payment contract. The sequencer should be able to inspect the public call instruction, consisting of contract address, function selector and arguments and be confident that this function will not fail. Provided the logic of the fee payment contract is defined correctly, once escrowed, the fee can't be modified by the user's transaction payload. This gives the sequencer the guarantee that they will be paid for the work they perform. Finally, the fee distribution function in either of these examples can be written such that the sequencer can be confident of success. This function simply needs to take the securely escrowed fee, compute the actual fee and subsequent refund before increasing the balance of the 2 parties within the payment asset. + + ### Paying Via L1 As a further option, it would be possible to facilitate payments directly from L1. Here, a mechanism similar to L1 -> L2 messaging would be used to transmit the payment to the sequencer. diff --git a/yellow-paper/docs/private-message-delivery/note-discovery.md b/yellow-paper/docs/private-message-delivery/note-discovery.md index d6b1d4781457..9894f6b13c25 100644 --- a/yellow-paper/docs/private-message-delivery/note-discovery.md +++ b/yellow-paper/docs/private-message-delivery/note-discovery.md @@ -6,9 +6,9 @@ sidebar_position: 3 ## Requirements -When users interact with contracts they will generate and publish encrypted notes for other network participants. In order for a user to consume those notes, they need to identify, retrieve and decrypt them. The total number of encrypted notes published by the network will be substantial, making it infeasible for some users to simply retrieve every note and attempt a naive brute-force decryption. For this reason, those users will want to utilize a note discovery protocol to privately identify and provide a much smaller subset of notes for the user to decrypt. +When users interact with contracts they will generate and publish encrypted notes for other network participants. In order for a user to consume notes that belong to them, they need to identify, retrieve and decrypt them. A simple, privacy-preserving approach to this would be to download all of the notes and attempt decryption. However, the total number of encrypted notes published by the network will be substantial, making it infeasible for some users to do this. Those users will want to utilize a note discovery protocol to privately identify their notes. -A number of techniques currently exist to perform this task with various compromises of levels of privacy and the required amounts of computational effort and/or network bandwidth. This is a field into which a lot of research if being conducted so our approach is not to dictate a specific technique but to put in place the necessary abstractions such that users can select their preferred protocol and new techniques can be integrated in the future. +A number of techniques currently exist to help with this and it is a field into which a lot of research is being conducted. Therefore, our approach is not to dictate or enshrine a specific note discovery mechanism but to put in place the necessary abstractions such that users can freely choose. Additionally, through this approach we allow for integration of new or improved protocols in the future. ## Tag Abstraction diff --git a/yellow-paper/docs/private-message-delivery/private-message-delivery.md b/yellow-paper/docs/private-message-delivery/private-message-delivery.md index 92564a139e58..c379a60bc307 100644 --- a/yellow-paper/docs/private-message-delivery/private-message-delivery.md +++ b/yellow-paper/docs/private-message-delivery/private-message-delivery.md @@ -12,7 +12,7 @@ Maintaining the core tenet of privacy within the Aztec Network imposes a number 2. Alice will need to broadcast the encrypted state so as to make it available for Bob to retrieve. 3. Alice will need to broadcast a 'tag' alongside the encrypted state. This tag must be identifiable by Bob's chosen [note discovery protocol](./note-discovery.md) but not identifiable by any third party. -Fulfilling these requirements will enable users to privately identify, retrieve, decrypt and spend their application state. +Fulfilling these requirements will enable users to privately identify, retrieve, decrypt and consume their application state. Individual pieces of application state transmitted in this way are termed 'notes'. ## Constraining Message Delivery @@ -34,5 +34,5 @@ Constraining publication to the correct data availability layer will be performe ## User Handshaking -One function that is useful regardless of the preferred note discovery and encryption schemes is for user's to be notified when they have been sent a note from another user for the first time. To achieve this we will deploy a 'user handshaking' contract that can be used to create a private note for a recipient containing the sender's details (e.g. public key). Network participants will be able to retrieve these notes, decrypt them and use the contents to guide them in the generation of tags of notes to retrieve. +One function that is useful regardless of a user's preferred note discovery and encryption scheme is for users to be notified when they have been sent a note from another user for the first time. To facilitate this we will deploy a 'handshaking' contract that can be used to create a private note for a recipient containing the sender's information (e.g. public key). The notes generated by this contract will be easy to identify enabling users to retrieve these notes, decrypt them and use the contents in any deterministic tag generation used by their chosen note discovery protocol. Trial decryption of these notes alone should not put too high a burden on end users. From 187d2f79d9390e43ec2e2ce6a0db0d6718cc1716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Rodr=C3=ADguez?= Date: Thu, 30 Nov 2023 11:49:14 +0100 Subject: [PATCH 03/37] feat: circuit optimized indexed tree batch insertion (#3367) Changes the batch insertion algorithm for indexed trees to a circuit-optimized one. --- .../src/structs/rollup/base_rollup.ts | 10 + .../circuits.js/src/tests/factories.ts | 11 +- .../src/interfaces/indexed_tree.ts | 27 +- .../standard_indexed_tree.ts | 218 ++++------ .../src/crates/rollup-base/src/main.nr | 3 +- .../src/abis/nullifier_leaf_preimage.nr | 2 +- .../rollup-lib/src/base/base_rollup_inputs.nr | 406 ++++++++---------- .../src/crates/rollup-lib/src/indexed_tree.nr | 121 ++++++ .../src/crates/rollup-lib/src/lib.nr | 4 +- .../src/type_conversion.ts | 12 + .../src/types/rollup_base_types.ts | 2 + .../src/block_builder/solo_block_builder.ts | 9 +- .../merkle_tree_operations_facade.ts | 6 +- .../src/world-state-db/merkle_tree_db.ts | 6 +- .../src/world-state-db/merkle_trees.ts | 7 +- 15 files changed, 472 insertions(+), 372 deletions(-) create mode 100644 yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/indexed_tree.nr diff --git a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts index 13e8edf46e14..454532ec6467 100644 --- a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts @@ -144,6 +144,14 @@ export class BaseRollupInputs { */ public startHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot, + /** + * The nullifiers to be inserted in the tree, sorted high to low. + */ + public sortedNewNullifiers: Tuple, + /** + * The indexes of the sorted nullifiers to the original ones. + */ + public sortednewNullifiersIndexes: Tuple, /** * The nullifiers which need to be updated to perform the batch insertion of the new nullifiers. * See `StandardIndexedTree.batchInsert` function for more details. @@ -210,6 +218,8 @@ export class BaseRollupInputs { fields.startContractTreeSnapshot, fields.startPublicDataTreeRoot, fields.startHistoricBlocksTreeSnapshot, + fields.sortedNewNullifiers, + fields.sortednewNullifiersIndexes, fields.lowNullifierLeafPreimages, fields.lowNullifierMembershipWitness, fields.newCommitmentsSubtreeSiblingPath, diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 3df6e72dccd1..6c03169795a8 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -920,20 +920,23 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { const newNullifiersSubtreeSiblingPath = makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, fr, seed + 0x4000); const newContractsSubtreeSiblingPath = makeTuple(CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, fr, seed + 0x5000); + const sortedNewNullifiers = makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, fr, seed + 0x6000); + const sortednewNullifiersIndexes = makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => i, seed + 0x7000); + const newPublicDataUpdateRequestsSiblingPaths = makeTuple( MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP, x => makeTuple(PUBLIC_DATA_TREE_HEIGHT, fr, x), - seed + 0x6000, + seed + 0x8000, ); const newPublicDataReadsSiblingPaths = makeTuple( MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP, x => makeTuple(PUBLIC_DATA_TREE_HEIGHT, fr, x), - seed + 0x6000, + seed + 0x8000, ); const historicBlocksTreeRootMembershipWitnesses = makeTuple(KERNELS_PER_BASE_ROLLUP, x => - makeMembershipWitness(HISTORIC_BLOCKS_TREE_HEIGHT, seed + x * 0x1000 + 0x7000), + makeMembershipWitness(HISTORIC_BLOCKS_TREE_HEIGHT, seed + x * 0x1000 + 0x9000), ); const constants = makeConstantBaseRollupData(0x100); @@ -946,6 +949,8 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { startContractTreeSnapshot, startPublicDataTreeRoot, startHistoricBlocksTreeSnapshot, + sortedNewNullifiers, + sortednewNullifiersIndexes, lowNullifierLeafPreimages, newCommitmentsSubtreeSiblingPath, newNullifiersSubtreeSiblingPath, diff --git a/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts b/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts index 1b8bade092e3..46c13f49bd91 100644 --- a/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts +++ b/yarn-project/merkle-tree/src/interfaces/indexed_tree.ts @@ -3,6 +3,28 @@ import { LeafData, SiblingPath } from '@aztec/types'; import { LowLeafWitnessData } from '../index.js'; import { AppendOnlyTree } from './append_only_tree.js'; +/** + * The result of a batch insertion in an indexed merkle tree. + */ +export interface BatchInsertionResult { + /** + * Data for the leaves to be updated when inserting the new ones. + */ + lowLeavesWitnessData?: LowLeafWitnessData[]; + /** + * Sibling path "pointing to" where the new subtree should be inserted into the tree. + */ + newSubtreeSiblingPath: SiblingPath; + /** + * The new leaves being inserted in high to low order. This order corresponds with the order of the low leaves witness. + */ + sortedNewLeaves: Buffer[]; + /** + * The indexes of the sorted new leaves to the original ones. + */ + sortedNewLeavesIndexes: number[]; +} + /** * Indexed merkle tree. */ @@ -45,8 +67,5 @@ export interface IndexedTree extends AppendOnlyTree { leaves: Buffer[], subtreeHeight: SubtreeHeight, includeUncommitted: boolean, - ): Promise< - | [LowLeafWitnessData[], SiblingPath] - | [undefined, SiblingPath] - >; + ): Promise>; } diff --git a/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts b/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts index c32ce3221e13..f9d44353fa94 100644 --- a/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts +++ b/yarn-project/merkle-tree/src/standard_indexed_tree/standard_indexed_tree.ts @@ -1,8 +1,9 @@ import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer'; +import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; import { LeafData, SiblingPath } from '@aztec/types'; -import { IndexedTree } from '../interfaces/indexed_tree.js'; +import { BatchInsertionResult, IndexedTree } from '../interfaces/indexed_tree.js'; import { TreeBase } from '../tree_base.js'; const log = createDebugLogger('aztec:standard-indexed-tree'); @@ -317,8 +318,6 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree { * * This offers massive circuit performance savings over doing incremental insertions. * - * A description of the algorithm can be found here: https://colab.research.google.com/drive/1A0gizduSi4FIiIJZ8OylwIpO9-OTqV-R - * * WARNING: This function has side effects, it will insert values into the tree. * * Assumptions: @@ -338,81 +337,78 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree { * roots. * * This become tricky when two items that are being batch inserted need to update the same low nullifier, or need to use - * a value that is part of the same batch insertion as their low nullifier. In this case a zero low nullifier path is given - * to the circuit, and it must determine from the set of batch inserted values if the insertion is valid. + * a value that is part of the same batch insertion as their low nullifier. What we do to avoid this case is to + * update the existing leaves in the tree with the nullifiers in high to low order, ensuring that this case never occurs. + * The circuit has to sort the nullifiers (or take a hint of the sorted nullifiers and prove that it's a valid permutation). + * Then we just batch insert the new nullifiers in the original order. * * The following example will illustrate attempting to insert 2,3,20,19 into a tree already containing 0,5,10,15 * * The example will explore two cases. In each case the values low nullifier will exist within the batch insertion, * One where the low nullifier comes before the item in the set (2,3), and one where it comes after (20,19). * + * First, we sort the nullifiers high to low, that's 20,19,3,2 + * * The original tree: Pending insertion subtree * - * index 0 2 3 4 - - - - + * index 0 1 2 3 - - - - * ------------------------------------- ---------------------------- * val 0 5 10 15 - - - - * nextIdx 1 2 3 0 - - - - * nextVal 5 10 15 0 - - - - * * - * Inserting 2: (happy path) - * 1. Find the low nullifier (0) - provide inclusion proof + * Inserting 20: + * 1. Find the low nullifier (3) - provide inclusion proof * 2. Update its pointers - * 3. Insert 2 into the pending subtree + * 3. Insert 20 into the pending subtree * - * index 0 2 3 4 5 - - - + * index 0 1 2 3 - - 6 - * ------------------------------------- ---------------------------- - * val 0 5 10 15 2 - - - - * nextIdx 5 2 3 0 2 - - - - * nextVal 2 10 15 0 5 - - - + * val 0 5 10 15 - - 20 - + * nextIdx 1 2 3 6 - - 0 - + * nextVal 5 10 15 20 - - 0 - * - * Inserting 3: The low nullifier exists within the insertion current subtree - * 1. When looking for the low nullifier for 3, we will receive 0 again as we have not inserted 2 into the main tree - * This is problematic, as we cannot use either 0 or 2 as our inclusion proof. - * Why cant we? - * - Index 0 has a val 0 and nextVal of 2. This is NOT enough to prove non inclusion of 2. - * - Our existing tree is in a state where we cannot prove non inclusion of 3. - * We do not provide a non inclusion proof to out circuit, but prompt it to look within the insertion subtree. - * 2. Update pending insertion subtree - * 3. Insert 3 into pending subtree + * Inserting 19: + * 1. Find the low nullifier (3) - provide inclusion proof + * 2. Update its pointers + * 3. Insert 19 into the pending subtree * - * (no inclusion proof provided) - * index 0 2 3 4 5 6 - - + * index 0 1 2 3 - - 6 7 * ------------------------------------- ---------------------------- - * val 0 5 10 15 2 3 - - - * nextIdx 5 2 3 0 6 2 - - - * nextVal 2 10 15 0 3 5 - - + * val 0 5 10 15 - - 20 19 + * nextIdx 1 2 3 7 - - 0 6 + * nextVal 5 10 15 19 - - 0 20 * - * Inserting 20: (happy path) - * 1. Find the low nullifier (15) - provide inclusion proof + * Inserting 3: + * 1. Find the low nullifier (0) - provide inclusion proof * 2. Update its pointers - * 3. Insert 20 into the pending subtree + * 3. Insert 3 into the pending subtree * - * index 0 2 3 4 5 6 7 - + * index 0 1 2 3 - 5 6 7 * ------------------------------------- ---------------------------- - * val 0 5 10 15 2 3 20 - - * nextIdx 5 2 3 7 6 2 0 - - * nextVal 2 10 15 20 3 5 0 - + * val 0 5 10 15 - 3 20 19 + * nextIdx 5 2 3 7 - 1 0 6 + * nextVal 3 10 15 19 - 5 0 20 * - * Inserting 19: - * 1. In this case we can find a low nullifier, but we are updating a low nullifier that has already been updated - * We can provide an inclusion proof of this intermediate tree state. + * Inserting 2: + * 1. Find the low nullifier (0) - provide inclusion proof * 2. Update its pointers - * 3. Insert 19 into the pending subtree + * 3. Insert 2 into the pending subtree * - * index 0 2 3 4 5 6 7 8 + * index 0 1 2 3 4 5 6 7 * ------------------------------------- ---------------------------- - * val 0 5 10 15 2 3 20 19 - * nextIdx 5 2 3 8 6 2 0 7 - * nextVal 2 10 15 19 3 5 0 20 + * val 0 5 10 15 2 3 20 19 + * nextIdx 4 2 3 7 5 1 0 6 + * nextVal 2 10 15 19 3 5 0 20 * * Perform subtree insertion * - * index 0 2 3 4 5 6 7 8 + * index 0 1 2 3 4 5 6 7 * --------------------------------------------------------------------- - * val 0 5 10 15 2 3 20 19 - * nextIdx 5 2 3 8 6 2 0 7 - * nextVal 2 10 15 19 3 5 0 20 + * val 0 5 10 15 2 3 20 19 + * nextIdx 4 2 3 7 5 1 0 6 + * nextVal 2 10 15 19 3 5 0 20 * * TODO: this implementation will change once the zero value is changed from h(0,0,0). Changes incoming over the next sprint * @param leaves - Values to insert into the tree. @@ -426,107 +422,67 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree { >( leaves: Buffer[], subtreeHeight: SubtreeHeight, - ): Promise< - | [LowLeafWitnessData[], SiblingPath] - | [undefined, SiblingPath] - > { - // Keep track of touched low leaves - const touched = new Map(); - + ): Promise> { const emptyLowLeafWitness = getEmptyLowLeafWitness(this.getDepth() as TreeHeight); // Accumulators - const lowLeavesWitnesses: LowLeafWitnessData[] = []; - const pendingInsertionSubtree: LeafData[] = []; + const lowLeavesWitnesses: LowLeafWitnessData[] = leaves.map(() => emptyLowLeafWitness); + const pendingInsertionSubtree: LeafData[] = leaves.map(() => zeroLeaf); // Start info const startInsertionIndex = this.getNumLeaves(true); + const leavesToInsert = leaves.map(leaf => toBigIntBE(leaf)); + const sortedDescendingLeafTuples = leavesToInsert + .map((leaf, index) => ({ leaf, index })) + .sort((a, b) => Number(b.leaf - a.leaf)); + const sortedDescendingLeaves = sortedDescendingLeafTuples.map(leafTuple => leafTuple.leaf); + // Get insertion path for each leaf - for (let i = 0; i < leaves.length; i++) { - const newValue = toBigIntBE(leaves[i]); + for (let i = 0; i < leavesToInsert.length; i++) { + const newValue = sortedDescendingLeaves[i]; + const originalIndex = leavesToInsert.indexOf(newValue); - // Keep space and just insert zero values if (newValue === 0n) { - pendingInsertionSubtree.push(zeroLeaf); - lowLeavesWitnesses.push(emptyLowLeafWitness); continue; } const indexOfPrevious = this.findIndexOfPreviousValue(newValue, true); - // If a touched node has a value that is less than the current value - const prevNodes = touched.get(indexOfPrevious.index); - if (prevNodes && prevNodes.some(v => v < newValue)) { - // check the pending low nullifiers for a low nullifier that works - // This is the case where the next value is less than the pending - for (let j = 0; j < pendingInsertionSubtree.length; j++) { - if (pendingInsertionSubtree[j].value === 0n) { - continue; - } - - if ( - pendingInsertionSubtree[j].value < newValue && - (pendingInsertionSubtree[j].nextValue > newValue || pendingInsertionSubtree[j].nextValue === 0n) - ) { - // add the new value to the pending low nullifiers - const currentLowLeaf: LeafData = { - value: newValue, - nextValue: pendingInsertionSubtree[j].nextValue, - nextIndex: pendingInsertionSubtree[j].nextIndex, - }; - - pendingInsertionSubtree.push(currentLowLeaf); - - // Update the pending low leaf to point at the new value - pendingInsertionSubtree[j].nextValue = newValue; - pendingInsertionSubtree[j].nextIndex = startInsertionIndex + BigInt(i); - - break; - } - } - - // Any node updated in this space will need to calculate its low nullifier from a previously inserted value - lowLeavesWitnesses.push(emptyLowLeafWitness); - } else { - // Update the touched mapping - if (prevNodes) { - prevNodes.push(newValue); - touched.set(indexOfPrevious.index, prevNodes); - } else { - touched.set(indexOfPrevious.index, [newValue]); - } - - // get the low leaf - const lowLeaf = this.getLatestLeafDataCopy(indexOfPrevious.index, true); - if (lowLeaf === undefined) { - return [undefined, await this.getSubtreeSiblingPath(subtreeHeight, true)]; - } - const siblingPath = await this.getSiblingPath(BigInt(indexOfPrevious.index), true); - - const witness: LowLeafWitnessData = { - leafData: { ...lowLeaf }, - index: BigInt(indexOfPrevious.index), - siblingPath, + // get the low leaf + const lowLeaf = this.getLatestLeafDataCopy(indexOfPrevious.index, true); + if (lowLeaf === undefined) { + return { + lowLeavesWitnessData: undefined, + sortedNewLeaves: sortedDescendingLeafTuples.map(leafTuple => new Fr(leafTuple.leaf).toBuffer()), + sortedNewLeavesIndexes: sortedDescendingLeafTuples.map(leafTuple => leafTuple.index), + newSubtreeSiblingPath: await this.getSubtreeSiblingPath(subtreeHeight, true), }; + } + const siblingPath = await this.getSiblingPath(BigInt(indexOfPrevious.index), true); - // Update the running paths - lowLeavesWitnesses.push(witness); + const witness: LowLeafWitnessData = { + leafData: { ...lowLeaf }, + index: BigInt(indexOfPrevious.index), + siblingPath, + }; - const currentLowLeaf: LeafData = { - value: newValue, - nextValue: lowLeaf.nextValue, - nextIndex: lowLeaf.nextIndex, - }; + // Update the running paths + lowLeavesWitnesses[i] = witness; + + const currentPendingLeaf: LeafData = { + value: newValue, + nextValue: lowLeaf.nextValue, + nextIndex: lowLeaf.nextIndex, + }; - pendingInsertionSubtree.push(currentLowLeaf); + pendingInsertionSubtree[originalIndex] = currentPendingLeaf; - lowLeaf.nextValue = newValue; - lowLeaf.nextIndex = startInsertionIndex + BigInt(i); + lowLeaf.nextValue = newValue; + lowLeaf.nextIndex = startInsertionIndex + BigInt(originalIndex); - const lowLeafIndex = indexOfPrevious.index; - this.cachedLeaves[lowLeafIndex] = lowLeaf; - await this.updateLeaf(lowLeaf, BigInt(lowLeafIndex)); - } + const lowLeafIndex = indexOfPrevious.index; + this.cachedLeaves[lowLeafIndex] = lowLeaf; + await this.updateLeaf(lowLeaf, BigInt(lowLeafIndex)); } const newSubtreeSiblingPath = await this.getSubtreeSiblingPath( @@ -538,7 +494,13 @@ export class StandardIndexedTree extends TreeBase implements IndexedTree { // Note: In this case we set `hash0Leaf` param to false because batch insertion algorithm use forced null leaf // inclusion. See {@link encodeLeaf} for a more through param explanation. await this.encodeAndAppendLeaves(pendingInsertionSubtree, false); - return [lowLeavesWitnesses, newSubtreeSiblingPath]; + + return { + lowLeavesWitnessData: lowLeavesWitnesses, + sortedNewLeaves: sortedDescendingLeafTuples.map(leafTuple => Buffer.from(new Fr(leafTuple.leaf).toBuffer())), + sortedNewLeavesIndexes: sortedDescendingLeafTuples.map(leafTuple => leafTuple.index), + newSubtreeSiblingPath, + }; } async getSubtreeSiblingPath( diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-base/src/main.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-base/src/main.nr index edf487213f5b..7405a9616330 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-base/src/main.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-base/src/main.nr @@ -1,5 +1,6 @@ use dep::rollup_lib::base::{BaseRollupInputs,BaseOrMergeRollupPublicInputs}; -fn main(inputs : BaseRollupInputs) -> pub BaseOrMergeRollupPublicInputs { +//TODO add a circuit variant +unconstrained fn main(inputs : BaseRollupInputs) -> pub BaseOrMergeRollupPublicInputs { inputs.base_rollup_circuit() } \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/nullifier_leaf_preimage.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/nullifier_leaf_preimage.nr index 5fce155fef6b..b55f943f25c1 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/nullifier_leaf_preimage.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/nullifier_leaf_preimage.nr @@ -6,7 +6,7 @@ struct NullifierLeafPreimage { impl NullifierLeafPreimage { pub fn default() -> Self { - NullifierLeafPreimage { + Self { leaf_value : 0, next_value : 0, next_index : 0, diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index 55da22511da7..172701cfb645 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -29,9 +29,10 @@ use dep::aztec::constants_gen::{ MAX_NEW_L2_TO_L1_MSGS_PER_TX, NUM_UNENCRYPTED_LOGS_HASHES_PER_TX, NULLIFIER_SUBTREE_HEIGHT, + NULLIFIER_TREE_HEIGHT, }; use dep::types::abis::previous_kernel_data::PreviousKernelData; -use dep::types::abis::membership_witness::NullifierMembershipWitness; +use dep::types::abis::membership_witness::{NullifierMembershipWitness, MembershipWitness}; use dep::types::abis::membership_witness::HistoricBlocksTreeRootMembershipWitness; struct BaseRollupInputs { @@ -42,6 +43,8 @@ struct BaseRollupInputs { start_public_data_tree_root: Field, start_historic_blocks_tree_snapshot: AppendOnlyTreeSnapshot, + sorted_new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], + sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], low_nullifier_leaf_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], low_nullifier_membership_witness: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], @@ -180,171 +183,64 @@ impl BaseRollupInputs { calculate_subtree(commitment_tree_leaves) } - unconstrained fn find_leaf_index(self, leaves: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_TX * 2], nullifier: Field, nullifier_index: u64) -> u64 { - let mut matched = false; - let mut index = 0; - for k in 0..nullifier_index { - if !matched { - if (!leaves[k].is_empty()) { - if (full_field_less_than(leaves[k].leaf_value, nullifier) & - (full_field_greater_than(leaves[k].next_value, nullifier) | - (leaves[k].next_value == 0))) { - matched = true; - index = k; - } - } - } - - - } - // if not matched, our subtree will misformed - we must reject - assert(matched, "Nullifier subtree is malformed"); - index - } + fn check_nullifier_tree_non_membership_and_insert_to_tree(self) -> AppendOnlyTreeSnapshot { + let mut new_nullifiers = [0; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP]; - // TODO this should be done in circuit. Ideally using the sorting strategy. - unconstrained fn check_nullifier_tree_non_membership_and_insert_to_tree(self) -> AppendOnlyTreeSnapshot { - // The below monologue is by Madiaa. fwiw, the plan was not simple. - // - // LADIES AND GENTLEMEN The P L A N ( is simple ) - // 1. Get the previous nullifier set setup - // 2. Check for the first added nullifier that it doesnt exist - // 3. Update the nullifier set - // 4. Calculate a new root with the sibling path - // 5. Use that for the next nullifier check. - // 6. Iterate for all of em - // 7. le bosh (profit) - - // BOYS AND GIRLS THE P L A N ( once the first plan is complete ) - // GENERATE OUR NEW NULLIFIER SUBTREE - // 1. We need to point the new nullifiers to point to the index that the previous nullifier replaced - // 2. If we receive the 0 nullifier leaf (where all values are 0, we skip insertion and leave a sparse subtree) - - // New nullifier subtree - let mut nullifier_insertion_subtree = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_TX * 2]; - - // This will update on each iteration - let mut current_nullifier_tree_root = self.start_nullifier_tree_snapshot.root; - - // This will increase with every insertion - let start_insertion_index = self.start_nullifier_tree_snapshot.next_available_leaf_index; - let mut new_index = start_insertion_index; - - // For each kernel circuit - for i in 0..KERNELS_PER_BASE_ROLLUP { - let new_nullifiers = self.kernel_data[i].public_inputs.end.new_nullifiers; - // For each of our nullifiers - for j in 0..MAX_NEW_NULLIFIERS_PER_TX { - // Witness containing index and path - let nullifier_index = i * MAX_NEW_NULLIFIERS_PER_TX + j; - - let witness = self.low_nullifier_membership_witness[nullifier_index]; - // Preimage of the lo-index required for a non-membership proof - let low_nullifier_preimage = self.low_nullifier_leaf_preimages[nullifier_index]; - // Newly created nullifier - let nullifier = new_nullifiers[j]; - - // TODO(maddiaa): reason about this more strongly, can this cause issues? - if (nullifier != 0) { - // Create the nullifier leaf of the new nullifier to be inserted - let mut new_nullifier_leaf = NullifierLeafPreimage { - leaf_value : nullifier, - next_value : low_nullifier_preimage.next_value, - next_index : low_nullifier_preimage.next_index, - }; - - // Assuming populated premier subtree - if (low_nullifier_preimage.is_empty()) { - // check previous nullifier leaves - let index = self.find_leaf_index(nullifier_insertion_subtree, nullifier, nullifier_index as u64); - let same_batch_nullifier = nullifier_insertion_subtree[index]; - assert(!same_batch_nullifier.is_empty(), "Same batch batch nullifier is empty"); - assert(full_field_less_than(same_batch_nullifier.leaf_value, nullifier), "Invalid hint"); - assert(full_field_greater_than(same_batch_nullifier.next_value, nullifier) | (same_batch_nullifier.next_value == 0), "Invalid hint"); - - new_nullifier_leaf.next_index = nullifier_insertion_subtree[index].next_index; - new_nullifier_leaf.next_value = nullifier_insertion_subtree[index].next_value; - - // Update child - nullifier_insertion_subtree[index].next_index = new_index; - nullifier_insertion_subtree[index].next_value = nullifier; - } else { - let is_less_than_nullifier = full_field_less_than(low_nullifier_preimage.leaf_value, nullifier); - let is_next_greater_than = full_field_greater_than(low_nullifier_preimage.next_value, nullifier); - - assert(is_less_than_nullifier, "invalid nullifier range"); - assert( - is_next_greater_than | - ((low_nullifier_preimage.next_value == 0) & (low_nullifier_preimage.next_index == 0)), - "invalid nullifier range" - ); - - // Recreate the original low nullifier from the preimage - let original_low_nullifier = NullifierLeafPreimage{ - leaf_value : low_nullifier_preimage.leaf_value, - next_value : low_nullifier_preimage.next_value, - next_index : low_nullifier_preimage.next_index, - }; - - // perform membership check for the low nullifier against the original root - components::assert_check_membership( - original_low_nullifier.hash(), - witness.leaf_index, - witness.sibling_path, - current_nullifier_tree_root, - ); - - // Calculate the new value of the low_nullifier_leaf - let updated_low_nullifier = NullifierLeafPreimage{ - leaf_value : low_nullifier_preimage.leaf_value, - next_value : nullifier, - next_index : new_index - }; - - // We need another set of witness values for this - current_nullifier_tree_root = components::root_from_sibling_path( - updated_low_nullifier.hash(), witness.leaf_index, witness.sibling_path); - } - nullifier_insertion_subtree[nullifier_index] = new_nullifier_leaf; - } - - // increment insertion index - new_index = new_index + 1; + for i in 0..2 { + for j in 0..MAX_NEW_NULLIFIERS_PER_TX { + new_nullifiers[i * MAX_NEW_NULLIFIERS_PER_TX + j] = self.kernel_data[i].public_inputs.end.new_nullifiers[j]; } - } + }; - // Check that the new subtree is to be inserted at the next location, and is empty currently - let empty_nullifier_subtree_root = calculate_empty_tree_root(NULLIFIER_SUBTREE_HEIGHT); - let leafIndexNullifierSubtreeDepth = self.start_nullifier_tree_snapshot.next_available_leaf_index >> (NULLIFIER_SUBTREE_HEIGHT as u32); - components::assert_check_membership( - empty_nullifier_subtree_root, - leafIndexNullifierSubtreeDepth as Field, + crate::indexed_tree::batch_insert( + self.start_nullifier_tree_snapshot, + new_nullifiers, + self.sorted_new_nullifiers, + self.sorted_new_nullifiers_indexes, self.new_nullifiers_subtree_sibling_path, - current_nullifier_tree_root, - ); - - // Create new nullifier subtree to insert into the whole nullifier tree - let nullifier_sibling_path = self.new_nullifiers_subtree_sibling_path; - let nullifier_subtree_root = self.create_nullifier_subtree(nullifier_insertion_subtree); - - // Calculate the new root - // We are inserting a subtree rather than a full tree here - let subtree_index = start_insertion_index >> (NULLIFIER_SUBTREE_HEIGHT as u32); - let new_root = components::root_from_sibling_path(nullifier_subtree_root, subtree_index as Field, nullifier_sibling_path); - - // Return the new state of the nullifier tree - AppendOnlyTreeSnapshot { - next_available_leaf_index: new_index, - root: new_root, - } + self.low_nullifier_leaf_preimages, + self.low_nullifier_membership_witness.map(|witness: NullifierMembershipWitness| { + MembershipWitness { + leaf_index: witness.leaf_index, + sibling_path: witness.sibling_path, + } + }), + |a: Field, b: Field| {a == b}, // Nullifier equals + |nullifier: Field| {nullifier == 0}, // Nullifier is zero + |leaf: NullifierLeafPreimage| {leaf.hash()}, // Hash leaf + |low_leaf: NullifierLeafPreimage, nullifier: Field| { // Is valid low leaf + let is_less_than_nullifier = full_field_less_than(low_leaf.leaf_value, nullifier); + let is_next_greater_than = full_field_less_than(nullifier, low_leaf.next_value); + + (!low_leaf.is_empty()) & is_less_than_nullifier & ( + is_next_greater_than | + ((low_leaf.next_index == 0) & (low_leaf.next_value == 0)) + ) + }, + |low_leaf: NullifierLeafPreimage, nullifier: Field, nullifier_index: u32| { // Update low leaf + NullifierLeafPreimage{ + leaf_value : low_leaf.leaf_value, + next_value : nullifier, + next_index : nullifier_index, + } + }, + |nullifier: Field, low_leaf: NullifierLeafPreimage| { // Build insertion leaf + NullifierLeafPreimage { + leaf_value : nullifier, + next_value : low_leaf.next_value, + next_index : low_leaf.next_index, + } + }, + [0; NULLIFIER_SUBTREE_HEIGHT], + [0; NULLIFIER_TREE_HEIGHT], + ) } fn create_nullifier_subtree(self, leaves: [NullifierLeafPreimage; N]) -> Field { calculate_subtree(leaves.map(|leaf:NullifierLeafPreimage| leaf.hash())) } - // TODO this should be changed to append only and done in-circuit - unconstrained fn validate_and_process_public_state(self) -> Field { + fn validate_and_process_public_state(self) -> Field { // TODO(#2521) - data read validation should happen against the current state of the tx and not the start state. // Blocks all interesting usecases that read and write to the same public state in the same tx. // https://aztecprotocol.slack.com/archives/C02M7VC7TN0/p1695809629015719?thread_ts=1695653252.007339&cid=C02M7VC7TN0 @@ -629,7 +525,8 @@ mod tests { CALL_DATA_HASH_LOG_FIELDS, NOTE_HASH_SUBTREE_WIDTH, NUM_CONTRACT_LEAVES, - BaseRollupInputs + BaseRollupInputs, + full_field_less_than, }, merkle_tree::{calculate_subtree, calculate_empty_tree_root}, abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot, @@ -662,6 +559,7 @@ mod tests { abis::new_contract_data::NewContractData, abis::public_data_read::PublicDataRead, abis::public_data_update_request::PublicDataUpdateRequest, + abis::previous_kernel_data::PreviousKernelData, tests::previous_kernel_data_builder::PreviousKernelDataBuilder, address::{Address, EthAddress}, utils::bounded_vec::BoundedVec, @@ -670,10 +568,18 @@ mod tests { use dep::std::option::Option; struct NullifierInsertion { - existing_index: Option, + existing_index: u64, + value: Field, + } + + + struct SortedNullifierTuple { value: Field, + original_index: u32, } + global MAX_NEW_NULLIFIERS_PER_TEST = 4; + struct BaseRollupInputsBuilder { kernel_data: [PreviousKernelDataBuilder; KERNELS_PER_BASE_ROLLUP], pre_existing_notes: [Field; NOTE_HASH_SUBTREE_WIDTH], @@ -683,7 +589,7 @@ mod tests { pre_existing_blocks: [Field; KERNELS_PER_BASE_ROLLUP], public_data_reads: BoundedVec, public_data_writes: BoundedVec<(u64, Field), 2>, - new_nullifiers: BoundedVec, + new_nullifiers: BoundedVec, constants: ConstantRollupData, } @@ -718,6 +624,77 @@ mod tests { sibling_path } + fn update_nullifier_tree_with_new_leaves( + mut self, + nullifier_tree: &mut NonEmptyMerkleTree, + kernel_data: &mut [PreviousKernelData; KERNELS_PER_BASE_ROLLUP], + start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot + ) -> ( + [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], + [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], + [Field; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], + [u32; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], + ) { + let mut low_nullifier_leaf_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); + let mut low_nullifier_membership_witness: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); + + let mut sorted_new_nullifier_tuples = [SortedNullifierTuple { + value: 0, + original_index: 0, + }; MAX_NEW_NULLIFIERS_PER_TEST]; + + + for i in 0..MAX_NEW_NULLIFIERS_PER_TEST { + sorted_new_nullifier_tuples[i] = SortedNullifierTuple { + value: self.new_nullifiers.get_unchecked(i).value, + original_index: i as u32, + }; + } + sorted_new_nullifier_tuples = sorted_new_nullifier_tuples.sort_via(|a: SortedNullifierTuple, b: SortedNullifierTuple| {full_field_less_than(b.value, a.value)}); + + let mut sorted_new_nullifiers = [0; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP]; + let mut sorted_new_nullifiers_indexes = [0; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP]; + + for i in 0..MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP { + if (i as u32) < (MAX_NEW_NULLIFIERS_PER_TEST as u32) { + sorted_new_nullifiers[i] = sorted_new_nullifier_tuples[i].value; + sorted_new_nullifiers_indexes[i] = sorted_new_nullifier_tuples[i].original_index; + } else { + sorted_new_nullifiers[i] = 0; + sorted_new_nullifiers_indexes[i] = i as u32; + } + } + + let mut pre_existing_nullifiers = self.pre_existing_nullifiers; + + for i in 0..MAX_NEW_NULLIFIERS_PER_TEST { + if (i as u64) < (self.new_nullifiers.len() as u64) { + let sorted_tuple = sorted_new_nullifier_tuples[i]; + let new_nullifier = sorted_tuple.value; + let original_index = sorted_tuple.original_index; + + let low_index = self.new_nullifiers.get_unchecked(original_index as Field).existing_index; + + kernel_data[0].public_inputs.end.new_nullifiers[original_index] = new_nullifier; + + let mut low_preimage = pre_existing_nullifiers[low_index]; + low_nullifier_leaf_preimages[i] = low_preimage; + low_nullifier_membership_witness[i] = NullifierMembershipWitness { + leaf_index: low_index as Field, + sibling_path: nullifier_tree.get_sibling_path(low_index as Field) + }; + + low_preimage.next_value = new_nullifier; + low_preimage.next_index = start_nullifier_tree_snapshot.next_available_leaf_index + original_index; + pre_existing_nullifiers[low_index] = low_preimage; + + nullifier_tree.update_leaf(low_index, low_preimage.hash()); + } + } + + (low_nullifier_leaf_preimages, low_nullifier_membership_witness, sorted_new_nullifiers, sorted_new_nullifiers_indexes) + } + fn build_inputs(mut self) -> BaseRollupInputs { let mut kernel_data = self.kernel_data.map(|builder: PreviousKernelDataBuilder|{ builder.finish() @@ -736,12 +713,12 @@ mod tests { [0; NULLIFIER_TREE_HEIGHT - NULLIFIER_SUBTREE_HEIGHT], [0; NULLIFIER_SUBTREE_HEIGHT] ); - + let start_nullifier_tree_snapshot = AppendOnlyTreeSnapshot { root: start_nullifier_tree.get_root(), next_available_leaf_index: start_nullifier_tree.get_next_available_index() as u32, }; - + let start_contract_tree = NonEmptyMerkleTree::new(self.pre_existing_contracts, [0; CONTRACT_TREE_HEIGHT], [0; CONTRACT_TREE_HEIGHT - 1], [0; 1]); let start_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: start_contract_tree.get_root(), @@ -761,7 +738,7 @@ mod tests { self.constants.start_historic_blocks_tree_roots_snapshot = start_historic_blocks_tree_snapshot; let mut new_public_data_reads_sibling_paths: [[Field; PUBLIC_DATA_TREE_HEIGHT]; MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - + for i in 0..self.public_data_reads.max_len() { if (i as u64) < (self.public_data_reads.len() as u64) { let index = self.public_data_reads.get_unchecked(i); @@ -792,29 +769,13 @@ mod tests { } } - let mut low_nullifier_leaf_preimages: [NullifierLeafPreimage; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - let mut low_nullifier_membership_witness: [NullifierMembershipWitness; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); - - for i in 0..self.new_nullifiers.max_len() { - if (i as u64) < (self.new_nullifiers.len() as u64) { - let new_nullifier = self.new_nullifiers.get_unchecked(i); - kernel_data[0].public_inputs.end.new_nullifiers[i] = new_nullifier.value; - - if (new_nullifier.existing_index.is_some()) { - let low_index = new_nullifier.existing_index.unwrap_unchecked(); - let mut low_preimage = self.pre_existing_nullifiers[low_index]; - low_nullifier_leaf_preimages[i] = low_preimage; - low_nullifier_membership_witness[i] = NullifierMembershipWitness { - leaf_index: low_index as Field, - sibling_path: start_nullifier_tree.get_sibling_path(low_index as Field) - }; - - low_preimage.next_value = new_nullifier.value; - low_preimage.next_index = start_nullifier_tree_snapshot.next_available_leaf_index + (i as u32); - start_nullifier_tree.update_leaf(low_index, low_preimage.hash()); - } - } - } + let ( + low_nullifier_leaf_preimages, + low_nullifier_membership_witness, + sorted_new_nullifiers, + sorted_new_nullifiers_indexes + ) = self.update_nullifier_tree_with_new_leaves(&mut start_nullifier_tree, &mut kernel_data, start_nullifier_tree_snapshot); + let new_nullifiers_subtree_sibling_path = BaseRollupInputsBuilder::extract_subtree_sibling_path(start_nullifier_tree.get_sibling_path(self.pre_existing_nullifiers.len()), [0; NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH]); BaseRollupInputs { @@ -825,6 +786,9 @@ mod tests { start_public_data_tree_root, start_historic_blocks_tree_snapshot, + sorted_new_nullifiers, + sorted_new_nullifiers_indexes, + low_nullifier_leaf_preimages, low_nullifier_membership_witness, @@ -833,7 +797,7 @@ mod tests { new_contracts_subtree_sibling_path, new_public_data_update_requests_sibling_paths, new_public_data_reads_sibling_paths, - + historic_blocks_tree_root_membership_witnesses: [ HistoricBlocksTreeRootMembershipWitness { leaf_index: 0, @@ -844,7 +808,7 @@ mod tests { sibling_path: start_historic_blocks_tree.get_sibling_path(1) }, ], - + constants: self.constants, } } @@ -863,7 +827,7 @@ mod tests { } #[test] - fn no_new_contract_leaves() { + unconstrained fn no_new_contract_leaves() { let outputs = BaseRollupInputsBuilder::new().execute(); let expected_start_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: test_compute_empty_root([0; CONTRACT_TREE_HEIGHT]), next_available_leaf_index: 2 }; let expected_end_contract_tree_snapshot = AppendOnlyTreeSnapshot { root: test_compute_empty_root([0; CONTRACT_TREE_HEIGHT]), next_available_leaf_index: 4 }; @@ -872,7 +836,7 @@ mod tests { } #[test] - fn contract_leaf_inserted() { + unconstrained fn contract_leaf_inserted() { let new_contract = NewContractData { contract_address: Address::from_field(1), portal_contract_address: EthAddress::from_field(2), @@ -903,7 +867,7 @@ mod tests { } #[test] - fn contract_leaf_inserted_in_non_empty_snapshot_tree() { + unconstrained fn contract_leaf_inserted_in_non_empty_snapshot_tree() { let new_contract = NewContractData { contract_address: Address::from_field(1), portal_contract_address: EthAddress::from_field(2), @@ -936,7 +900,7 @@ mod tests { } #[test] - fn new_commitments_tree() { + unconstrained fn new_commitments_tree() { let mut builder = BaseRollupInputsBuilder::new(); let new_commitments = [27, 28, 29, 30, 31, 32]; @@ -972,7 +936,7 @@ mod tests { } #[test] - fn new_nullifier_tree_empty() { + unconstrained fn new_nullifier_tree_empty() { /** * DESCRIPTION */ @@ -999,7 +963,7 @@ mod tests { } #[test] - fn nullifier_insertion_test() { + unconstrained fn nullifier_insertion_test() { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { @@ -1014,7 +978,7 @@ mod tests { }; builder.new_nullifiers.push(NullifierInsertion { - existing_index: Option::some(0), + existing_index: 0, value: 1, }); @@ -1047,7 +1011,7 @@ mod tests { } #[test] - fn new_nullifier_tree_all_larger() { + unconstrained fn new_nullifier_tree_all_larger() { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { @@ -1062,16 +1026,18 @@ mod tests { }; builder.new_nullifiers.push(NullifierInsertion { - existing_index: Option::some(1), + existing_index: 1, value: 8, }); for i in 1..builder.new_nullifiers.max_len() { builder.new_nullifiers.push(NullifierInsertion { - existing_index: Option::none(), + existing_index: 1, value: (8 + i) as Field, }); } + let output = builder.execute(); + let mut tree_nullifiers = [NullifierLeafPreimage::default(); MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP * 2]; tree_nullifiers[0] = builder.pre_existing_nullifiers[0]; @@ -1103,18 +1069,14 @@ mod tests { [0; NULLIFIER_SUBTREE_HEIGHT + 1] ); - let output = builder.execute(); - assert(output.end_nullifier_tree_snapshot.eq(AppendOnlyTreeSnapshot { root: end_nullifier_tree.get_root(), next_available_leaf_index: 2 * MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP as u32, })); } - // TODO(Alvaro) some nullifier tree tests. We are updating the nullifier tree insertion algorithm. - - #[test(should_fail_with = "membership check failed")] - fn new_nullifier_tree_double_spend() { + #[test(should_fail_with = "Invalid low leaf")] + unconstrained fn new_nullifier_tree_double_spend() { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { @@ -1129,20 +1091,19 @@ mod tests { }; builder.new_nullifiers.push(NullifierInsertion { - existing_index: Option::some(1), + existing_index: 1, value: 8, }); builder.new_nullifiers.push(NullifierInsertion { - existing_index: Option::some(1), + existing_index: 1, value: 8, }); builder.fails(); } - - #[test(should_fail_with = "Nullifier subtree is malformed")] - fn new_nullifier_tree_double_spend_same_batch() { + #[test(should_fail_with = "Invalid low leaf")] + unconstrained fn new_nullifier_tree_double_spend_same_batch() { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_nullifiers[0] = NullifierLeafPreimage { @@ -1157,30 +1118,31 @@ mod tests { }; builder.new_nullifiers.push(NullifierInsertion { - existing_index: Option::some(1), + existing_index: 1, value: 8, }); builder.new_nullifiers.push(NullifierInsertion { - existing_index: Option::none(), + existing_index: 1, value: 8, }); builder.fails(); } - #[test] - fn empty_block_calldata_hash() { + unconstrained fn empty_block_calldata_hash() { let outputs = BaseRollupInputsBuilder::new().execute(); let hash_input_flattened = [0; CALL_DATA_HASH_FULL_FIELDS * 32 + CALL_DATA_HASH_LOG_FIELDS * 16]; let sha_digest = dep::std::hash::sha256(hash_input_flattened); let expected_calldata_hash = U256::from_bytes32(sha_digest).to_u128_limbs(); - assert_eq(outputs.calldata_hash, expected_calldata_hash); + for i in 0..NUM_FIELDS_PER_SHA256 { + assert_eq(outputs.calldata_hash[i], expected_calldata_hash[i]); + } } #[test(should_fail_with = "membership check failed")] - fn compute_membership_historic_blocks_tree_negative() { + unconstrained fn compute_membership_historic_blocks_tree_negative() { let mut inputs = BaseRollupInputsBuilder::new().build_inputs(); inputs.historic_blocks_tree_root_membership_witnesses[0].sibling_path[0] = 27; @@ -1189,7 +1151,7 @@ mod tests { } #[test] - fn constants_dont_change() { + unconstrained fn constants_dont_change() { let inputs = BaseRollupInputsBuilder::new().build_inputs(); let outputs = inputs.base_rollup_circuit(); @@ -1197,28 +1159,28 @@ mod tests { } #[test(should_fail_with = "kernel chain_id does not match the rollup chain_id")] - fn constants_dont_match_kernels_chain_id() { + unconstrained fn constants_dont_match_kernels_chain_id() { let mut builder = BaseRollupInputsBuilder::new(); builder.constants.global_variables.chain_id = 3; builder.fails(); } #[test(should_fail_with = "kernel version does not match the rollup version")] - fn constants_dont_match_kernels_version() { + unconstrained fn constants_dont_match_kernels_version() { let mut builder = BaseRollupInputsBuilder::new(); builder.constants.global_variables.version = 3; builder.fails(); } #[test] - fn subtree_height_is_0() { + unconstrained fn subtree_height_is_0() { let outputs = BaseRollupInputsBuilder::new().execute(); assert_eq(outputs.rollup_subtree_height, 0); } #[test] - fn single_public_state_read() { + unconstrained fn single_public_state_read() { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_public_data[0] = 27; @@ -1228,7 +1190,7 @@ mod tests { } #[test] - fn single_public_state_write() { + unconstrained fn single_public_state_write() { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_public_data[0] = 27; @@ -1247,7 +1209,7 @@ mod tests { } #[test] - fn multiple_public_state_read_writes() { + unconstrained fn multiple_public_state_read_writes() { let mut builder = BaseRollupInputsBuilder::new(); builder.pre_existing_public_data[0] = 27; @@ -1271,4 +1233,4 @@ mod tests { assert_eq(outputs.end_public_data_tree_root, expected_public_data_tree.get_root()); } -} +} \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/indexed_tree.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/indexed_tree.nr new file mode 100644 index 000000000000..1f871270b2d7 --- /dev/null +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/indexed_tree.nr @@ -0,0 +1,121 @@ +use crate::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot; +use crate::merkle_tree::{calculate_subtree, calculate_empty_tree_root}; + +use dep::types::abis::membership_witness::MembershipWitness; + +fn check_permutation(original_array: [T; N], sorted_array: [T; N], indexes: [u32; N], is_equal: fn (T, T) -> bool) { + let mut seen_value = [false; N]; + for i in 0..N { + let index = indexes[i]; + let sorted_value = sorted_array[i]; + let original_value = original_array[index]; + assert(is_equal(sorted_value, original_value), "Invalid index"); + assert(!seen_value[index], "Duplicated index"); + seen_value[index] = true; + } +} + +#[test] +fn check_permutation_basic_test(){ + let original_array = [1, 2, 3]; + let sorted_array = [3, 1, 2]; + let indexes = [2, 0, 1]; + let is_equal = |a: Field, b: Field| a == b; + check_permutation(original_array, sorted_array, indexes, is_equal); +} + +#[test(should_fail_with = "Duplicated index")] +fn check_permutation_duplicated_index(){ + let original_array = [0, 1, 0]; + let sorted_array = [1, 0, 0]; + let indexes = [1, 0, 0]; + let is_equal = |a: Field, b: Field| a == b; + check_permutation(original_array, sorted_array, indexes, is_equal); +} + +#[test(should_fail_with = "Invalid index")] +fn check_permutation_invalid_index(){ + let original_array = [0, 1, 2]; + let sorted_array = [1, 0, 0]; + let indexes = [1, 0, 2]; + let is_equal = |a: Field, b: Field| a == b; + check_permutation(original_array, sorted_array, indexes, is_equal); +} + +pub fn batch_insert( + start_snapshot: AppendOnlyTreeSnapshot, + values_to_insert: [Value; SubtreeWidth], + sorted_values: [Value; SubtreeWidth], + sorted_values_indexes: [u32; SubtreeWidth], + new_subtree_sibling_path: [Field; SiblingPathLength], + low_leaf_preimages: [Leaf; SubtreeWidth], + low_leaf_membership_witnesses: [MembershipWitness; SubtreeWidth], + is_equal: fn (Value, Value) -> bool, + is_empty_value: fn (Value) -> bool, + hash_leaf: fn (Leaf) -> Field, + is_valid_low_leaf: fn(Leaf, Value) -> bool, + update_low_leaf: fn(Leaf, Value, u32) -> Leaf, + build_insertion_leaf: fn (Value, Leaf) -> Leaf, + _subtree_height: [Field; SubtreeHeight], + _tree_height: [Field; TreeHeight], +) -> AppendOnlyTreeSnapshot { + // A permutation to the values is provided to make the insertion use only one insertion strategy + check_permutation(values_to_insert, sorted_values, sorted_values_indexes, is_equal); + + // Now, update the existing leaves with the new leaves + let mut current_tree_root = start_snapshot.root; + let mut insertion_subtree: [Leaf; SubtreeWidth] = dep::std::unsafe::zeroed(); + let start_insertion_index = start_snapshot.next_available_leaf_index; + + for i in 0..sorted_values.len() { + let value = sorted_values[i]; + if !is_empty_value(value) { + let low_leaf_preimage = low_leaf_preimages[i]; + let witness = low_leaf_membership_witnesses[i]; + + assert(is_valid_low_leaf(low_leaf_preimage, value), "Invalid low leaf"); + + // perform membership check for the low leaf against the original root + crate::components::assert_check_membership( + hash_leaf(low_leaf_preimage), + witness.leaf_index, + witness.sibling_path, + current_tree_root, + ); + + let value_index = sorted_values_indexes[i]; + + // Calculate the new value of the low_leaf + let updated_low_leaf= update_low_leaf(low_leaf_preimage, value, start_insertion_index+value_index); + + current_tree_root = crate::components::root_from_sibling_path( + hash_leaf(updated_low_leaf), witness.leaf_index, witness.sibling_path); + + insertion_subtree[value_index] = build_insertion_leaf(value, low_leaf_preimage); + } + } + + let empty_subtree_root = calculate_empty_tree_root(SubtreeHeight); + let leaf_index_subtree_depth = start_insertion_index >> (SubtreeHeight as u32); + + crate::components::assert_check_membership( + empty_subtree_root, + leaf_index_subtree_depth as Field, + new_subtree_sibling_path, + current_tree_root, + ); + + // Create new subtree to insert into the whole indexed tree + let subtree_root = calculate_subtree(insertion_subtree.map(hash_leaf)); + + // Calculate the new root + // We are inserting a subtree rather than a full tree here + let subtree_index = start_insertion_index >> (SubtreeHeight as u32); + let new_root = crate::components::root_from_sibling_path(subtree_root, subtree_index as Field, new_subtree_sibling_path); + + AppendOnlyTreeSnapshot { + root: new_root, + next_available_leaf_index: start_insertion_index + (values_to_insert.len() as u32), + } +} + diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/lib.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/lib.nr index 3a225975d818..1d0df93cc9df 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/lib.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/lib.nr @@ -15,4 +15,6 @@ mod hash; mod merkle_tree; -mod tests; \ No newline at end of file +mod tests; + +mod indexed_tree; diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.ts index 0ae1b87bc337..8a539742be1f 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.ts @@ -156,6 +156,13 @@ export function mapNumberFromNoir(number: NoirField): number { return Number(Fr.fromString(number).toBigInt()); } +/** + * + */ +export function mapNumberToNoir(number: number): NoirField { + return new Fr(BigInt(number)).toString(); +} + /** * Maps a point to a noir point. * @param point - The point. @@ -1406,6 +1413,11 @@ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupI start_contract_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startContractTreeSnapshot), start_public_data_tree_root: mapFieldToNoir(inputs.startPublicDataTreeRoot), start_historic_blocks_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startHistoricBlocksTreeSnapshot), + sorted_new_nullifiers: inputs.sortedNewNullifiers.map(mapFieldToNoir) as FixedLengthArray, + sorted_new_nullifiers_indexes: inputs.sortednewNullifiersIndexes.map(mapNumberToNoir) as FixedLengthArray< + NoirField, + 128 + >, low_nullifier_leaf_preimages: inputs.lowNullifierLeafPreimages.map( mapNullifierLeafPreimageToNoir, ) as FixedLengthArray, diff --git a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts index a4ac38b38ebc..424535bad737 100644 --- a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts @@ -191,6 +191,8 @@ export interface BaseRollupInputs { start_contract_tree_snapshot: AppendOnlyTreeSnapshot; start_public_data_tree_root: Field; start_historic_blocks_tree_snapshot: AppendOnlyTreeSnapshot; + sorted_new_nullifiers: FixedLengthArray; + sorted_new_nullifiers_indexes: FixedLengthArray; low_nullifier_leaf_preimages: FixedLengthArray; low_nullifier_membership_witness: FixedLengthArray; new_commitments_subtree_sibling_path: FixedLengthArray; diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index da6b621773c2..464e766a69eb 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -708,7 +708,12 @@ export class SoloBlockBuilder implements BlockBuilder { // Update the nullifier tree, capturing the low nullifier info for each individual operation const newNullifiers = [...left.data.end.newNullifiers, ...right.data.end.newNullifiers]; - const [nullifierWitnessLeaves, newNullifiersSubtreeSiblingPath] = await this.db.batchInsert( + const { + lowLeavesWitnessData: nullifierWitnessLeaves, + newSubtreeSiblingPath: newNullifiersSubtreeSiblingPath, + sortedNewLeaves: sortedNewNullifiers, + sortedNewLeavesIndexes: sortednewNullifiersIndexes, + } = await this.db.batchInsert( MerkleTreeId.NULLIFIER_TREE, newNullifiers.map(fr => fr.toBuffer()), NULLIFIER_SUBTREE_HEIGHT, @@ -732,6 +737,8 @@ export class SoloBlockBuilder implements BlockBuilder { startNoteHashTreeSnapshot, startPublicDataTreeRoot: startPublicDataTreeSnapshot.root, startHistoricBlocksTreeSnapshot, + sortedNewNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => Fr.fromBuffer(sortedNewNullifiers[i])), + sortednewNullifiersIndexes: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => sortednewNullifiersIndexes[i]), newCommitmentsSubtreeSiblingPath, newContractsSubtreeSiblingPath, newNullifiersSubtreeSiblingPath: makeTuple(NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, i => diff --git a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts b/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts index 5917a8636941..312403577483 100644 --- a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts +++ b/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts @@ -1,5 +1,5 @@ import { Fr } from '@aztec/foundation/fields'; -import { LowLeafWitnessData } from '@aztec/merkle-tree'; +import { BatchInsertionResult } from '@aztec/merkle-tree'; import { L2Block, LeafData, MerkleTreeId, SiblingPath } from '@aztec/types'; import { CurrentTreeRoots, HandleL2BlockResult, MerkleTreeDb, MerkleTreeOperations, TreeInfo } from '../index.js'; @@ -171,11 +171,11 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations { * @param subtreeHeight - Height of the subtree. * @returns The data for the leaves to be updated when inserting the new ones. */ - public batchInsert( + public batchInsert( treeId: MerkleTreeId, leaves: Buffer[], subtreeHeight: number, - ): Promise<[LowLeafWitnessData[], SiblingPath] | [undefined, SiblingPath]> { + ): Promise> { return this.trees.batchInsert(treeId, leaves, subtreeHeight); } } diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts index 04f4d749fee2..8f191517a82d 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts @@ -1,7 +1,7 @@ import { MAX_NEW_NULLIFIERS_PER_TX } from '@aztec/circuits.js'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; -import { LowLeafWitnessData } from '@aztec/merkle-tree'; +import { BatchInsertionResult } from '@aztec/merkle-tree'; import { L2Block, LeafData, MerkleTreeId, SiblingPath } from '@aztec/types'; /** @@ -195,11 +195,11 @@ export interface MerkleTreeOperations { * @param subtreeHeight - Height of the subtree. * @returns The witness data for the leaves to be updated when inserting the new ones. */ - batchInsert( + batchInsert( treeId: MerkleTreeId, leaves: Buffer[], subtreeHeight: number, - ): Promise<[LowLeafWitnessData[], SiblingPath] | [undefined, SiblingPath]>; + ): Promise>; /** * Handles a single L2 block (i.e. Inserts the new commitments into the merkle tree). diff --git a/yarn-project/world-state/src/world-state-db/merkle_trees.ts b/yarn-project/world-state/src/world-state-db/merkle_trees.ts index cdf1aa5c9bd6..a27b1706612f 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_trees.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_trees.ts @@ -15,8 +15,8 @@ import { SerialQueue } from '@aztec/foundation/fifo'; import { createDebugLogger } from '@aztec/foundation/log'; import { AppendOnlyTree, + BatchInsertionResult, IndexedTree, - LowLeafWitnessData, Pedersen, SparseTree, StandardIndexedTree, @@ -401,10 +401,7 @@ export class MerkleTrees implements MerkleTreeDb { treeId: MerkleTreeId, leaves: Buffer[], subtreeHeight: SubtreeHeight, - ): Promise< - | [LowLeafWitnessData[], SiblingPath] - | [undefined, SiblingPath] - > { + ): Promise> { const tree = this.trees[treeId] as StandardIndexedTree; if (!('batchInsert' in tree)) { throw new Error('Tree does not support `batchInsert` method'); From 8cc54a48917ff319a5c2b706e01cfbf5ebca013e Mon Sep 17 00:00:00 2001 From: David Banks <47112877+dbanks12@users.noreply.github.com> Date: Thu, 30 Nov 2023 07:28:35 -0500 Subject: [PATCH 04/37] docs: first go at generated AVM instruction set doc (#3469) docs: first go at generated AVM instruction set doc (#3469) - [AVM Instruction set doc](https://github.com/AztecProtocol/aztec-packages/pull/3469/files#diff-b8e373dff5b442c7a730357c019e827bf2527130c4c6bbc703edcd88c0b3539eR1) generated from [JSON instruction list](https://github.com/AztecProtocol/aztec-packages/pull/3469/files#diff-26db57f44dd61937e5191ce9688506209f8a6c34f2ac43eef02c6bc565010e8bR1). - [Deployed here](https://aztec-packages.vercel.app/docs/public-vm/InstructionSet). --- .../docs/public-vm/InstructionSet.mdx | 5 + yellow-paper/docs/public-vm/Types.mdx | 0 yellow-paper/docs/public-vm/_category_.json | 8 + .../docs/public-vm/gen/_InstructionSet.mdx | 1330 +++++++++++++++++ .../public-vm/gen/images/bit-formats/ADD.png | Bin 0 -> 5237 bytes .../gen/images/bit-formats/ADDRESS.png | Bin 0 -> 3380 bytes .../public-vm/gen/images/bit-formats/AND.png | Bin 0 -> 5256 bytes .../images/bit-formats/BLOCKL1GASLIMIT.png | Bin 0 -> 3382 bytes .../images/bit-formats/BLOCKL2GASLIMIT.png | Bin 0 -> 3383 bytes .../gen/images/bit-formats/BLOCKNUMBER.png | Bin 0 -> 3375 bytes .../gen/images/bit-formats/BLOCKSROOT.png | Bin 0 -> 4342 bytes .../public-vm/gen/images/bit-formats/CALL.png | Bin 0 -> 9200 bytes .../gen/images/bit-formats/CALLDATACOPY.png | Bin 0 -> 4843 bytes .../gen/images/bit-formats/CALLDEPTH.png | Bin 0 -> 3391 bytes .../gen/images/bit-formats/CALLER.png | Bin 0 -> 3399 bytes .../public-vm/gen/images/bit-formats/CAST.png | Bin 0 -> 4538 bytes .../gen/images/bit-formats/CHAINID.png | Bin 0 -> 3373 bytes .../public-vm/gen/images/bit-formats/CMOV.png | Bin 0 -> 5606 bytes .../gen/images/bit-formats/COINBASE.png | Bin 0 -> 3400 bytes .../gen/images/bit-formats/CONTRACTSROOT.png | Bin 0 -> 4364 bytes .../public-vm/gen/images/bit-formats/DIV.png | Bin 0 -> 5256 bytes .../public-vm/gen/images/bit-formats/EQ.png | Bin 0 -> 5259 bytes .../gen/images/bit-formats/FEEPERL1GAS.png | Bin 0 -> 3400 bytes .../gen/images/bit-formats/FEEPERL2GAS.png | Bin 0 -> 3389 bytes .../gen/images/bit-formats/GLOBALSHASH.png | Bin 0 -> 4364 bytes .../public-vm/gen/images/bit-formats/JUMP.png | Bin 0 -> 3193 bytes .../gen/images/bit-formats/JUMPI.png | Bin 0 -> 4140 bytes .../gen/images/bit-formats/L1GAS.png | Bin 0 -> 3415 bytes .../gen/images/bit-formats/L1L2MSGLOAD.png | Bin 0 -> 7137 bytes .../gen/images/bit-formats/L2GAS.png | Bin 0 -> 3389 bytes .../public-vm/gen/images/bit-formats/LT.png | Bin 0 -> 5253 bytes .../public-vm/gen/images/bit-formats/LTE.png | Bin 0 -> 5265 bytes .../public-vm/gen/images/bit-formats/MOV.png | Bin 0 -> 4185 bytes .../gen/images/bit-formats/MSGSROOT.png | Bin 0 -> 4359 bytes .../public-vm/gen/images/bit-formats/NOT.png | Bin 0 -> 4540 bytes .../gen/images/bit-formats/NOTESROOT.png | Bin 0 -> 4361 bytes .../gen/images/bit-formats/NULLIFIERSROOT.png | Bin 0 -> 4346 bytes .../public-vm/gen/images/bit-formats/OR.png | Bin 0 -> 5246 bytes .../gen/images/bit-formats/ORIGIN.png | Bin 0 -> 3388 bytes .../gen/images/bit-formats/PORTAL.png | Bin 0 -> 3401 bytes .../gen/images/bit-formats/PUBLICDATAROOT.png | Bin 0 -> 4376 bytes .../gen/images/bit-formats/REFUNDEE.png | Bin 0 -> 3397 bytes .../gen/images/bit-formats/RETURN.png | Bin 0 -> 4060 bytes .../gen/images/bit-formats/REVERT.png | Bin 0 -> 4096 bytes .../gen/images/bit-formats/SENDL1TOL2MSG.png | Bin 0 -> 7129 bytes .../public-vm/gen/images/bit-formats/SET.png | Bin 0 -> 7248 bytes .../public-vm/gen/images/bit-formats/SHL.png | Bin 0 -> 5242 bytes .../public-vm/gen/images/bit-formats/SHR.png | Bin 0 -> 5240 bytes .../gen/images/bit-formats/SLOAD.png | Bin 0 -> 4152 bytes .../gen/images/bit-formats/SSTORE.png | Bin 0 -> 4208 bytes .../gen/images/bit-formats/STATICCALL.png | Bin 0 -> 9178 bytes .../public-vm/gen/images/bit-formats/SUB.png | Bin 0 -> 5239 bytes .../gen/images/bit-formats/TIMESTAMP.png | Bin 0 -> 3356 bytes .../public-vm/gen/images/bit-formats/ULOG.png | Bin 0 -> 4063 bytes .../gen/images/bit-formats/VERSION.png | Bin 0 -> 3362 bytes .../public-vm/gen/images/bit-formats/XOR.png | Bin 0 -> 5264 bytes yellow-paper/package.json | 6 +- .../InstructionSet/InstructionSet.js | 979 ++++++++++++ .../InstructionSetMarkdownGen.js | 137 ++ .../InstructionSet/InstructionSize.js | 80 + .../InstructionSet/genBitFormats.js | 16 + yellow-paper/src/preprocess/index.js | 6 + yellow-paper/yarn.lock | 74 +- 63 files changed, 2637 insertions(+), 4 deletions(-) create mode 100644 yellow-paper/docs/public-vm/InstructionSet.mdx create mode 100644 yellow-paper/docs/public-vm/Types.mdx create mode 100644 yellow-paper/docs/public-vm/_category_.json create mode 100644 yellow-paper/docs/public-vm/gen/_InstructionSet.mdx create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/ADD.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/ADDRESS.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/AND.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL1GASLIMIT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL2GASLIMIT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKNUMBER.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKSROOT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CALL.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CALLDATACOPY.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CALLDEPTH.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CALLER.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CAST.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CHAINID.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CMOV.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/COINBASE.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/CONTRACTSROOT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/DIV.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/EQ.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL1GAS.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL2GAS.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/GLOBALSHASH.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/JUMP.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/JUMPI.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/L1GAS.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/L1L2MSGLOAD.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/L2GAS.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/LT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/LTE.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/MOV.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/MSGSROOT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/NOT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/NOTESROOT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/NULLIFIERSROOT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/OR.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/ORIGIN.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/PORTAL.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/PUBLICDATAROOT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/REFUNDEE.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/RETURN.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/REVERT.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/SENDL1TOL2MSG.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/SET.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/SHL.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/SHR.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/SLOAD.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/SSTORE.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/STATICCALL.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/SUB.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/TIMESTAMP.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/ULOG.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/VERSION.png create mode 100644 yellow-paper/docs/public-vm/gen/images/bit-formats/XOR.png create mode 100644 yellow-paper/src/preprocess/InstructionSet/InstructionSet.js create mode 100644 yellow-paper/src/preprocess/InstructionSet/InstructionSetMarkdownGen.js create mode 100644 yellow-paper/src/preprocess/InstructionSet/InstructionSize.js create mode 100644 yellow-paper/src/preprocess/InstructionSet/genBitFormats.js create mode 100644 yellow-paper/src/preprocess/index.js diff --git a/yellow-paper/docs/public-vm/InstructionSet.mdx b/yellow-paper/docs/public-vm/InstructionSet.mdx new file mode 100644 index 000000000000..141e435dd25c --- /dev/null +++ b/yellow-paper/docs/public-vm/InstructionSet.mdx @@ -0,0 +1,5 @@ +# Instruction Set + +import GeneratedInstructionSet from './gen/_InstructionSet.mdx'; + + \ No newline at end of file diff --git a/yellow-paper/docs/public-vm/Types.mdx b/yellow-paper/docs/public-vm/Types.mdx new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/yellow-paper/docs/public-vm/_category_.json b/yellow-paper/docs/public-vm/_category_.json new file mode 100644 index 000000000000..b71bfdd8d049 --- /dev/null +++ b/yellow-paper/docs/public-vm/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "AVM: Aztec's Public VM", + "position": 5, + "link": { + "type": "generated-index", + "description": "Aztec's Public VM..." + } +} diff --git a/yellow-paper/docs/public-vm/gen/_InstructionSet.mdx b/yellow-paper/docs/public-vm/gen/_InstructionSet.mdx new file mode 100644 index 000000000000..60bd17532b4f --- /dev/null +++ b/yellow-paper/docs/public-vm/gen/_InstructionSet.mdx @@ -0,0 +1,1330 @@ +[comment]: # (THIS IS A GENERATED FILE! DO NOT EDIT!) +[comment]: # (Generated via `yarn preprocess`) + +[comment]: # (Generated by InstructionSetMarkdownGen.tsx and InstructionSet.js) + +import Markdown from 'react-markdown' +import CodeBlock from '@theme/CodeBlock' + + +## Instructions Table + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OpcodeNameSummaryBit-sizeExpression
0x00 [`ADD`](#isa-section-add)Addition (a + b)96{ + `M[dstOffset] = M[aOffset] + M[bOffset] mod 2^k` + }
0x01 [`SUB`](#isa-section-sub)Subtraction (a - b)96{ + `M[dstOffset] = M[aOffset] - M[bOffset] mod 2^k` + }
0x02 [`DIV`](#isa-section-div)Unsigned division (a / b)96{ + `M[dstOffset] = M[aOffset] / M[bOffset]` + }
0x03 [`EQ`](#isa-section-eq)Equality check (a == b)96{ + `M[dstOffset] = M[aOffset] == M[bOffset] ? 1 : 0` + }
0x04 [`LT`](#isa-section-lt)Less-than check (a < b)96{ + `M[dstOffset] = M[aOffset] < M[bOffset] ? 1 : 0` + }
0x05 [`LTE`](#isa-section-lte)Less-than-or-equals check (a <= b)96{ + `M[dstOffset] = M[aOffset] <= M[bOffset] ? 1 : 0` + }
0x06 [`AND`](#isa-section-and)Bitwise AND (a & b)96{ + `M[dstOffset] = M[aOffset] AND M[bOffset]` + }
0x07 [`OR`](#isa-section-or)Bitwise OR (a | b)96{ + `M[dstOffset] = M[aOffset] OR M[bOffset]` + }
0x08 [`XOR`](#isa-section-xor)Bitwise XOR (a ^ b)96{ + `M[dstOffset] = M[aOffset] XOR M[bOffset]` + }
0x09 [`NOT`](#isa-section-not)Bitwise NOT (inversion)72{ + `M[dstOffset] = NOT M[aOffset]` + }
0x0a [`SHL`](#isa-section-shl)Bitwise leftward shift (a << b)96{ + `M[dstOffset] = M[aOffset] << M[bOffset]` + }
0x0b [`SHR`](#isa-section-shr)Bitwise rightward shift (a >> b)96{ + `M[dstOffset] = M[aOffset] >> M[bOffset]` + }
0x0c [`SET`](#isa-section-set)Set a memory word from a constant in the bytecode.48+N{ + `M[dstOffset] = const` + }
0x0d [`MOV`](#isa-section-mov)Move a word from source memory location to destination`.64{ + `M[dstOffset] = M[srcOffset]` + }
0x0e [`CMOV`](#isa-section-cmov)Move a word (conditionally chosen) from one memory location to another (`d = cond > 0 ? a : b`).112{ + `M[dstOffset] = M[condOffset] > 0 ? M[aOffset] : M[bOffset]` + }
0x0f [`CAST`](#isa-section-cast)Type cast72{ + `M[dstOffset] = cast(M[aOffset])` + }
0x10 [`CALLDATACOPY`](#isa-section-calldatacopy)Copy calldata into memory.88{ + `M[dstOffset:dstOffset+size] = calldata[cdOffset:cdOffset+size]` + }
0x11 [`SLOAD`](#isa-section-sload)Load a word from storage.64{ + `M[dstOffset] = storage[M[slotOffset]]` + }
0x12 [`SSTORE`](#isa-section-sstore)Write a word to storage.64{ + `storage[M[slotOffset]] = M[srcOffset]` + }
0x13 [`L1L2MSGLOAD`](#isa-section-l1l2msgload)Retrieve an L1-to-L2 message by key136 +{`{ + M[dstMsgOffset], + M[dstSibPathOffset], + M[dstLeafIndexOffset], + M[dstRootOffset] +} = getL1ToL2Message(M[keyOffset])`} +
0x14 [`SENDL1TOL2MSG`](#isa-section-sendl2tol1msg)Retrieve an L1-to-L2 message by key136 +{`{ + M[dstMsgOffset], + M[dstSibPathOffset], + M[dstLeafIndexOffset], + M[dstRootOffset] +} = getL1ToL2Message(M[keyOffset])`} +
0x15 [`JUMP`](#isa-section-jump)Jump to a location in the bytecode.40{ + `PC = loc` + }
0x16 [`JUMPI`](#isa-section-jumpi)Conditionally jump to a location in the bytecode.64{ + `PC = M[condOffset] > 0 ? loc : PC` + }
0x17 [`RETURN`](#isa-section-return)Halt execution with `success`, optionally returning some data.64{ + `return(M[offset:offset+size])` + }
0x18 [`REVERT`](#isa-section-revert)Halt execution with `failure`, optionally returning some data.64{ + `revert(M[offset:offset+size])` + }
0x19 [`CALL`](#isa-section-call)Call into another contract.208 +{`M[successOffset] = call( + M[l1GasOffset], M[l2GasOffset], M[addrOffset], + M[argsOffset], M[argsSize], + M[retOffset], M[retSize])`} +
0x1a [`STATICCALL`](#isa-section-staticcall)Call into another contract, disallowing persistent state modifications.208 +{`M[successOffset] = staticcall( + M[l1GasOffset], M[l2GasOffset], M[addrOffset], + M[argsOffset], M[argsSize], + M[retOffset], M[retSize])`} +
0x1b [`ULOG`](#isa-section-ulog)Emit an unencrypted log with data from the `field` memory page64{ + `ulog(M[offset:offset+size])` + }
0x1c [`CHAINID`](#isa-section-chainid)Get this rollup's L1 chain ID40{ + `M[dstOffset] = Globals.chainId` + }
0x1d [`VERSION`](#isa-section-version)Get this rollup's L2 version ID40{ + `M[dstOffset] = Globals.version` + }
0x1e [`BLOCKNUMBER`](#isa-section-blocknumber)Get this block's number40{ + `M[dstOffset] = Globals.blocknumber` + }
0x1f [`TIMESTAMP`](#isa-section-timestamp)Get this L2 block's timestamp40{ + `M[dstOffset] = Globals.timestamp` + }
0x20 [`COINBASE`](#isa-section-coinbase)Get the block's beneficiary address40{ + `M[dstOffset] = Globals.coinbase` + }
0x21 [`BLOCKL1GASLIMIT`](#isa-section-blockl1gaslimit)Total amount of "L1 gas" that a block can consume40{ + `M[dstOffset] = Globals.l1GasLimit` + }
0x22 [`BLOCKL2GASLIMIT`](#isa-section-blockl2gaslimit)Total amount of "L2 gas" that a block can consume40{ + `M[dstOffset] = Globals.l2GasLimit` + }
0x23 [`NOTESROOT`](#isa-section-notesroot)Get the historical note-hash tree root as of the specified block number.64{ + `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].note_hash_tree_root` + }
0x24 [`NULLIFIERSROOT`](#isa-section-nullroot)Get the historical nullifier tree root as of the specified block number.64{ + `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].nullifier_tree_root` + }
0x25 [`CONTRACTSROOT`](#isa-section-contractsroot)Get the historical contracts tree root as of the specified block number.64{ + `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].contracts_tree_root` + }
0x26 [`MSGSROOT`](#isa-section-msgsroot)Get the historical l1-to-l2 messages tree root as of the specified block number.64{ + `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].l1_to_l2_messages_tree_root` + }
0x27 [`BLOCKSROOT`](#isa-section-blocksroot)Get the historical blocks tree root as of the specified block number.64{ + `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].blocks_tree_root` + }
0x28 [`PUBLICDATAROOT`](#isa-section-publicdataroot)Get the historical public data tree root as of the specified block number.64{ + `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].public_data_tree_root` + }
0x29 [`GLOBALSHASH`](#isa-section-globalshash)Get the historical global variables hash as of the specified block number.64{ + `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].global_variables_hash` + }
0x2a [`ORIGIN`](#isa-section-origin)Get the transaction's origination address40{ + `M[dstOffset] = TxContext.origin` + }
0x2b [`REFUNDEE`](#isa-section-refundee)The recipient of fee refunds for this transaction40{ + `M[dstOffset] = TxContext.refundee` + }
0x2c [`FEEPERL1GAS`](#isa-section-feeperl1gas)The fee to be paid per "L1 gas" - set by the transaction's original caller40{ + `M[dstOffset] = TxContext.feePerL1Gas` + }
0x2d [`FEEPERL2GAS`](#isa-section-feeperl2gas)The fee to be paid per "L2 gas" - set by the transaction's original caller40{ + `M[dstOffset] = TxContext.feePerL2Gas` + }
0x2e [`CALLER`](#isa-section-caller)Get the address of the sender (the caller's context)40{ + `M[dstOffset] = CallContext.sender` + }
0x2f [`ADDRESS`](#isa-section-address)Get the address of the currently executing l2 contract40{ + `M[dstOffset] = CallContext.storageContractAddress` + }
0x30 [`PORTAL`](#isa-section-portal)Get the address of the l1 portal contract40{ + `M[dstOffset] = CallContext.portalAddress` + }
0x31 [`CALLDEPTH`](#isa-section-calldepth)Get how many calls deep the current call context is40{ + `M[dstOffset] = CallContext.calldepth` + }
0x32 [`L1GAS`](#isa-section-l1gas)Remaining "L1 gas" for this call (after this instruction).40{ + `M[dstOffset] = LatestContext.l1Gas` + }
0x33 [`L2GAS`](#isa-section-l2gas)Remaining "L2 gas" for this call (after this instruction).40{ + `M[dstOffset] = LatestContext.l2Gas` + }
+ + +## Instructions + +### `ADD` (0x00) +Addition (a + b) + +[See in table.](#isa-table-add) + +- **Category**: arithmetic +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] + M[bOffset] mod 2^k` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/ADD.png) + +### `SUB` (0x01) +Subtraction (a - b) + +[See in table.](#isa-table-sub) + +- **Category**: arithmetic +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] - M[bOffset] mod 2^k` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/SUB.png) + +### `DIV` (0x02) +Unsigned division (a / b) + +[See in table.](#isa-table-div) + +- **Category**: arithmetic +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] / M[bOffset]` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/DIV.png) + +### `EQ` (0x03) +Equality check (a == b) + +[See in table.](#isa-table-eq) + +- **Category**: conditional +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] == M[bOffset] ? 1 : 0` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/EQ.png) + +### `LT` (0x04) +Less-than check (a < b) + +[See in table.](#isa-table-lt) + +- **Category**: conditional +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] < M[bOffset] ? 1 : 0` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/LT.png) + +### `LTE` (0x05) +Less-than-or-equals check (a <= b) + +[See in table.](#isa-table-lte) + +- **Category**: conditional +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] <= M[bOffset] ? 1 : 0` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/LTE.png) + +### `AND` (0x06) +Bitwise AND (a & b) + +[See in table.](#isa-table-and) + +- **Category**: bitwise +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] AND M[bOffset]` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/AND.png) + +### `OR` (0x07) +Bitwise OR (a | b) + +[See in table.](#isa-table-or) + +- **Category**: bitwise +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] OR M[bOffset]` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/OR.png) + +### `XOR` (0x08) +Bitwise XOR (a ^ b) + +[See in table.](#isa-table-xor) + +- **Category**: bitwise +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] XOR M[bOffset]` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/XOR.png) + +### `NOT` (0x09) +Bitwise NOT (inversion) + +[See in table.](#isa-table-not) + +- **Category**: bitwise +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = NOT M[aOffset]` +- **Tag checks**: `T[aOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 72 + +![](./images/bit-formats/NOT.png) + +### `SHL` (0x0a) +Bitwise leftward shift (a << b) + +[See in table.](#isa-table-shl) + +- **Category**: bitwise +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] << M[bOffset]` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/SHL.png) + +### `SHR` (0x0b) +Bitwise rightward shift (a >> b) + +[See in table.](#isa-table-shr) + +- **Category**: bitwise +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. +- **Args**: + - **aOffset**: memory offset of the operation's left input + - **bOffset**: memory offset of the operation's right input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[aOffset] >> M[bOffset]` +- **Tag checks**: `T[aOffset] == T[bOffset] == op-type` +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 96 + +![](./images/bit-formats/SHR.png) + +### `SET` (0x0c) +Set a memory word from a constant in the bytecode. + +[See in table.](#isa-table-set) + +- **Category**: memory +- **Flags**: + - **op-type**: The [type/size](./Types) to check inputs against and tag the output with. `field` type is NOT supported for SET. +- **Args**: + - **const**: a constant value from the bytecode to store in memory (any type except `field`) + - **dstOffset**: memory offset specifying where to store the constant +- **Expression**: `M[dstOffset] = const` +- **Details**: Set memory word at `dstOffset` to `const`'s immediate value. `const` _cannot be `field` type_! +- **Tag updates**: `T[dstOffset] = op-type` +- **Bit-size**: 48+N + +![](./images/bit-formats/SET.png) + +### `MOV` (0x0d) +Move a word from source memory location to destination`. + +[See in table.](#isa-table-mov) + +- **Category**: memory +- **Args**: + - **srcOffset**: memory offset of word to move + - **dstOffset**: memory offset specifying where to store that word +- **Expression**: `M[dstOffset] = M[srcOffset]` +- **Tag updates**: `T[dstOffset] = T[srcOffset]` +- **Bit-size**: 64 + +![](./images/bit-formats/MOV.png) + +### `CMOV` (0x0e) +Move a word (conditionally chosen) from one memory location to another (`d = cond > 0 ? a : b`). + +[See in table.](#isa-table-cmov) + +- **Category**: memory +- **Args**: + - **aOffset**: memory offset of word 'a' to conditionally move + - **bOffset**: memory offset of word 'b' to conditionally move + - **condOffset**: memory offset of the operations 'conditional' input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = M[condOffset] > 0 ? M[aOffset] : M[bOffset]` +- **Details**: One of two source memory locations is chosen based on the condition. `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type. +- **Tag updates**: `T[dstOffset] = M[condOffset] > 0 ? T[aOffset] : T[bOffset]` +- **Bit-size**: 112 + +![](./images/bit-formats/CMOV.png) + +### `CAST` (0x0f) +Type cast + +[See in table.](#isa-table-cast) + +- **Category**: types +- **Flags**: + - **dest-type**: The [type/size](./Types) to tag the output with when different from `op-type`. +- **Args**: + - **aOffset**: memory offset of word to cast + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = cast(M[aOffset])` +- **Details**: Cast a word in memory based on the `dest-type` specified in the bytecode. Truncates when casting to a smaller type, left-zero-pads when casting to a larger type. +- **Tag updates**: `T[dstOffset] = dest-type` +- **Bit-size**: 72 + +![](./images/bit-formats/CAST.png) + +### `CALLDATACOPY` (0x10) +Copy calldata into memory. + +[See in table.](#isa-table-calldatacopy) + +- **Category**: contract calls +- **Args**: + - **cdOffset**: offset into calldata to copy from + - **size**: number of words to copy + - **dstOffset**: memory offset specifying where to copy the first word to +- **Expression**: `M[dstOffset:dstOffset+size] = calldata[cdOffset:cdOffset+size]` +- **Details**: Calldata is read-only and cannot be directly operated on by other instructions. This instruction moves words from calldata into memory so they can be operated on normally. +- **Tag updates**: `T[dstOffset:dstOffset+size] = field` +- **Bit-size**: 88 + +![](./images/bit-formats/CALLDATACOPY.png) + +### `SLOAD` (0x11) +Load a word from storage. + +[See in table.](#isa-table-sload) + +- **Category**: storage & messaging +- **Args**: + - **slotOffset**: memory offset of the storage slot to load from + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = storage[M[slotOffset]]` +- **Details**: Load a word from this contract's persistent public storage into memory. +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/SLOAD.png) + +### `SSTORE` (0x12) +Write a word to storage. + +[See in table.](#isa-table-sstore) + +- **Category**: storage & messaging +- **Args**: + - **srcOffset**: memory offset of the word to store + - **slotOffset**: memory offset containing the storage slot to store to +- **Expression**: `storage[M[slotOffset]] = M[srcOffset]` +- **Details**: Store a word from memory into this contract's persistent public storage. +- **Bit-size**: 64 + +![](./images/bit-formats/SSTORE.png) + +### `L1L2MSGLOAD` (0x13) +Retrieve an L1-to-L2 message by key + +[See in table.](#isa-table-l1l2msgload) + +- **Category**: storage & messaging +- **Args**: + - **keyOffset**: memory offset of the message key + - **dstMsgOffset**: memory offset specifying where to store the `L1_TO_L2_MESSAGE_LENGTH` words of the retrieved message + - **dstSibPathOffset**: memory offset specifying where to store the `L1_TO_L2_MSG_TREE_HEIGHT` words of the retrieved message's sibling path + - **dstLeafIndexOffset**: memory offset specifying where to store the retrieved message's leaf index + - **dstRootOffset**: memory offset specifying where to store the retrieved message tree root +- **Expression**: + +{`{ + M[dstMsgOffset], + M[dstSibPathOffset], + M[dstLeafIndexOffset], + M[dstRootOffset] +} = getL1ToL2Message(M[keyOffset])`} + +- **Tag updates**: `T[dst*Offset] = field` +- **Bit-size**: 136 + +![](./images/bit-formats/L1L2MSGLOAD.png) + +### `SENDL1TOL2MSG` (0x14) +Retrieve an L1-to-L2 message by key + +[See in table.](#isa-table-sendl2tol1msg) + +- **Category**: storage & messaging +- **Args**: + - **keyOffset**: memory offset of the message key + - **dstMsgOffset**: memory offset specifying where to store the `L1_TO_L2_MESSAGE_LENGTH` words of the retrieved message + - **dstSibPathOffset**: memory offset specifying where to store the `L1_TO_L2_MSG_TREE_HEIGHT` words of the retrieved message's sibling path + - **dstLeafIndexOffset**: memory offset specifying where to store the retrieved message's leaf index + - **dstRootOffset**: memory offset specifying where to store the retrieved message tree root +- **Expression**: + +{`{ + M[dstMsgOffset], + M[dstSibPathOffset], + M[dstLeafIndexOffset], + M[dstRootOffset] +} = getL1ToL2Message(M[keyOffset])`} + +- **Tag updates**: `T[dst*Offset] = field` +- **Bit-size**: 136 + +![](./images/bit-formats/SENDL1TOL2MSG.png) + +### `JUMP` (0x15) +Jump to a location in the bytecode. + +[See in table.](#isa-table-jump) + +- **Category**: control +- **Args**: + - **loc**: target location to jump to +- **Expression**: `PC = loc` +- **Details**: Target location is an immediate value (a constant in the bytecode). +- **Bit-size**: 40 + +![](./images/bit-formats/JUMP.png) + +### `JUMPI` (0x16) +Conditionally jump to a location in the bytecode. + +[See in table.](#isa-table-jumpi) + +- **Category**: control +- **Args**: + - **loc**: target location conditionally jump to + - **condOffset**: memory offset of the operations 'conditional' input +- **Expression**: `PC = M[condOffset] > 0 ? loc : PC` +- **Details**: Target location is an immediate value (a constant in the bytecode). `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type. +- **Bit-size**: 64 + +![](./images/bit-formats/JUMPI.png) + +### `RETURN` (0x17) +Halt execution with `success`, optionally returning some data. + +[See in table.](#isa-table-return) + +- **Category**: contract calls +- **Args**: + - **offset**: memory offset of first word to return + - **size**: number of words to return +- **Expression**: `return(M[offset:offset+size])` +- **Details**: Return control flow to the calling context/contract. +- **Bit-size**: 64 + +![](./images/bit-formats/RETURN.png) + +### `REVERT` (0x18) +Halt execution with `failure`, optionally returning some data. + +[See in table.](#isa-table-revert) + +- **Category**: contract calls +- **Args**: + - **offset**: memory offset of first word to return + - **size**: number of words to return +- **Expression**: `revert(M[offset:offset+size])` +- **Details**: Return control flow to the calling context/contract. +- **Bit-size**: 64 + +![](./images/bit-formats/REVERT.png) + +### `CALL` (0x19) +Call into another contract. + +[See in table.](#isa-table-call) + +- **Category**: contract calls +- **Args**: + - **l1GasOffset**: amount of L1 gas to provide to the callee + - **l2GasOffset**: amount of L2 gas to provide to the callee + - **addrOffset**: address of the contract to call + - **argsOffset**: memory offset to args (will become the callee's calldata) + - **argsSize**: number of words to pass via callee's calldata + - **retOffset**: destination memory offset specifying where to store the data returned from the callee + - **retSize**: number of words to copy from data returned by callee + - **successOffset**: destination memory offset specifying where to store the call's success (0: failure, 1: success) +- **Expression**: + +{`M[successOffset] = call( + M[l1GasOffset], M[l2GasOffset], M[addrOffset], + M[argsOffset], M[argsSize], + M[retOffset], M[retSize])`} + +- **Details**: Creates a new CallContext, triggers execution of the corresponding contract code, + and then resumes execution in the current CallContext. A non-existent contract or one + with no code will return success. Nested call has an incremented `CallContext.calldepth`. +- **Tag checks**: `T[l1GasOffset] == T[l2GasOffset] == u32` +- **Tag updates**: + +{`T[successOffset] = u8 +T[retOffset:retOffset+retSize] = field`} + +- **Bit-size**: 208 + +![](./images/bit-formats/CALL.png) + +### `STATICCALL` (0x1a) +Call into another contract, disallowing persistent state modifications. + +[See in table.](#isa-table-staticcall) + +- **Category**: contract calls +- **Args**: + - **l1GasOffset**: amount of L1 gas to provide to the callee + - **l2GasOffset**: amount of L2 gas to provide to the callee + - **addrOffset**: address of the contract to call + - **argsOffset**: memory offset to args (will become the callee's calldata) + - **argsSize**: number of words to pass via callee's calldata + - **retOffset**: destination memory offset specifying where to store the data returned from the callee + - **retSize**: number of words to copy from data returned by callee + - **successOffset**: destination memory offset specifying where to store the call's success (0: failure, 1: success) +- **Expression**: + +{`M[successOffset] = staticcall( + M[l1GasOffset], M[l2GasOffset], M[addrOffset], + M[argsOffset], M[argsSize], + M[retOffset], M[retSize])`} + +- **Details**: Same as `CALL`, but the callee is cannot modify persistent state. Disallowed instructions are `SSTORE`, `ULOG`, `CALL`. +- **Tag checks**: `T[l1GasOffset] == T[l2GasOffset] == u32` +- **Tag updates**: + +{`T[successOffset] = u8 +T[retOffset:retOffset+retSize] = field`} + +- **Bit-size**: 208 + +![](./images/bit-formats/STATICCALL.png) + +### `ULOG` (0x1b) +Emit an unencrypted log with data from the `field` memory page + +[See in table.](#isa-table-ulog) + +- **Category**: logging +- **Args**: + - **offset**: memory offset of the data to log + - **size**: number of words to log +- **Expression**: `ulog(M[offset:offset+size])` +- **Bit-size**: 64 + +![](./images/bit-formats/ULOG.png) + +### `CHAINID` (0x1c) +Get this rollup's L1 chain ID + +[See in table.](#isa-table-chainid) + +- **Category**: block info +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = Globals.chainId` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/CHAINID.png) + +### `VERSION` (0x1d) +Get this rollup's L2 version ID + +[See in table.](#isa-table-version) + +- **Category**: block info +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = Globals.version` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/VERSION.png) + +### `BLOCKNUMBER` (0x1e) +Get this block's number + +[See in table.](#isa-table-blocknumber) + +- **Category**: block info +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = Globals.blocknumber` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/BLOCKNUMBER.png) + +### `TIMESTAMP` (0x1f) +Get this L2 block's timestamp + +[See in table.](#isa-table-timestamp) + +- **Category**: block info +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = Globals.timestamp` +- **Tag updates**: `T[dstOffset] = u64` +- **Bit-size**: 40 + +![](./images/bit-formats/TIMESTAMP.png) + +### `COINBASE` (0x20) +Get the block's beneficiary address + +[See in table.](#isa-table-coinbase) + +- **Category**: block info +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = Globals.coinbase` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/COINBASE.png) + +### `BLOCKL1GASLIMIT` (0x21) +Total amount of "L1 gas" that a block can consume + +[See in table.](#isa-table-blockl1gaslimit) + +- **Category**: block info +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = Globals.l1GasLimit` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/BLOCKL1GASLIMIT.png) + +### `BLOCKL2GASLIMIT` (0x22) +Total amount of "L2 gas" that a block can consume + +[See in table.](#isa-table-blockl2gaslimit) + +- **Category**: block info +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = Globals.l2GasLimit` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/BLOCKL2GASLIMIT.png) + +### `NOTESROOT` (0x23) +Get the historical note-hash tree root as of the specified block number. + +[See in table.](#isa-table-notesroot) + +- **Category**: historical access +- **Args**: + - **blockNumOffset**: memory offset of the block number input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].note_hash_tree_root` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/NOTESROOT.png) + +### `NULLIFIERSROOT` (0x24) +Get the historical nullifier tree root as of the specified block number. + +[See in table.](#isa-table-nullroot) + +- **Category**: historical access +- **Args**: + - **blockNumOffset**: memory offset of the block number input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].nullifier_tree_root` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/NULLIFIERSROOT.png) + +### `CONTRACTSROOT` (0x25) +Get the historical contracts tree root as of the specified block number. + +[See in table.](#isa-table-contractsroot) + +- **Category**: historical access +- **Args**: + - **blockNumOffset**: memory offset of the block number input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].contracts_tree_root` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/CONTRACTSROOT.png) + +### `MSGSROOT` (0x26) +Get the historical l1-to-l2 messages tree root as of the specified block number. + +[See in table.](#isa-table-msgsroot) + +- **Category**: historical access +- **Args**: + - **blockNumOffset**: memory offset of the block number input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].l1_to_l2_messages_tree_root` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/MSGSROOT.png) + +### `BLOCKSROOT` (0x27) +Get the historical blocks tree root as of the specified block number. + +[See in table.](#isa-table-blocksroot) + +- **Category**: historical access +- **Args**: + - **blockNumOffset**: memory offset of the block number input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].blocks_tree_root` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/BLOCKSROOT.png) + +### `PUBLICDATAROOT` (0x28) +Get the historical public data tree root as of the specified block number. + +[See in table.](#isa-table-publicdataroot) + +- **Category**: historical access +- **Args**: + - **blockNumOffset**: memory offset of the block number input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].public_data_tree_root` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/PUBLICDATAROOT.png) + +### `GLOBALSHASH` (0x29) +Get the historical global variables hash as of the specified block number. + +[See in table.](#isa-table-globalshash) + +- **Category**: historical access +- **Args**: + - **blockNumOffset**: memory offset of the block number input + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].global_variables_hash` +- **Tag updates**: `T[dstOffset] = field` +- **Bit-size**: 64 + +![](./images/bit-formats/GLOBALSHASH.png) + +### `ORIGIN` (0x2a) +Get the transaction's origination address + +[See in table.](#isa-table-origin) + +- **Category**: tx context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = TxContext.origin` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/ORIGIN.png) + +### `REFUNDEE` (0x2b) +The recipient of fee refunds for this transaction + +[See in table.](#isa-table-refundee) + +- **Category**: tx context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = TxContext.refundee` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/REFUNDEE.png) + +### `FEEPERL1GAS` (0x2c) +The fee to be paid per "L1 gas" - set by the transaction's original caller + +[See in table.](#isa-table-feeperl1gas) + +- **Category**: tx context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = TxContext.feePerL1Gas` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/FEEPERL1GAS.png) + +### `FEEPERL2GAS` (0x2d) +The fee to be paid per "L2 gas" - set by the transaction's original caller + +[See in table.](#isa-table-feeperl2gas) + +- **Category**: tx context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = TxContext.feePerL2Gas` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/FEEPERL2GAS.png) + +### `CALLER` (0x2e) +Get the address of the sender (the caller's context) + +[See in table.](#isa-table-caller) + +- **Category**: call context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = CallContext.sender` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/CALLER.png) + +### `ADDRESS` (0x2f) +Get the address of the currently executing l2 contract + +[See in table.](#isa-table-address) + +- **Category**: call context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = CallContext.storageContractAddress` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/ADDRESS.png) + +### `PORTAL` (0x30) +Get the address of the l1 portal contract + +[See in table.](#isa-table-portal) + +- **Category**: call context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = CallContext.portalAddress` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/PORTAL.png) + +### `CALLDEPTH` (0x31) +Get how many calls deep the current call context is + +[See in table.](#isa-table-calldepth) + +- **Category**: call context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = CallContext.calldepth` +- **Details**: Note: security issues with EVM's tx.origin can be resolved by asserting the `calldepth == 0`. +- **Tag updates**: `T[dstOffset] = u8` +- **Bit-size**: 40 + +![](./images/bit-formats/CALLDEPTH.png) + +### `L1GAS` (0x32) +Remaining "L1 gas" for this call (after this instruction). + +[See in table.](#isa-table-l1gas) + +- **Category**: latest context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = LatestContext.l1Gas` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/L1GAS.png) + +### `L2GAS` (0x33) +Remaining "L2 gas" for this call (after this instruction). + +[See in table.](#isa-table-l2gas) + +- **Category**: latest context +- **Args**: + - **dstOffset**: memory offset specifying where to store operation's result +- **Expression**: `M[dstOffset] = LatestContext.l2Gas` +- **Tag updates**: `T[dstOffset] = u32` +- **Bit-size**: 40 + +![](./images/bit-formats/L2GAS.png) diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/ADD.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/ADD.png new file mode 100644 index 0000000000000000000000000000000000000000..c358398a8d0bbdad7243644753f9bc93a2c37a80 GIT binary patch literal 5237 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 E332~4yZ`_I literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/ADDRESS.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/ADDRESS.png new file mode 100644 index 0000000000000000000000000000000000000000..14fe371aec91fc526b2a0a82c328068e4452bfcb GIT binary patch literal 3380 zcmdT{X;4$i7VabRJCJ8z-fwb{UzTV(m3-Yo*{<83E2GppLkb>tpMR1P-t$dl(!j_Bp&`ceJW+moWH_ zzhms&zw43hBZWlU@mopwE(As;66Im;F|Mbby?EgeuO-}ZdN3vNV zDSpahtysr@;2?27ycN*549kQuqjcc|I|~bz4fpcZK>EoOj=h%8CDxWD|IG>%h@g6Q zIj*@Z#xoZhcX@xGiyP~tFPAN^3L%o$8x{jt5!s<%&bWF-3V@VD|EY7%CS|VxcK3Ey z^3&K=TVF^CQVvT>*IN!WK}7#;69GyHe10L}x6^ub(G^?EvY2@|zl?O+Cp)IDz7mhtabMU=;t^DCL71DQRP z{)Iz<*j%g506NTTaOinnwP$w|Vpapll<${5e}LcN-#uXSwPh(_2s@1mVSF+HO*Ee8 z+zg0YON3_o#6S8SIU25)F-IG~VEji7fiVZXW$Vkdu3 zykXbTk241kTiHg@YCN3xfsH9fMr}<9k|PY>c1Qr5JFOx*e;H5kI69#QB^CiG;}&|L zUS{};h?4~~s9(L+qYG`68ZIM8RvsP8)6mhV?2>n41v^@cI#hhkB*&>yj~@`F#t%y# z^THb|P#JzzvquXKMCn$zGnI@lEK?}Y_GGs|T-L!k=33%~y;orrYc++oT-mhiZZl;I zjNyVY2Kv%n>Z3N20pUSXM`RbB;m-z5w>qLypJoHwJot~#@BEtD|F!u(F^%fZ)aFRx zV~`Dz{KYAyAStl=BHy+P!h9FVsPB=Vz5(*iVdM9=mQ|mcPM2yC+KWSBevTNJNoIfL4So4~Q!SLVMq$;(F;8by4(m|&U8ytqI@rDZ zEncxSpUpno2u4nXCxQNtVn$(OqNSZXT2lQ;0x#02#IQ<$HaErjezB7TIMfV%RmoH7#6xo}3_P#+dkltkvLl7otV0Bw0FDm($C8sue z{_V#rGrTyg>*Y6vB9HEMOq-hOgC$W<`uclRn58`&@hY0L@MTUqMLH9O<|W5)N9%`_YAwW@letGeP}y|g8LLxL2dpfUUT30J{Kpgk}|~3X=S$? z_jrBQ@@_;PGIxLaaCV0vu2^^YMT{<1 zF%#R1L0&V)x9PTsLW}Sk;POmr=gN&H{HtK)e6>brSJ*dd)uu90UtVN9_5QPJtMaOb z_A_$Iw`3JF&0;1#sG2#9hmfXyO8fmtEU@Isl|}hn^Tp>Se;_3`I}t*!7Y2GKskQaG zcVieqNz`)ZYcG_IbxP0b=JVHsR7HYa0mpp(RJ!gq=TAmxQ$0bPPx~{jucn-euR9{5 zCm8v1u6au3j4t51!Qbo(5R9$7myeO7D%_|z*c_}scqg!vyzlk-xvI>)8k9;`jBcT^ ze?;;6>6qm~Vr@cQ>i`-G{Qwcre?l&Rh;aJc6z)E=oRCWm&?oLd)EWv+zDBd}3-=!Q z69W^sf^S2I4Pg|PFXJ5Mp8PVk1iDT1itcgJcv?^N4gRP1@DlQ+H8%17C|a5 zgfHh?>W>&PQQhh0E_2$<=mlM1Dt;`~*qn+cuOAN9LjC0MvJ<1KqmwhpR^7&HjoHiL(uPipm?houjnui$Ng+Q@%Ec5@H29DTM1l6OXmt0mw3IOF z>Sm2HHLp`}MWuV&B(|Gx{RL}M*8zSj5s_m$Vlgan@jdk@XCfG(ho#tU)#|N_C&l~o z?Q5`gQaoufc$<-pqG` SBqX~49RK;$k#Z}qOaBI!!&_ni literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/AND.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/AND.png new file mode 100644 index 0000000000000000000000000000000000000000..c15ee272e57b49684c360e75ff50a8992affc74b GIT binary patch literal 5256 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 WEArg8F7;qCfMee|+ta@Z$oL1zg;FB` literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL2GASLIMIT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKL2GASLIMIT.png new file mode 100644 index 0000000000000000000000000000000000000000..816a84cb99d9fc4b80435e917ad041d4d8347975 GIT binary patch literal 3383 zcmdT{X;f3!7CuRsL5cN&hz!wIksvrAwiJ+nXk@4$g3$yKix4pkGD9#x(F$4wDYHdD zF{nrYg(S$-l%gmB0?1?n1ga1q4FLi~2tzOS@9TPR^+(rxf6hK@-*fgo`@7%X=esvu zPGC2vXsZAKHrOAxa|J*S1I^zkDL~`r>R2ZL)K=~7Y}}&qM1#VVylPE_j*tv#+=qq5 z{ij0F8YZu_t}*+5#NXB4kU?3(lpur52Xc^6a{hnVCYBBwUCGYq;>h^sM4R<2M(Q{ezM$T; zK-GEPhtJT4T)=LcQf480F`e-#LAxy1rCeI0H>Z1>H={}wg5l#rdpOZ*Oa9j&?FIxA zvWM8QUs7p3RJ_~;?MAw{FZRg$1M+P||h^yAqM~^^$RLwii_ov#;2kSpue+lj` zTC|Sv*cbm1=(-8S9jPq!yP5vD3myySwX#>XyfTxmT2MYg-XxVxX@Dh}Q*3B^f=lsC zpo}jXI&5<>Midk9b9^V|{KTsN`z1MwWxl4k>7m!YFBuaxf zNUN94(-(sF$Vv8hAiPw{u9`ljFWhro>RiapWT=ORsH!>b5-bZPm#bmGw4Wq!xPSA+ zsA45|k}p!+r+>{dCz;?i9AvBR`z#zj9)+ALz5V*eG@?)-3W#WPs)kUHoY+{ol^4E&d@I8w&EKJa1Z1 zGh(Ma6`?f7w+k!-wl|4ual^_X?UCj1fgRL`E2hRGeUS5w!>K;&YWek|PWqdLwN7<_ zvo~Ckit{A5NsYS?^I9K8%FfDG1Vo6#L{}KxX)m>EYoPziMgX*~{aM8v<9)2|hNl*c zK%d3cdo56fXeFv3r~=CSqoO%%U#Q>R&vCP)tmgh+ z?${8)tL%*L#4=&ZnaY;SY0IR{_gc=)0Lo*K%j(@`lCm22Ml2nA{Ok~=jU3oUau&@N z(kp}R`_cKJA~0ycg;zfL9=5b8UJj=%S9LdXqVBTZu4vzAv$tC=RmDR7D|rO3>ZaZ5>be(nZ&D))$q@y3a#s6pnIR^q{)jvjPalne z^J1bdiL8pK>N{xB=@Xp772&j}5-j0mf8553k1|SuLSLA1w2ADG#7T_rhMwF*e5IWx( z>n_DTorfijmo-2cbtDqJc6Cnvg2y>WVvi=;G!EdGS7O`}x;q%K6rp*n`H}UkAp$A# z$S!+<_uFQ~92G7%JhGtBSO$kDJ3=8+p~s0K@<@~k1V9`b1N0^-JwX9?elJ0>sv+8} zC}YliC{*QKh?7hDw4UGvmBnA&MTvzCbvKe<_^q`%$rM2j#9e4D%2EThw_M-b({QJ# zz|U_Du>5_?W8I;~^!M+%Pfa&}FLjPw?^&KFp|Sad#M-{i07RK+pjgG6=@ALv*%ZPa z0I3TMzE4TRgyrvG1hAEw-C{~JcLIEb4(Ih&P&oMpQF^ksGOI*0eukQHNG754drl~_ z3f$r=NE3zRQROk|tV6cDg|6(_yR4#81Hf@1oF%qCbE58;4ud04i_ZC7qFmwCOwN#L z`c9-r2r%Y;$}HHob<+ww75y(SIXF@?Q>O`k14U;G>+>u7xn(mg!l>zY}2GLX-Sy1pe}0u;fISQzF(JB zGDS>q%?w=ho6q-Gjzf@CC2nKLJO7iqFd zGv`Q87x974@wG~r{wht^Qe7?n+8QOnZF6kiS!}ysxDSc8LB~%Y8+iNDvwUJPZz;u$ z?ZMlKV=S8X7{y5XeZ-43R38_XU8Z?58c$10e)Z5< z%kJ^d?o5#fSS8HvE=jJu8M|J%Rkigg4Z-->RJRmaJu386L7z&f6R#9QX%t6zN zbD;Ny{0+zM!)+_+#MtEf^Y%0D2Jei=2q8gBUB+6pq0^NL>K}^7Jnk7qxP& zUK%rn+yg0lp7xO&JcR*);u5?la)5i7*1#X)52LZ{DngaUaI7&Jh#za~j9gr8ulV-5 z2+?W}8Xx?aURZ=XqNCP~)5dt1QJxqWKbn7DfL9K|%`5F|Fltt!-wzQ9uoKz6p5ZZL zVy{xgWR~&1Qf|$ybCQjVbPimCeqp>ZDJW>5BBC+YH$SGpyr%Whb$ud(Jrr=0DA;g? znGu>#&d7zd({@v%a^=y$oi@$x0d7z`@|B1`61lcXem{Q&q^_edfN{=;!CA(a^>;zC z(hL&U0}dUKS3U5%zt-M*2}`r+V`IfDrlycm@X|9B_|L7&iR)vUTAzB|KO|@VNB;p< Z)O|bfDWRp?Dj+a`{m~P4Wwu@ke*n?eUQz%6 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKNUMBER.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKNUMBER.png new file mode 100644 index 0000000000000000000000000000000000000000..267651b68002678cc7721cb94268a8661cd35b89 GIT binary patch literal 3375 zcmdT{X;_n27XFd|LAFGx78DXX^ciF;K`lr@7DbVzC`v#HiMSw3L^hE%5J0L`1g(Un zLVzO3(gaYGh#?T9MnIGuOn?N75D`N_AXGxge9ZK3pUyL#KmBvh-Ol;WdGCAgIp6n3 zz1_4mwrcE*sHKi`pz-deie_a=>^2oJ3gj#K*a}H# zzt}YIi zIQAi_8SZwHPeybhv^R!R#mXdQ%DSjzc1h*|*^+kXSZvdWr% z6exqd{~YMMjzD6oQco{e@i{M8nH9}XJ018?+ByI?0u4B)Y@A$KYtLI-v4wi@b}3Ui zJ}1$2WsbCr$TaoFS15BmHgwTdJ3jyPE)i^;|6-!>fX7S-jg~g2tJdbq7#7>BA^Gf6 zr-(}4eheD652%{xvV9mp6q#0{BT7$($uTA@F85r_t27cp+ZG5?OO^zh?&+&p3-ZG$ z*a~3!>@E16Xicp(_jhd;OmDytaV>OqTVYS@4BL;3_a%cIW%@3#mN17+(z{*RpeJuY zPyAgBek*#`Pq`?E?dB)xVO*CkF5*bd3h4AtP?dka{W4dd#z>aK`Xr2KIp7n)h>)PB z&pn5O5&u`jyVp1@-D;b*Sem#_yV*kO7Oj;!D2ES;9H%4Kk5JQy6_MygTct@)+T}mT z|NlbtW3TMSIa}gAOci4s9WaXC1FsSV`>&mfujlH%EtV2gA0PB^mxlxhoB+(-yefKH zl%^KA4O#lXT|Hqv+aCx3slFmDUc5kRq z!s?>YOa}sIYf~498v{vWB_r9{k?6K}@Kj3!4?M#hfHFf-cKDBap zSE@!YPI}Y@bn5DcQz%qGa!=??=3ye0Kwwk-9e!C(PNh?$cv~eQVWq2Ud|Zo-)_mY< z0(sq+>~-%MdwM0~&W~ZaDkiwda?@a-ZL7zqk5pDgf*II)i0rzOpbl9Yw!qg#KLa+Rg`Kb>x*&T91t`H_| z-+S~-9f`6wetRlKIr#Gkb{2;0!;>mN4Frqp^=mDh$e_;UT-V9G(u7}7tW>Milt;h} zMq<}uzH>xP>;*wWFqg{+0Iv!>S5H-SZo5SL3SL!3uK+ZG-dLW}FmnDqBEVr#UMmt9 z@v$!C=$T2#sxG;q!{u{o`?@;v-}_lykiUPBb`UP4L~Z@pf%T#y83Mo{K-=I8nPBEj zAUN@wk9i232Kv__WPUe6Q49SmDNQ;uZVot{@|amp;t=e_xPn%ePJF!y0L%xPIg`IF zebX*(Ej^#N41Qy-9I6t8Gz%p2^ZbCE^On^jc{XDJG7mb(t?F?Zx&uE^@pFhJ))JWX zG>wpniLG@dI%H7|aC)TQg)y?J%3Rok>5`#?_dycA6GZb?UUw{r(Yy%mz$WJtjQGm( zskWCCEij?{*vRwC;>}`ZWpk|l=)s+*Z#3?}Kq2ZkJao=j?nlCVLSC<;JX#ia51{qm zmEe0giGvo(F3CgNUiwKHHD9C{b_g$+O-(2(Fn@lCLCR~Jyh`Y z_78U`s3Bu-GS9keqS5A;or)CWM||`4EP<4iCxhm(-*3B3n<1Ld<}BF}&sLb{$3Fv; z(=`1$QHoPF%qsGRrsi2i|4*cf5Rn!6ls4zyDIGM4E-*WrcO*^{_0{J*JsQgLka zgw|H0z_|{ZRmdRWCVcqjmedQ_(d>`g#?<6~!{YY3N(RRCdxk{By2~-oQatCrJ@rI&vX(V;K|fjgO{rM-F$kP;{tak{E(Ani&9#L^|z>Sv)}hH+qiy(6Vp^leOzj# zAG|MJmW0i?xyvTW{s}(2hTP#xp1;a5NsClSRz!~sjKDC(k5QTB=J^Y6mkr*WPL0<} zA`;R_=Y-t7IjDLZdXiXb9uqH$m0`s+o-gk#SGO7{KRn|?3~Ok(6sHVzKi_HeOF9EA z0G9OA|~>T0HMR>_$Gq6|4s-Q zh`J%T+6e`mwZYWO+Hwh;&BO(P&($B4(pSq`ny=q(3R8A_$>BhuTbJDq#YVMS-lV!w i`~UrG^S|~3kp|2A4O1q_$rFNL0PY99UFrLSGX4dyM^e-P literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKSROOT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/BLOCKSROOT.png new file mode 100644 index 0000000000000000000000000000000000000000..aea3d00f76b016c447e0eb364f1b71ed2356566f GIT binary patch literal 4342 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CALL.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/CALL.png new file mode 100644 index 0000000000000000000000000000000000000000..9bc0b671d99533dc29de1408ca42c35839de24e4 GIT binary patch literal 9200 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CALLDATACOPY.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/CALLDATACOPY.png new file mode 100644 index 0000000000000000000000000000000000000000..0f5c08b1e9af4b2f2f3b90af4189d1afd4f70398 GIT binary patch literal 4843 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 BZ%zOJ literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CALLER.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/CALLER.png new file mode 100644 index 0000000000000000000000000000000000000000..323e2869b8ee5d1cf0a3ac461ceab5d6647b25a7 GIT binary patch literal 3399 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 Kc4fA{H~$T%e_vn# literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CAST.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/CAST.png new file mode 100644 index 0000000000000000000000000000000000000000..8767543b69f4af0ed567154ceaf545347b324c6c GIT binary patch literal 4538 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/CONTRACTSROOT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/CONTRACTSROOT.png new file mode 100644 index 0000000000000000000000000000000000000000..825ee2a8ff87d55e9fc97d518911cc867cdd8995 GIT binary patch literal 4364 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 E6G>@?U;qFB literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/DIV.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/DIV.png new file mode 100644 index 0000000000000000000000000000000000000000..423a4a91fc25a3a6751519a833059d4e6c169a94 GIT binary patch literal 5256 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL1GAS.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL1GAS.png new file mode 100644 index 0000000000000000000000000000000000000000..e260a83ce7aea832f3d0c3cd1823dd4ec65ac9ca GIT binary patch literal 3400 zcmdT{dpMNa8efcRNG>l8To9N=Ms5FRX z)Mgl$k4Y!C(u`Dw8I1cR#;7qfnMwAibN<}tIp^8WdCv3ff8O7E-fz9@Tkr4tz3W}y zr33riR;jL41puttv)k1R03|Fu?nElXb_2@I9rmO4xH@~s-4YB=XWpXgDtE_bOOwYX z3tJDKMC(|#uSu(C-|)ZO^O9^D+|{A%#k7OqP@pJ3EnQv}1b6^N7}8CE0t{{1B-nzH zl~~x4=9G+Kz{V+R!eES1K*FF|43uC%?*A)<38jPPF?rcNEIH3E%y~JBk!BW=$A_#- z)b@*y^6J*YF5o&xr0$eA%w>N~&^6afRzPVBX1!S#Tvw|G)9^{cJRRnsS8NZi{{oYw z`8KS3tEk3lsO)n$9IffYTwu%jqNUk@a+Ca6#5t$AT`sWSxUrvg{vgwC5Yk$HiC-aF zu*~q}#{Wok^AzHmRGyXcp)dJpfaIq&d5e1OHu5h!iC-!Ihg3eR17vddq?63l17#ng z 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL2GAS.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/FEEPERL2GAS.png new file mode 100644 index 0000000000000000000000000000000000000000..6dff4ec7c46ed24e487bb96be2914a919b789c5f GIT binary patch literal 3389 zcmdT`X*iqd8vYWo#T3(yjEb~J&=mQkWf21bJA@i}^fr8kAwfXLLzO{5q9Af0 zD3<^*5aiAQP!O(a0^0_yy9i(ly#HI6i5v0Ki$6PUCP+-VI&vTjWbqoEFM5ufiFsdT zzA)x01yUi%HTV7$Wbt*0;Wj}+hm(y(olE>eVWMAmUK}{1%$cMw)^c0V%OVF1!2M;L zUzh}@2;0YU5PP?WoyL;Yt&QJWOh@MAE5`wjQd0l6h}R>9G4FF?>~Z965t+G_Hh2&T z#(yqc)F$vryyb^Q2`{MTi@$CQkX*a?wpn72AbdiEYAmgRkS}pC7CGR zr|=@_ixr^Y$`MX?C^7j_PD*`pU%uxryb_^kO*w(gw?Bo>7%BYI)YC6#ssn(5%)eFe!V;>I-EiR(oy%g=-2LE+ zq6!j_EUPJjuGs#5@wvMTZs_FBNBJz7i`s6n=dwuLfuq)>Pa`^6Pl=Sb3>wq>Y4^Ye zZTx{vzP!P`Bcfl439}y|n+_1e%fu7jYGTRH96rO*FJiN3b-ZY#ggt#SEQoVzFti1N zotSKRNWH*nms&Xp$diuB1s~%NB(P9+%iYVNl}7QUw8;oH!beXbc{85SJPtLw%Rb>= zoFMq&tbE|yGBpx!T$lM^urep-u1x)~E9o~FljZ}Y0E>eE|^nRbnZI}&l4sS)8XKG=FS8db?tK>8*gQc zu=EtHEVEa`my}2N8}!81J-Y1P0rS<3I$BbM>J)ut2@qESg&ivVB94N6Xr z=cp%x{*~%OI$%^qf*VZkkgTBGx2>@EiBQB?JsMs5%2lMj(R8qDW2?%8>^d){-0zdT z%~XlTv@2t!QAj0=nKu>FuF@&%TX^RyLw!_8=Dcx=@%IR&=wi4sL3S+BK_BoN1pjLV z6gKrXQ+E7_CFR2O%L6fEgZ0PH_Pr zroW!W*5(&gfD-+Rl|%-HTr41ValF!-Ms@)}yq*e@S=syfy?}Ghs524##+n1T=^(ERz7_|p75zg)Jt4M!$A6S#VSFSY10m(r84^y`fp`H!Qb9;!^b?I4CF z)6-3(nuM;DM$N;yE@J|*sJts_IS$sgHqoL=1~N_ptq3ZKnJS~gZ}EX!+t|D2ZOw=z z&G~M1JsG|^FZ?2|J8o`R1vfEjT0HG#QEoL}mefizvDS2eTYLMqrw;jb5Ro_&MmK{j z9sqm?Jx@Q4!zM{2Yw}KK*Bz^aSWF#HpHa^+DQkB7U9W?lwcNrvs=41=!x8GsT&WHt z))Bnm-Myf$zS9W6ugWZs<0v2JA0C^3L|esW81iNO4!zeliVKG{N!E%bhbopb9phLtUvPOZ`(%L>O2klGUDv8# zdS~p*V}7)<#tPrFbaP@LPAmCzjh7E$Wd1?Q zC$S)6#=I4@tb|@YYwPBKFD`{!l+54cOGKeAw*ppFr|x^S-5n88y(6m}Wje}hHKQ4r zT&!8Um9E-^UK=RIhox;+Y*YRY-HtvUS?@3p$^P`s~Y+=LzB#vQxY`!^)f^Jw?vv&}$ z6_VE)*TI+eKc_Z_)tA(YZhWm%oh*Y+-a(|CM@|R=#Y2hhDlO#QbKqx zw4i2LKSL}m^0F^$*kz#z*FhHZJn&t60}P->+H_sT>*N{t$q(zPN9!&2Ew4ofHZ4r# z#m7woI9p?Gm35(31w!4hZn?-|(RF96H_M8W3Sf^*GE*ycuNDZ?q@wj*Gyq`b(;g%+ zUMBQ?1^^D<15hRr2BzedsokpJ1NFzXH+TPIee#d~k!%a2!7T_dbN5n@RVug}9UOW2 kZ&#K7c?JBx)mbY(ZqOfy-hiYx$NkHZhgT>;n)!F;FmZuluNwxkb$!hpl^@7$uY+2icgf*M88 zA2r0?e%&Licud!CDXK8~mUOVnvqh0o=Nxo|3ES4rX~&hDK!g8w*qFICXf;+JwIyw* za@*q}BYhTuWs8oB^%o9DK6!mR`bl^!0)XYG#DwbhO@6i^>_vrf`~~J6evTYyrK&Q$ z<&a6CT$R3JR)d^3_{*guG~=lpb)d{cEo3;r80l>lXB%z=Uq;rE#9hhl+^`YHnL7VFg1vpxI42eI^D z{F=s$jjx3_HPCM7mxWxFfh(d#WejF*l76v?W zU396uNK=O@vZFVu`9LF;jNAT%2dx#JpZ$N8N}BsIJM*_7$%}2dT>He`4I_S}vXb&^#eJln19(!(-<;cYm7;Af@9>_HsDtFm{l%R)ezI6u`APZ`HwD}E0N|!3| z=Ld|#dt2}--55J3wZ)%6oN5`iF!&%348PLeG*otKLZo#5T^?BM14*H@)=_+!xl~h@ z8)$}3t^k&W%4&}cs5sIQ&9XrU$Fk}zK|9Myeg~^RhvUD3onA;xsCp644)PUngBqz5 zOm#8KxW`Bcp*PwxMjFE6JO(KMMwI+8&LH_?=-V%GXSgUZ2+gKD3 z_+BZ-$oA@NLr32*caE@Q*V1lX2>Mt^yq<=NZQL1&I`}_%R39Prmk_UUN;PqG1+RNc zY#dbWijZ8A?_1tE1Nr~>9rAX?pCr7_mj}L>x)d5+YMib}8}((+G0Z%5EyLFBnbg!C z^0ooas(xM&ah(K!Rl(J=nvvVeNoe40KokAUymv zGua3M+Aqq~+?dw%<^)$$Lpp`*BZBKi_f|vBIA$10|G0SeIp1qezYbSfd5MGHctZtX zFjGk{H-uH}Y;*{qFX%!@RP9UeZ!Wz$nGr1XW+!}GjjHqc{8p4lrF5L1XT8Ji1xpE4 z{$^t7U|pyK#Z)36eD{gIVd3Iwr_+)QTao#{E36yhW z^Co-U)~7S(UW9nQA`c609mL)%sOt(GJn9n^sG_c4XeTI^0-p(AY$gHM9JxcLMrJ=sPb_N?X{1%M_7$Nv-@f?@XBQ=DHU!KAKOSDY>c zeBP+Rlf*;qu;Ga?=9!xlk+jGMobrfQMZV$i{GM+Qwesn8{*PKL-$LxSRR1pVz3!!GhkB1L7Lom4cju- z@2~}iD$8)zeDv0naQgRK;$O4dZ!7=zRr05Vx-pA;0XNeX{w%4_#Mzlg7)%_7{RLB$ z+?VL4^5~T-B5w73A$-zc!oYa-%Y5mA*1_uORa3oUMr(+xn|4*7X@8@K(nb+Lkl$|P zw-+*V1BklW?}i>rl=*BvbaGb$T5w{R%OEpnu1SFuhi*iFhOEY3vU7>4!Ak=k{;DsA zhcltqXVTY{Af9D-HG4nzbx-nRyS%`!!0=4(eZSO5zrB-eP3V0@MA3=)&Jb?-y}r4z zwk$pPqjN{*243U6hm*n`>y);qeVXQHe!)!pD*?{yhX>nKM_X0V@|w`u$g7Ha(Kt;! z0mBRbE1tCa6IP&i!zX#}w5rUwkM+J+} zurZQCZ)-vpGpLWlwRM*sJsYaCFE8W8Tt_V&jp6ccwp4`##b@9dJ>=9y>q|6zq9>WR zDiD+k;#LLHYfmz9m!H1T2YG6+8j>co(cHTL)db*i$!rkm%L zukzWYYW4%G@WhZl7;_IyuB5Y_I>7mmWXo37CX@rH2-0&1k7)LbZr0T1pK&$7FE^Zc zj*6wG-q7plNS8~{+Kk55(MPflG74>5?lDEI5qxxRmgHp%$3{wM z6H|v}!p-vH7EIwVAe0x6&%I+e&ez=VNzc9&Zg7=Yma8A1$WEK+PgFH6wTg|$fXUSg z#bW_*D23=k7FSAN&Ap-G)6eGba*VEJd~%@gs=>J1e|H(HXXeBWqBWL|=0=+GSJ%|Y zUBaQLb-!!w0nY;m#{zpOL)0TBR}mWa&kKF}ddZl+`>;yD6{pW-kx2Gze3l_EL)wKuBV5#yQE-N}LCrd*4p{z!U zMGUljpMpPKAJXF$mF6)NgZWTrQL3xpM_Y}*j-5qK$L*!}IDsWiqu!%NQcVO0fP0hH zr%$V88arq-D-@1<-7ZdK8C3_{jEwWH9Qk^%D|V07+(M1vJ);ZCHP`g)1R|1=3Me$>V`SQ_$g#Oj0K0n-Q++Le?s`b&U zOc5h@(8=~jtfQOEHS5>B1!~oFeS96r$=b-M78&yzlEUlKg1R!Ul~PHBtu2Yo;(jX69~-IRiHI@rnDO}rDzmVFH_xd+Zn5V}x;%!`@Fh^{ zVDV+^(nLAABL>-POCn&Hp@{qbuDfwe)|oa{KzIQBh92H+qRF35xOulRGTXUnkRd8F zXBVwCFwe;hmc&RG&jlWv;V{eDFCw=3TU>v_5>p4xl`PX5=P5|Y)O4<7?6GY4womtg zSuoL~_){>W)UT#?ZFGW};TCSGlUHxtbqqO^jUz%ELnumtSvI?9PiR0(xlU*?D= z6y?UFF{w7Zx)2F;kY%`6aujPp^+QXx?ksqp@hm`PQ};YvnnT^ifmW)Dph z;A_L~pa=o%Rxw+~!3Vlu8mK~4H@-MSqpfohl4vDn9j03GJC4gPcnFGv8x9k#w>vf2 zj2CjRSPuMQlPm7_g=s(n3ZW#BfEEJA7!i^{LXuwEdFEH=nR#aBndj-B^WJmsJ>R|G zd*1i^&gVf#{Pp#=>Hz@s4;}Ok20#k~UH^z&2aPs{{s922#~kwY4#~J9o)mpu*1lz3 z(C$%*=5NERu6?Ej2%qo|hB#qIBW_{Mf_Oe#EX@wO376o|TIB1oNqq=G!eOvBzp@j+ zAm}lsLL->g#XuwVt(Fx8m<+fP1XgGm5(1+NpalUk@Q<)eB7C!M;zQb!QYE?5WCi^` z^(?=yTk?`$QgF3K5hK8wL#Y7kWlv7I>O=-**qm(;m=>I0NtDgQxEN=H!D zo;L+hN`Y!Rp9SlXR@b0 z$J(m88EZxx`gkyt>+|PIhS^&!HzA`8v>mja*971+Iw1b$vk|GG!{s%3y!a0dsC>kL z4PmkKY$j>YrS%FvTUHV%Q8&qy>@g@R`#xOjb|kje1OeqX{8VFltW2 zg?8uE?1g;Ydl#-XrJ3l1bp2u@w3ARNc%&6?jhj)>P<&!##<{eWE^&BRJiBDoh8L5Z zL?MZ6o%XbbGSs`}HQW^Vz&A4|BEqgYTT~ftwld!3F&!<@jICZ0eZDoR-|{r^bi~R0 zGlmTpWwsw37rTIOd8IDf%#UAR04gLVm#z9Em|=$aWYw&;238+G*L~Jx=6UN4cPXG}4jL;*n6_%8ZzFl#-}f^?d=* ztCn_{gy=%YNaDe{`35zI&eFEZ9iCm+n?cR8!vOa=kGl@H&K2x`q%#*+xG-#Dcs37c zRW&kpRJ#eiyaWL^VCtmibI|>Vl{f+vsO(z)kYBW$JKlp4xMvbaEL3f(YUAI{{f(l_ zDU;}>xqa0wF4i9BJeqRsAHUAhG6i#6GNwK6`=Ox~L-E zk2v0$gUY!{w46j=FFXyC%#xoA1yiF5Oyiz+nwBUf~5Eqt|K=q}W=JnYn7Ri2aAZ zP-H1x@4x9`osew-Itn{4&FYGD6P|2ij{b?k(**zxzxcXTVaNUKfL+zW+$GTSy;CP09Su)WLc3xXO=mEb7!H!%_%PfGx2TLy_mnn+oK zG%!Ul@rp!l%b8I&$vRpz%;=otmGNTExirQe!FvEiZ=eRvP@IPCs@kKw3^FQCiJI)S ziMW2xMz(o)o)$q5q7iO$L9Ng%OqV5pp$2VvijVFey=jBoVRF;rB!-_wXM98desU5iLURQZ!ga> zl>k`~%;#1ME8nAEHX=%PTYMFf^6YuS_IoOGlP4vtPhOfm&a}g{PgLNdvP{GTgEt?s z)WLPFrZcJF1@BY0Ws2zxR|H&-Xd@5XPwu?`q&Qvtp-w|VoS#idQaN7lq<9gtsdq0` zgv319%Ps!Sto9jqm=axxSme8G@lbZ#U)^5a365V3(t|XLW?|G?^TUQz0$S*Bh zb%@A4H~Ksg>o>tH;umwvnmb0c0ktcH8q}P&Zq&PPA}m`iC=Q5dyl$ad8rUyG^W`it zXKS37C9NFz*Ty5-^Yx6>!FuS#HzIt;^l^3~Ovi6*-g%)T+AQ#laJtBZce8r#Zf(H7Usw$A`^)wrI7@)yO?{zPDAPN$tAs!Fx42 zIF{5UsZXKL@;{2lvkFuBT&(jq*rEaF!T%fOkt zECirdKpsE)Wwpyqh&vmol}})YU;y*?=K1@l*E6|_cf0&%ztNyjDoa4HuoWiDpe6{e m%x*M+;E#B&{a+rwRfwy{$T6j#jmNDO&qJRa@on%Sna=4Sb7tOo=bhhs-~HbG?(bXfcdz_# zc<+j3ddmO+EB5cRcLG3#1mR!RRG=rK|C12_n&SQTyN|`@P7X|_-o2-%(&p1KL;SU6 zt~v-sFDjiqS9kwb)b^~vTlb1VBJwE5A`#MrF110&arkE#W(?C>LO2W@y#z?!NZb+t zPt{1D!TD7HwuF$Iz-K+RJpj4%MT-p7mH=AkfA>e31>IlxZ>CJklPjZA{JIE&OWVLt57vAn#|l+JUm|J5=>V%Qj#QOKog(*}XfTld zLhP9_RZMopVZM_VFr9Q+gpp2m_s!&r3r1f7wj7wYw8HkFW;6$SM<-yj3Dc_J$gOlz z&LXFp0)MOCNgx`|>dMcfamRuNWoKER+^_WM#i>A^$LPlp5sf=TcqNnaeP7DJEUPx@ zw#SwHTM?YH=nbw9`ZXI)O05^%h(N2!mBEtef$%h6xxWndzBf?#1#ZdpASyKT?(!w* zz2*-^k?$&W6Dvs{|L3@;gV<=NqFd{D7PA|gMLt9 zrjR{Z1nAgFUjraLUqT`r7c3@tGBmZ^ z%JOCkZ?$AqsJDt1rY_CN zwBL}atj6Heo`1%@5lmGh#FkM~lg3-viM^ndlIYtJYHv~bg9zoD{f6I)D0_7n!o`(( zZ^z*6nmTTN*6Law%2?Q8w%0eJYu)ww3T{iSf_2BXZd6t?lL>(JAg9VF0L6x2RTgXq zDXrt(a=x2^7NzH4)7B8LqnwU{il_tq6liTL^8UP@A5Y2b8qGH)dkn9N7^z+dl z?j?!_dKNej`Xczz4NVqbqyc1gpp~JEI~U^drhX$P>+a388;pqMrTSU$KuNJ5ui>mfH%WC0MeUg@O~{*V`1Pn`=%?GUgB#313y&K zBej*n87#yZ%(0*?BYoBA4MKQ^(WK$TJ-w5E3T*`00%N4WiA`iF00RJ{UJj?VO zXcb1VCS#`q9!7|^?{u$Fr1o|!-%aC=1Q%!W8NWq9t!BR`@4hqUfTf3*YrvMmM&dNTe(uNCE9ivRr&KG5eTu1Kh z6fg(nPd($u+dCzPbPKoAh86R{TwIVH;o+}pd($^R z*6pDR3ezEa8g!ZgJoa&gc6iJwI0#EqGM1nmm1c#3JejQ=Vy+xgCi2J#G8p~%3JKnB zQ92`Bjdb#Ko2KZUObs+}m2|wXMy^vvGx*)cVJ^Ufv}>PX?Kb$1qDAa>2?|mml|oZ2 zsj9Ix3R{IYBhPps{WntXE@F+K0XivDngEmCeu8L<__JFJWf=i{6Uy{lf^9)=WanV$ zt=rL1&_NgfnFhMhU$5RlAva^DX)8ayRfo8VdZuAOGCQzqt^Z9JsZ>g3hYy7p(^6d+ z>l^k#>$qBsDA}cXC(h8%xH=osN&cF0%(}-TzJg#yT9pNBET*K2%a%{nV)ciAOx01d zF3V`G%!q)Nk6S~1YE*qy^^*!5eLQ5~P`l5(h|2>YIP3aZvIPLIuu--J5uc8Hr6*Z! zrfUKZ-2i;r^HaxCwMuChx~e?KC#qL+f{CXwF)y&Xv@uTmpx4}7@QUJ~ROS$el^B4k zZK@r{0?;6))}1*Pzc^f{>74_TJ?ituJa)g%lGEJpq_RTf#s?7%l#uwc$j+X?Z&Ph} z^y5#ijZ<62viWv={ahr}tf2}sA`FPkUG{s_SZ!`~%0?;0}?1)9?jVult(wH}PyMrt4Ol zkB|25aU2WLl66gNAyspl-MRHJoFH)iZ(EP=e}vze>RMaw?p|xTXL4*+{0W7B)m7Do zwOG=l{u>lQejD#auzy*G=wJZN*+c|O7QJk4pSyIiR)7Hf%B7jp>`$f)9(KFkc7tmN z_%AikXR2!W7Jsu|n_QaF8&`Y4z^-15Thq54jO5fW*aZ3xO%w7pFb2RULtoV> zG=2nK)s!7=xdWkO(ByxQG`? zGY)hw*Ygw2Sd?^ZN>)4l*nxP!NCIto4f+;BB5^qP1iU>9X5Zeie%i9BYCwX1*-@<- zXnn-7bzM=-WcT`gp~O(fF-k6|ZT3Zy>c1Dgj%S>SijpM1BwBex3{GV@H8F*cZ7DmQ zE7u`|TiCH;Qqe9)jaaHVJLmOTT5xDmsNeOoJ>e_5&aLfc?{>rA8Wl;SR(%0x-9o%P ztq6~v-I!wEz|(C_%3W;k5G2=&hTyU1b#W69>3CN?vQf)NbIVCWD_Yo0UPh~^$cZ2F zV@UdoZJOflqE4urCY%X^A2BHw#70~bD}dtka&gw z1+mRVUE}B3`nD+aHkj5msXNj(uBl1;;N=SW%APl0HT2iYJwq)y+@_>)hr;94mw~JK zc52!B@|tBIV5Fcf>5!wBaD&n1~yd|3rc(3^;`-Y}GVx&BqU(>!-%`@Ip( zq7QN@(k6y`=ot%HBvFs zW=U-GTO;**$Gp#-Seg^miDAd=HXT*KNbNdMGe+Jtl$)}s{0{)|s()v1_&+~X{)gw~ aVPc5W5q4$Lg(@Y}`@cVIPyN>W{NDkWN&+DO literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/L1GAS.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/L1GAS.png new file mode 100644 index 0000000000000000000000000000000000000000..e3236ec81c5d1690a825d539e08e0b4b79aef26c GIT binary patch literal 3415 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/L1L2MSGLOAD.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/L1L2MSGLOAD.png new file mode 100644 index 0000000000000000000000000000000000000000..cd1607fbc8225b88d5711cfe24db1b436c82c804 GIT binary patch literal 7137 zcmeHMdpMM9*M9~b=s?*iCF~>#TlQ2!gZ9=qRZf+h#YQ>g)S#I#d$->=atdR{#9-%? zYD{5dFsKwVj6<0khmkPDFmjq{jNyA|x3|5&Kfdd|uJ^j$Kfd?*<9_b-JnO#Ky4U?% z>t5@5;%(2GZ;{z80|3AlOA9l5@Ma43TQ;r-+lxP3ZvlWk_bts%o{P$!?C&k@RaF2w zYzfQD!$@UAyrl!H;a#AoPKkYny!V7>dGz}`SRYGWaO58s8XZF}{exQRG$=^hu6voPTl>4kEBLlWNv;{AnnQQRF}OB$txP`_ zi}0PfqAJGO5r`V_8)cViZ~qqms%A3wDXK|I&B&kS(zI@lhbl;*ALG^1PuJ0BnI_QA zC49#5IQ%3zlu@7PA5>sIEen0`&j#OgEaCg{pJOM3JIcucE{x~2Ar3)>@jP*2Lg*p# zGh>>3YJ+S|e_zA7X;+Ae2`10ey?+>Ny!Oq0j2q=5sogb&(sp6ksg7hy7J zS}fdWRKu5i>~$-f#e5^fi+oc@j)g}=RG5S74h&W}4cdrTlN7)mJnk829$LqzH&-(2 zxgNgdh|)-L>*e;^*~k3YT_;;wr;;V%so_g3(Pkv3d&zCn3sDT>tD9Ltg1)jy!!9I$-LF8lgplB}m0C@JErr0Kfl zV6&*t-U0Ao^74z*a~o*S69;L5PFRo9e_Z;`gs24u<>(%Fv~aOLRW~y=g3hUIpS?Px zCpoEtwkeIp6Cz}R#Iv=M%V9dSi3*hOZ^RYTjgB_lYRMc=bs{ER9ggxmkPB65*gOyv zGo>_D<$26Y#kWWdO(5=S)@$HYguY`h;Ov43%k!JSef5iQ5iIYOOr#mf(gFkEn7;!d`0m*canO68s&I%*B(aQ&aANTtd zDGo~$|NoA-D^A!q)!TJIw|`o?Hf917PFNpi{2ed^ss7^QR|cqW_u=Q?fRU8Y%hFG#hLSQ*9+rk;;z-Vk1PHuPK(YH@XzkR-*t^%0nNc50V6MoyQxs7S^vib6%OAIb6}DyeU;;+O`jjEkWH zSorUn4jMvDLlfMUYj=H{qCxf#wrLCdl2&%k^8=eMy zs+4Uv>`l(O8qC!HVhth=#iqWIUnO!p*WZ6ez`xh@;}_?T_+#H9qeF%RjjFo_us#$b z)$j|PGfyR;hIrGf4r~hBo_FA}02oe|x(AgF4@<|F2EOQFrHqd~+vYbxCP7)PPIN(i z8uIOfFQ}R;dP@!cYW-?3FB?>J^vk>MPf>sxUbi^%ba(x-JoIEnN9C%G2ZL>l>#LuC z-H0s3JV3%)(%@K-U@4-tQ^{kW9Z*%9z0}x9;wsXRV~wDW@Rbzb7q*K}9*%EqUIZx$l);szvt9 zj-Bj7T1vz+n{SRmKE?WC7wfY{KdN0_Rvaoq3>^ThGG2KF?BoAf7+sL*O~{mNR)^d^ zgZlYpKfd12BhFwplCTf3?T!rGHu=&EKr6?U0IHRJb;5CImXFg9Cm586TWww$`u6o5 z7?sL=!C{Ns7y6asvMQ5elprCw%xH@Wr`uMQHnb;aXb{XD;N^q6YBN3VQ@!jLhsT+{ zB**fZ6f9l3wzOyVeq!1@qtC?r=irv=ls;kaREAyk04G0Qf{{Hb-=32~PaJ&8CuB!` zq$O@LXP53~FKe-z(!@>y{eawg;;l`n)~6FL){N9}9gU*ff*MKFBMTHRxKBWM=M+|6 zA7W~9PyOVGTsZJX19IEJ${lDACHGNr{>ZH{$ZNisrtF>X)G8@m?>n8<6?)3_hZ@{O zvtmIX0zQz^VBqKe{nb$Ai&{`;d;VTAX7&&O)uLXQEDWY{cSi<0>Fod#M<$}PFN+5` zbnJ@IT6dA&$*JkHI-rT;o>6xL?cm}~_{!&^>l4e4?wi8nFac6(DBZ4&TNk=or_SGP zycQusZtMzhKaE-9Q7d-l(cTUh)29Mo>Y200mD`&Fcqd57Ay8=`Y(AuIX77sv%mouv ztbj&)VZc>N&6GjMA@Ql-Yd{SBjol3P68YC)JSz%-uGOHl)Oo#EOMeAr<2#YaC;n0gHtoV>Q`Z3s!0 zIv6pM*qk-{Lt7*zw{-y4`%RO-&)s11&)NLc@E?hA7)cuk9Wv!%3T>#ESRej_{O^-r zKf)gwU4)1aQKq*eq%yl^qlmMyW5Vf)rNB-bNJF|6>3lt5GTlW$^y4~lol6VcLG1b> zifoK)`q(V^Sa2nu?$9d`-{6)YMvZUA9gFh3BFZjwlT7rQJ6;q4b7|b+k{naqx3rMV z62C@Sp>h+lfL;H%sC`yNa}>DGcI3)*r1as8!pcK&J`|sCb`$(I8#sy7TVWsWyAig0 z%DKU*7U(whBTC(33L+#iM&a&l1}YB640FWNz&zQ zOS5h{rRJDP-ZR1^a|)0%4-P$DY9uOj=Rdn!ED~x>Y0jJWNtu>(e!SCFcUFaRmIj$? z+-#d&cGSzNy)3fZa;BizFAHfO+?4jK`7ZO8Y1gz4iUMOUf@kzG9u%v@9l2YGLmHns zz0TB{O0%FGbDqSH1hns`oEK!Xol#s}#Si>sMNR9c#DW{ps}donbVE<;_=yUshOljp z7{fg&ee*T!SEiBuS=+#vlwjxeq#U6`ZMqggDHd6P!2~=R?A%%~U8b9j62tIYmvu>zW!_oqqi(B=PN3prQ@Sd|X&} zek&+FQ5~t|Fq9ml`8i=P^woEQ>57j6T*F2C1cV{{@e`qcx6 z(~9Bt(KsrCM8O$X{B&XcYka6Y8U{<;=+UJ+)>@gt%d(i#>_62f)zE#f(JOy`42;5P z4j448WFd`jH6MR#eg!pNsDnN0?L0mngY>9xF$vI3THY;@AGJ6=co|$ zA%n_P*Ye?>@@sn<&jBIzM3KrAJ;&-5Pbc-_OgGfI(gqmXL(P?QyyHFh5rU4|HxFB& zu+0|wA<2vWU`AHK*k*j{mM9S{$lWFj;1s{2ST|!A{s^v50@JzKp!I z(O5uths{3|#B~@$;sV~p++$ap@B9EOtVu+k0OTAW*0E891&SZIeD_SqZ8vICbE}y5 zSBP-pgS*g(C$?|8|R`rHR8~|!h<)+T?*hdX~l-l@v?UJH@dUXbbo!Jgp zvgWi|{hONXp!#Z)aF)Y%{rD`v_j_;c${l+!-{JBrHtRJ-P=Pu;80p(1_5~0G@12y| zjg?TkBK-Lq1&ENtzf7^FXJ=~|spX}`<3eQ6Q)<4ppev}a*MwX-#nG>_<{A73cYzFn zidxZ|P~6rMdIq9@z?jBB2b1KT+ z;qIqvPu+b#-w1;_W`@dpx>6hUC@j`(ALk&}+xb2{;KN%MERq7oi;PF49pFiCfJ}O6 zJVKM0H>25k3zZkn>22tcl(v0jm@bu?Md*7FJ`-jEb2Rsl@h@Ooa7(DX`_Pl*yD%A! zM~gLComDb279N`r9yS*v12|ts5YA~S+&TodsP4sV!$cRmTbSU385D)J4s6uZULt@C5%L#u^C#f7Xc*5Sxl_h_4vTUB5H zZP-C=^2%iq-{U-p9&Mj>t#S{I0?0J14}PKTS4>y1hJ`QU$kBs+leE^*NU|OH^(g$v z>pcyeMiWyV9nuI878eVk-~ZVx>M!9V_7z;wS3*}NZr*D4!S^80aJ_Wo_mml}u=2$c zZ9tXZTIrsXeg`=5jIth3O$qo?<^e$7I}P_rE@cIM-VUq@<)LC60y^9Cye zoqzTJgVpNy=*yagb2W&)Yp3$0muYvO{q;!n-+n+aD)1g_`Al#8t0MpV%j3Tm_`fW` ZHPOt{{iQ22O9tY literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/L2GAS.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/L2GAS.png new file mode 100644 index 0000000000000000000000000000000000000000..c102ee0b00c02bf79814d91f97ad94ea0bfff3a4 GIT binary patch literal 3389 zcmdT{XH-+!7QP8p6k&8iQAF$#L{Xk75FwTU1*HjOObF%Cgh-JV36fmPATuh+s0fGz z7ZZ`h00JTOpgt*5q9_3Zgdjo)5TZcHK!m)@y!konmHF}3n)~DIv-T->ec$=^-sk-2 z=HjTWwLuF20PRyJPj~=;DjMpyYN|u+HXX;)kYDxGiKCvEawUV4X}MK;>ThRuOO-8> z*==WIk%+xb2G`g=|Ed}5T(KKSEQK@vhCGLmjyrM%*7sB)*&lky~$xhN{NZ9BCBSFi&!A^YA)Wgd^Ft6QU|eds&|$s$Sawsb zgu+fzsAfo5Qq~gOL7q%gl;56|2e>38WVOrD#Q6h<$L@G6o+C_B71xhixHDx7X|NOX z(>*exz4>zXM*$^x$=9M;(^}^Q{qje?@X`j{Y zt&Fq>7YshV2pWK^P}Y+yZZg-Sn^m^*Yt+VOEt7k+s%~oO0$^h%ayipjUA+BH_IbI* zE?d;;F$FSJ#lHOenyv_n|4y8aN=m9Ag3L%~`!)J_f{oX6KkYAIB}7q7YU-^bH=EFz zmCV6cxl_MFjQw}Q^O>5E|MZZvz(pw;w;Ph%hrUw(xYzf861DShM?YXnn~Rm(tiaH* z7KN?eLLRJ#yWWXyNJ0qpOm|4AVPQ(3@q$NA&GHL#imPEKMDMU)%m zv)N3giu5%W7&04ftwlT6hg;xY5_C+9#(8rk=fi1?YZa)z|t=1+HcVfwysz3>Nr7aXr8Pa z*73fL&{O{UxDQ7pnphQDao*lp@j=8D%&-DLQCG9dTp>JYE2fS>-gmetd;Vl}nM^Oo zLtVGRjh{whAChboR=F>By7SfxO+7(Xj7Oh4&bV&|QO24~9G&rZO~>>W4-O4pT>^y4 z>GAa|Kv$u6mc|2hThY6%vo>p6c3!^08j>;#uc+*(VH4i&8XC8bh3+K2n4&2R-ZBp_5T?-~ha@X*dUe;>jG z&|x3aO+e`S`#{6wmEn74AaGF(5pWg;|Li7ZkO|j$Y)b2yl#xbrqwvcDn}PZ~C|+VAO;{zT=unm99Ef|UqTbNb1&=wKMW zu+9Y8Y!mg?y2_`=U=AigfP3rFXI`2=#}?b1=eaaDFeTWTL-v+S8CL{-vVn(=9W%H{ zYWUXiE z9mH1O`;L-06n8hJgs)pLr??&6C79K#;=PA)yC?KAm|}w2WZIlHA+SKNjqn9eU@TxG zUBOySbZb#4ZEknEHJz8Gg(&Aza$&2YQ#PhWsB21jW?NROv{ihmfdDa zP`HP-y*-JB2Np4bx`K66ExqG=F`h{JGnK8MH~9Q?->BEw#V6eeMQ~jtJ=)_@JSY9U zRK06yX`b&T2FrSgB#zZZi71uPQ!V>S{SXO8AYbrnVv_h{jpLr6TM)Bsq@@CrygU`> zRzPH(axIWJ!(9z95o$tqms6?Wemtv$Q{ocLdoEz0o?Y{Re z$2-{S0Y+PZ$0xZju49G|T;R7`s-5YJH947C6WVn>!+S#83b2OXwGzi3^|vbtrT z2O*&Y7cjTus7uSI#Xx|xewImT-hV{>xOwK6Pcoz705Wk6si)YjGUt#*S`NDjpG*++ zXDol3ZV*i|I@3K58{_wZwM7s>@lirpX=z+MMH2pxJiYhsp_06hnf(b7hK`xtgd=_> zvPw45i#cx_8A0_Pijqb}-!BN}oAb4zIeG|?=&79+eSi}B{r;Epu(9ncF>vbbJI0n! zos>Ma7)}@PkuG*V5@yYOu=K&{PA%OL{DL>Ez>% literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/LT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/LT.png new file mode 100644 index 0000000000000000000000000000000000000000..296fee5bffd382dc6e7f163425965304cecc682d GIT binary patch literal 5253 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/LTE.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/LTE.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d827599fc381b026560b0527f07d6e4b02be26 GIT binary patch literal 5265 zcmeHLeLT}^|G&n1(5Vzhl%i8no{kmrP)sLbgglprIJrG!Botzs<#Z}{;@n}yXzMuh zP>qV25nCmq8l{NM!^y+SFv5n}c7Inn=l<({o!9Gr{eG|4@AtYte_Xr1pX<6l*XL=U z&-?pLKjP}JX4R%u0Dv_pM>`Jylxn)Smfv8l$bQ3& zltCv-Pl8LmIpJw=&@CZvOcB^WpiAc+VF=L93@r#zas=e?@M~PG?s70QG`8p6_W6_Y zoEx>&msPA<4%)M+77mZq0b<*<4X_n7?vri$1a^s)q3f&m&;f{-oBEGDbp?=I=`)3u ziZ938p3E*$%QU#bFF4kOnvW@xA^6<${JS7L`FM@#q6y&a8(?5rzW+b%wN0Qsk zcGN1erbqHBpa{W3HTv%}H;dRxc&Q=tqY1O2Zo=eR=wisC;*8to#%IE&xz2~{!2Rez z@l)#z*4&Dbf-%I6dSyJ>7YZ``&BVkQLwQVasoS02ktal^YGf6UMfv~BjW+ea` z=gqAVH$toFEz0(%P1#Jf$Cz&v$i~y?x>X=!C<3D?16ackb&PP1D0bW60jov z9PG1FFJgaR3O;!CpVk*|g2%$!1|h8iJB|(#_oRA?X@`(DJzZZ}Or{Wh1&68ny4;0J z9q-y8nTvq7e%>OH_GlOWpDl_`9j27d!U#Re45wCk$)~mrC-W~FU63bx48p~e|GllM zp3b0lux+{Q%a)lPlw16uV+txuC${SU&sY3XQs)-DpNErd(ZN3qX2k(hpxL^{_ll*p%Q~n z$Q)S{-`_?b-3UlFxiCWT{N--BkVchXy#C>_%KhU0AGFWM#qD$w9Pb$6;6&=f zR!Y#ib&6G4>yi?k_h~J7#(aPI;dN0icteiGK6j5_Nxr(FnL?4IE~f23fDXH#hVEJ9 zMaas(gHE$}A(?Vh7QBF_^WS^qIVBJdEe>z_;=*4c7e+bi1upD^7Fe6U9RCesj#=bi zo;3=9xC5)daOGR?POg!&$nY<$VmWIL$4@|C>!ioY{bBM#?)xJ|IKn6I445PG<<2^i zW-0%7MBaz*fPOyHUxbA?zr=wx9!}Ic@KQqtLgFM};3wXu6fFJUz`C4O!KAkE{Nm0) zysn2+6Y|L(>Bc+=+ho`;Dt;ZpX5Pkl{qLg3(UP+(@FHhDtj%ZTip9v$gM6Ia|8m;z zvJ4U2wSPWRD(2XI-1&tGY*A44fZuw&(HfBnTez2dI`s^;t#>WZ;B=2py3PLR3K=w% zd@#fFry3>l8Z{O^aGE^&66TYG8}WFXp{3CbrYJcH6+Hi};ZrL>d;Z)CFt9mR)z)7h z9~&`V>}T?5WK_!L&ZHb(ne34>s4mY*s!>Qp?3;eC+i*NCJ+(7E6_A4%qI0nwR(EV!0#+jn8NSXFMZHT6{q zhk@j+QW&ss;KJ8s!x7SZzULuWDBEu%LoAm1J@=_&i2XT)nqL=<bliMp z28_U%NL{sR*M$5aSr)s@qry1(nl2)w2OM4|s~X`XQ6)O9h}gmb+6l711GJQc40 z>`E%6_M|R_;K=1PoY`FYmQaJ@!XHAnCQy4z38-V}RHW0Jo?6)PZtdBe*0KIgioQ+F zxylyKGt=yZl#1QqB>(1HVc^*NgM%LY+J02N=2X7>=v=N%f>F~{r}R4ZS+A>##$;HE z+CJvCMy{EDc`Z)SR=Zk$b$Rp(uzzRbvVsjzKviu6QfU()wt#V;gyJ%YuNp*)0%bwG zP}YFyBc@S{hH@)m!=4oSTFs^+;@or`zy}WT zPIK2bDGWd7)Qp&zA7!is5iP&S# z%df=U?WPlsEH>J}`tFJ}68Swc36XCK+BKmvbZ>{vQC!wUo;4C9VgM+44yfw!=AC$rDLY8 z?e(r^2%2AkoPAV9`)+&y=qv+G<+N2+ZoaU%BHZ;&vaHZ*Tsn6D?o$(EAu*hy-w1SO z_0B^dd8%<)PYdrSHG9hHxLx5n6rxj0ck95h^cLA00`@K4g$61T$*cq4v7jHCH{NMH4U3QD$Mz)$?9K z_8KOvn(}}_zaZs!{qJquTV9F30ZAoPhT~Kgq;%iVD3&Jt`?ric(U*zU;$`jmtAY#S zgvGQChIhRa_1%AuxcL*}MKS%JMgZwJ{= ze&s$0z1=>^?jZqh_TwlEDJ5AByl!5+WN~@KEfK1WP+|Od3Wj%oTZ)%#ke4UtbhXod zck@-h`+l7{Y!RiPafiL*e1L>3b=}kaR+9TJ6WL4M>s9IZ%3tJ}+#f@Qciv9cNKFyn zh-A2l){@N=uhGy=TsO|`p`>tya_?>X!4dmYn61+FGGOasCZID8EsG-=pHeZ03Br^d z_l|q-uC1LJ?2C^VC01qSJ3ohoj^+0JTw(HDSux|c1hvLacH?|XR`0p1>ocKNRoZF2 zXe3I6(q+bohr{r+a3hw!qIp7%Ef;>z$fd({resWy5~Th&`?Fz|uBBzeD&^a=WClug zRPM3&CXe~(=plK>lSlDO+Z&NhwcY#qp8Wl$iqfiXdDstX&vIJqa^tTBh~k)SZ9dy> z*l80on#f;<=GmS4(%T0p0Ph#o~@m z$Jz17pH!dQDY8G>_Z%!eWE1)8pu&FpGroBXP{~{X3^Nhr-7*A_{%eq*(UXG!B17_< zAo4Pxktwes14x^{f@~y|b-SRZ_#*KsU!yi)@?Kv!z^2$k3`^*BqQ#}8WZQW;+V^_m z4PwX`HES`6e|clk_&QOpDgf!GWeX(Rer%WWb_D=lk=qx^1xzA9o}KwHLN>&G!tmom z_4p%`&=3{>jvG3JWzgEFt`Ufu8aSqIlh1&c6i!?|laEUxk9RIXXyd1^H+(IRbTy_T zfChE+6UBl`pyMG=MPO@nEhIEsSY9&g$^*?o<8rur7?;)*%EV|8Bsz^AgEjxKUAXEy z+&$iyaIrZ$ID6^W$50pm1=-~-kg+A*VMM#IFp>v(k4@t4Y0)1sx1?TAjJvHw6#-h= zTWU+E5{Q}25<1mFG@NRt+XvM(=&$Uo|Dl%F_jfzaeO3@{k91YZWvH!eCT@j4UPlZWKe?<_&^yZ(FML_xbZTN8Xk>_?;4fo#nJyl`YKNRyVX_I{-pPDqd`3Y7k#QTRMZ#L?DyRuwWeXZC8;J zI4->Z{>|gH@#2}@-K;~A%WWqugutfuhaT)q1`>=7ZkT|}E81Ac0@}OsI3)lYyL_Ha zjP7Fb`D!@x*(~mL5dg6ir4O$puvT<$E*QPQE=`$> z2o@e0ZW)?vcalYwK0@sNLiL~R)gLDN*A4xzgG@dPuROOWisSfMH*=QMZRl@k?i@9T zCl4&hBoKHfw^-~-6{t(@Yxtu)2U?Cn)nu`T>;Gp@Qa~8h!&TkMT@i>MSm-6SZFZy= zx^uW;oJBfcmdoLSieX6Nma?-LQ~rACNUNsv7au*LY!?zfGhM>)h@2VlQk3XOqR&}3q_`ns(Rvjl1`p3K6jq2FQhQAR zphuq@@z^ksu@wTwa)3(Bx2t<9=XxIXyZ_Y3<5pg|5jFIaUmSrAKxXNwWK+q)1(%Fj zCLTHG1fisAwEw(y!|bqa$}(eT*-4#CI9?atT-?8d8mViEJ|@(0thWSUpejSlW!Ns< zGgBF8GACq4^3?h0^&77*JEpWxYq#q)5p#DF`r>Ss*x zRn*P(U1&)Oj0Dlbs;wrV)y@k*90o_1ruzexz|A~aHZvU1pP$^r@RX2HY%Eogl;ph$ zP)&gAmomdW43U3-m{V@Wx9Wl8l|ieoG-JX+Q0LsOPXCQMWv+_W7Veh_MRsx}$Rv;jB zyKvfCQmpLygBQnt>NA3=5eQ4*fvO#tS@g>*n_0Lw9nS=?_yVK0_kDakA1GY6(5 zttRPcJuk4@=S&|gbI)Z>R?!Rj?GPl+C2K<{_z!oHNFzOPbPAS zpTdehDaG$nHaxEfKl3UPLrTH|5cam@a0>b3x)q|W+kvJxV_O11Jmpt`-*UbCvRoz- zn(k(tbBub2HX__)&F60xY)Gyb6(Tvqsrtkt_2RttiOtkgnbyhU`tg<^B)fSK`psA5=|VM%;;ih1|8L- z^Jl{Ng12l~W)z%~epJ$hPZ8k6bubo;(bA?qSYBM3aOTt4Q`*FL0YexJ*# z+nM3HB+QDQ9}N@@V0N>b!p)cbj$$IwaiO#~SF%t%;oNy5$MOx2=I9j$MHc$F+2vT#uJ4yV=u@4UuB! ziB-SE@dNZLHpWu%c>I_ZIQ=&i44r`myb5spMbIgFA=;l)`zT!AuaPt~d8jlcb-wZ{ zwC1S)6t^=>TvPdS`w8zVm2RK**xELtQ<)jatmz|X_9U##OEy*Ry@eU>bWP|~L!Pi1 zgU}e++(8I99-qsEZ0^Mz;&@*Z7&+PQ@A7Jd0_K?%>%SF~-InEOt_m9YgMO<0Z$JJMn{d1M`^c*PEO9Q4_De2 zH!=0|t50@sZeJhTz*lJF5Cpmec03drFfKq}Rc&>2X^qKXJaw_C7S|lTVQM*K>06W# zq5Od1*H)eRNiej_iXg^VEGpJnP(RXJb`Tc1y6zyI>d?{|0~x#vO}}4lI?1Vl+8jYp zwXoTXy}K-VG3^Q5PDjkJKK#bQ0(0(A>4N6wxTE`n(M6@t%)+wEO;18Xbm45159+Pj zUf_dulQa2kQVM3KI#L0~oR6vv9BSI69bT7h%8&ignmfCCVIF>~uM*7?%-^4^BFDsp zI!wWNuXX7|Dg*T*C|EgvKDBvQWThzRn-BEV7Le!(*>|nSIl}zdVCDSjBfm%Q?}G_> z{jbqFlXG)y8fAWZVupzA(t~?@33rcQb+2M_CZnS9^{19ByR=xoiJj~nCputTo#;hc zn{*ApWZ5%vrhZjurcKKgELd@qcBSnFy5p*kot+G_Xz{TxysAf@<~^LB*puqV5mw-l zU!5%j=Rb-d}~~r&7rc=doqN z^~Ty4bl#!nF4!*=w7cXH7$oQDaS=Q@)}c1DsRWY@SX=zsHyYO(ke!x$DQMhi&jSlj z<|&sgqV>NN_GtyHDTn1+@#Fg_H^iXTRicL0vn%VwuKuv?bJl9e;L2pF-LZC2tkW^8K{LPw-f#MWTk#mM!ot~#`##_2dB1Pe z1#_eATNJhc0Ja;SGqeOi5)#_)Hc1Mv;)Anl0LZi$8-8yUn9dwx#%7htg0{d;wxF?j z%}1v~jTWILIW~{9G|e*BG(R(Q_i6eGvx_|8QsGagp3uGLi&c7|QbhcS;dL=Ax3b$Y0~0Fq6Fw#Ft~&Xg(w9K&CasT@bRaPf_H;>R&|* zVgz808M9>9bAO*A{eBBm0)W~COWu&eG{f)hIT$dwHR2O`gpShyG6TLLIQ31+lq&4$ ztXRIrEtuv#;^&q~To`a1l#0~IS;Q7d$N!FePN z4PmC>E~A(cv#PD((~n?O7*zr}|}2DSIT+04U>BK0QBYAzelCrC|IH;&tpgm zWMEdMLs~JY^&N!Yxfn^$^_PMe&BsSNP8h?*;Q=S;;YvD6ptc0Tc(N7L zmKFr2#Bu2``CpDAx7}pJWuO#NeTW}0aJL(y_`x8p^Bs#A^_4fP;mR5gw*W*Xna^07 zRGag_=&=@YO^e0+)d;PXx4${!as1R}*yzO-aZP-d&+utsl`7w2nD!s}J`O9TSB|aJ>Tt}{p5_2+jo#4rtQokf=_}3-5&_NdWPEKqe5oA2eyKXU2x0;g5 z-;1`3YbA(_(wdc2g`iJ4i2(_E!EqbWE93t}4-bhyAQiCs?3z4QQks-S{vQji0Bp66 zy)3!`fBO?w=gnnz3e;_gHgm5^E3M6Q3@14lemSW*)g<=O+K19YXTNCy7O}&NhZ<+? z1Q2F$_YoHH+j=;NG?QopmL|DJ1C^c_%;-}}tE-r%yz-vz`1ZB$J&Z8ORXe7re`(ezo;rkcgGX3rYyMCo}f0iYEG@(c+*jE^Y3K{7&Gw4G$@v zGj1Pm3cwC@4~`7K_OjvWj-1T-Y4^_%DK<$DJ^kp0PAvYU+L|<>?;8N|lWHH9dmxD4 ziLx@4xZr3cN5URBkAL^5kTEpWIv!9yZLP%I!NLbucA+%(FaTiVaPJR(IfG2;gvu-~ zLczk#zf#|N91aZ1hg-~QQ-n^rVw*m~EC_9E_5JMwbrJxY2#RVI{SzwWd)bxzgio$% z>+5#DccsCsbXDCAr}F>`yDS!Kmz_wyESVXBk~N)-n(tzF_ItT5&Ff15`MM6{U0Mf) zqd^rCv)fwFFzIn0J_Wl%iVuEjnMJ^uKaAyY*TQi{K0n5cVVHW_0=@ofXL$gr2p3Ux zt-$u|6BkAXSciSAUNci`KdhGHDp8F|!3h1(N+bmacppq>x=qnAa5h)$a9Mg&M*I9K zk?BV23JUi=z||#_3+k^nCf4?vQy0!pR*3028GJ1EUvV@L5Y1 z6%H~_{(eSSWheI~tuWyh?uHof#)}AnkTocfUHmP086^fTJQhAtM*Y!o|8gv>mawRb z*@?C|Seno3@na3>4eICpDKaG57z?TY+|tm8$Z!CCh^Fv<*`h3R2Y;nJ3A4q4!0NuF$Iy!OpDU|*UZvA?wfSBoTGje2Zy^y8xMr$h6_n}JQ@`*^2V z4=3qNDPgUeQfu9=As!pQgM7$V1IY~r}yjCC>0lxOE+Z(mxua##8A7PQBbv%D zS8&qD1?pUz_Jg4lDuHTdqn|01y|JHi^9636QU$@jsH%#fd3QY{>jxM zx?PifVC7;~QDUAyrnOtko4%~;S5tHrUF2TMRWRk0FQEo+7xY}dS=>!-v3Yb;*6>%a zeBONC2v4uyp?T_^&XBGzXS62mxR31-TnMYm3In5NwC~ci6{0K+g{`>`!Fch%HQ4u zz2@v8Sp@x{WHNYVyl*;K3=rayWZZW80r!hS+zXpBjt^Y3COgR8E&r{f>#W6;IyLmg zsV)0xg}nt;MdRx&o{y*9=NXfFw#od8u~IqHd=sp77XA{JerbU8JWT?UCE|mcpV$#H z_SYc*`>9yuREx$MDW}`8f1u9YB`=vxyGFD=S_B&&Wi`=`cO}qvGWB@Ymho=($D6#t7{g@>v+vUiyxP|=OfqT^3^)uV2)obQEJn4aJ?A>%#bJ%xp%(S7+UbSeU+)m3QgSbyk?{kI zrV>I9>*O)iK9G_d`|{Izu?x=$+N!a=979bjXC*HdW(S(yw{K#I{6qew0qSjS&&FQ2 zF&9b(nrkMv+a$bURvMH13Y(X0`=+Fy<6aFuZf|KZ#ueSWpdj@SN#aYirEO7u{n^|W zTl2QB!c!>Kh|HviTVg$iU{@Ea^vSeS7zc}`g@ry8J(i`a8X6PKwkYiBnJRtLf}iZs zy#xt@$y2Ybmp&({X70yXy{1ondV7Yp^^krg8bs%u9c**zir!1N5|$)f*c_^iecqFC zhkL9l2s1P@>L4-nr4BQfLm9E%-1#DCQ(0@@y{0b4OJ-5PYTIv?-pGA*Xd(N(cm=?* z`H7$Pq}lzPRyn^&B!qhdM?B`dkQecaJDC6SAOZ^T#ovcd(TrL4u9#_f#ZTc#(;u&0 zd79lFc=1h~4VQ~wW;6x+E|xoZC<5CfsWi7*MGT|yOKzkSW*u!deL__(`O{hdhPWTz z?ncU8W1l*^M*yfUwP@jG{b9IJ1n%bC7jMI>Dv2g`S=$jx0(?pnydqB7^{~ih?4GD9R!zN(d03>=2eHwrWKfhsdHp zL=1=!P#~ZNNYq*?Ti7EBkSdmlAp`^hB#_JtY0u2RIWwm}=A60bot*n_?()8S?{}B$ z9>))>scuyT0I0bfIp_tzdM5~fqr49Kea_$R2EfKlmxJGUCl&EW-~GMlkR*Xe%8O!CV2~&TiZkv4nO+$*>;Ot~?4>3iF2~L( zJIOimR*LuJBqv?Cha5B705g?inm+(-Ii`F7{I2iH_Wvh!vsH;oDK2KK&C=pn9YuvT zXIK#!%{+cFuB+&Kw}p$Gv5Xm#EMhV+{>4^0CpjZt8MEUCb zT4pN7M$SA}VEx5iJ5X%9EEf+-JzC~S>&m+hX_ZGOXdUiy@56HO%UUMq>(t^|4UIKP zr&Kc%ak%`Yn=N;Mx=F4KSn4h-%hCTlLRpgvJ%m1YfgPZGb_as2UzWeXZ?w&TS=}FI z1op4LC)ew=jh5mAo^rUkhPG&pZ>?@7vZaxWLX{otFiyBwDQjBn!es25e#$u3nls08 zMD$7uZ>MV_%qib7X;xd1cE`%&V9K5(Li!L(#C0fDIOZMRmdXV?aE44Ki`J@%IE|bR zmv%aduhME`1EiY*DsLjEU!@j(1O=CGMRkUe(<%t*4QU}HK0=`_Ii!5`RTS}34lnRN zWPz(xkZTrwZjUWD!{P8N+hs&1IU!Qj=sx0e?iqfeM0E!%jKgxgMW#eCUv_?oeK40e zGcL;i*vfvIuF=`yqP{bjWw>ov1ihN$?dEu9BBR|_%H&huoA3x-B^*lkOBG2NAke@*!ezW|&+ ztSHg1714n1t+_40_|EEzHGj)`c^KYr{LgRk{CP8yA+ITY?UD3mwWd{bL}ciZ7V>DU zkLAZj(6Z& z7;6^s8}EU*+g@M&aF@hcyV-P`f0kIYXxPUITpSwn63VN*iHX|YsCJf544#&swHyq^EC z&)4JwhK9gspRtq4-@NR$?T-j>BBTd?Rojs2hC0e)dHES=b`0&V5+)^u6azpP#^bOw zUzvmhEHoOINk7FKqt*yajKg`!gRi>_;}wFRi*=z=IMrX5LC(_LR_j!bS7cSTcz!1=Xq?|Q?wOqnK=f7WfkVGr zR*R@aNGgTJo5Qylad>ZWrG58H4)6N0u^lI+RoI;Kw-jj+l;DhC*Mz=+=FeLk z?V$Mk2tMP{Y^ou#c<9rk@$bhq0jTHonhdqA2L+iR4o*^E+6;SNa^rg0xrsu-W1*Ow z@;v$y*PPG6IV3(P5)kjCP#!@&<6v)9R5cVS&AVpNCf_9}4g_>8==M(TP!eIDNJn>X zYWN}e3n-qk+|^9P{45Ood`{66RG-Gtauy{}Mij_s6G0G7J7QFMR(n4HS%=mV1j^E& zOD1#}Fw&8^C|MV#3ceU~PpcjMa@P9~wjcwzhtA}@!pcMv)S;eylm#8F>My^G|7O^b z_1_XB(g0Pp=cZ7@%A_qrCU##|eb+$wm2wZ0cRO}EKLzJf9@%*H+X5YU< z*#rNL?mJgS)^4W_;TlC)eNK430(j3xD!dJyzY9cGaBWl3lsD>GrnM_7TyIduNni4E zeLcR+5`;mly0_D{oC2Nkb(qNqDHrM9C&otOi@HqNF$Bo&yl^yQC`Z(FObKZE@RQHd zFoo$_GjVW_Q&<#cK=k31-`Pn_C9}gt7l5(u`Qq>>$<3Jlo={bAt!l!)meX*YrlNZZ z5DwvvpSL{F!}>g3!?kc_$1@u3>sM}Nj}50plFQ0h^4RFAvVar9Jaeg#6hDy1OVgFw zvJCvD9B~7U<0wJ8S=z*pjrPG*_<785Vhw7iT^<}5_e8;UiGUE07kOlHSFJW7S+$Z# z#%9Fr6`aiIK=80A-(RwlQqlIlT7X_FAT{`{F1{MExzM*I)0^ zqPo~2XWUQhT_vy)9Z;p)hdDnpv`ws8m|d(EOvO-$qxDm__H^!n0cM!>p$N?K&}soC ze$r;r2FCajkU}jZ{E@qBMytozm9}1E8zWB}_J4ZQNZA+tAZ^>T7tH%5=sdR8kfB*D z7U@5n=Qpw!yKwdfqI5P3hNVEg+*@{6@AEKUB8?bN=EaY=Nw+2N~&)?xPK!{w){;VJR z>U$k}Mu_ds$k7qR-wi=Y?ZSqj?uCx|yZAyqSo>e|CSKCQ4ARf7x1a_$B)F5VT4t%z zjx+e51gbN{-flJ}%y~;^9To(gayH!69|d260v<3ueQcXql)LgH#KCY1HjDr&5?BOZ zbW?|yu3dX$d39UnE|%I%TyK;&SzpYNa`&r&xn9T9AyiO}fC{{6aZ>HyVkP5O#SIeb z*}>z!)rkzMSzdXNWy{gh+Z&^qbSv>(B#BpEy#LviG<@`MKK-ERv#D0T*AINN-*1eICXT@LhV_d}buQXJD?#&w9|Q@FomK6{rCKyDQW#cm$xQYM2nj{d zo3mTb->ftFm%?781#t zYVQqmx2%XCcGp*7h0mMPP%Ul?7IW9PThaB<2B*SCxziZzm(s$&M7J0yD&PzKlUvDY z51WN^A~%s6y}l5hf0E=Gak!$@GOe+(xt^#bGIyiEqsI6fW-6)SgXsWp@UCb!gSGI))?|WaD*;l?Rhb9dG9=}F9!9Kp%zd%+hy}YXx zqa`EKp%w?8ZwecYx`Is~6!T>?{L-;YP*;_~zuCyVx@{L~4!T22-B`R_01xc~{pweW z9RAp~-xus#{(X!8Z|46$y5*ld`2HWL`&kO!98#Y&k*IKGp>a8M{9w(uL6`pljmECg literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/NOTESROOT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/NOTESROOT.png new file mode 100644 index 0000000000000000000000000000000000000000..b6617e00135a3924d9cd0841707c8bc9e559a25d GIT binary patch literal 4361 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/NULLIFIERSROOT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/NULLIFIERSROOT.png new file mode 100644 index 0000000000000000000000000000000000000000..6838aab58716e5a38955aa1e591fd1b30b17981d GIT binary patch literal 4346 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 Svyg9PC_5fKWnXjzbM4;|nt56P literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/OR.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/OR.png new file mode 100644 index 0000000000000000000000000000000000000000..e5e7f27c121013428338a0e2fdc06da9296f9c42 GIT binary patch literal 5246 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/ORIGIN.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/ORIGIN.png new file mode 100644 index 0000000000000000000000000000000000000000..2bb544c40ad17c1fbec19c2aae9bcc2b1071cdcb GIT binary patch literal 3388 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/PORTAL.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/PORTAL.png new file mode 100644 index 0000000000000000000000000000000000000000..ec89242e8aa77963b77452e7b3454b0f8f9e8d5b GIT binary patch literal 3401 zcmdT`c{H2p8vjD9Q%k9~YKhT7?Nvn$B04QobVDy{%UpvZs3MFs%S^SWy+uu1Ob|;W zwMI&XYD6+^k5Woev9xv(V@nlDC6nZSX3n{P%{g<=+;i?Z^UwQxzjt}Q_xZiQ=Xsx7 z=gxSksUA=T06^{3*C+e{0Ez(n-O7q!dr-s67aZ3-b;2VcqhxhrxuN*j9>q6Lmc;H? zh%i!brTM-{)V0=;ySV{dUrf*MkAyqs6-1q~1-BB|xc3tv0t61!2n0lioF)iHt`KDq zG)n;}2+C&xIS{hU00;=rv_FFW{i zlf*mMt3;2IFa|p=8GnLvNRpt8SHF2}>|-t|qCT7JdK=M+iroj!uNxRF_hnkSrUAxk z@*qjI{pFDh7<~Kb?Fx_>quQuoTss~vm_n`@FhdlEf`tI|M#1_+-(uYht^|9pDzUXMdV z8A1skmsD)jM3yq?VeG|@{#3jmc@Ey&-KlTpVw6W* z6dpFybM;*iTirBpe;nj8lz>5+Vw~h}+?>SXlCoRF*r5Rgc9#CU9hr(t!Wcaz!xQz4 zYMC9>sploAPdn88SK>U%5w*=0ByHQ>R;g$GA;i+v3jsp&AK>GqVNbhQjb?@|qj4--VdfZl%Ok!`LPfLQ_Cr3>4efK*0c>yUbH>A83fz2EAeG+4kL{a>5q{gSVE36XI6Gza*oo0Oppu4rmYjlgi5C zLIq_cdtvfs^ZXi@vRa?4J;LWYW1i_ai2BDJx3*K7aoGLSZQycA4M6<*cFb#-f|&{5 zO}k{p?Ye293e;g`A1&v4T{Um|iiL}J&%t>3@s?(i^@x&Jrt35G zvS{r9N(qoLB7Ki`%5RzgME0cmqmzWZ$M)`e(V^SBLRju`Rk!4w1){*d<-U5JxT-RY zJ}$305Ee-WFF*slfCro$`b8E$_h0Jwvf73}iG|fr^NJ+-l93eYmFsqf)2=#3fJRF? zIUMMW&Q@CV0oC-};B*#A0lL2sGy&V0=I$~=go1Z21^IM+E3Tj7d@&a6K}gn}gNU>V zk6xYGSNdF_tohseLiTSO{KI$0$pib{F5Q$N8IcG^(P0hH_D;UAK!h8*ceeX^i`<6> zWe~zxZ@8pZ?tgjH_`C@NMFl5@$d;tH1L zJjKlymJt`j5_khgyg3mYV&|euh4tdEdsvdmBi08fTB079^@Etsx(k%BO*Za}#1$}D^9g?q{@rV7P zP282y6!p;l6;~g1QRz|0489G|;*Yq+Hl@9VrI_7k!iU6-w?f=wniEs*oZFLOnvYDQ zchC;7y8;M#QFTpoy_gUtZk5^R_vRu$?p~>9@wA{e7qVnY1%53EQQ?Trt8p@ z!@20?PBP}sO6m7}1!S=g^3sFN#I^X9>N2XpBf0L{%7LEOZI0Mgt?Y|u>&EP7bs2QN ziO`g4lLiT=P0e+QdGC57v%sw+Rgi9y2X;0WOeUUhW-$_Y$c0D)H>uPiag?!eXcHrf zS&jw8zPeQl)l2A07GRQRRc`t!DC3=V8if&*#jj_~c7&^57OQY@VqODj#=bh^Yv5z#pva_?!L3eyG`t{v=k zTH9sm`3XmGRso|RMKe`^>KZ1^a3aUzTJB-nASddCyv)JOIGVU7-zfdU9bhhAx4q!T zD+&!36>359H?a2q0C6SxAV-_i_cG>nKVoQZnb>ZRw4TAt^4z;UvxE%q1xVn6x--q0 z(O1>$+|XCkaJ6%H2Mn1Q8(dHmLo}yED1IBwwX1kf?W80Ha;P$Sz%HR;crr! h|9KVsSIZ!chT-TRFDt8Vf@A=vPM$f@a2)x=zX3I7Xv6>j literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/PUBLICDATAROOT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/PUBLICDATAROOT.png new file mode 100644 index 0000000000000000000000000000000000000000..18a258a7ed55ec991c9cb9acba16c3c4f7a118c0 GIT binary patch literal 4376 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/REFUNDEE.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/REFUNDEE.png new file mode 100644 index 0000000000000000000000000000000000000000..5d64c008157e023c174d7ed1d2510168582582ce GIT binary patch literal 3397 zcmdT{YgAKL7QT4_B9c($p(4EZtps@n0kwsKRw$q} zpfspN0wPI(7zo;$Dqw)&p*#|w#0Vh>CJ`{nTxR}u*36ojHEZ?H`OZ0OpMB1^?|1gu z_q#)ZKI?Qh=>h<-&d+y04gla@VE>Vh7T8)MeFDIFJ-_{XgEMNRQ!}MC?M7MyspZPN z*NUa>htq5f9f&186Y+lNuO-vC^6k@6Fl%v5B)AmFS9N9~Ry&NZ00;>8*HczUFV=X0 zEoB~V0fJWs6a|8X8$<^L6cvDjpo0aVAQW2t8I~zm<_z2YF%q##R&&<^WI;(5io0Zs z!fHX$jpddk+G-d9gY4RwC%N0)qW{k960JNphCcsvhx}m`S_*Qt=xR!v3IiADd;M}8 zG~X}Zc&hKyY#H0ybLZ-?B26tltO8Z=fa$1<+Lu$->U}!+w#N=*MJd(ZAKZzUUQAkM7$zGVT7cq0hkQc2>kau?I1bJo z4@}Rf>QjcGv~y$boT5#rc>x$C?A!%mLf0@KJn=RgFXFzyg{r}D4%-to6}p*?M1|Z+ zh*vsTxq5(n|2^FqbC$U;r<2r<0!>_flKJ8;jnyCa^3wlLn#MhGnc{v%##pN+x%wcD z0q-Yg#`j$ik(+tzU)RVY5$#`N{8mWewICy~ZBW_tH zauIJHD-6nJRbyp}yNVS-H+a9Peh3{0ZaHrI>@xr@P@nSt{8S}wk9wd zydWjs2pwLx8y^M$FF&Jz2LfJnAY%UF|7MwHD?REmk^9 zhz*zS0&Y)i+BK}8gVwoliyrAZXn22?>|UJNS7&0*IQ?~_+Wx&P$> zm-)_p`>X?4*ZlJqf*I=O9#nbL2p+?#1sS-ZPe(p8pav zZrS4}LGR4k=rwR(m_E$mo)7{2ABM=KtyBOD`fYcw*us2s34QEy0*8v$*XW`s+P3aD zjVX5|U^HJP*HwEy+5uGIAHPKc??cBTy&q1t<;66pU_c)zUeFdr)xB6bR<^yl{6~eL ztt}5AI^V^2H~v=-)=G|27Z6n9GP#k>_$N!FZ<3lGOwFtT0JlnARNY(0?2n(6e=PxH z5AfWBDGqJi3J5A+*O=%WRJItuS2aqy{j)wL?~ zF5YzukcWfZZ=e;ttFWpP^%iIBaJ>@LRS-0~oHV$jh^48@=^##o@&Sz7W=bDc1T8yL(%=@e3m(rSE9S&C#?93BD-P5q z+3lUXBd#bKos(m_m?J^;+Br1a8hnC4DJ$Ey_-MkwL`2qna}VmE1<}c~KANx5vk~TT zHk8h~goQ0%m1$NYh1I9U&kk&K8$D-|d3#Pay#&ibfJO_I3E zv6pv8Ll>EoRDf(iIn-u^yS>Fkq|xM@4PKvX$_#aXPRxp++Y;gvp8KxsPL1DREO&D} zDsddOOG|K#c-9~YZa&!`6;DNbTSC^9&{)v?f3iTV?!l$lvv+`{d{60gA)d;ekacN`1)%uz$Wp2ycXVTUU z=So_e^7q6e&CuM|EG^br-X1nD`MdEO9eJq~Gw+$pFX@4;gg&x>EAeL&+cF6UA6>xD z{>17Po^R_ML1b{%5+9+bC}z&`q%kGh#%pVM=h^XB@Q{!1BkfpWB*V)H-r6KgD#N0fPajZ}FL&Qr6^*EM3y&*Uuo5cNtpDwkqqGJC7Xc z>^!!~^dy@8L7~mKn~qKC%@>aED7B-HWp+i*BqYu>hD%9y3ALfMNi(kPj|X>1jS>*; z$BK1%u8mqgCTWu!LrYq6R_m=JZQ?K9z8$&9(LWbhIDYHQmXuzJGIJ<3+|*zM$BF0})~|OLwb}`fU9j$t1FThVFIHEK6{fP?_wqv$f>*SGm_^w~ z5?BG8@Z1e3ac>}i7nTZv^3ZYSU#$fIC-4oK#0-G5$i)1AUXYueU0$#`Fx{YXbd;I{ wL^Esg$q(9K$}5~UG6CUFT&n+1{wGw(P(%OX*VVldU@!o`uLJip_7Tti4XJQf3jhEB literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/RETURN.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/RETURN.png new file mode 100644 index 0000000000000000000000000000000000000000..b99c0eb1e5f36e9e0f44085b39cb1e09888b5478 GIT binary patch literal 4060 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 E4f*TRCIA2c literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/REVERT.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/REVERT.png new file mode 100644 index 0000000000000000000000000000000000000000..0ae2c7b02fd10c5fc61d1e240ca9fc555da3f4ac GIT binary patch literal 4096 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SENDL1TOL2MSG.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/SENDL1TOL2MSG.png new file mode 100644 index 0000000000000000000000000000000000000000..f3a2d7a1aa8870ef20920673bd4abaec84bf4bc1 GIT binary patch literal 7129 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SHL.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/SHL.png new file mode 100644 index 0000000000000000000000000000000000000000..19879901d91fae9e5973494f1a8c96e534af1a20 GIT binary patch literal 5242 zcmeG=do+|=``e{Nr$oo0Qk>i>xpbr4WPDK(zG|Y#>PLuk@iTb?Ez2k{V(^tW2oxkak`rB2*M*#Q@ELVLW^tK-(JK)AS}}f&O);rv|?&@2!b-s<#H>VEU5wu$%;p z$NVGw?JD@2oHts?ZSEM%jGvVPBgg#6o{JxL)VXFhXNfeE^FhYvG`d=C6%EjhYK#Fr zrsHvC>}>$G;43E^1N6e0s9OOfm%p$I;D6O_a){b;rN+t(xE&vk22h6Y>-{1oo7*D2 zJx1zu6C(lrXb?Ly{zq8Pg7XaHBuElm3stY{@%$B-os84HflSEk*a|>a25nOK7~US) z^+&LJgcwl!g)0H3PgG77{wxa>3jzJIg?8{-pzo=>1}G(8{TXB-FbaLF>Ubk5LY^0z zWb)nE=vQA|eDQrWZSijzu3?1uIrJzsL}p;KG-Z2dbbt-11})JRvyEYCq7 z-%z*yhV9J8MfKTLBd0m9n&*Nu#uW~Dk|rBi?jI%aZ;?>1@0|%!*&67>jOmm-|DC}x zGx1|0p#bogdS6rycIp{Yg{!#$o08A#BjeX30kHWUv0q=w1GTB0i9n{y0)eBhpg8mn zbwMsijt{2&wO0qpW?>md^as16Yv15;Zab~p2#(n7TtaJM>^7h;FS7T|-<%BQ#Ax&}Xm)XEutkMT5 z=$#&k6+!XK;ekH#_ax;ZeH5fPoZ;2$d@hSP?y-`}Y{Y(m?!VE%t%MZz|EGBq{Z!|E z(vz~p^Dg5@b2D1Un`eT3Qw@kW(KAwn?ic%f1cJD!3G2@1Ied{w#tMwj-o?C9775fa zAMAq&t)n+%Y0~(QgXMzHrFx^DWD+u$FEL+?ZQMoM=Hj&xM!f9l-&-^tNi!CuTJL+H zqde!f4VDsFLi&toL-QRl#h=mLX2(yuy2JAjwqi=Kj9M%?WQI;4lYOYA#+GL*(IguFYIIMO7nPAr=<4p{ajTG0fjxnXWaqYFR5%~IPNZ5>m0(eg^8S(d z2Q##mOi=f@MjX*6Tr<#T@#E$~*_clwR~M$|IP>B#68ERiv~WTc+!H=sY|47YLV=r%VrRHXtb;!UT!DfuHF36jk6 z!G-W_`E$~pKf#D$R4tZXp?)pgrEgQ91Ghuy(f56#Lv=h5Swxm5{8QE4e|rZtK*WaH zTaj{YVrASw(M!bAFOzSG`$W{QdFQF;6HBUyB7;!Au*5l29eP&(P=em)1XmmYT1Ni~ zj_@$f68y6oPvoe*s=1=LfuE4o*X+c7qaL{dGqVEb1z=__BG1daXVvBHxfd4W(OpShwIKx_4R3@ zQ6k}sfb&pX$!x=}v=)g$r7YR=(!B6aUh6o3o^2(q7uu-|!v``eK-3r+#-su!9BJO9 zNZI?ZFUp>NPI!E2nr^f@MlY8@%kW2@d9f9kVFpwH6mj!iASoeHgiiN@Yoe`$L7^bya}g(D0c!UcHn z4WfJ7qc{}XVxdWVvrCq9F&Akl92{Y#Pdv5H~nCXvt`tG&W>R#th1g zG^FprjvBU5egt6&aOK&r6u8kWLY{7Paa>|9W2QE8X3?{}Kft%!(Y+sCk=s6&t+ju+ z>XR)yEJ_7c(Tq^3tspA@uFdk2#Jc_-=OeYDF}cP8E_-8O6N-~Vh}Ecz;ZZ}o^sU>b zGizBYx48D0E^q1;9H!fk@``^%dfTzYvbd_MHG?ywV>ql|XKISoZ=}TZ;Z7kfc#Pbs zh_u?MWNGz7#Bgu9!k~&5cPuow8Cg7@9GU-%4B&=7yk0qL2@A(Rs8jxS`8YSuy_6}B zfMtYD02Uq0JKo6z$_$Tom_*vrpDY-!v)A6vCBI!H?FqOPkv0cS#YMSv>GC!on<)=b z_Kq7hG2L5*apq}T1*>Vs^n@&MOha`T6CI29BX{(ikXQQalI5@cChi5N~R2ne89tSC&clJKKT5 zP>o}#jxQ1cPK28KAEo+iT_kt`G^yFn9i26_IwVn9EX&`Yyv;QhwwHkllUsp>u3CQL z7J1@I_D@NxoY})WyCgc0wxq&br{V$%lkIiYN#H8Bs4!mT{CKFFn4`P}WSxYa#?9($ z0qg{jFaa=rJ}I@)ueH*7)L2dIx<(?+rqg=>FP{UeM{1ax*x-O#SBaq4xJkd z#2rYAQp^7wh%Dwl>AS*YT8_@G`>Vv3e5h@&VCwnadN}+tw!;^Rq#7x zh{+Kc^pmx-XVXd3qp2ByE^@3GP65#d4ibTIkWdLie5KV}G_aJVH;_5;^BG1Q?3ckt zK_!!ls4jiNe@f|-BP&|ExIftw?wNY>tH;ef5_tAoL-NTe-ZTgG$MpNssRBFm3w6 zE{KXUtxZZWdG74j&2{(WUG3-2i>m!9|XQcnE(I) literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SHR.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/SHR.png new file mode 100644 index 0000000000000000000000000000000000000000..386b94cffcf940ebbe4f57c251110ef0077c5d36 GIT binary patch literal 5240 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SSTORE.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/SSTORE.png new file mode 100644 index 0000000000000000000000000000000000000000..fa07fbf2d95bc18f90a582adf2a362a5a98d604f GIT binary patch literal 4208 zcmeHKc~Fzr7QYFbs4Ru%fvkD52?F8@$QCzt3?it2?D|j^DWC)h314fAOCwZeHzgE| z8W0d6Y$1SxL`A|Pi!33OEudngfrKsa5}dyO+L_LD-preM_m6LWbMLwLo;l}te&4w_ z+>blRZC2Y10FZNXJn8{}G$g{WHc5-V62qU30Z=q|I(o=6o;b^zO)acZ0-f0^PdHV=mK^mS=+OXjfrVV_fGY8ulQw+T~_D9`XY zVUmA*nZp%1KXGCSjJIqM?Z)8G#M^bZ+k&;INdHIug%~n1wup5@%~&8|mZ_7xI+O$y z8G|*A0yPjF;U!dEfsGBQbM&AuWSJf@%Q4-6(22jso4rZ!9prgmngXcrSX406AGd4D zCai-HHQcJU?eD~EN6*Rw?!A9C#4?qhfp2GTEwTICWx(!sMnXRv%(d^-dN58;0Ig## z@>d7yfF$w(bvIiBC=LzQaD71FR!feZ%PZ2-x^UjqM%56tqqlbyv3V>LGK%e;cFplMKeWTl^bsgCoh)WT?=#d%)#i2fnD0ygZv0Gvzpntji+=C3s z0kh!&D}()b>}*!w%3N0ipIRn-^oKa@IDFH_T}V|~uHN3iOR#VuQHgu}!gCb@MNxiV*XAW=>{lYi_#%6SGZ zuR2&?7aDF@y%cVARlEwFq5$~fwZ`#{q#pg}@60CXjY>bQJllKfMRVV8ryPv*N-rf> zkz9s|l!=Yw3%)#q=2Ct| z&kN?yRlgQhcSHlQJa;b1pj8s6UKKeNqc;;1N+U;-hS_~jqcF=BtOMk8+pa==%#1sv zg^cs&{LBOO%bKtEqfv>rP-3xXcueR2?K+jzGwACd#11Hjqcb^?s>5X z*v#KPQ|iBiEj(@_G%4|KcnCmYycI=!@^v>U_du6ti#@&j@AaFarXn@y?g<5?P}7@y zzCf6aE{kR;b2_>)VapZO$s98PVuM`)6#WROz3fHd!fEuDu8hbI-P8w-zGK2?CmcEo zt2@j&<^W}vc!QNVV*r|_J%JSF{!>m^!diD6y2=Zi{Dd=|a2ex$%Y#$Qg#i?9fAAhr z0Gd>FA?YUwD9bTlqc+>(-kVyUR-Zrn!^15qsqYRprml|U2;U@^&VQh+0q~jVQ=TJ^ z@d1}6xiN~}NAErGI|-BQ+<^{+gU|cK4q12t*uM8GJ(GjS>K^Wa0Sg!L zK6zQ>KV+AG(QHTqz}ihTqe#*l6%!l$xk89!F<;7%Jm?375!VTCmc%^>%2VXm#`x|8 zYvI+Q1u-eV& zRo9^pyU*P>0mJ4b4x1QI_R%Gx@_2+~2F|%I8Y(_81K7SF0hC>{Q+v z?F6pILE5@OT8F?iJhpZBsU z#j{gH6_WAX{bM#*27V_vJ6J`Hy%aT6!R5Z;QzLC&c)gFu2iVa%GShTA8*|YdIHvoNY>a$k8izaSdZmu^++t4fG=j+*TKa zE1zT5CVIgpHG~macdnMab9t^Ir^Zf1ixN!Q>nvEB;rkwpf+C|j2D-G(486S#8{p8m z4jB7ea?5}M262SNXtiJX@k>l)W(WXx|gO@I)>WKVPe)xieB#x={eD6`b#>2&Vr$=R8pRnw@xwV}wzJu*=U3>u$yG%qi3ti#yV1-^ zs?i?brumWNb!V1eQ|Xdy`suA_%UNEE-_Y1 zJBUydV~xGH1?0X*-How~(ik$}cg5Io`6ZKrI1Gu*4|j!Z>%F@$`%NwP=JjY{OEo%*5v8FkQb5O0 zbNn$&VZitHBr|5}^q``8iD1j9oDpO(G2K%6wW6^XhG;^wQM&MPp**g$i$=W?OR_Ev zU$Lktt6pAOdQ6JNqUHT?X}$~&MNlo+mL3!58b5XxHt6wT`{L^}-OWu!ePlh06E~?g-&0T@ z9w^O?`=RQpd^+L)#2 znA&l$%y%+ArR$g$@zu*RMcU~)e(%I zYZLEBIVjnXnI|}Qz)WpU0hr|`kCB451f}4{K@a)0j93a^&zVEu(b&rTjL-I$ZzvJ*9QSEi^`5<^T3#$~iG-CTAqxf?s7+6`UY z#~5w*FyoRLF&DeRB+QUuFt@X&U(~NU=lt{goO3?sv)3Q9-u0~KdERGzpUeBaYt7Ar z4z>&DubK}4SZKG;<}d)updo0OHy8R{y60yD0Q7&iv-#m@VA?Pf_52UR=b)uIPb|ZS zl&jJpar7J_7g~Nn`*5j$5G?uzUC|KC z`vzHI8JP1m83*PA#jnZMKp7}}P1eIH;=ZPWMb-+|-yqM+1bW{f&-vTzFHrd#?JocU zV9w+#p0$ZlHk>WX$g%r}%`AhXvKUFk2mrBrE@-)Xi!r$A=W5 z_K>&e9}S$%p-hBrL(G`A`P7w9Y|Y2LyTzkEc?{vx#q(7H!g1KWlS)c6_giucwatH2 zn9Zxe)C(2eVp-xZvc2`8qF1~bJ^-#XyKG%EdubEbSY(1|kH3t$_iK>9?I(peGiO#q z;ILXTJy;ZUB6lEz7M&K0XNL@Lv|wKc4sc&SWYBzSnk&{bfWkK zs&aw%$$?O-+ED(s*gj$TD0N?C_};Z@=gwo@7*m@_&cycQ$?JE#qR<@tVoh1(MgyrU zRt>j9r%!CIk>l>k2}eEFk_qZ3-OpovDdN#Sw3U+Jj1LOqW46P9CCf@dpFiK8P=k7|%&<>UPq-*W! zHooDzT^b%HmF8*4T5fM6Pc4zPYjN;*`Z8n`S9rM9BmBtEr15+_UUF*QrPB?Q5Laqi zx#K82vgSKAu&17+q$jxO8Il_>)f7d(>~x<~!Cjd=sxIqXA9gU`b|j6o#oOh~GEcmc zn=a6d8gs>2=`1HvgG>tEHBDY;LEvt{q*Xz`y?cy#EXaKsmd&?P5e!`l zf!yQe8Dgn%aZRJ8RdXE?5-!%}yji_S)?S=t&YsM5M{?Lxo3dU{=V7F(Eitig94X3g zYm(E7Np+b&x}&YqRomkj=I#|M`gbL{3@w*61}$(d5=ux3s=a9IO=+^NTe;-O$LAMV z%Ca@EgRYJIU|)68V%Z)SN_VSgM1^^2#ET7^Mv_Nf)L7L%6)K$=Q-G!93)Yh{6(ulGJ(7+APS}EiIHH}PTXx6iTTCEf1 z%O!tsmF&VCBwKb)7Yg%j&q%(!ZIw4pg=b+bEa2=q$Qh|^qdr6JN>F5`-$X}-2Oo(Q zdYL4-#D~eKy4;m{WElUzV}0rGX0>pA%T+SJf4n`}P`DaW{iex33_9%qi!_%u_cVUEW% zfqC88s?c&|Zu|BQp5oCvhqp>s-W^r{#PxABdf2{@c(4P?_SxRy6OUf(XWh#u^8fjs zyfQaHrN_u9J6wiM$+-plefijyZ9*M5l1g>`242W8PYlQ`if{AwC6ltGRf<(JXBme*;tf?Lb{;`M=fisQmq_IMYHXe`C!AThol|7CuSW&5X5H>pq;rDokg1c)7I!hV5 z12Ki^-L&_Vl59!H`qzB>?t|-tBWIy}b;Ug_PTP1!DAN?*rK9Iy*Ge+(CZMof>D?G= zF|n;~s>mq&o?8#IsP<)C_#mN(%J^YAk2;c!nl+eW*pToN#d(0RI6kAyS{3pRj;p)8nwZ7_q!^&^r(@vn7vnPAG9u#HjZ8E(C{c8mR=nSWdkq*Y<;WWO58=8-8Y z`j*S=j+F7Rkg@BtiSDzzbb#g$S9cE{Uvk<0VQH`PjMhvYLa#x?(^<*OhrptqvxTug zW0De$d75xf{KF}7mPD&+Mw2!5 zGc_jD(CohUOFJftEZ1wFcs88;XT%uY$~WXUV~qBXF=m_(9kE>W!S4x-?Bmnl&8QJ@ ziUU*vX@?>z81!Cmj61SWsAB6^*P1Z81JUlr>G+f+B}byt)_ew{=Q5yO>7v-RR9WB` zJ3v`6M)X^Nr0R|zd9&JLqSlErNEvdU%D?Z58CRK^>h=SoE1Modpk}3234Gouq{O@A6*Fh*j2q4*6m5 z+p$ z5rsr>?0$S?_^%hlN+4^o4E%RLcF=UYkNrP;izH9mkualdy!`M;dBl@FP%jkCq(`MJ zl^fEe(-#o$tpZwBmF9o+=jI%F1!18w4w4d1N#+s+Glex1W0cJlM-jO8#Y*7P9fs3K z0ZlrzPJw#P#{5d;@LK#drHo1wg$PzBLVCTH%BmO1KxJn?dOA6%{3_A#oHocbZ8WzL zkE&Z}gUU2dGhoes?5hBVo(IeUSE2_IKn88IJ53QsmTF`;54am)0+coBt=hjGc1{<` zr+$EdoGRD{74CwI#%c`>&4wncI_;nSAXn!^DNM!Vhf8vVka?M*v=RWKo85GM)j*{c zJrzjzD_E-$5Z4aHW!%4uxzs1|$;Jb1OD(0L^aApQuuFX^`&+BAAack)L{I9GIH>}< z*43Ugs8zsK^e!uDM5LHRsaG!tm4?+YP`NVOb1SWcc9Nrr3rlDkLwcS+rwnl9QdR+F zd|l55W$?Nnu}O5b4~cm>7Z?V9n}%4UB($Py@Mu=T?R6$%2{_Z-G0CM& z_C!^~yPYRR3Sh9>yt~>Qv=m#?6%{~mEPA+qAjA`#*|3&=;ju3YovsR|{e}GY=ySOq zDa(Qtz^{J=x9^~*;+D(@&)!iigV-e3jA9|Cek#@Vwe&!be<9u$6+a}S2)TwMCa;Be z3}h2nR6LKab1YLAv+jOVht#TMTh4me-7dZY7;$xaqcrN6As@HsZh?x)tFf->WPf7N zf}<&%E4JR%35*B^BW4u@c*{>2oSZZ+wHE1)_S)ZN)Eue|y4<2vfnIcp3eb#zyeT{a ze%oMcSL|dYrpKgNo=&qX3FahqcTWtBroXNzBHikCB;nayDsQZruRr3N&DJf&w1mZ7 z&}Gx$K(Cgjvl`9Uw(#M;H7&du4sfe)`U0Fjj6leTnUO2T=Q{RYskZ<)O;`=WKh^cm*qx#Vi1zX3n3I>~Zlz$wx;Lw>9MW+&%rel#(! zq9$F#n7>}E9BJ}Stqa@jim+kbdPo@}UM05C`@OIib)6;_0uyJ7uX~uei4-a+mE8;- zbT8#P2334D=iu10(_5l7RY1jK0-WCj|G+4W(@(6x3tMjZ6c`aMyeoJg)2&*vWtAfaPLt;Z|(63OqpNp^7 zE`{&2A~HKp*gzQ;auUh*ksXMxI$gRryDl+RbV&cY5(sWVGYSGu8yYy2#EOD#4`9{` zmxIZ=1kd%RwDa;@E-YAKR#+)gtgOGsebJ`10rr%+lx{2bZh{g+N8Skqq#kWm3C zIkxM{%#`QpH%hwmmR}FKomKsq0XDr$I&4prQ3A`Tm||IuuaY)#iIPo?8mVq+cAe9- zTL|d!aSFR4sII``t7_n25ucJ&6+(1?3?4s;3{T8bv~c%>0~~gIiP`XQ?i#1D$AmwB zM&?6avp!8bFHc!;_j2>tVmdkxa?a*wZ!Pi!7#Bxx0}V_3Ai{dTeC^h%SbEUTw9CLC z-;%dr{#yIG6RI~46GFrMcuA@w2pqpLel8W`qd!A21@? zWtl9kTjq={?S_I@^W=ceqT;T=bHwa=-Q?T8Ak&dXV`ukHI*YUvt^aUNMN?~+v*}(s z?sh!?hgp(>iDH0T!SG)yD1O{<0x~w^J*@=VE|K3vr48@DE%7Q0nkYl?M2Y|wJdJTE z6@^?TwgpM^2G^H%_xX{&JHv*0fEGMS*O|07Liq&U-jB|Tu|rzS?K#Qj|I}u=Hmw6Y zgDa* zB_ba}Is;{iM4XX3l>Ma=%b>*^@YGfc2MX0g6Bab@toiTCicv`)G zZkFT*g!<`Te%d|Nx2Kc2``H>~t#0<*9*_ATwvP~3U>E0{H;3UP+130bGa`UBaXO)n zEb;0i%{`Y8mPlA`mQhTf79#j{D!@lDp=BUgtt$u%0gIZ0n=Nnn0zDVV5Kk(}V!{#| z@+9~Ku6WUl;)%U^fjl7)_c zG^3_`N)E|eM?qKce&zFdtJ%qnnCB8j@TQ~Qj?vv8oz!EfYiY3hHiQDmdnUK2^>~P% z2833RHeH>TP_c2}7Y*@9>7}Ry<4y zQxv99wX!h|WveXHNR1fdEgkgNoadEu05@K2Xe%DuAoo(1aD0_~sSxy^IFlzl7hoEb z|BFxsurd=Y#ty)_bYyg|3#P&7Xwuj;NmBS8itmgc^FPG4vuWEdb{nD$^em*fzzvUe z^{10%>zUFf(Ho3gcfLws7Zl7RR@gW%3UkgxShckOyHwQT7Y#b1Ks21cpa6eZe_rT& zHN$I{19J_|MLhWPfxEE1?a#&z4)z_d=bSAFej?OQYtytAqtl@Z$I8B{7MWyOV-5j$ zV%1p`OqjFW1S*8jQHmg3>mT01Xkx1ffQb**$)O`W+Ct?Q`r96OLfhN0urFr%>UgLE z&Wz}m(a5YQaG>aPr>Fljz(lD~?J$9MjhPEe))O>R;Ggf-YdkT{V zmkO*XL&lHra5$Hr7F@t&6|uSYJX&yVE4#k{X!?H3^2&lkAoXat z--P7u2On@t1}-~XqDa}liROb{`oV~tUre>3Rj4v0mpjEDvk*0q!eWWkEINPKQLI?` z!2VVl^A6@z+3KUuPJ8@7UJ_)5fv9d}No3wR$z2J7FYWJX;ct$B+X> zt>{OZ+!6#7IQnu|?A&y(7CSwmtp?uy!1rxWH@gzunW#Azyu0ZV_q5iZkz=|M1m>>b zPTdH-DPeM(6B^HHv)V^JZwQ}sz?h4O8FJE}0 zLPLdW%)9)1DAw1eI*b<_$_vO=zQSJ8cnVqr>pDN6TMeh42H;jS2^6wnGJT_UElrbD=-Z zY^eG&JA3E%@;zRyfF!Cs z-j+_B>EAc+^c(~rs2cH6%z8icy*qQgo&U${C)BQ;z}{*%EM lfPlaM((xrC;6DqJNx1QGn3v+J@D90%-H#47dArYC`ww}Or0xI! literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/SUB.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/SUB.png new file mode 100644 index 0000000000000000000000000000000000000000..c92598d92433605da0dad0483a878616237119d3 GIT binary patch literal 5239 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 Ws#^Zh+a5{=aQvv7L(7rStbYK=HBO`e literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/ULOG.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/ULOG.png new file mode 100644 index 0000000000000000000000000000000000000000..5a872ebc8931fee683cdeef1e13c30c147c7a4c1 GIT binary patch literal 4063 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 IzV*5MceQHY`v3p{ literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/VERSION.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/VERSION.png new file mode 100644 index 0000000000000000000000000000000000000000..b96b8ee5a83780fe9ec7f82f7924db2524130752 GIT binary patch literal 3362 zcmdT{YgCfi8vX!pX$0k1mWr-sx{M=su`=&umSb7jMJ+8g86zccsi`1{so9y*azwI5 z!NxR?hMM99mBMbOrCsSUL4PWG)aX6<{bbBEC z5=atKfa7nG)wm3n%=5w7Nbk7etjpNLXo_(Mt;DNv$5H>4!xuOlg zjyO{*cql>yIqM{DUR}@SGSW~lgU7V^Q%iAiLcrc03fciZ%sVTVjG-4^HQG`8CzMAO`|W z>JdnRk4QLv`rw5mkgb8g(5;(v$AN-im0fB`ig zp`%LOdhX(|ssHfmEi@9f3v;Qjk~N)n;)eBC-`8{`5$YMW;$$@(046;xF%(HLb;sjO zrWlkV7D-v$>>XQMC$B#~u2smi5dL`e8P2Fegpq||FX8di zK8?$?ienpg??7NR-Cx#!w9&CtI_iHmOlk|<6Pegj<>kr*3R%md#S9J&>rjm}??bIm z3`tz~dbK0pe`3cnZsK;8FUb)T2s-kk#KfwidG5D6TC$Ppx(Fh>I*akTgi6iUVF`Ww z$UW;qc*Ob(x#N#kzW7-^0>tx;uI3&EP_hce@{V5B}b)G+^K^ zjb3ciPSyv*^4evN;AiMx=gLtiKLT&0OE;V5$Z3vs!aF{hC6X)XQF}7wHLOD<^=EXT ziB5twNIa%1@UsS7V!dICC^AlOlpx^u(z)w(rUG7TAqwLhVzRg4JxZ|pY zLBg7yQBQnS_S5k=nrz`{bwI69*W$M(~v5QoG z9i(&2j?8v7M?}%}krZ7K!D|zMeccM1DTZpjeJ9s>Q~`xv-4AYh4g8#OUK?rgM??T> zlq84@zy7(*g4-}N1uQJV9RE;gz&o9+b@}Uf{~%DQ|DqOU6h3Iabd?>ddFiRr1@bcV zf3H+V7Mm)~u>s$&lQKd>H30YAnM$%Ze0*r%%1d;8Qy_cj1LFZ<3fC=)yN{No0A zf;~j9Twbw_<=DXf1p=^+Z58&G@e?>%PNgd8$j&fo)ze}}K)5Hrx$9*@($O(lvZefdFIqwteL}dbLy9agO z_(0O%ew)RaIFFBN*d{d;oeYiZKGhP8_V?ZCAI?)u@T_HRqUFZoculY=Y_kqTFS)l7 z%7{@9#TD&;_dGi%_tu6DMbwPy2x<#9^m6o!ER%l$f61U&tlB8m-dQ0;ul0X@!$(*k zi4i{AyPf7cR73NT3Et3w_~n$UPzh$%?4s3zMzQ48VBx2j{+iTGx;Lz*G%f_sgy)Bv z<03Lk@6&xtM9Qn{UYryyL+f7mE%TLsx^K(7bvxS`cy@$f^{{Bg=a;=B)@Vy3Zy{uP z0^B;o%&yAZF8Y*1!l(RAF6jls_R0b4bnKz~t6WXZyyQt&UI}@tnLTXzJfk~;5^mWt z8pd`Cj|qyk#O(ZuSv~ZURh#Pr$G|z|2MBAzH4<+#Shw%kaWZSgz4(w*lIbueE;Rj3 zmwu~*r4gh8ltCOWf)slHCGADZ$lfI`b!Fju=azCO!pvV}YSX0YYjKvQkiA9FwDq*{ z^tj2i2lOLMLAy`yXh2-vmC@9Yb)pa!7Q$T(MK0TtM-k_a8y4l~DachL0%`R(m#$Vb zQ?}v}r~yKVV(Gb6l(>kL+e;$P+;o>t)b`k5_nES7Ns^UU{UXczw!T-_vQA|=-w`ma zxnr{$ST_eg8eeC?-D+fU&ad&}DA%rjrC6g7l&yI&(si)XYUt${32&_^JuH_U78;(d z^j+6`7F$#!+LNw_ys3{=S1CSBFdr_ce+_`8Z9q7#9ob@BcK_;z%3(c(tO?8apH`09 z$aJ1X%a0E>uDCbDUK_7)@(qk5mpq#KOn|&Opskl->U0(jUrDPNXQ100?F0KyG~I3Z zgozAajiU+hPJxxPJL==TnKL#K;S4`UM8_8nqsvC9cs#(^)eiJ_$@m5QR7{rJj8&a{(p z4&>V?gQewl6~Q-}cax=&mHqz0jj7A?x_th=ee<Yrt^pR@m&&D`7VOcoa3jJLru4Z>gJ&HcaoF-V4Wc5Em_aBR>Z P8Gy&0gKibBK^Ol4Y932f literal 0 HcmV?d00001 diff --git a/yellow-paper/docs/public-vm/gen/images/bit-formats/XOR.png b/yellow-paper/docs/public-vm/gen/images/bit-formats/XOR.png new file mode 100644 index 0000000000000000000000000000000000000000..d6d4e80c525500ff7a75b8ec8cfedf4960d026b5 GIT binary patch literal 5264 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 literal 0 HcmV?d00001 diff --git a/yellow-paper/package.json b/yellow-paper/package.json index ad92226d9ad7..4e2bf4503ee1 100644 --- a/yellow-paper/package.json +++ b/yellow-paper/package.json @@ -4,13 +4,14 @@ "private": true, "scripts": { "docusaurus": "docusaurus", - "start": "docusaurus start", - "start:dev": "docusaurus start --host 0.0.0.0", + "start": "yarn preprocess && docusaurus start", + "start:dev": "yarn preprocess && docusaurus start --host 0.0.0.0", "build": "docusaurus build", "swizzle": "docusaurus swizzle", "deploy": "docusaurus deploy", "clear": "docusaurus clear", "serve": "docusaurus serve", + "preprocess": "yarn node ./src/preprocess/index.js", "write-translations": "docusaurus write-translations", "write-heading-ids": "docusaurus write-heading-ids", "typecheck": "tsc" @@ -23,6 +24,7 @@ "prism-react-renderer": "^1.3.5", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-markdown": "6.0.0", "rehype-katex": "5", "remark-math": "3" }, diff --git a/yellow-paper/src/preprocess/InstructionSet/InstructionSet.js b/yellow-paper/src/preprocess/InstructionSet/InstructionSet.js new file mode 100644 index 000000000000..176c852e677f --- /dev/null +++ b/yellow-paper/src/preprocess/InstructionSet/InstructionSet.js @@ -0,0 +1,979 @@ +const {instructionSize} = require('./InstructionSize'); + +const TOPICS_IN_TABLE = [ + "Name", "Summary", "Bit-size", "Expression", +]; +const TOPICS_IN_SECTIONS = [ + "Name", "Summary", "Category", "Flags", "Args", "Expression", "Details", "Tag checks", "Tag updates", "Bit-size", +]; + +const OP_TYPE_DESCRIPTION = "The [type/size](./Types) to check inputs against and tag the output with."; +const DEST_TYPE_DESCRIPTION = "The [type/size](./Types) to tag the output with when different from `op-type`."; + +const INSTRUCTION_SET_RAW = [ + { + "id": "add", + "Name": "`ADD`", + "Category": "arithmetic", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] + M[bOffset] mod 2^k`", + "Summary": "Addition (a + b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "sub", + "Name": "`SUB`", + "Category": "arithmetic", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] - M[bOffset] mod 2^k`", + "Summary": "Subtraction (a - b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "div", + "Name": "`DIV`", + "Category": "arithmetic", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] / M[bOffset]`", + "Summary": "Unsigned division (a / b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "eq", + "Name": "`EQ`", + "Category": "conditional", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result", "type": "u8"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] == M[bOffset] ? 1 : 0`", + "Summary": "Equality check (a == b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "lt", + "Name": "`LT`", + "Category": "conditional", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result", "type": "u8"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] < M[bOffset] ? 1 : 0`", + "Summary": "Less-than check (a < b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "lte", + "Name": "`LTE`", + "Category": "conditional", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result", "type": "u8"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] <= M[bOffset] ? 1 : 0`", + "Summary": "Less-than-or-equals check (a <= b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "and", + "Name": "`AND`", + "Category": "bitwise", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] AND M[bOffset]`", + "Summary": "Bitwise AND (a & b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "or", + "Name": "`OR`", + "Category": "bitwise", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] OR M[bOffset]`", + "Summary": "Bitwise OR (a | b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "xor", + "Name": "`XOR`", + "Category": "bitwise", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] XOR M[bOffset]`", + "Summary": "Bitwise XOR (a ^ b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "not", + "Name": "`NOT`", + "Category": "bitwise", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = NOT M[aOffset]`", + "Summary": "Bitwise NOT (inversion)", + "Details": "", + "Tag checks": "`T[aOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "shl", + "Name": "`SHL`", + "Category": "bitwise", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] << M[bOffset]`", + "Summary": "Bitwise leftward shift (a << b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "shr", + "Name": "`SHR`", + "Category": "bitwise", + "Flags": [ + {"name": "op-type", "description": OP_TYPE_DESCRIPTION}, + ], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of the operation's left input"}, + {"name": "bOffset", "description": "memory offset of the operation's right input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[aOffset] >> M[bOffset]`", + "Summary": "Bitwise rightward shift (a >> b)", + "Details": "", + "Tag checks": "`T[aOffset] == T[bOffset] == op-type`", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "set", + "Name": "`SET`", + "Category": "memory", + "Flags": [ + {"name": "op-type", "description": "The [type/size](./Types) to check inputs against and tag the output with. `field` type is NOT supported for SET."}, + ], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "const", "description": "a constant value from the bytecode to store in memory (any type except `field`)", "mode": "immediate"}, + {"name": "dstOffset", "description": "memory offset specifying where to store the constant"}, + ], + "Expression": "`M[dstOffset] = const`", + "Summary": "Set a memory word from a constant in the bytecode.", + "Details": "Set memory word at `dstOffset` to `const`'s immediate value. `const` _cannot be `field` type_!", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = op-type`", + }, + { + "id": "mov", + "Name": "`MOV`", + "Category": "memory", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "srcOffset", "description": "memory offset of word to move"}, + {"name": "dstOffset", "description": "memory offset specifying where to store that word"}, + ], + "Expression": "`M[dstOffset] = M[srcOffset]`", + "Summary": "Move a word from source memory location to destination`.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = T[srcOffset]`", + }, + { + "id": "cmov", + "Name": "`CMOV`", + "Category": "memory", + "Flags": [], + "#memreads": "3", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of word 'a' to conditionally move"}, + {"name": "bOffset", "description": "memory offset of word 'b' to conditionally move"}, + {"name": "condOffset", "description": "memory offset of the operations 'conditional' input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = M[condOffset] > 0 ? M[aOffset] : M[bOffset]`", + "Summary": "Move a word (conditionally chosen) from one memory location to another (`d = cond > 0 ? a : b`).", + "Details": "One of two source memory locations is chosen based on the condition. `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type.", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = M[condOffset] > 0 ? T[aOffset] : T[bOffset]`", + }, + { + "id": "cast", + "Name": "`CAST`", + "Category": "types", + "Flags": [ + {"name": "dest-type", "description": DEST_TYPE_DESCRIPTION}, + ], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "aOffset", "description": "memory offset of word to cast"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = cast(M[aOffset])`", + "Summary": "Type cast", + "Details": "Cast a word in memory based on the `dest-type` specified in the bytecode. Truncates when casting to a smaller type, left-zero-pads when casting to a larger type.", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = dest-type`", + }, + { + "id": "calldatacopy", + "Name": "`CALLDATACOPY`", + "Category": "contract calls", + "Flags": [], + "#memreads": "`s1`", + "#memwrites": "`s1`", + "Args": [ + {"name": "cdOffset", "description": "offset into calldata to copy from"}, + {"name": "size", "description": "number of words to copy", "mode": "immediate", "type": "u24"}, + {"name": "dstOffset", "description": "memory offset specifying where to copy the first word to"}, + ], + "Expression": "`M[dstOffset:dstOffset+size] = calldata[cdOffset:cdOffset+size]`", + "Summary": "Copy calldata into memory.", + "Details": "Calldata is read-only and cannot be directly operated on by other instructions. This instruction moves words from calldata into memory so they can be operated on normally.", + "Tag checks": "", + "Tag updates": "`T[dstOffset:dstOffset+size] = field`", + }, + { + "id": "sload", + "Name": "`SLOAD`", + "Category": "storage & messaging", + "Flags": [], + "#memreads": "2", + "#memwrites": "1", + "Args": [ + {"name": "slotOffset", "description": "memory offset of the storage slot to load from"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = storage[M[slotOffset]]`", + "Summary": "Load a word from storage.", + "Details": "Load a word from this contract's persistent public storage into memory.", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "sstore", + "Name": "`SSTORE`", + "Category": "storage & messaging", + "Flags": [], + "#memreads": "2", + "#memwrites": "0", + "Args": [ + {"name": "srcOffset", "description": "memory offset of the word to store"}, + {"name": "slotOffset", "description": "memory offset containing the storage slot to store to"}, + ], + "Expression": "`storage[M[slotOffset]] = M[srcOffset]`", + "Summary": "Write a word to storage.", + "Details": "Store a word from memory into this contract's persistent public storage.", + "Tag checks": "", + "Tag updates": "", + }, + { + "id": "l1l2msgload", + "Name": "`L1L2MSGLOAD`", + "Category": "storage & messaging", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "keyOffset", "description": "memory offset of the message key"}, + {"name": "dstMsgOffset", "description": "memory offset specifying where to store the `L1_TO_L2_MESSAGE_LENGTH` words of the retrieved message"}, + {"name": "dstSibPathOffset", "description": "memory offset specifying where to store the `L1_TO_L2_MSG_TREE_HEIGHT` words of the retrieved message's sibling path"}, + {"name": "dstLeafIndexOffset", "description": "memory offset specifying where to store the retrieved message's leaf index"}, + {"name": "dstRootOffset", "description": "memory offset specifying where to store the retrieved message tree root"}, + ], + "Expression": ` +{ + M[dstMsgOffset], + M[dstSibPathOffset], + M[dstLeafIndexOffset], + M[dstRootOffset] +} = getL1ToL2Message(M[keyOffset]) +`, + "Summary": "Retrieve an L1-to-L2 message by key", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dst*Offset] = field`", + }, + { + "id": "sendl2tol1msg", + "Name": "`SENDL1TOL2MSG`", + "Category": "storage & messaging", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "keyOffset", "description": "memory offset of the message key"}, + {"name": "dstMsgOffset", "description": "memory offset specifying where to store the `L1_TO_L2_MESSAGE_LENGTH` words of the retrieved message"}, + {"name": "dstSibPathOffset", "description": "memory offset specifying where to store the `L1_TO_L2_MSG_TREE_HEIGHT` words of the retrieved message's sibling path"}, + {"name": "dstLeafIndexOffset", "description": "memory offset specifying where to store the retrieved message's leaf index"}, + {"name": "dstRootOffset", "description": "memory offset specifying where to store the retrieved message tree root"}, + ], + "Expression": ` +{ + M[dstMsgOffset], + M[dstSibPathOffset], + M[dstLeafIndexOffset], + M[dstRootOffset] +} = getL1ToL2Message(M[keyOffset]) +`, + "Summary": "Retrieve an L1-to-L2 message by key", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dst*Offset] = field`", + }, + { + "id": "jump", + "Name": "`JUMP`", + "Category": "control", + "Flags": [], + "#memreads": "0", + "#memwrites": "0", + "Args": [ + {"name": "loc", "description": "target location to jump to", "mode": "immediate", "type": "u24"}, + ], + "Expression": "`PC = loc`", + "Summary": "Jump to a location in the bytecode.", + "Details": "Target location is an immediate value (a constant in the bytecode).", + "Tag checks": "", + "Tag updates": "", + }, + { + "id": "jumpi", + "Name": "`JUMPI`", + "Category": "control", + "Flags": [], + "#memreads": "3", + "#memwrites": "0", + "Args": [ + {"name": "loc", "description": "target location conditionally jump to", "mode": "immediate", "type": "u24"}, + {"name": "condOffset", "description": "memory offset of the operations 'conditional' input"}, + ], + "Expression": "`PC = M[condOffset] > 0 ? loc : PC`", + "Summary": "Conditionally jump to a location in the bytecode.", + "Details": "Target location is an immediate value (a constant in the bytecode). `T[condOffset]` is not checked because the greater-than-zero suboperation is the same regardless of type.", + "Tag checks": "", + "Tag updates": "", + }, + { + "id": "return", + "Name": "`RETURN`", + "Category": "contract calls", + "Flags": [], + "#memreads": "`s1`", + "#memwrites": "0", + "Args": [ + {"name": "offset", "description": "memory offset of first word to return"}, + {"name": "size", "description": "number of words to return", "mode": "immediate", "type": "u24"}, + ], + "Expression": "`return(M[offset:offset+size])`", + "Summary": "Halt execution with `success`, optionally returning some data.", + "Details": "Return control flow to the calling context/contract.", + "Tag checks": "", + "Tag updates": "", + }, + { + "id": "revert", + "Name": "`REVERT`", + "Category": "contract calls", + "Flags": [], + "#memreads": "`s1`", + "#memwrites": "0", + "Args": [ + {"name": "offset", "description": "memory offset of first word to return"}, + {"name": "size", "description": "number of words to return", "mode": "immediate", "type": "u24"}, + ], + "Expression": "`revert(M[offset:offset+size])`", + "Summary": "Halt execution with `failure`, optionally returning some data.", + "Details": "Return control flow to the calling context/contract.", + "Tag checks": "", + "Tag updates": "", + }, + { + "id": "call", + "Name": "`CALL`", + "Category": "contract calls", + "Flags": [], + "#memreads": "5", + "#memwrites": "`1+retSize`", + "Args": [ + {"name": "l1GasOffset", "description": "amount of L1 gas to provide to the callee"}, + {"name": "l2GasOffset", "description": "amount of L2 gas to provide to the callee"}, + {"name": "addrOffset", "description": "address of the contract to call"}, + {"name": "argsOffset", "description": "memory offset to args (will become the callee's calldata)"}, + {"name": "argsSize", "description": "number of words to pass via callee's calldata", "mode": "immediate", "type": "u24"}, + {"name": "retOffset", "description": "destination memory offset specifying where to store the data returned from the callee"}, + {"name": "retSize", "description": "number of words to copy from data returned by callee", "mode": "immediate", "type": "u24"}, + {"name": "successOffset", "description": "destination memory offset specifying where to store the call's success (0: failure, 1: success)", "type": "u8"}, + ], + "Expression":` +M[successOffset] = call( + M[l1GasOffset], M[l2GasOffset], M[addrOffset], + M[argsOffset], M[argsSize], + M[retOffset], M[retSize]) +`, + "Summary": "Call into another contract.", + "Details": `Creates a new CallContext, triggers execution of the corresponding contract code, + and then resumes execution in the current CallContext. A non-existent contract or one + with no code will return success. Nested call has an incremented \`CallContext.calldepth\`.`, + "Tag checks": "`T[l1GasOffset] == T[l2GasOffset] == u32`", + "Tag updates": ` +T[successOffset] = u8 +T[retOffset:retOffset+retSize] = field +`, + }, + { + "id": "staticcall", + "Name": "`STATICCALL`", + "Category": "contract calls", + "Flags": [], + "#memreads": "5", + "#memwrites": "`1+retSize`", + "Args": [ + {"name": "l1GasOffset", "description": "amount of L1 gas to provide to the callee"}, + {"name": "l2GasOffset", "description": "amount of L2 gas to provide to the callee"}, + {"name": "addrOffset", "description": "address of the contract to call"}, + {"name": "argsOffset", "description": "memory offset to args (will become the callee's calldata)"}, + {"name": "argsSize", "description": "number of words to pass via callee's calldata", "mode": "immediate", "type": "u24"}, + {"name": "retOffset", "description": "destination memory offset specifying where to store the data returned from the callee"}, + {"name": "retSize", "description": "number of words to copy from data returned by callee", "mode": "immediate", "type": "u24"}, + {"name": "successOffset", "description": "destination memory offset specifying where to store the call's success (0: failure, 1: success)", "type": "u8"}, + ], + "Expression": ` +M[successOffset] = staticcall( + M[l1GasOffset], M[l2GasOffset], M[addrOffset], + M[argsOffset], M[argsSize], + M[retOffset], M[retSize]) +`, + "Summary": "Call into another contract, disallowing persistent state modifications.", + "Details": "Same as `CALL`, but the callee is cannot modify persistent state. Disallowed instructions are `SSTORE`, `ULOG`, `CALL`.", + "Tag checks": "`T[l1GasOffset] == T[l2GasOffset] == u32`", + "Tag updates": ` +T[successOffset] = u8 +T[retOffset:retOffset+retSize] = field +`, + }, + { + "id": "ulog", + "Name": "`ULOG`", + "Category": "logging", + "Flags": [], + "#memreads": "`s1`", + "#memwrites": "0", + "Args": [ + {"name": "offset", "description": "memory offset of the data to log"}, + {"name": "size", "description": "number of words to log", "mode": "immediate", "type": "u24"}, + ], + "Expression": "`ulog(M[offset:offset+size])`", + "Summary": "Emit an unencrypted log with data from the `field` memory page", + "Details": "", + "Tag checks": "", + "Tag updates": "", + }, + { + "id": "chainid", + "Name": "`CHAINID`", + "Category": "block info", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = Globals.chainId`", + "Summary": "Get this rollup's L1 chain ID", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "version", + "Name": "`VERSION`", + "Category": "block info", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = Globals.version`", + "Summary": "Get this rollup's L2 version ID", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "blocknumber", + "Name": "`BLOCKNUMBER`", + "Category": "block info", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = Globals.blocknumber`", + "Summary": "Get this block's number", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "timestamp", + "Name": "`TIMESTAMP`", + "Category": "block info", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = Globals.timestamp`", + "Summary": "Get this L2 block's timestamp", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u64`", + }, + { + "id": "coinbase", + "Name": "`COINBASE`", + "Category": "block info", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = Globals.coinbase`", + "Summary": "Get the block's beneficiary address", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "blockl1gaslimit", + "Name": "`BLOCKL1GASLIMIT`", + "Category": "block info", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = Globals.l1GasLimit`", + "Summary": "Total amount of \"L1 gas\" that a block can consume", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "blockl2gaslimit", + "Name": "`BLOCKL2GASLIMIT`", + "Category": "block info", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = Globals.l2GasLimit`", + "Summary": "Total amount of \"L2 gas\" that a block can consume", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "notesroot", + "Name": "`NOTESROOT`", + "Category": "historical access", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "blockNumOffset", "description": "memory offset of the block number input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].note_hash_tree_root`", + "Summary": "Get the historical note-hash tree root as of the specified block number.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "nullroot", + "Name": "`NULLIFIERSROOT`", + "Category": "historical access", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "blockNumOffset", "description": "memory offset of the block number input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].nullifier_tree_root`", + "Summary": "Get the historical nullifier tree root as of the specified block number.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "contractsroot", + "Name": "`CONTRACTSROOT`", + "Category": "historical access", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "blockNumOffset", "description": "memory offset of the block number input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].contracts_tree_root`", + "Summary": "Get the historical contracts tree root as of the specified block number.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "msgsroot", + "Name": "`MSGSROOT`", + "Category": "historical access", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "blockNumOffset", "description": "memory offset of the block number input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].l1_to_l2_messages_tree_root`", + "Summary": "Get the historical l1-to-l2 messages tree root as of the specified block number.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "blocksroot", + "Name": "`BLOCKSROOT`", + "Category": "historical access", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "blockNumOffset", "description": "memory offset of the block number input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].blocks_tree_root`", + "Summary": "Get the historical blocks tree root as of the specified block number.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "publicdataroot", + "Name": "`PUBLICDATAROOT`", + "Category": "historical access", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "blockNumOffset", "description": "memory offset of the block number input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].public_data_tree_root`", + "Summary": "Get the historical public data tree root as of the specified block number.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "globalshash", + "Name": "`GLOBALSHASH`", + "Category": "historical access", + "Flags": [], + "#memreads": "1", + "#memwrites": "1", + "Args": [ + {"name": "blockNumOffset", "description": "memory offset of the block number input"}, + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = HistoricalBlockData[M[blockNumOffset]].global_variables_hash`", + "Summary": "Get the historical global variables hash as of the specified block number.", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = field`", + }, + { + "id": "origin", + "Name": "`ORIGIN`", + "Category": "tx context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = TxContext.origin`", + "Summary": "Get the transaction's origination address", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "refundee", + "Name": "`REFUNDEE`", + "Category": "tx context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = TxContext.refundee`", + "Summary": "The recipient of fee refunds for this transaction", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "feeperl1gas", + "Name": "`FEEPERL1GAS`", + "Category": "tx context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = TxContext.feePerL1Gas`", + "Summary": "The fee to be paid per \"L1 gas\" - set by the transaction's original caller", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "feeperl2gas", + "Name": "`FEEPERL2GAS`", + "Category": "tx context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = TxContext.feePerL2Gas`", + "Summary": "The fee to be paid per \"L2 gas\" - set by the transaction's original caller", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "caller", + "Name": "`CALLER`", + "Category": "call context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = CallContext.sender`", + "Summary": "Get the address of the sender (the caller's context)", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "address", + "Name": "`ADDRESS`", + "Category": "call context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = CallContext.storageContractAddress`", + "Summary": "Get the address of the currently executing l2 contract", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "portal", + "Name": "`PORTAL`", + "Category": "call context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = CallContext.portalAddress`", + "Summary": "Get the address of the l1 portal contract", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "calldepth", + "Name": "`CALLDEPTH`", + "Category": "call context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = CallContext.calldepth`", + "Summary": "Get how many calls deep the current call context is", + "Details": "Note: security issues with EVM's tx.origin can be resolved by asserting the `calldepth == 0`.", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u8`", + }, + { + "id": "l1gas", + "Name": "`L1GAS`", + "Category": "latest context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = LatestContext.l1Gas`", + "Summary": "Remaining \"L1 gas\" for this call (after this instruction).", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, + { + "id": "l2gas", + "Name": "`L2GAS`", + "Category": "latest context", + "Flags": [], + "#memreads": "0", + "#memwrites": "1", + "Args": [ + {"name": "dstOffset", "description": "memory offset specifying where to store operation's result"}, + ], + "Expression": "`M[dstOffset] = LatestContext.l2Gas`", + "Summary": "Remaining \"L2 gas\" for this call (after this instruction).", + "Details": "", + "Tag checks": "", + "Tag updates": "`T[dstOffset] = u32`", + }, +]; +const INSTRUCTION_SET = INSTRUCTION_SET_RAW.map((instr) => {instr['Bit-size'] = instructionSize(instr); return instr;}); + +module.exports = { + TOPICS_IN_TABLE, + TOPICS_IN_SECTIONS, + INSTRUCTION_SET, +}; diff --git a/yellow-paper/src/preprocess/InstructionSet/InstructionSetMarkdownGen.js b/yellow-paper/src/preprocess/InstructionSet/InstructionSetMarkdownGen.js new file mode 100644 index 000000000000..310efe12f20b --- /dev/null +++ b/yellow-paper/src/preprocess/InstructionSet/InstructionSetMarkdownGen.js @@ -0,0 +1,137 @@ +const fs = require("fs"); +const path = require("path"); + +const { + TOPICS_IN_TABLE, + TOPICS_IN_SECTIONS, + INSTRUCTION_SET, + instructionSize +} = require('./InstructionSet'); + +function escapeBraces(str) { + return str.replace(//g, ">"); +} + +function stripBraces(str) { + return str.replace(/[<>]/g, ''); +} + +function instructionSetPreface() { + let preface = "[comment]: # (THIS IS A GENERATED FILE! DO NOT EDIT!)\n"; + preface += "[comment]: # (Generated via `yarn preprocess`)\n\n"; + preface += "[comment]: # (Generated by InstructionSetMarkdownGen.tsx and InstructionSet.js)\n\n"; + preface += "import Markdown from 'react-markdown'\n"; + preface += "import CodeBlock from '@theme/CodeBlock'\n\n"; + return preface; +} + +function toOpcode(index) { + return '0x' + index.toString(16).padStart(2, '0'); +} + +function htmlInstructionSetTable() { + let table = "## Instructions Table\n"; + table += "\n\n"; + let header = ""; + for (let t = 0; t < TOPICS_IN_TABLE.length; t++) { + header += ``; + } + table += `${header}\n`; + + for (let i = 0; i < INSTRUCTION_SET.length; i++) { + const instr = INSTRUCTION_SET[i]; + const name = instr['Name']; + let row = `\n`; + row += `\t`; + row += `\t`; + + for (let t = 0; t < TOPICS_IN_TABLE.length; t++) { + const topic = TOPICS_IN_TABLE[t]; + + if (topic == 'Name') continue; // skip + let cell = instr[topic]; + if (cell[0] == '\n') { // if string starts with newline, assume it's a multi-line code block + cell = `\n{\`${cell.trim()}\`}\n\t`; + } else if (cell[0] == '`' && topic != 'Name') { + cell = `{\n\t\t\`${cell.replace(/`/g, '')}\`\n\t}`; + } else { + cell = escapeBraces(cell); // escape html + cell = `${cell}`; + } + row += `\n\t`; + } + row += "\n"; + table += `${row}\n`; + } + table += "
Opcode${TOPICS_IN_TABLE[t]}
${toOpcode(i)}[${stripBraces(name)}](#isa-section-${instr['id']})${cell}
\n"; + return table; +} + +function markdownSublist(items) { + let markdown = ""; + for (let i = 0; i < items.length; i++) { + let item = items[i]; + if (typeof item === 'string') { + markdown += `\n\t- ${item}`; + } else { + markdown += `\n\t- **${item['name']}**: ${item['description']}`; + } + } + return markdown; +} + +function markdownInstructionSetSection(pathToGenDir) { + let markdown = "## Instructions\n"; + for (let i = 0; i < INSTRUCTION_SET.length; i++) { + const instr = INSTRUCTION_SET[i]; + const name = instr['Name']; + let subsection = `###
${name} (${toOpcode(i)})\n`; + subsection += `${instr['Summary']}\n\n`; + subsection += `[See in table.](#isa-table-${instr['id']})\n\n`; + for (let t = 0; t < TOPICS_IN_SECTIONS.length; t++) { + const topic = TOPICS_IN_SECTIONS[t]; + let field = instr[topic]; + if (topic == 'Name' || topic == 'Summary' || !field || field.length == 0) continue; // skip + + let item = `- **${topic}**: ` + if (Array.isArray(field) ) { + item += markdownSublist(field); + } else if (field[0] == '\n') { // if string starts with newline, assume it's a multi-line code block + item += `\n\n{\`${field.trim()}\`}\n`; + } else { + item += field; + } + subsection += `${item}\n`; + } + const bitFormatPath = `./images/bit-formats/${name.replace(/`/g, '')}.png`; + if (fs.existsSync(`${pathToGenDir}/${bitFormatPath}`)) { + subsection += `\n![](${bitFormatPath})`; + } + markdown += `\n${subsection}\n`; + } + return markdown; +} + +async function generateInstructionSet() { + const rootDir = path.join(__dirname, "../../../"); + const docsDir = path.join(rootDir, "docs", "docs"); + + const relPath = path.relative(docsDir, "docs/public-vm/gen/_InstructionSet.mdx"); + const docsFilePath = path.resolve(docsDir, relPath); + const docsDirName = path.dirname(docsFilePath); + if (!fs.existsSync(docsDirName)) { + fs.mkdirSync(docsDirName, { recursive: true }); + } + + const preface = instructionSetPreface(); + const table = htmlInstructionSetTable(); + const section = markdownInstructionSetSection(docsDirName); + const doc = `${preface}\n${table}\n\n${section}`; + fs.writeFileSync(docsFilePath, doc); + + console.log("Preprocessing complete."); +} + +module.exports = { + generateInstructionSet, +}; \ No newline at end of file diff --git a/yellow-paper/src/preprocess/InstructionSet/InstructionSize.js b/yellow-paper/src/preprocess/InstructionSet/InstructionSize.js new file mode 100644 index 000000000000..37555faa4a3d --- /dev/null +++ b/yellow-paper/src/preprocess/InstructionSet/InstructionSize.js @@ -0,0 +1,80 @@ +const FIELD_SIZES = { // in bits + "Opcode": 8, + "Indirect": 8, +}; + +const DEFAULT_OPERAND_SIZE = 24; // for direct/indirect memory offsets + +function argSize(arg) { + if (arg['mode'] && arg['mode'] == 'immediate') { + if (arg['type']) { + return Number(arg['type'].replace(/u/, '')); + } else { + return undefined; // none specified! + } + } else { + return DEFAULT_OPERAND_SIZE; + } +} + +function toOpcode(index) { + return '0x' + index.toString(16).padStart(2, '0'); +} + +/* Compute bit-size of instruction based on flags and number of operands, + * whether they are immediate (and op-type if so) + * + * All instructions have: + * - 1 byte for opcode + * - 1 byte to toggle indirect mode for up to 8 non-immediate args + * 24 bits per-arg (for non-immediates) + * N bits per immediate arg, where N is 8, 16, 32, 64, or 128 based on type + * 1 byte for op-type + * 1 byte for dest-type + */ +function instructionSize(instr) { + let size = FIELD_SIZES['Opcode'] + FIELD_SIZES['Indirect']; + let numUntypedImmediates = 0; + for (let arg of instr['Args']) { + const aSize = argSize(arg); + if (aSize === undefined) { + numUntypedImmediates++; + } else { + size += aSize; + } + } + if (instr['Flags']) { + // assigns each flag a byte (op-type, dest-type) + size += instr['Flags'].length * 8; + } + let sizeStr = size.toString(); + if (numUntypedImmediates > 0) { + sizeStr += '+N'; + } + return sizeStr; +} + +function instructionBitFormat(instr, index) { + let bitFormat = { 'Name': instr['Name'], 'Opcode': {'code': toOpcode(index), 'size': 8}, 'Indirect': 8, 'Args': [], 'Flags': [] }; + + //for (let arg of instr['Args']) { + for (let a = 0; a < instr['Args'].length; a++) { + const arg = instr['Args'][a]; + const aSize = argSize(arg); + if (aSize === undefined) { + bitFormat['Args'][a] = {"name": arg['name'], "size": 'N'}; + } else { + bitFormat['Args'][a] = {"name": arg['name'], "size": aSize}; + } + } + for (let f = 0; f < instr['Flags'].length; f++) { + const flag = instr['Flags'][f]; + bitFormat['Flags'][f] = {"name": flag['name'], "size": 8}; + } + return bitFormat; +} + +module.exports = { + instructionSize, + instructionBitFormat, +}; \ No newline at end of file diff --git a/yellow-paper/src/preprocess/InstructionSet/genBitFormats.js b/yellow-paper/src/preprocess/InstructionSet/genBitFormats.js new file mode 100644 index 000000000000..968b769f51d8 --- /dev/null +++ b/yellow-paper/src/preprocess/InstructionSet/genBitFormats.js @@ -0,0 +1,16 @@ +const fs = require("fs"); + +const {instructionBitFormat} = require('./InstructionSize'); +const {INSTRUCTION_SET} = require('./InstructionSet'); + +function run() { + const formats = []; + for (let i = 0; i < INSTRUCTION_SET.length; i++) { + const instr = INSTRUCTION_SET[i]; + const bitFormat = instructionBitFormat(instr, i); + console.log(JSON.stringify(bitFormat)); + formats.push(bitFormat); + } + fs.writeFileSync('./InstructionBitFormats.json', JSON.stringify(formats)); +} +run(); \ No newline at end of file diff --git a/yellow-paper/src/preprocess/index.js b/yellow-paper/src/preprocess/index.js new file mode 100644 index 000000000000..71c4227df065 --- /dev/null +++ b/yellow-paper/src/preprocess/index.js @@ -0,0 +1,6 @@ +const {generateInstructionSet} = require('./InstructionSet/InstructionSetMarkdownGen'); + +async function run() { + await generateInstructionSet(); +} +run(); \ No newline at end of file diff --git a/yellow-paper/yarn.lock b/yellow-paper/yarn.lock index 3e351ffa1465..9692b54cac9e 100644 --- a/yellow-paper/yarn.lock +++ b/yellow-paper/yarn.lock @@ -3376,7 +3376,7 @@ debug@2.6.9, debug@^2.6.0: dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -5142,6 +5142,17 @@ mdast-util-definitions@^4.0.0: dependencies: unist-util-visit "^2.0.0" +mdast-util-from-markdown@^0.8.0: + version "0.8.5" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz#d1ef2ca42bc377ecb0463a987910dae89bd9a28c" + integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-string "^2.0.0" + micromark "~2.11.0" + parse-entities "^2.0.0" + unist-util-stringify-position "^2.0.0" + mdast-util-to-hast@10.0.1: version "10.0.1" resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" @@ -5156,6 +5167,20 @@ mdast-util-to-hast@10.0.1: unist-util-position "^3.0.0" unist-util-visit "^2.0.0" +mdast-util-to-hast@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz#61875526a017d8857b71abc9333942700b2d3604" + integrity sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + mdast-util-definitions "^4.0.0" + mdurl "^1.0.0" + unist-builder "^2.0.0" + unist-util-generated "^1.0.0" + unist-util-position "^3.0.0" + unist-util-visit "^2.0.0" + mdast-util-to-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" @@ -5203,6 +5228,14 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromark@~2.11.0: + version "2.11.4" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.11.4.tgz#d13436138eea826383e822449c9a5c50ee44665a" + integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== + dependencies: + debug "^4.0.0" + parse-entities "^2.0.0" + micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -6202,6 +6235,11 @@ react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.0: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-json-view@^1.21.3: version "1.21.3" resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" @@ -6224,6 +6262,24 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" +react-markdown@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-6.0.0.tgz#e63cd32d095e864384d524986c44c34c919de517" + integrity sha512-MC+zljUJeoLb4RbDm/wRbfoQFEZGz4TDOt/wb4dEehdaJWxLMn/T2IgwhQy0VYhuPEd2fhd7iOayE8lmENU0FA== + dependencies: + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.3" + comma-separated-tokens "^1.0.0" + prop-types "^15.7.2" + property-information "^5.0.0" + react-is "^17.0.0" + remark-parse "^9.0.0" + remark-rehype "^8.0.0" + space-separated-tokens "^1.1.0" + style-to-object "^0.3.0" + unified "^9.0.0" + unist-util-visit "^2.0.0" + react-router-config@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" @@ -6461,6 +6517,20 @@ remark-parse@8.0.3: vfile-location "^3.0.0" xtend "^4.0.1" +remark-parse@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" + integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== + dependencies: + mdast-util-from-markdown "^0.8.0" + +remark-rehype@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-8.1.0.tgz#610509a043484c1e697437fa5eb3fd992617c945" + integrity sha512-EbCu9kHgAxKmW1yEYjx3QafMyGY3q8noUbNUI5xyKbaFP89wbhDrKxyIQNukNYthzjNHZu6J7hwFg7hRm1svYA== + dependencies: + mdast-util-to-hast "^10.2.0" + remark-squeeze-paragraphs@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" @@ -6881,7 +6951,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -space-separated-tokens@^1.0.0: +space-separated-tokens@^1.0.0, space-separated-tokens@^1.1.0: version "1.1.5" resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== From 1db30bf0d61a7b2920ab1aedaef58bc0922ec78e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Bene=C5=A1?= Date: Thu, 30 Nov 2023 13:58:45 +0100 Subject: [PATCH 05/37] refactor: naming fixes (#3476) Fixes https://github.com/AztecProtocol/aztec-packages/issues/3471 1. historic -> historical 2. `HistoricBlockData` -> `BlockHeader` 3. `Historic Blocks Tree` -> `Blocks Tree` 4. Blocks Tree was sometimes incorrectly referred to as Blocks Tree Roots so I fixed that in [this commit](https://github.com/AztecProtocol/aztec-packages/pull/3476/commits/8c9ae59bd9d6fb768fb08572aa61607634a7b65e). 5. Rewrote documentation of `perform_blocks_tree_membership_checks` in [this commit](https://github.com/AztecProtocol/aztec-packages/pull/3476/commits/8c9ae59bd9d6fb768fb08572aa61607634a7b65e) as it was confusing. 6. Fixed some stale naming of note hash tree (private data tree) --- .../circuits/abis/combined_constant_data.hpp | 14 +-- .../circuits/abis/historic_block_data.hpp | 14 +-- .../cpp/src/aztec3/circuits/abis/packers.hpp | 4 +- .../abis/private_circuit_public_inputs.hpp | 39 +++--- .../abis/public_circuit_public_inputs.hpp | 10 +- .../abis/rollup/base/base_rollup_inputs.hpp | 10 +- .../abis/rollup/constant_rollup_data.hpp | 4 +- .../abis/rollup/root/root_rollup_inputs.hpp | 8 +- .../rollup/root/root_rollup_public_inputs.hpp | 48 +++---- .../aztec3/circuits/apps/opcodes/opcodes.tpp | 4 +- .../apps/test_apps/escrow/transfer.cpp | 2 +- .../apps/test_apps/escrow/withdraw.cpp | 2 +- .../src/aztec3/circuits/apps/utxo_datum.hpp | 4 +- .../aztec3/circuits/kernel/private/common.cpp | 14 +-- .../aztec3/circuits/kernel/private/common.hpp | 2 +- .../native_private_kernel_circuit_init.cpp | 6 +- ...ative_private_kernel_circuit_init.test.cpp | 20 +-- .../native_private_kernel_circuit_inner.cpp | 8 +- ...tive_private_kernel_circuit_inner.test.cpp | 58 ++++----- .../kernel/private/testing_harness.cpp | 18 +-- .../kernel/private/testing_harness.hpp | 2 +- .../aztec3/circuits/kernel/public/.test.cpp | 18 +-- .../src/aztec3/circuits/rollup/base/.test.cpp | 17 ++- .../base/native_base_rollup_circuit.cpp | 49 ++++---- .../src/aztec3/circuits/rollup/root/.test.cpp | 6 +- .../root/native_root_rollup_circuit.cpp | 16 +-- .../circuits/rollup/test_utils/utils.cpp | 56 ++++----- circuits/cpp/src/aztec3/constants.hpp | 20 +-- .../cpp/src/aztec3/dbs/private_state_db.hpp | 2 +- circuits/cpp/src/aztec3/oracle/fake_db.hpp | 6 +- docs/docs/about_aztec/overview.mdx | 2 +- .../advanced/data_structures/trees.md | 6 +- .../communication/public_private_calls.md | 8 +- .../resources/common_patterns/main.md | 2 +- .../dev_docs/contracts/syntax/context.mdx | 12 +- .../docs/dev_docs/debugging/sandbox-errors.md | 10 +- .../aztecjs-getting-started.md | 2 +- .../dev_docs/getting_started/core-concepts.md | 2 +- docs/docs/dev_docs/limitations/main.md | 2 +- docs/docs/dev_docs/privacy/main.md | 6 +- docs/internal_notes/building_dapps.md | 2 +- .../dev_docs/sandbox/components.md | 2 +- .../src/core/libraries/ConstantsGen.sol | 4 +- l1-contracts/src/core/libraries/Decoder.sol | 8 +- .../src/core/messagebridge/Registry.sol | 2 +- .../acir-simulator/src/acvm/deserialize.ts | 10 +- .../acir-simulator/src/acvm/oracle/oracle.ts | 10 +- .../src/acvm/oracle/typed_oracle.ts | 4 +- .../acir-simulator/src/acvm/serialize.ts | 24 ++-- .../src/client/client_execution_context.ts | 14 +-- .../acir-simulator/src/client/db_oracle.ts | 10 +- .../src/client/private_execution.test.ts | 10 +- .../acir-simulator/src/client/simulator.ts | 8 +- .../client/unconstrained_execution.test.ts | 4 +- .../src/client/view_data_oracle.ts | 20 +-- .../acir-simulator/src/public/executor.ts | 6 +- .../acir-simulator/src/public/index.test.ts | 14 +-- .../src/public/public_execution_context.ts | 14 +-- .../src/aztec-node/http_rpc_server.ts | 4 +- .../aztec-node/src/aztec-node/server.ts | 18 ++- yarn-project/aztec-nr/aztec/src/abi.nr | 34 ++--- .../aztec-nr/aztec/src/constants_gen.nr | 4 +- yarn-project/aztec-nr/aztec/src/context.nr | 28 ++--- yarn-project/aztec-nr/aztec/src/oracle.nr | 2 +- .../aztec/src/oracle/get_block_data.nr | 39 ------ .../aztec/src/oracle/get_block_header.nr | 39 ++++++ .../src/artifacts/ecdsa_account_contract.json | 8 +- .../artifacts/schnorr_account_contract.json | 8 +- .../schnorr_single_key_account_contract.json | 8 +- yarn-project/circuits.js/src/abis/abis.ts | 28 ++--- yarn-project/circuits.js/src/constants.gen.ts | 4 +- yarn-project/circuits.js/src/structs/index.ts | 2 +- .../src/structs/kernel/block_header.test.ts | 17 +++ ...historic_block_data.ts => block_header.ts} | 24 ++-- .../structs/kernel/combined_constant_data.ts | 10 +- .../kernel/historic_block_data.test.ts | 17 --- .../structs/private_circuit_public_inputs.ts | 12 +- .../structs/public_circuit_public_inputs.ts | 10 +- .../src/structs/rollup/base_rollup.ts | 22 ++-- .../src/structs/rollup/root_rollup.ts | 62 +++++----- .../circuits.js/src/tests/factories.ts | 50 ++++---- .../src/integration_l1_publisher.test.ts | 14 +-- .../inclusion_proofs_contract/src/main.nr | 46 ++++--- .../contracts/test_contract/src/interface.nr | 9 +- .../src/__snapshots__/index.test.ts.snap | 6 +- .../__snapshots__/noir_test_gen.test.ts.snap | 2 +- .../crates/private-kernel-lib/src/common.nr | 12 +- .../src/private_kernel_init.nr | 10 +- .../src/private_kernel_inner.nr | 26 ++-- .../src/abis/constant_rollup_data.nr | 4 +- .../rollup-lib/src/base/base_rollup_inputs.nr | 66 +++++----- .../src/crates/rollup-lib/src/root.nr | 26 ++-- .../rollup-lib/src/root/root_rollup_inputs.nr | 6 +- .../src/root/root_rollup_public_inputs.nr | 16 +-- .../src/tests/root_rollup_inputs.nr | 16 +-- .../src/crates/types/src/abis.nr | 2 +- ...storical_block_data.nr => block_header.nr} | 4 +- .../types/src/abis/combined_constant_data.nr | 4 +- .../types/src/abis/membership_witness.nr | 6 +- .../src/abis/private_circuit_public_inputs.nr | 6 +- .../src/abis/public_circuit_public_inputs.nr | 6 +- .../src/crates/types/src/tests/fixtures.nr | 4 +- .../src/tests/previous_kernel_data_builder.nr | 8 +- .../private_circuit_public_inputs_builder.nr | 8 +- .../public_circuit_public_inputs_builder.nr | 8 +- .../noir-protocol-circuits/src/index.test.ts | 16 +-- .../src/noir_test_gen.test.ts | 2 +- .../src/type_conversion.test.ts | 14 +-- .../src/type_conversion.ts | 117 +++++++++--------- .../src/types/private_kernel_init_types.ts | 6 +- .../src/types/private_kernel_inner_types.ts | 6 +- .../types/private_kernel_ordering_types.ts | 4 +- .../public_kernel_private_previous_types.ts | 6 +- .../public_kernel_public_previous_types.ts | 6 +- .../src/types/rollup_base_types.ts | 12 +- .../src/types/rollup_merge_types.ts | 2 +- .../src/types/rollup_root_types.ts | 22 ++-- yarn-project/p2p/src/client/p2p_client.ts | 2 +- yarn-project/pxe/src/database/database.ts | 16 +-- yarn-project/pxe/src/database/memory_db.ts | 22 ++-- .../pxe/src/note_processor/note_processor.ts | 2 +- .../pxe/src/pxe_service/pxe_service.ts | 4 +- .../pxe/src/simulator_oracle/index.ts | 14 +-- .../pxe/src/synchronizer/synchronizer.test.ts | 22 ++-- .../pxe/src/synchronizer/synchronizer.ts | 15 +-- .../block_builder/solo_block_builder.test.ts | 22 ++-- .../src/block_builder/solo_block_builder.ts | 66 +++++----- .../src/block_builder/types.ts | 2 +- .../src/sequencer/processed_tx.ts | 10 +- .../src/sequencer/public_processor.test.ts | 6 +- .../src/sequencer/public_processor.ts | 18 +-- .../src/sequencer/sequencer.test.ts | 4 +- .../sequencer-client/src/sequencer/utils.ts | 8 +- .../src/aztec_node/rpc/aztec_node_client.ts | 4 +- .../types/src/interfaces/aztec-node.ts | 8 +- .../types/src/interfaces/state_provider.ts | 4 +- yarn-project/types/src/l2_block.ts | 48 +++---- yarn-project/world-state/README.md | 4 +- .../merkle_tree_operations_facade.ts | 4 +- .../server_world_state_synchronizer.test.ts | 4 +- .../src/world-state-db/merkle_tree_db.ts | 2 +- .../src/world-state-db/merkle_trees.ts | 20 +-- yellow-paper/docs/transactions/tx-object.md | 4 +- yellow-paper/docs/transactions/validity.md | 2 +- 144 files changed, 996 insertions(+), 1018 deletions(-) delete mode 100644 yarn-project/aztec-nr/aztec/src/oracle/get_block_data.nr create mode 100644 yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr create mode 100644 yarn-project/circuits.js/src/structs/kernel/block_header.test.ts rename yarn-project/circuits.js/src/structs/kernel/{historic_block_data.ts => block_header.ts} (80%) delete mode 100644 yarn-project/circuits.js/src/structs/kernel/historic_block_data.test.ts rename yarn-project/noir-protocol-circuits/src/crates/types/src/abis/{historical_block_data.nr => block_header.nr} (95%) diff --git a/circuits/cpp/src/aztec3/circuits/abis/combined_constant_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/combined_constant_data.hpp index 21beafda1977..21d2aef29b41 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/combined_constant_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/combined_constant_data.hpp @@ -2,7 +2,7 @@ #include "tx_context.hpp" -#include "aztec3/circuits/abis/historic_block_data.hpp" +#include "aztec3/circuits/abis/block_header.hpp" #include "aztec3/utils/types/circuit_types.hpp" #include "aztec3/utils/types/native_types.hpp" @@ -10,7 +10,7 @@ namespace aztec3::circuits::abis { -using aztec3::circuits::abis::HistoricBlockData; +using aztec3::circuits::abis::BlockHeader; using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; using std::is_same; @@ -19,11 +19,11 @@ template struct CombinedConstantData { using fr = typename NCT::fr; using boolean = typename NCT::boolean; - HistoricBlockData block_data{}; + BlockHeader block_header{}; TxContext tx_context{}; // for serialization: update up with new fields - MSGPACK_FIELDS(block_data, tx_context); + MSGPACK_FIELDS(block_header, tx_context); boolean operator==(CombinedConstantData const& other) const { return msgpack_derived_equals(*this, other); @@ -34,7 +34,7 @@ template struct CombinedConstantData { static_assert((std::is_same::value)); CombinedConstantData> constant_data = { - block_data.to_circuit_type(builder), + block_header.to_circuit_type(builder), tx_context.to_circuit_type(builder), }; @@ -48,7 +48,7 @@ template struct CombinedConstantData { auto to_native_type = [](T& e) { return e.template to_native_type(); }; CombinedConstantData constant_data = { - to_native_type(block_data), + to_native_type(block_header), to_native_type(tx_context), }; @@ -59,7 +59,7 @@ template struct CombinedConstantData { { static_assert(!(std::is_same::value)); - block_data.set_public(); + block_header.set_public(); tx_context.set_public(); } }; diff --git a/circuits/cpp/src/aztec3/circuits/abis/historic_block_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/historic_block_data.hpp index 45161128c060..7d07d16fe0a5 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/historic_block_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/historic_block_data.hpp @@ -17,7 +17,7 @@ using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; using std::is_same; -template struct HistoricBlockData { +template struct BlockHeader { using fr = typename NCT::fr; using boolean = typename NCT::boolean; @@ -43,12 +43,12 @@ template struct HistoricBlockData { public_data_tree_root, global_variables_hash); - boolean operator==(HistoricBlockData const& other) const + boolean operator==(BlockHeader const& other) const { return note_hash_tree_root == other.note_hash_tree_root && nullifier_tree_root == other.nullifier_tree_root && contract_tree_root == other.contract_tree_root && l1_to_l2_messages_tree_root == other.l1_to_l2_messages_tree_root && - blocks_tree_root == other.historic_block_root && + blocks_tree_root == other.blocks_tree_root && private_kernel_vk_tree_root == other.private_kernel_vk_tree_root && public_data_tree_root == other.public_data_tree_root && global_variables_hash == other.global_variables_hash; @@ -68,14 +68,14 @@ template struct HistoricBlockData { global_variables_hash.assert_is_zero(); } - template HistoricBlockData> to_circuit_type(Builder& builder) const + template BlockHeader> to_circuit_type(Builder& builder) const { static_assert((std::is_same::value)); // Capture the circuit builder: auto to_ct = [&](auto& e) { return aztec3::utils::types::to_ct(builder, e); }; - HistoricBlockData> data = { + BlockHeader> data = { to_ct(note_hash_tree_root), to_ct(nullifier_tree_root), to_ct(contract_tree_root), to_ct(l1_to_l2_messages_tree_root), to_ct(blocks_tree_root), to_ct(private_kernel_vk_tree_root), to_ct(public_data_tree_root), to_ct(global_variables_hash), @@ -84,12 +84,12 @@ template struct HistoricBlockData { return data; }; - template HistoricBlockData to_native_type() const + template BlockHeader to_native_type() const { static_assert(std::is_same, NCT>::value); auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt(e); }; - HistoricBlockData data = { + BlockHeader data = { to_nt(note_hash_tree_root), to_nt(nullifier_tree_root), to_nt(contract_tree_root), to_nt(l1_to_l2_messages_tree_root), to_nt(blocks_tree_root), to_nt(private_kernel_vk_tree_root), to_nt(public_data_tree_root), to_nt(global_variables_hash), diff --git a/circuits/cpp/src/aztec3/circuits/abis/packers.hpp b/circuits/cpp/src/aztec3/circuits/abis/packers.hpp index 894481245a6d..2ee938409085 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/packers.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/packers.hpp @@ -59,7 +59,7 @@ struct ConstantsPacker { NOTE_HASH_SUBTREE_HEIGHT, NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH, NULLIFIER_SUBTREE_HEIGHT, - HISTORIC_BLOCKS_TREE_HEIGHT, + BLOCKS_TREE_HEIGHT, NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH, L1_TO_L2_MSG_SUBTREE_HEIGHT), NVP(L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, @@ -73,7 +73,7 @@ struct ConstantsPacker { MAX_NOTES_PER_PAGE, VIEW_NOTE_ORACLE_RETURN_LENGTH, CALL_CONTEXT_LENGTH, - HISTORIC_BLOCK_DATA_LENGTH, + BLOCK_HEADER_LENGTH, FUNCTION_DATA_LENGTH, CONTRACT_DEPLOYMENT_DATA_LENGTH, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_circuit_public_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_circuit_public_inputs.hpp index 5950c4be70d4..e06860ce3c2e 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_circuit_public_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_circuit_public_inputs.hpp @@ -3,7 +3,7 @@ #include "call_context.hpp" #include "contract_deployment_data.hpp" -#include "aztec3/circuits/abis/historic_block_data.hpp" +#include "aztec3/circuits/abis/block_header.hpp" #include "aztec3/constants.hpp" #include "aztec3/utils/types/circuit_types.hpp" #include "aztec3/utils/types/convert.hpp" @@ -46,7 +46,7 @@ template class PrivateCircuitPublicInputs { fr encrypted_log_preimages_length = 0; fr unencrypted_log_preimages_length = 0; - HistoricBlockData historic_block_data{}; + BlockHeader block_header{}; ContractDeploymentData contract_deployment_data{}; @@ -69,7 +69,7 @@ template class PrivateCircuitPublicInputs { unencrypted_logs_hash, encrypted_log_preimages_length, unencrypted_log_preimages_length, - historic_block_data, + block_header, contract_deployment_data, chain_id, version); @@ -85,9 +85,8 @@ template class PrivateCircuitPublicInputs { unencrypted_logs_hash == other.unencrypted_logs_hash && encrypted_log_preimages_length == other.encrypted_log_preimages_length && unencrypted_log_preimages_length == other.unencrypted_log_preimages_length && - historic_block_data == other.historic_block_data && - contract_deployment_data == other.contract_deployment_data && chain_id == other.chain_id && - version == other.version; + block_header == other.block_header && contract_deployment_data == other.contract_deployment_data && + chain_id == other.chain_id && version == other.version; }; template @@ -122,7 +121,7 @@ template class PrivateCircuitPublicInputs { to_ct(encrypted_log_preimages_length), to_ct(unencrypted_log_preimages_length), - to_circuit_type(historic_block_data), + to_circuit_type(block_header), to_circuit_type(contract_deployment_data), @@ -162,7 +161,7 @@ template class PrivateCircuitPublicInputs { to_nt(encrypted_log_preimages_length), to_nt(unencrypted_log_preimages_length), - to_native_type(historic_block_data), + to_native_type(block_header), to_native_type(contract_deployment_data), @@ -201,7 +200,7 @@ template class PrivateCircuitPublicInputs { inputs.push_back(encrypted_log_preimages_length); inputs.push_back(unencrypted_log_preimages_length); - spread_arr_into_vec(historic_block_data.to_array(), inputs); + spread_arr_into_vec(block_header.to_array(), inputs); inputs.push_back(contract_deployment_data.hash()); @@ -252,7 +251,7 @@ template class OptionalPrivateCircuitPublicInputs { opt_fr encrypted_log_preimages_length; opt_fr unencrypted_log_preimages_length; - std::optional> historic_block_data; + std::optional> block_header; std::optional> contract_deployment_data; @@ -275,7 +274,7 @@ template class OptionalPrivateCircuitPublicInputs { unencrypted_logs_hash, encrypted_log_preimages_length, unencrypted_log_preimages_length, - historic_block_data, + block_header, contract_deployment_data, chain_id, version); @@ -305,7 +304,7 @@ template class OptionalPrivateCircuitPublicInputs { opt_fr const& encrypted_log_preimages_length, opt_fr const& unencrypted_log_preimages_length, - std::optional> const& historic_block_data, + std::optional> const& block_header, std::optional> const& contract_deployment_data, @@ -326,7 +325,7 @@ template class OptionalPrivateCircuitPublicInputs { , unencrypted_logs_hash(unencrypted_logs_hash) , encrypted_log_preimages_length(encrypted_log_preimages_length) , unencrypted_log_preimages_length(unencrypted_log_preimages_length) - , historic_block_data(historic_block_data) + , block_header(block_header) , contract_deployment_data(contract_deployment_data) , chain_id(chain_id) , version(version){}; @@ -359,7 +358,7 @@ template class OptionalPrivateCircuitPublicInputs { new_inputs.encrypted_log_preimages_length = std::nullopt; new_inputs.unencrypted_log_preimages_length = std::nullopt; - new_inputs.historic_block_data = std::nullopt; + new_inputs.block_header = std::nullopt; new_inputs.contract_deployment_data = std::nullopt; @@ -425,7 +424,7 @@ template class OptionalPrivateCircuitPublicInputs { make_unused_element_zero(builder, encrypted_log_preimages_length); make_unused_element_zero(builder, unencrypted_log_preimages_length); - make_unused_element_zero(builder, historic_block_data); + make_unused_element_zero(builder, block_header); make_unused_element_zero(builder, contract_deployment_data); @@ -465,7 +464,7 @@ template class OptionalPrivateCircuitPublicInputs { (*encrypted_log_preimages_length).set_public(); (*unencrypted_log_preimages_length).set_public(); - (*historic_block_data).set_public(); + (*block_header).set_public(); (*contract_deployment_data).set_public(); @@ -507,7 +506,7 @@ template class OptionalPrivateCircuitPublicInputs { to_ct(encrypted_log_preimages_length), to_ct(unencrypted_log_preimages_length), - to_circuit_type(historic_block_data), + to_circuit_type(block_header), to_circuit_type(contract_deployment_data), @@ -549,7 +548,7 @@ template class OptionalPrivateCircuitPublicInputs { to_nt(encrypted_log_preimages_length), to_nt(unencrypted_log_preimages_length), - to_native_type(historic_block_data), + to_native_type(block_header), to_native_type(contract_deployment_data), @@ -592,7 +591,7 @@ template class OptionalPrivateCircuitPublicInputs { inputs.push_back(*encrypted_log_preimages_length); inputs.push_back(*unencrypted_log_preimages_length); - spread_arr_opt_into_vec((*historic_block_data).to_array(), inputs); + spread_arr_opt_into_vec((*block_header).to_array(), inputs); inputs.push_back((*contract_deployment_data).hash()); @@ -630,7 +629,7 @@ template class OptionalPrivateCircuitPublicInputs { .encrypted_log_preimages_length = encrypted_log_preimages_length.value(), .unencrypted_log_preimages_length = unencrypted_log_preimages_length.value(), - .historic_block_data = historic_block_data.value(), + .block_header = block_header.value(), .contract_deployment_data = contract_deployment_data.value(), 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 75d2b804020d..6548b93a28d8 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 @@ -5,7 +5,7 @@ #include "contract_storage_update_request.hpp" #include "../../constants.hpp" -#include "aztec3/circuits/abis/historic_block_data.hpp" +#include "aztec3/circuits/abis/block_header.hpp" #include "aztec3/utils/types/circuit_types.hpp" #include "aztec3/utils/types/native_types.hpp" @@ -42,7 +42,7 @@ template struct PublicCircuitPublicInputs { // variable-length data. fr unencrypted_log_preimages_length = 0; - HistoricBlockData historic_block_data{}; + BlockHeader block_header{}; address prover_address{}; @@ -58,7 +58,7 @@ template struct PublicCircuitPublicInputs { new_l2_to_l1_msgs, unencrypted_logs_hash, unencrypted_log_preimages_length, - historic_block_data, + block_header, prover_address); boolean operator==(PublicCircuitPublicInputs const& other) const @@ -91,7 +91,7 @@ template struct PublicCircuitPublicInputs { .unencrypted_logs_hash = to_ct(unencrypted_logs_hash), .unencrypted_log_preimages_length = to_ct(unencrypted_log_preimages_length), - .historic_block_data = to_ct(historic_block_data), + .block_header = to_ct(block_header), .prover_address = to_ct(prover_address), }; @@ -121,7 +121,7 @@ template struct PublicCircuitPublicInputs { spread_arr_into_vec(unencrypted_logs_hash, inputs); inputs.push_back(unencrypted_log_preimages_length); - spread_arr_into_vec(historic_block_data.to_array(), inputs); + spread_arr_into_vec(block_header.to_array(), inputs); inputs.push_back(prover_address); if (inputs.size() != PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH) { 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 5b0d5e2ac949..380b1a2eec47 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 @@ -21,7 +21,7 @@ template struct BaseRollupInputs { AppendOnlyTreeSnapshot start_nullifier_tree_snapshot{}; AppendOnlyTreeSnapshot start_contract_tree_snapshot{}; fr start_public_data_tree_root{}; - AppendOnlyTreeSnapshot start_historic_blocks_tree_snapshot{}; + AppendOnlyTreeSnapshot start_blocks_tree_snapshot{}; std::array, MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP> low_nullifier_leaf_preimages{}; std::array, MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP> @@ -37,8 +37,8 @@ template struct BaseRollupInputs { std::array, MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP> new_public_data_reads_sibling_paths{}; - std::array, KERNELS_PER_BASE_ROLLUP> - historic_blocks_tree_root_membership_witnesses{}; + std::array, KERNELS_PER_BASE_ROLLUP> + blocks_tree_root_membership_witnesses{}; ConstantRollupData constants{}; @@ -48,7 +48,7 @@ template struct BaseRollupInputs { start_nullifier_tree_snapshot, start_contract_tree_snapshot, start_public_data_tree_root, - start_historic_blocks_tree_snapshot, + start_blocks_tree_snapshot, low_nullifier_leaf_preimages, low_nullifier_membership_witness, new_commitments_subtree_sibling_path, @@ -56,7 +56,7 @@ template struct BaseRollupInputs { new_contracts_subtree_sibling_path, new_public_data_update_requests_sibling_paths, new_public_data_reads_sibling_paths, - historic_blocks_tree_root_membership_witnesses, + blocks_tree_root_membership_witnesses, constants); boolean operator==(BaseRollupInputs const& other) const diff --git a/circuits/cpp/src/aztec3/circuits/abis/rollup/constant_rollup_data.hpp b/circuits/cpp/src/aztec3/circuits/abis/rollup/constant_rollup_data.hpp index d94788674b4e..a1cb37b6a66f 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/rollup/constant_rollup_data.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/rollup/constant_rollup_data.hpp @@ -11,7 +11,7 @@ template struct ConstantRollupData { using fr = typename NCT::fr; // The very latest roots as at the very beginning of the entire rollup: - AppendOnlyTreeSnapshot start_historic_blocks_tree_roots_snapshot{}; + AppendOnlyTreeSnapshot start_blocks_tree_snapshot{}; // Some members of this struct tbd: fr private_kernel_vk_tree_root = 0; @@ -21,7 +21,7 @@ template struct ConstantRollupData { GlobalVariables global_variables{}; - MSGPACK_FIELDS(start_historic_blocks_tree_roots_snapshot, + MSGPACK_FIELDS(start_blocks_tree_snapshot, private_kernel_vk_tree_root, public_kernel_vk_tree_root, base_rollup_vk_hash, diff --git a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp index 372390a8c056..c765c9d09ad0 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_inputs.hpp @@ -25,16 +25,16 @@ template struct RootRollupInputs { AppendOnlyTreeSnapshot start_l1_to_l2_messages_tree_snapshot{}; // inputs required to add the block hash - AppendOnlyTreeSnapshot start_historic_blocks_tree_snapshot{}; - std::array new_historic_blocks_tree_sibling_path{}; + AppendOnlyTreeSnapshot start_blocks_tree_snapshot{}; + std::array new_blocks_tree_sibling_path{}; // For serialization, update with new fields MSGPACK_FIELDS(previous_rollup_data, new_l1_to_l2_messages, new_l1_to_l2_messages_tree_root_sibling_path, start_l1_to_l2_messages_tree_snapshot, - start_historic_blocks_tree_snapshot, - new_historic_blocks_tree_sibling_path); + start_blocks_tree_snapshot, + new_blocks_tree_sibling_path); bool operator==(RootRollupInputs const&) const = default; }; diff --git a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp index 51879fd95664..74aff1ba5e89 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/rollup/root/root_rollup_public_inputs.hpp @@ -31,20 +31,20 @@ template struct RootRollupPublicInputs { fr start_public_data_tree_root{}; fr end_public_data_tree_root{}; - AppendOnlyTreeSnapshot start_tree_of_historic_note_hash_tree_roots_snapshot{}; - AppendOnlyTreeSnapshot end_tree_of_historic_note_hash_tree_roots_snapshot{}; + AppendOnlyTreeSnapshot start_tree_of_historical_note_hash_tree_roots_snapshot{}; + AppendOnlyTreeSnapshot end_tree_of_historical_note_hash_tree_roots_snapshot{}; - AppendOnlyTreeSnapshot start_tree_of_historic_contract_tree_roots_snapshot{}; - AppendOnlyTreeSnapshot end_tree_of_historic_contract_tree_roots_snapshot{}; + AppendOnlyTreeSnapshot start_tree_of_historical_contract_tree_roots_snapshot{}; + AppendOnlyTreeSnapshot end_tree_of_historical_contract_tree_roots_snapshot{}; AppendOnlyTreeSnapshot start_l1_to_l2_messages_tree_snapshot{}; AppendOnlyTreeSnapshot end_l1_to_l2_messages_tree_snapshot{}; - AppendOnlyTreeSnapshot start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot{}; - AppendOnlyTreeSnapshot end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot{}; + AppendOnlyTreeSnapshot start_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot{}; + AppendOnlyTreeSnapshot end_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot{}; - AppendOnlyTreeSnapshot start_historic_blocks_tree_snapshot{}; - AppendOnlyTreeSnapshot end_historic_blocks_tree_snapshot{}; + AppendOnlyTreeSnapshot start_blocks_tree_snapshot{}; + AppendOnlyTreeSnapshot end_blocks_tree_snapshot{}; std::array calldata_hash{}; std::array l1_to_l2_messages_hash{}; @@ -60,16 +60,16 @@ template struct RootRollupPublicInputs { end_contract_tree_snapshot, start_public_data_tree_root, end_public_data_tree_root, - start_tree_of_historic_note_hash_tree_roots_snapshot, - end_tree_of_historic_note_hash_tree_roots_snapshot, - start_tree_of_historic_contract_tree_roots_snapshot, - end_tree_of_historic_contract_tree_roots_snapshot, + start_tree_of_historical_note_hash_tree_roots_snapshot, + end_tree_of_historical_note_hash_tree_roots_snapshot, + start_tree_of_historical_contract_tree_roots_snapshot, + end_tree_of_historical_contract_tree_roots_snapshot, start_l1_to_l2_messages_tree_snapshot, end_l1_to_l2_messages_tree_snapshot, - start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot, - end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot, - start_historic_blocks_tree_snapshot, - end_historic_blocks_tree_snapshot, + start_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot, + end_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot, + start_blocks_tree_snapshot, + end_blocks_tree_snapshot, calldata_hash, l1_to_l2_messages_hash); @@ -83,21 +83,21 @@ template struct RootRollupPublicInputs { write(buf, start_note_hash_tree_snapshot); write(buf, start_nullifier_tree_snapshot); write(buf, start_contract_tree_snapshot); - write(buf, start_tree_of_historic_note_hash_tree_roots_snapshot); - write(buf, start_tree_of_historic_contract_tree_roots_snapshot); + write(buf, start_tree_of_historical_note_hash_tree_roots_snapshot); + write(buf, start_tree_of_historical_contract_tree_roots_snapshot); write(buf, start_public_data_tree_root); write(buf, start_l1_to_l2_messages_tree_snapshot); - write(buf, start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot); - write(buf, start_historic_blocks_tree_snapshot); + write(buf, start_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot); + write(buf, start_blocks_tree_snapshot); write(buf, end_note_hash_tree_snapshot); write(buf, end_nullifier_tree_snapshot); write(buf, end_contract_tree_snapshot); - write(buf, end_tree_of_historic_note_hash_tree_roots_snapshot); - write(buf, end_tree_of_historic_contract_tree_roots_snapshot); + write(buf, end_tree_of_historical_note_hash_tree_roots_snapshot); + write(buf, end_tree_of_historical_contract_tree_roots_snapshot); write(buf, end_public_data_tree_root); write(buf, end_l1_to_l2_messages_tree_snapshot); - write(buf, end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot); - write(buf, end_historic_blocks_tree_snapshot); + write(buf, end_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot); + write(buf, end_blocks_tree_snapshot); // Stitching calldata hash together auto high_buffer = calldata_hash[0].to_buffer(); diff --git a/circuits/cpp/src/aztec3/circuits/apps/opcodes/opcodes.tpp b/circuits/cpp/src/aztec3/circuits/apps/opcodes/opcodes.tpp index 6708e266c7d1..25c8c81a8602 100644 --- a/circuits/cpp/src/aztec3/circuits/apps/opcodes/opcodes.tpp +++ b/circuits/cpp/src/aztec3/circuits/apps/opcodes/opcodes.tpp @@ -54,7 +54,7 @@ Note Opcodes::UTXO_SLOAD(UTXOStateVar* utxo_state_var, // TODO within this function: // - Merkle Membership Check using the contract_address, utxo_datum.{sibling_path, leaf_index, - // historic_note_hash_tree_root} + // historical_note_hash_tree_root} return new_note; }; @@ -95,7 +95,7 @@ std::vector Opcodes::UTXO_SLOAD(UTXOSetStateVar* u // TODO within this function: // - Merkle Membership Check using the contract_address, utxo_datum.{sibling_path, leaf_index, - // historic_note_hash_tree_root} + // historical_note_hash_tree_root} new_notes.push_back(new_note); } diff --git a/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/transfer.cpp b/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/transfer.cpp index 5b6d5a6afdb0..08809a8e4e2c 100644 --- a/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/transfer.cpp +++ b/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/transfer.cpp @@ -93,7 +93,7 @@ OptionalPrivateCircuitPublicInputs transfer(FunctionExecutionContext& exec_c { amount, to.to_field(), asset_id, memo, CT::fr(reveal_msg_sender_to_recipient), fee }); /// TODO: merkle membership check - // public_inputs.historic_note_hash_tree_root + // public_inputs.historical_note_hash_tree_root exec_ctx.finalize(); diff --git a/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/withdraw.cpp b/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/withdraw.cpp index 5effa070436f..d61fcceed273 100644 --- a/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/withdraw.cpp +++ b/circuits/cpp/src/aztec3/circuits/apps/test_apps/escrow/withdraw.cpp @@ -86,7 +86,7 @@ OptionalPrivateCircuitPublicInputs withdraw(FunctionExecutionContext& exec_c exec_ctx.finalize(); /// TODO: merkle membership check - // public_inputs.historic_note_hash_tree_root + // public_inputs.historical_note_hash_tree_root // info("public inputs: ", public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/apps/utxo_datum.hpp b/circuits/cpp/src/aztec3/circuits/apps/utxo_datum.hpp index 360dbeb2ecb0..c13bd18527b0 100644 --- a/circuits/cpp/src/aztec3/circuits/apps/utxo_datum.hpp +++ b/circuits/cpp/src/aztec3/circuits/apps/utxo_datum.hpp @@ -26,7 +26,7 @@ template struct UTXOSLoadDatum { std::vector sibling_path; uint32 leaf_index; - fr historic_note_hash_tree_root = 0; + fr historical_note_hash_tree_root = 0; template auto to_circuit_type(Builder& builder) const { @@ -39,7 +39,7 @@ template struct UTXOSLoadDatum { UTXOSLoadDatum, decltype(preimage_ct)> datum = { to_ct(commitment), to_ct(contract_address), preimage_ct, - to_ct(sibling_path), to_ct(leaf_index), to_ct(historic_note_hash_tree_root), + to_ct(sibling_path), to_ct(leaf_index), to_ct(historical_note_hash_tree_root), }; return datum; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp index c5b993a340cb..f0e23c9e69da 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp @@ -53,8 +53,8 @@ void common_validate_call_stack(DummyBuilder& builder, PrivateCallData const } /** - * @brief Validate all read requests against the historic note hash tree root. - * Use their membership witnesses to do so. If the historic root is not yet + * @brief Validate all read requests against the historical note hash tree root. + * Use their membership witnesses to do so. If the historical root is not yet * initialized, initialize it using the first read request here (if present). * * @details More info here: @@ -62,7 +62,7 @@ void common_validate_call_stack(DummyBuilder& builder, PrivateCallData const * - https://discourse.aztec.network/t/spending-notes-which-havent-yet-been-inserted/180 * * @param builder - * @param historic_note_hash_tree_root This is a reference to the historic root which all + * @param historical_note_hash_tree_root This is a reference to the historical root which all * read requests are checked against here. * @param read_requests the commitments being read by this private call - 'transient note reads' here are * `inner_note_hashes` (not yet siloed, not unique), but 'pre-existing note reads' are `unique_siloed_note_hashes` @@ -70,7 +70,7 @@ void common_validate_call_stack(DummyBuilder& builder, PrivateCallData const * for a given request which is essentially a membership check */ void common_validate_read_requests(DummyBuilder& builder, - NT::fr const& historic_note_hash_tree_root, + NT::fr const& historical_note_hash_tree_root, std::array const& read_requests, std::array, MAX_READ_REQUESTS_PER_CALL> const& read_request_membership_witnesses) @@ -92,12 +92,12 @@ void common_validate_read_requests(DummyBuilder& builder, const auto& root_for_read_request = root_from_sibling_path(read_request, witness.leaf_index, witness.sibling_path); builder.do_assert( - root_for_read_request == historic_note_hash_tree_root, + root_for_read_request == historical_note_hash_tree_root, format("note hash tree root mismatch at read_request[", rr_idx, "]", "\n\texpected root: ", - historic_note_hash_tree_root, + historical_note_hash_tree_root, "\n\tbut got root*: ", root_for_read_request, "\n\tread_request**: ", @@ -429,7 +429,7 @@ void common_contract_logic(DummyBuilder& builder, private_call.contract_leaf_membership_witness.sibling_path); auto const& purported_contract_tree_root = - private_call.call_stack_item.public_inputs.historic_block_data.contract_tree_root; + private_call.call_stack_item.public_inputs.block_header.contract_tree_root; builder.do_assert( computed_contract_tree_root == purported_contract_tree_root, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp index ee0e5c350fbb..2e1191a252fb 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -31,7 +31,7 @@ using DummyBuilder = aztec3::utils::DummyCircuitBuilder; void common_validate_call_stack(DummyBuilder& builder, PrivateCallData const& private_call); void common_validate_read_requests(DummyBuilder& builder, - NT::fr const& historic_note_hash_tree_root, + NT::fr const& historical_note_hash_tree_root, std::array const& read_requests, std::array, MAX_READ_REQUESTS_PER_CALL> const& read_request_membership_witnesses); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp index e5c70bbd1742..1d8fc42f8bcf 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp @@ -1,8 +1,8 @@ #include "common.hpp" #include "init.hpp" +#include "aztec3/circuits/abis/block_header.hpp" #include "aztec3/circuits/abis/combined_constant_data.hpp" -#include "aztec3/circuits/abis/historic_block_data.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" #include "aztec3/constants.hpp" #include "aztec3/utils/array.hpp" @@ -26,7 +26,7 @@ void initialize_end_values(PrivateKernelInputsInit const& private_inputs, // Define the constants data. auto const& private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; auto const constants = CombinedConstantData{ - .block_data = private_call_public_inputs.historic_block_data, + .block_header = private_call_public_inputs.block_header, .tx_context = private_inputs.tx_request.tx_context, }; @@ -167,7 +167,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyCircuit common_validate_read_requests( builder, - public_inputs.constants.block_data.note_hash_tree_root, + public_inputs.constants.block_header.note_hash_tree_root, private_inputs.private_call.call_stack_item.public_inputs.read_requests, // read requests from private call private_inputs.private_call.read_request_membership_witnesses); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.test.cpp index f46023cae17a..f502436d603a 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.test.cpp @@ -433,7 +433,7 @@ TEST_F(native_private_kernel_init_tests, native_read_request_bad_request) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // tweak read_request so it gives wrong root when paired with its sibling path read_requests[1] += 1; @@ -467,7 +467,7 @@ TEST_F(native_private_kernel_init_tests, native_read_request_bad_leaf_index) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // tweak leaf index so it gives wrong root when paired with its request and sibling path read_request_membership_witnesses[1].leaf_index += 1; @@ -500,7 +500,7 @@ TEST_F(native_private_kernel_init_tests, native_read_request_bad_sibling_path) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // tweak sibling path so it gives wrong root when paired with its request read_request_membership_witnesses[1].sibling_path[1] += 1; @@ -534,7 +534,7 @@ TEST_F(native_private_kernel_init_tests, native_read_request_root_mismatch) _transient_read_requests0, _transient_read_request_membership_witnesses0, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; auto [read_requests1, read_request_membership_witnesses1, _transient_read_requests1, @@ -613,7 +613,7 @@ TEST_F(native_private_kernel_init_tests, native_one_read_requests_works) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 1); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = read_requests; private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; @@ -650,7 +650,7 @@ TEST_F(native_private_kernel_init_tests, native_two_read_requests_works) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = read_requests; private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; @@ -687,7 +687,7 @@ TEST_F(native_private_kernel_init_tests, native_max_read_requests_works) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, MAX_READ_REQUESTS_PER_CALL); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = read_requests; private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; @@ -728,7 +728,7 @@ TEST_F(native_private_kernel_init_tests, native_one_transient_read_requests_work transient_read_requests, transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 1); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // Make the read request transient read_requests[0] = transient_read_requests[0]; @@ -766,7 +766,7 @@ TEST_F(native_private_kernel_init_tests, native_max_read_requests_one_transient_ transient_read_requests, transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, MAX_READ_REQUESTS_PER_CALL); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = read_requests; // Make the read request at position 1 transient @@ -804,7 +804,7 @@ TEST_F(native_private_kernel_init_tests, native_max_read_requests_all_transient_ transient_read_requests, transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, MAX_READ_REQUESTS_PER_CALL); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = transient_read_requests; private_inputs.private_call.read_request_membership_witnesses = transient_read_request_membership_witnesses; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp index 371bcbf81dd0..d98423e8322b 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp @@ -58,9 +58,9 @@ void pop_and_validate_this_private_call_hash( void validate_contract_tree_root(DummyCircuitBuilder& builder, PrivateKernelInputsInner const& private_inputs) { auto const& purported_contract_tree_root = - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.contract_tree_root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.contract_tree_root; auto const& previous_kernel_contract_tree_root = - private_inputs.previous_kernel.public_inputs.constants.block_data.contract_tree_root; + private_inputs.previous_kernel.public_inputs.constants.block_header.contract_tree_root; builder.do_assert( purported_contract_tree_root == previous_kernel_contract_tree_root, "purported_contract_tree_root doesn't match previous_kernel_contract_tree_root", @@ -114,7 +114,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit_inner(DummyCircuitBu common_validate_read_requests( builder, - public_inputs.constants.block_data.note_hash_tree_root, + public_inputs.constants.block_header.note_hash_tree_root, private_inputs.private_call.call_stack_item.public_inputs.read_requests, // read requests from private call private_inputs.private_call.read_request_membership_witnesses); @@ -122,7 +122,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit_inner(DummyCircuitBu // TODO(dbanks12): feels like update_end_values should happen later common_update_end_values(builder, private_inputs.private_call, public_inputs); - // ensure that historic/purported contract tree root matches the one in previous kernel + // ensure that historical/purported contract tree root matches the one in previous kernel validate_contract_tree_root(builder, private_inputs); const auto private_call_stack_item = private_inputs.private_call.call_stack_item; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.test.cpp index 4c1d83856a07..d29c08eb590a 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.test.cpp @@ -93,8 +93,8 @@ TEST_F(native_private_kernel_inner_tests, private_function_incorrect_contract_tr { auto private_inputs = do_private_call_get_kernel_inputs_inner(false, deposit, standard_test_args()); - // Set historic_tree_root to a random scalar. - private_inputs.previous_kernel.public_inputs.constants.block_data.contract_tree_root = NT::fr::random_element(); + // Set historical_tree_root to a random scalar. + private_inputs.previous_kernel.public_inputs.constants.block_header.contract_tree_root = NT::fr::random_element(); // Invoke the native private kernel circuit DummyBuilder builder = DummyBuilder("private_kernel_tests__private_function_incorrect_contract_tree_root_fails"); @@ -477,8 +477,8 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_bad_request) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // tweak read_request so it gives wrong root when paired with its sibling path read_requests[1] += 1; @@ -487,7 +487,7 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_bad_request) private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); @@ -516,8 +516,8 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_bad_leaf_index) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // tweak leaf index so it gives wrong root when paired with its request and sibling path read_request_membership_witnesses[1].leaf_index += 1; @@ -525,7 +525,7 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_bad_leaf_index) private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); @@ -554,8 +554,8 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_bad_sibling_path) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // tweak sibling path so it gives wrong root when paired with its request read_request_membership_witnesses[1].sibling_path[1] += 1; @@ -563,7 +563,7 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_bad_sibling_path) private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); @@ -593,8 +593,8 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_root_mismatch) _transient_read_requests0, _transient_read_request_membership_witnesses0, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; auto [read_requests1, read_request_membership_witnesses1, _transient_read_requests1, @@ -615,7 +615,7 @@ TEST_F(native_private_kernel_inner_tests, native_read_request_root_mismatch) private_inputs.private_call.read_request_membership_witnesses = bad_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); @@ -679,8 +679,8 @@ TEST_F(native_private_kernel_inner_tests, native_one_read_requests_works) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 1); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = read_requests; private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; @@ -720,8 +720,8 @@ TEST_F(native_private_kernel_inner_tests, native_two_read_requests_works) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 2); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = read_requests; private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; @@ -761,13 +761,13 @@ TEST_F(native_private_kernel_inner_tests, native_max_read_requests_works) _transient_read_requests, _transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, MAX_READ_REQUESTS_PER_CALL); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = read_requests; private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); @@ -803,7 +803,7 @@ TEST_F(native_private_kernel_inner_tests, native_one_transient_read_requests_wor transient_read_requests, transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, 1); - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // Make the read request transient read_requests[0] = transient_read_requests[0]; @@ -812,7 +812,7 @@ TEST_F(native_private_kernel_inner_tests, native_one_transient_read_requests_wor private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); @@ -847,8 +847,8 @@ TEST_F(native_private_kernel_inner_tests, native_max_read_requests_one_transient transient_read_requests, transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, MAX_READ_REQUESTS_PER_CALL); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; // Make the read request at position 1 transient read_requests[1] = transient_read_requests[1]; @@ -857,7 +857,7 @@ TEST_F(native_private_kernel_inner_tests, native_max_read_requests_one_transient private_inputs.private_call.read_request_membership_witnesses = read_request_membership_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); @@ -894,13 +894,13 @@ TEST_F(native_private_kernel_inner_tests, native_max_read_requests_all_transient transient_read_requests, transient_read_request_membership_witnesses, root] = get_random_reads(first_nullifier, contract_address, MAX_READ_REQUESTS_PER_CALL); - private_inputs.previous_kernel.public_inputs.constants.block_data.note_hash_tree_root = root; - private_inputs.private_call.call_stack_item.public_inputs.historic_block_data.note_hash_tree_root = root; + private_inputs.previous_kernel.public_inputs.constants.block_header.note_hash_tree_root = root; + private_inputs.private_call.call_stack_item.public_inputs.block_header.note_hash_tree_root = root; private_inputs.private_call.call_stack_item.public_inputs.read_requests = transient_read_requests; private_inputs.private_call.read_request_membership_witnesses = transient_read_request_membership_witnesses; // We need to update the previous_kernel's private_call_stack because the current_call_stack_item has changed - // i.e. we changed the public_inputs->read_requests and public_inputs->historic_note_hash_tree_root of the + // i.e. we changed the public_inputs->read_requests and public_inputs->historical_note_hash_tree_root of the // current_call_stack_item private_inputs.previous_kernel.public_inputs.end.private_call_stack[0] = private_inputs.private_call.call_stack_item.hash(); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.cpp index 33d0b4cb7920..f068662a3e56 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.cpp @@ -3,6 +3,7 @@ #include "index.hpp" #include "init.hpp" +#include "aztec3/circuits/abis/block_header.hpp" #include "aztec3/circuits/abis/call_context.hpp" #include "aztec3/circuits/abis/call_stack_item.hpp" #include "aztec3/circuits/abis/combined_accumulated_data.hpp" @@ -10,7 +11,6 @@ #include "aztec3/circuits/abis/complete_address.hpp" #include "aztec3/circuits/abis/contract_deployment_data.hpp" #include "aztec3/circuits/abis/function_data.hpp" -#include "aztec3/circuits/abis/historic_block_data.hpp" #include "aztec3/circuits/abis/private_circuit_public_inputs.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include "aztec3/circuits/abis/tx_context.hpp" @@ -28,13 +28,13 @@ namespace aztec3::circuits::kernel::private_kernel::testing_harness { +using aztec3::circuits::abis::BlockHeader; using aztec3::circuits::abis::CallContext; using aztec3::circuits::abis::CallStackItem; using aztec3::circuits::abis::CombinedAccumulatedData; using aztec3::circuits::abis::CombinedConstantData; using aztec3::circuits::abis::ContractDeploymentData; using aztec3::circuits::abis::FunctionData; -using aztec3::circuits::abis::HistoricBlockData; using aztec3::circuits::abis::PrivateCircuitPublicInputs; using aztec3::circuits::abis::PrivateTypes; using aztec3::circuits::abis::TxContext; @@ -52,7 +52,7 @@ using aztec3::utils::array_length; * @param first_nullifier used when computing nonce for unique_siloed_commitments (note hash tree leaves) * @param contract_address address to use when siloing read requests * @param num_read_requests if negative, use random num. Must be < MAX_READ_REQUESTS_PER_CALL - * @return std::tuple + * @return std::tuple */ std::tuple, std::array, MAX_READ_REQUESTS_PER_CALL>, @@ -285,7 +285,7 @@ std::pair, ContractDeploymentData> create_private_call_d OptionalPrivateCircuitPublicInputs const opt_private_circuit_public_inputs = func(ctx, args_vec); private_circuit_public_inputs = opt_private_circuit_public_inputs.remove_optionality(); // TODO(suyash): this should likely be handled as part of the DB/Oracle/Context infrastructure - private_circuit_public_inputs.historic_block_data.contract_tree_root = contract_tree_root; + private_circuit_public_inputs.block_header.contract_tree_root = contract_tree_root; private_circuit_public_inputs.encrypted_logs_hash = encrypted_logs_hash; private_circuit_public_inputs.unencrypted_logs_hash = unencrypted_logs_hash; @@ -305,7 +305,7 @@ std::pair, ContractDeploymentData> create_private_call_d .unencrypted_logs_hash = unencrypted_logs_hash, .encrypted_log_preimages_length = encrypted_log_preimages_length, .unencrypted_log_preimages_length = unencrypted_log_preimages_length, - .historic_block_data = HistoricBlockData{ .contract_tree_root = contract_tree_root }, + .block_header = BlockHeader{ .contract_tree_root = contract_tree_root }, .contract_deployment_data = contract_deployment_data, }; } @@ -489,10 +489,10 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner( // 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 = CombinedConstantData{ - .block_data = - HistoricBlockData{ - .note_hash_tree_root = private_circuit_public_inputs.historic_block_data.note_hash_tree_root, - .contract_tree_root = private_circuit_public_inputs.historic_block_data.contract_tree_root, + .block_header = + BlockHeader{ + .note_hash_tree_root = private_circuit_public_inputs.block_header.note_hash_tree_root, + .contract_tree_root = private_circuit_public_inputs.block_header.contract_tree_root, }, .tx_context = tx_context, }; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.hpp index 0da5106b240e..8ed964569985 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/testing_harness.hpp @@ -89,7 +89,7 @@ inline const auto& get_empty_contract_siblings() * read_request_memberships_witnesses, * transient_read_requests, * transient_read_request_memberships_witnesses, - * historic_note_hash_tree_root> + * historical_note_hash_tree_root> */ std::tuple, std::array, MAX_READ_REQUESTS_PER_CALL>, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp index e136a00d265a..0e9c5394aa86 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp @@ -26,13 +26,13 @@ namespace aztec3::circuits::kernel::public_kernel { using DummyCircuitBuilder = aztec3::utils::DummyCircuitBuilder; using aztec3::circuits::abis::public_kernel::PublicKernelInputs; using NT = aztec3::utils::types::NativeTypes; +using aztec3::circuits::abis::BlockHeader; using aztec3::circuits::abis::CallContext; using aztec3::circuits::abis::CallStackItem; using aztec3::circuits::abis::CombinedAccumulatedData; using aztec3::circuits::abis::CombinedConstantData; using aztec3::circuits::abis::ContractStorageRead; using aztec3::circuits::abis::ContractStorageUpdateRequest; -using aztec3::circuits::abis::HistoricBlockData; using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::OptionallyRevealedData; using aztec3::circuits::abis::PreviousKernelData; @@ -328,7 +328,7 @@ PublicKernelInputs get_kernel_inputs_with_previous_kernel(NT::boolean privat std::array const unencrypted_logs_hash = array_of_values(seed, NUM_FIELDS_PER_SHA256); fr const unencrypted_log_preimages_length = ++seed; - HistoricBlockData block_data = { + BlockHeader block_header = { .note_hash_tree_root = ++seed, .nullifier_tree_root = ++seed, .contract_tree_root = ++seed, @@ -352,7 +352,7 @@ PublicKernelInputs get_kernel_inputs_with_previous_kernel(NT::boolean privat .new_l2_to_l1_msgs = new_l2_to_l1_msgs, .unencrypted_logs_hash = unencrypted_logs_hash, .unencrypted_log_preimages_length = unencrypted_log_preimages_length, - .historic_block_data = block_data, + .block_header = block_header, }; const PublicCallStackItem call_stack_item{ @@ -369,18 +369,18 @@ PublicKernelInputs get_kernel_inputs_with_previous_kernel(NT::boolean privat }; // TODO(914) Should this be unused? - [[maybe_unused]] HistoricBlockData const historic_tree_roots = { + [[maybe_unused]] BlockHeader const historical_tree_roots = { .note_hash_tree_root = 1000, .contract_tree_root = 2000, .l1_to_l2_messages_tree_root = 3000, .private_kernel_vk_tree_root = 4000, }; - CombinedConstantData const end_constants = { .block_data = - HistoricBlockData{ .note_hash_tree_root = ++seed, - .nullifier_tree_root = ++seed, - .contract_tree_root = ++seed, - .private_kernel_vk_tree_root = ++seed }, + CombinedConstantData const end_constants = { .block_header = + BlockHeader{ .note_hash_tree_root = ++seed, + .nullifier_tree_root = ++seed, + .contract_tree_root = ++seed, + .private_kernel_vk_tree_root = ++seed }, .tx_context = TxContext{ .is_fee_payment_tx = false, .is_rebate_payment_tx = false, diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp index a5109cabf3b9..652e6b0ca520 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -628,26 +628,26 @@ TEST_F(base_rollup_tests, native_calldata_hash) // run_cbind(inputs, outputs); } -TEST_F(base_rollup_tests, native_compute_membership_historic_blocks_tree_negative) +TEST_F(base_rollup_tests, native_compute_membership_blocks_tree_negative) { // WRITE a negative test that will fail the inclusion proof // Test membership works for empty trees DummyCircuitBuilder builder = - DummyCircuitBuilder("base_rollup_tests__native_compute_membership_historic_private_data_negative"); + DummyCircuitBuilder("base_rollup_tests__native_compute_membership_historical_private_data_negative"); std::array, 2> const kernel_data = { get_empty_kernel(), get_empty_kernel() }; BaseRollupInputs inputs = base_rollup_inputs_from_kernels(kernel_data); MemoryStore blocks_store; - auto blocks_tree = MerkleTree(blocks_store, HISTORIC_BLOCKS_TREE_HEIGHT); + auto blocks_tree = MerkleTree(blocks_store, BLOCKS_TREE_HEIGHT); - // Create an INCORRECT sibling path for the note hash tree root in the historic tree roots. + // Create an INCORRECT sibling path for the note hash tree root in the historical tree roots. auto hash_path = blocks_tree.get_sibling_path(0); - std::array sibling_path{}; - for (size_t i = 0; i < HISTORIC_BLOCKS_TREE_HEIGHT; ++i) { + std::array sibling_path{}; + for (size_t i = 0; i < BLOCKS_TREE_HEIGHT; ++i) { sibling_path[i] = hash_path[i] + 1; } - inputs.historic_blocks_tree_root_membership_witnesses[0] = { + inputs.blocks_tree_root_membership_witnesses[0] = { .leaf_index = 0, .sibling_path = sibling_path, }; @@ -658,8 +658,7 @@ TEST_F(base_rollup_tests, native_compute_membership_historic_blocks_tree_negativ ASSERT_TRUE(builder.failed()); ASSERT_EQ(builder.get_first_failure().message, "Membership check failed: base_rollup_circuit: historical root is in rollup constants but not in " - "historic block tree roots at kernel input 0 to this " - "base rollup circuit"); + "blocks tree at kernel input 0 to this base rollup circuit"); } 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 a75226964e55..1b2fa67ea7dd 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 @@ -132,42 +132,41 @@ NT::fr calculate_commitments_subtree(DummyBuilder& builder, BaseRollupInputs con * @param constantBaseRollupData * @param baseRollupInputs */ -void perform_historical_blocks_tree_membership_checks(DummyBuilder& builder, BaseRollupInputs const& baseRollupInputs) +void perform_blocks_tree_membership_checks(DummyBuilder& builder, BaseRollupInputs const& baseRollupInputs) { - // For each of the historic_note_hash_tree_membership_checks, we need to do an inclusion proof + // For each of the historical_note_hash_tree_membership_checks, we need to do an inclusion proof // against the historical root provided in the rollup constants - auto historic_root = baseRollupInputs.constants.start_historic_blocks_tree_roots_snapshot.root; + auto historical_root = baseRollupInputs.constants.start_blocks_tree_snapshot.root; for (size_t i = 0; i < 2; i++) { // Rebuild the block hash - auto historic_block = baseRollupInputs.kernel_data[i].public_inputs.constants.block_data; + auto historical_block = baseRollupInputs.kernel_data[i].public_inputs.constants.block_header; - auto note_hash_tree_root = historic_block.note_hash_tree_root; - auto nullifier_tree_root = historic_block.nullifier_tree_root; - auto contract_tree_root = historic_block.contract_tree_root; - auto l1_to_l2_messages_tree_root = historic_block.l1_to_l2_messages_tree_root; - auto public_data_tree_root = historic_block.public_data_tree_root; + auto note_hash_tree_root = historical_block.note_hash_tree_root; + auto nullifier_tree_root = historical_block.nullifier_tree_root; + auto contract_tree_root = historical_block.contract_tree_root; + auto l1_to_l2_messages_tree_root = historical_block.l1_to_l2_messages_tree_root; + auto public_data_tree_root = historical_block.public_data_tree_root; - auto previous_block_hash = compute_block_hash(historic_block.global_variables_hash, + auto previous_block_hash = compute_block_hash(historical_block.global_variables_hash, note_hash_tree_root, nullifier_tree_root, contract_tree_root, l1_to_l2_messages_tree_root, public_data_tree_root); - abis::MembershipWitness const historic_root_witness = - baseRollupInputs.historic_blocks_tree_root_membership_witnesses[i]; - - check_membership( - builder, - previous_block_hash, - historic_root_witness.leaf_index, - historic_root_witness.sibling_path, - historic_root, - format(BASE_CIRCUIT_ERROR_MESSAGE_BEGINNING, - "historical root is in rollup constants but not in historic block tree roots at kernel input ", - i, - " to this base rollup circuit")); + abis::MembershipWitness const historical_root_witness = + baseRollupInputs.blocks_tree_root_membership_witnesses[i]; + + check_membership(builder, + previous_block_hash, + historical_root_witness.leaf_index, + historical_root_witness.sibling_path, + historical_root, + format(BASE_CIRCUIT_ERROR_MESSAGE_BEGINNING, + "historical root is in rollup constants but not in blocks tree at kernel input ", + i, + " to this base rollup circuit")); } } @@ -524,8 +523,8 @@ BaseOrMergeRollupPublicInputs base_rollup_circuit(DummyBuilder& builder, BaseRol std::array const calldata_hash = components::compute_kernels_calldata_hash(baseRollupInputs.kernel_data); - // Perform membership checks that the notes provided exist within the historic trees data - perform_historical_blocks_tree_membership_checks(builder, baseRollupInputs); + // Perform membership checks that the notes provided exist within the historical trees data + perform_blocks_tree_membership_checks(builder, baseRollupInputs); AggregationObject const aggregation_object = aggregate_proofs(baseRollupInputs); diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp index b9c05fe4bca6..ed6f6ca0c25c 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp @@ -177,7 +177,7 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) auto nullifier_tree = get_initial_nullifier_tree_empty(); MemoryStore blocks_tree_store; - MerkleTree blocks_tree(blocks_tree_store, HISTORIC_BLOCKS_TREE_HEIGHT); + MerkleTree blocks_tree(blocks_tree_store, BLOCKS_TREE_HEIGHT); std::array kernels = { get_empty_kernel(), get_empty_kernel(), get_empty_kernel(), get_empty_kernel() @@ -292,8 +292,8 @@ TEST_F(root_rollup_tests, native_root_missing_nullifier_logic) rootRollupInputs.previous_rollup_data[1].base_or_merge_rollup_public_inputs.end_contract_tree_snapshot); ASSERT_EQ(outputs.end_l1_to_l2_messages_tree_snapshot, end_l1_to_l2_messages_tree_snapshot); - ASSERT_EQ(outputs.start_historic_blocks_tree_snapshot, start_blocks_tree_snapshot); - ASSERT_EQ(outputs.end_historic_blocks_tree_snapshot, end_blocks_tree_snapshot); + ASSERT_EQ(outputs.start_blocks_tree_snapshot, start_blocks_tree_snapshot); + ASSERT_EQ(outputs.end_blocks_tree_snapshot, end_blocks_tree_snapshot); // Compute the expected calldata hash for the root rollup (including the l2 -> l1 messages) auto left = components::compute_kernels_calldata_hash({ kernels[0], kernels[1] }); diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp index f2c5fd304a47..3c801da601f6 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/native_root_rollup_circuit.cpp @@ -107,7 +107,7 @@ RootRollupPublicInputs root_rollup_circuit(DummyBuilder& builder, RootRollupInpu "l1 to l2 message tree not empty at location where subtree would be inserted")); // Build the block hash for this iteration from the tree roots and global variables - // Then insert the block into the historic blocks tree + // Then insert the block into the blocks tree auto block_hash = compute_block_hash_with_globals(left.constants.global_variables, right.end_note_hash_tree_snapshot.root, right.end_nullifier_tree_snapshot.root, @@ -115,16 +115,16 @@ RootRollupPublicInputs root_rollup_circuit(DummyBuilder& builder, RootRollupInpu new_l1_to_l2_messages_tree_snapshot.root, right.end_public_data_tree_root); - // Update the historic blocks tree - auto end_historic_blocks_tree_snapshot = components::insert_subtree_to_snapshot_tree( + // Update the blocks tree + auto end_blocks_tree_snapshot = components::insert_subtree_to_snapshot_tree( builder, - rootRollupInputs.start_historic_blocks_tree_snapshot, - rootRollupInputs.new_historic_blocks_tree_sibling_path, + rootRollupInputs.start_blocks_tree_snapshot, + rootRollupInputs.new_blocks_tree_sibling_path, fr::zero(), block_hash, 0, format(ROOT_CIRCUIT_ERROR_MESSAGE_BEGINNING, - "historic blocks tree roots not empty at location where subtree would be inserted")); + "blocks tree roots not empty at location where subtree would be inserted")); RootRollupPublicInputs public_inputs = { @@ -140,8 +140,8 @@ RootRollupPublicInputs root_rollup_circuit(DummyBuilder& builder, RootRollupInpu .end_public_data_tree_root = right.end_public_data_tree_root, .start_l1_to_l2_messages_tree_snapshot = rootRollupInputs.start_l1_to_l2_messages_tree_snapshot, .end_l1_to_l2_messages_tree_snapshot = new_l1_to_l2_messages_tree_snapshot, - .start_historic_blocks_tree_snapshot = rootRollupInputs.start_historic_blocks_tree_snapshot, - .end_historic_blocks_tree_snapshot = end_historic_blocks_tree_snapshot, + .start_blocks_tree_snapshot = rootRollupInputs.start_blocks_tree_snapshot, + .end_blocks_tree_snapshot = end_blocks_tree_snapshot, .calldata_hash = components::compute_calldata_hash(rootRollupInputs.previous_rollup_data), .l1_to_l2_messages_hash = compute_messages_hash(rootRollupInputs.new_l1_to_l2_messages) }; diff --git a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp index a872a26497b4..72fee73a7331 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/test_utils/utils.cpp @@ -86,8 +86,8 @@ BaseRollupInputs base_rollup_inputs_from_kernels(std::array kerne { // @todo Look at the starting points for all of these. // By supporting as inputs we can make very generic tests, where it is trivial to try new setups. - MemoryStore historic_blocks_tree_store; - MerkleTree historic_blocks_tree = MerkleTree(historic_blocks_tree_store, HISTORIC_BLOCKS_TREE_HEIGHT); + MemoryStore blocks_tree_store; + MerkleTree blocks_tree = MerkleTree(blocks_tree_store, BLOCKS_TREE_HEIGHT); BaseRollupInputs baseRollupInputs = { .kernel_data = kernel_data, @@ -154,31 +154,31 @@ BaseRollupInputs base_rollup_inputs_from_kernels(std::array kerne baseRollupInputs.start_public_data_tree_root = public_data_tree.root(); - // create the original historic blocks tree leaf + // create the original blocks tree leaf auto block_hash = compute_block_hash(prev_global_variables_hash, note_hash_tree.root(), nullifier_tree.root(), contract_tree.root(), l1_to_l2_msg_tree.root(), public_data_tree.root()); - historic_blocks_tree.update_element(0, block_hash); + blocks_tree.update_element(0, block_hash); - ConstantRollupData const constantRollupData = { .start_historic_blocks_tree_roots_snapshot = { - .root = historic_blocks_tree.root(), + ConstantRollupData const constantRollupData = { .start_blocks_tree_snapshot = { + .root = blocks_tree.root(), .next_available_leaf_index = 1, } }; baseRollupInputs.constants = constantRollupData; - // Set historic tree roots data in the public inputs. + // Set historical tree roots data in the public inputs. for (size_t i = 0; i < 2; i++) { - kernel_data[i].public_inputs.constants.block_data.note_hash_tree_root = note_hash_tree.root(); - kernel_data[i].public_inputs.constants.block_data.nullifier_tree_root = nullifier_tree.root(); - kernel_data[i].public_inputs.constants.block_data.nullifier_tree_root = nullifier_tree.root(); - kernel_data[i].public_inputs.constants.block_data.contract_tree_root = contract_tree.root(); - kernel_data[i].public_inputs.constants.block_data.l1_to_l2_messages_tree_root = l1_to_l2_msg_tree.root(); - kernel_data[i].public_inputs.constants.block_data.blocks_tree_root = historic_blocks_tree.root(); - kernel_data[i].public_inputs.constants.block_data.public_data_tree_root = public_data_tree.root(); - kernel_data[i].public_inputs.constants.block_data.global_variables_hash = prev_global_variables_hash; + kernel_data[i].public_inputs.constants.block_header.note_hash_tree_root = note_hash_tree.root(); + kernel_data[i].public_inputs.constants.block_header.nullifier_tree_root = nullifier_tree.root(); + kernel_data[i].public_inputs.constants.block_header.nullifier_tree_root = nullifier_tree.root(); + kernel_data[i].public_inputs.constants.block_header.contract_tree_root = contract_tree.root(); + kernel_data[i].public_inputs.constants.block_header.l1_to_l2_messages_tree_root = l1_to_l2_msg_tree.root(); + kernel_data[i].public_inputs.constants.block_header.blocks_tree_root = blocks_tree.root(); + kernel_data[i].public_inputs.constants.block_header.public_data_tree_root = public_data_tree.root(); + kernel_data[i].public_inputs.constants.block_header.global_variables_hash = prev_global_variables_hash; } // Then we collect all sibling paths for the reads in the left tx, and then apply the update requests while @@ -207,13 +207,13 @@ BaseRollupInputs base_rollup_inputs_from_kernels(std::array kerne } } - // Get historic_root sibling paths - baseRollupInputs.historic_blocks_tree_root_membership_witnesses[0] = { + // Get historical_root sibling paths + baseRollupInputs.blocks_tree_root_membership_witnesses[0] = { .leaf_index = 0, - .sibling_path = get_sibling_path(historic_blocks_tree, 0, 0), + .sibling_path = get_sibling_path(blocks_tree, 0, 0), }; - baseRollupInputs.historic_blocks_tree_root_membership_witnesses[1] = - baseRollupInputs.historic_blocks_tree_root_membership_witnesses[0]; + baseRollupInputs.blocks_tree_root_membership_witnesses[1] = + baseRollupInputs.blocks_tree_root_membership_witnesses[0]; baseRollupInputs.kernel_data = kernel_data; @@ -378,8 +378,8 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder, MemoryStore public_data_tree_store; MerkleTree public_data_tree(public_data_tree_store, PUBLIC_DATA_TREE_HEIGHT); - MemoryStore historic_blocks_tree_store; - MerkleTree historic_blocks_tree(historic_blocks_tree_store, HISTORIC_BLOCKS_TREE_HEIGHT); + MemoryStore blocks_tree_store; + MerkleTree blocks_tree(blocks_tree_store, BLOCKS_TREE_HEIGHT); // Start blocks tree auto block_hash = compute_block_hash_with_globals(globals, @@ -388,16 +388,16 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder, contract_tree.root(), l1_to_l2_msg_tree.root(), public_data_tree.root()); - historic_blocks_tree.update_element(0, block_hash); + blocks_tree.update_element(0, block_hash); // Blocks tree snapshots - AppendOnlyTreeSnapshot const start_historic_blocks_tree_snapshot = { - .root = historic_blocks_tree.root(), + AppendOnlyTreeSnapshot const start_blocks_tree_snapshot = { + .root = blocks_tree.root(), .next_available_leaf_index = 1, }; // Blocks tree - auto blocks_tree_sibling_path = get_sibling_path(historic_blocks_tree, 1, 0); + auto blocks_tree_sibling_path = get_sibling_path(blocks_tree, 1, 0); // l1 to l2 tree auto l1_to_l2_tree_sibling_path = @@ -414,8 +414,8 @@ RootRollupInputs get_root_rollup_inputs(utils::DummyBuilder& builder, .new_l1_to_l2_messages = l1_to_l2_messages, .new_l1_to_l2_messages_tree_root_sibling_path = l1_to_l2_tree_sibling_path, .start_l1_to_l2_messages_tree_snapshot = start_l1_to_l2_msg_tree_snapshot, - .start_historic_blocks_tree_snapshot = start_historic_blocks_tree_snapshot, - .new_historic_blocks_tree_sibling_path = blocks_tree_sibling_path, + .start_blocks_tree_snapshot = start_blocks_tree_snapshot, + .new_blocks_tree_sibling_path = blocks_tree_sibling_path, }; return rootRollupInputs; } diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index feb162d9a879..39062de3b556 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -104,7 +104,7 @@ constexpr size_t NOTE_HASH_TREE_HEIGHT = 32; constexpr size_t PUBLIC_DATA_TREE_HEIGHT = 254; constexpr size_t NULLIFIER_TREE_HEIGHT = 20; constexpr size_t L1_TO_L2_MSG_TREE_HEIGHT = 16; -constexpr size_t HISTORIC_BLOCKS_TREE_HEIGHT = 16; +constexpr size_t BLOCKS_TREE_HEIGHT = 16; constexpr size_t ROLLUP_VK_TREE_HEIGHT = 8; // TODO: update @@ -315,7 +315,7 @@ constexpr size_t VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE constexpr size_t CALL_CONTEXT_LENGTH = 7; // Must be updated if any data is added into the block hash calculation. -constexpr size_t HISTORIC_BLOCK_DATA_LENGTH = 7; +constexpr size_t BLOCK_HEADER_LENGTH = 7; constexpr size_t FUNCTION_DATA_LENGTH = 4; constexpr size_t CONTRACT_DEPLOYMENT_DATA_LENGTH = 6; @@ -327,16 +327,16 @@ constexpr size_t PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = + RETURN_VALUES_LENGTH + MAX_READ_REQUESTS_PER_CALL + MAX_PENDING_READ_REQUESTS_PER_CALL + MAX_NEW_COMMITMENTS_PER_CALL + 2 * MAX_NEW_NULLIFIERS_PER_CALL + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + MAX_NEW_L2_TO_L1_MSGS_PER_CALL + NUM_FIELDS_PER_SHA256 + - NUM_FIELDS_PER_SHA256 + 2 // + 2 for logs preimage lengths - + HISTORIC_BLOCK_DATA_LENGTH + CONTRACT_DEPLOYMENT_DATA_LENGTH + 2; // + 2 for chain_id and version + NUM_FIELDS_PER_SHA256 + 2 // + 2 for logs preimage lengths + + BLOCK_HEADER_LENGTH + CONTRACT_DEPLOYMENT_DATA_LENGTH + 2; // + 2 for chain_id and version constexpr size_t PRIVATE_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 1 + 1 // call_context_hash + args_hash + RETURN_VALUES_LENGTH + MAX_READ_REQUESTS_PER_CALL + MAX_PENDING_READ_REQUESTS_PER_CALL + MAX_NEW_COMMITMENTS_PER_CALL + 2 * MAX_NEW_NULLIFIERS_PER_CALL + MAX_PRIVATE_CALL_STACK_LENGTH_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + MAX_NEW_L2_TO_L1_MSGS_PER_CALL + NUM_FIELDS_PER_SHA256 + - NUM_FIELDS_PER_SHA256 + 2 // + 2 for logs preimage lengths - + HISTORIC_BLOCK_DATA_LENGTH + 3; // + 3 for contract_deployment_data.hash(), chain_id, version + NUM_FIELDS_PER_SHA256 + 2 // + 2 for logs preimage lengths + + BLOCK_HEADER_LENGTH + 3; // + 3 for contract_deployment_data.hash(), chain_id, version constexpr size_t CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH = 3; constexpr size_t CONTRACT_STORAGE_READ_LENGTH = 2; @@ -347,15 +347,15 @@ constexpr size_t PUBLIC_CIRCUIT_PUBLIC_INPUTS_LENGTH = MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL * CONTRACT_STORAGE_UPDATE_REQUEST_LENGTH + MAX_PUBLIC_DATA_READS_PER_CALL * CONTRACT_STORAGE_READ_LENGTH + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + MAX_NEW_COMMITMENTS_PER_CALL + MAX_NEW_NULLIFIERS_PER_CALL + MAX_NEW_L2_TO_L1_MSGS_PER_CALL + - NUM_FIELDS_PER_SHA256 + 1 + // + 1 for unencrypted logs preimage length - HISTORIC_BLOCK_DATA_LENGTH + 2; // + 2 for chain_id and version + NUM_FIELDS_PER_SHA256 + 1 + // + 1 for unencrypted logs preimage length + BLOCK_HEADER_LENGTH + 2; // + 2 for chain_id and version constexpr size_t PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH = 2 + RETURN_VALUES_LENGTH + // + 1 for args_hash + 1 call_context.hash MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL + MAX_PUBLIC_DATA_READS_PER_CALL + MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL + MAX_NEW_COMMITMENTS_PER_CALL + MAX_NEW_NULLIFIERS_PER_CALL + MAX_NEW_L2_TO_L1_MSGS_PER_CALL + - NUM_FIELDS_PER_SHA256 + // unencrypted_logs_hash (being represented by NUM_FIELDS_PER_SHA256) - HISTORIC_BLOCK_DATA_LENGTH + 2; // unencrypted_log_preimages_length + prover_address + NUM_FIELDS_PER_SHA256 + // unencrypted_logs_hash (being represented by NUM_FIELDS_PER_SHA256) + BLOCK_HEADER_LENGTH + 2; // unencrypted_log_preimages_length + prover_address // Size of the return value of a private function call, diff --git a/circuits/cpp/src/aztec3/dbs/private_state_db.hpp b/circuits/cpp/src/aztec3/dbs/private_state_db.hpp index 5689dc163ca5..60d4ecaedf85 100644 --- a/circuits/cpp/src/aztec3/dbs/private_state_db.hpp +++ b/circuits/cpp/src/aztec3/dbs/private_state_db.hpp @@ -17,7 +17,7 @@ // std::vector active_private_state_preimages; // }; -// // contract->storageSlots->[current->historic] +// // contract->storageSlots->[current->historical] // /** // * Hmmm... There are multiple active leaves for partitioned states. diff --git a/circuits/cpp/src/aztec3/oracle/fake_db.hpp b/circuits/cpp/src/aztec3/oracle/fake_db.hpp index 96ddfd62a212..a14ffa6f57e5 100644 --- a/circuits/cpp/src/aztec3/oracle/fake_db.hpp +++ b/circuits/cpp/src/aztec3/oracle/fake_db.hpp @@ -61,7 +61,7 @@ class FakeDB { .sibling_path = sibling_path, .leaf_index = 2, - .historic_note_hash_tree_root = required_utxo_tree_root, + .historical_note_hash_tree_root = required_utxo_tree_root, }; }; @@ -109,7 +109,7 @@ class FakeDB { .sibling_path = sibling_path, .leaf_index = 2, - .historic_note_hash_tree_root = required_utxo_tree_root, + .historical_note_hash_tree_root = required_utxo_tree_root, }); } @@ -153,7 +153,7 @@ class FakeDB { .sibling_path = sibling_path, .leaf_index = 2, - .historic_note_hash_tree_root = required_utxo_tree_root, + .historical_note_hash_tree_root = required_utxo_tree_root, }; }; }; diff --git a/docs/docs/about_aztec/overview.mdx b/docs/docs/about_aztec/overview.mdx index dde9f2c11925..3fceee95c47f 100644 --- a/docs/docs/about_aztec/overview.mdx +++ b/docs/docs/about_aztec/overview.mdx @@ -10,7 +10,7 @@ Aztec is an L2 that brings programmable privacy to Ethereum. A smart contract on Aztec is a collection of functions, written as ZK-SNARK circuits. These circuits can have different modes of execution: -1. Secret Functions -- can read and write private state, read historic public state, consume or send messages to / from Ethereum, and read Ethereum state. They can call other secret functions in the same contract, or other contracts, and can call public functions. +1. Secret Functions -- can read and write private state, read historical public state, consume or send messages to / from Ethereum, and read Ethereum state. They can call other secret functions in the same contract, or other contracts, and can call public functions. 2. Public Functions -- can read and write public state, write private state, consume or send messages to / from Ethereum and read Ethereum state. They can call other public functions on the same or other contracts. 3. Portal Contracts -- these are contracts on Ethereum that can receive messages from Aztec or send messages to Aztec from Ethereum contracts. diff --git a/docs/docs/concepts/advanced/data_structures/trees.md b/docs/docs/concepts/advanced/data_structures/trees.md index 45fc60c51a89..79ee1149d672 100644 --- a/docs/docs/concepts/advanced/data_structures/trees.md +++ b/docs/docs/concepts/advanced/data_structures/trees.md @@ -160,10 +160,10 @@ The contract tree contains information about every function of every contract de > Note: Aztec supports the ability to keep the logic of private functions of a smart contract private. In such cases, no information about the logic of that private function will be broadcast; only a randomized merkle root of that contract's data. -## Trees of historic trees' roots +## Blocks Tree -- `treeOfHistoricNoteHashTreeRoots`: for membership checks against historic roots of the `noteHashTree` -- `treeOfHistoricContractTreeRoots`: for membership checks against historic roots of the `contractTree` +Leaves are hashes of blocks (of block headers). +Can be used to access any of the trees above at some older point in time by doing a membership check of the old root in the block header and of the block header hash in the blocks tree. ## Trees of valid Kernel/Rollup circuit Verification Keys diff --git a/docs/docs/concepts/foundation/communication/public_private_calls.md b/docs/docs/concepts/foundation/communication/public_private_calls.md index 683126a14a3d..224574beeb7a 100644 --- a/docs/docs/concepts/foundation/communication/public_private_calls.md +++ b/docs/docs/concepts/foundation/communication/public_private_calls.md @@ -34,7 +34,7 @@ To avoid this issue, we permit the use of historical data as long as the data ha In this model, instead of informing the builder of our intentions, we construct the proof $\pi$ and then provide them with the transaction results (new commitments and nullifiers, contract deployments and cross-chain messages) in addition to $\pi$. The builder will then be responsible for inserting these new commitments and nullifiers into the state. They will be aware of the intermediates and can discard transactions that try to produce existing nullifiers (double spend), as doing so would invalidate the rollup proof. -On the left-hand side of the diagram below, we see the fully public world where storage is shared, while on the right-hand side, we see the private world where all reads are historic. +On the left-hand side of the diagram below, we see the fully public world where storage is shared, while on the right-hand side, we see the private world where all reads are historical. @@ -82,15 +82,15 @@ From the above, we should have a decent idea about what private and public funct Many applications rely on some form of access control to function well. USDC have a blacklist, where only parties not on the list should be able to transfer. And other systems such as Aave have limits such that only the pool contract is able to mint debt tokens and transfers held funds. -Access control like this cannot easily be enforced in the private domain, as reading is also nullifying(to ensure data is up to date). However, as it is possible to read historic public state, one can combine private and public functions to get the desired effect. +Access control like this cannot easily be enforced in the private domain, as reading is also nullifying(to ensure data is up to date). However, as it is possible to read historical public state, one can combine private and public functions to get the desired effect. -Say the public state holds a `mapping(address user => bool blacklisted)` and a value with the block number of the last update `last_updated`. The private functions can then use this public blacklist IF it also performs a public function call that reverts if the block number of the historic state is older than the `last_updated`. This means that updating the blacklist would make pending transactions fail, but allow a public blacklist to be used. Similar would work for the Aave example, where it is just a public value with the allowed caller contracts. Example of how this would be written is seen below. Note that because the `onlyFresh` is done in public, the user might not know when he is generating his proof whether it will be valid or not. +Say the public state holds a `mapping(address user => bool blacklisted)` and a value with the block number of the last update `last_updated`. The private functions can then use this public blacklist IF it also performs a public function call that reverts if the block number of the historical state is older than the `last_updated`. This means that updating the blacklist would make pending transactions fail, but allow a public blacklist to be used. Similar would work for the Aave example, where it is just a public value with the allowed caller contracts. Example of how this would be written is seen below. Note that because the `onlyFresh` is done in public, the user might not know when he is generating his proof whether it will be valid or not. ```solidity function transfer( secret address to, secret uint256 amount, - secret HistoricState state + secret HistoricalState state ) secret returns(bool) { if (blacklisted[msg.sender] || blacklisted[to]) revert("Blacklisted"); onlyFresh(state.blockNumber); diff --git a/docs/docs/dev_docs/contracts/resources/common_patterns/main.md b/docs/docs/dev_docs/contracts/resources/common_patterns/main.md index 82afee5c96d7..d0c535df8717 100644 --- a/docs/docs/dev_docs/contracts/resources/common_patterns/main.md +++ b/docs/docs/dev_docs/contracts/resources/common_patterns/main.md @@ -125,7 +125,7 @@ There are several patterns here: There are several other designs we are discussing through [in this discourse post](https://discourse.aztec.network/t/how-to-handle-private-escrows-between-two-parties/2440) but they need some changes in the protocol or in our demo contract. If you are interested in this discussion, please participate in the discourse post! ### Share Private Notes -If you have private state that needs to be handled by more than a single user (but no more than a handful), you can add the note commitment to the private data tree, and then encrypt the note once for each of the users that need to see it. And if any of those users should be able to consume the note, you can generate a random nullifier on creation and store it in the encrypted note, instead of relying on the user secret. +If you have private state that needs to be handled by more than a single user (but no more than a handful), you can add the note commitment to the note hash tree, and then encrypt the note once for each of the users that need to see it. And if any of those users should be able to consume the note, you can generate a random nullifier on creation and store it in the encrypted note, instead of relying on the user secret. ## Anti Patterns There are mistakes one can make to reduce their privacy set and therefore make it trivial to do analysis and link addresses. Some of them are: diff --git a/docs/docs/dev_docs/contracts/syntax/context.mdx b/docs/docs/dev_docs/contracts/syntax/context.mdx index f73bfbe72ad0..1855f59222e2 100644 --- a/docs/docs/dev_docs/contracts/syntax/context.mdx +++ b/docs/docs/dev_docs/contracts/syntax/context.mdx @@ -18,7 +18,7 @@ On this page, you'll learn - The details and functionalities of the private context in Aztec.nr - Difference between the private and public contexts and their unified APIs -- Components of the private context, such as inputs, historic block data, and contract deployment data +- Components of the private context, such as inputs, block header, and contract deployment data - Elements like return values, read requests, new commitments, and nullifiers in transaction processing - Differences between the private and public contexts, especially the unique features and variables in the public context @@ -44,7 +44,7 @@ The context inputs includes all of the information that is passed from the kerne #include_code private-context-inputs /yarn-project/aztec-nr/aztec/src/abi.nr rust -As shown in the snippet, the application context is made up of 4 main structures. The call context, the block data, the contract deployment data and the private global variables. +As shown in the snippet, the application context is made up of 4 main structures. The call context, the block header, the contract deployment data and the private global variables. First of all, the call context. @@ -71,11 +71,11 @@ The call context contains information about the current call being made: - is_static_call: This will be set if and only if the current call is a static call. In a static call, state changing altering operations are not allowed. - is_contract_deployment: This will be set if and only if the current call is the contract's constructor. -### Historic Block Data +### Block Header -Another structure that is contained within the context is the Historic Block Data object. This object is a special one as it contains all of the roots of Aztec's data trees. +Another structure that is contained within the context is the Block Header object. This object is a special one as it contains all of the roots of Aztec's data trees. -#include_code historic-block-data /yarn-project/aztec-nr/aztec/src/abi.nr rust +#include_code block-header /yarn-project/aztec-nr/aztec/src/abi.nr rust ### Contract Deployment Data @@ -137,7 +137,7 @@ The Public Context includes all of the information passed from the `Public VM` i ### Public Context Inputs -In the current version of the system, the public context is almost a clone of the private execution context. It contains the same call context data, access to the same historic tree roots, however it does NOT have access to contract deployment data, this is due to traditional contract deployments only currently being possible from private transactions. +In the current version of the system, the public context is almost a clone of the private execution context. It contains the same call context data, access to the same historical tree roots, however it does NOT have access to contract deployment data, this is due to traditional contract deployments only currently being possible from private transactions. #include_code public-context-inputs /yarn-project/aztec-nr/aztec/src/abi.nr rust diff --git a/docs/docs/dev_docs/debugging/sandbox-errors.md b/docs/docs/dev_docs/debugging/sandbox-errors.md index f31752a8d69f..fd69c43d831f 100644 --- a/docs/docs/dev_docs/debugging/sandbox-errors.md +++ b/docs/docs/dev_docs/debugging/sandbox-errors.md @@ -62,7 +62,7 @@ Confirms that the TxRequest (user's intent) matches the private call being execu #### 2018 - PRIVATE_KERNEL\_\_READ_REQUEST_NOTE_HASH_TREE_ROOT_MISMATCH -Given a read request and provided witness, we check that the merkle root obtained from the witness' sibling path and it's leaf is similar to the historic state root we want to read against. This is a sanity check to ensure we are reading from the right state. +Given a read request and provided witness, we check that the merkle root obtained from the witness' sibling path and it's leaf is similar to the historical state root we want to read against. This is a sanity check to ensure we are reading from the right state. For a non transient read, we fetch the merkle root from the membership witnesses and the leaf index #### 2019 - PRIVATE_KERNEL\_\_TRANSIENT_READ_REQUEST_NO_MATCH @@ -164,11 +164,11 @@ You can have a look at our current constants/limitations in [constants.nr](https #### 7008 - MEMBERSHIP_CHECK_FAILED -Users may create a proof against a historic state in Aztec. The rollup circuits performs a merkle membership check to ensure this state existed at some point. If the historic state doesn't exist, you get this error. Some examples when you may hit this error are: +Users may create a proof against a historical state in Aztec. The rollup circuits performs a merkle membership check to ensure this state existed at some point. If the historical state doesn't exist, you get this error. Some examples when you may hit this error are: -- using invalid historic note hash tree state (aka historic commitments tree) -- using invalid historic contracts data tree state -- using invalid historic L1 to L2 message data tree state +- using invalid historical note hash tree state (aka historical commitments tree) +- using invalid historical contracts data tree state +- using invalid historical L1 to L2 message data tree state - inserting a subtree into the greater tree - we make a smaller merkle tree of all the new commitments/nullifiers etc that were created in a transaction or in a rollup and add it to the bigger state tree. Before inserting, we do a merkle membership check to ensure that the index to insert at is indeed an empty subtree (otherwise we would be overwriting state). This can happen when `next_available_leaf_index` in the state tree's snapshot is wrong (it is fetched by the sequencer from the archiver). The error message should reveal which tree is causing this issue - nullifier tree related errors - The nullifier tree uses an [Indexed Merkle Tree](../../concepts/advanced/data_structures/indexed_merkle_tree.md). It requires additional data from the archiver to know which is the nullifier in the tree that is just below the current nullifier before it can perform batch insertion. If the low nullifier is wrong, or the nullifier is in incorrect range, you may receive this error. diff --git a/docs/docs/dev_docs/getting_started/aztecjs-getting-started.md b/docs/docs/dev_docs/getting_started/aztecjs-getting-started.md index e7be7d00720c..185c8bdaf15b 100644 --- a/docs/docs/dev_docs/getting_started/aztecjs-getting-started.md +++ b/docs/docs/dev_docs/getting_started/aztecjs-getting-started.md @@ -337,7 +337,7 @@ This function takes: 1. A quantity of tokens to be minted. 2. A secret hash. -This function is public and it inserts a new note into the private data tree and increases the total token supply by the amount minted. +This function is public and it inserts a new note into the note hash tree and increases the total token supply by the amount minted. To make the note spendable the note has to be redeemed. A user can do that by calling the `redeem_shield` function. diff --git a/docs/docs/dev_docs/getting_started/core-concepts.md b/docs/docs/dev_docs/getting_started/core-concepts.md index e22e1d3a04db..e5087c624c14 100644 --- a/docs/docs/dev_docs/getting_started/core-concepts.md +++ b/docs/docs/dev_docs/getting_started/core-concepts.md @@ -31,7 +31,7 @@ You can call a public function from a private function by using `context.call_pu #include_code call_public_function yarn-project/noir-contracts/src/contracts/card_game_contract/src/main.nr rust -You cannot call a private function from a public function, but you can use a slow updates tree to read historic public state and stage writes to public state from a private function. +You cannot call a private function from a public function, but you can use a slow updates tree to read historical public state and stage writes to public state from a private function. ### Data types diff --git a/docs/docs/dev_docs/limitations/main.md b/docs/docs/dev_docs/limitations/main.md index 08a911d29e27..c697898a6f78 100644 --- a/docs/docs/dev_docs/limitations/main.md +++ b/docs/docs/dev_docs/limitations/main.md @@ -130,7 +130,7 @@ A contract can't perform a delegatecall yet (if ever). Delegatecalls are quite a Ethereum has a notion of a 'full node' which keeps-up with the blockchain and stores the full chain state. Many users don't wish to run full nodes, so rely on 3rd-party 'full-node-as-a-service' infrastructure providers, who service blockchain queries from their users. -This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are, or about their historic network activity, or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, research is underway to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. +This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are, or about their historical network activity, or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, research is underway to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. ### No private data authentication diff --git a/docs/docs/dev_docs/privacy/main.md b/docs/docs/dev_docs/privacy/main.md index b1818b7f84ba..7964a5828887 100644 --- a/docs/docs/dev_docs/privacy/main.md +++ b/docs/docs/dev_docs/privacy/main.md @@ -97,7 +97,7 @@ It's not just the broadcasting of transactions to the network that can leak data Ethereum has a notion of a 'full node' which keeps-up with the blockchain and stores the full chain state. Many users don't wish to run full nodes, so rely on 3rd-party 'full-node-as-a-service' infrastructure providers, who service blockchain queries from their users. -This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are; about their historic network activity; or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, research is underway to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. +This pattern is likely to develop in Aztec as well, except there's a problem: privacy. If a privacy-seeking user makes a query to a 3rd-party 'full node', that user might leak data about who they are; about their historical network activity; or about their future intentions. One solution to this problem is "always run a full node", but pragmatically, not everyone will. To protect less-advanced users' privacy, research is underway to explore how a privacy-seeking user may request and receive data from a 3rd-party node without revealing what that data is, nor who is making the request. App developers should be aware of this avenue for private data leakage. **Whenever an app requests information from a node, the entity running that node is unlikely be your user!** @@ -105,9 +105,9 @@ App developers should be aware of this avenue for private data leakage. **Whenev ##### Querying for up-to-date note sibling paths -To read a private state is to read a note from the note hash tree. To read a note is to prove existence of that note in the note hash tree. And to prove existence is to re-compute the root of the note hash tree using the leaf value, the leaf index, and the sibling path of that leaf. This computed root is then exposed to the world, as a way of saying "This note exists", or more precisely "This note has existed at least since this historic snapshot time". +To read a private state is to read a note from the note hash tree. To read a note is to prove existence of that note in the note hash tree. And to prove existence is to re-compute the root of the note hash tree using the leaf value, the leaf index, and the sibling path of that leaf. This computed root is then exposed to the world, as a way of saying "This note exists", or more precisely "This note has existed at least since this historical snapshot time". -If an old historic snapshot is used, then that old historic root will be exposed, and this leaks some information about the nature of your transaction: it leaks that your note was created before the snapshot date. It shrinks the 'privacy set' of the transaction to a smaller window of time than the entire history of the network. +If an old historical snapshot is used, then that old historical root will be exposed, and this leaks some information about the nature of your transaction: it leaks that your note was created before the snapshot date. It shrinks the 'privacy set' of the transaction to a smaller window of time than the entire history of the network. So for maximal privacy, it's in a user's best interest to read from the very-latest snapshot of the data tree. diff --git a/docs/internal_notes/building_dapps.md b/docs/internal_notes/building_dapps.md index fc807def92b6..b6d4f3a1be11 100644 --- a/docs/internal_notes/building_dapps.md +++ b/docs/internal_notes/building_dapps.md @@ -29,7 +29,7 @@ Explain how to write a dapp using [`aztec.js`](https://github.com/AztecProtocol/ - How to query state - How to query whether a tx has been 'mined' - How to subscribe to logs - - How to filter for historic data in the historic block tree? + - How to filter for historical data in the historical block tree? - How to query data from any of the trees (advanced) FOR INSTRUCTIONS FOR BUILDING A WALLET, WE SHOULD WRITE DOCS HERE diff --git a/docs/internal_notes/dev_docs/sandbox/components.md b/docs/internal_notes/dev_docs/sandbox/components.md index 509e851da715..5045e2c18fdc 100644 --- a/docs/internal_notes/dev_docs/sandbox/components.md +++ b/docs/internal_notes/dev_docs/sandbox/components.md @@ -246,7 +246,7 @@ Responsibilities: - "Persists" the various merkle trees (configurable). - For this milestone 1.1, we'll need the following trees: - Contract Tree - - Contract Tree Roots Tree (the tree whose leaves are the roots of historic rollups' contract trees) + - Contract Tree Roots Tree (the tree whose leaves are the roots of historical rollups' contract trees) - Nullifier Tree (so that the contract address can never be re-registered in a future deployment) - Note: Suyash has implemented C++ for the 'new' kind of nullifier tree. - Provides methods for updating the trees with commit, rollback semantics. diff --git a/l1-contracts/src/core/libraries/ConstantsGen.sol b/l1-contracts/src/core/libraries/ConstantsGen.sol index 9cb97e57a6b6..d63790f5e034 100644 --- a/l1-contracts/src/core/libraries/ConstantsGen.sol +++ b/l1-contracts/src/core/libraries/ConstantsGen.sol @@ -56,7 +56,7 @@ library Constants { uint256 internal constant NOTE_HASH_SUBTREE_HEIGHT = 7; uint256 internal constant NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH = 25; uint256 internal constant NULLIFIER_SUBTREE_HEIGHT = 7; - uint256 internal constant HISTORIC_BLOCKS_TREE_HEIGHT = 16; + uint256 internal constant BLOCKS_TREE_HEIGHT = 16; uint256 internal constant NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH = 13; uint256 internal constant L1_TO_L2_MSG_SUBTREE_HEIGHT = 4; uint256 internal constant L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12; @@ -70,7 +70,7 @@ library Constants { uint256 internal constant MAX_NOTES_PER_PAGE = 10; uint256 internal constant VIEW_NOTE_ORACLE_RETURN_LENGTH = 212; uint256 internal constant CALL_CONTEXT_LENGTH = 7; - uint256 internal constant HISTORIC_BLOCK_DATA_LENGTH = 7; + uint256 internal constant BLOCK_HEADER_LENGTH = 7; uint256 internal constant FUNCTION_DATA_LENGTH = 4; uint256 internal constant CONTRACT_DEPLOYMENT_DATA_LENGTH = 6; uint256 internal constant PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 155; diff --git a/l1-contracts/src/core/libraries/Decoder.sol b/l1-contracts/src/core/libraries/Decoder.sol index ccc7d0cf677a..110522190b1b 100644 --- a/l1-contracts/src/core/libraries/Decoder.sol +++ b/l1-contracts/src/core/libraries/Decoder.sol @@ -35,8 +35,8 @@ import {Hash} from "./Hash.sol"; * | 0x00ec | 0x20 | startPublicDataTreeRoot * | 0x010c | 0x20 | startL1ToL2MessageTreeSnapshot.root * | 0x012c | 0x04 | startL1ToL2MessageTreeSnapshot.nextAvailableLeafIndex - * | 0x0130 | 0x20 | startHistoricBlocksTreeSnapshot.root - * | 0x0150 | 0x04 | startHistoricBlocksTreeSnapshot.nextAvailableLeafIndex + * | 0x0130 | 0x20 | startBlocksTreeSnapshot.root + * | 0x0150 | 0x04 | startBlocksTreeSnapshot.nextAvailableLeafIndex * | 0x0154 | 0x20 | endNoteHashTreeSnapshot.root * | 0x0174 | 0x04 | endNoteHashTreeSnapshot.nextAvailableLeafIndex * | 0x0178 | 0x20 | endNullifierTreeSnapshot.root @@ -46,8 +46,8 @@ import {Hash} from "./Hash.sol"; * | 0x01c0 | 0x20 | endPublicDataTreeRoot * | 0x01e0 | 0x20 | endL1ToL2MessageTreeSnapshot.root * | 0x0200 | 0x04 | endL1ToL2MessageTreeSnapshot.nextAvailableLeafIndex - * | 0x0204 | 0x20 | endHistoricBlocksTreeSnapshot.root - * | 0x0224 | 0x04 | endHistoricBlocksTreeSnapshot.nextAvailableLeafIndex + * | 0x0204 | 0x20 | endBlocksTreeSnapshot.root + * | 0x0224 | 0x04 | endBlocksTreeSnapshot.nextAvailableLeafIndex * | 0x0228 | 0x04 | len(newCommitments) (denoted a) * | 0x022c | a * 0x20 | newCommitments * | 0x022c + a * 0x20 | 0x04 | len(newNullifiers) (denoted b) diff --git a/l1-contracts/src/core/messagebridge/Registry.sol b/l1-contracts/src/core/messagebridge/Registry.sol index 15f6ce6b2c8f..947597c8b02f 100644 --- a/l1-contracts/src/core/messagebridge/Registry.sol +++ b/l1-contracts/src/core/messagebridge/Registry.sol @@ -15,7 +15,7 @@ import {Errors} from "../libraries/Errors.sol"; /** * @title Registry * @author Aztec Labs - * @notice Keeps track of addresses of rollup, inbox and outbox as well as historic addresses. + * @notice Keeps track of addresses of rollup, inbox and outbox as well as historical addresses. * Used as the source of truth for finding the "head" of the rollup chain. Very important information * for L1<->L2 communication. */ diff --git a/yarn-project/acir-simulator/src/acvm/deserialize.ts b/yarn-project/acir-simulator/src/acvm/deserialize.ts index d82640a42e9b..649ad620cf03 100644 --- a/yarn-project/acir-simulator/src/acvm/deserialize.ts +++ b/yarn-project/acir-simulator/src/acvm/deserialize.ts @@ -1,10 +1,10 @@ import { + BlockHeader, CallContext, ContractDeploymentData, ContractStorageRead, ContractStorageUpdateRequest, FunctionSelector, - HistoricBlockData, MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, MAX_NEW_NULLIFIERS_PER_CALL, @@ -163,7 +163,7 @@ export function extractPrivateCircuitPublicInputs( const encryptedLogPreimagesLength = witnessReader.readField(); const unencryptedLogPreimagesLength = witnessReader.readField(); - const historicBlockData = new HistoricBlockData( + const blockHeader = new BlockHeader( witnessReader.readField(), witnessReader.readField(), witnessReader.readField(), @@ -201,7 +201,7 @@ export function extractPrivateCircuitPublicInputs( unencryptedLogsHash, encryptedLogPreimagesLength, unencryptedLogPreimagesLength, - historicBlockData, + blockHeader, contractDeploymentData, chainId, version, @@ -255,7 +255,7 @@ export function extractPublicCircuitPublicInputs(partialWitness: ACVMWitness, ac const unencryptedLogsHash = witnessReader.readFieldArray(NUM_FIELDS_PER_SHA256); const unencryptedLogPreimagesLength = witnessReader.readField(); - const historicBlockData = new HistoricBlockData( + const blockHeader = new BlockHeader( witnessReader.readField(), witnessReader.readField(), witnessReader.readField(), @@ -282,7 +282,7 @@ export function extractPublicCircuitPublicInputs(partialWitness: ACVMWitness, ac newL2ToL1Msgs, unencryptedLogsHash, unencryptedLogPreimagesLength, - historicBlockData, + blockHeader, proverAddress, ); } diff --git a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts index ebc8ca180f16..87a32f072c0f 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/oracle.ts @@ -109,14 +109,14 @@ export class Oracle { return witness.toFieldArray().map(toACVMField); } - async getBlockData([blockNumber]: ACVMField[]): Promise { + async getBlockHeader([blockNumber]: ACVMField[]): Promise { const parsedBlockNumber = frToNumber(fromACVMField(blockNumber)); - const blockData = await this.typedOracle.getBlockData(parsedBlockNumber); - if (!blockData) { - throw new Error(`Block data not found for block ${parsedBlockNumber}.`); + const blockHeader = await this.typedOracle.getBlockHeader(parsedBlockNumber); + if (!blockHeader) { + throw new Error(`Block header not found for block ${parsedBlockNumber}.`); } - return blockData.toArray().map(toACVMField); + return blockHeader.toArray().map(toACVMField); } async getAuthWitness([messageHash]: ACVMField[]): Promise { diff --git a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts index 9138009309c4..7013689a8ca3 100644 --- a/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts +++ b/yarn-project/acir-simulator/src/acvm/oracle/typed_oracle.ts @@ -1,4 +1,4 @@ -import { HistoricBlockData, PrivateCallStackItem, PublicCallRequest } from '@aztec/circuits.js'; +import { BlockHeader, PrivateCallStackItem, PublicCallRequest } from '@aztec/circuits.js'; import { FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -102,7 +102,7 @@ export abstract class TypedOracle { throw new Error('Not available.'); } - getBlockData(_blockNumber: number): Promise { + getBlockHeader(_blockNumber: number): Promise { throw new Error('Not available.'); } diff --git a/yarn-project/acir-simulator/src/acvm/serialize.ts b/yarn-project/acir-simulator/src/acvm/serialize.ts index dff75ab6cb97..abf78f63c1b6 100644 --- a/yarn-project/acir-simulator/src/acvm/serialize.ts +++ b/yarn-project/acir-simulator/src/acvm/serialize.ts @@ -1,9 +1,9 @@ import { + BlockHeader, CallContext, ContractDeploymentData, FunctionData, GlobalVariables, - HistoricBlockData, PrivateCallStackItem, PrivateCircuitPublicInputs, PublicCallRequest, @@ -101,19 +101,19 @@ export function toACVMContractDeploymentData(contractDeploymentData: ContractDep } /** - * Converts a historic block data into ACVM fields. - * @param historicBlockData - The historic block data object to convert. + * Converts a block header into ACVM fields. + * @param blockHeader - The block header object to convert. * @returns The ACVM fields. */ -export function toACVMHistoricBlockData(historicBlockData: HistoricBlockData): ACVMField[] { +export function toACVMBlockHeader(blockHeader: BlockHeader): ACVMField[] { return [ - toACVMField(historicBlockData.noteHashTreeRoot), - toACVMField(historicBlockData.nullifierTreeRoot), - toACVMField(historicBlockData.contractTreeRoot), - toACVMField(historicBlockData.l1ToL2MessagesTreeRoot), - toACVMField(historicBlockData.blocksTreeRoot), - toACVMField(historicBlockData.publicDataTreeRoot), - toACVMField(historicBlockData.globalVariablesHash), + toACVMField(blockHeader.noteHashTreeRoot), + toACVMField(blockHeader.nullifierTreeRoot), + toACVMField(blockHeader.contractTreeRoot), + toACVMField(blockHeader.l1ToL2MessagesTreeRoot), + toACVMField(blockHeader.blocksTreeRoot), + toACVMField(blockHeader.publicDataTreeRoot), + toACVMField(blockHeader.globalVariablesHash), ]; } @@ -156,7 +156,7 @@ export function toACVMPublicInputs(publicInputs: PrivateCircuitPublicInputs): AC toACVMField(publicInputs.encryptedLogPreimagesLength), toACVMField(publicInputs.unencryptedLogPreimagesLength), - ...toACVMHistoricBlockData(publicInputs.historicBlockData), + ...toACVMBlockHeader(publicInputs.blockHeader), ...toACVMContractDeploymentData(publicInputs.contractDeploymentData), diff --git a/yarn-project/acir-simulator/src/client/client_execution_context.ts b/yarn-project/acir-simulator/src/client/client_execution_context.ts index 5ccbbcc2b998..d113bed04b3c 100644 --- a/yarn-project/acir-simulator/src/client/client_execution_context.ts +++ b/yarn-project/acir-simulator/src/client/client_execution_context.ts @@ -1,9 +1,9 @@ import { + BlockHeader, CallContext, ContractDeploymentData, FunctionData, FunctionSelector, - HistoricBlockData, PublicCallRequest, ReadRequestMembershipWitness, TxContext, @@ -18,9 +18,9 @@ import { AuthWitness, FunctionL2Logs, L1NotePayload, Note, UnencryptedL2Log } fr import { NoteData, + toACVMBlockHeader, toACVMCallContext, toACVMContractDeploymentData, - toACVMHistoricBlockData, toACVMWitness, } from '../acvm/index.js'; import { SideEffectCounter } from '../common/index.js'; @@ -64,8 +64,8 @@ export class ClientExecutionContext extends ViewDataOracle { private readonly argsHash: Fr, private readonly txContext: TxContext, private readonly callContext: CallContext, - /** Data required to reconstruct the block hash, it contains historic roots. */ - protected readonly historicBlockData: HistoricBlockData, + /** Data required to reconstruct the block hash, it contains historical roots. */ + protected readonly blockHeader: BlockHeader, /** List of transient auth witnesses to be used during this simulation */ protected readonly authWitnesses: AuthWitness[], private readonly packedArgsCache: PackedArgsCache, @@ -75,7 +75,7 @@ export class ClientExecutionContext extends ViewDataOracle { private readonly curve: Grumpkin, protected log = createDebugLogger('aztec:simulator:client_execution_context'), ) { - super(contractAddress, historicBlockData, authWitnesses, db, undefined, log); + super(contractAddress, blockHeader, authWitnesses, db, undefined, log); } // We still need this function until we can get user-defined ordering of structs for fn arguments @@ -98,7 +98,7 @@ export class ClientExecutionContext extends ViewDataOracle { const fields = [ ...toACVMCallContext(this.callContext), - ...toACVMHistoricBlockData(this.historicBlockData), + ...toACVMBlockHeader(this.blockHeader), ...toACVMContractDeploymentData(contractDeploymentData), this.txContext.chainId, @@ -326,7 +326,7 @@ export class ClientExecutionContext extends ViewDataOracle { argsHash, derivedTxContext, derivedCallContext, - this.historicBlockData, + this.blockHeader, this.authWitnesses, this.packedArgsCache, this.noteCache, diff --git a/yarn-project/acir-simulator/src/client/db_oracle.ts b/yarn-project/acir-simulator/src/client/db_oracle.ts index ad2cb1a19c49..6ed7a6a8e6a1 100644 --- a/yarn-project/acir-simulator/src/client/db_oracle.ts +++ b/yarn-project/acir-simulator/src/client/db_oracle.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, GrumpkinPrivateKey, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; +import { BlockHeader, CompleteAddress, GrumpkinPrivateKey, PublicKey } from '@aztec/circuits.js'; import { FunctionArtifact, FunctionDebugMetadata, FunctionSelector } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; @@ -109,12 +109,12 @@ export interface DBOracle extends CommitmentsDB { getNullifierIndex(nullifier: Fr): Promise; /** - * Retrieve the databases view of the Historic Block Data object. - * This structure is fed into the circuits simulator and is used to prove against certain historic roots. + * Retrieve the databases view of the Block Header object. + * This structure is fed into the circuits simulator and is used to prove against certain historical roots. * - * @returns A Promise that resolves to a HistoricBlockData object. + * @returns A Promise that resolves to a BlockHeader object. */ - getHistoricBlockData(): Promise; + getBlockHeader(): Promise; /** * Fetch the index of the leaf in the respective tree diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index b96d69dc3384..6b0a7816a51f 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -1,11 +1,11 @@ import { + BlockHeader, CallContext, CompleteAddress, ContractDeploymentData, EMPTY_NULLIFIED_COMMITMENT, FieldsOf, FunctionData, - HistoricBlockData, L1_TO_L2_MSG_TREE_HEIGHT, MAX_NEW_COMMITMENTS_PER_CALL, NOTE_HASH_TREE_HEIGHT, @@ -58,7 +58,7 @@ describe('Private Execution test suite', () => { let oracle: MockProxy; let acirSimulator: AcirSimulator; - let blockData = HistoricBlockData.empty(); + let blockHeader = BlockHeader.empty(); let logger: DebugLogger; const defaultContractAddress = AztecAddress.random(); @@ -132,10 +132,10 @@ describe('Private Execution test suite', () => { // Update root. const newRoot = trees[name].getRoot(false); - const prevRoots = blockData.toBuffer(); + const prevRoots = blockHeader.toBuffer(); const rootIndex = name === 'noteHash' ? 0 : 32 * 3; const newRoots = Buffer.concat([prevRoots.subarray(0, rootIndex), newRoot, prevRoots.subarray(rootIndex + 32)]); - blockData = HistoricBlockData.fromBuffer(newRoots); + blockHeader = BlockHeader.fromBuffer(newRoots); return trees[name]; }; @@ -163,7 +163,7 @@ describe('Private Execution test suite', () => { } throw new Error(`Unknown address ${pubKey}`); }); - oracle.getHistoricBlockData.mockResolvedValue(blockData); + oracle.getBlockHeader.mockResolvedValue(blockHeader); acirSimulator = new AcirSimulator(oracle); }); diff --git a/yarn-project/acir-simulator/src/client/simulator.ts b/yarn-project/acir-simulator/src/client/simulator.ts index cf7222cbe20b..520626add64e 100644 --- a/yarn-project/acir-simulator/src/client/simulator.ts +++ b/yarn-project/acir-simulator/src/client/simulator.ts @@ -79,7 +79,7 @@ export class AcirSimulator { const curve = new Grumpkin(); - const historicBlockData = await this.db.getHistoricBlockData(); + const blockHeader = await this.db.getBlockHeader(); const callContext = new CallContext( msgSender, contractAddress, @@ -94,7 +94,7 @@ export class AcirSimulator { request.argsHash, request.txContext, callContext, - historicBlockData, + blockHeader, request.authWitnesses, PackedArgsCache.create(request.packedArguments), new ExecutionNoteCache(), @@ -133,8 +133,8 @@ export class AcirSimulator { throw new Error(`Cannot run ${entryPointArtifact.functionType} function as constrained`); } - const historicBlockData = await this.db.getHistoricBlockData(); - const context = new ViewDataOracle(contractAddress, historicBlockData, [], this.db, aztecNode); + const blockHeader = await this.db.getBlockHeader(); + const context = new ViewDataOracle(contractAddress, blockHeader, [], this.db, aztecNode); try { return await executeUnconstrainedFunction( diff --git a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts index 7e7eb3716d45..3db5f2e9f3da 100644 --- a/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/unconstrained_execution.test.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, FunctionData, HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader, CompleteAddress, FunctionData } from '@aztec/circuits.js'; import { FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr, GrumpkinScalar } from '@aztec/foundation/fields'; @@ -46,7 +46,7 @@ describe('Unconstrained Execution test suite', () => { const notes: Note[] = [...Array(5).fill(buildNote(1n, owner)), ...Array(2).fill(buildNote(2n, owner))]; - oracle.getHistoricBlockData.mockResolvedValue(HistoricBlockData.empty()); + oracle.getBlockHeader.mockResolvedValue(BlockHeader.empty()); oracle.getNotes.mockResolvedValue( notes.map((note, index) => ({ contractAddress, diff --git a/yarn-project/acir-simulator/src/client/view_data_oracle.ts b/yarn-project/acir-simulator/src/client/view_data_oracle.ts index fe124f853d29..f744e54dd6c2 100644 --- a/yarn-project/acir-simulator/src/client/view_data_oracle.ts +++ b/yarn-project/acir-simulator/src/client/view_data_oracle.ts @@ -1,4 +1,4 @@ -import { HistoricBlockData, PublicKey } from '@aztec/circuits.js'; +import { BlockHeader, PublicKey } from '@aztec/circuits.js'; import { computeGlobalsHash, siloNullifier } from '@aztec/circuits.js/abis'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; @@ -16,8 +16,8 @@ import { pickNotes } from './pick_notes.js'; export class ViewDataOracle extends TypedOracle { constructor( protected readonly contractAddress: AztecAddress, - /** Data required to reconstruct the block hash, it contains historic roots. */ - protected readonly historicBlockData: HistoricBlockData, + /** Data required to reconstruct the block hash, it contains historical roots. */ + protected readonly blockHeader: BlockHeader, /** List of transient auth witnesses to be used during this simulation */ protected readonly authWitnesses: AuthWitness[], protected readonly db: DBOracle, @@ -92,21 +92,21 @@ export class ViewDataOracle extends TypedOracle { } /** - * Fetches historic block data for a given block. - * @param blockNumber - The block number at which to get the historic block data. - * @returns Historic block data extracted from a block with block number `blockNumber`. + * Fetches a block header of a given block. + * @param blockNumber - The number of a block of which to get the block header. + * @returns Block extracted from a block with block number `blockNumber`. */ - public async getBlockData(blockNumber: number): Promise { + public async getBlockHeader(blockNumber: number): Promise { const block = await this.db.getBlock(blockNumber); if (!block) { return undefined; } - return new HistoricBlockData( + return new BlockHeader( block.endNoteHashTreeSnapshot.root, block.endNullifierTreeSnapshot.root, block.endContractTreeSnapshot.root, block.endL1ToL2MessagesTreeSnapshot.root, - block.endHistoricBlocksTreeSnapshot.root, + block.endBlocksTreeSnapshot.root, new Fr(0), // TODO(#3441) privateKernelVkTreeRoot is not present in L2Block and it's not yet populated in noir block.endPublicDataTreeRoot, computeGlobalsHash(block.globalVariables), @@ -199,7 +199,7 @@ export class ViewDataOracle extends TypedOracle { */ public async getL1ToL2Message(msgKey: Fr) { const message = await this.db.getL1ToL2Message(msgKey); - return { ...message, root: this.historicBlockData.l1ToL2MessagesTreeRoot }; + return { ...message, root: this.blockHeader.l1ToL2MessagesTreeRoot }; } /** diff --git a/yarn-project/acir-simulator/src/public/executor.ts b/yarn-project/acir-simulator/src/public/executor.ts index fdcb691898d0..77d9b1e9baa9 100644 --- a/yarn-project/acir-simulator/src/public/executor.ts +++ b/yarn-project/acir-simulator/src/public/executor.ts @@ -1,4 +1,4 @@ -import { GlobalVariables, HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader, GlobalVariables } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; import { Oracle, acvm, extractCallStack, extractPublicCircuitPublicInputs } from '../acvm/index.js'; @@ -81,7 +81,7 @@ export class PublicExecutor { private readonly stateDb: PublicStateDB, private readonly contractsDb: PublicContractsDB, private readonly commitmentsDb: CommitmentsDB, - private readonly blockData: HistoricBlockData, + private readonly blockHeader: BlockHeader, ) {} /** @@ -105,7 +105,7 @@ export class PublicExecutor { const context = new PublicExecutionContext( execution, - this.blockData, + this.blockHeader, globalVariables, packedArgs, sideEffectCounter, diff --git a/yarn-project/acir-simulator/src/public/index.test.ts b/yarn-project/acir-simulator/src/public/index.test.ts index 4d985f476af8..1ab7da481bef 100644 --- a/yarn-project/acir-simulator/src/public/index.test.ts +++ b/yarn-project/acir-simulator/src/public/index.test.ts @@ -1,10 +1,4 @@ -import { - CallContext, - FunctionData, - GlobalVariables, - HistoricBlockData, - L1_TO_L2_MSG_TREE_HEIGHT, -} from '@aztec/circuits.js'; +import { BlockHeader, CallContext, FunctionData, GlobalVariables, L1_TO_L2_MSG_TREE_HEIGHT } from '@aztec/circuits.js'; import { FunctionArtifact, FunctionSelector, encodeArguments } from '@aztec/foundation/abi'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { pedersenHash } from '@aztec/foundation/crypto'; @@ -34,15 +28,15 @@ describe('ACIR public execution simulator', () => { let publicContracts: MockProxy; let commitmentsDb: MockProxy; let executor: PublicExecutor; - let blockData: HistoricBlockData; + let blockHeader: BlockHeader; beforeEach(() => { publicState = mock(); publicContracts = mock(); commitmentsDb = mock(); - blockData = HistoricBlockData.empty(); - executor = new PublicExecutor(publicState, publicContracts, commitmentsDb, blockData); + blockHeader = BlockHeader.empty(); + executor = new PublicExecutor(publicState, publicContracts, commitmentsDb, blockHeader); }, 10000); describe('Token contract', () => { diff --git a/yarn-project/acir-simulator/src/public/public_execution_context.ts b/yarn-project/acir-simulator/src/public/public_execution_context.ts index 6db7acfd3fdf..de7ee848009a 100644 --- a/yarn-project/acir-simulator/src/public/public_execution_context.ts +++ b/yarn-project/acir-simulator/src/public/public_execution_context.ts @@ -1,4 +1,4 @@ -import { CallContext, FunctionData, FunctionSelector, GlobalVariables, HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader, CallContext, FunctionData, FunctionSelector, GlobalVariables } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; @@ -7,9 +7,9 @@ import { FunctionL2Logs, UnencryptedL2Log } from '@aztec/types'; import { TypedOracle, + toACVMBlockHeader, toACVMCallContext, toACVMGlobalVariables, - toACVMHistoricBlockData, toACVMWitness, } from '../acvm/index.js'; import { PackedArgsCache, SideEffectCounter } from '../common/index.js'; @@ -31,7 +31,7 @@ export class PublicExecutionContext extends TypedOracle { * Data for this execution. */ public readonly execution: PublicExecution, - private readonly historicBlockData: HistoricBlockData, + private readonly blockHeader: BlockHeader, private readonly globalVariables: GlobalVariables, private readonly packedArgsCache: PackedArgsCache, private readonly sideEffectCounter: SideEffectCounter, @@ -48,7 +48,7 @@ export class PublicExecutionContext extends TypedOracle { * Generates the initial witness for a public function. * @param args - The arguments to the function. * @param callContext - The call context of the function. - * @param historicBlockData - Historic Trees roots and data required to reconstruct block hash. + * @param blockHeader - Contains data required to reconstruct a block hash (historical roots etc.). * @param globalVariables - The global variables. * @param witnessStartIndex - The index where to start inserting the parameters. * @returns The initial witness. @@ -57,7 +57,7 @@ export class PublicExecutionContext extends TypedOracle { const { callContext, args } = this.execution; const fields = [ ...toACVMCallContext(callContext), - ...toACVMHistoricBlockData(this.historicBlockData), + ...toACVMBlockHeader(this.blockHeader), ...toACVMGlobalVariables(this.globalVariables), ...args, @@ -104,7 +104,7 @@ export class PublicExecutionContext extends TypedOracle { public async getL1ToL2Message(msgKey: Fr) { // l1 to l2 messages in public contexts TODO: https://github.com/AztecProtocol/aztec-packages/issues/616 const message = await this.commitmentsDb.getL1ToL2Message(msgKey); - return { ...message, root: this.historicBlockData.l1ToL2MessagesTreeRoot }; + return { ...message, root: this.blockHeader.l1ToL2MessagesTreeRoot }; } /** @@ -210,7 +210,7 @@ export class PublicExecutionContext extends TypedOracle { const context = new PublicExecutionContext( nestedExecution, - this.historicBlockData, + this.blockHeader, this.globalVariables, this.packedArgsCache, this.sideEffectCounter, diff --git a/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts b/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts index 03f94ab8252a..09d316e86705 100644 --- a/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts +++ b/yarn-project/aztec-node/src/aztec-node/http_rpc_server.ts @@ -1,4 +1,4 @@ -import { FunctionSelector, HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader, FunctionSelector } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; @@ -34,7 +34,7 @@ export function createAztecNodeRpcServer(node: AztecNode) { ContractData, Fr, FunctionSelector, - HistoricBlockData, + BlockHeader, L2Block, L2Tx, LogId, diff --git a/yarn-project/aztec-node/src/aztec-node/server.ts b/yarn-project/aztec-node/src/aztec-node/server.ts index 817b1a6b2067..d1744c26b14f 100644 --- a/yarn-project/aztec-node/src/aztec-node/server.ts +++ b/yarn-project/aztec-node/src/aztec-node/server.ts @@ -1,10 +1,10 @@ import { Archiver, LMDBArchiverStore } from '@aztec/archiver'; import { + BLOCKS_TREE_HEIGHT, + BlockHeader, CONTRACT_TREE_HEIGHT, Fr, GlobalVariables, - HISTORIC_BLOCKS_TREE_HEIGHT, - HistoricBlockData, L1_TO_L2_MSG_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, NULLIFIER_TREE_HEIGHT, @@ -364,13 +364,11 @@ export class AztecNodeService implements AztecNode { } /** - * Returns a sibling path for a leaf in the committed historic blocks tree. + * Returns a sibling path for a leaf in the committed blocks tree. * @param leafIndex - Index of the leaf in the tree. * @returns The sibling path. */ - public async getHistoricBlocksTreeSiblingPath( - leafIndex: bigint, - ): Promise> { + public async getBlocksTreeSiblingPath(leafIndex: bigint): Promise> { const committedDb = await this.#getWorldState(); return committedDb.getSiblingPath(MerkleTreeId.BLOCKS_TREE, leafIndex); } @@ -499,14 +497,14 @@ export class AztecNodeService implements AztecNode { } /** - * Returns the currently committed historic block data. - * @returns The current committed block data. + * Returns the currently committed block header. + * @returns The current committed block header. */ - public async getHistoricBlockData(): Promise { + public async getBlockHeader(): Promise { const committedDb = await this.#getWorldState(); const [roots, globalsHash] = await Promise.all([this.getTreeRoots(), committedDb.getLatestGlobalVariablesHash()]); - return new HistoricBlockData( + return new BlockHeader( roots[MerkleTreeId.NOTE_HASH_TREE], roots[MerkleTreeId.NULLIFIER_TREE], roots[MerkleTreeId.CONTRACT_TREE], diff --git a/yarn-project/aztec-nr/aztec/src/abi.nr b/yarn-project/aztec-nr/aztec/src/abi.nr index c84ad8b6d8bd..88923767db7d 100644 --- a/yarn-project/aztec-nr/aztec/src/abi.nr +++ b/yarn-project/aztec-nr/aztec/src/abi.nr @@ -11,7 +11,7 @@ use crate::constants_gen::{ MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_CALL, MAX_PUBLIC_DATA_READS_PER_CALL, GENERATOR_INDEX__FUNCTION_ARGS, - HISTORIC_BLOCK_DATA_LENGTH, + BLOCK_HEADER_LENGTH, CONTRACT_DEPLOYMENT_DATA_LENGTH, CALL_CONTEXT_LENGTH, PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH, @@ -94,7 +94,7 @@ impl ContractDeploymentData { // docs:start:private-context-inputs struct PrivateContextInputs { call_context : CallContext, - block_data: HistoricBlockData, + block_header: BlockHeader, contract_deployment_data: ContractDeploymentData, private_global_variables: PrivateGlobalVariables, } @@ -104,7 +104,7 @@ struct PrivateContextInputs { // docs:start:public-context-inputs struct PublicContextInputs { call_context: CallContext, - block_data: HistoricBlockData, + block_header: BlockHeader, public_global_variables: PublicGlobalVariables, } @@ -141,8 +141,8 @@ impl CallContext { } } -// docs:start:historic-block-data -struct HistoricBlockData { +// docs:start:block-header +struct BlockHeader { note_hash_tree_root : Field, nullifier_tree_root : Field, contract_tree_root : Field, @@ -151,11 +151,11 @@ struct HistoricBlockData { public_data_tree_root: Field, global_variables_hash: Field, } -// docs:end:historic-block-data +// docs:end:block-header -impl HistoricBlockData { +impl BlockHeader { // NOTE: this order must match the order in `private_circuit_public_inputs.hpp` - pub fn serialize(self) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] { + pub fn serialize(self) -> [Field; BLOCK_HEADER_LENGTH] { [ self.note_hash_tree_root, self.nullifier_tree_root, @@ -167,8 +167,8 @@ impl HistoricBlockData { ] } - pub fn deserialize(deserialized: [Field; HISTORIC_BLOCK_DATA_LENGTH]) -> Self { - HistoricBlockData { + pub fn deserialize(deserialized: [Field; BLOCK_HEADER_LENGTH]) -> Self { + BlockHeader { note_hash_tree_root: deserialized[0], nullifier_tree_root: deserialized[1], contract_tree_root: deserialized[2], @@ -184,7 +184,7 @@ impl HistoricBlockData { } pub fn block_hash(self) -> Field { - // TODO(#3442): Unify the ordering in `HistoricBlockData::serialize` function and the ordering + // TODO(#3442): Unify the ordering in `BlockHeader::serialize` function and the ordering // in the block hash preimage --> This requires changes in the circuits. let inputs = [ self.global_variables_hash, @@ -234,7 +234,7 @@ struct PrivateCircuitPublicInputs { unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], encrypted_log_preimages_length: Field, unencrypted_log_preimages_length: Field, - block_data: HistoricBlockData, + block_header: BlockHeader, contract_deployment_data: ContractDeploymentData, chain_id: Field, version: Field, @@ -258,7 +258,7 @@ impl PrivateCircuitPublicInputs { fields.push_array(self.unencrypted_logs_hash); fields.push(self.encrypted_log_preimages_length); fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.block_data.serialize()); + fields.push_array(self.block_header.serialize()); fields.push(self.contract_deployment_data.hash()); fields.push(self.chain_id); fields.push(self.version); @@ -282,7 +282,7 @@ impl PrivateCircuitPublicInputs { fields.push_array(self.unencrypted_logs_hash); fields.push(self.encrypted_log_preimages_length); fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.block_data.serialize()); + fields.push_array(self.block_header.serialize()); fields.push_array(self.contract_deployment_data.serialize()); fields.push(self.chain_id); fields.push(self.version); @@ -341,7 +341,7 @@ struct PublicCircuitPublicInputs { new_l2_to_l1_msgs: [Field; crate::abi::MAX_NEW_L2_TO_L1_MSGS_PER_CALL], unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], unencrypted_log_preimages_length: Field, - block_data: HistoricBlockData, + block_header: BlockHeader, prover_address: Field, } @@ -365,7 +365,7 @@ impl PublicCircuitPublicInputs { inputs.push_array(self.unencrypted_logs_hash); inputs.push(self.unencrypted_log_preimages_length); - inputs.push_array(self.block_data.serialize()); + inputs.push_array(self.block_header.serialize()); inputs.push(self.prover_address); pedersen_hash(inputs.storage, GENERATOR_INDEX__PUBLIC_CIRCUIT_PUBLIC_INPUTS) @@ -388,7 +388,7 @@ impl PublicCircuitPublicInputs { fields.push_array(self.new_l2_to_l1_msgs); fields.push_array(self.unencrypted_logs_hash); fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.block_data.serialize()); + fields.push_array(self.block_header.serialize()); fields.push(self.prover_address); fields.storage } diff --git a/yarn-project/aztec-nr/aztec/src/constants_gen.nr b/yarn-project/aztec-nr/aztec/src/constants_gen.nr index 368810a0a429..6ac5589e0f84 100644 --- a/yarn-project/aztec-nr/aztec/src/constants_gen.nr +++ b/yarn-project/aztec-nr/aztec/src/constants_gen.nr @@ -73,7 +73,7 @@ global CONTRACT_SUBTREE_SIBLING_PATH_LENGTH: Field = 15; global NOTE_HASH_SUBTREE_HEIGHT: Field = 7; global NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH: Field = 25; global NULLIFIER_SUBTREE_HEIGHT: Field = 7; -global HISTORIC_BLOCKS_TREE_HEIGHT: Field = 16; +global BLOCKS_TREE_HEIGHT: Field = 16; global NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH: Field = 13; global L1_TO_L2_MSG_SUBTREE_HEIGHT: Field = 4; global L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH: Field = 12; @@ -98,7 +98,7 @@ global MAX_NOTES_PER_PAGE: Field = 10; // VIEW_NOTE_ORACLE_RETURN_LENGTH = MAX_NOTES_PER_PAGE * (MAX_NOTE_FIELDS_LENGTH + 1) + 2; global VIEW_NOTE_ORACLE_RETURN_LENGTH: Field = 212; global CALL_CONTEXT_LENGTH: Field = 7; -global HISTORIC_BLOCK_DATA_LENGTH: Field = 7; +global BLOCK_HEADER_LENGTH: Field = 7; global FUNCTION_DATA_LENGTH: Field = 4; global CONTRACT_DEPLOYMENT_DATA_LENGTH: Field = 6; // Change this ONLY if you have changed the PrivateCircuitPublicInputs structure. diff --git a/yarn-project/aztec-nr/aztec/src/context.nr b/yarn-project/aztec-nr/aztec/src/context.nr index 3efe8bda4acc..720ce9981fbe 100644 --- a/yarn-project/aztec-nr/aztec/src/context.nr +++ b/yarn-project/aztec-nr/aztec/src/context.nr @@ -19,7 +19,7 @@ use crate::abi::{ hash_args, CallContext, ContractDeploymentData, - HistoricBlockData, + BlockHeader, FunctionData, PrivateCircuitPublicInputs, PublicCircuitPublicInputs, @@ -46,7 +46,7 @@ use crate::oracle::{ public_call::call_public_function_internal, enqueue_public_function_call::enqueue_public_function_call_internal, context::get_portal_address, - get_block_data::get_block_data, + get_block_header::get_block_header, }; use dep::std::option::Option; @@ -71,7 +71,7 @@ struct PrivateContext { new_l2_to_l1_msgs : BoundedVec, // docs:end:private-context - block_data: HistoricBlockData, + block_header: BlockHeader, // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) // encrypted_logs_preimages: Vec, @@ -93,7 +93,7 @@ impl PrivateContext { new_nullifiers: BoundedVec::new(0), nullified_commitments: BoundedVec::new(0), - block_data: inputs.block_data, + block_header: inputs.block_header, private_call_stack: BoundedVec::new(0), public_call_stack: BoundedVec::new(0), @@ -129,8 +129,8 @@ impl PrivateContext { self.inputs.call_context.function_selector } - pub fn get_block_data(self, block_number: Field) -> HistoricBlockData { - get_block_data(block_number, self) + pub fn get_block_header(self, block_number: Field) -> BlockHeader { + get_block_header(block_number, self) } pub fn finish(self) -> abi::PrivateCircuitPublicInputs { @@ -156,7 +156,7 @@ impl PrivateContext { unencrypted_logs_hash: unencrypted_logs_hash, encrypted_log_preimages_length: encrypted_log_preimages_length, unencrypted_log_preimages_length: unencrypted_log_preimages_length, - block_data: self.block_data, + block_header: self.block_header, contract_deployment_data: self.inputs.contract_deployment_data, chain_id: self.inputs.private_global_variables.chain_id, version: self.inputs.private_global_variables.version, @@ -207,7 +207,7 @@ impl PrivateContext { ) // docs:end:context_consume_l1_to_l2_message { - let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, self.this_address(), self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret); + let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_messages_tree_root, self.this_address(), self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret); // Push nullifier (and the "commitment" corresponding to this can be "empty") self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT) @@ -289,7 +289,7 @@ impl PrivateContext { unencrypted_logs_hash: arr_copy_slice(fields, [0; NUM_FIELDS_PER_SHA256], 141), encrypted_log_preimages_length: fields[143], unencrypted_log_preimages_length: fields[144], - block_data: HistoricBlockData { + block_header: BlockHeader { // Must match order in `private_circuit_public_inputs.hpp` note_hash_tree_root : fields[145], nullifier_tree_root : fields[146], @@ -391,7 +391,7 @@ impl PrivateContext { new_l2_to_l1_msgs:[0; MAX_NEW_L2_TO_L1_MSGS_PER_CALL], unencrypted_logs_hash:[0; NUM_FIELDS_PER_SHA256], unencrypted_log_preimages_length: 0, - block_data: HistoricBlockData::empty(), + block_header: BlockHeader::empty(), prover_address: 0, }, is_execution_request: true, @@ -439,7 +439,7 @@ struct PublicContext { unencrypted_logs_hash: BoundedVec, unencrypted_logs_preimages_length: Field, - block_data: HistoricBlockData, + block_header: BlockHeader, prover_address: Field, } @@ -466,7 +466,7 @@ impl PublicContext { unencrypted_logs_hash: BoundedVec::new(0), unencrypted_logs_preimages_length: 0, - block_data: inputs.block_data, + block_header: inputs.block_header, prover_address: 0, // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) @@ -526,7 +526,7 @@ impl PublicContext { new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, unencrypted_logs_hash: unencrypted_logs_hash, unencrypted_log_preimages_length: unencrypted_log_preimages_length, - block_data: self.inputs.block_data, + block_header: self.inputs.block_header, prover_address: self.prover_address, }; pub_circuit_pub_inputs @@ -548,7 +548,7 @@ impl PublicContext { // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned pub fn consume_l1_to_l2_message(&mut self, msg_key: Field, content: Field, secret: Field) { let this = (*self).this_address(); - let nullifier = process_l1_to_l2_message(self.block_data.l1_to_l2_messages_tree_root, this, self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret); + let nullifier = process_l1_to_l2_message(self.block_header.l1_to_l2_messages_tree_root, this, self.this_portal_address(), self.chain_id(), self.version(), msg_key, content, secret); // Push nullifier (and the "commitment" corresponding to this can be "empty") self.push_new_nullifier(nullifier, EMPTY_NULLIFIED_COMMITMENT) diff --git a/yarn-project/aztec-nr/aztec/src/oracle.nr b/yarn-project/aztec-nr/aztec/src/oracle.nr index 4bed8383bfaf..6a7aac259db1 100644 --- a/yarn-project/aztec-nr/aztec/src/oracle.nr +++ b/yarn-project/aztec-nr/aztec/src/oracle.nr @@ -14,7 +14,7 @@ mod get_secret_key; mod get_sibling_path; mod rand; mod enqueue_public_function_call; -mod get_block_data; +mod get_block_header; mod public_call; mod notes; mod storage; diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_block_data.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_block_data.nr deleted file mode 100644 index 2b645a62dd92..000000000000 --- a/yarn-project/aztec-nr/aztec/src/oracle/get_block_data.nr +++ /dev/null @@ -1,39 +0,0 @@ -use dep::std::merkle::compute_merkle_root; -use crate::{ - abi::HistoricBlockData, - constants_gen::{ - HISTORIC_BLOCK_DATA_LENGTH, - HISTORIC_BLOCKS_TREE_HEIGHT, - }, - context::PrivateContext, - oracle::get_membership_witness::{ - get_membership_witness, - MembershipWitness, - }, -}; - -#[oracle(getBlockData)] -fn get_block_data_oracle(_block_number: Field) -> [Field; HISTORIC_BLOCK_DATA_LENGTH] {} - -unconstrained pub fn get_block_data_internal(block_number: Field) -> HistoricBlockData { - let block_data = get_block_data_oracle(block_number); - HistoricBlockData::deserialize(block_data) -} - -pub fn get_block_data(block_number: Field, context: PrivateContext) -> HistoricBlockData { - // 1) Get historic block data from oracle at the given block - let block_data = get_block_data_internal(block_number); - - // 2) Compute the block hash from the block data - let block_hash = block_data.block_hash(); - - // 3) Get the membership wintess of the block in the blocks tree - let blocks_tree_id = 5; // TODO(#3443) - let witness: MembershipWitness = get_membership_witness(block_number, blocks_tree_id, block_hash); - - // 4) Check that the block is in the blocks tree (i.e. the witness is valid) - assert(context.block_data.blocks_tree_root == compute_merkle_root(block_hash, witness.index, witness.path), "Proving membership of a block in blocks tree failed"); - - // 5) Return the block data - block_data -} diff --git a/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr new file mode 100644 index 000000000000..5f4532219525 --- /dev/null +++ b/yarn-project/aztec-nr/aztec/src/oracle/get_block_header.nr @@ -0,0 +1,39 @@ +use dep::std::merkle::compute_merkle_root; +use crate::{ + abi::BlockHeader, + constants_gen::{ + BLOCK_HEADER_LENGTH, + BLOCKS_TREE_HEIGHT, + }, + context::PrivateContext, + oracle::get_membership_witness::{ + get_membership_witness, + MembershipWitness, + }, +}; + +#[oracle(getBlockHeader)] +fn get_block_header_oracle(_block_number: Field) -> [Field; BLOCK_HEADER_LENGTH] {} + +unconstrained pub fn get_block_header_internal(block_number: Field) -> BlockHeader { + let block_header = get_block_header_oracle(block_number); + BlockHeader::deserialize(block_header) +} + +pub fn get_block_header(block_number: Field, context: PrivateContext) -> BlockHeader { + // 1) Get block header of a given block from oracle + let block_header = get_block_header_internal(block_number); + + // 2) Compute the block hash from the block header + let block_hash = block_header.block_hash(); + + // 3) Get the membership wintess of the block in the blocks tree + let blocks_tree_id = 5; // TODO(#3443) + let witness: MembershipWitness = get_membership_witness(block_number, blocks_tree_id, block_hash); + + // 4) Check that the block is in the blocks tree (i.e. the witness is valid) + assert(context.block_header.blocks_tree_root == compute_merkle_root(block_hash, witness.index, witness.path), "Proving membership of a block in blocks tree failed"); + + // 5) Return the block header + block_header +} diff --git a/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json b/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json index 0c4d56e844c2..491da2af12cb 100644 --- a/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/ecdsa_account_contract.json @@ -365,10 +365,10 @@ } }, { - "name": "block_data", + "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::HistoricBlockData", + "path": "aztec::abi::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -632,10 +632,10 @@ } }, { - "name": "block_data", + "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::HistoricBlockData", + "path": "aztec::abi::BlockHeader", "fields": [ { "name": "note_hash_tree_root", diff --git a/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json b/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json index 8163729ec65f..f05dd9664f7c 100644 --- a/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/schnorr_account_contract.json @@ -353,10 +353,10 @@ } }, { - "name": "block_data", + "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::HistoricBlockData", + "path": "aztec::abi::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -620,10 +620,10 @@ } }, { - "name": "block_data", + "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::HistoricBlockData", + "path": "aztec::abi::BlockHeader", "fields": [ { "name": "note_hash_tree_root", diff --git a/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json b/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json index cc776fe5d4ea..fb155f98ec1e 100644 --- a/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json +++ b/yarn-project/aztec.js/src/artifacts/schnorr_single_key_account_contract.json @@ -288,10 +288,10 @@ } }, { - "name": "block_data", + "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::HistoricBlockData", + "path": "aztec::abi::BlockHeader", "fields": [ { "name": "note_hash_tree_root", @@ -555,10 +555,10 @@ } }, { - "name": "block_data", + "name": "block_header", "type": { "kind": "struct", - "path": "aztec::abi::HistoricBlockData", + "path": "aztec::abi::BlockHeader", "fields": [ { "name": "note_hash_tree_root", diff --git a/yarn-project/circuits.js/src/abis/abis.ts b/yarn-project/circuits.js/src/abis/abis.ts index dd249bbb5d6f..ecee67a7528d 100644 --- a/yarn-project/circuits.js/src/abis/abis.ts +++ b/yarn-project/circuits.js/src/abis/abis.ts @@ -531,13 +531,13 @@ function computePrivateInputsHash(input: PrivateCircuitPublicInputs) { ...input.unencryptedLogsHash.map(fr => fr.toBuffer()), input.encryptedLogPreimagesLength.toBuffer(), input.unencryptedLogPreimagesLength.toBuffer(), - input.historicBlockData.noteHashTreeRoot.toBuffer(), - input.historicBlockData.nullifierTreeRoot.toBuffer(), - input.historicBlockData.contractTreeRoot.toBuffer(), - input.historicBlockData.l1ToL2MessagesTreeRoot.toBuffer(), - input.historicBlockData.blocksTreeRoot.toBuffer(), - input.historicBlockData.publicDataTreeRoot.toBuffer(), - input.historicBlockData.globalVariablesHash.toBuffer(), + input.blockHeader.noteHashTreeRoot.toBuffer(), + input.blockHeader.nullifierTreeRoot.toBuffer(), + input.blockHeader.contractTreeRoot.toBuffer(), + input.blockHeader.l1ToL2MessagesTreeRoot.toBuffer(), + input.blockHeader.blocksTreeRoot.toBuffer(), + input.blockHeader.publicDataTreeRoot.toBuffer(), + input.blockHeader.globalVariablesHash.toBuffer(), computeContractDeploymentDataHash(input.contractDeploymentData).toBuffer(), input.chainId.toBuffer(), input.version.toBuffer(), @@ -599,13 +599,13 @@ function computePublicInputsHash(input: PublicCircuitPublicInputs) { ...input.newL2ToL1Msgs.map(fr => fr.toBuffer()), ...input.unencryptedLogsHash.map(fr => fr.toBuffer()), input.unencryptedLogPreimagesLength.toBuffer(), - input.historicBlockData.noteHashTreeRoot.toBuffer(), - input.historicBlockData.nullifierTreeRoot.toBuffer(), - input.historicBlockData.contractTreeRoot.toBuffer(), - input.historicBlockData.l1ToL2MessagesTreeRoot.toBuffer(), - input.historicBlockData.blocksTreeRoot.toBuffer(), - input.historicBlockData.publicDataTreeRoot.toBuffer(), - input.historicBlockData.globalVariablesHash.toBuffer(), + input.blockHeader.noteHashTreeRoot.toBuffer(), + input.blockHeader.nullifierTreeRoot.toBuffer(), + input.blockHeader.contractTreeRoot.toBuffer(), + input.blockHeader.l1ToL2MessagesTreeRoot.toBuffer(), + input.blockHeader.blocksTreeRoot.toBuffer(), + input.blockHeader.publicDataTreeRoot.toBuffer(), + input.blockHeader.globalVariablesHash.toBuffer(), input.proverAddress.toBuffer(), ]; if (toHash.length != PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH) { diff --git a/yarn-project/circuits.js/src/constants.gen.ts b/yarn-project/circuits.js/src/constants.gen.ts index 3cbbab211214..e5fc7359815d 100644 --- a/yarn-project/circuits.js/src/constants.gen.ts +++ b/yarn-project/circuits.js/src/constants.gen.ts @@ -42,7 +42,7 @@ export const CONTRACT_SUBTREE_SIBLING_PATH_LENGTH = 15; export const NOTE_HASH_SUBTREE_HEIGHT = 7; export const NOTE_HASH_SUBTREE_SIBLING_PATH_LENGTH = 25; export const NULLIFIER_SUBTREE_HEIGHT = 7; -export const HISTORIC_BLOCKS_TREE_HEIGHT = 16; +export const BLOCKS_TREE_HEIGHT = 16; export const NULLIFIER_SUBTREE_SIBLING_PATH_LENGTH = 13; export const L1_TO_L2_MSG_SUBTREE_HEIGHT = 4; export const L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH = 12; @@ -56,7 +56,7 @@ export const GET_NOTE_ORACLE_RETURN_LENGTH = 23; export const MAX_NOTES_PER_PAGE = 10; export const VIEW_NOTE_ORACLE_RETURN_LENGTH = 212; export const CALL_CONTEXT_LENGTH = 7; -export const HISTORIC_BLOCK_DATA_LENGTH = 7; +export const BLOCK_HEADER_LENGTH = 7; export const FUNCTION_DATA_LENGTH = 4; export const CONTRACT_DEPLOYMENT_DATA_LENGTH = 6; export const PRIVATE_CIRCUIT_PUBLIC_INPUTS_LENGTH = 155; diff --git a/yarn-project/circuits.js/src/structs/index.ts b/yarn-project/circuits.js/src/structs/index.ts index c8ed1585aeae..7ce2c3d0cede 100644 --- a/yarn-project/circuits.js/src/structs/index.ts +++ b/yarn-project/circuits.js/src/structs/index.ts @@ -11,7 +11,7 @@ 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/historic_block_data.js'; +export * from './kernel/block_header.js'; export * from './kernel/previous_kernel_data.js'; export * from './kernel/public_inputs.js'; export * from './kernel/public_inputs_final.js'; diff --git a/yarn-project/circuits.js/src/structs/kernel/block_header.test.ts b/yarn-project/circuits.js/src/structs/kernel/block_header.test.ts new file mode 100644 index 000000000000..3bb78282c2a5 --- /dev/null +++ b/yarn-project/circuits.js/src/structs/kernel/block_header.test.ts @@ -0,0 +1,17 @@ +import { BlockHeader } from './block_header.js'; + +describe('BlockHeader', () => { + it('serializes to buffer and back', () => { + const blockHeader = BlockHeader.random(); + const serialized = blockHeader.toBuffer(); + const deserialized = BlockHeader.fromBuffer(serialized); + expect(deserialized).toEqual(blockHeader); + }); + + it('serializes to string and back', () => { + const blockHeader = BlockHeader.random(); + const serialized = blockHeader.toString(); + const deserialized = BlockHeader.fromString(serialized); + expect(deserialized).toEqual(blockHeader); + }); +}); diff --git a/yarn-project/circuits.js/src/structs/kernel/historic_block_data.ts b/yarn-project/circuits.js/src/structs/kernel/block_header.ts similarity index 80% rename from yarn-project/circuits.js/src/structs/kernel/historic_block_data.ts rename to yarn-project/circuits.js/src/structs/kernel/block_header.ts index eda21d334f1a..1c83f50351c0 100644 --- a/yarn-project/circuits.js/src/structs/kernel/historic_block_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/block_header.ts @@ -5,14 +5,14 @@ import { FieldsOf } from '../../utils/jsUtils.js'; import { serializeToBuffer } from '../../utils/serialize.js'; /** - * The string encoding used for serializing HistoricBlockData objects. + * The string encoding used for serializing BlockHeader objects. */ const STRING_ENCODING: BufferEncoding = 'hex'; /** * Information about the tree roots used for both public and private kernels. */ -export class HistoricBlockData { +export class BlockHeader { constructor( /** * Root of the note hash tree at the time of when this information was assembled. @@ -31,7 +31,7 @@ export class HistoricBlockData { */ public l1ToL2MessagesTreeRoot: Fr, /** - * Root of the historic blocks tree at the time of when this information was assembled. + * Root of the blocks tree at the time of when this information was assembled. */ public blocksTreeRoot: Fr, /** @@ -48,12 +48,12 @@ export class HistoricBlockData { public globalVariablesHash: Fr, ) {} - static from(fields: FieldsOf) { - return new HistoricBlockData(...HistoricBlockData.getFields(fields)); + static from(fields: FieldsOf) { + return new BlockHeader(...BlockHeader.getFields(fields)); } static random() { - return new HistoricBlockData( + return new BlockHeader( Fr.random(), Fr.random(), Fr.random(), @@ -65,7 +65,7 @@ export class HistoricBlockData { ); } - static getFields(fields: FieldsOf) { + static getFields(fields: FieldsOf) { return [ fields.noteHashTreeRoot, fields.nullifierTreeRoot, @@ -79,7 +79,7 @@ export class HistoricBlockData { } toBuffer() { - return serializeToBuffer(...HistoricBlockData.getFields(this)); + return serializeToBuffer(...BlockHeader.getFields(this)); } toString() { @@ -88,7 +88,7 @@ export class HistoricBlockData { } /** - * Return the historic block data as an array of items in the order they are serialized in noir. + * Return the block header as an array of items in the order they are serialized in noir. * @returns Array of items in the order they are stored in the contract */ toArray(): Fr[] { @@ -106,7 +106,7 @@ export class HistoricBlockData { static fromBuffer(buffer: Buffer | BufferReader) { const reader = BufferReader.asReader(buffer); - return new HistoricBlockData( + return new BlockHeader( Fr.fromBuffer(reader), Fr.fromBuffer(reader), Fr.fromBuffer(reader), @@ -119,7 +119,7 @@ export class HistoricBlockData { } static fromString(str: string) { - return HistoricBlockData.fromBuffer(Buffer.from(str, STRING_ENCODING)); + return BlockHeader.fromBuffer(Buffer.from(str, STRING_ENCODING)); } isEmpty() { @@ -136,6 +136,6 @@ export class HistoricBlockData { } static empty() { - return new HistoricBlockData(Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO); + return new BlockHeader(Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO, Fr.ZERO); } } 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 index 34f10df67619..2410d624191c 100644 --- a/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts +++ b/yarn-project/circuits.js/src/structs/kernel/combined_constant_data.ts @@ -2,7 +2,7 @@ import { BufferReader } from '@aztec/foundation/serialize'; import { serializeToBuffer } from '../../utils/serialize.js'; import { TxContext } from '../tx_context.js'; -import { HistoricBlockData } from './historic_block_data.js'; +import { BlockHeader } from './block_header.js'; /** * Data that is constant/not modified by neither of the kernels. @@ -12,7 +12,7 @@ export class CombinedConstantData { /** * Roots of the trees relevant for both kernel circuits. */ - public blockData: HistoricBlockData, + public blockHeader: BlockHeader, /** * Context of the transaction. */ @@ -20,7 +20,7 @@ export class CombinedConstantData { ) {} toBuffer() { - return serializeToBuffer(this.blockData, this.txContext); + return serializeToBuffer(this.blockHeader, this.txContext); } /** @@ -30,10 +30,10 @@ export class CombinedConstantData { */ static fromBuffer(buffer: Buffer | BufferReader): CombinedConstantData { const reader = BufferReader.asReader(buffer); - return new CombinedConstantData(reader.readObject(HistoricBlockData), reader.readObject(TxContext)); + return new CombinedConstantData(reader.readObject(BlockHeader), reader.readObject(TxContext)); } static empty() { - return new CombinedConstantData(HistoricBlockData.empty(), TxContext.empty()); + return new CombinedConstantData(BlockHeader.empty(), TxContext.empty()); } } diff --git a/yarn-project/circuits.js/src/structs/kernel/historic_block_data.test.ts b/yarn-project/circuits.js/src/structs/kernel/historic_block_data.test.ts deleted file mode 100644 index 9179c979ca40..000000000000 --- a/yarn-project/circuits.js/src/structs/kernel/historic_block_data.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { HistoricBlockData } from './historic_block_data.js'; - -describe('HistoricBlockData', () => { - it('serializes to buffer and back', () => { - const historicBlockData = HistoricBlockData.random(); - const serialized = historicBlockData.toBuffer(); - const deserialized = HistoricBlockData.fromBuffer(serialized); - expect(deserialized).toEqual(historicBlockData); - }); - - it('serializes to string and back', () => { - const historicBlockData = HistoricBlockData.random(); - const serialized = historicBlockData.toString(); - const deserialized = HistoricBlockData.fromString(serialized); - expect(deserialized).toEqual(historicBlockData); - }); -}); 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 11dd3c26d392..1b3fe3222fc9 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 @@ -16,7 +16,7 @@ import { import { FieldsOf, makeTuple } from '../utils/jsUtils.js'; import { serializeToBuffer } from '../utils/serialize.js'; import { CallContext } from './call_context.js'; -import { HistoricBlockData } from './index.js'; +import { BlockHeader } from './index.js'; import { ContractDeploymentData } from './tx_context.js'; /** @@ -90,9 +90,9 @@ export class PrivateCircuitPublicInputs { */ public unencryptedLogPreimagesLength: Fr, /** - * Historic roots of the data trees, used to calculate the block hash the user is proving against. + * Historical roots of the data trees, used to calculate the block hash the user is proving against. */ - public historicBlockData: HistoricBlockData, + public blockHeader: BlockHeader, /** * Deployment data of contracts being deployed in this kernel iteration. */ @@ -136,7 +136,7 @@ export class PrivateCircuitPublicInputs { makeTuple(NUM_FIELDS_PER_SHA256, Fr.zero), Fr.ZERO, Fr.ZERO, - HistoricBlockData.empty(), + BlockHeader.empty(), ContractDeploymentData.empty(), Fr.ZERO, Fr.ZERO, @@ -161,7 +161,7 @@ export class PrivateCircuitPublicInputs { isFrArrayEmpty(this.unencryptedLogsHash) && this.encryptedLogPreimagesLength.isZero() && this.unencryptedLogPreimagesLength.isZero() && - this.historicBlockData.isEmpty() && + this.blockHeader.isEmpty() && this.contractDeploymentData.isEmpty() && this.chainId.isZero() && this.version.isZero() @@ -190,7 +190,7 @@ export class PrivateCircuitPublicInputs { fields.unencryptedLogsHash, fields.encryptedLogPreimagesLength, fields.unencryptedLogPreimagesLength, - fields.historicBlockData, + fields.blockHeader, fields.contractDeploymentData, fields.chainId, fields.version, 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 aafd9b454bb1..bb160941456c 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 @@ -15,7 +15,7 @@ import { import { FieldsOf, makeTuple } from '../utils/jsUtils.js'; import { serializeToBuffer } from '../utils/serialize.js'; import { CallContext } from './call_context.js'; -import { HistoricBlockData } from './index.js'; +import { BlockHeader } from './index.js'; /** * Contract storage read operation on a specific contract. @@ -200,7 +200,7 @@ export class PublicCircuitPublicInputs { /** * Root of the commitment trees when the call started. */ - public historicBlockData: HistoricBlockData, + public blockHeader: BlockHeader, /** * Address of the prover. */ @@ -233,7 +233,7 @@ export class PublicCircuitPublicInputs { makeTuple(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, Fr.zero), makeTuple(2, Fr.zero), Fr.ZERO, - HistoricBlockData.empty(), + BlockHeader.empty(), AztecAddress.ZERO, ); } @@ -252,7 +252,7 @@ export class PublicCircuitPublicInputs { isFrArrayEmpty(this.newL2ToL1Msgs) && isFrArrayEmpty(this.unencryptedLogsHash) && this.unencryptedLogPreimagesLength.isZero() && - this.historicBlockData.isEmpty() && + this.blockHeader.isEmpty() && this.proverAddress.isZero() ); } @@ -275,7 +275,7 @@ export class PublicCircuitPublicInputs { fields.newL2ToL1Msgs, fields.unencryptedLogsHash, fields.unencryptedLogPreimagesLength, - fields.historicBlockData, + fields.blockHeader, fields.proverAddress, ] as const; } diff --git a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts index 454532ec6467..1d6babb0ebee 100644 --- a/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/base_rollup.ts @@ -2,8 +2,8 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple } from '@aztec/foundation/serialize'; import { + BLOCKS_TREE_HEIGHT, CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, - HISTORIC_BLOCKS_TREE_HEIGHT, KERNELS_PER_BASE_ROLLUP, MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP, @@ -56,9 +56,9 @@ export class NullifierLeafPreimage { export class ConstantRollupData { constructor( /** - * Snapshot of the historic blocks roots tree at the start of the rollup. + * Snapshot of the blocks tree at the start of the rollup. */ - public startHistoricBlocksTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public startBlocksTreeSnapshot: AppendOnlyTreeSnapshot, /** * Root of the private kernel verification key tree. @@ -100,7 +100,7 @@ export class ConstantRollupData { static getFields(fields: FieldsOf) { return [ - fields.startHistoricBlocksTreeRootsSnapshot, + fields.startBlocksTreeSnapshot, fields.privateKernelVkTreeRoot, fields.publicKernelVkTreeRoot, fields.baseRollupVkHash, @@ -140,9 +140,9 @@ export class BaseRollupInputs { */ public startPublicDataTreeRoot: Fr, /** - * Snapshot of the historic blocks tree at the start of the base rollup circuit. + * Snapshot of the blocks tree at the start of the base rollup circuit. */ - public startHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot, + public startBlocksTreeSnapshot: AppendOnlyTreeSnapshot, /** * The nullifiers to be inserted in the tree, sorted high to low. @@ -194,10 +194,10 @@ export class BaseRollupInputs { typeof MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP >, /** - * Membership witnesses of historic blocks referred by each of the 2 kernels. + * Membership witnesses of blocks referred by each of the 2 kernels. */ - public historicBlocksTreeRootMembershipWitnesses: Tuple< - MembershipWitness, + public blocksTreeRootMembershipWitnesses: Tuple< + MembershipWitness, typeof KERNELS_PER_BASE_ROLLUP >, /** @@ -217,7 +217,7 @@ export class BaseRollupInputs { fields.startNullifierTreeSnapshot, fields.startContractTreeSnapshot, fields.startPublicDataTreeRoot, - fields.startHistoricBlocksTreeSnapshot, + fields.startBlocksTreeSnapshot, fields.sortedNewNullifiers, fields.sortednewNullifiersIndexes, fields.lowNullifierLeafPreimages, @@ -227,7 +227,7 @@ export class BaseRollupInputs { fields.newContractsSubtreeSiblingPath, fields.newPublicDataUpdateRequestsSiblingPaths, fields.newPublicDataReadsSiblingPaths, - fields.historicBlocksTreeRootMembershipWitnesses, + fields.blocksTreeRootMembershipWitnesses, fields.constants, ] as const; } diff --git a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts index 5688f5e5f5c0..087accf15261 100644 --- a/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts +++ b/yarn-project/circuits.js/src/structs/rollup/root_rollup.ts @@ -2,7 +2,7 @@ import { Fr } from '@aztec/foundation/fields'; import { BufferReader, Tuple } from '@aztec/foundation/serialize'; import { - HISTORIC_BLOCKS_TREE_HEIGHT, + BLOCKS_TREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, } from '../../constants.gen.js'; @@ -37,13 +37,13 @@ export class RootRollupInputs { */ public startL1ToL2MessagesTreeSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic block roots tree at the start of the rollup. + * Snapshot of the historical block roots tree at the start of the rollup. */ - public startHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot, + public startBlocksTreeSnapshot: AppendOnlyTreeSnapshot, /** - * Sibling path of the new historic block roots tree root. + * Sibling path of the new block tree root. */ - public newHistoricBlocksTreeSiblingPath: Tuple, + public newBlocksTreeSiblingPath: Tuple, ) {} toBuffer() { @@ -60,8 +60,8 @@ export class RootRollupInputs { fields.newL1ToL2Messages, fields.newL1ToL2MessagesTreeRootSiblingPath, fields.startL1ToL2MessagesTreeSnapshot, - fields.startHistoricBlocksTreeSnapshot, - fields.newHistoricBlocksTreeSiblingPath, + fields.startBlocksTreeSnapshot, + fields.newBlocksTreeSiblingPath, ] as const; } } @@ -120,22 +120,22 @@ export class RootRollupPublicInputs { public endPublicDataTreeRoot: Fr, /** - * Snapshot of the historic note hash tree roots tree at the start of the rollup. + * Snapshot of the historical note hash tree roots tree at the start of the rollup. */ - public startTreeOfHistoricNoteHashTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public startTreeOfHistoricalNoteHashTreeRootsSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic note hash tree roots tree at the end of the rollup. + * Snapshot of the historical note hash tree roots tree at the end of the rollup. */ - public endTreeOfHistoricNoteHashTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public endTreeOfHistoricalNoteHashTreeRootsSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic contract tree roots tree at the start of the rollup. + * Snapshot of the historical contract tree roots tree at the start of the rollup. */ - public startTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public startTreeOfHistoricalContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic contract tree roots tree at the end of the rollup. + * Snapshot of the historical contract tree roots tree at the end of the rollup. */ - public endTreeOfHistoricContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public endTreeOfHistoricalContractTreeRootsSnapshot: AppendOnlyTreeSnapshot, /** * Snapshot of the L1 to L2 message tree at the start of the rollup. @@ -147,22 +147,22 @@ export class RootRollupPublicInputs { public endL1ToL2MessagesTreeSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic L1 to L2 message tree roots tree at the start of the rollup. + * Snapshot of the historical L1 to L2 message tree roots tree at the start of the rollup. */ - public startTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public startTreeOfHistoricalL1ToL2MessagesTreeRootsSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic L1 to L2 message tree roots tree at the end of the rollup. + * Snapshot of the historical L1 to L2 message tree roots tree at the end of the rollup. */ - public endTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot: AppendOnlyTreeSnapshot, + public endTreeOfHistoricalL1ToL2MessagesTreeRootsSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic blocks tree roots tree at the start of the rollup. + * Snapshot of the blocks tree roots tree at the start of the rollup. */ - public startHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot, + public startBlocksTreeSnapshot: AppendOnlyTreeSnapshot, /** - * Snapshot of the historic blocks tree roots tree at the end of the rollup. + * Snapshot of the blocks tree roots tree at the end of the rollup. */ - public endHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot, + public endBlocksTreeSnapshot: AppendOnlyTreeSnapshot, /** * Hash of the calldata. @@ -186,16 +186,16 @@ export class RootRollupPublicInputs { fields.endContractTreeSnapshot, fields.startPublicDataTreeRoot, fields.endPublicDataTreeRoot, - fields.startTreeOfHistoricNoteHashTreeRootsSnapshot, - fields.endTreeOfHistoricNoteHashTreeRootsSnapshot, - fields.startTreeOfHistoricContractTreeRootsSnapshot, - fields.endTreeOfHistoricContractTreeRootsSnapshot, + fields.startTreeOfHistoricalNoteHashTreeRootsSnapshot, + fields.endTreeOfHistoricalNoteHashTreeRootsSnapshot, + fields.startTreeOfHistoricalContractTreeRootsSnapshot, + fields.endTreeOfHistoricalContractTreeRootsSnapshot, fields.startL1ToL2MessagesTreeSnapshot, fields.endL1ToL2MessagesTreeSnapshot, - fields.startTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot, - fields.endTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot, - fields.startHistoricBlocksTreeSnapshot, - fields.endHistoricBlocksTreeSnapshot, + fields.startTreeOfHistoricalL1ToL2MessagesTreeRootsSnapshot, + fields.endTreeOfHistoricalL1ToL2MessagesTreeRootsSnapshot, + fields.startBlocksTreeSnapshot, + fields.endBlocksTreeSnapshot, fields.calldataHash, fields.l1ToL2MessagesHash, ] as const; diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 6c03169795a8..2c08c8572437 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -7,8 +7,10 @@ import { ARGS_LENGTH, AggregationObject, AppendOnlyTreeSnapshot, + BLOCKS_TREE_HEIGHT, BaseOrMergeRollupPublicInputs, BaseRollupInputs, + BlockHeader, CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, CONTRACT_TREE_HEIGHT, CallContext, @@ -28,8 +30,6 @@ import { FunctionData, FunctionSelector, G1AffineElement, - HISTORIC_BLOCKS_TREE_HEIGHT, - HistoricBlockData, KERNELS_PER_BASE_ROLLUP, KernelCircuitPublicInputs, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, @@ -114,13 +114,13 @@ export function makeTxContext(seed: number): TxContext { } /** - * Creates an arbitrary combined historic tree roots object from the given seed. + * Creates an arbitrary combined historical tree roots object from the given seed. * Note: "Combined" indicates that it's the combined output of both private and public circuit flows. - * @param seed - The seed to use for generating the combined historic tree roots. - * @returns A combined historic tree roots object. + * @param seed - The seed to use for generating the combined historical tree roots. + * @returns A combined historical tree roots object. */ -export function makeHistoricBlockData(seed: number): HistoricBlockData { - return new HistoricBlockData( +export function makeBlockHeader(seed: number): BlockHeader { + return new BlockHeader( fr(seed), fr(seed + 1), fr(seed + 2), @@ -138,7 +138,7 @@ export function makeHistoricBlockData(seed: number): HistoricBlockData { * @returns A constant data object. */ export function makeConstantData(seed = 1): CombinedConstantData { - return new CombinedConstantData(makeHistoricBlockData(seed), makeTxContext(seed + 4)); + return new CombinedConstantData(makeBlockHeader(seed), makeTxContext(seed + 4)); } /** @@ -340,7 +340,7 @@ export function makePublicCircuitPublicInputs( tupleGenerator(MAX_NEW_L2_TO_L1_MSGS_PER_CALL, fr, seed + 0x900), tupleGenerator(2, fr, seed + 0x901), fr(seed + 0x902), - makeHistoricBlockData(seed + 0xa00), + makeBlockHeader(seed + 0xa00), makeAztecAddress(seed + 0xb01), ); } @@ -679,7 +679,7 @@ export function makePrivateCircuitPublicInputs(seed = 0): PrivateCircuitPublicIn unencryptedLogsHash: makeTuple(NUM_FIELDS_PER_SHA256, fr, seed + 0xa00), encryptedLogPreimagesLength: fr(seed + 0xb00), unencryptedLogPreimagesLength: fr(seed + 0xc00), - historicBlockData: makeHistoricBlockData(seed + 0xd00), + blockHeader: makeBlockHeader(seed + 0xd00), contractDeploymentData: makeContractDeploymentData(seed + 0xe00), chainId: fr(seed + 0x1400), version: fr(seed + 0x1500), @@ -726,7 +726,7 @@ export function makeConstantBaseRollupData( globalVariables: GlobalVariables | undefined = undefined, ): ConstantRollupData { return ConstantRollupData.from({ - startHistoricBlocksTreeRootsSnapshot: makeAppendOnlyTreeSnapshot(seed + 0x300), + startBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot(seed + 0x300), privateKernelVkTreeRoot: fr(seed + 0x401), publicKernelVkTreeRoot: fr(seed + 0x402), baseRollupVkHash: fr(seed + 0x403), @@ -840,7 +840,7 @@ export function makeRootRollupInputs(seed = 0, globalVariables?: GlobalVariables makeTuple(L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, fr, 0x2100), makeAppendOnlyTreeSnapshot(seed + 0x2200), makeAppendOnlyTreeSnapshot(seed + 0x2200), - makeTuple(HISTORIC_BLOCKS_TREE_HEIGHT, fr, 0x2400), + makeTuple(BLOCKS_TREE_HEIGHT, fr, 0x2400), ); } @@ -866,16 +866,16 @@ export function makeRootRollupPublicInputs( endContractTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), startPublicDataTreeRoot: fr((seed += 0x100)), endPublicDataTreeRoot: fr((seed += 0x100)), - startTreeOfHistoricNoteHashTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), - endTreeOfHistoricNoteHashTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), - startTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), - endTreeOfHistoricContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + startTreeOfHistoricalNoteHashTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + endTreeOfHistoricalNoteHashTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + startTreeOfHistoricalContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + endTreeOfHistoricalContractTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), startL1ToL2MessagesTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), endL1ToL2MessagesTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), - startTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), - endTreeOfHistoricL1ToL2MessagesTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), - startHistoricBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), - endHistoricBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + startTreeOfHistoricalL1ToL2MessagesTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + endTreeOfHistoricalL1ToL2MessagesTreeRootsSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + startBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), + endBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot((seed += 0x100)), calldataHash: [new Fr(1n), new Fr(2n)], l1ToL2MessagesHash: [new Fr(3n), new Fr(4n)], }); @@ -902,7 +902,7 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { const startNullifierTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x200); const startContractTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x300); const startPublicDataTreeRoot = fr(seed + 0x400); - const startHistoricBlocksTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x500); + const startBlocksTreeSnapshot = makeAppendOnlyTreeSnapshot(seed + 0x500); const lowNullifierLeafPreimages = makeTuple( MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, @@ -935,8 +935,8 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { seed + 0x8000, ); - const historicBlocksTreeRootMembershipWitnesses = makeTuple(KERNELS_PER_BASE_ROLLUP, x => - makeMembershipWitness(HISTORIC_BLOCKS_TREE_HEIGHT, seed + x * 0x1000 + 0x9000), + const blocksTreeRootMembershipWitnesses = makeTuple(KERNELS_PER_BASE_ROLLUP, x => + makeMembershipWitness(BLOCKS_TREE_HEIGHT, seed + x * 0x1000 + 0x9000), ); const constants = makeConstantBaseRollupData(0x100); @@ -948,7 +948,7 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { startNullifierTreeSnapshot, startContractTreeSnapshot, startPublicDataTreeRoot, - startHistoricBlocksTreeSnapshot, + startBlocksTreeSnapshot, sortedNewNullifiers, sortednewNullifiersIndexes, lowNullifierLeafPreimages, @@ -957,7 +957,7 @@ export function makeBaseRollupInputs(seed = 0): BaseRollupInputs { newContractsSubtreeSiblingPath, newPublicDataUpdateRequestsSiblingPaths, newPublicDataReadsSiblingPaths, - historicBlocksTreeRootMembershipWitnesses, + blocksTreeRootMembershipWitnesses, constants, }); } diff --git a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts index 533bf66783a9..6d7805dd4d2c 100644 --- a/yarn-project/end-to-end/src/integration_l1_publisher.test.ts +++ b/yarn-project/end-to-end/src/integration_l1_publisher.test.ts @@ -28,10 +28,10 @@ import { L1Publisher, RealRollupCircuitSimulator, SoloBlockBuilder, - getHistoricBlockData, + getBlockHeader, getL1Publisher, getVerificationKeys, - makeEmptyProcessedTx as makeEmptyProcessedTxFromHistoricTreeRoots, + makeEmptyProcessedTx as makeEmptyProcessedTxFromHistoricalTreeRoots, makeProcessedTx, } from '@aztec/sequencer-client'; import { MerkleTreeOperations, MerkleTrees } from '@aztec/world-state'; @@ -152,12 +152,8 @@ describe('L1Publisher integration', () => { }, 100_000); const makeEmptyProcessedTx = async () => { - const historicTreeRoots = await getHistoricBlockData(builderDb, prevGlobals); - const tx = await makeEmptyProcessedTxFromHistoricTreeRoots( - historicTreeRoots, - new Fr(chainId), - new Fr(config.version), - ); + const blockHeader = await getBlockHeader(builderDb, prevGlobals); + const tx = await makeEmptyProcessedTxFromHistoricalTreeRoots(blockHeader, new Fr(chainId), new Fr(config.version)); return tx; }; @@ -166,7 +162,7 @@ describe('L1Publisher integration', () => { const kernelOutput = KernelCircuitPublicInputs.empty(); kernelOutput.constants.txContext.chainId = fr(chainId); kernelOutput.constants.txContext.version = fr(config.version); - kernelOutput.constants.blockData = await getHistoricBlockData(builderDb, prevGlobals); + kernelOutput.constants.blockHeader = await getBlockHeader(builderDb, prevGlobals); kernelOutput.end.publicDataUpdateRequests = makeTuple( MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => new PublicDataUpdateRequest(fr(i), fr(0), fr(i + 10)), diff --git a/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr b/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr index 7a8871b72185..462f95091be3 100644 --- a/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr +++ b/yarn-project/noir-contracts/src/contracts/inclusion_proofs_contract/src/main.nr @@ -22,13 +22,11 @@ contract InclusionProofs { }, constants_gen::{ NOTE_HASH_TREE_HEIGHT, - NULLIFIER_TREE_HEIGHT, - HISTORIC_BLOCKS_TREE_HEIGHT, PUBLIC_DATA_TREE_HEIGHT, GENERATOR_INDEX__PUBLIC_LEAF_INDEX, }, oracle::{ - get_block_data::get_block_data, + get_block_header::get_block_header, get_membership_witness::{ get_membership_witness, MembershipWitness, @@ -103,13 +101,13 @@ contract InclusionProofs { block_number: Field, // The block at which we'll prove that the note exists spare_commitment: Field, // This is only used when the note is not found --> used to test the failure case ) { - // TODO: assert that block number is less than the block number of context.block_data - // --> This will either require a new oracle method that returns block_data.global_variables_hash preimage + // TODO: assert that block number is less than the block number of context.block_header + // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage // or modifying the private context so that we somehow expose it. - // 1) Get historic block data from oracle and ensure that the block hash is included in the current blocks tree + // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. - let block_data = context.get_block_data(block_number); + let block_header = context.get_block_header(block_number); // 2) Get the note from PXE. let private_values = storage.private_values.at(owner.address); @@ -132,7 +130,7 @@ contract InclusionProofs { // 5) Prove that the commitment is in the note hash tree assert( - block_data.note_hash_tree_root == compute_merkle_root(note_commitment, witness.index, witness.path), + block_header.note_hash_tree_root == compute_merkle_root(note_commitment, witness.index, witness.path), "Proving note inclusion failed" ); @@ -146,13 +144,13 @@ contract InclusionProofs { block_number: Field, // The block at which we'll prove that the nullifier does not exists spare_nullifier: Field, // This is only used when the note is not found --> used to test the failure case ) { - // TODO: assert that block number is less than the block number of context.block_data - // --> This will either require a new oracle method that returns block_data.global_variables_hash preimage + // TODO: assert that block number is less than the block number of context.block_header + // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage // or modifying the private context so that we somehow expose it. - // 1) Get historic block data from oracle and ensure that the block hash is included in the current blocks tree + // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. - let block_data = context.get_block_data(block_number); + let block_header = context.get_block_header(block_number); // 2) Get the note from PXE let private_values = storage.private_values.at(owner.address); @@ -176,7 +174,7 @@ contract InclusionProofs { // 5.a) Compute the low nullifier leaf and prove that it is in the nullifier tree let low_nullifier_leaf = witness.leaf_data.hash(); assert( - block_data.nullifier_tree_root == compute_merkle_root(low_nullifier_leaf, witness.index, witness.path), + block_header.nullifier_tree_root == compute_merkle_root(low_nullifier_leaf, witness.index, witness.path), "Proving nullifier non-inclusion failed: Could not prove low nullifier inclusion" ); @@ -217,13 +215,13 @@ contract InclusionProofs { nullifier: Field, block_number: Field, // The block at which we'll prove that the nullifier not exists in the tree ) { - // TODO: assert that block number is less than the block number of context.block_data - // --> This will either require a new oracle method that returns block_data.global_variables_hash preimage + // TODO: assert that block number is less than the block number of context.block_header + // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage // or modifying the private context so that we somehow expose it. - // 1) Get historic block data from oracle and ensure that the block hash is included in the current blocks tree + // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. - let block_data = context.get_block_data(block_number); + let block_header = context.get_block_header(block_number); // 2) Get the membership witness of the nullifier let witness = get_nullifier_membership_witness(block_number, nullifier); @@ -236,7 +234,7 @@ contract InclusionProofs { // 5) Prove that the nullifier is in the nullifier tree assert( - block_data.nullifier_tree_root == compute_merkle_root(nullifier_leaf, witness.index, witness.path), + block_header.nullifier_tree_root == compute_merkle_root(nullifier_leaf, witness.index, witness.path), "Proving nullifier inclusion failed" ); @@ -249,13 +247,13 @@ contract InclusionProofs { public_value: Field, block_number: Field, // The block at which we'll prove that the public value exists ) { - // TODO: assert that block number is less than the block number of context.block_data - // --> This will either require a new oracle method that returns block_data.global_variables_hash preimage + // TODO: assert that block number is less than the block number of context.block_header + // --> This will either require a new oracle method that returns block_header.global_variables_hash preimage // or modifying the private context so that we somehow expose it. - // 1) Get historic block data from oracle and ensure that the block hash is included in the current blocks tree + // 1) Get block header from oracle and ensure that the block hash is included in the current blocks tree // root. - let block_data = context.get_block_data(block_number); + let block_header = context.get_block_header(block_number); // 2) Compute the public value leaf index. // We have to compute the leaf index here because unlike in the case of note commitments, public values are @@ -273,7 +271,7 @@ contract InclusionProofs { // 4) Prove that the public value provided on input is in the public data tree assert( - block_data.public_data_tree_root == compute_merkle_root(public_value, public_value_leaf_index, path), + block_header.public_data_tree_root == compute_merkle_root(public_value, public_value_leaf_index, path), "Proving public value inclusion failed" ); @@ -288,4 +286,4 @@ contract InclusionProofs { let note_header = NoteHeader::new(contract_address, nonce, storage_slot); note_utils::compute_note_hash_and_nullifier(ValueNoteMethods, note_header, serialized_note) } -} +} \ No newline at end of file diff --git a/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr b/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr index 65cf52e96b5b..1bb62e9f3f6f 100644 --- a/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr +++ b/yarn-project/noir-contracts/src/contracts/test_contract/src/interface.nr @@ -1,5 +1,5 @@ /* Autogenerated file, do not edit! */ - + use dep::std; use dep::aztec::context::{ PrivateContext, PublicContext }; use dep::aztec::constants_gen::RETURN_VALUES_LENGTH; @@ -26,6 +26,7 @@ struct ManyNotesADeepStructTestCodeGenStruct { secret_hash: Field, } + // Interface for calling Test functions from a private context struct TestPrivateContextInterface { address: Field, @@ -241,6 +242,9 @@ impl TestPrivateContextInterface { } } + + + // Interface for calling Test functions from a public context struct TestPublicContextInterface { @@ -326,4 +330,5 @@ impl TestPublicContextInterface { } } - + + diff --git a/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap b/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap index 0918bd55a078..af2dbd89ecb1 100644 --- a/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap +++ b/yarn-project/noir-protocol-circuits/src/__snapshots__/index.test.ts.snap @@ -103,7 +103,7 @@ exports[`Noir compatibility tests (interop_testing.nr) TxRequest Hash matches No exports[`Private kernel Executes private kernel init circuit for a contract deployment 1`] = ` KernelCircuitPublicInputs { "constants": CombinedConstantData { - "blockData": HistoricBlockData { + "blockHeader": BlockHeader { "blocksTreeRoot": Fr { "asBigInt": 10561895175368852737061915973188839857007468377789560793687187642867659280638n, "asBuffer": { @@ -25719,7 +25719,7 @@ KernelCircuitPublicInputs { exports[`Private kernel Executes private kernel inner for a nested call 1`] = ` KernelCircuitPublicInputs { "constants": CombinedConstantData { - "blockData": HistoricBlockData { + "blockHeader": BlockHeader { "blocksTreeRoot": Fr { "asBigInt": 5141115076863619919216387293080007096006645021873634395499188999297490933851n, "asBuffer": { @@ -51335,7 +51335,7 @@ KernelCircuitPublicInputs { exports[`Private kernel Executes private kernel ordering after a deployment 1`] = ` KernelCircuitPublicInputsFinal { "constants": CombinedConstantData { - "blockData": HistoricBlockData { + "blockHeader": BlockHeader { "blocksTreeRoot": Fr { "asBigInt": 10561895175368852737061915973188839857007468377789560793687187642867659280638n, "asBuffer": { diff --git a/yarn-project/noir-protocol-circuits/src/__snapshots__/noir_test_gen.test.ts.snap b/yarn-project/noir-protocol-circuits/src/__snapshots__/noir_test_gen.test.ts.snap index 63015d107dbf..86437f04b439 100644 --- a/yarn-project/noir-protocol-circuits/src/__snapshots__/noir_test_gen.test.ts.snap +++ b/yarn-project/noir-protocol-circuits/src/__snapshots__/noir_test_gen.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Data generation for noir tests Computes a private data tree 1`] = ` +exports[`Data generation for noir tests Computes a note hash tree 1`] = ` { "root": "0x0d2f152f19e366e9e690e3e551c1aadc0eab0bb27f6d011a9622d8f31bfa6e22", "siblingPaths": [ diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr index 9e9422608f90..8653d993183b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/common.nr @@ -63,15 +63,15 @@ pub fn validate_arrays(app_public_inputs : PrivateCircuitPublicInputs) { // encrypted_logs_hash and unencrypted_logs_hash have their own integrity checks. } -// Validate all read requests against the historic private data root. -// Use their membership witnesses to do so. If the historic root is not yet +// Validate all read requests against the historical private data root. +// Use their membership witnesses to do so. If the historical root is not yet // initialized, initialize it using the first read request here (if present). // // More info here: // - https://discourse.aztec.network/t/to-read-or-not-to-read/178 // - https://discourse.aztec.network/t/spending-notes-which-havent-yet-been-inserted/180 pub fn validate_read_requests( - historic_note_hash_tree_root: Field, + historical_note_hash_tree_root: Field, read_requests: [Field; MAX_READ_REQUESTS_PER_CALL], read_request_membership_witnesses: [ReadRequestMembershipWitness; MAX_READ_REQUESTS_PER_CALL], ) { @@ -81,7 +81,7 @@ pub fn validate_read_requests( let read_request = read_requests[rr_idx]; let witness = read_request_membership_witnesses[rr_idx]; - // A pending commitment is the one that is not yet added to private data tree + // A pending commitment is the one that is not yet added to note hash tree // A "transient read" is when we try to "read" a pending commitment within a transaction // between function calls, as opposed to reading the outputs of a previous transaction // which is a "pending read". @@ -92,7 +92,7 @@ pub fn validate_read_requests( if (read_request != 0) & (witness.is_transient == false) { let root_for_read_request = read_request_root_from_siblings(read_request, witness.leaf_index, witness.sibling_path); - assert(root_for_read_request == historic_note_hash_tree_root, "private data tree root mismatch"); + assert(root_for_read_request == historical_note_hash_tree_root, "note hash tree root mismatch"); // TODO(https://github.com/AztecProtocol/aztec-packages/issues/1354): do we need to enforce // that a non-transient read_request was derived from the proper/current contract address? @@ -347,7 +347,7 @@ pub fn contract_logic(private_call : PrivateCallData, public_inputs : &mut Kerne private_call.contract_leaf_membership_witness.leaf_index, private_call.contract_leaf_membership_witness.sibling_path); - let purported_contract_tree_root = private_call.call_stack_item.public_inputs.historical_block_data.contract_tree_root(); + let purported_contract_tree_root = private_call.call_stack_item.public_inputs.block_header.contract_tree_root(); assert_eq(computed_contract_tree_root, purported_contract_tree_root, "computed_contract_tree_root does not match purported_contract_tree_root"); } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr index 7266c6919240..88a34b4049c5 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_init.nr @@ -21,7 +21,7 @@ struct PrivateKernelInputsInit { impl PrivateKernelInputsInit { fn initialize_end_values(self, public_inputs: &mut KernelCircuitPublicInputsBuilder) { public_inputs.constants = CombinedConstantData { - block_data: self.private_call.call_stack_item.public_inputs.historical_block_data, + block_header: self.private_call.call_stack_item.public_inputs.block_header, tx_context: self.tx_request.tx_context, }; } @@ -91,7 +91,7 @@ impl PrivateKernelInputsInit { self.validate_this_private_call_against_tx_request(); common::validate_read_requests( - public_inputs.constants.block_data.note_hash_tree_root(), + public_inputs.constants.block_header.note_hash_tree_root(), self.private_call.call_stack_item.public_inputs.read_requests, self.private_call.read_request_membership_witnesses ); @@ -451,7 +451,7 @@ mod tests { builder.failed(); } - #[test(should_fail_with="private data tree root mismatch")] + #[test(should_fail_with="note hash tree root mismatch")] fn native_read_request_bad_request() { let mut builder = PrivateKernelInitInputsBuilder::new(); @@ -464,7 +464,7 @@ mod tests { builder.failed(); } - #[test(should_fail_with="private data tree root mismatch")] + #[test(should_fail_with="note hash tree root mismatch")] fn native_read_request_bad_leaf_index() { let mut builder = PrivateKernelInitInputsBuilder::new(); @@ -478,7 +478,7 @@ mod tests { builder.failed(); } - #[test(should_fail_with="private data tree root mismatch")] + #[test(should_fail_with="note hash tree root mismatch")] fn native_read_request_bad_sibling_path() { let mut builder = PrivateKernelInitInputsBuilder::new(); diff --git a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr index 23231fdd4a08..cdee6d1b9410 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/private-kernel-lib/src/private_kernel_inner.nr @@ -22,8 +22,8 @@ impl PrivateKernelInputsInner { } fn validate_contract_tree_root(self) { - let purported_contract_tree_root = self.private_call.call_stack_item.public_inputs.historical_block_data.contract_tree_root(); - let previous_kernel_contract_tree_root = self.previous_kernel.public_inputs.constants.block_data.contract_tree_root(); + let purported_contract_tree_root = self.private_call.call_stack_item.public_inputs.block_header.contract_tree_root(); + let previous_kernel_contract_tree_root = self.previous_kernel.public_inputs.constants.block_header.contract_tree_root(); assert(purported_contract_tree_root == previous_kernel_contract_tree_root, "purported_contract_tree_root does not match previous_kernel_contract_tree_root"); } @@ -52,14 +52,14 @@ impl PrivateKernelInputsInner { self.pop_and_validate_this_private_call_hash(&mut public_inputs); common::validate_read_requests( - public_inputs.constants.block_data.note_hash_tree_root(), + public_inputs.constants.block_header.note_hash_tree_root(), self.private_call.call_stack_item.public_inputs.read_requests, // read requests from private call self.private_call.read_request_membership_witnesses); //TODO(David): feels like update_end_values should happen later common::update_end_values(self.private_call, &mut public_inputs); - // ensure that historic/purported contract tree root matches the one in previous kernel + // ensure that historical/purported contract tree root matches the one in previous kernel self.validate_contract_tree_root(); let this_call_stack_item = self.private_call.call_stack_item; @@ -171,9 +171,9 @@ mod tests { fn private_function_incorrect_contract_tree_root_fails() { let mut builder = PrivateKernelInnerInputsBuilder::new(); - // Set historic_tree_root to a wrong value (the correct value + 1). - let contract_tree_root = builder.previous_kernel.block_data.block.contract_tree_root; - builder.previous_kernel.block_data.block.contract_tree_root = contract_tree_root + 1; + // Set historical_tree_root to a wrong value (the correct value + 1). + let contract_tree_root = builder.previous_kernel.block_header.block.contract_tree_root; + builder.previous_kernel.block_header.block.contract_tree_root = contract_tree_root + 1; builder.failed(); } @@ -560,7 +560,7 @@ mod tests { builder.failed(); } - #[test(should_fail_with="private data tree root mismatch")] + #[test(should_fail_with="note hash tree root mismatch")] fn native_read_request_bad_request() { let mut builder = PrivateKernelInnerInputsBuilder::new(); @@ -573,7 +573,7 @@ mod tests { builder.failed(); } - #[test(should_fail_with="private data tree root mismatch")] + #[test(should_fail_with="note hash tree root mismatch")] fn native_read_request_bad_leaf_index() { let mut builder = PrivateKernelInnerInputsBuilder::new(); @@ -587,7 +587,7 @@ mod tests { builder.failed(); } - #[test(should_fail_with="private data tree root mismatch")] + #[test(should_fail_with="note hash tree root mismatch")] fn native_read_request_bad_sibling_path() { let mut builder = PrivateKernelInnerInputsBuilder::new(); @@ -601,15 +601,15 @@ mod tests { builder.failed(); } - #[test(should_fail_with="private data tree root mismatch")] + #[test(should_fail_with="note hash tree root mismatch")] fn native_read_request_root_mismatch() { let mut builder = PrivateKernelInnerInputsBuilder::new(); builder.private_call.append_read_requests(1); // Set the root to be a different root so the above read request is not under this root. - let old_root = builder.previous_kernel.block_data.block.note_hash_tree_root; - builder.previous_kernel.block_data.block.note_hash_tree_root = old_root + 1; + let old_root = builder.previous_kernel.block_header.block.note_hash_tree_root; + builder.previous_kernel.block_header.block.note_hash_tree_root = old_root + 1; builder.failed(); } diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr index 675c6d6dcb34..410826c29c34 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/abis/constant_rollup_data.nr @@ -3,7 +3,7 @@ use crate::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot; struct ConstantRollupData { // The very latest roots as at the very beginning of the entire rollup: - start_historic_blocks_tree_roots_snapshot : AppendOnlyTreeSnapshot, + start_blocks_tree_snapshot : AppendOnlyTreeSnapshot, // TODO(Sean): Some members of this struct tbd private_kernel_vk_tree_root : Field, @@ -16,7 +16,7 @@ struct ConstantRollupData { impl ConstantRollupData { pub fn eq(self, other : ConstantRollupData) -> bool { - self.start_historic_blocks_tree_roots_snapshot.eq(other.start_historic_blocks_tree_roots_snapshot) & + self.start_blocks_tree_snapshot.eq(other.start_blocks_tree_snapshot) & self.global_variables.eq(other.global_variables) & (self.private_kernel_vk_tree_root == other.private_kernel_vk_tree_root) & (self.public_kernel_vk_tree_root == other.public_kernel_vk_tree_root) & diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr index 172701cfb645..a453771ce150 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/base/base_rollup_inputs.nr @@ -33,7 +33,7 @@ use dep::aztec::constants_gen::{ }; use dep::types::abis::previous_kernel_data::PreviousKernelData; use dep::types::abis::membership_witness::{NullifierMembershipWitness, MembershipWitness}; -use dep::types::abis::membership_witness::HistoricBlocksTreeRootMembershipWitness; +use dep::types::abis::membership_witness::BlocksTreeRootMembershipWitness; struct BaseRollupInputs { kernel_data: [PreviousKernelData; KERNELS_PER_BASE_ROLLUP], @@ -41,7 +41,7 @@ struct BaseRollupInputs { start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot, start_contract_tree_snapshot: AppendOnlyTreeSnapshot, start_public_data_tree_root: Field, - start_historic_blocks_tree_snapshot: AppendOnlyTreeSnapshot, + start_blocks_tree_snapshot: AppendOnlyTreeSnapshot, sorted_new_nullifiers: [Field; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], sorted_new_nullifiers_indexes: [u32; MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP], @@ -56,7 +56,7 @@ struct BaseRollupInputs { new_public_data_update_requests_sibling_paths: [[Field; PUBLIC_DATA_TREE_HEIGHT]; MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_BASE_ROLLUP], new_public_data_reads_sibling_paths: [[Field; PUBLIC_DATA_TREE_HEIGHT]; MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP], - historic_blocks_tree_root_membership_witnesses: [HistoricBlocksTreeRootMembershipWitness; KERNELS_PER_BASE_ROLLUP], + blocks_tree_root_membership_witnesses: [BlocksTreeRootMembershipWitness; KERNELS_PER_BASE_ROLLUP], constants: ConstantRollupData, } @@ -112,8 +112,8 @@ impl BaseRollupInputs { // Calculate the overall calldata hash let calldata_hash = BaseRollupInputs::components_compute_kernel_calldata_hash(self.kernel_data); - // Perform membership checks that the notes provided exist within the historic trees data - self.perform_historical_blocks_tree_membership_checks(); + // Perform membership checks that the notes provided exist within the historical trees data + self.perform_blocks_tree_membership_checks(); let aggregation_object = self.aggregate_proofs(); @@ -373,24 +373,26 @@ impl BaseRollupInputs { U256::from_bytes32(sha_digest).to_u128_limbs() } - // Check all of the provided commitments against the historical tree roots - fn perform_historical_blocks_tree_membership_checks(self) { - // For each of the historic_note_hash_tree_membership_checks, we need to do an inclusion proof - // against the historical root provided in the rollup constants - let historic_root = self.constants.start_historic_blocks_tree_roots_snapshot.root; + // Check that the block header used by each kernel is a member of the blocks tree --> since the block header + // contains roots of all the trees this is sufficient to verify that the tree roots used by kernels are correct + fn perform_blocks_tree_membership_checks(self) { + // For each of the block header (their block hashes), we need to do an inclusion proof + // against the blocks tree root from the beginning of a rollup provided in the rollup constants + let blocks_treee_root = self.constants.start_blocks_tree_snapshot.root; for i in 0..KERNELS_PER_BASE_ROLLUP { // Rebuild the block hash - let historical_block_data = self.kernel_data[i].public_inputs.constants.block_data; - let previous_block_hash = historical_block_data.block.hash(); + let block_header = self.kernel_data[i].public_inputs.constants.block_header; + let previous_block_hash = block_header.block.hash(); - let historic_root_witness = self.historic_blocks_tree_root_membership_witnesses[i]; + let previous_block_hash_witness = self.blocks_tree_root_membership_witnesses[i]; + // Now check that the previous block hash is in the blocks tree from the beginning of the rollup components::assert_check_membership( previous_block_hash, - historic_root_witness.leaf_index, - historic_root_witness.sibling_path, - historic_root + previous_block_hash_witness.leaf_index, + previous_block_hash_witness.sibling_path, + blocks_treee_root ); } } @@ -540,7 +542,7 @@ mod tests { CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, CONTRACT_TREE_HEIGHT, CONTRACT_SUBTREE_HEIGHT, - HISTORIC_BLOCKS_TREE_HEIGHT, + BLOCKS_TREE_HEIGHT, KERNELS_PER_BASE_ROLLUP, MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP, @@ -554,7 +556,7 @@ mod tests { PUBLIC_DATA_TREE_HEIGHT, }; use dep::types::{ - abis::membership_witness::HistoricBlocksTreeRootMembershipWitness, + abis::membership_witness::BlocksTreeRootMembershipWitness, abis::membership_witness::NullifierMembershipWitness, abis::new_contract_data::NewContractData, abis::public_data_read::PublicDataRead, @@ -610,7 +612,7 @@ mod tests { }); inputs.pre_existing_blocks = inputs.kernel_data.map(|builder: PreviousKernelDataBuilder|{ - builder.block_data.block.hash() + builder.block_header.block.hash() }); inputs @@ -729,13 +731,13 @@ mod tests { let mut start_public_data_tree = NonEmptyMerkleTree::new(self.pre_existing_public_data, [0; PUBLIC_DATA_TREE_HEIGHT], [0; PUBLIC_DATA_TREE_HEIGHT - 5], [0; 5]); let start_public_data_tree_root = start_public_data_tree.get_root(); - let start_historic_blocks_tree = NonEmptyMerkleTree::new(self.pre_existing_blocks, [0; HISTORIC_BLOCKS_TREE_HEIGHT], [0; HISTORIC_BLOCKS_TREE_HEIGHT - 1], [0; 1]); - let start_historic_blocks_tree_snapshot = AppendOnlyTreeSnapshot { - root: start_historic_blocks_tree.get_root(), - next_available_leaf_index: start_historic_blocks_tree.get_next_available_index() as u32, + let start_blocks_tree = NonEmptyMerkleTree::new(self.pre_existing_blocks, [0; BLOCKS_TREE_HEIGHT], [0; BLOCKS_TREE_HEIGHT - 1], [0; 1]); + let start_blocks_tree_snapshot = AppendOnlyTreeSnapshot { + root: start_blocks_tree.get_root(), + next_available_leaf_index: start_blocks_tree.get_next_available_index() as u32, }; - self.constants.start_historic_blocks_tree_roots_snapshot = start_historic_blocks_tree_snapshot; + self.constants.start_blocks_tree_snapshot = start_blocks_tree_snapshot; let mut new_public_data_reads_sibling_paths: [[Field; PUBLIC_DATA_TREE_HEIGHT]; MAX_PUBLIC_DATA_READS_PER_BASE_ROLLUP] = dep::std::unsafe::zeroed(); @@ -784,7 +786,7 @@ mod tests { start_nullifier_tree_snapshot, start_contract_tree_snapshot, start_public_data_tree_root, - start_historic_blocks_tree_snapshot, + start_blocks_tree_snapshot, sorted_new_nullifiers, sorted_new_nullifiers_indexes, @@ -798,14 +800,14 @@ mod tests { new_public_data_update_requests_sibling_paths, new_public_data_reads_sibling_paths, - historic_blocks_tree_root_membership_witnesses: [ - HistoricBlocksTreeRootMembershipWitness { + blocks_tree_root_membership_witnesses: [ + BlocksTreeRootMembershipWitness { leaf_index: 0, - sibling_path: start_historic_blocks_tree.get_sibling_path(0) + sibling_path: start_blocks_tree.get_sibling_path(0) }, - HistoricBlocksTreeRootMembershipWitness { + BlocksTreeRootMembershipWitness { leaf_index: 1, - sibling_path: start_historic_blocks_tree.get_sibling_path(1) + sibling_path: start_blocks_tree.get_sibling_path(1) }, ], @@ -1142,10 +1144,10 @@ mod tests { } #[test(should_fail_with = "membership check failed")] - unconstrained fn compute_membership_historic_blocks_tree_negative() { + unconstrained fn compute_membership_blocks_tree_negative() { let mut inputs = BaseRollupInputsBuilder::new().build_inputs(); - inputs.historic_blocks_tree_root_membership_witnesses[0].sibling_path[0] = 27; + inputs.blocks_tree_root_membership_witnesses[0].sibling_path[0] = 27; let _output = inputs.base_rollup_circuit(); } diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root.nr index c64ee5fcbdd7..d6052cee5e24 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root.nr @@ -37,7 +37,7 @@ impl RootRollupInputs { ); // Build the block hash for this iteration from the tree roots and global variables - // Then insert the block into the historic blocks tree + // Then insert the block into the blocks tree let block_hash = compute_block_hash_with_globals(left.constants.global_variables, right.end_note_hash_tree_snapshot.root, right.end_nullifier_tree_snapshot.root, @@ -45,10 +45,10 @@ impl RootRollupInputs { new_l1_to_l2_messages_tree_snapshot.root, right.end_public_data_tree_root); - // Update the historic blocks tree - let end_historic_blocks_tree_snapshot = components::insert_subtree_to_snapshot_tree( - self.start_historic_blocks_tree_snapshot, - self.new_historic_blocks_tree_sibling_path, + // Update the blocks tree + let end_blocks_tree_snapshot = components::insert_subtree_to_snapshot_tree( + self.start_blocks_tree_snapshot, + self.new_blocks_tree_sibling_path, 0, block_hash, 0 @@ -72,19 +72,19 @@ impl RootRollupInputs { end_public_data_tree_root : right.end_public_data_tree_root, start_l1_to_l2_messages_tree_snapshot : self.start_l1_to_l2_messages_tree_snapshot, end_l1_to_l2_messages_tree_snapshot : new_l1_to_l2_messages_tree_snapshot, - start_historic_blocks_tree_snapshot : self.start_historic_blocks_tree_snapshot, - end_historic_blocks_tree_snapshot : end_historic_blocks_tree_snapshot, + start_blocks_tree_snapshot : self.start_blocks_tree_snapshot, + end_blocks_tree_snapshot : end_blocks_tree_snapshot, calldata_hash : components::compute_calldata_hash(self.previous_rollup_data), l1_to_l2_messages_hash : compute_messages_hash(self.new_l1_to_l2_messages), // The cpp code was just not initializing these, so they would be zeroed out // TODO(Lasse/Jean): add explanation for this. - end_tree_of_historic_contract_tree_roots_snapshot : zeroed_out_snapshot, - end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot : zeroed_out_snapshot, - end_tree_of_historic_note_hash_tree_roots_snapshot : zeroed_out_snapshot, - start_tree_of_historic_contract_tree_roots_snapshot : zeroed_out_snapshot, - start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot : zeroed_out_snapshot, - start_tree_of_historic_note_hash_tree_roots_snapshot : zeroed_out_snapshot, + end_tree_of_historical_contract_tree_roots_snapshot : zeroed_out_snapshot, + end_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot : zeroed_out_snapshot, + end_tree_of_historical_note_hash_tree_roots_snapshot : zeroed_out_snapshot, + start_tree_of_historical_contract_tree_roots_snapshot : zeroed_out_snapshot, + start_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot : zeroed_out_snapshot, + start_tree_of_historical_note_hash_tree_roots_snapshot : zeroed_out_snapshot, } } } diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_inputs.nr index 23f1f6db7e93..5c2fa4075ff1 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_inputs.nr @@ -6,7 +6,7 @@ use crate::abis::constant_rollup_data::ConstantRollupData; use dep::aztec::constants_gen::{ NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, - HISTORIC_BLOCKS_TREE_HEIGHT + BLOCKS_TREE_HEIGHT }; struct RootRollupInputs { @@ -20,6 +20,6 @@ struct RootRollupInputs { start_l1_to_l2_messages_tree_snapshot : AppendOnlyTreeSnapshot, // inputs required to add the block hash - start_historic_blocks_tree_snapshot : AppendOnlyTreeSnapshot, - new_historic_blocks_tree_sibling_path : [Field; HISTORIC_BLOCKS_TREE_HEIGHT], + start_blocks_tree_snapshot : AppendOnlyTreeSnapshot, + new_blocks_tree_sibling_path : [Field; BLOCKS_TREE_HEIGHT], } \ No newline at end of file diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_public_inputs.nr index 2a1ca5daa5e5..9b15ca2955f0 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/root/root_rollup_public_inputs.nr @@ -26,20 +26,20 @@ struct RootRollupPublicInputs { start_public_data_tree_root : Field, end_public_data_tree_root : Field, - start_tree_of_historic_note_hash_tree_roots_snapshot : AppendOnlyTreeSnapshot, - end_tree_of_historic_note_hash_tree_roots_snapshot : AppendOnlyTreeSnapshot, + start_tree_of_historical_note_hash_tree_roots_snapshot : AppendOnlyTreeSnapshot, + end_tree_of_historical_note_hash_tree_roots_snapshot : AppendOnlyTreeSnapshot, - start_tree_of_historic_contract_tree_roots_snapshot : AppendOnlyTreeSnapshot, - end_tree_of_historic_contract_tree_roots_snapshot : AppendOnlyTreeSnapshot, + start_tree_of_historical_contract_tree_roots_snapshot : AppendOnlyTreeSnapshot, + end_tree_of_historical_contract_tree_roots_snapshot : AppendOnlyTreeSnapshot, start_l1_to_l2_messages_tree_snapshot : AppendOnlyTreeSnapshot, end_l1_to_l2_messages_tree_snapshot : AppendOnlyTreeSnapshot, - start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot : AppendOnlyTreeSnapshot, - end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot : AppendOnlyTreeSnapshot, + start_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot : AppendOnlyTreeSnapshot, + end_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot : AppendOnlyTreeSnapshot, - start_historic_blocks_tree_snapshot : AppendOnlyTreeSnapshot, - end_historic_blocks_tree_snapshot : AppendOnlyTreeSnapshot, + start_blocks_tree_snapshot : AppendOnlyTreeSnapshot, + end_blocks_tree_snapshot : AppendOnlyTreeSnapshot, calldata_hash : [Field; NUM_FIELDS_PER_SHA256], l1_to_l2_messages_hash : [Field; NUM_FIELDS_PER_SHA256], diff --git a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/tests/root_rollup_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/tests/root_rollup_inputs.nr index 81e026c53d50..7da05d2df6d6 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/tests/root_rollup_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/rollup-lib/src/tests/root_rollup_inputs.nr @@ -7,7 +7,7 @@ use dep::aztec::constants_gen::{ L1_TO_L2_MSG_TREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, L1_TO_L2_MSG_SUBTREE_HEIGHT, - HISTORIC_BLOCKS_TREE_HEIGHT, + BLOCKS_TREE_HEIGHT, }; use crate::abis::append_only_tree_snapshot::AppendOnlyTreeSnapshot; use crate::tests::previous_rollup_data::default_previous_rollup_data; @@ -25,10 +25,10 @@ pub fn compute_l1_l2_empty_snapshot() -> (AppendOnlyTreeSnapshot, [Field; L1_TO_ (AppendOnlyTreeSnapshot{ root: zero_hashes[zero_hashes.len() - 1], next_available_leaf_index: 0 }, new_l1_to_l2_messages_tree_root_sibling_path) } -pub fn compute_historic_blocks_tree_snapshot() -> (AppendOnlyTreeSnapshot, [Field; HISTORIC_BLOCKS_TREE_HEIGHT]) { - let zero_hashes = compute_zero_hashes([0; HISTORIC_BLOCKS_TREE_HEIGHT]); - let mut sibling_path = [0; HISTORIC_BLOCKS_TREE_HEIGHT]; - for i in 1..HISTORIC_BLOCKS_TREE_HEIGHT { +pub fn compute_blocks_tree_snapshot() -> (AppendOnlyTreeSnapshot, [Field; BLOCKS_TREE_HEIGHT]) { + let zero_hashes = compute_zero_hashes([0; BLOCKS_TREE_HEIGHT]); + let mut sibling_path = [0; BLOCKS_TREE_HEIGHT]; + for i in 1..BLOCKS_TREE_HEIGHT { sibling_path[i] = zero_hashes[i-1]; } (AppendOnlyTreeSnapshot { root: zero_hashes[zero_hashes.len() - 1], next_available_leaf_index: 0 }, sibling_path) @@ -42,10 +42,10 @@ pub fn default_root_rollup_inputs() -> RootRollupInputs { inputs.new_l1_to_l2_messages_tree_root_sibling_path = l1_l2_empty_sibling_path; inputs.start_l1_to_l2_messages_tree_snapshot = l1_l2_empty_snapshot; - let (historic_blocks_snapshot, historic_blocks_sibling_path) = compute_historic_blocks_tree_snapshot(); + let (blocks_snapshot, blocks_sibling_path) = compute_blocks_tree_snapshot(); - inputs.start_historic_blocks_tree_snapshot = historic_blocks_snapshot; - inputs.new_historic_blocks_tree_sibling_path = historic_blocks_sibling_path; + inputs.start_blocks_tree_snapshot = blocks_snapshot; + inputs.new_blocks_tree_sibling_path = blocks_sibling_path; inputs.previous_rollup_data = default_previous_rollup_data(); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis.nr index 8fd4ee281090..dd2b52402dfe 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis.nr @@ -7,7 +7,7 @@ mod membership_witness; mod new_contract_data; mod contract_leaf_preimage; -mod historical_block_data; +mod block_header; mod combined_constant_data; mod public_data_read; mod public_data_update_request; diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/historical_block_data.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr similarity index 95% rename from yarn-project/noir-protocol-circuits/src/crates/types/src/abis/historical_block_data.nr rename to yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr index 488d4cf6ba0d..9616da0aa8c0 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/historical_block_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/block_header.nr @@ -1,6 +1,6 @@ use crate::block::Block; -struct HistoricalBlockData { +struct BlockHeader { blocks_tree_root : Field, block : Block, // Private data @@ -8,7 +8,7 @@ struct HistoricalBlockData { private_kernel_vk_tree_root : Field, } -impl HistoricalBlockData { +impl BlockHeader { fn assert_is_zero(self) { self.block.assert_is_zero(); assert(self.private_kernel_vk_tree_root == 0); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/combined_constant_data.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/combined_constant_data.nr index 947c6c882144..d1706c9624e4 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/combined_constant_data.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/combined_constant_data.nr @@ -1,7 +1,7 @@ use crate::transaction::context::TxContext; -use crate::abis::historical_block_data::HistoricalBlockData; +use crate::abis::block_header::BlockHeader; struct CombinedConstantData { - block_data: HistoricalBlockData, + block_header: BlockHeader, tx_context: TxContext, } diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr index 2af3ca4ff215..6b4c29dcb71b 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/membership_witness.nr @@ -5,7 +5,7 @@ use dep::aztec::constants_gen::{ NULLIFIER_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, ROLLUP_VK_TREE_HEIGHT, - HISTORIC_BLOCKS_TREE_HEIGHT, + BLOCKS_TREE_HEIGHT, }; struct MembershipWitness { @@ -37,9 +37,9 @@ struct NullifierMembershipWitness{ sibling_path: [Field; NULLIFIER_TREE_HEIGHT] } -struct HistoricBlocksTreeRootMembershipWitness{ +struct BlocksTreeRootMembershipWitness{ leaf_index: Field, - sibling_path: [Field; HISTORIC_BLOCKS_TREE_HEIGHT] + sibling_path: [Field; BLOCKS_TREE_HEIGHT] } struct ReadRequestMembershipWitness { diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr index 12bb26c95ad5..b13e029a9266 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/private_circuit_public_inputs.nr @@ -1,7 +1,7 @@ use crate::{ abis::{ call_context::CallContext, - historical_block_data::HistoricalBlockData, + block_header::BlockHeader, }, contrakt::deployment_data::ContractDeploymentData, hash::NUM_FIELDS_PER_SHA256, @@ -46,7 +46,7 @@ struct PrivateCircuitPublicInputs { encrypted_log_preimages_length: Field, unencrypted_log_preimages_length: Field, - historical_block_data: HistoricalBlockData, + block_header: BlockHeader, contract_deployment_data: ContractDeploymentData, @@ -73,7 +73,7 @@ impl PrivateCircuitPublicInputs { fields.push_array(self.unencrypted_logs_hash); fields.push(self.encrypted_log_preimages_length); fields.push(self.unencrypted_log_preimages_length); - fields.push_array(self.historical_block_data.to_array()); + fields.push_array(self.block_header.to_array()); fields.push(self.contract_deployment_data.hash()); fields.push(self.chain_id); fields.push(self.version); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr index 98370a90c2cd..abcaf60e7afa 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/abis/public_circuit_public_inputs.nr @@ -11,7 +11,7 @@ use dep::aztec::constants_gen::{ use crate::{ abis::{ call_context::CallContext, - historical_block_data::HistoricalBlockData, + block_header::BlockHeader, }, address::Address, contrakt::{ @@ -42,7 +42,7 @@ struct PublicCircuitPublicInputs{ // variable-length data. unencrypted_log_preimages_length: Field, - historical_block_data: HistoricalBlockData, + block_header: BlockHeader, prover_address: Address, } @@ -66,7 +66,7 @@ impl PublicCircuitPublicInputs{ inputs.push_array(self.new_l2_to_l1_msgs); inputs.push_array(self.unencrypted_logs_hash); inputs.push(self.unencrypted_log_preimages_length); - inputs.push_array(self.historical_block_data.to_array()); + inputs.push_array(self.block_header.to_array()); inputs.push(self.prover_address.to_field()); assert_eq(inputs.len(), constants_gen::PUBLIC_CIRCUIT_PUBLIC_INPUTS_HASH_INPUT_LENGTH, "Incorrect number of input fields when hashing PublicCircuitPublicInputs"); diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr index 00c81df572cc..fca591a7fa63 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/fixtures.nr @@ -5,7 +5,7 @@ mod note_hash_tree; mod read_requests; use crate::address::Address; -use crate::abis::historical_block_data::HistoricalBlockData; +use crate::abis::block_header::BlockHeader; use crate::block::Block; use crate::point::Point; use crate::tests::fixtures; @@ -14,7 +14,7 @@ global MSG_SENDER = Address { inner: 27 }; global DEPLOYER_PUBLIC_KEY = Point { x: 123456789, y: 123456789 }; -global HISTORICAL_BLOCK_DATA = HistoricalBlockData { +global BLOCK_HEADER = BlockHeader { blocks_tree_root: 0, block: Block { note_hash_tree_root: fixtures::note_hash_tree::ROOT, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr index b5c02900860a..d41008a7ad48 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/previous_kernel_data_builder.nr @@ -4,7 +4,7 @@ use crate::{ call_request::{CallerContext, CallRequest}, combined_constant_data::CombinedConstantData, combined_accumulated_data::CombinedAccumulatedDataBuilder, - historical_block_data::HistoricalBlockData, + block_header::BlockHeader, kernel_circuit_public_inputs::KernelCircuitPublicInputs, previous_kernel_data::PreviousKernelData, public_data_read::PublicDataRead, @@ -34,7 +34,7 @@ struct PreviousKernelDataBuilder { contract_address: Address, portal_contract_address: EthAddress, end: CombinedAccumulatedDataBuilder, - block_data: HistoricalBlockData, + block_header: BlockHeader, tx_context: TxContext, is_private: bool, proof: Proof, @@ -55,7 +55,7 @@ impl PreviousKernelDataBuilder { contract_address: fixtures::contracts::parent_contract.address, portal_contract_address: fixtures::contracts::parent_contract.portal_contract_address, end, - block_data: fixtures::HISTORICAL_BLOCK_DATA, + block_header: fixtures::BLOCK_HEADER, tx_context, is_private: true, proof: Proof {}, @@ -171,7 +171,7 @@ impl PreviousKernelDataBuilder { let public_inputs = KernelCircuitPublicInputs { end: self.end.finish(), constants: CombinedConstantData { - block_data: self.block_data, + block_header: self.block_header, tx_context: self.tx_context, }, is_private: self.is_private, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr index 9a4f29397978..f000639f3df7 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/private_circuit_public_inputs_builder.nr @@ -2,7 +2,7 @@ use crate::{ abis::{ call_context::CallContext, complete_address::CompleteAddress, - historical_block_data::HistoricalBlockData, + block_header::BlockHeader, private_circuit_public_inputs::PrivateCircuitPublicInputs, }, contrakt::deployment_data::ContractDeploymentData, @@ -50,7 +50,7 @@ struct PrivateCircuitPublicInputsBuilder { encrypted_log_preimages_length: Field, unencrypted_log_preimages_length: Field, - historical_block_data: HistoricalBlockData, + block_header: BlockHeader, contract_deployment_data: ContractDeploymentData, @@ -101,7 +101,7 @@ impl PrivateCircuitPublicInputsBuilder { public_inputs.call_context = call_context; public_inputs.args_hash = args_hash; public_inputs.contract_deployment_data = contract_deployment_data; - public_inputs.historical_block_data = fixtures::HISTORICAL_BLOCK_DATA; + public_inputs.block_header = fixtures::BLOCK_HEADER; public_inputs.chain_id = 0; public_inputs.version = 1; @@ -131,7 +131,7 @@ impl PrivateCircuitPublicInputsBuilder { encrypted_log_preimages_length: self.encrypted_log_preimages_length, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, - historical_block_data: self.historical_block_data, + block_header: self.block_header, contract_deployment_data: self.contract_deployment_data, diff --git a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr index 184c558a82e9..7f1de0beee63 100644 --- a/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr +++ b/yarn-project/noir-protocol-circuits/src/crates/types/src/tests/public_circuit_public_inputs_builder.nr @@ -1,7 +1,7 @@ use crate::{ abis::{ call_context::CallContext, - historical_block_data::HistoricalBlockData, + block_header::BlockHeader, public_circuit_public_inputs::PublicCircuitPublicInputs, }, address::Address, @@ -35,7 +35,7 @@ struct PublicCircuitPublicInputsBuilder { new_l2_to_l1_msgs: BoundedVec, unencrypted_logs_hash: [Field; NUM_FIELDS_PER_SHA256], unencrypted_log_preimages_length: Field, - historical_block_data: HistoricalBlockData, + block_header: BlockHeader, prover_address: Address, } @@ -43,7 +43,7 @@ impl PublicCircuitPublicInputsBuilder { pub fn new() -> Self { let mut public_inputs: PublicCircuitPublicInputsBuilder = dep::std::unsafe::zeroed(); public_inputs.call_context.msg_sender = fixtures::MSG_SENDER; - public_inputs.historical_block_data = fixtures::HISTORICAL_BLOCK_DATA; + public_inputs.block_header = fixtures::BLOCK_HEADER; public_inputs } @@ -60,7 +60,7 @@ impl PublicCircuitPublicInputsBuilder { new_l2_to_l1_msgs: self.new_l2_to_l1_msgs.storage, unencrypted_logs_hash: self.unencrypted_logs_hash, unencrypted_log_preimages_length: self.unencrypted_log_preimages_length, - historical_block_data: self.historical_block_data, + block_header: self.block_header, prover_address: self.prover_address, } } diff --git a/yarn-project/noir-protocol-circuits/src/index.test.ts b/yarn-project/noir-protocol-circuits/src/index.test.ts index 9b7671574b12..974269bb8f7d 100644 --- a/yarn-project/noir-protocol-circuits/src/index.test.ts +++ b/yarn-project/noir-protocol-circuits/src/index.test.ts @@ -1,6 +1,7 @@ import { AggregationObject, AztecAddress, + BlockHeader, CONTRACT_TREE_HEIGHT, CallContext, CallRequest, @@ -12,7 +13,6 @@ import { FunctionData, FunctionLeafPreimage, FunctionSelector, - HistoricBlockData, KernelCircuitPublicInputs, MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_COMMITMENTS_PER_TX, @@ -103,7 +103,7 @@ describe('Private kernel', () => { const callContext = new CallContext(AztecAddress.ZERO, contractAddress, Fr.ZERO, selector, false, false, true); - const historicBlockData = new HistoricBlockData( + const blockHeader = new BlockHeader( Fr.fromString('0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb'), Fr.fromString('0x0bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278'), Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), @@ -130,7 +130,7 @@ describe('Private kernel', () => { [Fr.fromString('0xe3b0c44298fc1c149afbf4c8996fb924'), Fr.fromString('0x27ae41e4649b934ca495991b7852b855')], Fr.fromString('0xf8'), Fr.fromString('0x04'), - historicBlockData, + blockHeader, contractDeploymentData, Fr.ZERO, Fr.ZERO, @@ -215,7 +215,7 @@ describe('Private kernel', () => { makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataRead.empty()), ); - const historicBlockData = new HistoricBlockData( + const blockHeader = new BlockHeader( Fr.fromString('0x16642d9ccd8346c403aa4c3fa451178b22534a27035cdaa6ec34ae53b29c50cb'), Fr.fromString('0x0bcfa3e9f1a8922ee92c6dc964d6595907c1804a86753774322b468f69d4f278'), Fr.fromString('0x1864fcdaa80ff2719154fa7c8a9050662972707168d69eac9db6fd3110829f80'), @@ -226,7 +226,7 @@ describe('Private kernel', () => { Fr.fromString('0x200569267c0f73ac89aaa414239398db9445dd4ad3a8cf37015cd55b8d4c5e8d'), ); - const constants = new CombinedConstantData(historicBlockData, txContext); + const constants = new CombinedConstantData(blockHeader, txContext); const kernelPublicInputs = new KernelCircuitPublicInputs(combinedAccumulatedData, constants, true); @@ -275,7 +275,7 @@ describe('Private kernel', () => { false, ); - const historicBlockData = new HistoricBlockData( + const blockHeader = new BlockHeader( Fr.fromString('0x0dc1f2fbe77c0c72d329cc63f2bd88cd76a30c5802f8138814874cc328148834'), Fr.fromString('0x1861d7a76f4c8f7db95fa8aa1bcbdd5cbf576efe17455fee698f625292667070'), Fr.fromString('0x2f7255183443071e94e90651593c46342978e689e1f4f3e402616fa59633b974'), @@ -305,7 +305,7 @@ describe('Private kernel', () => { [Fr.fromString('0xe3b0c44298fc1c149afbf4c8996fb924'), Fr.fromString('0x27ae41e4649b934ca495991b7852b855')], Fr.fromString('0x04'), Fr.fromString('0x04'), - historicBlockData, + blockHeader, ContractDeploymentData.empty(), chainId, version, @@ -381,7 +381,7 @@ describe('Private kernel', () => { makeTuple(MAX_PUBLIC_DATA_READS_PER_TX, () => PublicDataRead.empty()), ); - const constants = new CombinedConstantData(historicBlockData, txContext); + const constants = new CombinedConstantData(blockHeader, txContext); const kernelPublicInputs = new KernelCircuitPublicInputs(combinedAccumulatedData, constants, true); diff --git a/yarn-project/noir-protocol-circuits/src/noir_test_gen.test.ts b/yarn-project/noir-protocol-circuits/src/noir_test_gen.test.ts index 9449c90f6d8d..aada805f27ac 100644 --- a/yarn-project/noir-protocol-circuits/src/noir_test_gen.test.ts +++ b/yarn-project/noir-protocol-circuits/src/noir_test_gen.test.ts @@ -90,7 +90,7 @@ describe('Data generation for noir tests', () => { }).toMatchSnapshot(); }); - it('Computes a private data tree', async () => { + it('Computes a note hash tree', async () => { const indexes = new Array(128).fill(null).map((_, i) => BigInt(i)); const leaves = indexes.map(i => new Fr(i + 1n).toBuffer()); diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts index 93bf57ae9405..f9cd72f820e3 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.test.ts @@ -1,11 +1,11 @@ import { AztecAddress, + BlockHeader, ContractDeploymentData, EthAddress, Fr, FunctionData, FunctionSelector, - HistoricBlockData, Point, TxContext, } from '@aztec/circuits.js'; @@ -13,6 +13,8 @@ import { import { mapAztecAddressFromNoir, mapAztecAddressToNoir, + mapBlockHeaderFromNoir, + mapBlockHeaderToNoir, mapContractDeploymentDataFromNoir, mapContractDeploymentDataToNoir, mapEthAddressFromNoir, @@ -23,8 +25,6 @@ import { mapFunctionDataToNoir, mapFunctionSelectorFromNoir, mapFunctionSelectorToNoir, - mapHistoricalBlockDataFromNoir, - mapHistoricalBlockDataToNoir, mapPointFromNoir, mapPointToNoir, mapTxContextFromNoir, @@ -85,8 +85,8 @@ describe('Noir<>Circuits.js type conversion test suite', () => { expect(mapFunctionDataFromNoir(mapFunctionDataToNoir(functionData))).toEqual(functionData); }); - it('should map historical block data', () => { - const historicalBlockData = new HistoricBlockData( + it('should map block header', () => { + const blockHeader = new BlockHeader( new Fr(35n), new Fr(36n), new Fr(37n), @@ -96,9 +96,7 @@ describe('Noir<>Circuits.js type conversion test suite', () => { new Fr(41n), new Fr(42n), ); - expect(mapHistoricalBlockDataFromNoir(mapHistoricalBlockDataToNoir(historicalBlockData))).toEqual( - historicalBlockData, - ); + expect(mapBlockHeaderFromNoir(mapBlockHeaderToNoir(blockHeader))).toEqual(blockHeader); }); }); }); diff --git a/yarn-project/noir-protocol-circuits/src/type_conversion.ts b/yarn-project/noir-protocol-circuits/src/type_conversion.ts index 8a539742be1f..e42a3cceb562 100644 --- a/yarn-project/noir-protocol-circuits/src/type_conversion.ts +++ b/yarn-project/noir-protocol-circuits/src/type_conversion.ts @@ -2,8 +2,10 @@ import { AggregationObject, AppendOnlyTreeSnapshot, AztecAddress, + BLOCKS_TREE_HEIGHT, BaseOrMergeRollupPublicInputs, BaseRollupInputs, + BlockHeader, CallContext, CallRequest, CallerContext, @@ -19,8 +21,6 @@ import { FunctionData, FunctionSelector, GlobalVariables, - HISTORIC_BLOCKS_TREE_HEIGHT, - HistoricBlockData, KernelCircuitPublicInputs, KernelCircuitPublicInputsFinal, MAX_NEW_COMMITMENTS_PER_TX, @@ -64,6 +64,7 @@ import { import { Tuple } from '@aztec/foundation/serialize'; import { + BlockHeader as BlockHeaderNoir, CallContext as CallContextNoir, CallRequest as CallRequestNoir, CallerContext as CallerContextNoir, @@ -75,7 +76,6 @@ import { FunctionData as FunctionDataNoir, FunctionLeafMembershipWitness as FunctionLeafMembershipWitnessNoir, FunctionSelector as FunctionSelectorNoir, - HistoricalBlockData as HistoricalBlockDataNoir, KernelCircuitPublicInputs as KernelCircuitPublicInputsNoir, NewContractData as NewContractDataNoir, Address as NoirAztecAddress, @@ -112,7 +112,7 @@ import { } from './types/public_kernel_private_previous_types.js'; import { BaseRollupInputs as BaseRollupInputsNoir, - HistoricBlocksTreeRootMembershipWitness as HistoricBlocksTreeRootMembershipWitnessNoir, + BlocksTreeRootMembershipWitness as BlocksTreeRootMembershipWitnessNoir, NullifierLeafPreimage as NullifierLeafPreimageNoir, NullifierMembershipWitness as NullifierMembershipWitnessNoir, } from './types/rollup_base_types.js'; @@ -433,40 +433,40 @@ export function mapCallRequestToNoir(callRequest: CallRequest): CallRequestNoir } /** - * Maps a historical block data to a noir historical block data. - * @param historicalBlockData - The historical block data. - * @returns The noir historical block data. + * Maps a block header to a noir block header. + * @param blockHeader - The block header. + * @returns The noir block header. */ -export function mapHistoricalBlockDataToNoir(historicalBlockData: HistoricBlockData): HistoricalBlockDataNoir { +export function mapBlockHeaderToNoir(blockHeader: BlockHeader): BlockHeaderNoir { return { - blocks_tree_root: mapFieldToNoir(historicalBlockData.blocksTreeRoot), + blocks_tree_root: mapFieldToNoir(blockHeader.blocksTreeRoot), block: { - note_hash_tree_root: mapFieldToNoir(historicalBlockData.noteHashTreeRoot), - nullifier_tree_root: mapFieldToNoir(historicalBlockData.nullifierTreeRoot), - contract_tree_root: mapFieldToNoir(historicalBlockData.contractTreeRoot), - l1_to_l2_messages_tree_root: mapFieldToNoir(historicalBlockData.l1ToL2MessagesTreeRoot), - public_data_tree_root: mapFieldToNoir(historicalBlockData.publicDataTreeRoot), - global_variables_hash: mapFieldToNoir(historicalBlockData.globalVariablesHash), + note_hash_tree_root: mapFieldToNoir(blockHeader.noteHashTreeRoot), + nullifier_tree_root: mapFieldToNoir(blockHeader.nullifierTreeRoot), + contract_tree_root: mapFieldToNoir(blockHeader.contractTreeRoot), + l1_to_l2_messages_tree_root: mapFieldToNoir(blockHeader.l1ToL2MessagesTreeRoot), + public_data_tree_root: mapFieldToNoir(blockHeader.publicDataTreeRoot), + global_variables_hash: mapFieldToNoir(blockHeader.globalVariablesHash), }, - private_kernel_vk_tree_root: mapFieldToNoir(historicalBlockData.privateKernelVkTreeRoot), + private_kernel_vk_tree_root: mapFieldToNoir(blockHeader.privateKernelVkTreeRoot), }; } /** - * Maps a noir historical block data to a historical block data. - * @param historicalBlockData - The noir historical block data. - * @returns The historical block data. + * Maps a noir block header to a block header. + * @param blockHeader - The noir block header. + * @returns The block header. */ -export function mapHistoricalBlockDataFromNoir(historicalBlockData: HistoricalBlockDataNoir): HistoricBlockData { - return new HistoricBlockData( - mapFieldFromNoir(historicalBlockData.block.note_hash_tree_root), - mapFieldFromNoir(historicalBlockData.block.nullifier_tree_root), - mapFieldFromNoir(historicalBlockData.block.contract_tree_root), - mapFieldFromNoir(historicalBlockData.block.l1_to_l2_messages_tree_root), - mapFieldFromNoir(historicalBlockData.blocks_tree_root), - mapFieldFromNoir(historicalBlockData.private_kernel_vk_tree_root), - mapFieldFromNoir(historicalBlockData.block.public_data_tree_root), - mapFieldFromNoir(historicalBlockData.block.global_variables_hash), +export function mapBlockHeaderFromNoir(blockHeader: BlockHeaderNoir): BlockHeader { + return new BlockHeader( + mapFieldFromNoir(blockHeader.block.note_hash_tree_root), + mapFieldFromNoir(blockHeader.block.nullifier_tree_root), + mapFieldFromNoir(blockHeader.block.contract_tree_root), + mapFieldFromNoir(blockHeader.block.l1_to_l2_messages_tree_root), + mapFieldFromNoir(blockHeader.blocks_tree_root), + mapFieldFromNoir(blockHeader.private_kernel_vk_tree_root), + mapFieldFromNoir(blockHeader.block.public_data_tree_root), + mapFieldFromNoir(blockHeader.block.global_variables_hash), ); } @@ -511,7 +511,7 @@ export function mapPrivateCircuitPublicInputsToNoir( >, encrypted_log_preimages_length: mapFieldToNoir(privateCircuitPublicInputs.encryptedLogPreimagesLength), unencrypted_log_preimages_length: mapFieldToNoir(privateCircuitPublicInputs.unencryptedLogPreimagesLength), - historical_block_data: mapHistoricalBlockDataToNoir(privateCircuitPublicInputs.historicBlockData), + block_header: mapBlockHeaderToNoir(privateCircuitPublicInputs.blockHeader), contract_deployment_data: mapContractDeploymentDataToNoir(privateCircuitPublicInputs.contractDeploymentData), chain_id: mapFieldToNoir(privateCircuitPublicInputs.chainId), version: mapFieldToNoir(privateCircuitPublicInputs.version), @@ -894,7 +894,7 @@ export function mapCombinedAccumulatedDataToNoir( */ export function mapCombinedConstantDataFromNoir(combinedConstantData: CombinedConstantDataNoir): CombinedConstantData { return new CombinedConstantData( - mapHistoricalBlockDataFromNoir(combinedConstantData.block_data), + mapBlockHeaderFromNoir(combinedConstantData.block_header), mapTxContextFromNoir(combinedConstantData.tx_context), ); } @@ -906,7 +906,7 @@ export function mapCombinedConstantDataFromNoir(combinedConstantData: CombinedCo */ export function mapCombinedConstantDataToNoir(combinedConstantData: CombinedConstantData): CombinedConstantDataNoir { return { - block_data: mapHistoricalBlockDataToNoir(combinedConstantData.blockData), + block_header: mapBlockHeaderToNoir(combinedConstantData.blockHeader), tx_context: mapTxContextToNoir(combinedConstantData.txContext), }; } @@ -1074,9 +1074,7 @@ export function mapGlobalVariablesFromNoir(globalVariables: GlobalVariablesNoir) */ export function mapConstantRollupDataToNoir(constantRollupData: ConstantRollupData): ConstantRollupDataNoir { return { - start_historic_blocks_tree_roots_snapshot: mapAppendOnlyTreeSnapshotToNoir( - constantRollupData.startHistoricBlocksTreeRootsSnapshot, - ), + start_blocks_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(constantRollupData.startBlocksTreeSnapshot), private_kernel_vk_tree_root: mapFieldToNoir(constantRollupData.privateKernelVkTreeRoot), public_kernel_vk_tree_root: mapFieldToNoir(constantRollupData.publicKernelVkTreeRoot), base_rollup_vk_hash: mapFieldToNoir(constantRollupData.baseRollupVkHash), @@ -1110,7 +1108,7 @@ export function mapPublicCircuitPublicInputsToNoir( new_l2_to_l1_msgs: publicInputs.newL2ToL1Msgs.map(mapFieldToNoir) as FixedLengthArray, unencrypted_logs_hash: publicInputs.unencryptedLogsHash.map(mapFieldToNoir) as FixedLengthArray, unencrypted_log_preimages_length: mapFieldToNoir(publicInputs.unencryptedLogPreimagesLength), - historical_block_data: mapHistoricalBlockDataToNoir(publicInputs.historicBlockData), + block_header: mapBlockHeaderToNoir(publicInputs.blockHeader), prover_address: mapAztecAddressToNoir(publicInputs.proverAddress), }; @@ -1122,7 +1120,7 @@ export function mapPublicCircuitPublicInputsToNoir( */ export function mapConstantRollupDataFromNoir(constantRollupData: ConstantRollupDataNoir): ConstantRollupData { return new ConstantRollupData( - mapAppendOnlyTreeSnapshotFromNoir(constantRollupData.start_historic_blocks_tree_roots_snapshot), + mapAppendOnlyTreeSnapshotFromNoir(constantRollupData.start_blocks_tree_snapshot), mapFieldFromNoir(constantRollupData.private_kernel_vk_tree_root), mapFieldFromNoir(constantRollupData.public_kernel_vk_tree_root), mapFieldFromNoir(constantRollupData.base_rollup_vk_hash), @@ -1290,12 +1288,11 @@ export function mapRootRollupInputsToNoir(rootRollupInputs: RootRollupInputs): R start_l1_to_l2_messages_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir( rootRollupInputs.startL1ToL2MessagesTreeSnapshot, ), - start_historic_blocks_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir( - rootRollupInputs.startHistoricBlocksTreeSnapshot, - ), - new_historic_blocks_tree_sibling_path: rootRollupInputs.newHistoricBlocksTreeSiblingPath.map( - mapFieldToNoir, - ) as FixedLengthArray, + start_blocks_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(rootRollupInputs.startBlocksTreeSnapshot), + new_blocks_tree_sibling_path: rootRollupInputs.newBlocksTreeSiblingPath.map(mapFieldToNoir) as FixedLengthArray< + NoirField, + 16 + >, }; } @@ -1318,20 +1315,20 @@ export function mapRootRollupPublicInputsFromNoir( mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_contract_tree_snapshot), mapFieldFromNoir(rootRollupPublicInputs.start_public_data_tree_root), mapFieldFromNoir(rootRollupPublicInputs.end_public_data_tree_root), - mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.start_tree_of_historic_note_hash_tree_roots_snapshot), - mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_tree_of_historic_note_hash_tree_roots_snapshot), - mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.start_tree_of_historic_contract_tree_roots_snapshot), - mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_tree_of_historic_contract_tree_roots_snapshot), + mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.start_tree_of_historical_note_hash_tree_roots_snapshot), + mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_tree_of_historical_note_hash_tree_roots_snapshot), + mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.start_tree_of_historical_contract_tree_roots_snapshot), + mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_tree_of_historical_contract_tree_roots_snapshot), mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.start_l1_to_l2_messages_tree_snapshot), mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_l1_to_l2_messages_tree_snapshot), mapAppendOnlyTreeSnapshotFromNoir( - rootRollupPublicInputs.start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot, + rootRollupPublicInputs.start_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot, ), mapAppendOnlyTreeSnapshotFromNoir( - rootRollupPublicInputs.end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot, + rootRollupPublicInputs.end_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot, ), - mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.start_historic_blocks_tree_snapshot), - mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_historic_blocks_tree_snapshot), + mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.start_blocks_tree_snapshot), + mapAppendOnlyTreeSnapshotFromNoir(rootRollupPublicInputs.end_blocks_tree_snapshot), mapTupleFromNoir(rootRollupPublicInputs.calldata_hash, 2, mapFieldFromNoir), mapTupleFromNoir(rootRollupPublicInputs.l1_to_l2_messages_hash, 2, mapFieldFromNoir), ); @@ -1384,18 +1381,18 @@ export function mapNullifierMembershipWitnessToNoir( } /** - * Maps a membership witness of the historic blocks tree to noir. + * Maps a membership witness of the blocks tree to noir. * @param membershipWitness - The membership witness. * @returns The noir membership witness. */ -export function mapHistoricBlocksTreeRootMembershipWitnessToNoir( - membershipWitness: MembershipWitness, -): HistoricBlocksTreeRootMembershipWitnessNoir { +export function mapBlocksTreeRootMembershipWitnessToNoir( + membershipWitness: MembershipWitness, +): BlocksTreeRootMembershipWitnessNoir { return { leaf_index: membershipWitness.leafIndex.toString(), sibling_path: membershipWitness.siblingPath.map(mapFieldToNoir) as FixedLengthArray< NoirField, - typeof HISTORIC_BLOCKS_TREE_HEIGHT + typeof BLOCKS_TREE_HEIGHT >, }; } @@ -1412,7 +1409,7 @@ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupI start_nullifier_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startNullifierTreeSnapshot), start_contract_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startContractTreeSnapshot), start_public_data_tree_root: mapFieldToNoir(inputs.startPublicDataTreeRoot), - start_historic_blocks_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startHistoricBlocksTreeSnapshot), + start_blocks_tree_snapshot: mapAppendOnlyTreeSnapshotToNoir(inputs.startBlocksTreeSnapshot), sorted_new_nullifiers: inputs.sortedNewNullifiers.map(mapFieldToNoir) as FixedLengthArray, sorted_new_nullifiers_indexes: inputs.sortednewNullifiersIndexes.map(mapNumberToNoir) as FixedLengthArray< NoirField, @@ -1441,9 +1438,9 @@ export function mapBaseRollupInputsToNoir(inputs: BaseRollupInputs): BaseRollupI new_public_data_reads_sibling_paths: inputs.newPublicDataReadsSiblingPaths.map(siblingPath => siblingPath.map(mapFieldToNoir), ) as FixedLengthArray, 32>, - historic_blocks_tree_root_membership_witnesses: inputs.historicBlocksTreeRootMembershipWitnesses.map( - mapHistoricBlocksTreeRootMembershipWitnessToNoir, - ) as FixedLengthArray, + blocks_tree_root_membership_witnesses: inputs.blocksTreeRootMembershipWitnesses.map( + mapBlocksTreeRootMembershipWitnessToNoir, + ) as FixedLengthArray, constants: mapConstantRollupDataToNoir(inputs.constants), }; } diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts index 4f00c7e19537..af47e9d082f9 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_init_types.ts @@ -74,7 +74,7 @@ export interface Block { global_variables_hash: Field; } -export interface HistoricalBlockData { +export interface BlockHeader { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; @@ -96,7 +96,7 @@ export interface PrivateCircuitPublicInputs { unencrypted_logs_hash: FixedLengthArray; encrypted_log_preimages_length: Field; unencrypted_log_preimages_length: Field; - historical_block_data: HistoricalBlockData; + block_header: BlockHeader; contract_deployment_data: ContractDeploymentData; chain_id: Field; version: Field; @@ -210,7 +210,7 @@ export interface CombinedAccumulatedData { } export interface CombinedConstantData { - block_data: HistoricalBlockData; + block_header: BlockHeader; tx_context: TxContext; } diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts index e59e29b2b374..935af55a1220 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_inner_types.ts @@ -96,7 +96,7 @@ export interface Block { global_variables_hash: Field; } -export interface HistoricalBlockData { +export interface BlockHeader { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; @@ -125,7 +125,7 @@ export interface TxContext { } export interface CombinedConstantData { - block_data: HistoricalBlockData; + block_header: BlockHeader; tx_context: TxContext; } @@ -173,7 +173,7 @@ export interface PrivateCircuitPublicInputs { unencrypted_logs_hash: FixedLengthArray; encrypted_log_preimages_length: Field; unencrypted_log_preimages_length: Field; - historical_block_data: HistoricalBlockData; + block_header: BlockHeader; contract_deployment_data: ContractDeploymentData; chain_id: Field; version: Field; diff --git a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts index 67f146a9d92a..a84711e7fea4 100644 --- a/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/private_kernel_ordering_types.ts @@ -96,7 +96,7 @@ export interface Block { global_variables_hash: Field; } -export interface HistoricalBlockData { +export interface BlockHeader { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; @@ -125,7 +125,7 @@ export interface TxContext { } export interface CombinedConstantData { - block_data: HistoricalBlockData; + block_header: BlockHeader; tx_context: TxContext; } diff --git a/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts b/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts index 20dccc4b25cb..7690aca56f53 100644 --- a/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/public_kernel_private_previous_types.ts @@ -96,7 +96,7 @@ export interface Block { global_variables_hash: Field; } -export interface HistoricalBlockData { +export interface BlockHeader { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; @@ -125,7 +125,7 @@ export interface TxContext { } export interface CombinedConstantData { - block_data: HistoricalBlockData; + block_header: BlockHeader; tx_context: TxContext; } @@ -180,7 +180,7 @@ export interface PublicCircuitPublicInputs { new_l2_to_l1_msgs: FixedLengthArray; unencrypted_logs_hash: FixedLengthArray; unencrypted_log_preimages_length: Field; - historical_block_data: HistoricalBlockData; + block_header: BlockHeader; prover_address: Address; } diff --git a/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts b/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts index bb0596aff1cc..739dce883791 100644 --- a/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/public_kernel_public_previous_types.ts @@ -96,7 +96,7 @@ export interface Block { global_variables_hash: Field; } -export interface HistoricalBlockData { +export interface BlockHeader { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; @@ -125,7 +125,7 @@ export interface TxContext { } export interface CombinedConstantData { - block_data: HistoricalBlockData; + block_header: BlockHeader; tx_context: TxContext; } @@ -180,7 +180,7 @@ export interface PublicCircuitPublicInputs { new_l2_to_l1_msgs: FixedLengthArray; unencrypted_logs_hash: FixedLengthArray; unencrypted_log_preimages_length: Field; - historical_block_data: HistoricalBlockData; + block_header: BlockHeader; prover_address: Address; } diff --git a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts index 424535bad737..1c880cb2cdf8 100644 --- a/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/rollup_base_types.ts @@ -96,7 +96,7 @@ export interface Block { global_variables_hash: Field; } -export interface HistoricalBlockData { +export interface BlockHeader { blocks_tree_root: Field; block: Block; private_kernel_vk_tree_root: Field; @@ -125,7 +125,7 @@ export interface TxContext { } export interface CombinedConstantData { - block_data: HistoricalBlockData; + block_header: BlockHeader; tx_context: TxContext; } @@ -163,7 +163,7 @@ export interface NullifierMembershipWitness { sibling_path: FixedLengthArray; } -export interface HistoricBlocksTreeRootMembershipWitness { +export interface BlocksTreeRootMembershipWitness { leaf_index: Field; sibling_path: FixedLengthArray; } @@ -176,7 +176,7 @@ export interface GlobalVariables { } export interface ConstantRollupData { - start_historic_blocks_tree_roots_snapshot: AppendOnlyTreeSnapshot; + start_blocks_tree_snapshot: AppendOnlyTreeSnapshot; private_kernel_vk_tree_root: Field; public_kernel_vk_tree_root: Field; base_rollup_vk_hash: Field; @@ -190,7 +190,7 @@ export interface BaseRollupInputs { start_nullifier_tree_snapshot: AppendOnlyTreeSnapshot; start_contract_tree_snapshot: AppendOnlyTreeSnapshot; start_public_data_tree_root: Field; - start_historic_blocks_tree_snapshot: AppendOnlyTreeSnapshot; + start_blocks_tree_snapshot: AppendOnlyTreeSnapshot; sorted_new_nullifiers: FixedLengthArray; sorted_new_nullifiers_indexes: FixedLengthArray; low_nullifier_leaf_preimages: FixedLengthArray; @@ -200,7 +200,7 @@ export interface BaseRollupInputs { new_contracts_subtree_sibling_path: FixedLengthArray; new_public_data_update_requests_sibling_paths: FixedLengthArray, 32>; new_public_data_reads_sibling_paths: FixedLengthArray, 32>; - historic_blocks_tree_root_membership_witnesses: FixedLengthArray; + blocks_tree_root_membership_witnesses: FixedLengthArray; constants: ConstantRollupData; } diff --git a/yarn-project/noir-protocol-circuits/src/types/rollup_merge_types.ts b/yarn-project/noir-protocol-circuits/src/types/rollup_merge_types.ts index bf438c2c3cd2..233624ab34de 100644 --- a/yarn-project/noir-protocol-circuits/src/types/rollup_merge_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/rollup_merge_types.ts @@ -22,7 +22,7 @@ export interface GlobalVariables { } export interface ConstantRollupData { - start_historic_blocks_tree_roots_snapshot: AppendOnlyTreeSnapshot; + start_blocks_tree_snapshot: AppendOnlyTreeSnapshot; private_kernel_vk_tree_root: Field; public_kernel_vk_tree_root: Field; base_rollup_vk_hash: Field; diff --git a/yarn-project/noir-protocol-circuits/src/types/rollup_root_types.ts b/yarn-project/noir-protocol-circuits/src/types/rollup_root_types.ts index ee37cbf72ff1..63c4b01df512 100644 --- a/yarn-project/noir-protocol-circuits/src/types/rollup_root_types.ts +++ b/yarn-project/noir-protocol-circuits/src/types/rollup_root_types.ts @@ -22,7 +22,7 @@ export interface GlobalVariables { } export interface ConstantRollupData { - start_historic_blocks_tree_roots_snapshot: AppendOnlyTreeSnapshot; + start_blocks_tree_snapshot: AppendOnlyTreeSnapshot; private_kernel_vk_tree_root: Field; public_kernel_vk_tree_root: Field; base_rollup_vk_hash: Field; @@ -68,8 +68,8 @@ export interface RootRollupInputs { new_l1_to_l2_messages: FixedLengthArray; new_l1_to_l2_messages_tree_root_sibling_path: FixedLengthArray; start_l1_to_l2_messages_tree_snapshot: AppendOnlyTreeSnapshot; - start_historic_blocks_tree_snapshot: AppendOnlyTreeSnapshot; - new_historic_blocks_tree_sibling_path: FixedLengthArray; + start_blocks_tree_snapshot: AppendOnlyTreeSnapshot; + new_blocks_tree_sibling_path: FixedLengthArray; } export interface RootRollupPublicInputs { @@ -83,16 +83,16 @@ export interface RootRollupPublicInputs { end_contract_tree_snapshot: AppendOnlyTreeSnapshot; start_public_data_tree_root: Field; end_public_data_tree_root: Field; - start_tree_of_historic_note_hash_tree_roots_snapshot: AppendOnlyTreeSnapshot; - end_tree_of_historic_note_hash_tree_roots_snapshot: AppendOnlyTreeSnapshot; - start_tree_of_historic_contract_tree_roots_snapshot: AppendOnlyTreeSnapshot; - end_tree_of_historic_contract_tree_roots_snapshot: AppendOnlyTreeSnapshot; + start_tree_of_historical_note_hash_tree_roots_snapshot: AppendOnlyTreeSnapshot; + end_tree_of_historical_note_hash_tree_roots_snapshot: AppendOnlyTreeSnapshot; + start_tree_of_historical_contract_tree_roots_snapshot: AppendOnlyTreeSnapshot; + end_tree_of_historical_contract_tree_roots_snapshot: AppendOnlyTreeSnapshot; start_l1_to_l2_messages_tree_snapshot: AppendOnlyTreeSnapshot; end_l1_to_l2_messages_tree_snapshot: AppendOnlyTreeSnapshot; - start_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot: AppendOnlyTreeSnapshot; - end_tree_of_historic_l1_to_l2_messages_tree_roots_snapshot: AppendOnlyTreeSnapshot; - start_historic_blocks_tree_snapshot: AppendOnlyTreeSnapshot; - end_historic_blocks_tree_snapshot: AppendOnlyTreeSnapshot; + start_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot: AppendOnlyTreeSnapshot; + end_tree_of_historical_l1_to_l2_messages_tree_roots_snapshot: AppendOnlyTreeSnapshot; + start_blocks_tree_snapshot: AppendOnlyTreeSnapshot; + end_blocks_tree_snapshot: AppendOnlyTreeSnapshot; calldata_hash: FixedLengthArray; l1_to_l2_messages_hash: FixedLengthArray; } diff --git a/yarn-project/p2p/src/client/p2p_client.ts b/yarn-project/p2p/src/client/p2p_client.ts index 7880bf2310b2..d8baeb7ac8f9 100644 --- a/yarn-project/p2p/src/client/p2p_client.ts +++ b/yarn-project/p2p/src/client/p2p_client.ts @@ -114,7 +114,7 @@ export class P2PClient implements P2P { /** * In-memory P2P client constructor. - * @param l2BlockSource - P2P client's source for fetching existing block data. + * @param l2BlockSource - P2P client's source for fetching existing blocks. * @param txPool - The client's instance of a transaction pool. Defaults to in-memory implementation. * @param p2pService - The concrete instance of p2p networking to use. * @param log - A logger. diff --git a/yarn-project/pxe/src/database/database.ts b/yarn-project/pxe/src/database/database.ts index 906bc4bcc93f..72f50a1c5764 100644 --- a/yarn-project/pxe/src/database/database.ts +++ b/yarn-project/pxe/src/database/database.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; +import { BlockHeader, CompleteAddress, PublicKey } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { ContractDatabase, MerkleTreeId, NoteFilter } from '@aztec/types'; @@ -91,24 +91,24 @@ export interface Database extends ContractDatabase { setTreeRoots(roots: Record): Promise; /** - * Retrieve the stored Historic Block Data from the database. - * The function returns a Promise that resolves to the Historic Block Data. + * Retrieve the stored Block Header from the database. + * The function returns a Promise that resolves to the Block Header. * This data is required to reproduce block attestations. - * Throws an error if the historic block data is not available within the database. + * Throws an error if the block header is not available within the database. * * note: this data is a combination of the tree roots and the global variables hash. */ - getHistoricBlockData(): HistoricBlockData; + getBlockHeader(): BlockHeader; /** - * Set the latest Historic Block Data. + * Set the latest Block Header. * This function updates the 'global variables hash' and `tree roots` property of the instance * Note that this will overwrite any existing hash or roots in the database. * - * @param historicBlockData - An object containing the most recent historic block data. + * @param blockHeader - An object containing the most recent block header. * @returns A Promise that resolves when the hash has been successfully updated in the database. */ - setHistoricBlockData(historicBlockData: HistoricBlockData): Promise; + setBlockHeader(blockHeader: BlockHeader): Promise; /** * Adds complete address to the database. diff --git a/yarn-project/pxe/src/database/memory_db.ts b/yarn-project/pxe/src/database/memory_db.ts index 88f98601c3b6..b0562f0ceb6a 100644 --- a/yarn-project/pxe/src/database/memory_db.ts +++ b/yarn-project/pxe/src/database/memory_db.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; +import { BlockHeader, CompleteAddress, PublicKey } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -118,12 +118,12 @@ export class MemoryDB extends MemoryContractDatabase implements Database { return Promise.resolve(); } - public getHistoricBlockData(): HistoricBlockData { + public getBlockHeader(): BlockHeader { const roots = this.getTreeRoots(); if (!this.globalVariablesHash) { throw new Error(`Global variables hash not set in memory database`); } - return new HistoricBlockData( + return new BlockHeader( roots[MerkleTreeId.NOTE_HASH_TREE], roots[MerkleTreeId.NULLIFIER_TREE], roots[MerkleTreeId.CONTRACT_TREE], @@ -135,15 +135,15 @@ export class MemoryDB extends MemoryContractDatabase implements Database { ); } - public async setHistoricBlockData(historicBlockData: HistoricBlockData): Promise { - this.globalVariablesHash = historicBlockData.globalVariablesHash; + public async setBlockHeader(blockHeader: BlockHeader): Promise { + this.globalVariablesHash = blockHeader.globalVariablesHash; await this.setTreeRoots({ - [MerkleTreeId.NOTE_HASH_TREE]: historicBlockData.noteHashTreeRoot, - [MerkleTreeId.NULLIFIER_TREE]: historicBlockData.nullifierTreeRoot, - [MerkleTreeId.CONTRACT_TREE]: historicBlockData.contractTreeRoot, - [MerkleTreeId.L1_TO_L2_MESSAGES_TREE]: historicBlockData.l1ToL2MessagesTreeRoot, - [MerkleTreeId.BLOCKS_TREE]: historicBlockData.blocksTreeRoot, - [MerkleTreeId.PUBLIC_DATA_TREE]: historicBlockData.publicDataTreeRoot, + [MerkleTreeId.NOTE_HASH_TREE]: blockHeader.noteHashTreeRoot, + [MerkleTreeId.NULLIFIER_TREE]: blockHeader.nullifierTreeRoot, + [MerkleTreeId.CONTRACT_TREE]: blockHeader.contractTreeRoot, + [MerkleTreeId.L1_TO_L2_MESSAGES_TREE]: blockHeader.l1ToL2MessagesTreeRoot, + [MerkleTreeId.BLOCKS_TREE]: blockHeader.blocksTreeRoot, + [MerkleTreeId.PUBLIC_DATA_TREE]: blockHeader.publicDataTreeRoot, }); } diff --git a/yarn-project/pxe/src/note_processor/note_processor.ts b/yarn-project/pxe/src/note_processor/note_processor.ts index c3a57994f489..0f07830436f8 100644 --- a/yarn-project/pxe/src/note_processor/note_processor.ts +++ b/yarn-project/pxe/src/note_processor/note_processor.ts @@ -16,7 +16,7 @@ import { getAcirSimulator } from '../simulator/index.js'; */ interface ProcessedData { /** - * Holds L2 block data and associated context. + * Holds L2 block and a cache of already requested tx hashes. */ blockContext: L2BlockContext; /** diff --git a/yarn-project/pxe/src/pxe_service/pxe_service.ts b/yarn-project/pxe/src/pxe_service/pxe_service.ts index fc0bb37c78e3..8d781c1d2cdd 100644 --- a/yarn-project/pxe/src/pxe_service/pxe_service.ts +++ b/yarn-project/pxe/src/pxe_service/pxe_service.ts @@ -449,10 +449,10 @@ export class PXEService implements PXE { /** * Retrieves the simulation parameters required to run an ACIR simulation. - * This includes the contract address, function artifact, portal contract address, and historic tree roots. + * This includes the contract address, function artifact, portal contract address, and historical tree roots. * * @param execRequest - The transaction request object containing details of the contract call. - * @returns An object containing the contract address, function artifact, portal contract address, and historic tree roots. + * @returns An object containing the contract address, function artifact, portal contract address, and historical tree roots. */ async #getSimulationParameters(execRequest: FunctionCall | TxExecutionRequest) { const contractAddress = (execRequest as FunctionCall).to ?? (execRequest as TxExecutionRequest).origin; diff --git a/yarn-project/pxe/src/simulator_oracle/index.ts b/yarn-project/pxe/src/simulator_oracle/index.ts index 42c3edd74c4e..2c1f571612a6 100644 --- a/yarn-project/pxe/src/simulator_oracle/index.ts +++ b/yarn-project/pxe/src/simulator_oracle/index.ts @@ -1,12 +1,12 @@ import { DBOracle, FunctionArtifactWithDebugMetadata, MessageLoadOracleInputs } from '@aztec/acir-simulator'; import { AztecAddress, + BlockHeader, CompleteAddress, EthAddress, Fr, FunctionSelector, GrumpkinPrivateKey, - HistoricBlockData, PublicKey, } from '@aztec/circuits.js'; import { createDebugLogger } from '@aztec/foundation/log'; @@ -152,7 +152,7 @@ export class SimulatorOracle implements DBOracle { case MerkleTreeId.NOTE_HASH_TREE: return (await this.stateInfoProvider.getNoteHashSiblingPath(leafIndex)).toFieldArray(); case MerkleTreeId.BLOCKS_TREE: - return (await this.stateInfoProvider.getHistoricBlocksTreeSiblingPath(leafIndex)).toFieldArray(); + return (await this.stateInfoProvider.getBlocksTreeSiblingPath(leafIndex)).toFieldArray(); case MerkleTreeId.PUBLIC_DATA_TREE: return (await this.stateInfoProvider.getPublicDataTreeSiblingPath(leafIndex)).toFieldArray(); default: @@ -179,12 +179,12 @@ export class SimulatorOracle implements DBOracle { } /** - * Retrieve the databases view of the Historic Block Data object. - * This structure is fed into the circuits simulator and is used to prove against certain historic roots. + * Retrieve the databases view of the Block Header object. + * This structure is fed into the circuits simulator and is used to prove against certain historical roots. * - * @returns A Promise that resolves to a HistoricBlockData object. + * @returns A Promise that resolves to a BlockHeader object. */ - getHistoricBlockData(): Promise { - return Promise.resolve(this.db.getHistoricBlockData()); + getBlockHeader(): Promise { + return Promise.resolve(this.db.getBlockHeader()); } } diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts index 2179fecc524a..6ee3071712c4 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.test.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.test.ts @@ -1,4 +1,4 @@ -import { CompleteAddress, Fr, GrumpkinScalar, HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader, CompleteAddress, Fr, GrumpkinScalar } from '@aztec/circuits.js'; import { Grumpkin } from '@aztec/circuits.js/barretenberg'; import { TestKeyStore } from '@aztec/key-store'; import { AztecNode, INITIAL_L2_BLOCK_NUM, L2Block, MerkleTreeId } from '@aztec/types'; @@ -14,17 +14,17 @@ describe('Synchronizer', () => { let database: Database; let synchronizer: TestSynchronizer; let roots: Record; - let blockData: HistoricBlockData; + let blockHeader: BlockHeader; beforeEach(() => { - blockData = HistoricBlockData.random(); + blockHeader = BlockHeader.random(); roots = { - [MerkleTreeId.CONTRACT_TREE]: blockData.contractTreeRoot, - [MerkleTreeId.NOTE_HASH_TREE]: blockData.noteHashTreeRoot, - [MerkleTreeId.NULLIFIER_TREE]: blockData.nullifierTreeRoot, - [MerkleTreeId.PUBLIC_DATA_TREE]: blockData.publicDataTreeRoot, - [MerkleTreeId.L1_TO_L2_MESSAGES_TREE]: blockData.l1ToL2MessagesTreeRoot, - [MerkleTreeId.BLOCKS_TREE]: blockData.blocksTreeRoot, + [MerkleTreeId.CONTRACT_TREE]: blockHeader.contractTreeRoot, + [MerkleTreeId.NOTE_HASH_TREE]: blockHeader.noteHashTreeRoot, + [MerkleTreeId.NULLIFIER_TREE]: blockHeader.nullifierTreeRoot, + [MerkleTreeId.PUBLIC_DATA_TREE]: blockHeader.publicDataTreeRoot, + [MerkleTreeId.L1_TO_L2_MESSAGES_TREE]: blockHeader.l1ToL2MessagesTreeRoot, + [MerkleTreeId.BLOCKS_TREE]: blockHeader.blocksTreeRoot, }; aztecNode = mock(); @@ -34,7 +34,7 @@ describe('Synchronizer', () => { it('sets tree roots from aztec node on initial sync', async () => { aztecNode.getBlockNumber.mockResolvedValue(3); - aztecNode.getHistoricBlockData.mockResolvedValue(blockData); + aztecNode.getBlockHeader.mockResolvedValue(blockHeader); await synchronizer.initialSync(); @@ -55,7 +55,7 @@ describe('Synchronizer', () => { it('overrides tree roots from initial sync once current block number is larger', async () => { // Initial sync is done on block with height 3 aztecNode.getBlockNumber.mockResolvedValue(3); - aztecNode.getHistoricBlockData.mockResolvedValue(blockData); + aztecNode.getBlockHeader.mockResolvedValue(blockHeader); await synchronizer.initialSync(); const roots0 = database.getTreeRoots(); diff --git a/yarn-project/pxe/src/synchronizer/synchronizer.ts b/yarn-project/pxe/src/synchronizer/synchronizer.ts index 524fddd2a3e1..98dfd30c7e63 100644 --- a/yarn-project/pxe/src/synchronizer/synchronizer.ts +++ b/yarn-project/pxe/src/synchronizer/synchronizer.ts @@ -1,4 +1,4 @@ -import { AztecAddress, Fr, HistoricBlockData, PublicKey } from '@aztec/circuits.js'; +import { AztecAddress, BlockHeader, Fr, PublicKey } from '@aztec/circuits.js'; import { computeGlobalsHash } from '@aztec/circuits.js/abis'; import { DebugLogger, createDebugLogger } from '@aztec/foundation/log'; import { InterruptibleSleep } from '@aztec/foundation/sleep'; @@ -68,13 +68,10 @@ export class Synchronizer { } protected async initialSync() { - const [blockNumber, historicBlockData] = await Promise.all([ - this.node.getBlockNumber(), - this.node.getHistoricBlockData(), - ]); + const [blockNumber, blockHeader] = await Promise.all([this.node.getBlockNumber(), this.node.getBlockHeader()]); this.initialSyncBlockNumber = blockNumber; this.synchedToBlock = this.initialSyncBlockNumber; - await this.db.setHistoricBlockData(historicBlockData); + await this.db.setBlockHeader(blockHeader); } protected async work(limit = 1, retryInterval = 1000): Promise { @@ -204,18 +201,18 @@ export class Synchronizer { } const globalsHash = computeGlobalsHash(latestBlock.block.globalVariables); - const blockData = new HistoricBlockData( + const blockHeader = new BlockHeader( block.endNoteHashTreeSnapshot.root, block.endNullifierTreeSnapshot.root, block.endContractTreeSnapshot.root, block.endL1ToL2MessagesTreeSnapshot.root, - block.endHistoricBlocksTreeSnapshot.root, + block.endBlocksTreeSnapshot.root, Fr.ZERO, // todo: private kernel vk tree root block.endPublicDataTreeRoot, globalsHash, ); - await this.db.setHistoricBlockData(blockData); + await this.db.setBlockHeader(blockHeader); } /** diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts index ea943c691207..808e02f6cae5 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.test.ts @@ -54,10 +54,10 @@ import { EmptyRollupProver } from '../prover/empty.js'; import { RollupProver } from '../prover/index.js'; import { ProcessedTx, - makeEmptyProcessedTx as makeEmptyProcessedTxFromHistoricTreeRoots, + makeEmptyProcessedTx as makeEmptyProcessedTxFromHistoricalTreeRoots, makeProcessedTx, } from '../sequencer/processed_tx.js'; -import { getHistoricBlockData } from '../sequencer/utils.js'; +import { getBlockHeader } from '../sequencer/utils.js'; import { RollupSimulator } from '../simulator/index.js'; import { RealRollupCircuitSimulator } from '../simulator/rollup.js'; import { SoloBlockBuilder } from './solo_block_builder.js'; @@ -115,8 +115,8 @@ describe('sequencer/solo_block_builder', () => { }, 20_000); const makeEmptyProcessedTx = async () => { - const historicTreeRoots = await getHistoricBlockData(builderDb); - return makeEmptyProcessedTxFromHistoricTreeRoots(historicTreeRoots, chainId, version); + const historicalTreeRoots = await getBlockHeader(builderDb); + return makeEmptyProcessedTxFromHistoricalTreeRoots(historicalTreeRoots, chainId, version); }; // Updates the expectedDb trees based on the new commitments, contracts, and nullifiers from these txs @@ -143,7 +143,7 @@ describe('sequencer/solo_block_builder', () => { await expectsDb.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGES_TREE, asBuffer); }; - const updateHistoricBlocksTree = async () => { + const updateBlocksTree = async () => { const blockHash = computeBlockHashWithGlobals( globalVariables, rootRollupOutput.endNoteHashTreeSnapshot.root, @@ -162,7 +162,7 @@ describe('sequencer/solo_block_builder', () => { const buildMockSimulatorInputs = async () => { const kernelOutput = makePrivateKernelPublicInputsFinal(); - kernelOutput.constants.blockData = await getHistoricBlockData(expectsDb); + kernelOutput.constants.blockHeader = await getBlockHeader(expectsDb); const tx = await makeProcessedTx( new Tx( @@ -204,8 +204,8 @@ describe('sequencer/solo_block_builder', () => { // Calculate block hash rootRollupOutput.globalVariables = globalVariables; - await updateHistoricBlocksTree(); - rootRollupOutput.endHistoricBlocksTreeSnapshot = await getTreeSnapshot(MerkleTreeId.BLOCKS_TREE); + await updateBlocksTree(); + rootRollupOutput.endBlocksTreeSnapshot = await getTreeSnapshot(MerkleTreeId.BLOCKS_TREE); const txs = [...txsLeft, ...txsRight]; @@ -235,8 +235,8 @@ describe('sequencer/solo_block_builder', () => { endPublicDataTreeRoot: rootRollupOutput.endPublicDataTreeRoot, startL1ToL2MessagesTreeSnapshot: rootRollupOutput.startL1ToL2MessagesTreeSnapshot, endL1ToL2MessagesTreeSnapshot: rootRollupOutput.endL1ToL2MessagesTreeSnapshot, - startHistoricBlocksTreeSnapshot: rootRollupOutput.startHistoricBlocksTreeSnapshot, - endHistoricBlocksTreeSnapshot: rootRollupOutput.endHistoricBlocksTreeSnapshot, + startBlocksTreeSnapshot: rootRollupOutput.startBlocksTreeSnapshot, + endBlocksTreeSnapshot: rootRollupOutput.endBlocksTreeSnapshot, newCommitments, newNullifiers, newContracts, @@ -298,7 +298,7 @@ describe('sequencer/solo_block_builder', () => { const makeBloatedProcessedTx = async (seed = 0x1) => { const tx = mockTx(seed); const kernelOutput = KernelCircuitPublicInputs.empty(); - kernelOutput.constants.blockData = await getHistoricBlockData(builderDb); + kernelOutput.constants.blockHeader = await getBlockHeader(builderDb); kernelOutput.end.publicDataUpdateRequests = makeTuple( MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX, i => new PublicDataUpdateRequest(fr(i), fr(0), fr(i + 10)), diff --git a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts index 464e766a69eb..06976b2f2099 100644 --- a/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts +++ b/yarn-project/sequencer-client/src/block_builder/solo_block_builder.ts @@ -1,12 +1,12 @@ import { AppendOnlyTreeSnapshot, + BLOCKS_TREE_HEIGHT, BaseOrMergeRollupPublicInputs, BaseRollupInputs, CONTRACT_SUBTREE_HEIGHT, CONTRACT_SUBTREE_SIBLING_PATH_LENGTH, ConstantRollupData, GlobalVariables, - HISTORIC_BLOCKS_TREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_HEIGHT, L1_TO_L2_MSG_SUBTREE_SIBLING_PATH_LENGTH, MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, @@ -103,7 +103,7 @@ export class SoloBlockBuilder implements BlockBuilder { startContractTreeSnapshot, startPublicDataTreeSnapshot, startL1ToL2MessageTreeSnapshot, - startHistoricBlocksTreeSnapshot, + startBlocksTreeSnapshot, ] = await Promise.all( [ MerkleTreeId.NOTE_HASH_TREE, @@ -127,7 +127,7 @@ export class SoloBlockBuilder implements BlockBuilder { endContractTreeSnapshot, endPublicDataTreeRoot, endL1ToL2MessagesTreeSnapshot, - endHistoricBlocksTreeSnapshot, + endBlocksTreeSnapshot, } = circuitsOutput; // Collect all new nullifiers, commitments, and contracts from all txs in this block @@ -167,8 +167,8 @@ export class SoloBlockBuilder implements BlockBuilder { endPublicDataTreeRoot, startL1ToL2MessagesTreeSnapshot: startL1ToL2MessageTreeSnapshot, endL1ToL2MessagesTreeSnapshot, - startHistoricBlocksTreeSnapshot, - endHistoricBlocksTreeSnapshot, + startBlocksTreeSnapshot, + endBlocksTreeSnapshot, newCommitments, newNullifiers, newL2ToL1Msgs, @@ -193,14 +193,14 @@ export class SoloBlockBuilder implements BlockBuilder { protected validateTxs(txs: ProcessedTx[]) { for (const tx of txs) { - for (const historicTreeRoot of [ + for (const historicalTreeRoot of [ 'noteHashTreeRoot', 'contractTreeRoot', 'nullifierTreeRoot', 'l1ToL2MessagesTreeRoot', ] as const) { - if (tx.data.constants.blockData[historicTreeRoot].isZero()) { - throw new Error(`Empty ${historicTreeRoot} for tx: ${toFriendlyJSON(tx)}`); + if (tx.data.constants.blockHeader[historicalTreeRoot].isZero()) { + throw new Error(`Empty ${historicalTreeRoot} for tx: ${toFriendlyJSON(tx)}`); } } } @@ -313,15 +313,15 @@ export class SoloBlockBuilder implements BlockBuilder { this.debug(`Updating and validating root trees`); const globalVariablesHash = computeGlobalsHash(left[0].constants.globalVariables); await this.db.updateLatestGlobalVariablesHash(globalVariablesHash); - await this.db.updateHistoricBlocksTree(globalVariablesHash); + await this.db.updateBlocksTree(globalVariablesHash); await this.validateRootOutput(rootOutput); return [rootOutput, rootProof]; } - async updateHistoricBlocksTree(globalVariables: GlobalVariables) { - // Calculate the block hash and add it to the historic block hashes tree + async updateBlocksTree(globalVariables: GlobalVariables) { + // Calculate the block hash and add it to the historical block hashes tree const blockHash = await this.calculateBlockHash(globalVariables); await this.db.appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]); } @@ -364,7 +364,7 @@ export class SoloBlockBuilder implements BlockBuilder { protected async validateRootOutput(rootOutput: RootRollupPublicInputs) { await Promise.all([ this.validateTrees(rootOutput), - this.validateTree(rootOutput, MerkleTreeId.BLOCKS_TREE, 'HistoricBlocks'), + this.validateTree(rootOutput, MerkleTreeId.BLOCKS_TREE, 'Blocks'), this.validateTree(rootOutput, MerkleTreeId.L1_TO_L2_MESSAGES_TREE, 'L1ToL2Messages'), ]); } @@ -376,7 +376,7 @@ export class SoloBlockBuilder implements BlockBuilder { name: 'Contract' | 'NoteHash' | 'L1ToL2Messages', ) { const localTree = await this.getTreeSnapshot(treeId); - const simulatedTree = rootOutput[`endTreeOfHistoric${name}TreeRootsSnapshot`]; + const simulatedTree = rootOutput[`endTreeOfHistorical${name}TreeRootsSnapshot`]; this.validateSimulatedTree(localTree, simulatedTree, name, `Roots ${name}`); } @@ -414,7 +414,7 @@ export class SoloBlockBuilder implements BlockBuilder { protected validateSimulatedTree( localTree: AppendOnlyTreeSnapshot, simulatedTree: AppendOnlyTreeSnapshot, - name: 'NoteHash' | 'Contract' | 'Nullifier' | 'L1ToL2Messages' | 'HistoricBlocks', + name: 'NoteHash' | 'Contract' | 'Nullifier' | 'L1ToL2Messages' | 'Blocks', label?: string, ) { if (!simulatedTree.root.toBuffer().equals(localTree.root.toBuffer())) { @@ -466,13 +466,13 @@ export class SoloBlockBuilder implements BlockBuilder { // Get tree snapshots const startL1ToL2MessagesTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.L1_TO_L2_MESSAGES_TREE); - // Get historic block tree roots - const startHistoricBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE); - const newHistoricBlocksTreeSiblingPathArray = await getRootTreeSiblingPath(MerkleTreeId.BLOCKS_TREE); + // Get blocks tree + const startBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE); + const newBlocksTreeSiblingPathArray = await getRootTreeSiblingPath(MerkleTreeId.BLOCKS_TREE); - const newHistoricBlocksTreeSiblingPath = makeTuple( - HISTORIC_BLOCKS_TREE_HEIGHT, - i => (i < newHistoricBlocksTreeSiblingPathArray.length ? newHistoricBlocksTreeSiblingPathArray[i] : Fr.ZERO), + const newBlocksTreeSiblingPath = makeTuple( + BLOCKS_TREE_HEIGHT, + i => (i < newBlocksTreeSiblingPathArray.length ? newBlocksTreeSiblingPathArray[i] : Fr.ZERO), 0, ); @@ -481,8 +481,8 @@ export class SoloBlockBuilder implements BlockBuilder { newL1ToL2Messages, newL1ToL2MessagesTreeRootSiblingPath, startL1ToL2MessagesTreeSnapshot, - startHistoricBlocksTreeSnapshot, - newHistoricBlocksTreeSiblingPath, + startBlocksTreeSnapshot, + newBlocksTreeSiblingPath, }); } @@ -539,19 +539,19 @@ export class SoloBlockBuilder implements BlockBuilder { return new MembershipWitness(height, index, assertLength(path.toFieldArray(), height)); } - protected getHistoricTreesMembershipWitnessFor(tx: ProcessedTx) { - const blockData = tx.data.constants.blockData; + protected getHistoricalTreesMembershipWitnessFor(tx: ProcessedTx) { + const blockHeader = tx.data.constants.blockHeader; const { noteHashTreeRoot, nullifierTreeRoot, contractTreeRoot, l1ToL2MessagesTreeRoot, publicDataTreeRoot } = - blockData; + blockHeader; const blockHash = computeBlockHash( - blockData.globalVariablesHash, + blockHeader.globalVariablesHash, noteHashTreeRoot, nullifierTreeRoot, contractTreeRoot, l1ToL2MessagesTreeRoot, publicDataTreeRoot, ); - return this.getMembershipWitnessFor(blockHash, MerkleTreeId.BLOCKS_TREE, HISTORIC_BLOCKS_TREE_HEIGHT); + return this.getMembershipWitnessFor(blockHash, MerkleTreeId.BLOCKS_TREE, BLOCKS_TREE_HEIGHT); } protected async getConstantRollupData(globalVariables: GlobalVariables): Promise { @@ -560,7 +560,7 @@ export class SoloBlockBuilder implements BlockBuilder { mergeRollupVkHash: DELETE_FR, privateKernelVkTreeRoot: FUTURE_FR, publicKernelVkTreeRoot: FUTURE_FR, - startHistoricBlocksTreeRootsSnapshot: await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE), + startBlocksTreeSnapshot: await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE), globalVariables, }); } @@ -651,7 +651,7 @@ export class SoloBlockBuilder implements BlockBuilder { const startContractTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.CONTRACT_TREE); const startNoteHashTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.NOTE_HASH_TREE); const startPublicDataTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.PUBLIC_DATA_TREE); - const startHistoricBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE); + const startBlocksTreeSnapshot = await this.getTreeSnapshot(MerkleTreeId.BLOCKS_TREE); // Get the subtree sibling paths for the circuit const newCommitmentsSubtreeSiblingPathArray = await this.getSubtreeSiblingPath( @@ -736,7 +736,7 @@ export class SoloBlockBuilder implements BlockBuilder { startContractTreeSnapshot, startNoteHashTreeSnapshot, startPublicDataTreeRoot: startPublicDataTreeSnapshot.root, - startHistoricBlocksTreeSnapshot, + startBlocksTreeSnapshot, sortedNewNullifiers: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => Fr.fromBuffer(sortedNewNullifiers[i])), sortednewNullifiersIndexes: makeTuple(MAX_NEW_NULLIFIERS_PER_BASE_ROLLUP, i => sortednewNullifiersIndexes[i]), newCommitmentsSubtreeSiblingPath, @@ -761,9 +761,9 @@ export class SoloBlockBuilder implements BlockBuilder { : this.makeEmptyMembershipWitness(NULLIFIER_TREE_HEIGHT), ), kernelData: [this.getKernelDataFor(left), this.getKernelDataFor(right)], - historicBlocksTreeRootMembershipWitnesses: [ - await this.getHistoricTreesMembershipWitnessFor(left), - await this.getHistoricTreesMembershipWitnessFor(right), + blocksTreeRootMembershipWitnesses: [ + await this.getHistoricalTreesMembershipWitnessFor(left), + await this.getHistoricalTreesMembershipWitnessFor(right), ], }); } diff --git a/yarn-project/sequencer-client/src/block_builder/types.ts b/yarn-project/sequencer-client/src/block_builder/types.ts index b909dbc17212..b39f0a90a17b 100644 --- a/yarn-project/sequencer-client/src/block_builder/types.ts +++ b/yarn-project/sequencer-client/src/block_builder/types.ts @@ -5,7 +5,7 @@ import { AppendOnlyTreeSnapshot, BaseOrMergeRollupPublicInputs, RootRollupPublic */ export type AllowedTreeNames = T extends RootRollupPublicInputs - ? 'NoteHash' | 'Contract' | 'Nullifier' | 'L1ToL2Messages' | 'HistoricBlocks' + ? 'NoteHash' | 'Contract' | 'Nullifier' | 'L1ToL2Messages' | 'Blocks' : 'NoteHash' | 'Contract' | 'Nullifier'; /** diff --git a/yarn-project/sequencer-client/src/sequencer/processed_tx.ts b/yarn-project/sequencer-client/src/sequencer/processed_tx.ts index 508981f981d9..b3d098acb476 100644 --- a/yarn-project/sequencer-client/src/sequencer/processed_tx.ts +++ b/yarn-project/sequencer-client/src/sequencer/processed_tx.ts @@ -1,7 +1,7 @@ import { + BlockHeader, CombinedAccumulatedData, Fr, - HistoricBlockData, Proof, PublicKernelPublicInputs, makeEmptyProof, @@ -87,13 +87,9 @@ export async function makeProcessedTx( * Makes an empty tx from an empty kernel circuit public inputs. * @returns A processed empty tx. */ -export function makeEmptyProcessedTx( - historicTreeRoots: HistoricBlockData, - chainId: Fr, - version: Fr, -): Promise { +export function makeEmptyProcessedTx(historicalTreeRoots: BlockHeader, chainId: Fr, version: Fr): Promise { const emptyKernelOutput = PublicKernelPublicInputs.empty(); - emptyKernelOutput.constants.blockData = historicTreeRoots; + emptyKernelOutput.constants.blockHeader = historicalTreeRoots; emptyKernelOutput.constants.txContext.chainId = chainId; emptyKernelOutput.constants.txContext.version = version; const emptyProof = makeEmptyProof(); diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts index 621018a04595..382730e4c365 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.test.ts @@ -2,6 +2,7 @@ import { PublicExecution, PublicExecutionResult, PublicExecutor } from '@aztec/a import { ARGS_LENGTH, AztecAddress, + BlockHeader, CallContext, CallRequest, CombinedAccumulatedData, @@ -9,7 +10,6 @@ import { Fr, FunctionData, GlobalVariables, - HistoricBlockData, MAX_PRIVATE_CALL_STACK_LENGTH_PER_TX, MAX_PUBLIC_CALL_STACK_LENGTH_PER_TX, PUBLIC_DATA_TREE_HEIGHT, @@ -85,7 +85,7 @@ describe('public_processor', () => { publicKernel, publicProver, GlobalVariables.empty(), - HistoricBlockData.empty(), + BlockHeader.empty(), publicContractsDB, publicWorldStateDB, ); @@ -140,7 +140,7 @@ describe('public_processor', () => { publicKernel, publicProver, GlobalVariables.empty(), - HistoricBlockData.empty(), + BlockHeader.empty(), publicContractsDB, publicWorldStateDB, ); diff --git a/yarn-project/sequencer-client/src/sequencer/public_processor.ts b/yarn-project/sequencer-client/src/sequencer/public_processor.ts index e243f5c82e53..820da1cf0c67 100644 --- a/yarn-project/sequencer-client/src/sequencer/public_processor.ts +++ b/yarn-project/sequencer-client/src/sequencer/public_processor.ts @@ -9,13 +9,13 @@ import { } from '@aztec/acir-simulator'; import { AztecAddress, + BlockHeader, CallRequest, CombinedAccumulatedData, ContractStorageRead, ContractStorageUpdateRequest, Fr, GlobalVariables, - HistoricBlockData, KernelCircuitPublicInputs, MAX_NEW_COMMITMENTS_PER_CALL, MAX_NEW_L2_TO_L1_MSGS_PER_CALL, @@ -52,7 +52,7 @@ import { PublicKernelCircuitSimulator } from '../simulator/index.js'; import { ContractsDataSourcePublicDB, WorldStateDB, WorldStatePublicDB } from '../simulator/public_executor.js'; import { RealPublicKernelCircuitSimulator } from '../simulator/public_kernel.js'; import { FailedTx, ProcessedTx, makeEmptyProcessedTx, makeProcessedTx } from './processed_tx.js'; -import { getHistoricBlockData } from './utils.js'; +import { getBlockHeader } from './utils.js'; /** * Creates new instances of PublicProcessor given the provided merkle tree db and contract data source. @@ -75,18 +75,18 @@ export class PublicProcessorFactory { prevGlobalVariables: GlobalVariables, globalVariables: GlobalVariables, ): Promise { - const blockData = await getHistoricBlockData(this.merkleTree, prevGlobalVariables); + const blockHeader = await getBlockHeader(this.merkleTree, prevGlobalVariables); const publicContractsDB = new ContractsDataSourcePublicDB(this.contractDataSource); const worldStatePublicDB = new WorldStatePublicDB(this.merkleTree); const worldStateDB = new WorldStateDB(this.merkleTree, this.l1Tol2MessagesDataSource); - const publicExecutor = new PublicExecutor(worldStatePublicDB, publicContractsDB, worldStateDB, blockData); + const publicExecutor = new PublicExecutor(worldStatePublicDB, publicContractsDB, worldStateDB, blockHeader); return new PublicProcessor( this.merkleTree, publicExecutor, new RealPublicKernelCircuitSimulator(), new EmptyPublicProver(), globalVariables, - blockData, + blockHeader, publicContractsDB, worldStatePublicDB, ); @@ -104,7 +104,7 @@ export class PublicProcessor { protected publicKernel: PublicKernelCircuitSimulator, protected publicProver: PublicProver, protected globalVariables: GlobalVariables, - protected blockData: HistoricBlockData, + protected blockHeader: BlockHeader, protected publicContractsDB: ContractsDataSourcePublicDB, protected publicStateDB: PublicStateDB, @@ -152,7 +152,7 @@ export class PublicProcessor { */ public makeEmptyProcessedTx(): Promise { const { chainId, version } = this.globalVariables; - return makeEmptyProcessedTx(this.blockData, chainId, version); + return makeEmptyProcessedTx(this.blockHeader, chainId, version); } protected async processTx(tx: Tx): Promise { @@ -259,7 +259,7 @@ export class PublicProcessor { protected async getPublicCircuitPublicInputs(result: PublicExecutionResult) { const publicDataTreeInfo = await this.db.getTreeInfo(MerkleTreeId.PUBLIC_DATA_TREE); - this.blockData.publicDataTreeRoot = Fr.fromBuffer(publicDataTreeInfo.root); + this.blockHeader.publicDataTreeRoot = Fr.fromBuffer(publicDataTreeInfo.root); const callStackPreimages = await this.getPublicCallStackPreimages(result); const publicCallStackHashes = padArrayEnd( @@ -293,7 +293,7 @@ export class PublicProcessor { publicCallStackHashes, unencryptedLogsHash, unencryptedLogPreimagesLength, - historicBlockData: this.blockData, + blockHeader: this.blockHeader, }); } diff --git a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts index 792c6236ecd7..694f4ee61b71 100644 --- a/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts +++ b/yarn-project/sequencer-client/src/sequencer/sequencer.test.ts @@ -1,7 +1,7 @@ import { + BlockHeader, Fr, GlobalVariables, - HistoricBlockData, NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP, makeEmptyProof, } from '@aztec/circuits.js'; @@ -57,7 +57,7 @@ describe('sequencer', () => { publicProcessor = mock({ process: async txs => [await Promise.all(txs.map(tx => makeProcessedTx(tx))), []], - makeEmptyProcessedTx: () => makeEmptyProcessedTx(HistoricBlockData.empty(), chainId, version), + makeEmptyProcessedTx: () => makeEmptyProcessedTx(BlockHeader.empty(), chainId, version), }); publicProcessorFactory = mock({ diff --git a/yarn-project/sequencer-client/src/sequencer/utils.ts b/yarn-project/sequencer-client/src/sequencer/utils.ts index b43747fc6442..62cde96601b4 100644 --- a/yarn-project/sequencer-client/src/sequencer/utils.ts +++ b/yarn-project/sequencer-client/src/sequencer/utils.ts @@ -1,18 +1,18 @@ -import { Fr, GlobalVariables, HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader, Fr, GlobalVariables } from '@aztec/circuits.js'; import { computeGlobalsHash } from '@aztec/circuits.js/abis'; import { MerkleTreeOperations } from '@aztec/world-state'; /** - * Fetches the private, nullifier, contract tree and l1 to l2 messages tree roots from a given db and assembles a CombinedHistoricTreeRoots object. + * Fetches the private, nullifier, contract tree and l1 to l2 messages tree roots from a given db and assembles a CombinedHistoricalTreeRoots object. */ -export async function getHistoricBlockData( +export async function getBlockHeader( db: MerkleTreeOperations, prevBlockGlobalVariables: GlobalVariables = GlobalVariables.empty(), ) { const prevGlobalsHash = computeGlobalsHash(prevBlockGlobalVariables); const roots = await db.getTreeRoots(); - return new HistoricBlockData( + return new BlockHeader( Fr.fromBuffer(roots.noteHashTreeRoot), Fr.fromBuffer(roots.nullifierTreeRoot), Fr.fromBuffer(roots.contractDataTreeRoot), diff --git a/yarn-project/types/src/aztec_node/rpc/aztec_node_client.ts b/yarn-project/types/src/aztec_node/rpc/aztec_node_client.ts index 1c3123023575..4f2f702c21c4 100644 --- a/yarn-project/types/src/aztec_node/rpc/aztec_node_client.ts +++ b/yarn-project/types/src/aztec_node/rpc/aztec_node_client.ts @@ -1,4 +1,4 @@ -import { FunctionSelector, HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader, FunctionSelector } from '@aztec/circuits.js'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { EthAddress } from '@aztec/foundation/eth-address'; import { Fr } from '@aztec/foundation/fields'; @@ -35,7 +35,7 @@ export function createAztecNodeClient(url: string, fetch = defaultFetch): AztecN ContractData, Fr, FunctionSelector, - HistoricBlockData, + BlockHeader, L2Block, L2Tx, LogId, diff --git a/yarn-project/types/src/interfaces/aztec-node.ts b/yarn-project/types/src/interfaces/aztec-node.ts index e03966ec8aed..92463e96b0f7 100644 --- a/yarn-project/types/src/interfaces/aztec-node.ts +++ b/yarn-project/types/src/interfaces/aztec-node.ts @@ -1,4 +1,4 @@ -import { HistoricBlockData } from '@aztec/circuits.js'; +import { BlockHeader } from '@aztec/circuits.js'; import { L1ContractAddresses } from '@aztec/ethereum'; import { AztecAddress } from '@aztec/foundation/aztec-address'; import { Fr } from '@aztec/foundation/fields'; @@ -139,10 +139,10 @@ export interface AztecNode extends StateInfoProvider { getTreeRoots(): Promise>; /** - * Returns the currently committed historic block data. - * @returns The current committed block data. + * Returns the currently committed block header. + * @returns The current committed block header. */ - getHistoricBlockData(): Promise; + getBlockHeader(): Promise; /** * Simulates the public part of a transaction with the current state. diff --git a/yarn-project/types/src/interfaces/state_provider.ts b/yarn-project/types/src/interfaces/state_provider.ts index 68d01812a7e6..33117aab1d5d 100644 --- a/yarn-project/types/src/interfaces/state_provider.ts +++ b/yarn-project/types/src/interfaces/state_provider.ts @@ -1,7 +1,7 @@ import { + BLOCKS_TREE_HEIGHT, CONTRACT_TREE_HEIGHT, Fr, - HISTORIC_BLOCKS_TREE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, NULLIFIER_TREE_HEIGHT, @@ -72,7 +72,7 @@ export interface StateInfoProvider { * @returns The sibling path. * TODO: https://github.com/AztecProtocol/aztec-packages/issues/3414 */ - getHistoricBlocksTreeSiblingPath(leafIndex: bigint): Promise>; + getBlocksTreeSiblingPath(leafIndex: bigint): Promise>; /** * Returns a sibling path for a leaf in the committed public data tree. diff --git a/yarn-project/types/src/l2_block.ts b/yarn-project/types/src/l2_block.ts index 1ddd1347ede0..67832ef2da73 100644 --- a/yarn-project/types/src/l2_block.ts +++ b/yarn-project/types/src/l2_block.ts @@ -86,9 +86,9 @@ export class L2Block { */ public startL1ToL2MessagesTreeSnapshot: AppendOnlyTreeSnapshot, /** - * The tree snapshot of the historic blocks tree at the start of the rollup. + * The tree snapshot of the blocks tree at the start of the rollup. */ - public startHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot = AppendOnlyTreeSnapshot.empty(), + public startBlocksTreeSnapshot: AppendOnlyTreeSnapshot = AppendOnlyTreeSnapshot.empty(), /** * The tree snapshot of the note hash tree at the end of the rollup. */ @@ -110,9 +110,9 @@ export class L2Block { */ public endL1ToL2MessagesTreeSnapshot: AppendOnlyTreeSnapshot, /** - * The tree snapshot of the historic blocks tree at the end of the rollup. + * The tree snapshot of the blocks tree at the end of the rollup. */ - public endHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot, + public endBlocksTreeSnapshot: AppendOnlyTreeSnapshot, /** * The commitments to be inserted into the note hash tree. */ @@ -216,13 +216,13 @@ export class L2Block { startContractTreeSnapshot: makeAppendOnlyTreeSnapshot(0), startPublicDataTreeRoot: Fr.random(), startL1ToL2MessagesTreeSnapshot: makeAppendOnlyTreeSnapshot(0), - startHistoricBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot(0), + startBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot(0), endNoteHashTreeSnapshot: makeAppendOnlyTreeSnapshot(newCommitments.length), endNullifierTreeSnapshot: makeAppendOnlyTreeSnapshot(newNullifiers.length), endContractTreeSnapshot: makeAppendOnlyTreeSnapshot(newContracts.length), endPublicDataTreeRoot: Fr.random(), endL1ToL2MessagesTreeSnapshot: makeAppendOnlyTreeSnapshot(1), - endHistoricBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot(1), + endBlocksTreeSnapshot: makeAppendOnlyTreeSnapshot(1), newCommitments, newNullifiers, newContracts, @@ -277,9 +277,9 @@ export class L2Block { */ startL1ToL2MessagesTreeSnapshot: AppendOnlyTreeSnapshot; /** - * The tree snapshot of the historic blocks tree at the start of the rollup. + * The tree snapshot of the blocks tree at the start of the rollup. */ - startHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot; + startBlocksTreeSnapshot: AppendOnlyTreeSnapshot; /** * The tree snapshot of the note hash tree at the end of the rollup. */ @@ -301,9 +301,9 @@ export class L2Block { */ endL1ToL2MessagesTreeSnapshot: AppendOnlyTreeSnapshot; /** - * The tree snapshot of the historic blocks tree at the end of the rollup. + * The tree snapshot of the blocks tree at the end of the rollup. */ - endHistoricBlocksTreeSnapshot: AppendOnlyTreeSnapshot; + endBlocksTreeSnapshot: AppendOnlyTreeSnapshot; /** * The commitments to be inserted into the note hash tree. */ @@ -352,13 +352,13 @@ export class L2Block { fields.startContractTreeSnapshot, fields.startPublicDataTreeRoot, fields.startL1ToL2MessagesTreeSnapshot, - fields.startHistoricBlocksTreeSnapshot, + fields.startBlocksTreeSnapshot, fields.endNoteHashTreeSnapshot, fields.endNullifierTreeSnapshot, fields.endContractTreeSnapshot, fields.endPublicDataTreeRoot, fields.endL1ToL2MessagesTreeSnapshot, - fields.endHistoricBlocksTreeSnapshot, + fields.endBlocksTreeSnapshot, fields.newCommitments, fields.newNullifiers, fields.newPublicDataWrites, @@ -387,13 +387,13 @@ export class L2Block { this.startContractTreeSnapshot, this.startPublicDataTreeRoot, this.startL1ToL2MessagesTreeSnapshot, - this.startHistoricBlocksTreeSnapshot, + this.startBlocksTreeSnapshot, this.endNoteHashTreeSnapshot, this.endNullifierTreeSnapshot, this.endContractTreeSnapshot, this.endPublicDataTreeRoot, this.endL1ToL2MessagesTreeSnapshot, - this.endHistoricBlocksTreeSnapshot, + this.endBlocksTreeSnapshot, this.newCommitments.length, this.newCommitments, this.newNullifiers.length, @@ -449,13 +449,13 @@ export class L2Block { const startContractTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const startPublicDataTreeRoot = reader.readObject(Fr); const startL1ToL2MessagesTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); - const startHistoricBlocksTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); + const startBlocksTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endNoteHashTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endNullifierTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endContractTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const endPublicDataTreeRoot = reader.readObject(Fr); const endL1ToL2MessagesTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); - const endHistoricBlocksTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); + const endBlocksTreeSnapshot = reader.readObject(AppendOnlyTreeSnapshot); const newCommitments = reader.readVector(Fr); const newNullifiers = reader.readVector(Fr); const newPublicDataWrites = reader.readVector(PublicDataWrite); @@ -473,13 +473,13 @@ export class L2Block { startContractTreeSnapshot, startPublicDataTreeRoot, startL1ToL2MessagesTreeSnapshot: startL1ToL2MessagesTreeSnapshot, - startHistoricBlocksTreeSnapshot, + startBlocksTreeSnapshot, endNoteHashTreeSnapshot, endNullifierTreeSnapshot, endContractTreeSnapshot, endPublicDataTreeRoot, endL1ToL2MessagesTreeSnapshot, - endHistoricBlocksTreeSnapshot, + endBlocksTreeSnapshot, newCommitments, newNullifiers, newPublicDataWrites, @@ -589,13 +589,13 @@ export class L2Block { this.startContractTreeSnapshot, this.startPublicDataTreeRoot, this.startL1ToL2MessagesTreeSnapshot, - this.startHistoricBlocksTreeSnapshot, + this.startBlocksTreeSnapshot, this.endNoteHashTreeSnapshot, this.endNullifierTreeSnapshot, this.endContractTreeSnapshot, this.endPublicDataTreeRoot, this.endL1ToL2MessagesTreeSnapshot, - this.endHistoricBlocksTreeSnapshot, + this.endBlocksTreeSnapshot, this.getCalldataHash(), this.getL1ToL2MessagesHash(), ); @@ -615,7 +615,7 @@ export class L2Block { this.startContractTreeSnapshot, this.startPublicDataTreeRoot, this.startL1ToL2MessagesTreeSnapshot, - this.startHistoricBlocksTreeSnapshot, + this.startBlocksTreeSnapshot, ); return sha256(inputValue); } @@ -632,7 +632,7 @@ export class L2Block { this.endContractTreeSnapshot, this.endPublicDataTreeRoot, this.endL1ToL2MessagesTreeSnapshot, - this.endHistoricBlocksTreeSnapshot, + this.endBlocksTreeSnapshot, ); return sha256(inputValue); } @@ -843,14 +843,14 @@ export class L2Block { `startContractTreeSnapshot: ${inspectTreeSnapshot(this.startContractTreeSnapshot)}`, `startPublicDataTreeRoot: ${this.startPublicDataTreeRoot.toString()}`, `startL1ToL2MessagesTreeSnapshot: ${inspectTreeSnapshot(this.startL1ToL2MessagesTreeSnapshot)}`, - `startHistoricBlocksTreeSnapshot: ${inspectTreeSnapshot(this.startHistoricBlocksTreeSnapshot)}`, + `startBlocksTreeSnapshot: ${inspectTreeSnapshot(this.startBlocksTreeSnapshot)}`, `endNoteHashTreeSnapshot: ${inspectTreeSnapshot(this.endNoteHashTreeSnapshot)}`, `endNullifierTreeSnapshot: ${inspectTreeSnapshot(this.endNullifierTreeSnapshot)}`, `endContractTreeSnapshot: ${inspectTreeSnapshot(this.endContractTreeSnapshot)}`, `endPublicDataTreeRoot: ${this.endPublicDataTreeRoot.toString()}`, `endPublicDataTreeRoot: ${this.endPublicDataTreeRoot.toString()}`, `endL1ToL2MessagesTreeSnapshot: ${inspectTreeSnapshot(this.endL1ToL2MessagesTreeSnapshot)}`, - `endHistoricBlocksTreeSnapshot: ${inspectTreeSnapshot(this.endHistoricBlocksTreeSnapshot)}`, + `endBlocksTreeSnapshot: ${inspectTreeSnapshot(this.endBlocksTreeSnapshot)}`, `newCommitments: ${inspectFrArray(this.newCommitments)}`, `newNullifiers: ${inspectFrArray(this.newNullifiers)}`, `newPublicDataWrite: ${inspectPublicDataWriteArray(this.newPublicDataWrites)}`, diff --git a/yarn-project/world-state/README.md b/yarn-project/world-state/README.md index 42f095d9dbb8..a14b1fa02b6c 100644 --- a/yarn-project/world-state/README.md +++ b/yarn-project/world-state/README.md @@ -11,9 +11,9 @@ As of the time of writing the collection consisted of the following trees. #### Standard 'Append Only' trees - The Contract Tree. Every contract created within the system has a 'Function Tree', a tree of leaves generated from the functions on the contract. The root of the function tree is inserted as a leaf in the contracts tree. -- The Contract Tree Roots Tree. A tree whose leaves are the historic roots of the contract tree. +- The Contract Tree Roots Tree. A tree whose leaves are the historical roots of the contract tree. - The Note Hash Tree. A tree whose leaves are the note hashes of notes generated by the private contract function calls within the system. -- The Note Hash Tree Roots Tree. A tree whose leaves are the historic roots of the note hash tree. +- The Note Hash Tree Roots Tree. A tree whose leaves are the historical roots of the note hash tree. #### Indexed trees diff --git a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts b/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts index 312403577483..29ba293736d2 100644 --- a/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts +++ b/yarn-project/world-state/src/merkle-tree/merkle_tree_operations_facade.ts @@ -120,8 +120,8 @@ export class MerkleTreeOperationsFacade implements MerkleTreeOperations { * @param globalVariablesHash - The hash of the current global variables to include in the block hash. * @returns Empty promise. */ - public updateHistoricBlocksTree(globalVariablesHash: Fr): Promise { - return this.trees.updateHistoricBlocksTree(globalVariablesHash, this.includeUncommitted); + public updateBlocksTree(globalVariablesHash: Fr): Promise { + return this.trees.updateBlocksTree(globalVariablesHash, this.includeUncommitted); } /** diff --git a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts index 4fe162c12b07..d5e3798a7c60 100644 --- a/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts +++ b/yarn-project/world-state/src/synchronizer/server_world_state_synchronizer.test.ts @@ -72,13 +72,13 @@ const getMockBlock = (blockNumber: number, newContractsCommitments?: Buffer[]) = startContractTreeSnapshot: getMockTreeSnapshot(), startPublicDataTreeRoot: Fr.random(), startL1ToL2MessagesTreeSnapshot: getMockTreeSnapshot(), - startHistoricBlocksTreeSnapshot: getMockTreeSnapshot(), + startBlocksTreeSnapshot: getMockTreeSnapshot(), endNoteHashTreeSnapshot: getMockTreeSnapshot(), endNullifierTreeSnapshot: getMockTreeSnapshot(), endContractTreeSnapshot: getMockTreeSnapshot(), endPublicDataTreeRoot: Fr.random(), endL1ToL2MessagesTreeSnapshot: getMockTreeSnapshot(), - endHistoricBlocksTreeSnapshot: getMockTreeSnapshot(), + endBlocksTreeSnapshot: getMockTreeSnapshot(), newCommitments: times(MAX_NEW_COMMITMENTS_PER_TX, Fr.random), newNullifiers: times(MAX_NEW_NULLIFIERS_PER_TX, Fr.random), newContracts: newContractsCommitments?.map(x => Fr.fromBuffer(x)) ?? [Fr.random()], diff --git a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts index 8f191517a82d..b9dc631ff1f0 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_tree_db.ts @@ -175,7 +175,7 @@ export interface MerkleTreeOperations { * This includes all of the current roots of all of the data trees and the current blocks global vars. * @param globalVariablesHash - The global variables hash to insert into the block hash. */ - updateHistoricBlocksTree(globalVariablesHash: Fr): Promise; + updateBlocksTree(globalVariablesHash: Fr): Promise; /** * Updates the latest global variables hash diff --git a/yarn-project/world-state/src/world-state-db/merkle_trees.ts b/yarn-project/world-state/src/world-state-db/merkle_trees.ts index a27b1706612f..3d167bf4a9c3 100644 --- a/yarn-project/world-state/src/world-state-db/merkle_trees.ts +++ b/yarn-project/world-state/src/world-state-db/merkle_trees.ts @@ -1,8 +1,8 @@ import { + BLOCKS_TREE_HEIGHT, CONTRACT_TREE_HEIGHT, Fr, GlobalVariables, - HISTORIC_BLOCKS_TREE_HEIGHT, L1_TO_L2_MSG_TREE_HEIGHT, NOTE_HASH_TREE_HEIGHT, NULLIFIER_SUBTREE_HEIGHT, @@ -110,14 +110,14 @@ export class MerkleTrees implements MerkleTreeDb { `${MerkleTreeId[MerkleTreeId.L1_TO_L2_MESSAGES_TREE]}`, L1_TO_L2_MSG_TREE_HEIGHT, ); - const historicBlocksTree: AppendOnlyTree = await initializeTree( + const blocksTree: AppendOnlyTree = await initializeTree( StandardTree, this.db, hasher, `${MerkleTreeId[MerkleTreeId.BLOCKS_TREE]}`, - HISTORIC_BLOCKS_TREE_HEIGHT, + BLOCKS_TREE_HEIGHT, ); - this.trees = [contractTree, nullifierTree, noteHashTree, publicDataTree, l1Tol2MessagesTree, historicBlocksTree]; + this.trees = [contractTree, nullifierTree, noteHashTree, publicDataTree, l1Tol2MessagesTree, blocksTree]; this.jobQueue.start(); @@ -125,7 +125,7 @@ export class MerkleTrees implements MerkleTreeDb { if (!fromDb) { const initialGlobalVariablesHash = computeGlobalsHash(GlobalVariables.empty()); await this._updateLatestGlobalVariablesHash(initialGlobalVariablesHash); - await this._updateHistoricBlocksTree(initialGlobalVariablesHash, true); + await this._updateBlocksTree(initialGlobalVariablesHash, true); await this._commit(); } else { await this._updateLatestGlobalVariablesHash(fromDbOptions.globalVariablesHash); @@ -177,8 +177,8 @@ export class MerkleTrees implements MerkleTreeDb { * @param globalsHash - The current global variables hash. * @param includeUncommitted - Indicates whether to include uncommitted data. */ - public async updateHistoricBlocksTree(globalsHash: Fr, includeUncommitted: boolean) { - await this.synchronize(() => this._updateHistoricBlocksTree(globalsHash, includeUncommitted)); + public async updateBlocksTree(globalsHash: Fr, includeUncommitted: boolean) { + await this.synchronize(() => this._updateBlocksTree(globalsHash, includeUncommitted)); } /** @@ -427,7 +427,7 @@ export class MerkleTrees implements MerkleTreeDb { return Promise.resolve(this.latestGlobalVariablesHash.get(includeUncommitted)); } - private async _updateHistoricBlocksTree(globalsHash: Fr, includeUncommitted: boolean) { + private async _updateBlocksTree(globalsHash: Fr, includeUncommitted: boolean) { const blockHash = await this._getCurrentBlockHash(globalsHash, includeUncommitted); await this._appendLeaves(MerkleTreeId.BLOCKS_TREE, [blockHash.toBuffer()]); } @@ -532,7 +532,7 @@ export class MerkleTrees implements MerkleTreeDb { [l2Block.endNoteHashTreeSnapshot.root, MerkleTreeId.NOTE_HASH_TREE], [l2Block.endPublicDataTreeRoot, MerkleTreeId.PUBLIC_DATA_TREE], [l2Block.endL1ToL2MessagesTreeSnapshot.root, MerkleTreeId.L1_TO_L2_MESSAGES_TREE], - [l2Block.endHistoricBlocksTreeSnapshot.root, MerkleTreeId.BLOCKS_TREE], + [l2Block.endBlocksTreeSnapshot.root, MerkleTreeId.BLOCKS_TREE], ] as const; const compareRoot = (root: Fr, treeId: MerkleTreeId) => { const treeRoot = this.trees[treeId].getRoot(true); @@ -573,7 +573,7 @@ export class MerkleTrees implements MerkleTreeDb { await this._updateLeaf(MerkleTreeId.PUBLIC_DATA_TREE, newValue.toBuffer(), leafIndex.value); } - // Sync and add the block to the historic blocks tree + // Sync and add the block to the blocks tree const globalVariablesHash = computeGlobalsHash(l2Block.globalVariables); await this._updateLatestGlobalVariablesHash(globalVariablesHash); this.log(`Synced global variables with hash ${globalVariablesHash}`); diff --git a/yellow-paper/docs/transactions/tx-object.md b/yellow-paper/docs/transactions/tx-object.md index 38123b6ffb90..ccfa2f7d4a73 100644 --- a/yellow-paper/docs/transactions/tx-object.md +++ b/yellow-paper/docs/transactions/tx-object.md @@ -17,7 +17,7 @@ The fields of a transaction object are the following: ### Private kernel public inputs final -Output of the last iteration of the private kernel circuit. Includes _accumulated data_ after recursing through all private function calls, as well as _constant data_ composed of _historic block data_ reflecting the state of the chain when such functions were executed, and the global _transaction context_. Refer to the circuits section for more info. +Output of the last iteration of the private kernel circuit. Includes _accumulated data_ after recursing through all private function calls, as well as _constant data_ composed of _block header_ reflecting the state of the chain when such functions were executed, and the global _transaction context_. Refer to the circuits section for more info. **Accumulated data** @@ -37,7 +37,7 @@ Output of the last iteration of the private kernel circuit. Includes _accumulate | newContracts | NewContractData[] | All the new contracts deployed in this transaction. | | maxBlockNum | Field | Maximum block number (inclusive) for inclusion of this transaction in a block. | -**Historic block data** +**Block header** | Field | Type | Description | |-------|------|-------------| diff --git a/yellow-paper/docs/transactions/validity.md b/yellow-paper/docs/transactions/validity.md index f4121e6faade..9d464e0d8587 100644 --- a/yellow-paper/docs/transactions/validity.md +++ b/yellow-paper/docs/transactions/validity.md @@ -7,7 +7,7 @@ In addition to being well-formed, the transaction object needs to pass the follo - **Proof is valid**: The `proof` for the given public `data` should be valid according to a protocol-wide verification key for the final private kernel circuit. - **No double-spends**: No `nullifier` in the transaction `data` should be already present in the nullifier tree. - **No pending private function calls**: The `data` private call stack should be empty. -- **Valid historic data**: The tree roots in the historic block data of `data` must match the tree roots of a block in the chain. +- **Valid historic data**: The tree roots in the block header of `data` must match the tree roots of a block in the chain. - **Maximum block number not exceeded**: The transaction must be included in a block with height no greater than the value specified in `maxBlockNum` within the transaction's `data`. - **Preimages must match commitments in `data`**: The expanded fields in the transaction object should match the commitments (hashes) to them in the public `data`. - The `encryptedLogs` should match the `encryptedLogsHash` and `encryptedLogPreimagesLength` in the transaction `data`. From 798565d5a8a5cb096c9b2efb6d41de1c449d2c4e Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Thu, 30 Nov 2023 11:32:46 -0300 Subject: [PATCH 06/37] chore: Fix broken link in txs in yellow paper (#3484) --- yellow-paper/docs/transactions/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yellow-paper/docs/transactions/index.md b/yellow-paper/docs/transactions/index.md index 6f72811501b0..d9d7bbb3e46a 100644 --- a/yellow-paper/docs/transactions/index.md +++ b/yellow-paper/docs/transactions/index.md @@ -8,7 +8,7 @@ A transaction is the minimal action that changes the state of the network. Trans A transaction is also split into three phases to [support authorization abstraction and fee payments](../gas-and-fees/gas-and-fees.md#fees): a validation and fee preparation phase, a main execution phase, and fee distribution phase. -Users initiate a transaction by sending a _transaction request_ to their local PXE, which [locally simulates and proves the transaction](./local-execution.md) and returns a [_transaction_ object](./tx-object.md) identified by a [_transaction hash_](./tx-hash.md). This transaction object is then broadcasted to the network via an Aztec Node, which checks its [validity](./validity.md), and eventually picked up by a sequencer who [executes the public component of the transaction](./public-execution.md) and includes it in a block. +Users initiate a transaction by sending a _transaction request_ to their local PXE, which [locally simulates and proves the transaction](./local-execution.md) and returns a [_transaction_ object](./tx-object.md) identified by a [_transaction hash_](./tx-object.md#transaction-hash). This transaction object is then broadcasted to the network via an Aztec Node, which checks its [validity](./validity.md), and eventually picked up by a sequencer who [executes the public component of the transaction](./public-execution.md) and includes it in a block. import DocCardList from '@theme/DocCardList'; From 8d6b01304d797f7cbb576b23a7e115390d113c79 Mon Sep 17 00:00:00 2001 From: ludamad Date: Thu, 30 Nov 2023 09:43:36 -0500 Subject: [PATCH 07/37] feat: flavor refactor, reduce duplication (#3407) Reduces duplication in Flavor classes by using a macro that combines pointer_view with struct fields (along with a new get_all getter that is perhaps more ergonomic) and subclassing. Note that this is a stepping stone, ideally https://github.com/AztecProtocol/barretenberg/issues/788 is used instead of multiple inheritance Also resolves https://github.com/AztecProtocol/barretenberg/issues/784 - Introduces a RefVector class, like `std::vector` (which is impossible). It is backed by a pointer, and gives operator[] and iterator semantics on the underlying derefenced pointer. Compare std::vector>, which would operate more like actual pointers (you change the reference, not the value held by the reference). - Introduces a get_all alternative to pointer_view that uses RefVector, update other types to use RefVector, get rid of the HandleType in flavor entity classes - Removes some flavor base classes that didn't do much after array backing removal. Now we get rid of virtual base class methods here, but I don't think it makes sense to do polymorphism in two ways. We can instead use concepts if we want to constrain this with a static assert - Introduces macros that define flavor classes in flavor_macros.hpp. These remove duplication of pointer view and normal listing. - Use inheritance to remove duplication in the larger AllEntities classes in GoblinUltra and GoblinTranslator - Removes modernize-use-nodiscard - too noisy a linter setting, I doubt we'd hit a bug that it would fix (i.e. if you return error codes it can be useful to not ignore them). --------- Co-authored-by: ludamad --- barretenberg/cpp/.clangd | 4 + .../relations_bench/relations.bench.cpp | 2 +- .../zeromorph/zeromorph.hpp | 14 +- .../zeromorph/zeromorph.test.cpp | 4 +- .../barretenberg/common/constexpr_utils.hpp | 27 - .../cpp/src/barretenberg/common/ref_array.hpp | 140 ++ .../src/barretenberg/common/ref_vector.hpp | 149 ++ .../cpp/src/barretenberg/common/std_array.hpp | 39 + .../ecc/groups/affine_element.hpp | 8 +- .../ecc/groups/affine_element_impl.hpp | 31 - .../src/barretenberg/eccvm/eccvm_prover.cpp | 4 + .../cpp/src/barretenberg/flavor/ecc_vm.hpp | 928 ++------ .../cpp/src/barretenberg/flavor/flavor.hpp | 75 +- .../src/barretenberg/flavor/flavor.test.cpp | 7 +- .../src/barretenberg/flavor/flavor_macros.hpp | 71 + .../flavor/generated/AvmMini_flavor.hpp | 228 +- .../flavor/generated/Fib_flavor.hpp | 98 +- .../barretenberg/flavor/goblin_translator.hpp | 2008 +++++++---------- .../src/barretenberg/flavor/goblin_ultra.hpp | 372 ++- .../flavor/goblin_ultra_recursive.hpp | 378 ++-- .../flavor/relation_definitions_fwd.hpp | 2 +- .../cpp/src/barretenberg/flavor/ultra.hpp | 308 +-- .../barretenberg/flavor/ultra_recursive.hpp | 276 +-- .../goblin/full_goblin_composer.test.cpp | 26 +- .../honk/proof_system/permutation_library.hpp | 9 +- .../proof_system/composer/permutation_lib.hpp | 5 +- ...n_translator_relation_consistency.test.cpp | 8 +- .../src/barretenberg/sumcheck/sumcheck.hpp | 2 +- .../goblin_translator_verifier.cpp | 28 +- .../ultra_honk/relation_correctness.test.cpp | 48 +- 30 files changed, 2126 insertions(+), 3173 deletions(-) create mode 100644 barretenberg/cpp/src/barretenberg/common/ref_array.hpp create mode 100644 barretenberg/cpp/src/barretenberg/common/ref_vector.hpp create mode 100644 barretenberg/cpp/src/barretenberg/common/std_array.hpp create mode 100644 barretenberg/cpp/src/barretenberg/flavor/flavor_macros.hpp diff --git a/barretenberg/cpp/.clangd b/barretenberg/cpp/.clangd index e09234d9e7a7..bb22a6eed3ef 100644 --- a/barretenberg/cpp/.clangd +++ b/barretenberg/cpp/.clangd @@ -61,6 +61,10 @@ Diagnostics: - google-explicit-constructor # Not honouring. - cppcoreguidelines-owning-memory + # "This check is deprecated since it’s no longer part of the CERT standard. It will be removed in clang-tidy version 19." + - cert-dc21-cpp + # Noisy. As we don't need to return error types or raw allocations, really unlikely we'd cause problems by ignoring a return type. + - modernize-use-nodiscard --- # this divider is necessary # Disable some checks for Google Test/Bench diff --git a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp index d27dc35f9bc5..616e85957be2 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/relations_bench/relations.bench.cpp @@ -24,7 +24,7 @@ template void execute_relation(::benchmark: auto params = proof_system::RelationParameters::get_random(); // Extract an array containing all the polynomial evaluations at a given row i - AllValues new_value; + AllValues new_value{}; // Define the appropriate SumcheckArrayOfValuesOverSubrelations type for this relation and initialize to zero SumcheckArrayOfValuesOverSubrelations accumulator; // Evaluate each constraint in the relation and check that each is satisfied diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp index 1cd359ebe69a..d90f94f96a96 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.hpp @@ -1,4 +1,5 @@ #pragma once +#include "barretenberg/common/ref_vector.hpp" #include "barretenberg/common/zip_view.hpp" #include "barretenberg/polynomials/polynomial.hpp" namespace proof_system::honk::pcs::zeromorph { @@ -321,7 +322,8 @@ template class ZeroMorphProver_ { auto& transcript, const std::vector>& concatenated_polynomials = {}, const std::vector& concatenated_evaluations = {}, - const std::vector>>& concatenation_groups = {}) + // TODO(https://github.com/AztecProtocol/barretenberg/issues/743) remove span + const std::vector>>& concatenation_groups = {}) { // Generate batching challenge \rho and powers 1,...,\rho^{m-1} FF rho = transcript.get_challenge("rho"); @@ -513,14 +515,14 @@ template class ZeroMorphVerifier_ { * @param concatenation_groups_commitments * @return Commitment */ - static Commitment compute_C_Z_x(std::vector f_commitments, - std::vector g_commitments, + static Commitment compute_C_Z_x(const std::vector& f_commitments, + const std::vector& g_commitments, std::vector& C_q_k, FF rho, FF batched_evaluation, FF x_challenge, std::vector u_challenge, - const std::vector>& concatenation_groups_commitments = {}) + const std::vector>& concatenation_groups_commitments = {}) { size_t log_N = C_q_k.size(); size_t N = 1 << log_N; @@ -611,7 +613,7 @@ template class ZeroMorphVerifier_ { * @brief Utility for native batch multiplication of group elements * @note This is used only for native verification and is not optimized for efficiency */ - static Commitment batch_mul_native(std::vector points, std::vector scalars) + static Commitment batch_mul_native(const std::vector& points, const std::vector& scalars) { auto result = points[0] * scalars[0]; for (size_t idx = 1; idx < scalars.size(); ++idx) { @@ -637,7 +639,7 @@ template class ZeroMorphVerifier_ { auto&& shifted_evaluations, auto& multivariate_challenge, auto& transcript, - const std::vector>& concatenation_group_commitments = {}, + const std::vector>& concatenation_group_commitments = {}, const std::vector& concatenated_evaluations = {}) { size_t log_N = multivariate_challenge.size(); diff --git a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp index 30876c73e506..47fb203c64f2 100644 --- a/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp +++ b/barretenberg/cpp/src/barretenberg/commitment_schemes/zeromorph/zeromorph.test.cpp @@ -246,7 +246,7 @@ template class ZeroMorphWithConcatenationTest : public CommitmentT prover_transcript, concatenated_polynomials_views, c_evaluations, - concatenation_groups_views); + to_vector_of_ref_vectors(concatenation_groups_views)); auto verifier_transcript = BaseTranscript::verifier_init_empty(prover_transcript); @@ -257,7 +257,7 @@ template class ZeroMorphWithConcatenationTest : public CommitmentT w_evaluations, // shifted u_challenge, verifier_transcript, - concatenation_groups_commitments, + to_vector_of_ref_vectors(concatenation_groups_commitments), c_evaluations); verified = this->vk()->pairing_check(pairing_points[0], pairing_points[1]); diff --git a/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp b/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp index ed11246196fa..29bbfc473874 100644 --- a/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp +++ b/barretenberg/cpp/src/barretenberg/common/constexpr_utils.hpp @@ -12,8 +12,6 @@ * * constexpr_for : loop over a range , where the size_t iterator `i` is a constexpr variable * constexpr_find : find if an element is in an array - * concatenate_arrays : smoosh multiple std::array objects into a single std::array - * */ namespace barretenberg { @@ -121,31 +119,6 @@ template constexpr bool constexpr_find() return found; } -/** - * @brief merges multiple std::arrays into a single array. - * Array lengths can be different but array type must match - * Method is constexpr and should concat constexpr arrays at compile time - * - * @tparam Type the array type - * @tparam sizes template parameter pack of size_t value params - * @param arrays - * @return constexpr auto - * - * @details template params should be autodeducted. Example use case: - * - * ``` - * std::array a{1, 2}; - * std::array b{1,3, 5}; - * std::array c = concatenate(a, b); - * ``` - */ -template -constexpr auto concatenate_arrays(const std::array&... arrays) -{ - return std::apply([](auto... elems) -> std::array { return { { elems... } }; }, - std::tuple_cat(std::tuple_cat(arrays)...)); -} - /** * @brief Create a constexpr array object whose elements contain a default value * diff --git a/barretenberg/cpp/src/barretenberg/common/ref_array.hpp b/barretenberg/cpp/src/barretenberg/common/ref_array.hpp new file mode 100644 index 000000000000..f9c9fa11f3b9 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/common/ref_array.hpp @@ -0,0 +1,140 @@ +#include "barretenberg/common/assert.hpp" +#include +#include +#include +#include +#include + +// TODO(https://github.com/AztecProtocol/barretenberg/issues/794) namespace this once convenient +/** + * @brief A template class for a reference array. Behaves as if std::array was possible. + * + * This class provides a fixed-size array of pointers to elements of type T, exposed as references. + * It offers random access to its elements and provides an iterator class + * for traversal. + * + * @tparam T The type of elements stored in the array. + * @tparam N The size of the array. + */ +template class RefArray { + public: + RefArray(const std::array& ptr_array) + { + std::size_t i = 0; + for (T& elem : ptr_array) { + storage[i++] = &elem; + } + } + RefArray(std::initializer_list init) + { + if (init.size() != N) { + throw std::invalid_argument("Initializer list size does not match RefArray size"); + } + std::size_t i = 0; + for (auto& elem : init) { + storage[i++] = &elem; + } + } + + T& operator[](std::size_t idx) const + { + ASSERT(idx < N); + return *storage[idx]; + } + + /** + * @brief Nested iterator class for RefArray, based on indexing into the pointer array. + * Provides semantics similar to what would be expected if std::array was possible. + */ + class iterator { + public: + /** + * @brief Constructs an iterator for a given RefArray object. + * + * @param array Pointer to the RefArray object. + * @param pos The starting position in the array. + */ + iterator(RefArray const* array, std::size_t pos) + : array(array) + , pos(pos) + {} + + T& operator*() const { return (*array)[pos]; } + + iterator& operator++() + { + pos++; + return *this; + } + + iterator operator++(int) + { + iterator temp = *this; + ++(*this); + return temp; + } + + bool operator==(iterator const& other) const { return pos == other.pos; } + bool operator!=(iterator const& other) const { return pos != other.pos; } + + private: + RefArray const* array; + std::size_t pos; + }; + + /** + * @brief Returns an iterator to the beginning of the RefArray. + * + * @return An iterator to the first element. + */ + iterator begin() const { return iterator(this, 0); } + /** + * @brief Returns an iterator to the end of the RefArray. + * + * @return An iterator to the element following the last element. + */ + iterator end() const { return iterator(this, N); } + + private: + // We are making a high-level array, for simplicity having a C array as backing makes sense. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays) + T* storage[N]; +}; + +/** + * @brief Deduction guide for the RefArray class. + * Allows for RefArray {a, b, c} without explicit template params. + */ +template RefArray(T&, Ts&...) -> RefArray; + +/** + * @brief Concatenates multiple RefArray objects into a single RefArray. + * + * This function takes multiple RefArray objects as input and concatenates them into a single + * RefArray. + + * @tparam T The type of elements in the RefArray. + * @tparam Ns The sizes of the input RefArrays. + * @param ref_arrays The RefArray objects to be concatenated. + * @return RefArray object containing all elements from the input arrays. + */ +template RefArray concatenate(const RefArray&... ref_arrays) +{ + // Fold expression to calculate the total size of the new array using fold expression + constexpr std::size_t TotalSize = (Ns + ...); + std::array concatenated; + + std::size_t offset = 0; + // Copies elements from a given RefArray to the concatenated array + auto copy_into = [&](const auto& ref_array, std::size_t& offset) { + for (std::size_t i = 0; i < ref_array.size(); ++i) { + concatenated[offset + i] = &ref_array[i]; + } + offset += ref_array.size(); + }; + + // Fold expression to copy elements from each input RefArray to the concatenated array + (..., copy_into(ref_arrays, offset)); + + return RefArray{ concatenated }; +} \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/common/ref_vector.hpp b/barretenberg/cpp/src/barretenberg/common/ref_vector.hpp new file mode 100644 index 000000000000..fa47379ba833 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/common/ref_vector.hpp @@ -0,0 +1,149 @@ +#pragma once +#include "barretenberg/common/assert.hpp" +#include +#include +#include +#include +#include + +// TODO(https://github.com/AztecProtocol/barretenberg/issues/794) namespace this once convenient +/** + * @brief A template class for a reference vector. Behaves as if std::vector was possible. + * + * This class provides a dynamic-size vector of pointers to elements of type T, exposed as references. + * It offers random access to its elements and provides an iterator class for traversal. + * + * @tparam T The type of elements stored in the vector. + * @warning This should NOT be used for long-term storage, only for efficient passing. Any long-term sharing of values + * should use shared pointers. + */ +template class RefVector { + public: + RefVector() = default; + explicit RefVector(const std::vector& ptr_vector) + : storage(ptr_vector) + {} + + explicit RefVector(std::vector& vector) + : storage(vector.size()) + { + for (size_t i = 0; i < vector.size(); i++) { + storage[i] = &vector[i]; + } + } + + template RefVector(T& ref, Ts&... rest) + { + storage.push_back(&ref); + (storage.push_back(&rest), ...); + } + + T& operator[](std::size_t idx) const + { + ASSERT(idx < storage.size()); + return *storage[idx]; + } + + /** + * @brief Nested iterator class for RefVector, based on indexing into the pointer vector. + * Provides semantics similar to what would be expected if std::vector was possible. + */ + class iterator { + public: + /** + * @brief Constructs an iterator for a given RefVector object. + * + * @param vector Pointer to the RefVector object. + * @param pos The starting position in the vector. + */ + iterator(RefVector const* vector, std::size_t pos) + : vector(vector) + , pos(pos) + {} + + T& operator*() const { return (*vector)[pos]; } + + iterator& operator++() + { + pos++; + return *this; + } + + iterator operator++(int) + { + iterator temp = *this; + ++(*this); + return temp; + } + + bool operator==(iterator const& other) const { return pos == other.pos; } + bool operator!=(iterator const& other) const { return pos != other.pos; } + + private: + RefVector const* vector; + std::size_t pos; + }; + + [[nodiscard]] std::size_t size() const { return storage.size(); } + + void push_back(T& element) { storage.push_back(element); } + iterator begin() const { return iterator(this, 0); } + iterator end() const { return iterator(this, storage.size()); } + + template operator std::vector() const + { + std::vector ret; + for (T* elem : storage) { + ret.push_back(*elem); + } + return ret; + } + + std::vector& get_storage() { return storage; } + const std::vector& get_storage() const { return storage; } + + private: + std::vector storage; +}; + +/** + * @brief Deduction guide for the RefVector class. + * Allows for RefVector {a, b, c} without explicit template params. + */ +template RefVector(T&, Ts&...) -> RefVector; + +/** + * @brief Concatenates multiple RefVector objects into a single RefVector. + * + * This function takes multiple RefVector objects as input and concatenates them into a single + * RefVector. + * + * @tparam T The type of elements in the RefVector. + * @param ref_vectors The RefVector objects to be concatenated. + * @return RefVector object containing all elements from the input vectors. + */ +template RefVector concatenate(const RefVector& ref_vector, const auto&... ref_vectors) +{ + RefVector concatenated; + // Reserve our final space + concatenated.get_storage().reserve(ref_vector.size() + (ref_vectors.size() + ...)); + + auto append = [&](const auto& vec) { + std::copy(vec.get_storage().begin(), vec.get_storage().end(), std::back_inserter(concatenated.get_storage())); + }; + + append(ref_vector); + // Unpack and append each RefVector's elements to concatenated + (append(ref_vectors), ...); + + return concatenated; +} + +template static std::vector> to_vector_of_ref_vectors(std::vector>& vec) +{ + std::vector> result; + for (std::vector& inner : vec) { + result.push_back(RefVector{ inner }); + } + return result; +} diff --git a/barretenberg/cpp/src/barretenberg/common/std_array.hpp b/barretenberg/cpp/src/barretenberg/common/std_array.hpp new file mode 100644 index 000000000000..850464ae36ad --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/common/std_array.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +// TODO(https://github.com/AztecProtocol/barretenberg/issues/794) namespace this once convenient +/** + * @brief Concatenates multiple std::array objects into a single array. + * + * This function template takes a variadic number of std::array objects and concatenates + * their elements into a single std::array. The size of the resulting array is the sum of the sizes + * of the input arrays. + * + * @tparam T The type of elements stored in the arrays. + * @tparam Ns The sizes of the input arrays. This is a variadic template parameter pack representing + * the sizes of each input array. + * @param arrays Variadic number of std::array objects to concatenate. Each array can have a + * different size but must contain the same type of elements. + * @return std::array A new std::array containing all elements from the input arrays + * concatenated in the order they were passed. + * + * Example usage: + * std::array a = {1, 2}; + * std::array b = {3, 4, 5}; + * auto result = concatenate(a, b); // result is std::array{1, 2, 3, 4, 5} + */ +template std::array concatenate(const std::array&... arrays) +{ + std::array result; + + std::size_t offset = 0; + auto copy_into = [&](const auto& array) { + std::copy(array.begin(), array.end(), result.begin() + offset); + offset += array.size(); + }; + + (copy_into(arrays), ...); + + return result; +} diff --git a/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp index 286aed4c0cdf..f8d874cc6014 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element.hpp @@ -20,9 +20,9 @@ template class alignas(64) affine_el constexpr affine_element(const Fq& a, const Fq& b) noexcept; - constexpr affine_element(const affine_element& other) noexcept; + constexpr affine_element(const affine_element& other) noexcept = default; - constexpr affine_element(affine_element&& other) noexcept; + constexpr affine_element(affine_element&& other) noexcept = default; static constexpr affine_element one() noexcept { return { Params::one_x, Params::one_y }; }; @@ -52,9 +52,9 @@ template class alignas(64) affine_el typename CompileTimeEnabled = std::enable_if_t<(BaseField::modulus >> 255) == uint256_t(1), void>> static constexpr std::array from_compressed_unsafe(const uint256_t& compressed) noexcept; - constexpr affine_element& operator=(const affine_element& other) noexcept; + constexpr affine_element& operator=(const affine_element& other) noexcept = default; - constexpr affine_element& operator=(affine_element&& other) noexcept; + constexpr affine_element& operator=(affine_element&& other) noexcept = default; constexpr affine_element operator+(const affine_element& other) const noexcept; diff --git a/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp index a917dfebed7d..21fa09e3f64e 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp @@ -10,18 +10,6 @@ constexpr affine_element::affine_element(const Fq& a, const Fq& b) no , y(b) {} -template -constexpr affine_element::affine_element(const affine_element& other) noexcept - : x(other.x) - , y(other.y) -{} - -template -constexpr affine_element::affine_element(affine_element&& other) noexcept - : x(other.x) - , y(other.y) -{} - template template constexpr affine_element affine_element::from_compressed(const uint256_t& compressed) noexcept @@ -80,25 +68,6 @@ constexpr affine_element affine_element::operator+( return affine_element(element(*this) + element(other)); } -template -constexpr affine_element& affine_element::operator=(const affine_element& other) noexcept -{ - if (this == &other) { - return *this; - } - x = other.x; - y = other.y; - return *this; -} - -template -constexpr affine_element& affine_element::operator=(affine_element&& other) noexcept -{ - x = other.x; - y = other.y; - return *this; -} - template template diff --git a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp index d757c37c5eda..f06aea8497b2 100644 --- a/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/eccvm/eccvm_prover.cpp @@ -226,13 +226,17 @@ template void ECCVMProver_::execute_univariatizatio // Batch the unshifted polynomials and the to-be-shifted polynomials using ρ Polynomial batched_poly_unshifted(key->circuit_size); // batched unshifted polynomials size_t poly_idx = 0; // TODO(https://github.com/AztecProtocol/barretenberg/issues/391) zip + ASSERT(prover_polynomials.get_to_be_shifted().size() == prover_polynomials.get_shifted().size()); + for (auto& unshifted_poly : prover_polynomials.get_unshifted()) { + ASSERT(poly_idx < rhos.size()); batched_poly_unshifted.add_scaled(unshifted_poly, rhos[poly_idx]); ++poly_idx; } Polynomial batched_poly_to_be_shifted(key->circuit_size); // batched to-be-shifted polynomials for (auto& to_be_shifted_poly : prover_polynomials.get_to_be_shifted()) { + ASSERT(poly_idx < rhos.size()); batched_poly_to_be_shifted.add_scaled(to_be_shifted_poly, rhos[poly_idx]); ++poly_idx; }; diff --git a/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp b/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp index 0f1049f109fe..0b938556ae5b 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ecc_vm.hpp @@ -2,9 +2,11 @@ #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/ipa/ipa.hpp" #include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/common/std_array.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/relations/ecc_vm/ecc_lookup_relation.hpp" #include "barretenberg/relations/ecc_vm/ecc_msm_relation.hpp" @@ -85,715 +87,238 @@ template class ECCVMBa * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. */ - template - class PrecomputedEntities : public PrecomputedEntities_ { + template class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType lagrange_first; // column 0 - DataType lagrange_second; // column 1 - DataType lagrange_last; // column 2 - - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, &lagrange_first, &lagrange_second, &lagrange_last) + using DataType = DataType_; + DEFINE_FLAVOR_MEMBERS(DataType, + lagrange_first, // column 0 + lagrange_second, // column 1 + lagrange_last); // column 2 + + DataType get_selectors() { return get_all(); }; + RefVector get_sigma_polynomials() { return {}; }; + RefVector get_id_polynomials() { return {}; }; + RefVector get_table_polynomials() { return {}; }; + }; - std::vector get_selectors() override { return { lagrange_first, lagrange_second, lagrange_last }; }; - std::vector get_sigma_polynomials() override { return {}; }; - std::vector get_id_polynomials() override { return {}; }; - std::vector get_table_polynomials() { return {}; }; + /** + * @brief Container for all derived witness polynomials used/constructed by the prover. + * @details Shifts are not included here since they do not occupy their own memory. + */ + template struct DerivedWitnessEntities { + DEFINE_FLAVOR_MEMBERS(DataType, + z_perm, // column 0 + lookup_inverses); // column 1 }; /** * @brief Container for all witness polynomials used/constructed by the prover. * @details Shifts are not included here since they do not occupy their own memory. */ - template - class WitnessEntities : public WitnessEntities_ { + template class WireEntities { public: - DataType transcript_add; // column 0 - DataType transcript_mul; // column 1 - DataType transcript_eq; // column 2 - DataType transcript_collision_check; // column 3 - DataType transcript_msm_transition; // column 4 - DataType transcript_pc; // column 5 - DataType transcript_msm_count; // column 6 - DataType transcript_Px; // column 7 - DataType transcript_Py; // column 8 - DataType transcript_z1; // column 9 - DataType transcript_z2; // column 10 - DataType transcript_z1zero; // column 11 - DataType transcript_z2zero; // column 12 - DataType transcript_op; // column 13 - DataType transcript_accumulator_x; // column 14 - DataType transcript_accumulator_y; // column 15 - DataType transcript_msm_x; // column 16 - DataType transcript_msm_y; // column 17 - DataType precompute_pc; // column 18 - DataType precompute_point_transition; // column 19 - DataType precompute_round; // column 20 - DataType precompute_scalar_sum; // column 21 - DataType precompute_s1hi; // column 22 - DataType precompute_s1lo; // column 23 - DataType precompute_s2hi; // column 24 - DataType precompute_s2lo; // column 25 - DataType precompute_s3hi; // column 26 - DataType precompute_s3lo; // column 27 - DataType precompute_s4hi; // column 28 - DataType precompute_s4lo; // column 29 - DataType precompute_skew; // column 30 - DataType precompute_dx; // column 31 - DataType precompute_dy; // column 32 - DataType precompute_tx; // column 33 - DataType precompute_ty; // column 34 - DataType msm_transition; // column 35 - DataType msm_add; // column 36 - DataType msm_double; // column 37 - DataType msm_skew; // column 38 - DataType msm_accumulator_x; // column 39 - DataType msm_accumulator_y; // column 40 - DataType msm_pc; // column 41 - DataType msm_size_of_msm; // column 42 - DataType msm_count; // column 43 - DataType msm_round; // column 44 - DataType msm_add1; // column 45 - DataType msm_add2; // column 46 - DataType msm_add3; // column 47 - DataType msm_add4; // column 48 - DataType msm_x1; // column 49 - DataType msm_y1; // column 50 - DataType msm_x2; // column 51 - DataType msm_y2; // column 52 - DataType msm_x3; // column 53 - DataType msm_y3; // column 54 - DataType msm_x4; // column 55 - DataType msm_y4; // column 56 - DataType msm_collision_x1; // column 57 - DataType msm_collision_x2; // column 58 - DataType msm_collision_x3; // column 59 - DataType msm_collision_x4; // column 60 - DataType msm_lambda1; // column 61 - DataType msm_lambda2; // column 62 - DataType msm_lambda3; // column 63 - DataType msm_lambda4; // column 64 - DataType msm_slice1; // column 65 - DataType msm_slice2; // column 66 - DataType msm_slice3; // column 67 - DataType msm_slice4; // column 68 - DataType transcript_accumulator_empty; // column 69 - DataType transcript_reset_accumulator; // column 70 - DataType precompute_select; // column 71 - DataType lookup_read_counts_0; // column 72 - DataType lookup_read_counts_1; // column 73 - DataType z_perm; // column 74 - DataType lookup_inverses; // column 75 + DEFINE_FLAVOR_MEMBERS(DataType, + transcript_add, // column 0 + transcript_mul, // column 1 + transcript_eq, // column 2 + transcript_collision_check, // column 3 + transcript_msm_transition, // column 4 + transcript_pc, // column 5 + transcript_msm_count, // column 6 + transcript_Px, // column 7 + transcript_Py, // column 8 + transcript_z1, // column 9 + transcript_z2, // column 10 + transcript_z1zero, // column 11 + transcript_z2zero, // column 12 + transcript_op, // column 13 + transcript_accumulator_x, // column 14 + transcript_accumulator_y, // column 15 + transcript_msm_x, // column 16 + transcript_msm_y, // column 17 + precompute_pc, // column 18 + precompute_point_transition, // column 19 + precompute_round, // column 20 + precompute_scalar_sum, // column 21 + precompute_s1hi, // column 22 + precompute_s1lo, // column 23 + precompute_s2hi, // column 24 + precompute_s2lo, // column 25 + precompute_s3hi, // column 26 + precompute_s3lo, // column 27 + precompute_s4hi, // column 28 + precompute_s4lo, // column 29 + precompute_skew, // column 30 + precompute_dx, // column 31 + precompute_dy, // column 32 + precompute_tx, // column 33 + precompute_ty, // column 34 + msm_transition, // column 35 + msm_add, // column 36 + msm_double, // column 37 + msm_skew, // column 38 + msm_accumulator_x, // column 39 + msm_accumulator_y, // column 40 + msm_pc, // column 41 + msm_size_of_msm, // column 42 + msm_count, // column 43 + msm_round, // column 44 + msm_add1, // column 45 + msm_add2, // column 46 + msm_add3, // column 47 + msm_add4, // column 48 + msm_x1, // column 49 + msm_y1, // column 50 + msm_x2, // column 51 + msm_y2, // column 52 + msm_x3, // column 53 + msm_y3, // column 54 + msm_x4, // column 55 + msm_y4, // column 56 + msm_collision_x1, // column 57 + msm_collision_x2, // column 58 + msm_collision_x3, // column 59 + msm_collision_x4, // column 60 + msm_lambda1, // column 61 + msm_lambda2, // column 62 + msm_lambda3, // column 63 + msm_lambda4, // column 64 + msm_slice1, // column 65 + msm_slice2, // column 66 + msm_slice3, // column 67 + msm_slice4, // column 68 + transcript_accumulator_empty, // column 69 + transcript_reset_accumulator, // column 70 + precompute_select, // column 71 + lookup_read_counts_0, // column 72 + lookup_read_counts_1); // column 73 + }; - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &transcript_add, - &transcript_mul, - &transcript_eq, - &transcript_collision_check, - &transcript_msm_transition, - &transcript_pc, - &transcript_msm_count, - &transcript_Px, - &transcript_Py, - &transcript_z1, - &transcript_z2, - &transcript_z1zero, - &transcript_z2zero, - &transcript_op, - &transcript_accumulator_x, - &transcript_accumulator_y, - &transcript_msm_x, - &transcript_msm_y, - &precompute_pc, - &precompute_point_transition, - &precompute_round, - &precompute_scalar_sum, - &precompute_s1hi, - &precompute_s1lo, - &precompute_s2hi, - &precompute_s2lo, - &precompute_s3hi, - &precompute_s3lo, - &precompute_s4hi, - &precompute_s4lo, - &precompute_skew, - &precompute_dx, - &precompute_dy, - &precompute_tx, - &precompute_ty, - &msm_transition, - &msm_add, - &msm_double, - &msm_skew, - &msm_accumulator_x, - &msm_accumulator_y, - &msm_pc, - &msm_size_of_msm, - &msm_count, - &msm_round, - &msm_add1, - &msm_add2, - &msm_add3, - &msm_add4, - &msm_x1, - &msm_y1, - &msm_x2, - &msm_y2, - &msm_x3, - &msm_y3, - &msm_x4, - &msm_y4, - &msm_collision_x1, - &msm_collision_x2, - &msm_collision_x3, - &msm_collision_x4, - &msm_lambda1, - &msm_lambda2, - &msm_lambda3, - &msm_lambda4, - &msm_slice1, - &msm_slice2, - &msm_slice3, - &msm_slice4, - &transcript_accumulator_empty, - &transcript_reset_accumulator, - &precompute_select, - &lookup_read_counts_0, - &lookup_read_counts_1, - &z_perm, - &lookup_inverses) - std::vector get_wires() override - { - return { - transcript_add, - transcript_mul, - transcript_eq, - transcript_collision_check, - transcript_msm_transition, - transcript_pc, - transcript_msm_count, - transcript_Px, - transcript_Py, - transcript_z1, - transcript_z2, - transcript_z1zero, - transcript_z2zero, - transcript_op, - transcript_accumulator_x, - transcript_accumulator_y, - transcript_msm_x, - transcript_msm_y, - precompute_pc, - precompute_point_transition, - precompute_round, - precompute_scalar_sum, - precompute_s1hi, - precompute_s1lo, - precompute_s2hi, - precompute_s2lo, - precompute_s3hi, - precompute_s3lo, - precompute_s4hi, - precompute_s4lo, - precompute_skew, - precompute_dx, - precompute_dy, - precompute_tx, - precompute_ty, - msm_transition, - msm_add, - msm_double, - msm_skew, - msm_accumulator_x, - msm_accumulator_y, - msm_pc, - msm_size_of_msm, - msm_count, - msm_round, - msm_add1, - msm_add2, - msm_add3, - msm_add4, - msm_x1, - msm_y1, - msm_x2, - msm_y2, - msm_x3, - msm_y3, - msm_x4, - msm_y4, - msm_collision_x1, - msm_collision_x2, - msm_collision_x3, - msm_collision_x4, - msm_lambda1, - msm_lambda2, - msm_lambda3, - msm_lambda4, - msm_slice1, - msm_slice2, - msm_slice3, - msm_slice4, - transcript_accumulator_empty, - transcript_reset_accumulator, - precompute_select, - lookup_read_counts_0, - lookup_read_counts_1, - }; - }; + /** + * @brief Container for all witness polynomials used/constructed by the prover. + * @details Shifts are not included here since they do not occupy their own memory. + */ + template + class WitnessEntities : public WireEntities, public DerivedWitnessEntities { + public: + DEFINE_COMPOUND_GET_ALL(WireEntities::get_all(), DerivedWitnessEntities::get_all()) + DEFINE_COMPOUND_POINTER_VIEW(WireEntities::pointer_view(), + DerivedWitnessEntities::pointer_view()) + RefVector get_wires() { return WireEntities::get_all(); }; // The sorted concatenations of table and witness data needed for plookup. - std::vector get_sorted_polynomials() { return {}; }; + RefVector get_sorted_polynomials() { return {}; }; }; + /** + * @brief Represents polynomials shifted by 1 or their evaluations, defined relative to WitnessEntities. + */ + template class ShiftedEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + transcript_mul_shift, // column 0 + transcript_msm_count_shift, // column 1 + transcript_accumulator_x_shift, // column 2 + transcript_accumulator_y_shift, // column 3 + precompute_scalar_sum_shift, // column 4 + precompute_s1hi_shift, // column 5 + precompute_dx_shift, // column 6 + precompute_dy_shift, // column 7 + precompute_tx_shift, // column 8 + precompute_ty_shift, // column 9 + msm_transition_shift, // column 10 + msm_add_shift, // column 11 + msm_double_shift, // column 12 + msm_skew_shift, // column 13 + msm_accumulator_x_shift, // column 14 + msm_accumulator_y_shift, // column 15 + msm_count_shift, // column 16 + msm_round_shift, // column 17 + msm_add1_shift, // column 18 + msm_pc_shift, // column 19 + precompute_pc_shift, // column 20 + transcript_pc_shift, // column 21 + precompute_round_shift, // column 22 + transcript_accumulator_empty_shift, // column 23 + precompute_select_shift, // column 24 + z_perm_shift); // column 25 + }; /** * @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during * sumcheck) in this Honk variant along with particular subsets of interest * @details Used to build containers for: the prover's polynomial during sumcheck; the sumcheck's folded * polynomials; the univariates consturcted during during sumcheck; the evaluations produced by sumcheck. * - * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be - * implemented as such, but we have this now. + * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + ShiftedEntities. + * TODO(https://github.com/AztecProtocol/barretenberg/issues/788): Move to normal composition once comfortable + * updating usage sites. */ - template - class AllEntities : public AllEntities_ { + template + class AllEntities : public PrecomputedEntities, + public WitnessEntities, + public ShiftedEntities { public: - DataType lagrange_first; // column 0 - DataType lagrange_second; // column 1 - DataType lagrange_last; // column 2 - DataType transcript_add; // column 3 - DataType transcript_mul; // column 4 - DataType transcript_eq; // column 5 - DataType transcript_collision_check; // column 6 - DataType transcript_msm_transition; // column 7 - DataType transcript_pc; // column 8 - DataType transcript_msm_count; // column 9 - DataType transcript_Px; // column 10 - DataType transcript_Py; // column 11 - DataType transcript_z1; // column 12 - DataType transcript_z2; // column 13 - DataType transcript_z1zero; // column 14 - DataType transcript_z2zero; // column 15 - DataType transcript_op; // column 16 - DataType transcript_accumulator_x; // column 17 - DataType transcript_accumulator_y; // column 18 - DataType transcript_msm_x; // column 19 - DataType transcript_msm_y; // column 20 - DataType precompute_pc; // column 21 - DataType precompute_point_transition; // column 22 - DataType precompute_round; // column 23 - DataType precompute_scalar_sum; // column 24 - DataType precompute_s1hi; // column 25 - DataType precompute_s1lo; // column 26 - DataType precompute_s2hi; // column 27 - DataType precompute_s2lo; // column 28 - DataType precompute_s3hi; // column 29 - DataType precompute_s3lo; // column 30 - DataType precompute_s4hi; // column 31 - DataType precompute_s4lo; // column 32 - DataType precompute_skew; // column 33 - DataType precompute_dx; // column 34 - DataType precompute_dy; // column 35 - DataType precompute_tx; // column 36 - DataType precompute_ty; // column 37 - DataType msm_transition; // column 38 - DataType msm_add; // column 39 - DataType msm_double; // column 40 - DataType msm_skew; // column 41 - DataType msm_accumulator_x; // column 42 - DataType msm_accumulator_y; // column 43 - DataType msm_pc; // column 44 - DataType msm_size_of_msm; // column 45 - DataType msm_count; // column 46 - DataType msm_round; // column 47 - DataType msm_add1; // column 48 - DataType msm_add2; // column 49 - DataType msm_add3; // column 50 - DataType msm_add4; // column 51 - DataType msm_x1; // column 52 - DataType msm_y1; // column 53 - DataType msm_x2; // column 54 - DataType msm_y2; // column 55 - DataType msm_x3; // column 56 - DataType msm_y3; // column 57 - DataType msm_x4; // column 58 - DataType msm_y4; // column 59 - DataType msm_collision_x1; // column 60 - DataType msm_collision_x2; // column 61 - DataType msm_collision_x3; // column 62 - DataType msm_collision_x4; // column 63 - DataType msm_lambda1; // column 64 - DataType msm_lambda2; // column 65 - DataType msm_lambda3; // column 66 - DataType msm_lambda4; // column 67 - DataType msm_slice1; // column 68 - DataType msm_slice2; // column 69 - DataType msm_slice3; // column 70 - DataType msm_slice4; // column 71 - DataType transcript_accumulator_empty; // column 72 - DataType transcript_reset_accumulator; // column 73 - DataType precompute_select; // column 74 - DataType lookup_read_counts_0; // column 75 - DataType lookup_read_counts_1; // column 76 - DataType z_perm; // column 77 - DataType lookup_inverses; // column 78 - DataType transcript_mul_shift; // column 79 - DataType transcript_msm_count_shift; // column 80 - DataType transcript_accumulator_x_shift; // column 81 - DataType transcript_accumulator_y_shift; // column 82 - DataType precompute_scalar_sum_shift; // column 83 - DataType precompute_s1hi_shift; // column 84 - DataType precompute_dx_shift; // column 85 - DataType precompute_dy_shift; // column 86 - DataType precompute_tx_shift; // column 87 - DataType precompute_ty_shift; // column 88 - DataType msm_transition_shift; // column 89 - DataType msm_add_shift; // column 90 - DataType msm_double_shift; // column 91 - DataType msm_skew_shift; // column 92 - DataType msm_accumulator_x_shift; // column 93 - DataType msm_accumulator_y_shift; // column 94 - DataType msm_count_shift; // column 95 - DataType msm_round_shift; // column 96 - DataType msm_add1_shift; // column 97 - DataType msm_pc_shift; // column 98 - DataType precompute_pc_shift; // column 99 - DataType transcript_pc_shift; // column 100 - DataType precompute_round_shift; // column 101 - DataType transcript_accumulator_empty_shift; // column 102 - DataType precompute_select_shift; // column 103 - DataType z_perm_shift; // column 104 - - template [[nodiscard]] const DataType& lookup_read_counts() const - { - if constexpr (index == 0) { - return lookup_read_counts_0; - } else { - static_assert(index == 1); - return lookup_read_counts_1; - } - } - - // defines a method pointer_view that returns the following, with const and non-const variants - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &lagrange_first, - &lagrange_second, - &lagrange_last, - &transcript_add, - &transcript_mul, - &transcript_eq, - &transcript_collision_check, - &transcript_msm_transition, - &transcript_pc, - &transcript_msm_count, - &transcript_Px, - &transcript_Py, - &transcript_z1, - &transcript_z2, - &transcript_z1zero, - &transcript_z2zero, - &transcript_op, - &transcript_accumulator_x, - &transcript_accumulator_y, - &transcript_msm_x, - &transcript_msm_y, - &precompute_pc, - &precompute_point_transition, - &precompute_round, - &precompute_scalar_sum, - &precompute_s1hi, - &precompute_s1lo, - &precompute_s2hi, - &precompute_s2lo, - &precompute_s3hi, - &precompute_s3lo, - &precompute_s4hi, - &precompute_s4lo, - &precompute_skew, - &precompute_dx, - &precompute_dy, - &precompute_tx, - &precompute_ty, - &msm_transition, - &msm_add, - &msm_double, - &msm_skew, - &msm_accumulator_x, - &msm_accumulator_y, - &msm_pc, - &msm_size_of_msm, - &msm_count, - &msm_round, - &msm_add1, - &msm_add2, - &msm_add3, - &msm_add4, - &msm_x1, - &msm_y1, - &msm_x2, - &msm_y2, - &msm_x3, - &msm_y3, - &msm_x4, - &msm_y4, - &msm_collision_x1, - &msm_collision_x2, - &msm_collision_x3, - &msm_collision_x4, - &msm_lambda1, - &msm_lambda2, - &msm_lambda3, - &msm_lambda4, - &msm_slice1, - &msm_slice2, - &msm_slice3, - &msm_slice4, - &transcript_accumulator_empty, - &transcript_reset_accumulator, - &precompute_select, - &lookup_read_counts_0, - &lookup_read_counts_1, - &z_perm, - &lookup_inverses, - &transcript_mul_shift, - &transcript_msm_count_shift, - &transcript_accumulator_x_shift, - &transcript_accumulator_y_shift, - &precompute_scalar_sum_shift, - &precompute_s1hi_shift, - &precompute_dx_shift, - &precompute_dy_shift, - &precompute_tx_shift, - &precompute_ty_shift, - &msm_transition_shift, - &msm_add_shift, - &msm_double_shift, - &msm_skew_shift, - &msm_accumulator_x_shift, - &msm_accumulator_y_shift, - &msm_count_shift, - &msm_round_shift, - &msm_add1_shift, - &msm_pc_shift, - &precompute_pc_shift, - &transcript_pc_shift, - &precompute_round_shift, - &transcript_accumulator_empty_shift, - &precompute_select_shift, - &z_perm_shift) - std::vector get_wires() override - { - return { - transcript_add, - transcript_mul, - transcript_eq, - transcript_collision_check, - transcript_msm_transition, - transcript_pc, - transcript_msm_count, - transcript_Px, - transcript_Py, - transcript_z1, - transcript_z2, - transcript_z1zero, - transcript_z2zero, - transcript_op, - transcript_accumulator_x, - transcript_accumulator_y, - transcript_msm_x, - transcript_msm_y, - precompute_pc, - precompute_point_transition, - precompute_round, - precompute_scalar_sum, - precompute_s1hi, - precompute_s1lo, - precompute_s2hi, - precompute_s2lo, - precompute_s3hi, - precompute_s3lo, - precompute_s4hi, - precompute_s4lo, - precompute_skew, - precompute_dx, - precompute_dy, - precompute_tx, - precompute_ty, - msm_transition, - msm_add, - msm_double, - msm_skew, - msm_accumulator_x, - msm_accumulator_y, - msm_pc, - msm_size_of_msm, - msm_count, - msm_round, - msm_add1, - msm_add2, - msm_add3, - msm_add4, - msm_x1, - msm_y1, - msm_x2, - msm_y2, - msm_x3, - msm_y3, - msm_x4, - msm_y4, - msm_collision_x1, - msm_collision_x2, - msm_collision_x3, - msm_collision_x4, - msm_lambda1, - msm_lambda2, - msm_lambda3, - msm_lambda4, - msm_slice1, - msm_slice2, - msm_slice3, - msm_slice4, - transcript_accumulator_empty, - transcript_reset_accumulator, - precompute_select, - lookup_read_counts_0, - lookup_read_counts_1, - }; - }; + // Initialize members + AllEntities() + : PrecomputedEntities{} + , WitnessEntities{} + , ShiftedEntities{} + {} + // get_wires is inherited + + DEFINE_COMPOUND_GET_ALL(PrecomputedEntities::get_all(), + WitnessEntities::get_all(), + ShiftedEntities::get_all()) + DEFINE_COMPOUND_POINTER_VIEW(PrecomputedEntities::pointer_view(), + WitnessEntities::pointer_view(), + ShiftedEntities::pointer_view()) // Gemini-specific getters. - std::vector get_unshifted() override + RefVector get_unshifted() { - return { - lagrange_first, - lagrange_second, - lagrange_last, - transcript_add, - transcript_eq, - transcript_collision_check, - transcript_msm_transition, - transcript_Px, - transcript_Py, - transcript_z1, - transcript_z2, - transcript_z1zero, - transcript_z2zero, - transcript_op, - transcript_msm_x, - transcript_msm_y, - precompute_point_transition, - precompute_s1hi, - precompute_s2hi, - precompute_s2lo, - precompute_s3hi, - precompute_s3lo, - precompute_s4hi, - precompute_s4lo, - precompute_skew, - msm_size_of_msm, - msm_add2, - msm_add3, - msm_add4, - msm_x1, - msm_y1, - msm_x2, - msm_y2, - msm_x3, - msm_y3, - msm_x4, - msm_y4, - msm_collision_x1, - msm_collision_x2, - msm_collision_x3, - msm_collision_x4, - msm_lambda1, - msm_lambda2, - msm_lambda3, - msm_lambda4, - msm_slice1, - msm_slice2, - msm_slice3, - msm_slice4, - transcript_reset_accumulator, - lookup_read_counts_0, - lookup_read_counts_1, - lookup_inverses, - }; + return concatenate(PrecomputedEntities::get_all(), WitnessEntities::get_all()); }; - std::vector get_to_be_shifted() override + RefVector get_to_be_shifted() { - return { - transcript_mul, - transcript_msm_count, - transcript_accumulator_x, - transcript_accumulator_y, - precompute_scalar_sum, - precompute_s1hi, - precompute_dx, - precompute_dy, - precompute_tx, - precompute_ty, - msm_transition, - msm_add, - msm_double, - msm_skew, - msm_accumulator_x, - msm_accumulator_y, - msm_count, - msm_round, - msm_add1, - msm_pc, - precompute_pc, - transcript_pc, - precompute_round, - transcript_accumulator_empty, - precompute_select, - z_perm, - }; - }; - std::vector get_shifted() override - { - return { - transcript_mul_shift, - transcript_msm_count_shift, - transcript_accumulator_x_shift, - transcript_accumulator_y_shift, - precompute_scalar_sum_shift, - precompute_s1hi_shift, - precompute_dx_shift, - precompute_dy_shift, - precompute_tx_shift, - precompute_ty_shift, - msm_transition_shift, - msm_add_shift, - msm_double_shift, - msm_skew_shift, - msm_accumulator_x_shift, - msm_accumulator_y_shift, - msm_count_shift, - msm_round_shift, - msm_add1_shift, - msm_pc_shift, - precompute_pc_shift, - transcript_pc_shift, - precompute_round_shift, - transcript_accumulator_empty_shift, - precompute_select_shift, - z_perm_shift, - }; - }; + return { this->transcript_mul, + this->transcript_msm_count, + this->transcript_accumulator_x, + this->transcript_accumulator_y, + this->precompute_scalar_sum, + this->precompute_s1hi, + this->precompute_dx, + this->precompute_dy, + this->precompute_tx, + this->precompute_ty, + this->msm_transition, + this->msm_add, + this->msm_double, + this->msm_skew, + this->msm_accumulator_x, + this->msm_accumulator_y, + this->msm_count, + this->msm_round, + this->msm_add1, + this->msm_pc, + this->precompute_pc, + this->transcript_pc, + this->precompute_round, + this->transcript_accumulator_empty, + this->precompute_select, + this->z_perm }; + } + RefVector get_shifted() { return ShiftedEntities::get_all(); }; }; public: /** * @brief The proving key is responsible for storing the polynomials used by the prover. - * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve inherit - * from ProvingKey. + * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve + * inherit from ProvingKey. */ - class ProvingKey : public ProvingKey_, - WitnessEntities> { + class ProvingKey : public ProvingKey_, WitnessEntities> { public: // Expose constructors on the base class - using Base = ProvingKey_, - WitnessEntities>; + using Base = ProvingKey_, WitnessEntities>; using Base::Base; // The plookup wires that store plookup read data. @@ -804,25 +329,25 @@ template class ECCVMBa * @brief The verification key is responsible for storing the the commitments to the precomputed (non-witnessk) * polynomials used by the verifier. * - * @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to resolve - * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our - * circuits. + * @note Note the discrepancy with what sort of data is stored here vs in the proving key. We may want to + * resolve that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for + * portability of our circuits. */ - using VerificationKey = VerificationKey_>; + using VerificationKey = VerificationKey_>; /** * @brief A container for polynomials produced after the first round of sumcheck. * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. */ - using FoldedPolynomials = AllEntities, PolynomialHandle>; + using FoldedPolynomials = AllEntities>; /** - * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated - * at one point. + * @brief A field element for each entity of the flavor. These entities represent the prover polynomials + * evaluated at one point. */ - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; AllValues(std::array _data_in) { this->_data = _data_in; } }; @@ -830,15 +355,15 @@ template class ECCVMBa /** * @brief An owning container of polynomials. * @warning When this was introduced it broke some of our design principles. - * - Execution trace builders don't handle "polynomials" because the interpretation of the execution trace columns - * as polynomials is a detail of the proving system, and trace builders are (sometimes in practice, always in - * principle) reusable for different proving protocols (e.g., Plonk and Honk). + * - Execution trace builders don't handle "polynomials" because the interpretation of the execution trace + * columns as polynomials is a detail of the proving system, and trace builders are (sometimes in practice, + * always in principle) reusable for different proving protocols (e.g., Plonk and Honk). * - Polynomial storage is handled by key classes. Polynomials aren't moved, but are accessed elsewhere by * std::spans. * * We will consider revising this data model: TODO(https://github.com/AztecProtocol/barretenberg/issues/743) */ - class AllPolynomials : public AllEntities { + class AllPolynomials : public AllEntities { public: [[nodiscard]] size_t get_polynomial_size() const { return this->lagrange_first.size(); } AllValues get_row(const size_t row_idx) const @@ -854,12 +379,12 @@ template class ECCVMBa * @brief A container for polynomials produced after the first round of sumcheck. * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. */ - using RowPolynomials = AllEntities; + using RowPolynomials = AllEntities; /** * @brief A container for storing the partially evaluated multivariates produced by sumcheck. */ - class PartiallyEvaluatedMultivariates : public AllEntities { + class PartiallyEvaluatedMultivariates : public AllEntities { public: PartiallyEvaluatedMultivariates() = default; @@ -875,8 +400,7 @@ template class ECCVMBa /** * @brief A container for univariates used during sumcheck. */ - template - using ProverUnivariates = AllEntities, barretenberg::Univariate>; + template using ProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -886,7 +410,7 @@ template class ECCVMBa /** * @brief A container for the prover polynomials handles; only stores spans. */ - class ProverPolynomials : public AllEntities { + class ProverPolynomials : public AllEntities { public: /** * @brief Returns the evaluations of all prover polynomials at one point on the boolean hypercube, which @@ -904,17 +428,17 @@ template class ECCVMBa /** * @brief A container for commitment labels. - * @note It's debatable whether this should inherit from AllEntities. since most entries are not strictly needed. It - * has, however, been useful during debugging to have these labels available. + * @note It's debatable whether this should inherit from AllEntities. since most entries are not strictly + * needed. It has, however, been useful during debugging to have these labels available. * */ - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { private: - using Base = AllEntities; + using Base = AllEntities; public: CommitmentLabels() - : AllEntities() + : AllEntities() { Base::transcript_add = "TRANSCRIPT_ADD"; Base::transcript_mul = "TRANSCRIPT_MUL"; @@ -999,9 +523,9 @@ template class ECCVMBa }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { private: - using Base = AllEntities; + using Base = AllEntities; public: VerifierCommitments(const std::shared_ptr& verification_key, @@ -1115,7 +639,7 @@ template class ECCVMBa : BaseTranscript(proof) {} - void deserialize_full_transcript() override + void deserialize_full_transcript() { // take current proof and put them into the struct size_t num_bytes_read = 0; @@ -1312,7 +836,7 @@ template class ECCVMBa } } - void serialize_full_transcript() override + void serialize_full_transcript() { size_t old_proof_length = BaseTranscript::proof_data.size(); BaseTranscript::proof_data.clear(); diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp index 4f9f1d515b97..4d29ca7ffb2c 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.hpp @@ -64,6 +64,7 @@ */ #pragma once +#include "barretenberg/common/std_array.hpp" #include "barretenberg/common/zip_view.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" @@ -75,63 +76,16 @@ namespace proof_system::honk::flavor { -#define DEFINE_POINTER_VIEW(ExpectedSize, ...) \ - [[nodiscard]] auto pointer_view() \ - { \ - std::array view{ __VA_ARGS__ }; \ - static_assert(view.size() == ExpectedSize, \ - "Expected array size to match given size (first parameter) in DEFINE_POINTER_VIEW"); \ - return view; \ - } \ - [[nodiscard]] auto pointer_view() const \ - { \ - std::array view{ __VA_ARGS__ }; \ - static_assert(view.size() == ExpectedSize, \ - "Expected array size to match given size (first parameter) in DEFINE_POINTER_VIEW"); \ - return view; \ - } - -/** - * @brief Base data class template, a wrapper for std::array, from which every flavor class ultimately derives. - * - * @tparam T The underlying data type stored in the array - * @tparam HandleType The type that will be used to - * @tparam NUM_ENTITIES The size of the underlying array. - */ -template class Entities_ { - public: - virtual ~Entities_() = default; - - constexpr size_t size() { return NUM_ENTITIES; }; -}; - /** * @brief Base class template containing circuit-specifying data. * */ -template -class PrecomputedEntities_ : public Entities_ { +class PrecomputedEntitiesBase { public: - using DataType = DataType_; - size_t circuit_size; size_t log_circuit_size; size_t num_public_inputs; CircuitType circuit_type; // TODO(#392) - - virtual std::vector get_selectors() = 0; - virtual std::vector get_sigma_polynomials() = 0; - virtual std::vector get_id_polynomials() = 0; -}; - -/** - * @brief Base class template containing witness (wires and derived witnesses). - * @details Shifts are not included here since they do not occupy their own memory. - */ -template -class WitnessEntities_ : public Entities_ { - public: - virtual std::vector get_wires() = 0; }; /** @@ -186,27 +140,10 @@ template class VerificationKey_ : public Preco }; }; -/** - * @brief Base class containing all entities (or handles on these) in one place. - * - * @tparam PrecomputedEntities An instance of PrecomputedEntities_ with affine_element data type and handle type. - */ -template -class AllEntities_ : public Entities_ { - public: - virtual std::vector get_wires() = 0; - virtual std::vector get_unshifted() = 0; - virtual std::vector get_to_be_shifted() = 0; - virtual std::vector get_shifted() = 0; - - // Because of how Gemini is written, is importat to put the polynomials out in this order. - std::vector get_unshifted_then_shifted() - { - std::vector result{ get_unshifted() }; - std::vector shifted{ get_shifted() }; - result.insert(result.end(), shifted.begin(), shifted.end()); - return result; - }; +// Because of how Gemini is written, is importat to put the polynomials out in this order. +auto get_unshifted_then_shifted(const auto& all_entities) +{ + return concatenate(all_entities.get_unshifted(), all_entities.get_shifted()); }; /** diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp b/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp index 8e99d56e3974..4b2c8fc27524 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor.test.cpp @@ -28,15 +28,14 @@ TEST(Flavor, Getters) EXPECT_EQ(proving_key.id_2[0], FF(4)); EXPECT_EQ(proving_key.id_3[0], FF(8)); - Flavor::VerificationKey verification_key; Flavor::ProverPolynomials prover_polynomials; - Flavor::AllValues evals; Flavor::CommitmentLabels commitment_labels; // Globals are also available through STL container sizes - EXPECT_EQ(prover_polynomials.size(), Flavor::NUM_ALL_ENTITIES); + EXPECT_EQ(prover_polynomials.get_all().size(), Flavor::NUM_ALL_ENTITIES); // Shited polynomials have the righ tsize - EXPECT_EQ(prover_polynomials.size(), prover_polynomials.get_unshifted_then_shifted().size()); + EXPECT_EQ(prover_polynomials.get_all().size(), + prover_polynomials.get_shifted().size() + prover_polynomials.get_unshifted().size()); // Commitment lables are stored in the flavor. EXPECT_EQ(commitment_labels.w_r, "W_R"); diff --git a/barretenberg/cpp/src/barretenberg/flavor/flavor_macros.hpp b/barretenberg/cpp/src/barretenberg/flavor/flavor_macros.hpp new file mode 100644 index 000000000000..c378aa514896 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/flavor/flavor_macros.hpp @@ -0,0 +1,71 @@ +#pragma once + +// Macros for defining the flavor classes. +// These are used to derive iterator methods along with the body of a 'flavor' class. +// DEFINE_FLAVOR_MEMBERS lets you define a flavor entity as a collection of individual members, and derive an iterator. +// while DEFINE_COMPOUND_GET_ALL and DEFINE_COMPOUND_POINTER_VIEW let you combine the iterators of substructures or base +// classes. + +#include "barretenberg/common/ref_vector.hpp" +#include "barretenberg/common/std_array.hpp" +#include +#include +#include + +template auto _refs_to_pointer_array(Refs&... refs) +{ + return std::array{ &refs... }; +} + +// @deprecated this was less natural than the ref view +#define DEFINE_POINTER_VIEW(...) \ + [[nodiscard]] auto pointer_view() \ + { \ + return _refs_to_pointer_array(__VA_ARGS__); \ + } \ + [[nodiscard]] auto pointer_view() const \ + { \ + return _refs_to_pointer_array(__VA_ARGS__); \ + } + +#define DEFINE_REF_VIEW(...) \ + [[nodiscard]] auto get_all() \ + { \ + return RefVector{ __VA_ARGS__ }; \ + } \ + [[nodiscard]] auto get_all() const \ + { \ + return RefVector{ __VA_ARGS__ }; \ + } + +/** + * @brief Define the body of a flavor class, included each member and a pointer view with which to iterate the struct. + * + * @tparam T The underlying data type stored in the array + * @tparam HandleType The type that will be used to + * @tparam NUM_ENTITIES The size of the underlying array. + */ +#define DEFINE_FLAVOR_MEMBERS(DataType, ...) \ + DataType __VA_ARGS__; \ + DEFINE_POINTER_VIEW(__VA_ARGS__) \ + DEFINE_REF_VIEW(__VA_ARGS__) + +#define DEFINE_COMPOUND_POINTER_VIEW(...) \ + [[nodiscard]] auto pointer_view() \ + { \ + return concatenate(__VA_ARGS__); \ + } \ + [[nodiscard]] auto pointer_view() const \ + { \ + return concatenate(__VA_ARGS__); \ + } + +#define DEFINE_COMPOUND_GET_ALL(...) \ + [[nodiscard]] auto get_all() \ + { \ + return concatenate(__VA_ARGS__); \ + } \ + [[nodiscard]] auto get_all() const \ + { \ + return concatenate(__VA_ARGS__); \ + } diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp index 9e0c6c9bc345..7f2b128a3f23 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp @@ -8,6 +8,7 @@ #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/generated/AvmMini.hpp" @@ -57,16 +58,12 @@ class AvmMiniFlavor { static constexpr bool has_zero_row = true; private: - template - class PrecomputedEntities : public PrecomputedEntities_ { + template class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType avmMini_clk; - DataType avmMini_positive; - DataType avmMini_first; + using DataType = DataType_; + DEFINE_FLAVOR_MEMBERS(DataType, avmMini_clk, avmMini_positive, avmMini_first); - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, &avmMini_clk, &avmMini_positive, &avmMini_first) - - std::vector get_selectors() override + RefVector get_selectors() { return { avmMini_clk, @@ -75,58 +72,36 @@ class AvmMiniFlavor { }; }; - std::vector get_sigma_polynomials() override { return {}; }; - std::vector get_id_polynomials() override { return {}; }; - std::vector get_table_polynomials() { return {}; }; + RefVector get_sigma_polynomials() { return {}; }; + RefVector get_id_polynomials() { return {}; }; + RefVector get_table_polynomials() { return {}; }; }; - template - class WitnessEntities : public WitnessEntities_ { + template class WitnessEntities { public: - DataType avmMini_subop; - DataType avmMini_ia; - DataType avmMini_ib; - DataType avmMini_ic; - DataType avmMini_mem_op_a; - DataType avmMini_mem_op_b; - DataType avmMini_mem_op_c; - DataType avmMini_rwa; - DataType avmMini_rwb; - DataType avmMini_rwc; - DataType avmMini_mem_idx_a; - DataType avmMini_mem_idx_b; - DataType avmMini_mem_idx_c; - DataType avmMini_last; - DataType avmMini_m_clk; - DataType avmMini_m_sub_clk; - DataType avmMini_m_addr; - DataType avmMini_m_val; - DataType avmMini_m_lastAccess; - DataType avmMini_m_rw; - - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &avmMini_subop, - &avmMini_ia, - &avmMini_ib, - &avmMini_ic, - &avmMini_mem_op_a, - &avmMini_mem_op_b, - &avmMini_mem_op_c, - &avmMini_rwa, - &avmMini_rwb, - &avmMini_rwc, - &avmMini_mem_idx_a, - &avmMini_mem_idx_b, - &avmMini_mem_idx_c, - &avmMini_last, - &avmMini_m_clk, - &avmMini_m_sub_clk, - &avmMini_m_addr, - &avmMini_m_val, - &avmMini_m_lastAccess, - &avmMini_m_rw) - - std::vector get_wires() override + DEFINE_FLAVOR_MEMBERS(DataType, + avmMini_subop, + avmMini_ia, + avmMini_ib, + avmMini_ic, + avmMini_mem_op_a, + avmMini_mem_op_b, + avmMini_mem_op_c, + avmMini_rwa, + avmMini_rwb, + avmMini_rwc, + avmMini_mem_idx_a, + avmMini_mem_idx_b, + avmMini_mem_idx_c, + avmMini_last, + avmMini_m_clk, + avmMini_m_sub_clk, + avmMini_m_addr, + avmMini_m_val, + avmMini_m_lastAccess, + avmMini_m_rw); + + RefVector get_wires() { return { avmMini_subop, avmMini_ia, avmMini_ib, avmMini_ic, avmMini_mem_op_a, @@ -137,70 +112,42 @@ class AvmMiniFlavor { }; }; - std::vector get_sorted_polynomials() { return {}; }; + RefVector get_sorted_polynomials() { return {}; }; }; - template - class AllEntities : public AllEntities_ { + template class AllEntities { public: - DataType avmMini_clk; - DataType avmMini_positive; - DataType avmMini_first; - - DataType avmMini_subop; - DataType avmMini_ia; - DataType avmMini_ib; - DataType avmMini_ic; - DataType avmMini_mem_op_a; - DataType avmMini_mem_op_b; - DataType avmMini_mem_op_c; - DataType avmMini_rwa; - DataType avmMini_rwb; - DataType avmMini_rwc; - DataType avmMini_mem_idx_a; - DataType avmMini_mem_idx_b; - DataType avmMini_mem_idx_c; - DataType avmMini_last; - DataType avmMini_m_clk; - DataType avmMini_m_sub_clk; - DataType avmMini_m_addr; - DataType avmMini_m_val; - DataType avmMini_m_lastAccess; - DataType avmMini_m_rw; - - DataType avmMini_m_val_shift; - DataType avmMini_m_addr_shift; - DataType avmMini_m_rw_shift; - - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &avmMini_clk, - &avmMini_positive, - &avmMini_first, - &avmMini_subop, - &avmMini_ia, - &avmMini_ib, - &avmMini_ic, - &avmMini_mem_op_a, - &avmMini_mem_op_b, - &avmMini_mem_op_c, - &avmMini_rwa, - &avmMini_rwb, - &avmMini_rwc, - &avmMini_mem_idx_a, - &avmMini_mem_idx_b, - &avmMini_mem_idx_c, - &avmMini_last, - &avmMini_m_clk, - &avmMini_m_sub_clk, - &avmMini_m_addr, - &avmMini_m_val, - &avmMini_m_lastAccess, - &avmMini_m_rw, - &avmMini_m_val_shift, - &avmMini_m_addr_shift, - &avmMini_m_rw_shift) - - std::vector get_wires() override + DEFINE_FLAVOR_MEMBERS(DataType, + avmMini_clk, + avmMini_positive, + avmMini_first, + + avmMini_subop, + avmMini_ia, + avmMini_ib, + avmMini_ic, + avmMini_mem_op_a, + avmMini_mem_op_b, + avmMini_mem_op_c, + avmMini_rwa, + avmMini_rwb, + avmMini_rwc, + avmMini_mem_idx_a, + avmMini_mem_idx_b, + avmMini_mem_idx_c, + avmMini_last, + avmMini_m_clk, + avmMini_m_sub_clk, + avmMini_m_addr, + avmMini_m_val, + avmMini_m_lastAccess, + avmMini_m_rw, + + avmMini_m_val_shift, + avmMini_m_addr_shift, + avmMini_m_rw_shift) + + RefVector get_wires() { return { avmMini_clk, avmMini_positive, avmMini_first, avmMini_subop, avmMini_ia, @@ -213,7 +160,7 @@ class AvmMiniFlavor { }; }; - std::vector get_unshifted() override + RefVector get_unshifted() { return { avmMini_clk, avmMini_positive, avmMini_first, avmMini_subop, avmMini_ia, @@ -225,7 +172,7 @@ class AvmMiniFlavor { }; }; - std::vector get_to_be_shifted() override + RefVector get_to_be_shifted() { return { avmMini_m_val, @@ -235,7 +182,7 @@ class AvmMiniFlavor { }; }; - std::vector get_shifted() override + RefVector get_shifted() { return { avmMini_m_val_shift, @@ -247,31 +194,29 @@ class AvmMiniFlavor { }; public: - class ProvingKey : public ProvingKey_, - WitnessEntities> { + class ProvingKey : public ProvingKey_, WitnessEntities> { public: // Expose constructors on the base class - using Base = ProvingKey_, - WitnessEntities>; + using Base = ProvingKey_, WitnessEntities>; using Base::Base; // The plookup wires that store plookup read data. std::array get_table_column_wires() { return {}; }; }; - using VerificationKey = VerificationKey_>; + using VerificationKey = VerificationKey_>; - using ProverPolynomials = AllEntities; + using ProverPolynomials = AllEntities; - using FoldedPolynomials = AllEntities, PolynomialHandle>; + using FoldedPolynomials = AllEntities>; - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; }; - class AllPolynomials : public AllEntities { + class AllPolynomials : public AllEntities { public: [[nodiscard]] size_t get_polynomial_size() const { return this->avmMini_clk.size(); } [[nodiscard]] AllValues get_row(const size_t row_idx) const @@ -284,9 +229,9 @@ class AvmMiniFlavor { } }; - using RowPolynomials = AllEntities; + using RowPolynomials = AllEntities; - class PartiallyEvaluatedMultivariates : public AllEntities { + class PartiallyEvaluatedMultivariates : public AllEntities { public: PartiallyEvaluatedMultivariates() = default; PartiallyEvaluatedMultivariates(const size_t circuit_size) @@ -302,21 +247,20 @@ class AvmMiniFlavor { * @brief A container for univariates used during Protogalaxy folding and sumcheck. * @details During folding and sumcheck, the prover evaluates the relations on these univariates. */ - template - using ProverUnivariates = AllEntities, barretenberg::Univariate>; + template using ProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. */ using ExtendedEdges = ProverUnivariates; - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { private: - using Base = AllEntities; + using Base = AllEntities; public: CommitmentLabels() - : AllEntities() + : AllEntities() { Base::avmMini_clk = "avmMini_clk"; Base::avmMini_positive = "avmMini_positive"; @@ -344,9 +288,9 @@ class AvmMiniFlavor { }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { private: - using Base = AllEntities; + using Base = AllEntities; public: VerifierCommitments(const std::shared_ptr& verification_key, @@ -396,7 +340,7 @@ class AvmMiniFlavor { : BaseTranscript(proof) {} - void deserialize_full_transcript() override + void deserialize_full_transcript() { size_t num_bytes_read = 0; circuit_size = deserialize_from_buffer(proof_data, num_bytes_read); @@ -437,7 +381,7 @@ class AvmMiniFlavor { zm_pi_comm = deserialize_from_buffer(proof_data, num_bytes_read); } - void serialize_full_transcript() override + void serialize_full_transcript() { size_t old_proof_length = proof_data.size(); BaseTranscript::proof_data.clear(); diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp index 281587d0f42e..031410e2df2a 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/Fib_flavor.hpp @@ -8,6 +8,7 @@ #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/relations/generated/Fib.hpp" @@ -57,15 +58,12 @@ class FibFlavor { static constexpr bool has_zero_row = true; private: - template - class PrecomputedEntities : public PrecomputedEntities_ { + template class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType Fibonacci_LAST; - DataType Fibonacci_FIRST; + using DataType = DataType_; + DEFINE_FLAVOR_MEMBERS(DataType, Fibonacci_LAST, Fibonacci_FIRST) - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, &Fibonacci_LAST, &Fibonacci_FIRST) - - std::vector get_selectors() override + RefVector get_selectors() { return { Fibonacci_LAST, @@ -73,20 +71,16 @@ class FibFlavor { }; }; - std::vector get_sigma_polynomials() override { return {}; }; - std::vector get_id_polynomials() override { return {}; }; - std::vector get_table_polynomials() { return {}; }; + RefVector get_sigma_polynomials() { return {}; }; + RefVector get_id_polynomials() { return {}; }; + RefVector get_table_polynomials() { return {}; }; }; - template - class WitnessEntities : public WitnessEntities_ { + template class WitnessEntities { public: - DataType Fibonacci_x; - DataType Fibonacci_y; - - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, &Fibonacci_x, &Fibonacci_y) + DEFINE_FLAVOR_MEMBERS(DataType, Fibonacci_x, Fibonacci_y) - std::vector get_wires() override + RefVector get_wires() { return { Fibonacci_x, @@ -95,30 +89,15 @@ class FibFlavor { }; }; - std::vector get_sorted_polynomials() { return {}; }; + RefVector get_sorted_polynomials() { return {}; }; }; - template - class AllEntities : public AllEntities_ { + template class AllEntities { public: - DataType Fibonacci_LAST; - DataType Fibonacci_FIRST; - - DataType Fibonacci_x; - DataType Fibonacci_y; - - DataType Fibonacci_x_shift; - DataType Fibonacci_y_shift; - - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &Fibonacci_LAST, - &Fibonacci_FIRST, - &Fibonacci_x, - &Fibonacci_y, - &Fibonacci_x_shift, - &Fibonacci_y_shift) + DEFINE_FLAVOR_MEMBERS( + DataType, Fibonacci_LAST, Fibonacci_FIRST, Fibonacci_x, Fibonacci_y, Fibonacci_x_shift, Fibonacci_y_shift) - std::vector get_wires() override + RefVector get_wires() { return { Fibonacci_LAST, Fibonacci_FIRST, Fibonacci_x, Fibonacci_y, Fibonacci_x_shift, Fibonacci_y_shift, @@ -126,7 +105,7 @@ class FibFlavor { }; }; - std::vector get_unshifted() override + RefVector get_unshifted() { return { Fibonacci_LAST, @@ -137,7 +116,7 @@ class FibFlavor { }; }; - std::vector get_to_be_shifted() override + RefVector get_to_be_shifted() { return { Fibonacci_x, @@ -146,7 +125,7 @@ class FibFlavor { }; }; - std::vector get_shifted() override + RefVector get_shifted() { return { Fibonacci_x_shift, @@ -157,31 +136,29 @@ class FibFlavor { }; public: - class ProvingKey : public ProvingKey_, - WitnessEntities> { + class ProvingKey : public ProvingKey_, WitnessEntities> { public: // Expose constructors on the base class - using Base = ProvingKey_, - WitnessEntities>; + using Base = ProvingKey_, WitnessEntities>; using Base::Base; // The plookup wires that store plookup read data. std::array get_table_column_wires() { return {}; }; }; - using VerificationKey = VerificationKey_>; + using VerificationKey = VerificationKey_>; - using ProverPolynomials = AllEntities; + using ProverPolynomials = AllEntities; - using FoldedPolynomials = AllEntities, PolynomialHandle>; + using FoldedPolynomials = AllEntities>; - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; }; - class AllPolynomials : public AllEntities { + class AllPolynomials : public AllEntities { public: [[nodiscard]] size_t get_polynomial_size() const { return this->Fibonacci_LAST.size(); } [[nodiscard]] AllValues get_row(const size_t row_idx) const @@ -194,9 +171,9 @@ class FibFlavor { } }; - using RowPolynomials = AllEntities; + using RowPolynomials = AllEntities; - class PartiallyEvaluatedMultivariates : public AllEntities { + class PartiallyEvaluatedMultivariates : public AllEntities { public: PartiallyEvaluatedMultivariates() = default; PartiallyEvaluatedMultivariates(const size_t circuit_size) @@ -212,21 +189,20 @@ class FibFlavor { * @brief A container for univariates used during Protogalaxy folding and sumcheck. * @details During folding and sumcheck, the prover evaluates the relations on these univariates. */ - template - using ProverUnivariates = AllEntities, barretenberg::Univariate>; + template using ProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. */ using ExtendedEdges = ProverUnivariates; - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { private: - using Base = AllEntities; + using Base = AllEntities; public: CommitmentLabels() - : AllEntities() + : AllEntities() { Base::Fibonacci_LAST = "Fibonacci_LAST"; Base::Fibonacci_FIRST = "Fibonacci_FIRST"; @@ -235,9 +211,9 @@ class FibFlavor { }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { private: - using Base = AllEntities; + using Base = AllEntities; public: VerifierCommitments(const std::shared_ptr& verification_key, @@ -268,7 +244,7 @@ class FibFlavor { : BaseTranscript(proof) {} - void deserialize_full_transcript() override + void deserialize_full_transcript() { size_t num_bytes_read = 0; circuit_size = deserialize_from_buffer(proof_data, num_bytes_read); @@ -291,7 +267,7 @@ class FibFlavor { zm_pi_comm = deserialize_from_buffer(proof_data, num_bytes_read); } - void serialize_full_transcript() override + void serialize_full_transcript() { size_t old_proof_length = proof_data.size(); BaseTranscript::proof_data.clear(); diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp index 454bbf85b679..d649a88f392a 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_translator.hpp @@ -1,7 +1,12 @@ #pragma once #include "barretenberg/commitment_schemes/commitment_key.hpp" #include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/common/ref_vector.hpp" +#include "barretenberg/ecc/curves/bn254/bn254.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" +#include "barretenberg/polynomials/univariate.hpp" +#include "barretenberg/proof_system/arithmetization/arithmetization.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_translator_circuit_builder.hpp" #include "barretenberg/relations/relation_parameters.hpp" #include "barretenberg/relations/translator_vm/translator_decomposition_relation.hpp" @@ -62,9 +67,9 @@ class GoblinTranslator { // This is not a configurable value. Relations are sepcifically designed for it to be 68 static constexpr size_t NUM_LIMB_BITS = CircuitBuilder::NUM_LIMB_BITS; - // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We often - // need containers of this size to hold related data, so we choose a name more agnostic than `NUM_POLYNOMIALS`. - // Note: this number does not include the individual sorted list polynomials. + // The number of multivariate polynomials on which a sumcheck prover sumcheck operates (including shifts). We + // often need containers of this size to hold related data, so we choose a name more agnostic than + // `NUM_POLYNOMIALS`. Note: this number does not include the individual sorted list polynomials. static constexpr size_t NUM_ALL_ENTITIES = 184; // The number of polynomials precomputed to describe a circuit and to aid a prover in constructing a satisfying // assignment of witnesses. We again choose a neutral name. @@ -102,1295 +107,859 @@ class GoblinTranslator { using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); private: - template /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. */ - class PrecomputedEntities : public PrecomputedEntities_ { + template class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType lagrange_first; // column 0 - DataType lagrange_last; // column 1 - // TODO(#758): Check if one of these can be replaced by shifts - DataType lagrange_odd_in_minicircuit; // column 2 - DataType lagrange_even_in_minicircuit; // column 3 - DataType lagrange_second; // column 4 - DataType lagrange_second_to_last_in_minicircuit; // column 5 - DataType ordered_extra_range_constraints_numerator; // column 6 - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, - &lagrange_first, - &lagrange_last, - &lagrange_odd_in_minicircuit, - &lagrange_even_in_minicircuit, - &lagrange_second, - &lagrange_second_to_last_in_minicircuit, - &ordered_extra_range_constraints_numerator); - - std::vector get_selectors() { return {}; }; - std::vector get_sigma_polynomials() { return {}; }; - std::vector get_id_polynomials() { return {}; }; + using DataType = DataType_; + DEFINE_FLAVOR_MEMBERS(DataType, + lagrange_first, // column 0 + lagrange_last, // column 1 + // TODO(#758): Check if one of these can be replaced by shifts + lagrange_odd_in_minicircuit, // column 2 + lagrange_even_in_minicircuit, // column 3 + lagrange_second, // column 4 + lagrange_second_to_last_in_minicircuit, // column 5 + ordered_extra_range_constraints_numerator); // column 6 + RefVector get_selectors() { return {}; }; + RefVector get_sigma_polynomials() { return {}; }; + RefVector get_id_polynomials() { return {}; }; }; + template class ConcatenatedRangeConstraints { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + concatenated_range_constraints_0, // column 0 + concatenated_range_constraints_1, // column 1 + concatenated_range_constraints_2, // column 2 + concatenated_range_constraints_3) // column 3 + }; + // TODO(https://github.com/AztecProtocol/barretenberg/issues/790) dedupe with shifted? + template class WireToBeShiftedEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + x_lo_y_hi, // column 0 + x_hi_z_1, // column 1 + y_lo_z_2, // column 2 + p_x_low_limbs, // column 3 + p_x_low_limbs_range_constraint_0, // column 4 + p_x_low_limbs_range_constraint_1, // column 5 + p_x_low_limbs_range_constraint_2, // column 6 + p_x_low_limbs_range_constraint_3, // column 7 + p_x_low_limbs_range_constraint_4, // column 8 + p_x_low_limbs_range_constraint_tail, // column 9 + p_x_high_limbs, // column 10 + p_x_high_limbs_range_constraint_0, // column 11 + p_x_high_limbs_range_constraint_1, // column 12 + p_x_high_limbs_range_constraint_2, // column 13 + p_x_high_limbs_range_constraint_3, // column 14 + p_x_high_limbs_range_constraint_4, // column 15 + p_x_high_limbs_range_constraint_tail, // column 16 + p_y_low_limbs, // column 17 + p_y_low_limbs_range_constraint_0, // column 18 + p_y_low_limbs_range_constraint_1, // column 19 + p_y_low_limbs_range_constraint_2, // column 20 + p_y_low_limbs_range_constraint_3, // column 21 + p_y_low_limbs_range_constraint_4, // column 22 + p_y_low_limbs_range_constraint_tail, // column 23 + p_y_high_limbs, // column 24 + p_y_high_limbs_range_constraint_0, // column 25 + p_y_high_limbs_range_constraint_1, // column 26 + p_y_high_limbs_range_constraint_2, // column 27 + p_y_high_limbs_range_constraint_3, // column 28 + p_y_high_limbs_range_constraint_4, // column 29 + p_y_high_limbs_range_constraint_tail, // column 30 + z_low_limbs, // column 31 + z_low_limbs_range_constraint_0, // column 32 + z_low_limbs_range_constraint_1, // column 33 + z_low_limbs_range_constraint_2, // column 34 + z_low_limbs_range_constraint_3, // column 35 + z_low_limbs_range_constraint_4, // column 36 + z_low_limbs_range_constraint_tail, // column 37 + z_high_limbs, // column 38 + z_high_limbs_range_constraint_0, // column 39 + z_high_limbs_range_constraint_1, // column 40 + z_high_limbs_range_constraint_2, // column 41 + z_high_limbs_range_constraint_3, // column 42 + z_high_limbs_range_constraint_4, // column 43 + z_high_limbs_range_constraint_tail, // column 44 + accumulators_binary_limbs_0, // column 45 + accumulators_binary_limbs_1, // column 46 + accumulators_binary_limbs_2, // column 47 + accumulators_binary_limbs_3, // column 48 + accumulator_low_limbs_range_constraint_0, // column 49 + accumulator_low_limbs_range_constraint_1, // column 50 + accumulator_low_limbs_range_constraint_2, // column 51 + accumulator_low_limbs_range_constraint_3, // column 52 + accumulator_low_limbs_range_constraint_4, // column 53 + accumulator_low_limbs_range_constraint_tail, // column 54 + accumulator_high_limbs_range_constraint_0, // column 55 + accumulator_high_limbs_range_constraint_1, // column 56 + accumulator_high_limbs_range_constraint_2, // column 57 + accumulator_high_limbs_range_constraint_3, // column 58 + accumulator_high_limbs_range_constraint_4, // column 59 + accumulator_high_limbs_range_constraint_tail, // column 60 + quotient_low_binary_limbs, // column 61 + quotient_high_binary_limbs, // column 62 + quotient_low_limbs_range_constraint_0, // column 63 + quotient_low_limbs_range_constraint_1, // column 64 + quotient_low_limbs_range_constraint_2, // column 65 + quotient_low_limbs_range_constraint_3, // column 66 + quotient_low_limbs_range_constraint_4, // column 67 + quotient_low_limbs_range_constraint_tail, // column 68 + quotient_high_limbs_range_constraint_0, // column 69 + quotient_high_limbs_range_constraint_1, // column 70 + quotient_high_limbs_range_constraint_2, // column 71 + quotient_high_limbs_range_constraint_3, // column 72 + quotient_high_limbs_range_constraint_4, // column 73 + quotient_high_limbs_range_constraint_tail, // column 74 + relation_wide_limbs, // column 75 + relation_wide_limbs_range_constraint_0, // column 76 + relation_wide_limbs_range_constraint_1, // column 77 + relation_wide_limbs_range_constraint_2, // column 78 + relation_wide_limbs_range_constraint_3, // column 79 + ordered_range_constraints_0, // column 80 + ordered_range_constraints_1, // column 81 + ordered_range_constraints_2, // column 82 + ordered_range_constraints_3, // column 83 + ordered_range_constraints_4); // column 84 + }; + template class WireNonshiftedEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + op // column 0 + ); + }; + template class DerivedWitnessEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + z_perm); // column 0 + }; /** * @brief Container for all witness polynomials used/constructed by the prover. - * @details Shifts are not included here since they do not occupy their own memory. */ - template - class WitnessEntities : public WitnessEntities_ { + template + class WitnessEntities : public WireNonshiftedEntities, + public WireToBeShiftedEntities, + public DerivedWitnessEntities, + public ConcatenatedRangeConstraints { public: - DataType op; // column 0 - DataType x_lo_y_hi; // column 1 - DataType x_hi_z_1; // column 2 - DataType y_lo_z_2; // column 3 - DataType p_x_low_limbs; // column 4 - DataType p_x_low_limbs_range_constraint_0; // column 5 - DataType p_x_low_limbs_range_constraint_1; // column 6 - DataType p_x_low_limbs_range_constraint_2; // column 7 - DataType p_x_low_limbs_range_constraint_3; // column 8 - DataType p_x_low_limbs_range_constraint_4; // column 9 - DataType p_x_low_limbs_range_constraint_tail; // column 10 - DataType p_x_high_limbs; // column 11 - DataType p_x_high_limbs_range_constraint_0; // column 12 - DataType p_x_high_limbs_range_constraint_1; // column 13 - DataType p_x_high_limbs_range_constraint_2; // column 14 - DataType p_x_high_limbs_range_constraint_3; // column 15 - DataType p_x_high_limbs_range_constraint_4; // column 16 - DataType p_x_high_limbs_range_constraint_tail; // column 17 - DataType p_y_low_limbs; // column 18 - DataType p_y_low_limbs_range_constraint_0; // column 19 - DataType p_y_low_limbs_range_constraint_1; // column 20 - DataType p_y_low_limbs_range_constraint_2; // column 21 - DataType p_y_low_limbs_range_constraint_3; // column 22 - DataType p_y_low_limbs_range_constraint_4; // column 23 - DataType p_y_low_limbs_range_constraint_tail; // column 24 - DataType p_y_high_limbs; // column 25 - DataType p_y_high_limbs_range_constraint_0; // column 26 - DataType p_y_high_limbs_range_constraint_1; // column 27 - DataType p_y_high_limbs_range_constraint_2; // column 28 - DataType p_y_high_limbs_range_constraint_3; // column 29 - DataType p_y_high_limbs_range_constraint_4; // column 30 - DataType p_y_high_limbs_range_constraint_tail; // column 31 - DataType z_low_limbs; // column 32 - DataType z_low_limbs_range_constraint_0; // column 33 - DataType z_low_limbs_range_constraint_1; // column 34 - DataType z_low_limbs_range_constraint_2; // column 35 - DataType z_low_limbs_range_constraint_3; // column 36 - DataType z_low_limbs_range_constraint_4; // column 37 - DataType z_low_limbs_range_constraint_tail; // column 38 - DataType z_high_limbs; // column 39 - DataType z_high_limbs_range_constraint_0; // column 40 - DataType z_high_limbs_range_constraint_1; // column 41 - DataType z_high_limbs_range_constraint_2; // column 42 - DataType z_high_limbs_range_constraint_3; // column 43 - DataType z_high_limbs_range_constraint_4; // column 44 - DataType z_high_limbs_range_constraint_tail; // column 45 - DataType accumulators_binary_limbs_0; // column 46 - DataType accumulators_binary_limbs_1; // column 47 - DataType accumulators_binary_limbs_2; // column 48 - DataType accumulators_binary_limbs_3; // column 49 - DataType accumulator_low_limbs_range_constraint_0; // column 50 - DataType accumulator_low_limbs_range_constraint_1; // column 51 - DataType accumulator_low_limbs_range_constraint_2; // column 52 - DataType accumulator_low_limbs_range_constraint_3; // column 53 - DataType accumulator_low_limbs_range_constraint_4; // column 54 - DataType accumulator_low_limbs_range_constraint_tail; // column 55 - DataType accumulator_high_limbs_range_constraint_0; // column 56 - DataType accumulator_high_limbs_range_constraint_1; // column 57 - DataType accumulator_high_limbs_range_constraint_2; // column 58 - DataType accumulator_high_limbs_range_constraint_3; // column 59 - DataType accumulator_high_limbs_range_constraint_4; // column 60 - DataType accumulator_high_limbs_range_constraint_tail; // column 61 - DataType quotient_low_binary_limbs; // column 62 - DataType quotient_high_binary_limbs; // column 63 - DataType quotient_low_limbs_range_constraint_0; // column 64 - DataType quotient_low_limbs_range_constraint_1; // column 65 - DataType quotient_low_limbs_range_constraint_2; // column 66 - DataType quotient_low_limbs_range_constraint_3; // column 67 - DataType quotient_low_limbs_range_constraint_4; // column 68 - DataType quotient_low_limbs_range_constraint_tail; // column 69 - DataType quotient_high_limbs_range_constraint_0; // column 70 - DataType quotient_high_limbs_range_constraint_1; // column 71 - DataType quotient_high_limbs_range_constraint_2; // column 72 - DataType quotient_high_limbs_range_constraint_3; // column 73 - DataType quotient_high_limbs_range_constraint_4; // column 74 - DataType quotient_high_limbs_range_constraint_tail; // column 75 - DataType relation_wide_limbs; // column 76 - DataType relation_wide_limbs_range_constraint_0; // column 77 - DataType relation_wide_limbs_range_constraint_1; // column 78 - DataType relation_wide_limbs_range_constraint_2; // column 79 - DataType relation_wide_limbs_range_constraint_3; // column 80 - DataType concatenated_range_constraints_0; // column 81 - DataType concatenated_range_constraints_1; // column 82 - DataType concatenated_range_constraints_2; // column 83 - DataType concatenated_range_constraints_3; // column 84 - DataType ordered_range_constraints_0; // column 85 - DataType ordered_range_constraints_1; // column 86 - DataType ordered_range_constraints_2; // column 87 - DataType ordered_range_constraints_3; // column 88 - DataType ordered_range_constraints_4; // column 89 - DataType z_perm; // column 90 + DEFINE_COMPOUND_GET_ALL(WireNonshiftedEntities::get_all(), + WireToBeShiftedEntities::get_all(), + DerivedWitnessEntities::get_all(), + ConcatenatedRangeConstraints::get_all()) + DEFINE_COMPOUND_POINTER_VIEW(WireNonshiftedEntities::pointer_view(), + WireToBeShiftedEntities::pointer_view(), + DerivedWitnessEntities::pointer_view(), + ConcatenatedRangeConstraints::pointer_view()) - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &op, - &x_lo_y_hi, - &x_hi_z_1, - &y_lo_z_2, - &p_x_low_limbs, - &p_x_low_limbs_range_constraint_0, - &p_x_low_limbs_range_constraint_1, - &p_x_low_limbs_range_constraint_2, - &p_x_low_limbs_range_constraint_3, - &p_x_low_limbs_range_constraint_4, - &p_x_low_limbs_range_constraint_tail, - &p_x_high_limbs, - &p_x_high_limbs_range_constraint_0, - &p_x_high_limbs_range_constraint_1, - &p_x_high_limbs_range_constraint_2, - &p_x_high_limbs_range_constraint_3, - &p_x_high_limbs_range_constraint_4, - &p_x_high_limbs_range_constraint_tail, - &p_y_low_limbs, - &p_y_low_limbs_range_constraint_0, - &p_y_low_limbs_range_constraint_1, - &p_y_low_limbs_range_constraint_2, - &p_y_low_limbs_range_constraint_3, - &p_y_low_limbs_range_constraint_4, - &p_y_low_limbs_range_constraint_tail, - &p_y_high_limbs, - &p_y_high_limbs_range_constraint_0, - &p_y_high_limbs_range_constraint_1, - &p_y_high_limbs_range_constraint_2, - &p_y_high_limbs_range_constraint_3, - &p_y_high_limbs_range_constraint_4, - &p_y_high_limbs_range_constraint_tail, - &z_low_limbs, - &z_low_limbs_range_constraint_0, - &z_low_limbs_range_constraint_1, - &z_low_limbs_range_constraint_2, - &z_low_limbs_range_constraint_3, - &z_low_limbs_range_constraint_4, - &z_low_limbs_range_constraint_tail, - &z_high_limbs, - &z_high_limbs_range_constraint_0, - &z_high_limbs_range_constraint_1, - &z_high_limbs_range_constraint_2, - &z_high_limbs_range_constraint_3, - &z_high_limbs_range_constraint_4, - &z_high_limbs_range_constraint_tail, - &accumulators_binary_limbs_0, - &accumulators_binary_limbs_1, - &accumulators_binary_limbs_2, - &accumulators_binary_limbs_3, - &accumulator_low_limbs_range_constraint_0, - &accumulator_low_limbs_range_constraint_1, - &accumulator_low_limbs_range_constraint_2, - &accumulator_low_limbs_range_constraint_3, - &accumulator_low_limbs_range_constraint_4, - &accumulator_low_limbs_range_constraint_tail, - &accumulator_high_limbs_range_constraint_0, - &accumulator_high_limbs_range_constraint_1, - &accumulator_high_limbs_range_constraint_2, - &accumulator_high_limbs_range_constraint_3, - &accumulator_high_limbs_range_constraint_4, - &accumulator_high_limbs_range_constraint_tail, - "ient_low_binary_limbs, - "ient_high_binary_limbs, - "ient_low_limbs_range_constraint_0, - "ient_low_limbs_range_constraint_1, - "ient_low_limbs_range_constraint_2, - "ient_low_limbs_range_constraint_3, - "ient_low_limbs_range_constraint_4, - "ient_low_limbs_range_constraint_tail, - "ient_high_limbs_range_constraint_0, - "ient_high_limbs_range_constraint_1, - "ient_high_limbs_range_constraint_2, - "ient_high_limbs_range_constraint_3, - "ient_high_limbs_range_constraint_4, - "ient_high_limbs_range_constraint_tail, - &relation_wide_limbs, - &relation_wide_limbs_range_constraint_0, - &relation_wide_limbs_range_constraint_1, - &relation_wide_limbs_range_constraint_2, - &relation_wide_limbs_range_constraint_3, - &concatenated_range_constraints_0, - &concatenated_range_constraints_1, - &concatenated_range_constraints_2, - &concatenated_range_constraints_3, - &ordered_range_constraints_0, - &ordered_range_constraints_1, - &ordered_range_constraints_2, - &ordered_range_constraints_3, - &ordered_range_constraints_4, - &z_perm) + RefVector get_wires() + { + return { this->op, + this->x_lo_y_hi, + this->x_hi_z_1, + this->y_lo_z_2, + this->p_x_low_limbs, + this->p_x_low_limbs_range_constraint_0, + this->p_x_low_limbs_range_constraint_1, + this->p_x_low_limbs_range_constraint_2, + this->p_x_low_limbs_range_constraint_3, + this->p_x_low_limbs_range_constraint_4, + this->p_x_low_limbs_range_constraint_tail, + this->p_x_high_limbs, + this->p_x_high_limbs_range_constraint_0, + this->p_x_high_limbs_range_constraint_1, + this->p_x_high_limbs_range_constraint_2, + this->p_x_high_limbs_range_constraint_3, + this->p_x_high_limbs_range_constraint_4, + this->p_x_high_limbs_range_constraint_tail, + this->p_y_low_limbs, + this->p_y_low_limbs_range_constraint_0, + this->p_y_low_limbs_range_constraint_1, + this->p_y_low_limbs_range_constraint_2, + this->p_y_low_limbs_range_constraint_3, + this->p_y_low_limbs_range_constraint_4, + this->p_y_low_limbs_range_constraint_tail, + this->p_y_high_limbs, + this->p_y_high_limbs_range_constraint_0, + this->p_y_high_limbs_range_constraint_1, + this->p_y_high_limbs_range_constraint_2, + this->p_y_high_limbs_range_constraint_3, + this->p_y_high_limbs_range_constraint_4, + this->p_y_high_limbs_range_constraint_tail, + this->z_low_limbs, + this->z_low_limbs_range_constraint_0, + this->z_low_limbs_range_constraint_1, + this->z_low_limbs_range_constraint_2, + this->z_low_limbs_range_constraint_3, + this->z_low_limbs_range_constraint_4, + this->z_low_limbs_range_constraint_tail, + this->z_high_limbs, + this->z_high_limbs_range_constraint_0, + this->z_high_limbs_range_constraint_1, + this->z_high_limbs_range_constraint_2, + this->z_high_limbs_range_constraint_3, + this->z_high_limbs_range_constraint_4, + this->z_high_limbs_range_constraint_tail, + this->accumulators_binary_limbs_0, + this->accumulators_binary_limbs_1, + this->accumulators_binary_limbs_2, + this->accumulators_binary_limbs_3, + this->accumulator_low_limbs_range_constraint_0, + this->accumulator_low_limbs_range_constraint_1, + this->accumulator_low_limbs_range_constraint_2, + this->accumulator_low_limbs_range_constraint_3, + this->accumulator_low_limbs_range_constraint_4, + this->accumulator_low_limbs_range_constraint_tail, + this->accumulator_high_limbs_range_constraint_0, + this->accumulator_high_limbs_range_constraint_1, + this->accumulator_high_limbs_range_constraint_2, + this->accumulator_high_limbs_range_constraint_3, + this->accumulator_high_limbs_range_constraint_4, + this->accumulator_high_limbs_range_constraint_tail, + this->quotient_low_binary_limbs, + this->quotient_high_binary_limbs, + this->quotient_low_limbs_range_constraint_0, + this->quotient_low_limbs_range_constraint_1, + this->quotient_low_limbs_range_constraint_2, + this->quotient_low_limbs_range_constraint_3, + this->quotient_low_limbs_range_constraint_4, + this->quotient_low_limbs_range_constraint_tail, + this->quotient_high_limbs_range_constraint_0, + this->quotient_high_limbs_range_constraint_1, + this->quotient_high_limbs_range_constraint_2, + this->quotient_high_limbs_range_constraint_3, + this->quotient_high_limbs_range_constraint_4, + this->quotient_high_limbs_range_constraint_tail, + this->relation_wide_limbs, + this->relation_wide_limbs_range_constraint_0, + this->relation_wide_limbs_range_constraint_1, + this->relation_wide_limbs_range_constraint_2, + this->relation_wide_limbs_range_constraint_3, + this->ordered_range_constraints_0, + this->ordered_range_constraints_1, + this->ordered_range_constraints_2, + this->ordered_range_constraints_3, + this->ordered_range_constraints_4 }; + }; - std::vector get_wires() override + // everything but ConcatenatedRangeConstraints + RefVector get_unshifted_wires() + { + return concatenate(WireNonshiftedEntities::get_all(), + WireToBeShiftedEntities::get_all(), + DerivedWitnessEntities::get_all()); + }; + RefVector get_to_be_shifted() { - return { op, - x_lo_y_hi, - x_hi_z_1, - y_lo_z_2, - p_x_low_limbs, - p_x_low_limbs_range_constraint_0, - p_x_low_limbs_range_constraint_1, - p_x_low_limbs_range_constraint_2, - p_x_low_limbs_range_constraint_3, - p_x_low_limbs_range_constraint_4, - p_x_low_limbs_range_constraint_tail, - p_x_high_limbs, - p_x_high_limbs_range_constraint_0, - p_x_high_limbs_range_constraint_1, - p_x_high_limbs_range_constraint_2, - p_x_high_limbs_range_constraint_3, - p_x_high_limbs_range_constraint_4, - p_x_high_limbs_range_constraint_tail, - p_y_low_limbs, - p_y_low_limbs_range_constraint_0, - p_y_low_limbs_range_constraint_1, - p_y_low_limbs_range_constraint_2, - p_y_low_limbs_range_constraint_3, - p_y_low_limbs_range_constraint_4, - p_y_low_limbs_range_constraint_tail, - p_y_high_limbs, - p_y_high_limbs_range_constraint_0, - p_y_high_limbs_range_constraint_1, - p_y_high_limbs_range_constraint_2, - p_y_high_limbs_range_constraint_3, - p_y_high_limbs_range_constraint_4, - p_y_high_limbs_range_constraint_tail, - z_low_limbs, - z_low_limbs_range_constraint_0, - z_low_limbs_range_constraint_1, - z_low_limbs_range_constraint_2, - z_low_limbs_range_constraint_3, - z_low_limbs_range_constraint_4, - z_low_limbs_range_constraint_tail, - z_high_limbs, - z_high_limbs_range_constraint_0, - z_high_limbs_range_constraint_1, - z_high_limbs_range_constraint_2, - z_high_limbs_range_constraint_3, - z_high_limbs_range_constraint_4, - z_high_limbs_range_constraint_tail, - accumulators_binary_limbs_0, - accumulators_binary_limbs_1, - accumulators_binary_limbs_2, - accumulators_binary_limbs_3, - accumulator_low_limbs_range_constraint_0, - accumulator_low_limbs_range_constraint_1, - accumulator_low_limbs_range_constraint_2, - accumulator_low_limbs_range_constraint_3, - accumulator_low_limbs_range_constraint_4, - accumulator_low_limbs_range_constraint_tail, - accumulator_high_limbs_range_constraint_0, - accumulator_high_limbs_range_constraint_1, - accumulator_high_limbs_range_constraint_2, - accumulator_high_limbs_range_constraint_3, - accumulator_high_limbs_range_constraint_4, - accumulator_high_limbs_range_constraint_tail, - quotient_low_binary_limbs, - quotient_high_binary_limbs, - quotient_low_limbs_range_constraint_0, - quotient_low_limbs_range_constraint_1, - quotient_low_limbs_range_constraint_2, - quotient_low_limbs_range_constraint_3, - quotient_low_limbs_range_constraint_4, - quotient_low_limbs_range_constraint_tail, - quotient_high_limbs_range_constraint_0, - quotient_high_limbs_range_constraint_1, - quotient_high_limbs_range_constraint_2, - quotient_high_limbs_range_constraint_3, - quotient_high_limbs_range_constraint_4, - quotient_high_limbs_range_constraint_tail, - relation_wide_limbs, - relation_wide_limbs_range_constraint_0, - relation_wide_limbs_range_constraint_1, - relation_wide_limbs_range_constraint_2, - relation_wide_limbs_range_constraint_3, - ordered_range_constraints_0, - ordered_range_constraints_1, - ordered_range_constraints_2, - ordered_range_constraints_3, - ordered_range_constraints_4 }; + return concatenate(WireToBeShiftedEntities::get_all(), + DerivedWitnessEntities::get_all()); }; /** * @brief Get the polynomials that need to be constructed from other polynomials by concatenation * - * @return std::vector + * @return RefVector */ - std::vector get_concatenated_constraints() - { - return { concatenated_range_constraints_0, - concatenated_range_constraints_1, - concatenated_range_constraints_2, - concatenated_range_constraints_3 }; - } + auto get_concatenated_constraints() { return ConcatenatedRangeConstraints::get_all(); } /** * @brief Get the polynomials that are concatenated for the permutation relation * - * @return std::vector> + * @return std::vector> */ - std::vector> get_concatenation_groups() + std::vector> get_concatenation_groups() { return { { - p_x_low_limbs_range_constraint_0, - p_x_low_limbs_range_constraint_1, - p_x_low_limbs_range_constraint_2, - p_x_low_limbs_range_constraint_3, - p_x_low_limbs_range_constraint_4, - p_x_low_limbs_range_constraint_tail, - p_x_high_limbs_range_constraint_0, - p_x_high_limbs_range_constraint_1, - p_x_high_limbs_range_constraint_2, - p_x_high_limbs_range_constraint_3, - p_x_high_limbs_range_constraint_4, - p_x_high_limbs_range_constraint_tail, - p_y_low_limbs_range_constraint_0, - p_y_low_limbs_range_constraint_1, - p_y_low_limbs_range_constraint_2, - p_y_low_limbs_range_constraint_3, + this->p_x_low_limbs_range_constraint_0, + this->p_x_low_limbs_range_constraint_1, + this->p_x_low_limbs_range_constraint_2, + this->p_x_low_limbs_range_constraint_3, + this->p_x_low_limbs_range_constraint_4, + this->p_x_low_limbs_range_constraint_tail, + this->p_x_high_limbs_range_constraint_0, + this->p_x_high_limbs_range_constraint_1, + this->p_x_high_limbs_range_constraint_2, + this->p_x_high_limbs_range_constraint_3, + this->p_x_high_limbs_range_constraint_4, + this->p_x_high_limbs_range_constraint_tail, + this->p_y_low_limbs_range_constraint_0, + this->p_y_low_limbs_range_constraint_1, + this->p_y_low_limbs_range_constraint_2, + this->p_y_low_limbs_range_constraint_3, }, { - p_y_low_limbs_range_constraint_4, - p_y_low_limbs_range_constraint_tail, - p_y_high_limbs_range_constraint_0, - p_y_high_limbs_range_constraint_1, - p_y_high_limbs_range_constraint_2, - p_y_high_limbs_range_constraint_3, - p_y_high_limbs_range_constraint_4, - p_y_high_limbs_range_constraint_tail, - z_low_limbs_range_constraint_0, - z_low_limbs_range_constraint_1, - z_low_limbs_range_constraint_2, - z_low_limbs_range_constraint_3, - z_low_limbs_range_constraint_4, - z_low_limbs_range_constraint_tail, - z_high_limbs_range_constraint_0, - z_high_limbs_range_constraint_1, + this->p_y_low_limbs_range_constraint_4, + this->p_y_low_limbs_range_constraint_tail, + this->p_y_high_limbs_range_constraint_0, + this->p_y_high_limbs_range_constraint_1, + this->p_y_high_limbs_range_constraint_2, + this->p_y_high_limbs_range_constraint_3, + this->p_y_high_limbs_range_constraint_4, + this->p_y_high_limbs_range_constraint_tail, + this->z_low_limbs_range_constraint_0, + this->z_low_limbs_range_constraint_1, + this->z_low_limbs_range_constraint_2, + this->z_low_limbs_range_constraint_3, + this->z_low_limbs_range_constraint_4, + this->z_low_limbs_range_constraint_tail, + this->z_high_limbs_range_constraint_0, + this->z_high_limbs_range_constraint_1, }, { - z_high_limbs_range_constraint_2, - z_high_limbs_range_constraint_3, - z_high_limbs_range_constraint_4, - z_high_limbs_range_constraint_tail, - accumulator_low_limbs_range_constraint_0, - accumulator_low_limbs_range_constraint_1, - accumulator_low_limbs_range_constraint_2, - accumulator_low_limbs_range_constraint_3, - accumulator_low_limbs_range_constraint_4, - accumulator_low_limbs_range_constraint_tail, - accumulator_high_limbs_range_constraint_0, - accumulator_high_limbs_range_constraint_1, - accumulator_high_limbs_range_constraint_2, - accumulator_high_limbs_range_constraint_3, - accumulator_high_limbs_range_constraint_4, - accumulator_high_limbs_range_constraint_tail, + this->z_high_limbs_range_constraint_2, + this->z_high_limbs_range_constraint_3, + this->z_high_limbs_range_constraint_4, + this->z_high_limbs_range_constraint_tail, + this->accumulator_low_limbs_range_constraint_0, + this->accumulator_low_limbs_range_constraint_1, + this->accumulator_low_limbs_range_constraint_2, + this->accumulator_low_limbs_range_constraint_3, + this->accumulator_low_limbs_range_constraint_4, + this->accumulator_low_limbs_range_constraint_tail, + this->accumulator_high_limbs_range_constraint_0, + this->accumulator_high_limbs_range_constraint_1, + this->accumulator_high_limbs_range_constraint_2, + this->accumulator_high_limbs_range_constraint_3, + this->accumulator_high_limbs_range_constraint_4, + this->accumulator_high_limbs_range_constraint_tail, }, { - quotient_low_limbs_range_constraint_0, - quotient_low_limbs_range_constraint_1, - quotient_low_limbs_range_constraint_2, - quotient_low_limbs_range_constraint_3, - quotient_low_limbs_range_constraint_4, - quotient_low_limbs_range_constraint_tail, - quotient_high_limbs_range_constraint_0, - quotient_high_limbs_range_constraint_1, - quotient_high_limbs_range_constraint_2, - quotient_high_limbs_range_constraint_3, - quotient_high_limbs_range_constraint_4, - quotient_high_limbs_range_constraint_tail, - relation_wide_limbs_range_constraint_0, - relation_wide_limbs_range_constraint_1, - relation_wide_limbs_range_constraint_2, - relation_wide_limbs_range_constraint_3, + this->quotient_low_limbs_range_constraint_0, + this->quotient_low_limbs_range_constraint_1, + this->quotient_low_limbs_range_constraint_2, + this->quotient_low_limbs_range_constraint_3, + this->quotient_low_limbs_range_constraint_4, + this->quotient_low_limbs_range_constraint_tail, + this->quotient_high_limbs_range_constraint_0, + this->quotient_high_limbs_range_constraint_1, + this->quotient_high_limbs_range_constraint_2, + this->quotient_high_limbs_range_constraint_3, + this->quotient_high_limbs_range_constraint_4, + this->quotient_high_limbs_range_constraint_tail, + this->relation_wide_limbs_range_constraint_0, + this->relation_wide_limbs_range_constraint_1, + this->relation_wide_limbs_range_constraint_2, + this->relation_wide_limbs_range_constraint_3, }, }; }; }; + /** + * @brief Represents polynomials shifted by 1 or their evaluations, defined relative to WireToBeShiftedEntities. + */ + template class ShiftedEntities { + public: + DEFINE_FLAVOR_MEMBERS(DataType, + x_lo_y_hi_shift, // column 0 + x_hi_z_1_shift, // column 1 + y_lo_z_2_shift, // column 2 + p_x_low_limbs_shift, // column 3 + p_x_low_limbs_range_constraint_0_shift, // column 4 + p_x_low_limbs_range_constraint_1_shift, // column 5 + p_x_low_limbs_range_constraint_2_shift, // column 6 + p_x_low_limbs_range_constraint_3_shift, // column 7 + p_x_low_limbs_range_constraint_4_shift, // column 8 + p_x_low_limbs_range_constraint_tail_shift, // column 9 + p_x_high_limbs_shift, // column 10 + p_x_high_limbs_range_constraint_0_shift, // column 11 + p_x_high_limbs_range_constraint_1_shift, // column 12 + p_x_high_limbs_range_constraint_2_shift, // column 13 + p_x_high_limbs_range_constraint_3_shift, // column 14 + p_x_high_limbs_range_constraint_4_shift, // column 15 + p_x_high_limbs_range_constraint_tail_shift, // column 16 + p_y_low_limbs_shift, // column 17 + p_y_low_limbs_range_constraint_0_shift, // column 18 + p_y_low_limbs_range_constraint_1_shift, // column 19 + p_y_low_limbs_range_constraint_2_shift, // column 20 + p_y_low_limbs_range_constraint_3_shift, // column 21 + p_y_low_limbs_range_constraint_4_shift, // column 22 + p_y_low_limbs_range_constraint_tail_shift, // column 23 + p_y_high_limbs_shift, // column 24 + p_y_high_limbs_range_constraint_0_shift, // column 25 + p_y_high_limbs_range_constraint_1_shift, // column 26 + p_y_high_limbs_range_constraint_2_shift, // column 27 + p_y_high_limbs_range_constraint_3_shift, // column 28 + p_y_high_limbs_range_constraint_4_shift, // column 29 + p_y_high_limbs_range_constraint_tail_shift, // column 30 + z_low_limbs_shift, // column 31 + z_low_limbs_range_constraint_0_shift, // column 32 + z_low_limbs_range_constraint_1_shift, // column 33 + z_low_limbs_range_constraint_2_shift, // column 34 + z_low_limbs_range_constraint_3_shift, // column 35 + z_low_limbs_range_constraint_4_shift, // column 36 + z_low_limbs_range_constraint_tail_shift, // column 37 + z_high_limbs_shift, // column 38 + z_high_limbs_range_constraint_0_shift, // column 39 + z_high_limbs_range_constraint_1_shift, // column 40 + z_high_limbs_range_constraint_2_shift, // column 41 + z_high_limbs_range_constraint_3_shift, // column 42 + z_high_limbs_range_constraint_4_shift, // column 43 + z_high_limbs_range_constraint_tail_shift, // column 44 + accumulators_binary_limbs_0_shift, // column 45 + accumulators_binary_limbs_1_shift, // column 46 + accumulators_binary_limbs_2_shift, // column 47 + accumulators_binary_limbs_3_shift, // column 48 + accumulator_low_limbs_range_constraint_0_shift, // column 49 + accumulator_low_limbs_range_constraint_1_shift, // column 50 + accumulator_low_limbs_range_constraint_2_shift, // column 51 + accumulator_low_limbs_range_constraint_3_shift, // column 52 + accumulator_low_limbs_range_constraint_4_shift, // column 53 + accumulator_low_limbs_range_constraint_tail_shift, // column 54 + accumulator_high_limbs_range_constraint_0_shift, // column 55 + accumulator_high_limbs_range_constraint_1_shift, // column 56 + accumulator_high_limbs_range_constraint_2_shift, // column 57 + accumulator_high_limbs_range_constraint_3_shift, // column 58 + accumulator_high_limbs_range_constraint_4_shift, // column 59 + accumulator_high_limbs_range_constraint_tail_shift, // column 60 + quotient_low_binary_limbs_shift, // column 61 + quotient_high_binary_limbs_shift, // column 62 + quotient_low_limbs_range_constraint_0_shift, // column 63 + quotient_low_limbs_range_constraint_1_shift, // column 64 + quotient_low_limbs_range_constraint_2_shift, // column 65 + quotient_low_limbs_range_constraint_3_shift, // column 66 + quotient_low_limbs_range_constraint_4_shift, // column 67 + quotient_low_limbs_range_constraint_tail_shift, // column 68 + quotient_high_limbs_range_constraint_0_shift, // column 69 + quotient_high_limbs_range_constraint_1_shift, // column 70 + quotient_high_limbs_range_constraint_2_shift, // column 71 + quotient_high_limbs_range_constraint_3_shift, // column 72 + quotient_high_limbs_range_constraint_4_shift, // column 73 + quotient_high_limbs_range_constraint_tail_shift, // column 74 + relation_wide_limbs_shift, // column 75 + relation_wide_limbs_range_constraint_0_shift, // column 76 + relation_wide_limbs_range_constraint_1_shift, // column 77 + relation_wide_limbs_range_constraint_2_shift, // column 78 + relation_wide_limbs_range_constraint_3_shift, // column 79 + ordered_range_constraints_0_shift, // column 80 + ordered_range_constraints_1_shift, // column 81 + ordered_range_constraints_2_shift, // column 82 + ordered_range_constraints_3_shift, // column 83 + ordered_range_constraints_4_shift, // column 84 + z_perm_shift) // column 85 + }; /** * @brief A base class labelling all entities (for instance, all of the polynomials used by the prover during * sumcheck) in this Honk variant along with particular subsets of interest * @details Used to build containers for: the prover's polynomial during sumcheck; the sumcheck's folded * polynomials; the univariates consturcted during during sumcheck; the evaluations produced by sumcheck. * - * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "shiftEntities". It could be - * implemented as such, but we have this now. + * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + ShiftedEntities. */ - template - class AllEntities : public AllEntities_ { + template + class AllEntities : public PrecomputedEntities, + public WitnessEntities, + public ShiftedEntities { public: - DataType op; // column 0 - DataType x_lo_y_hi; // column 1 - DataType x_hi_z_1; // column 2 - DataType y_lo_z_2; // column 3 - DataType p_x_low_limbs; // column 4 - DataType p_x_low_limbs_range_constraint_0; // column 5 - DataType p_x_low_limbs_range_constraint_1; // column 6 - DataType p_x_low_limbs_range_constraint_2; // column 7 - DataType p_x_low_limbs_range_constraint_3; // column 8 - DataType p_x_low_limbs_range_constraint_4; // column 9 - DataType p_x_low_limbs_range_constraint_tail; // column 10 - DataType p_x_high_limbs; // column 11 - DataType p_x_high_limbs_range_constraint_0; // column 12 - DataType p_x_high_limbs_range_constraint_1; // column 13 - DataType p_x_high_limbs_range_constraint_2; // column 14 - DataType p_x_high_limbs_range_constraint_3; // column 15 - DataType p_x_high_limbs_range_constraint_4; // column 16 - DataType p_x_high_limbs_range_constraint_tail; // column 17 - DataType p_y_low_limbs; // column 18 - DataType p_y_low_limbs_range_constraint_0; // column 19 - DataType p_y_low_limbs_range_constraint_1; // column 20 - DataType p_y_low_limbs_range_constraint_2; // column 21 - DataType p_y_low_limbs_range_constraint_3; // column 22 - DataType p_y_low_limbs_range_constraint_4; // column 23 - DataType p_y_low_limbs_range_constraint_tail; // column 24 - DataType p_y_high_limbs; // column 25 - DataType p_y_high_limbs_range_constraint_0; // column 26 - DataType p_y_high_limbs_range_constraint_1; // column 27 - DataType p_y_high_limbs_range_constraint_2; // column 28 - DataType p_y_high_limbs_range_constraint_3; // column 29 - DataType p_y_high_limbs_range_constraint_4; // column 30 - DataType p_y_high_limbs_range_constraint_tail; // column 31 - DataType z_low_limbs; // column 32 - DataType z_low_limbs_range_constraint_0; // column 33 - DataType z_low_limbs_range_constraint_1; // column 34 - DataType z_low_limbs_range_constraint_2; // column 35 - DataType z_low_limbs_range_constraint_3; // column 36 - DataType z_low_limbs_range_constraint_4; // column 37 - DataType z_low_limbs_range_constraint_tail; // column 38 - DataType z_high_limbs; // column 39 - DataType z_high_limbs_range_constraint_0; // column 40 - DataType z_high_limbs_range_constraint_1; // column 41 - DataType z_high_limbs_range_constraint_2; // column 42 - DataType z_high_limbs_range_constraint_3; // column 43 - DataType z_high_limbs_range_constraint_4; // column 44 - DataType z_high_limbs_range_constraint_tail; // column 45 - DataType accumulators_binary_limbs_0; // column 46 - DataType accumulators_binary_limbs_1; // column 47 - DataType accumulators_binary_limbs_2; // column 48 - DataType accumulators_binary_limbs_3; // column 49 - DataType accumulator_low_limbs_range_constraint_0; // column 50 - DataType accumulator_low_limbs_range_constraint_1; // column 51 - DataType accumulator_low_limbs_range_constraint_2; // column 52 - DataType accumulator_low_limbs_range_constraint_3; // column 53 - DataType accumulator_low_limbs_range_constraint_4; // column 54 - DataType accumulator_low_limbs_range_constraint_tail; // column 55 - DataType accumulator_high_limbs_range_constraint_0; // column 56 - DataType accumulator_high_limbs_range_constraint_1; // column 57 - DataType accumulator_high_limbs_range_constraint_2; // column 58 - DataType accumulator_high_limbs_range_constraint_3; // column 59 - DataType accumulator_high_limbs_range_constraint_4; // column 60 - DataType accumulator_high_limbs_range_constraint_tail; // column 61 - DataType quotient_low_binary_limbs; // column 62 - DataType quotient_high_binary_limbs; // column 63 - DataType quotient_low_limbs_range_constraint_0; // column 64 - DataType quotient_low_limbs_range_constraint_1; // column 65 - DataType quotient_low_limbs_range_constraint_2; // column 66 - DataType quotient_low_limbs_range_constraint_3; // column 67 - DataType quotient_low_limbs_range_constraint_4; // column 68 - DataType quotient_low_limbs_range_constraint_tail; // column 69 - DataType quotient_high_limbs_range_constraint_0; // column 70 - DataType quotient_high_limbs_range_constraint_1; // column 71 - DataType quotient_high_limbs_range_constraint_2; // column 72 - DataType quotient_high_limbs_range_constraint_3; // column 73 - DataType quotient_high_limbs_range_constraint_4; // column 74 - DataType quotient_high_limbs_range_constraint_tail; // column 75 - DataType relation_wide_limbs; // column 76 - DataType relation_wide_limbs_range_constraint_0; // column 77 - DataType relation_wide_limbs_range_constraint_1; // column 78 - DataType relation_wide_limbs_range_constraint_2; // column 79 - DataType relation_wide_limbs_range_constraint_3; // column 80 - DataType concatenated_range_constraints_0; // column 81 - DataType concatenated_range_constraints_1; // column 82 - DataType concatenated_range_constraints_2; // column 83 - DataType concatenated_range_constraints_3; // column 84 - DataType ordered_range_constraints_0; // column 85 - DataType ordered_range_constraints_1; // column 86 - DataType ordered_range_constraints_2; // column 87 - DataType ordered_range_constraints_3; // column 88 - DataType ordered_range_constraints_4; // column 89 - DataType z_perm; // column 90 - DataType x_lo_y_hi_shift; // column 91 - DataType x_hi_z_1_shift; // column 92 - DataType y_lo_z_2_shift; // column 93 - DataType p_x_low_limbs_shift; // column 94 - DataType p_x_low_limbs_range_constraint_0_shift; // column 95 - DataType p_x_low_limbs_range_constraint_1_shift; // column 96 - DataType p_x_low_limbs_range_constraint_2_shift; // column 97 - DataType p_x_low_limbs_range_constraint_3_shift; // column 98 - DataType p_x_low_limbs_range_constraint_4_shift; // column 99 - DataType p_x_low_limbs_range_constraint_tail_shift; // column 100 - DataType p_x_high_limbs_shift; // column 101 - DataType p_x_high_limbs_range_constraint_0_shift; // column 102 - DataType p_x_high_limbs_range_constraint_1_shift; // column 103 - DataType p_x_high_limbs_range_constraint_2_shift; // column 104 - DataType p_x_high_limbs_range_constraint_3_shift; // column 105 - DataType p_x_high_limbs_range_constraint_4_shift; // column 106 - DataType p_x_high_limbs_range_constraint_tail_shift; // column 107 - DataType p_y_low_limbs_shift; // column 108 - DataType p_y_low_limbs_range_constraint_0_shift; // column 109 - DataType p_y_low_limbs_range_constraint_1_shift; // column 110 - DataType p_y_low_limbs_range_constraint_2_shift; // column 111 - DataType p_y_low_limbs_range_constraint_3_shift; // column 112 - DataType p_y_low_limbs_range_constraint_4_shift; // column 113 - DataType p_y_low_limbs_range_constraint_tail_shift; // column 114 - DataType p_y_high_limbs_shift; // column 115 - DataType p_y_high_limbs_range_constraint_0_shift; // column 116 - DataType p_y_high_limbs_range_constraint_1_shift; // column 117 - DataType p_y_high_limbs_range_constraint_2_shift; // column 118 - DataType p_y_high_limbs_range_constraint_3_shift; // column 119 - DataType p_y_high_limbs_range_constraint_4_shift; // column 120 - DataType p_y_high_limbs_range_constraint_tail_shift; // column 121 - DataType z_low_limbs_shift; // column 122 - DataType z_low_limbs_range_constraint_0_shift; // column 123 - DataType z_low_limbs_range_constraint_1_shift; // column 124 - DataType z_low_limbs_range_constraint_2_shift; // column 125 - DataType z_low_limbs_range_constraint_3_shift; // column 126 - DataType z_low_limbs_range_constraint_4_shift; // column 127 - DataType z_low_limbs_range_constraint_tail_shift; // column 128 - DataType z_high_limbs_shift; // column 129 - DataType z_high_limbs_range_constraint_0_shift; // column 130 - DataType z_high_limbs_range_constraint_1_shift; // column 131 - DataType z_high_limbs_range_constraint_2_shift; // column 132 - DataType z_high_limbs_range_constraint_3_shift; // column 133 - DataType z_high_limbs_range_constraint_4_shift; // column 134 - DataType z_high_limbs_range_constraint_tail_shift; // column 135 - DataType accumulators_binary_limbs_0_shift; // column 136 - DataType accumulators_binary_limbs_1_shift; // column 137 - DataType accumulators_binary_limbs_2_shift; // column 138 - DataType accumulators_binary_limbs_3_shift; // column 139 - DataType accumulator_low_limbs_range_constraint_0_shift; // column 140 - DataType accumulator_low_limbs_range_constraint_1_shift; // column 141 - DataType accumulator_low_limbs_range_constraint_2_shift; // column 142 - DataType accumulator_low_limbs_range_constraint_3_shift; // column 143 - DataType accumulator_low_limbs_range_constraint_4_shift; // column 144 - DataType accumulator_low_limbs_range_constraint_tail_shift; // column 145 - DataType accumulator_high_limbs_range_constraint_0_shift; // column 146 - DataType accumulator_high_limbs_range_constraint_1_shift; // column 147 - DataType accumulator_high_limbs_range_constraint_2_shift; // column 148 - DataType accumulator_high_limbs_range_constraint_3_shift; // column 149 - DataType accumulator_high_limbs_range_constraint_4_shift; // column 150 - DataType accumulator_high_limbs_range_constraint_tail_shift; // column 151 - DataType quotient_low_binary_limbs_shift; // column 152 - DataType quotient_high_binary_limbs_shift; // column 153 - DataType quotient_low_limbs_range_constraint_0_shift; // column 154 - DataType quotient_low_limbs_range_constraint_1_shift; // column 155 - DataType quotient_low_limbs_range_constraint_2_shift; // column 156 - DataType quotient_low_limbs_range_constraint_3_shift; // column 157 - DataType quotient_low_limbs_range_constraint_4_shift; // column 158 - DataType quotient_low_limbs_range_constraint_tail_shift; // column 159 - DataType quotient_high_limbs_range_constraint_0_shift; // column 160 - DataType quotient_high_limbs_range_constraint_1_shift; // column 161 - DataType quotient_high_limbs_range_constraint_2_shift; // column 162 - DataType quotient_high_limbs_range_constraint_3_shift; // column 163 - DataType quotient_high_limbs_range_constraint_4_shift; // column 164 - DataType quotient_high_limbs_range_constraint_tail_shift; // column 165 - DataType relation_wide_limbs_shift; // column 166 - DataType relation_wide_limbs_range_constraint_0_shift; // column 167 - DataType relation_wide_limbs_range_constraint_1_shift; // column 168 - DataType relation_wide_limbs_range_constraint_2_shift; // column 169 - DataType relation_wide_limbs_range_constraint_3_shift; // column 170 - DataType ordered_range_constraints_0_shift; // column 171 - DataType ordered_range_constraints_1_shift; // column 172 - DataType ordered_range_constraints_2_shift; // column 173 - DataType ordered_range_constraints_3_shift; // column 174 - DataType ordered_range_constraints_4_shift; // column 175 - DataType z_perm_shift; // column 176 - DataType lagrange_first; // column 177 - DataType lagrange_last; // column 178 - DataType lagrange_odd_in_minicircuit; // column 179 - DataType lagrange_even_in_minicircuit; // column 180 - DataType lagrange_second; // column 181 - DataType lagrange_second_to_last_in_minicircuit; // column 182 - DataType ordered_extra_range_constraints_numerator; // column 183 - // defines a method pointer_view that returns the following, with const and non-const variants - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &op, - &x_lo_y_hi, - &x_hi_z_1, - &y_lo_z_2, - &p_x_low_limbs, - &p_x_low_limbs_range_constraint_0, - &p_x_low_limbs_range_constraint_1, - &p_x_low_limbs_range_constraint_2, - &p_x_low_limbs_range_constraint_3, - &p_x_low_limbs_range_constraint_4, - &p_x_low_limbs_range_constraint_tail, - &p_x_high_limbs, - &p_x_high_limbs_range_constraint_0, - &p_x_high_limbs_range_constraint_1, - &p_x_high_limbs_range_constraint_2, - &p_x_high_limbs_range_constraint_3, - &p_x_high_limbs_range_constraint_4, - &p_x_high_limbs_range_constraint_tail, - &p_y_low_limbs, - &p_y_low_limbs_range_constraint_0, - &p_y_low_limbs_range_constraint_1, - &p_y_low_limbs_range_constraint_2, - &p_y_low_limbs_range_constraint_3, - &p_y_low_limbs_range_constraint_4, - &p_y_low_limbs_range_constraint_tail, - &p_y_high_limbs, - &p_y_high_limbs_range_constraint_0, - &p_y_high_limbs_range_constraint_1, - &p_y_high_limbs_range_constraint_2, - &p_y_high_limbs_range_constraint_3, - &p_y_high_limbs_range_constraint_4, - &p_y_high_limbs_range_constraint_tail, - &z_low_limbs, - &z_low_limbs_range_constraint_0, - &z_low_limbs_range_constraint_1, - &z_low_limbs_range_constraint_2, - &z_low_limbs_range_constraint_3, - &z_low_limbs_range_constraint_4, - &z_low_limbs_range_constraint_tail, - &z_high_limbs, - &z_high_limbs_range_constraint_0, - &z_high_limbs_range_constraint_1, - &z_high_limbs_range_constraint_2, - &z_high_limbs_range_constraint_3, - &z_high_limbs_range_constraint_4, - &z_high_limbs_range_constraint_tail, - &accumulators_binary_limbs_0, - &accumulators_binary_limbs_1, - &accumulators_binary_limbs_2, - &accumulators_binary_limbs_3, - &accumulator_low_limbs_range_constraint_0, - &accumulator_low_limbs_range_constraint_1, - &accumulator_low_limbs_range_constraint_2, - &accumulator_low_limbs_range_constraint_3, - &accumulator_low_limbs_range_constraint_4, - &accumulator_low_limbs_range_constraint_tail, - &accumulator_high_limbs_range_constraint_0, - &accumulator_high_limbs_range_constraint_1, - &accumulator_high_limbs_range_constraint_2, - &accumulator_high_limbs_range_constraint_3, - &accumulator_high_limbs_range_constraint_4, - &accumulator_high_limbs_range_constraint_tail, - "ient_low_binary_limbs, - "ient_high_binary_limbs, - "ient_low_limbs_range_constraint_0, - "ient_low_limbs_range_constraint_1, - "ient_low_limbs_range_constraint_2, - "ient_low_limbs_range_constraint_3, - "ient_low_limbs_range_constraint_4, - "ient_low_limbs_range_constraint_tail, - "ient_high_limbs_range_constraint_0, - "ient_high_limbs_range_constraint_1, - "ient_high_limbs_range_constraint_2, - "ient_high_limbs_range_constraint_3, - "ient_high_limbs_range_constraint_4, - "ient_high_limbs_range_constraint_tail, - &relation_wide_limbs, - &relation_wide_limbs_range_constraint_0, - &relation_wide_limbs_range_constraint_1, - &relation_wide_limbs_range_constraint_2, - &relation_wide_limbs_range_constraint_3, - &concatenated_range_constraints_0, - &concatenated_range_constraints_1, - &concatenated_range_constraints_2, - &concatenated_range_constraints_3, - &ordered_range_constraints_0, - &ordered_range_constraints_1, - &ordered_range_constraints_2, - &ordered_range_constraints_3, - &ordered_range_constraints_4, - &z_perm, - &x_lo_y_hi_shift, - &x_hi_z_1_shift, - &y_lo_z_2_shift, - &p_x_low_limbs_shift, - &p_x_low_limbs_range_constraint_0_shift, - &p_x_low_limbs_range_constraint_1_shift, - &p_x_low_limbs_range_constraint_2_shift, - &p_x_low_limbs_range_constraint_3_shift, - &p_x_low_limbs_range_constraint_4_shift, - &p_x_low_limbs_range_constraint_tail_shift, - &p_x_high_limbs_shift, - &p_x_high_limbs_range_constraint_0_shift, - &p_x_high_limbs_range_constraint_1_shift, - &p_x_high_limbs_range_constraint_2_shift, - &p_x_high_limbs_range_constraint_3_shift, - &p_x_high_limbs_range_constraint_4_shift, - &p_x_high_limbs_range_constraint_tail_shift, - &p_y_low_limbs_shift, - &p_y_low_limbs_range_constraint_0_shift, - &p_y_low_limbs_range_constraint_1_shift, - &p_y_low_limbs_range_constraint_2_shift, - &p_y_low_limbs_range_constraint_3_shift, - &p_y_low_limbs_range_constraint_4_shift, - &p_y_low_limbs_range_constraint_tail_shift, - &p_y_high_limbs_shift, - &p_y_high_limbs_range_constraint_0_shift, - &p_y_high_limbs_range_constraint_1_shift, - &p_y_high_limbs_range_constraint_2_shift, - &p_y_high_limbs_range_constraint_3_shift, - &p_y_high_limbs_range_constraint_4_shift, - &p_y_high_limbs_range_constraint_tail_shift, - &z_low_limbs_shift, - &z_low_limbs_range_constraint_0_shift, - &z_low_limbs_range_constraint_1_shift, - &z_low_limbs_range_constraint_2_shift, - &z_low_limbs_range_constraint_3_shift, - &z_low_limbs_range_constraint_4_shift, - &z_low_limbs_range_constraint_tail_shift, - &z_high_limbs_shift, - &z_high_limbs_range_constraint_0_shift, - &z_high_limbs_range_constraint_1_shift, - &z_high_limbs_range_constraint_2_shift, - &z_high_limbs_range_constraint_3_shift, - &z_high_limbs_range_constraint_4_shift, - &z_high_limbs_range_constraint_tail_shift, - &accumulators_binary_limbs_0_shift, - &accumulators_binary_limbs_1_shift, - &accumulators_binary_limbs_2_shift, - &accumulators_binary_limbs_3_shift, - &accumulator_low_limbs_range_constraint_0_shift, - &accumulator_low_limbs_range_constraint_1_shift, - &accumulator_low_limbs_range_constraint_2_shift, - &accumulator_low_limbs_range_constraint_3_shift, - &accumulator_low_limbs_range_constraint_4_shift, - &accumulator_low_limbs_range_constraint_tail_shift, - &accumulator_high_limbs_range_constraint_0_shift, - &accumulator_high_limbs_range_constraint_1_shift, - &accumulator_high_limbs_range_constraint_2_shift, - &accumulator_high_limbs_range_constraint_3_shift, - &accumulator_high_limbs_range_constraint_4_shift, - &accumulator_high_limbs_range_constraint_tail_shift, - "ient_low_binary_limbs_shift, - "ient_high_binary_limbs_shift, - "ient_low_limbs_range_constraint_0_shift, - "ient_low_limbs_range_constraint_1_shift, - "ient_low_limbs_range_constraint_2_shift, - "ient_low_limbs_range_constraint_3_shift, - "ient_low_limbs_range_constraint_4_shift, - "ient_low_limbs_range_constraint_tail_shift, - "ient_high_limbs_range_constraint_0_shift, - "ient_high_limbs_range_constraint_1_shift, - "ient_high_limbs_range_constraint_2_shift, - "ient_high_limbs_range_constraint_3_shift, - "ient_high_limbs_range_constraint_4_shift, - "ient_high_limbs_range_constraint_tail_shift, - &relation_wide_limbs_shift, - &relation_wide_limbs_range_constraint_0_shift, - &relation_wide_limbs_range_constraint_1_shift, - &relation_wide_limbs_range_constraint_2_shift, - &relation_wide_limbs_range_constraint_3_shift, - &ordered_range_constraints_0_shift, - &ordered_range_constraints_1_shift, - &ordered_range_constraints_2_shift, - &ordered_range_constraints_3_shift, - &ordered_range_constraints_4_shift, - &z_perm_shift, - &lagrange_first, - &lagrange_last, - &lagrange_odd_in_minicircuit, - &lagrange_even_in_minicircuit, - &lagrange_second, - &lagrange_second_to_last_in_minicircuit, - &ordered_extra_range_constraints_numerator) - std::vector get_wires() override + // Initialize members + AllEntities() + : PrecomputedEntities{} + , WitnessEntities{} + , ShiftedEntities{} + {} + RefVector get_wires() { + return { this->op, + this->x_lo_y_hi, + this->x_hi_z_1, + this->y_lo_z_2, + this->p_x_low_limbs, + this->p_x_low_limbs_range_constraint_0, + this->p_x_low_limbs_range_constraint_1, + this->p_x_low_limbs_range_constraint_2, + this->p_x_low_limbs_range_constraint_3, + this->p_x_low_limbs_range_constraint_4, + this->p_x_low_limbs_range_constraint_tail, + this->p_x_high_limbs, + this->p_x_high_limbs_range_constraint_0, + this->p_x_high_limbs_range_constraint_1, + this->p_x_high_limbs_range_constraint_2, + this->p_x_high_limbs_range_constraint_3, + this->p_x_high_limbs_range_constraint_4, + this->p_x_high_limbs_range_constraint_tail, + this->p_y_low_limbs, + this->p_y_low_limbs_range_constraint_0, + this->p_y_low_limbs_range_constraint_1, + this->p_y_low_limbs_range_constraint_2, + this->p_y_low_limbs_range_constraint_3, + this->p_y_low_limbs_range_constraint_4, + this->p_y_low_limbs_range_constraint_tail, + this->p_y_high_limbs, + this->p_y_high_limbs_range_constraint_0, + this->p_y_high_limbs_range_constraint_1, + this->p_y_high_limbs_range_constraint_2, + this->p_y_high_limbs_range_constraint_3, + this->p_y_high_limbs_range_constraint_4, + this->p_y_high_limbs_range_constraint_tail, + this->z_low_limbs, + this->z_low_limbs_range_constraint_0, + this->z_low_limbs_range_constraint_1, + this->z_low_limbs_range_constraint_2, + this->z_low_limbs_range_constraint_3, + this->z_low_limbs_range_constraint_4, + this->z_low_limbs_range_constraint_tail, + this->z_high_limbs, + this->z_high_limbs_range_constraint_0, + this->z_high_limbs_range_constraint_1, + this->z_high_limbs_range_constraint_2, + this->z_high_limbs_range_constraint_3, + this->z_high_limbs_range_constraint_4, + this->z_high_limbs_range_constraint_tail, + this->accumulators_binary_limbs_0, + this->accumulators_binary_limbs_1, + this->accumulators_binary_limbs_2, + this->accumulators_binary_limbs_3, + this->accumulator_low_limbs_range_constraint_0, + this->accumulator_low_limbs_range_constraint_1, + this->accumulator_low_limbs_range_constraint_2, + this->accumulator_low_limbs_range_constraint_3, + this->accumulator_low_limbs_range_constraint_4, + this->accumulator_low_limbs_range_constraint_tail, + this->accumulator_high_limbs_range_constraint_0, + this->accumulator_high_limbs_range_constraint_1, + this->accumulator_high_limbs_range_constraint_2, + this->accumulator_high_limbs_range_constraint_3, + this->accumulator_high_limbs_range_constraint_4, + this->accumulator_high_limbs_range_constraint_tail, + this->quotient_low_binary_limbs, + this->quotient_high_binary_limbs, + this->quotient_low_limbs_range_constraint_0, + this->quotient_low_limbs_range_constraint_1, + this->quotient_low_limbs_range_constraint_2, + this->quotient_low_limbs_range_constraint_3, + this->quotient_low_limbs_range_constraint_4, + this->quotient_low_limbs_range_constraint_tail, + this->quotient_high_limbs_range_constraint_0, + this->quotient_high_limbs_range_constraint_1, + this->quotient_high_limbs_range_constraint_2, + this->quotient_high_limbs_range_constraint_3, + this->quotient_high_limbs_range_constraint_4, + this->quotient_high_limbs_range_constraint_tail, + this->relation_wide_limbs, + this->relation_wide_limbs_range_constraint_0, + this->relation_wide_limbs_range_constraint_1, + this->relation_wide_limbs_range_constraint_2, + this->relation_wide_limbs_range_constraint_3, + this->ordered_range_constraints_0, + this->ordered_range_constraints_1, + this->ordered_range_constraints_2, + this->ordered_range_constraints_3, + this->ordered_range_constraints_4 }; + } - return { op, - x_lo_y_hi, - x_hi_z_1, - y_lo_z_2, - p_x_low_limbs, - p_x_low_limbs_range_constraint_0, - p_x_low_limbs_range_constraint_1, - p_x_low_limbs_range_constraint_2, - p_x_low_limbs_range_constraint_3, - p_x_low_limbs_range_constraint_4, - p_x_low_limbs_range_constraint_tail, - p_x_high_limbs, - p_x_high_limbs_range_constraint_0, - p_x_high_limbs_range_constraint_1, - p_x_high_limbs_range_constraint_2, - p_x_high_limbs_range_constraint_3, - p_x_high_limbs_range_constraint_4, - p_x_high_limbs_range_constraint_tail, - p_y_low_limbs, - p_y_low_limbs_range_constraint_0, - p_y_low_limbs_range_constraint_1, - p_y_low_limbs_range_constraint_2, - p_y_low_limbs_range_constraint_3, - p_y_low_limbs_range_constraint_4, - p_y_low_limbs_range_constraint_tail, - p_y_high_limbs, - p_y_high_limbs_range_constraint_0, - p_y_high_limbs_range_constraint_1, - p_y_high_limbs_range_constraint_2, - p_y_high_limbs_range_constraint_3, - p_y_high_limbs_range_constraint_4, - p_y_high_limbs_range_constraint_tail, - z_low_limbs, - z_low_limbs_range_constraint_0, - z_low_limbs_range_constraint_1, - z_low_limbs_range_constraint_2, - z_low_limbs_range_constraint_3, - z_low_limbs_range_constraint_4, - z_low_limbs_range_constraint_tail, - z_high_limbs, - z_high_limbs_range_constraint_0, - z_high_limbs_range_constraint_1, - z_high_limbs_range_constraint_2, - z_high_limbs_range_constraint_3, - z_high_limbs_range_constraint_4, - z_high_limbs_range_constraint_tail, - accumulators_binary_limbs_0, - accumulators_binary_limbs_1, - accumulators_binary_limbs_2, - accumulators_binary_limbs_3, - accumulator_low_limbs_range_constraint_0, - accumulator_low_limbs_range_constraint_1, - accumulator_low_limbs_range_constraint_2, - accumulator_low_limbs_range_constraint_3, - accumulator_low_limbs_range_constraint_4, - accumulator_low_limbs_range_constraint_tail, - accumulator_high_limbs_range_constraint_0, - accumulator_high_limbs_range_constraint_1, - accumulator_high_limbs_range_constraint_2, - accumulator_high_limbs_range_constraint_3, - accumulator_high_limbs_range_constraint_4, - accumulator_high_limbs_range_constraint_tail, - quotient_low_binary_limbs, - quotient_high_binary_limbs, - quotient_low_limbs_range_constraint_0, - quotient_low_limbs_range_constraint_1, - quotient_low_limbs_range_constraint_2, - quotient_low_limbs_range_constraint_3, - quotient_low_limbs_range_constraint_4, - quotient_low_limbs_range_constraint_tail, - quotient_high_limbs_range_constraint_0, - quotient_high_limbs_range_constraint_1, - quotient_high_limbs_range_constraint_2, - quotient_high_limbs_range_constraint_3, - quotient_high_limbs_range_constraint_4, - quotient_high_limbs_range_constraint_tail, - relation_wide_limbs, - relation_wide_limbs_range_constraint_0, - relation_wide_limbs_range_constraint_1, - relation_wide_limbs_range_constraint_2, - relation_wide_limbs_range_constraint_3, - ordered_range_constraints_0, - ordered_range_constraints_1, - ordered_range_constraints_2, - ordered_range_constraints_3, - ordered_range_constraints_4 }; - }; - + DEFINE_COMPOUND_GET_ALL(PrecomputedEntities::get_all(), + WitnessEntities::get_all(), + ShiftedEntities::get_all()) + DEFINE_COMPOUND_POINTER_VIEW(PrecomputedEntities::pointer_view(), + WitnessEntities::pointer_view(), + ShiftedEntities::pointer_view()) /** * @brief Get the polynomials that are concatenated for the permutation relation * - * @return std::vector> + * @return std::vector> */ - std::vector> get_concatenation_groups() + std::vector> get_concatenation_groups() { return { { - p_x_low_limbs_range_constraint_0, - p_x_low_limbs_range_constraint_1, - p_x_low_limbs_range_constraint_2, - p_x_low_limbs_range_constraint_3, - p_x_low_limbs_range_constraint_4, - p_x_low_limbs_range_constraint_tail, - p_x_high_limbs_range_constraint_0, - p_x_high_limbs_range_constraint_1, - p_x_high_limbs_range_constraint_2, - p_x_high_limbs_range_constraint_3, - p_x_high_limbs_range_constraint_4, - p_x_high_limbs_range_constraint_tail, - p_y_low_limbs_range_constraint_0, - p_y_low_limbs_range_constraint_1, - p_y_low_limbs_range_constraint_2, - p_y_low_limbs_range_constraint_3, + this->p_x_low_limbs_range_constraint_0, + this->p_x_low_limbs_range_constraint_1, + this->p_x_low_limbs_range_constraint_2, + this->p_x_low_limbs_range_constraint_3, + this->p_x_low_limbs_range_constraint_4, + this->p_x_low_limbs_range_constraint_tail, + this->p_x_high_limbs_range_constraint_0, + this->p_x_high_limbs_range_constraint_1, + this->p_x_high_limbs_range_constraint_2, + this->p_x_high_limbs_range_constraint_3, + this->p_x_high_limbs_range_constraint_4, + this->p_x_high_limbs_range_constraint_tail, + this->p_y_low_limbs_range_constraint_0, + this->p_y_low_limbs_range_constraint_1, + this->p_y_low_limbs_range_constraint_2, + this->p_y_low_limbs_range_constraint_3, }, { - p_y_low_limbs_range_constraint_4, - p_y_low_limbs_range_constraint_tail, - p_y_high_limbs_range_constraint_0, - p_y_high_limbs_range_constraint_1, - p_y_high_limbs_range_constraint_2, - p_y_high_limbs_range_constraint_3, - p_y_high_limbs_range_constraint_4, - p_y_high_limbs_range_constraint_tail, - z_low_limbs_range_constraint_0, - z_low_limbs_range_constraint_1, - z_low_limbs_range_constraint_2, - z_low_limbs_range_constraint_3, - z_low_limbs_range_constraint_4, - z_low_limbs_range_constraint_tail, - z_high_limbs_range_constraint_0, - z_high_limbs_range_constraint_1, + this->p_y_low_limbs_range_constraint_4, + this->p_y_low_limbs_range_constraint_tail, + this->p_y_high_limbs_range_constraint_0, + this->p_y_high_limbs_range_constraint_1, + this->p_y_high_limbs_range_constraint_2, + this->p_y_high_limbs_range_constraint_3, + this->p_y_high_limbs_range_constraint_4, + this->p_y_high_limbs_range_constraint_tail, + this->z_low_limbs_range_constraint_0, + this->z_low_limbs_range_constraint_1, + this->z_low_limbs_range_constraint_2, + this->z_low_limbs_range_constraint_3, + this->z_low_limbs_range_constraint_4, + this->z_low_limbs_range_constraint_tail, + this->z_high_limbs_range_constraint_0, + this->z_high_limbs_range_constraint_1, }, { - z_high_limbs_range_constraint_2, - z_high_limbs_range_constraint_3, - z_high_limbs_range_constraint_4, - z_high_limbs_range_constraint_tail, - accumulator_low_limbs_range_constraint_0, - accumulator_low_limbs_range_constraint_1, - accumulator_low_limbs_range_constraint_2, - accumulator_low_limbs_range_constraint_3, - accumulator_low_limbs_range_constraint_4, - accumulator_low_limbs_range_constraint_tail, - accumulator_high_limbs_range_constraint_0, - accumulator_high_limbs_range_constraint_1, - accumulator_high_limbs_range_constraint_2, - accumulator_high_limbs_range_constraint_3, - accumulator_high_limbs_range_constraint_4, - accumulator_high_limbs_range_constraint_tail, + this->z_high_limbs_range_constraint_2, + this->z_high_limbs_range_constraint_3, + this->z_high_limbs_range_constraint_4, + this->z_high_limbs_range_constraint_tail, + this->accumulator_low_limbs_range_constraint_0, + this->accumulator_low_limbs_range_constraint_1, + this->accumulator_low_limbs_range_constraint_2, + this->accumulator_low_limbs_range_constraint_3, + this->accumulator_low_limbs_range_constraint_4, + this->accumulator_low_limbs_range_constraint_tail, + this->accumulator_high_limbs_range_constraint_0, + this->accumulator_high_limbs_range_constraint_1, + this->accumulator_high_limbs_range_constraint_2, + this->accumulator_high_limbs_range_constraint_3, + this->accumulator_high_limbs_range_constraint_4, + this->accumulator_high_limbs_range_constraint_tail, }, { - quotient_low_limbs_range_constraint_0, - quotient_low_limbs_range_constraint_1, - quotient_low_limbs_range_constraint_2, - quotient_low_limbs_range_constraint_3, - quotient_low_limbs_range_constraint_4, - quotient_low_limbs_range_constraint_tail, - quotient_high_limbs_range_constraint_0, - quotient_high_limbs_range_constraint_1, - quotient_high_limbs_range_constraint_2, - quotient_high_limbs_range_constraint_3, - quotient_high_limbs_range_constraint_4, - quotient_high_limbs_range_constraint_tail, - relation_wide_limbs_range_constraint_0, - relation_wide_limbs_range_constraint_1, - relation_wide_limbs_range_constraint_2, - relation_wide_limbs_range_constraint_3, + this->quotient_low_limbs_range_constraint_0, + this->quotient_low_limbs_range_constraint_1, + this->quotient_low_limbs_range_constraint_2, + this->quotient_low_limbs_range_constraint_3, + this->quotient_low_limbs_range_constraint_4, + this->quotient_low_limbs_range_constraint_tail, + this->quotient_high_limbs_range_constraint_0, + this->quotient_high_limbs_range_constraint_1, + this->quotient_high_limbs_range_constraint_2, + this->quotient_high_limbs_range_constraint_3, + this->quotient_high_limbs_range_constraint_4, + this->quotient_high_limbs_range_constraint_tail, + this->relation_wide_limbs_range_constraint_0, + this->relation_wide_limbs_range_constraint_1, + this->relation_wide_limbs_range_constraint_2, + this->relation_wide_limbs_range_constraint_3, }, }; } /** * @brief Get the polynomials that need to be constructed from other polynomials by concatenation * - * @return std::vector + * @return RefVector */ - std::vector get_concatenated_constraints() + RefVector get_concatenated_constraints() { - return { concatenated_range_constraints_0, - concatenated_range_constraints_1, - concatenated_range_constraints_2, - concatenated_range_constraints_3 }; + return ConcatenatedRangeConstraints::get_all(); }; /** * @brief Get the polynomials from the grand product denominator * - * @return std::vector + * @return RefVector */ - std::vector get_ordered_constraints() + RefVector get_ordered_constraints() { - return { ordered_range_constraints_0, - ordered_range_constraints_1, - ordered_range_constraints_2, - ordered_range_constraints_3, - ordered_range_constraints_4 }; + return { this->ordered_range_constraints_0, + this->ordered_range_constraints_1, + this->ordered_range_constraints_2, + this->ordered_range_constraints_3, + this->ordered_range_constraints_4 }; }; // Gemini-specific getters. - std::vector get_unshifted() override + RefVector get_unshifted() { return { - op, - x_lo_y_hi, - x_hi_z_1, - y_lo_z_2, - p_x_low_limbs, - p_x_low_limbs_range_constraint_0, - p_x_low_limbs_range_constraint_1, - p_x_low_limbs_range_constraint_2, - p_x_low_limbs_range_constraint_3, - p_x_low_limbs_range_constraint_4, - p_x_low_limbs_range_constraint_tail, - p_x_high_limbs, - p_x_high_limbs_range_constraint_0, - p_x_high_limbs_range_constraint_1, - p_x_high_limbs_range_constraint_2, - p_x_high_limbs_range_constraint_3, - p_x_high_limbs_range_constraint_4, - p_x_high_limbs_range_constraint_tail, - p_y_low_limbs, - p_y_low_limbs_range_constraint_0, - p_y_low_limbs_range_constraint_1, - p_y_low_limbs_range_constraint_2, - p_y_low_limbs_range_constraint_3, - p_y_low_limbs_range_constraint_4, - p_y_low_limbs_range_constraint_tail, - p_y_high_limbs, - p_y_high_limbs_range_constraint_0, - p_y_high_limbs_range_constraint_1, - p_y_high_limbs_range_constraint_2, - p_y_high_limbs_range_constraint_3, - p_y_high_limbs_range_constraint_4, - p_y_high_limbs_range_constraint_tail, - z_low_limbs, - z_low_limbs_range_constraint_0, - z_low_limbs_range_constraint_1, - z_low_limbs_range_constraint_2, - z_low_limbs_range_constraint_3, - z_low_limbs_range_constraint_4, - z_low_limbs_range_constraint_tail, - z_high_limbs, - z_high_limbs_range_constraint_0, - z_high_limbs_range_constraint_1, - z_high_limbs_range_constraint_2, - z_high_limbs_range_constraint_3, - z_high_limbs_range_constraint_4, - z_high_limbs_range_constraint_tail, - accumulators_binary_limbs_0, - accumulators_binary_limbs_1, - accumulators_binary_limbs_2, - accumulators_binary_limbs_3, - accumulator_low_limbs_range_constraint_0, - accumulator_low_limbs_range_constraint_1, - accumulator_low_limbs_range_constraint_2, - accumulator_low_limbs_range_constraint_3, - accumulator_low_limbs_range_constraint_4, - accumulator_low_limbs_range_constraint_tail, - accumulator_high_limbs_range_constraint_0, - accumulator_high_limbs_range_constraint_1, - accumulator_high_limbs_range_constraint_2, - accumulator_high_limbs_range_constraint_3, - accumulator_high_limbs_range_constraint_4, - accumulator_high_limbs_range_constraint_tail, - quotient_low_binary_limbs, - quotient_high_binary_limbs, - quotient_low_limbs_range_constraint_0, - quotient_low_limbs_range_constraint_1, - quotient_low_limbs_range_constraint_2, - quotient_low_limbs_range_constraint_3, - quotient_low_limbs_range_constraint_4, - quotient_low_limbs_range_constraint_tail, - quotient_high_limbs_range_constraint_0, - quotient_high_limbs_range_constraint_1, - quotient_high_limbs_range_constraint_2, - quotient_high_limbs_range_constraint_3, - quotient_high_limbs_range_constraint_4, - quotient_high_limbs_range_constraint_tail, - relation_wide_limbs, - relation_wide_limbs_range_constraint_0, - relation_wide_limbs_range_constraint_1, - relation_wide_limbs_range_constraint_2, - relation_wide_limbs_range_constraint_3, - ordered_range_constraints_0, - ordered_range_constraints_1, - ordered_range_constraints_2, - ordered_range_constraints_3, - ordered_range_constraints_4, - z_perm, - - lagrange_first, - lagrange_last, - lagrange_odd_in_minicircuit, - lagrange_even_in_minicircuit, - lagrange_second, - lagrange_second_to_last_in_minicircuit, - ordered_extra_range_constraints_numerator, + this->x_lo_y_hi, + this->x_hi_z_1, + this->y_lo_z_2, + this->p_x_low_limbs, + this->p_x_low_limbs_range_constraint_0, + this->p_x_low_limbs_range_constraint_1, + this->p_x_low_limbs_range_constraint_2, + this->p_x_low_limbs_range_constraint_3, + this->p_x_low_limbs_range_constraint_4, + this->p_x_low_limbs_range_constraint_tail, + this->p_x_high_limbs, + this->p_x_high_limbs_range_constraint_0, + this->p_x_high_limbs_range_constraint_1, + this->p_x_high_limbs_range_constraint_2, + this->p_x_high_limbs_range_constraint_3, + this->p_x_high_limbs_range_constraint_4, + this->p_x_high_limbs_range_constraint_tail, + this->p_y_low_limbs, + this->p_y_low_limbs_range_constraint_0, + this->p_y_low_limbs_range_constraint_1, + this->p_y_low_limbs_range_constraint_2, + this->p_y_low_limbs_range_constraint_3, + this->p_y_low_limbs_range_constraint_4, + this->p_y_low_limbs_range_constraint_tail, + this->p_y_high_limbs, + this->p_y_high_limbs_range_constraint_0, + this->p_y_high_limbs_range_constraint_1, + this->p_y_high_limbs_range_constraint_2, + this->p_y_high_limbs_range_constraint_3, + this->p_y_high_limbs_range_constraint_4, + this->p_y_high_limbs_range_constraint_tail, + this->z_low_limbs, + this->z_low_limbs_range_constraint_0, + this->z_low_limbs_range_constraint_1, + this->z_low_limbs_range_constraint_2, + this->z_low_limbs_range_constraint_3, + this->z_low_limbs_range_constraint_4, + this->z_low_limbs_range_constraint_tail, + this->z_high_limbs, + this->z_high_limbs_range_constraint_0, + this->z_high_limbs_range_constraint_1, + this->z_high_limbs_range_constraint_2, + this->z_high_limbs_range_constraint_3, + this->z_high_limbs_range_constraint_4, + this->z_high_limbs_range_constraint_tail, + this->accumulators_binary_limbs_0, + this->accumulators_binary_limbs_1, + this->accumulators_binary_limbs_2, + this->accumulators_binary_limbs_3, + this->accumulator_low_limbs_range_constraint_0, + this->accumulator_low_limbs_range_constraint_1, + this->accumulator_low_limbs_range_constraint_2, + this->accumulator_low_limbs_range_constraint_3, + this->accumulator_low_limbs_range_constraint_4, + this->accumulator_low_limbs_range_constraint_tail, + this->accumulator_high_limbs_range_constraint_0, + this->accumulator_high_limbs_range_constraint_1, + this->accumulator_high_limbs_range_constraint_2, + this->accumulator_high_limbs_range_constraint_3, + this->accumulator_high_limbs_range_constraint_4, + this->accumulator_high_limbs_range_constraint_tail, + this->quotient_low_binary_limbs, + this->quotient_high_binary_limbs, + this->quotient_low_limbs_range_constraint_0, + this->quotient_low_limbs_range_constraint_1, + this->quotient_low_limbs_range_constraint_2, + this->quotient_low_limbs_range_constraint_3, + this->quotient_low_limbs_range_constraint_4, + this->quotient_low_limbs_range_constraint_tail, + this->quotient_high_limbs_range_constraint_0, + this->quotient_high_limbs_range_constraint_1, + this->quotient_high_limbs_range_constraint_2, + this->quotient_high_limbs_range_constraint_3, + this->quotient_high_limbs_range_constraint_4, + this->quotient_high_limbs_range_constraint_tail, + this->relation_wide_limbs, + this->relation_wide_limbs_range_constraint_0, + this->relation_wide_limbs_range_constraint_1, + this->relation_wide_limbs_range_constraint_2, + this->relation_wide_limbs_range_constraint_3, + this->ordered_range_constraints_0, + this->ordered_range_constraints_1, + this->ordered_range_constraints_2, + this->ordered_range_constraints_3, + this->ordered_range_constraints_4, + this->z_perm, }; - }; - std::vector get_to_be_shifted() override - { - return { - x_lo_y_hi, - x_hi_z_1, - y_lo_z_2, - p_x_low_limbs, - p_x_low_limbs_range_constraint_0, - p_x_low_limbs_range_constraint_1, - p_x_low_limbs_range_constraint_2, - p_x_low_limbs_range_constraint_3, - p_x_low_limbs_range_constraint_4, - p_x_low_limbs_range_constraint_tail, - p_x_high_limbs, - p_x_high_limbs_range_constraint_0, - p_x_high_limbs_range_constraint_1, - p_x_high_limbs_range_constraint_2, - p_x_high_limbs_range_constraint_3, - p_x_high_limbs_range_constraint_4, - p_x_high_limbs_range_constraint_tail, - p_y_low_limbs, - p_y_low_limbs_range_constraint_0, - p_y_low_limbs_range_constraint_1, - p_y_low_limbs_range_constraint_2, - p_y_low_limbs_range_constraint_3, - p_y_low_limbs_range_constraint_4, - p_y_low_limbs_range_constraint_tail, - p_y_high_limbs, - p_y_high_limbs_range_constraint_0, - p_y_high_limbs_range_constraint_1, - p_y_high_limbs_range_constraint_2, - p_y_high_limbs_range_constraint_3, - p_y_high_limbs_range_constraint_4, - p_y_high_limbs_range_constraint_tail, - z_low_limbs, - z_low_limbs_range_constraint_0, - z_low_limbs_range_constraint_1, - z_low_limbs_range_constraint_2, - z_low_limbs_range_constraint_3, - z_low_limbs_range_constraint_4, - z_low_limbs_range_constraint_tail, - z_high_limbs, - z_high_limbs_range_constraint_0, - z_high_limbs_range_constraint_1, - z_high_limbs_range_constraint_2, - z_high_limbs_range_constraint_3, - z_high_limbs_range_constraint_4, - z_high_limbs_range_constraint_tail, - accumulators_binary_limbs_0, - accumulators_binary_limbs_1, - accumulators_binary_limbs_2, - accumulators_binary_limbs_3, - accumulator_low_limbs_range_constraint_0, - accumulator_low_limbs_range_constraint_1, - accumulator_low_limbs_range_constraint_2, - accumulator_low_limbs_range_constraint_3, - accumulator_low_limbs_range_constraint_4, - accumulator_low_limbs_range_constraint_tail, - accumulator_high_limbs_range_constraint_0, - accumulator_high_limbs_range_constraint_1, - accumulator_high_limbs_range_constraint_2, - accumulator_high_limbs_range_constraint_3, - accumulator_high_limbs_range_constraint_4, - accumulator_high_limbs_range_constraint_tail, - quotient_low_binary_limbs, - quotient_high_binary_limbs, - quotient_low_limbs_range_constraint_0, - quotient_low_limbs_range_constraint_1, - quotient_low_limbs_range_constraint_2, - quotient_low_limbs_range_constraint_3, - quotient_low_limbs_range_constraint_4, - quotient_low_limbs_range_constraint_tail, - quotient_high_limbs_range_constraint_0, - quotient_high_limbs_range_constraint_1, - quotient_high_limbs_range_constraint_2, - quotient_high_limbs_range_constraint_3, - quotient_high_limbs_range_constraint_4, - quotient_high_limbs_range_constraint_tail, - relation_wide_limbs, - relation_wide_limbs_range_constraint_0, - relation_wide_limbs_range_constraint_1, - relation_wide_limbs_range_constraint_2, - relation_wide_limbs_range_constraint_3, - ordered_range_constraints_0, - ordered_range_constraints_1, - ordered_range_constraints_2, - ordered_range_constraints_3, - ordered_range_constraints_4, - - z_perm, - }; - }; - std::vector get_shifted() override + } + // get_to_be_shifted is inherited + RefVector get_shifted() { - return { - x_lo_y_hi_shift, - x_hi_z_1_shift, - y_lo_z_2_shift, - p_x_low_limbs_shift, - p_x_low_limbs_range_constraint_0_shift, - p_x_low_limbs_range_constraint_1_shift, - p_x_low_limbs_range_constraint_2_shift, - p_x_low_limbs_range_constraint_3_shift, - p_x_low_limbs_range_constraint_4_shift, - p_x_low_limbs_range_constraint_tail_shift, - p_x_high_limbs_shift, - p_x_high_limbs_range_constraint_0_shift, - p_x_high_limbs_range_constraint_1_shift, - p_x_high_limbs_range_constraint_2_shift, - p_x_high_limbs_range_constraint_3_shift, - p_x_high_limbs_range_constraint_4_shift, - p_x_high_limbs_range_constraint_tail_shift, - p_y_low_limbs_shift, - p_y_low_limbs_range_constraint_0_shift, - p_y_low_limbs_range_constraint_1_shift, - p_y_low_limbs_range_constraint_2_shift, - p_y_low_limbs_range_constraint_3_shift, - p_y_low_limbs_range_constraint_4_shift, - p_y_low_limbs_range_constraint_tail_shift, - p_y_high_limbs_shift, - p_y_high_limbs_range_constraint_0_shift, - p_y_high_limbs_range_constraint_1_shift, - p_y_high_limbs_range_constraint_2_shift, - p_y_high_limbs_range_constraint_3_shift, - p_y_high_limbs_range_constraint_4_shift, - p_y_high_limbs_range_constraint_tail_shift, - z_low_limbs_shift, - z_low_limbs_range_constraint_0_shift, - z_low_limbs_range_constraint_1_shift, - z_low_limbs_range_constraint_2_shift, - z_low_limbs_range_constraint_3_shift, - z_low_limbs_range_constraint_4_shift, - z_low_limbs_range_constraint_tail_shift, - z_high_limbs_shift, - z_high_limbs_range_constraint_0_shift, - z_high_limbs_range_constraint_1_shift, - z_high_limbs_range_constraint_2_shift, - z_high_limbs_range_constraint_3_shift, - z_high_limbs_range_constraint_4_shift, - z_high_limbs_range_constraint_tail_shift, - accumulators_binary_limbs_0_shift, - accumulators_binary_limbs_1_shift, - accumulators_binary_limbs_2_shift, - accumulators_binary_limbs_3_shift, - accumulator_low_limbs_range_constraint_0_shift, - accumulator_low_limbs_range_constraint_1_shift, - accumulator_low_limbs_range_constraint_2_shift, - accumulator_low_limbs_range_constraint_3_shift, - accumulator_low_limbs_range_constraint_4_shift, - accumulator_low_limbs_range_constraint_tail_shift, - accumulator_high_limbs_range_constraint_0_shift, - accumulator_high_limbs_range_constraint_1_shift, - accumulator_high_limbs_range_constraint_2_shift, - accumulator_high_limbs_range_constraint_3_shift, - accumulator_high_limbs_range_constraint_4_shift, - accumulator_high_limbs_range_constraint_tail_shift, - quotient_low_binary_limbs_shift, - quotient_high_binary_limbs_shift, - quotient_low_limbs_range_constraint_0_shift, - quotient_low_limbs_range_constraint_1_shift, - quotient_low_limbs_range_constraint_2_shift, - quotient_low_limbs_range_constraint_3_shift, - quotient_low_limbs_range_constraint_4_shift, - quotient_low_limbs_range_constraint_tail_shift, - quotient_high_limbs_range_constraint_0_shift, - quotient_high_limbs_range_constraint_1_shift, - quotient_high_limbs_range_constraint_2_shift, - quotient_high_limbs_range_constraint_3_shift, - quotient_high_limbs_range_constraint_4_shift, - quotient_high_limbs_range_constraint_tail_shift, - relation_wide_limbs_shift, - relation_wide_limbs_range_constraint_0_shift, - relation_wide_limbs_range_constraint_1_shift, - relation_wide_limbs_range_constraint_2_shift, - relation_wide_limbs_range_constraint_3_shift, - ordered_range_constraints_0_shift, - ordered_range_constraints_1_shift, - ordered_range_constraints_2_shift, - ordered_range_constraints_3_shift, - ordered_range_constraints_4_shift, + return { this->x_lo_y_hi_shift, + this->x_hi_z_1_shift, + this->y_lo_z_2_shift, + this->p_x_low_limbs_shift, + this->p_x_low_limbs_range_constraint_0_shift, + this->p_x_low_limbs_range_constraint_1_shift, + this->p_x_low_limbs_range_constraint_2_shift, + this->p_x_low_limbs_range_constraint_3_shift, + this->p_x_low_limbs_range_constraint_4_shift, + this->p_x_low_limbs_range_constraint_tail_shift, + this->p_x_high_limbs_shift, + this->p_x_high_limbs_range_constraint_0_shift, + this->p_x_high_limbs_range_constraint_1_shift, + this->p_x_high_limbs_range_constraint_2_shift, + this->p_x_high_limbs_range_constraint_3_shift, + this->p_x_high_limbs_range_constraint_4_shift, + this->p_x_high_limbs_range_constraint_tail_shift, + this->p_y_low_limbs_shift, + this->p_y_low_limbs_range_constraint_0_shift, + this->p_y_low_limbs_range_constraint_1_shift, + this->p_y_low_limbs_range_constraint_2_shift, + this->p_y_low_limbs_range_constraint_3_shift, + this->p_y_low_limbs_range_constraint_4_shift, + this->p_y_low_limbs_range_constraint_tail_shift, + this->p_y_high_limbs_shift, + this->p_y_high_limbs_range_constraint_0_shift, + this->p_y_high_limbs_range_constraint_1_shift, + this->p_y_high_limbs_range_constraint_2_shift, + this->p_y_high_limbs_range_constraint_3_shift, + this->p_y_high_limbs_range_constraint_4_shift, + this->p_y_high_limbs_range_constraint_tail_shift, + this->z_low_limbs_shift, + this->z_low_limbs_range_constraint_0_shift, + this->z_low_limbs_range_constraint_1_shift, + this->z_low_limbs_range_constraint_2_shift, + this->z_low_limbs_range_constraint_3_shift, + this->z_low_limbs_range_constraint_4_shift, + this->z_low_limbs_range_constraint_tail_shift, + this->z_high_limbs_shift, + this->z_high_limbs_range_constraint_0_shift, + this->z_high_limbs_range_constraint_1_shift, + this->z_high_limbs_range_constraint_2_shift, + this->z_high_limbs_range_constraint_3_shift, + this->z_high_limbs_range_constraint_4_shift, + this->z_high_limbs_range_constraint_tail_shift, + this->accumulators_binary_limbs_0_shift, + this->accumulators_binary_limbs_1_shift, + this->accumulators_binary_limbs_2_shift, + this->accumulators_binary_limbs_3_shift, + this->accumulator_low_limbs_range_constraint_0_shift, + this->accumulator_low_limbs_range_constraint_1_shift, + this->accumulator_low_limbs_range_constraint_2_shift, + this->accumulator_low_limbs_range_constraint_3_shift, + this->accumulator_low_limbs_range_constraint_4_shift, + this->accumulator_low_limbs_range_constraint_tail_shift, + this->accumulator_high_limbs_range_constraint_0_shift, + this->accumulator_high_limbs_range_constraint_1_shift, + this->accumulator_high_limbs_range_constraint_2_shift, + this->accumulator_high_limbs_range_constraint_3_shift, + this->accumulator_high_limbs_range_constraint_4_shift, + this->accumulator_high_limbs_range_constraint_tail_shift, + this->quotient_low_binary_limbs_shift, + this->quotient_high_binary_limbs_shift, + this->quotient_low_limbs_range_constraint_0_shift, + this->quotient_low_limbs_range_constraint_1_shift, + this->quotient_low_limbs_range_constraint_2_shift, + this->quotient_low_limbs_range_constraint_3_shift, + this->quotient_low_limbs_range_constraint_4_shift, + this->quotient_low_limbs_range_constraint_tail_shift, + this->quotient_high_limbs_range_constraint_0_shift, + this->quotient_high_limbs_range_constraint_1_shift, + this->quotient_high_limbs_range_constraint_2_shift, + this->quotient_high_limbs_range_constraint_3_shift, + this->quotient_high_limbs_range_constraint_4_shift, + this->quotient_high_limbs_range_constraint_tail_shift, + this->relation_wide_limbs_shift, + this->relation_wide_limbs_range_constraint_0_shift, + this->relation_wide_limbs_range_constraint_1_shift, + this->relation_wide_limbs_range_constraint_2_shift, + this->relation_wide_limbs_range_constraint_3_shift, + this->ordered_range_constraints_0_shift, + this->ordered_range_constraints_1_shift, + this->ordered_range_constraints_2_shift, + this->ordered_range_constraints_3_shift, + this->ordered_range_constraints_4_shift, - z_perm_shift, - }; + this->z_perm_shift }; }; /** * @brief Polynomials/commitments, that can be constructed only after the r challenge has been received from * gemini * - * @return std::vector + * @return RefVector */ - std::vector get_special() { return get_concatenated_constraints(); } + RefVector get_special() { return get_concatenated_constraints(); } - std::vector get_unshifted_then_shifted_then_special() + RefVector get_unshifted_then_shifted_then_special() { - std::vector result{ get_unshifted() }; - std::vector shifted{ get_shifted() }; - std::vector special{ get_special() }; + RefVector result{ this->get_unshifted() }; + RefVector shifted{ get_shifted() }; + RefVector special{ get_special() }; result.insert(result.end(), shifted.begin(), shifted.end()); result.insert(result.end(), special.begin(), special.end()); return result; @@ -1417,25 +986,21 @@ class GoblinTranslator { * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve * inherit from ProvingKey. */ - class ProvingKey : public ProvingKey_, - WitnessEntities> { + class ProvingKey : public ProvingKey_, WitnessEntities> { public: BF batching_challenge_v = { 0 }; BF evaluation_input_x = { 0 }; ProvingKey() = default; // Expose constructors on the base class - using Base = ProvingKey_, - WitnessEntities>; + using Base = ProvingKey_, WitnessEntities>; using Base::Base; ProvingKey(const size_t circuit_size) - : ProvingKey_, - WitnessEntities>(circuit_size, 0) + : ProvingKey_, WitnessEntities>(circuit_size, 0) , batching_challenge_v(0) , evaluation_input_x(0) - {} }; @@ -1447,21 +1012,21 @@ class GoblinTranslator { * resolve that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for * portability of our circuits. */ - using VerificationKey = VerificationKey_>; + using VerificationKey = VerificationKey_>; /** - * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated - * at one point. + * @brief A field element for each entity of the flavor. These entities represent the prover polynomials + * evaluated at one point. */ - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; }; /** * @brief A container for the prover polynomials handles; only stores spans. */ - class ProverPolynomials : public AllEntities { + class ProverPolynomials : public AllEntities { public: [[nodiscard]] size_t get_polynomial_size() const { return this->op.size(); } /** @@ -1481,20 +1046,20 @@ class GoblinTranslator { /** * @brief A container for easier mapping of polynomials */ - using ProverPolynomialIds = AllEntities; + using ProverPolynomialIds = AllEntities; /** * @brief An owning container of polynomials. * @warning When this was introduced it broke some of our design principles. - * - Execution trace builders don't handle "polynomials" because the interpretation of the execution trace columns - * as polynomials is a detail of the proving system, and trace builders are (sometimes in practice, always in - * principle) reusable for different proving protocols (e.g., Plonk and Honk). + * - Execution trace builders don't handle "polynomials" because the interpretation of the execution trace + * columns as polynomials is a detail of the proving system, and trace builders are (sometimes in practice, + * always in principle) reusable for different proving protocols (e.g., Plonk and Honk). * - Polynomial storage is handled by key classes. Polynomials aren't moved, but are accessed elsewhere by * std::spans. * * We will consider revising this data model: TODO(https://github.com/AztecProtocol/barretenberg/issues/743) */ - class AllPolynomials : public AllEntities { + class AllPolynomials : public AllEntities { public: [[nodiscard]] AllValues get_row(const size_t row_idx) const { @@ -1509,12 +1074,12 @@ class GoblinTranslator { * @brief A container for polynomials produced after the first round of sumcheck. * @todo TODO(#394) Use polynomial classes for guaranteed memory alignment. */ - using RowPolynomials = AllEntities; + using RowPolynomials = AllEntities; /** * @brief A container for storing the partially evaluated multivariates produced by sumcheck. */ - class PartiallyEvaluatedMultivariates : public AllEntities { + class PartiallyEvaluatedMultivariates : public AllEntities { public: PartiallyEvaluatedMultivariates() = default; @@ -1530,8 +1095,7 @@ class GoblinTranslator { /** * @brief A container for univariates used during sumcheck. */ - template - using ProverUnivariates = AllEntities, barretenberg::Univariate>; + template using ProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -1544,7 +1108,7 @@ class GoblinTranslator { * needed. It has, however, been useful during debugging to have these labels available. * */ - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { public: CommitmentLabels() { @@ -1645,7 +1209,7 @@ class GoblinTranslator { }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { public: VerifierCommitments([[maybe_unused]] std::shared_ptr verification_key, [[maybe_unused]] const BaseTranscript& transcript) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp index 661275243280..96cf254eb1d3 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra.hpp @@ -1,6 +1,8 @@ #pragma once #include "barretenberg/commitment_schemes/kzg/kzg.hpp" +#include "barretenberg/common/ref_vector.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/proof_system/circuit_builder/goblin_ultra_circuit_builder.hpp" #include "barretenberg/relations/auxiliary_relation.hpp" @@ -78,137 +80,87 @@ class GoblinUltra { static constexpr bool has_zero_row = true; private: - template /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. */ - class PrecomputedEntities : public PrecomputedEntities_ { + template class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType q_m; // column 0 - DataType q_c; // column 1 - DataType q_l; // column 2 - DataType q_r; // column 3 - DataType q_o; // column 4 - DataType q_4; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType q_busread; // column 11 - DataType sigma_1; // column 12 - DataType sigma_2; // column 13 - DataType sigma_3; // column 14 - DataType sigma_4; // column 15 - DataType id_1; // column 16 - DataType id_2; // column 17 - DataType id_3; // column 18 - DataType id_4; // column 19 - DataType table_1; // column 20 - DataType table_2; // column 21 - DataType table_3; // column 22 - DataType table_4; // column 23 - DataType lagrange_first; // column 24 - DataType lagrange_last; // column 25 - DataType lagrange_ecc_op; // column 26 // indicator poly for ecc op gates - DataType databus_id; // column 27 // id polynomial, i.e. id_i = i - - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, - &q_m, - &q_c, - &q_l, - &q_r, - &q_o, - &q_4, - &q_arith, - &q_sort, - &q_elliptic, - &q_aux, - &q_lookup, - &q_busread, - &sigma_1, - &sigma_2, - &sigma_3, - &sigma_4, - &id_1, - &id_2, - &id_3, - &id_4, - &table_1, - &table_2, - &table_3, - &table_4, - &lagrange_first, - &lagrange_last, - &lagrange_ecc_op, - &databus_id) + using DataType = DataType_; + DEFINE_FLAVOR_MEMBERS(DataType, + q_m, // column 0 + q_c, // column 1 + q_l, // column 2 + q_r, // column 3 + q_o, // column 4 + q_4, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + q_busread, // column 11 + sigma_1, // column 12 + sigma_2, // column 13 + sigma_3, // column 14 + sigma_4, // column 15 + id_1, // column 16 + id_2, // column 17 + id_3, // column 18 + id_4, // column 19 + table_1, // column 20 + table_2, // column 21 + table_3, // column 22 + table_4, // column 23 + lagrange_first, // column 24 + lagrange_last, // column 25 + lagrange_ecc_op, // column 26 // indicator poly for ecc op gates + databus_id) // column 27 // id polynomial, i.e. id_i = i static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; - std::vector get_selectors() override + RefVector get_selectors() { return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup, q_busread }; }; - std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; - std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; - - std::vector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; + RefVector get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; + RefVector get_id_polynomials() { return { id_1, id_2, id_3, id_4 }; }; + RefVector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; }; /** * @brief Container for all witness polynomials used/constructed by the prover. * @details Shifts are not included here since they do not occupy their own memory. */ - template - class WitnessEntities : public WitnessEntities_ { + template class WitnessEntities { public: - DataType w_l; // column 0 - DataType w_r; // column 1 - DataType w_o; // column 2 - DataType w_4; // column 3 - DataType sorted_1; // column 4 - DataType sorted_2; // column 5 - DataType sorted_3; // column 6 - DataType sorted_4; // column 7 - DataType sorted_accum; // column 8 - DataType z_perm; // column 9 - DataType z_lookup; // column 10 - DataType ecc_op_wire_1; // column 11 - DataType ecc_op_wire_2; // column 12 - DataType ecc_op_wire_3; // column 13 - DataType ecc_op_wire_4; // column 14 - DataType calldata; // column 15 - DataType calldata_read_counts; // column 16 - DataType lookup_inverses; // column 17 - - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_1, - &sorted_2, - &sorted_3, - &sorted_4, - &sorted_accum, - &z_perm, - &z_lookup, - &ecc_op_wire_1, - &ecc_op_wire_2, - &ecc_op_wire_3, - &ecc_op_wire_4, - &calldata, - &calldata_read_counts, - &lookup_inverses) - - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; - std::vector get_ecc_op_wires() + DEFINE_FLAVOR_MEMBERS(DataType, + w_l, // column 0 + w_r, // column 1 + w_o, // column 2 + w_4, // column 3 + sorted_1, // column 4 + sorted_2, // column 5 + sorted_3, // column 6 + sorted_4, // column 7 + sorted_accum, // column 8 + z_perm, // column 9 + z_lookup, // column 10 + ecc_op_wire_1, // column 11 + ecc_op_wire_2, // column 12 + ecc_op_wire_3, // column 13 + ecc_op_wire_4, // column 14 + calldata, // column 15 + calldata_read_counts, // column 16 + lookup_inverses // column 17 + ) + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; + RefVector get_ecc_op_wires() { return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; }; // The sorted concatenations of table and witness data needed for plookup. - std::vector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; + RefVector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; }; /** @@ -220,126 +172,71 @@ class GoblinUltra { * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be * implemented as such, but we have this now. */ - template - class AllEntities : public AllEntities_ { + template class AllEntities { public: - DataType q_c; // column 0 - DataType q_l; // column 1 - DataType q_r; // column 2 - DataType q_o; // column 3 - DataType q_4; // column 4 - DataType q_m; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType q_busread; // column 11 - DataType sigma_1; // column 12 - DataType sigma_2; // column 13 - DataType sigma_3; // column 14 - DataType sigma_4; // column 15 - DataType id_1; // column 16 - DataType id_2; // column 17 - DataType id_3; // column 18 - DataType id_4; // column 19 - DataType table_1; // column 20 - DataType table_2; // column 21 - DataType table_3; // column 22 - DataType table_4; // column 23 - DataType lagrange_first; // column 24 - DataType lagrange_last; // column 25 - DataType lagrange_ecc_op; // column 26 - DataType databus_id; // column 27 - DataType w_l; // column 28 - DataType w_r; // column 29 - DataType w_o; // column 30 - DataType w_4; // column 31 - DataType sorted_accum; // column 32 - DataType z_perm; // column 33 - DataType z_lookup; // column 34 - DataType ecc_op_wire_1; // column 35 - DataType ecc_op_wire_2; // column 36 - DataType ecc_op_wire_3; // column 37 - DataType ecc_op_wire_4; // column 38 - DataType calldata; // column 39 - DataType calldata_read_counts; // column 40 - DataType lookup_inverses; // column 41 - DataType table_1_shift; // column 42 - DataType table_2_shift; // column 43 - DataType table_3_shift; // column 44 - DataType table_4_shift; // column 45 - DataType w_l_shift; // column 46 - DataType w_r_shift; // column 47 - DataType w_o_shift; // column 48 - DataType w_4_shift; // column 49 - DataType sorted_accum_shift; // column 50 - DataType z_perm_shift; // column 51 - DataType z_lookup_shift; // column 52 - - // defines a method pointer_view that returns the following, with const and non-const variants - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &q_c, - &q_l, - &q_r, - &q_o, - &q_4, - &q_m, - &q_arith, - &q_sort, - &q_elliptic, - &q_aux, - &q_lookup, - &q_busread, - &sigma_1, - &sigma_2, - &sigma_3, - &sigma_4, - &id_1, - &id_2, - &id_3, - &id_4, - &table_1, - &table_2, - &table_3, - &table_4, - &lagrange_first, - &lagrange_last, - &lagrange_ecc_op, - &databus_id, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_accum, - &z_perm, - &z_lookup, - &ecc_op_wire_1, - &ecc_op_wire_2, - &ecc_op_wire_3, - &ecc_op_wire_4, - &calldata, - &calldata_read_counts, - &lookup_inverses, - &table_1_shift, - &table_2_shift, - &table_3_shift, - &table_4_shift, - &w_l_shift, - &w_r_shift, - &w_o_shift, - &w_4_shift, - &sorted_accum_shift, - &z_perm_shift, - &z_lookup_shift); - - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; - std::vector get_ecc_op_wires() + DEFINE_FLAVOR_MEMBERS(DataType, + q_c, // column 0 + q_l, // column 1 + q_r, // column 2 + q_o, // column 3 + q_4, // column 4 + q_m, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + q_busread, // column 11 + sigma_1, // column 12 + sigma_2, // column 13 + sigma_3, // column 14 + sigma_4, // column 15 + id_1, // column 16 + id_2, // column 17 + id_3, // column 18 + id_4, // column 19 + table_1, // column 20 + table_2, // column 21 + table_3, // column 22 + table_4, // column 23 + lagrange_first, // column 24 + lagrange_last, // column 25 + lagrange_ecc_op, // column 26 + databus_id, // column 27 + w_l, // column 28 + w_r, // column 29 + w_o, // column 30 + w_4, // column 31 + sorted_accum, // column 32 + z_perm, // column 33 + z_lookup, // column 34 + ecc_op_wire_1, // column 35 + ecc_op_wire_2, // column 36 + ecc_op_wire_3, // column 37 + ecc_op_wire_4, // column 38 + calldata, // column 39 + calldata_read_counts, // column 40 + lookup_inverses, // column 41 + table_1_shift, // column 42 + table_2_shift, // column 43 + table_3_shift, // column 44 + table_4_shift, // column 45 + w_l_shift, // column 46 + w_r_shift, // column 47 + w_o_shift, // column 48 + w_4_shift, // column 49 + sorted_accum_shift, // column 50 + z_perm_shift, // column 51 + z_lookup_shift // column 52 + ) + + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; + RefVector get_ecc_op_wires() { return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; }; // Gemini-specific getters. - std::vector get_unshifted() override + RefVector get_unshifted() { return { q_c, q_l, @@ -384,11 +281,11 @@ class GoblinUltra { calldata_read_counts, lookup_inverses }; }; - std::vector get_to_be_shifted() override + RefVector get_to_be_shifted() { return { table_1, table_2, table_3, table_4, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; }; - std::vector get_shifted() override + RefVector get_shifted() { return { table_1_shift, table_2_shift, table_3_shift, table_4_shift, w_l_shift, w_r_shift, w_o_shift, w_4_shift, sorted_accum_shift, z_perm_shift, z_lookup_shift }; @@ -401,12 +298,10 @@ class GoblinUltra { * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve inherit * from ProvingKey. */ - class ProvingKey : public ProvingKey_, - WitnessEntities> { + class ProvingKey : public ProvingKey_, WitnessEntities> { public: // Expose constructors on the base class - using Base = ProvingKey_, - WitnessEntities>; + using Base = ProvingKey_, WitnessEntities>; using Base::Base; std::vector memory_read_records; @@ -426,12 +321,12 @@ class GoblinUltra { * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our * circuits. */ - using VerificationKey = VerificationKey_>; + using VerificationKey = VerificationKey_>; /** * @brief A container for storing the partially evaluated multivariates produced by sumcheck. */ - class PartiallyEvaluatedMultivariates : public AllEntities { + class PartiallyEvaluatedMultivariates : public AllEntities { public: PartiallyEvaluatedMultivariates() = default; @@ -448,8 +343,7 @@ class GoblinUltra { * @brief A container for univariates used during Protogalaxy folding and sumcheck. * @details During folding and sumcheck, the prover evaluates the relations on these univariates. */ - template - using ProverUnivariates = AllEntities, barretenberg::Univariate>; + template using ProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -460,16 +354,16 @@ class GoblinUltra { * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated * at one point. */ - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; }; /** * @brief A container for the prover polynomials handles; only stores spans. */ - class ProverPolynomials : public AllEntities { + class ProverPolynomials : public AllEntities { public: [[nodiscard]] size_t get_polynomial_size() const { return q_c.size(); } [[nodiscard]] AllValues get_row(size_t row_idx) const @@ -488,7 +382,7 @@ class GoblinUltra { * has, however, been useful during debugging to have these labels available. * */ - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { public: CommitmentLabels() { @@ -538,7 +432,7 @@ class GoblinUltra { }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { public: VerifierCommitments(std::shared_ptr verification_key, [[maybe_unused]] const BaseTranscript& transcript) diff --git a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp index f37d26b3adca..691e99fdda3d 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/goblin_ultra_recursive.hpp @@ -6,6 +6,7 @@ #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/goblin_ultra.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" @@ -91,137 +92,90 @@ template class GoblinUltraRecursive_ { using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); private: - template + template /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. */ - class PrecomputedEntities : public PrecomputedEntities_ { + class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType q_m; // column 0 - DataType q_c; // column 1 - DataType q_l; // column 2 - DataType q_r; // column 3 - DataType q_o; // column 4 - DataType q_4; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType q_busread; // column 11 - DataType sigma_1; // column 12 - DataType sigma_2; // column 13 - DataType sigma_3; // column 14 - DataType sigma_4; // column 15 - DataType id_1; // column 16 - DataType id_2; // column 17 - DataType id_3; // column 18 - DataType id_4; // column 19 - DataType table_1; // column 20 - DataType table_2; // column 21 - DataType table_3; // column 22 - DataType table_4; // column 23 - DataType lagrange_first; // column 24 - DataType lagrange_last; // column 25 - DataType lagrange_ecc_op; // column 26 // indicator poly for ecc op gates - DataType databus_id; // column 27 // id polynomial, i.e. id_i = i - - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, - &q_m, - &q_c, - &q_l, - &q_r, - &q_o, - &q_4, - &q_arith, - &q_sort, - &q_elliptic, - &q_aux, - &q_lookup, - &q_busread, - &sigma_1, - &sigma_2, - &sigma_3, - &sigma_4, - &id_1, - &id_2, - &id_3, - &id_4, - &table_1, - &table_2, - &table_3, - &table_4, - &lagrange_first, - &lagrange_last, - &lagrange_ecc_op, - &databus_id) + DEFINE_FLAVOR_MEMBERS(DataType, + q_m, // column 0 + q_c, // column 1 + q_l, // column 2 + q_r, // column 3 + q_o, // column 4 + q_4, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + q_busread, // column 11 + sigma_1, // column 12 + sigma_2, // column 13 + sigma_3, // column 14 + sigma_4, // column 15 + id_1, // column 16 + id_2, // column 17 + id_3, // column 18 + id_4, // column 19 + table_1, // column 20 + table_2, // column 21 + table_3, // column 22 + table_4, // column 23 + lagrange_first, // column 24 + lagrange_last, // column 25 + lagrange_ecc_op, // column 26 // indicator poly for ecc op gates + databus_id // column 27 // id polynomial, i.e. id_i = i + ) static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; - std::vector get_selectors() override + RefVector get_selectors() { return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup, q_busread }; }; - std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; - std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; + RefVector get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; + RefVector get_id_polynomials() { return { id_1, id_2, id_3, id_4 }; }; - std::vector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; + RefVector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; }; /** * @brief Container for all witness polynomials used/constructed by the prover. * @details Shifts are not included here since they do not occupy their own memory. */ - template - class WitnessEntities : public WitnessEntities_ { + template class WitnessEntities { public: - DataType w_l; // column 0 - DataType w_r; // column 1 - DataType w_o; // column 2 - DataType w_4; // column 3 - DataType sorted_1; // column 4 - DataType sorted_2; // column 5 - DataType sorted_3; // column 6 - DataType sorted_4; // column 7 - DataType sorted_accum; // column 8 - DataType z_perm; // column 9 - DataType z_lookup; // column 10 - DataType ecc_op_wire_1; // column 11 - DataType ecc_op_wire_2; // column 12 - DataType ecc_op_wire_3; // column 13 - DataType ecc_op_wire_4; // column 14 - DataType calldata; // column 15 - DataType calldata_read_counts; // column 16 - DataType lookup_inverses; // column 17 - - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_1, - &sorted_2, - &sorted_3, - &sorted_4, - &sorted_accum, - &z_perm, - &z_lookup, - &ecc_op_wire_1, - &ecc_op_wire_2, - &ecc_op_wire_3, - &ecc_op_wire_4, - &calldata, - &calldata_read_counts, - &lookup_inverses) - - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; - std::vector get_ecc_op_wires() + DEFINE_FLAVOR_MEMBERS(DataType, + w_l, // column 0 + w_r, // column 1 + w_o, // column 2 + w_4, // column 3 + sorted_1, // column 4 + sorted_2, // column 5 + sorted_3, // column 6 + sorted_4, // column 7 + sorted_accum, // column 8 + z_perm, // column 9 + z_lookup, // column 10 + ecc_op_wire_1, // column 11 + ecc_op_wire_2, // column 12 + ecc_op_wire_3, // column 13 + ecc_op_wire_4, // column 14 + calldata, // column 15 + calldata_read_counts, // column 16 + lookup_inverses // column 17 + ) + + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; + RefVector get_ecc_op_wires() { return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; }; // The sorted concatenations of table and witness data needed for plookup. - std::vector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; + RefVector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; }; /** @@ -233,126 +187,70 @@ template class GoblinUltraRecursive_ { * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be * implemented as such, but we have this now. */ - template - class AllEntities : public AllEntities_ { + template class AllEntities { public: - DataType q_c; // column 0 - DataType q_l; // column 1 - DataType q_r; // column 2 - DataType q_o; // column 3 - DataType q_4; // column 4 - DataType q_m; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType q_busread; // column 11 - DataType sigma_1; // column 12 - DataType sigma_2; // column 13 - DataType sigma_3; // column 14 - DataType sigma_4; // column 15 - DataType id_1; // column 16 - DataType id_2; // column 17 - DataType id_3; // column 18 - DataType id_4; // column 19 - DataType table_1; // column 20 - DataType table_2; // column 21 - DataType table_3; // column 22 - DataType table_4; // column 23 - DataType lagrange_first; // column 24 - DataType lagrange_last; // column 25 - DataType lagrange_ecc_op; // column 26 - DataType databus_id; // column 27 - DataType w_l; // column 28 - DataType w_r; // column 29 - DataType w_o; // column 30 - DataType w_4; // column 31 - DataType sorted_accum; // column 32 - DataType z_perm; // column 33 - DataType z_lookup; // column 34 - DataType ecc_op_wire_1; // column 35 - DataType ecc_op_wire_2; // column 36 - DataType ecc_op_wire_3; // column 37 - DataType ecc_op_wire_4; // column 38 - DataType calldata; // column 39 - DataType calldata_read_counts; // column 40 - DataType lookup_inverses; // column 41 - DataType table_1_shift; // column 42 - DataType table_2_shift; // column 43 - DataType table_3_shift; // column 44 - DataType table_4_shift; // column 45 - DataType w_l_shift; // column 46 - DataType w_r_shift; // column 47 - DataType w_o_shift; // column 48 - DataType w_4_shift; // column 49 - DataType sorted_accum_shift; // column 50 - DataType z_perm_shift; // column 51 - DataType z_lookup_shift; // column 52 - - // defines a method pointer_view that returns the following, with const and non-const variants - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &q_c, - &q_l, - &q_r, - &q_o, - &q_4, - &q_m, - &q_arith, - &q_sort, - &q_elliptic, - &q_aux, - &q_lookup, - &q_busread, - &sigma_1, - &sigma_2, - &sigma_3, - &sigma_4, - &id_1, - &id_2, - &id_3, - &id_4, - &table_1, - &table_2, - &table_3, - &table_4, - &lagrange_first, - &lagrange_last, - &lagrange_ecc_op, - &databus_id, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_accum, - &z_perm, - &z_lookup, - &ecc_op_wire_1, - &ecc_op_wire_2, - &ecc_op_wire_3, - &ecc_op_wire_4, - &calldata, - &calldata_read_counts, - &lookup_inverses, - &table_1_shift, - &table_2_shift, - &table_3_shift, - &table_4_shift, - &w_l_shift, - &w_r_shift, - &w_o_shift, - &w_4_shift, - &sorted_accum_shift, - &z_perm_shift, - &z_lookup_shift); - - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; - std::vector get_ecc_op_wires() + DEFINE_FLAVOR_MEMBERS(DataType, + q_c, // column 0 + q_l, // column 1 + q_r, // column 2 + q_o, // column 3 + q_4, // column 4 + q_m, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + q_busread, // column 11 + sigma_1, // column 12 + sigma_2, // column 13 + sigma_3, // column 14 + sigma_4, // column 15 + id_1, // column 16 + id_2, // column 17 + id_3, // column 18 + id_4, // column 19 + table_1, // column 20 + table_2, // column 21 + table_3, // column 22 + table_4, // column 23 + lagrange_first, // column 24 + lagrange_last, // column 25 + lagrange_ecc_op, // column 26 + databus_id, // column 27 + w_l, // column 28 + w_r, // column 29 + w_o, // column 30 + w_4, // column 31 + sorted_accum, // column 32 + z_perm, // column 33 + z_lookup, // column 34 + ecc_op_wire_1, // column 35 + ecc_op_wire_2, // column 36 + ecc_op_wire_3, // column 37 + ecc_op_wire_4, // column 38 + calldata, // column 39 + calldata_read_counts, // column 40 + lookup_inverses, // column 41 + table_1_shift, // column 42 + table_2_shift, // column 43 + table_3_shift, // column 44 + table_4_shift, // column 45 + w_l_shift, // column 46 + w_r_shift, // column 47 + w_o_shift, // column 48 + w_4_shift, // column 49 + sorted_accum_shift, // column 50 + z_perm_shift, // column 51 + z_lookup_shift); // column 52 + + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; + RefVector get_ecc_op_wires() { return { ecc_op_wire_1, ecc_op_wire_2, ecc_op_wire_3, ecc_op_wire_4 }; }; // Gemini-specific getters. - std::vector get_unshifted() override + RefVector get_unshifted() { return { q_c, q_l, @@ -397,11 +295,11 @@ template class GoblinUltraRecursive_ { calldata_read_counts, lookup_inverses }; }; - std::vector get_to_be_shifted() override + RefVector get_to_be_shifted() { return { table_1, table_2, table_3, table_4, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; }; - std::vector get_shifted() override + RefVector get_shifted() { return { table_1_shift, table_2_shift, table_3_shift, table_4_shift, w_l_shift, w_r_shift, w_o_shift, w_4_shift, sorted_accum_shift, z_perm_shift, z_lookup_shift }; @@ -417,17 +315,17 @@ template class GoblinUltraRecursive_ { * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our * circuits. */ - class VerificationKey : public VerificationKey_> { + class VerificationKey : public VerificationKey_> { public: /** - * @brief Construct a new Verification Key with stdlib types from a provided native verification key + * @brief Construct a new Verification Key with stdlib types from a provided native verification + * key * * @param builder * @param native_key Native verification key from which to extract the precomputed commitments */ VerificationKey(CircuitBuilder* builder, auto native_key) - : VerificationKey_>(native_key->circuit_size, - native_key->num_public_inputs) + : VerificationKey_>(native_key->circuit_size, native_key->num_public_inputs) { this->q_m = Commitment::from_witness(builder, native_key->q_m); this->q_l = Commitment::from_witness(builder, native_key->q_l); @@ -464,9 +362,9 @@ template class GoblinUltraRecursive_ { * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated * at one point. */ - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; AllValues(std::array _data_in) { this->_data = _data_in; } }; @@ -477,7 +375,7 @@ template class GoblinUltraRecursive_ { * has, however, been useful during debugging to have these labels available. * */ - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { public: CommitmentLabels() { @@ -527,7 +425,7 @@ template class GoblinUltraRecursive_ { }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { public: VerifierCommitments(std::shared_ptr verification_key) { @@ -599,11 +497,12 @@ template class GoblinUltraRecursive_ { : BaseTranscript(proof) {} /** - * @brief Takes a FULL GoblinUltraRecursive proof and deserializes it into the public member variables that - * compose the structure. Must be called in order to access the structure of the proof. + * @brief Takes a FULL GoblinUltraRecursive proof and deserializes it into the public member + * variables that compose the structure. Must be called in order to access the structure of the + * proof. * */ - void deserialize_full_transcript() override + void deserialize_full_transcript() { // take current proof and put them into the struct size_t num_bytes_read = 0; @@ -646,11 +545,12 @@ template class GoblinUltraRecursive_ { } /** - * @brief Serializes the structure variables into a FULL GoblinUltraRecursive proof. Should be called only if - * deserialize_full_transcript() was called and some transcript variable was modified. + * @brief Serializes the structure variables into a FULL GoblinUltraRecursive proof. Should be + * called only if deserialize_full_transcript() was called and some transcript variable was + * modified. * */ - void serialize_full_transcript() override + void serialize_full_transcript() { size_t old_proof_length = BaseTranscript::proof_data.size(); BaseTranscript::proof_data.clear(); diff --git a/barretenberg/cpp/src/barretenberg/flavor/relation_definitions_fwd.hpp b/barretenberg/cpp/src/barretenberg/flavor/relation_definitions_fwd.hpp index 8ebca000c949..f8a547cbf470 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/relation_definitions_fwd.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/relation_definitions_fwd.hpp @@ -4,7 +4,7 @@ #define ExtendedEdge(Flavor) Flavor::ExtendedEdges #define EvaluationEdge(Flavor) Flavor::AllValues -#define EntityEdge(Flavor) Flavor::AllEntities +#define EntityEdge(Flavor) Flavor::AllEntities #define ACCUMULATE(...) _ACCUMULATE(__VA_ARGS__) #define _ACCUMULATE(Preface, RelationImpl, Flavor, AccumulatorType, EdgeType) \ diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp index da12a3994ef1..93a716820cd7 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra.hpp @@ -2,6 +2,7 @@ #include "barretenberg/commitment_schemes/kzg/kzg.hpp" #include "barretenberg/ecc/curves/bn254/g1.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/barycentric.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" @@ -75,113 +76,74 @@ class Ultra { static constexpr bool has_zero_row = true; private: - template /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. */ - class PrecomputedEntities : public PrecomputedEntities_ { + template class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType q_m; // column 0 - DataType q_c; // column 1 - DataType q_l; // column 2 - DataType q_r; // column 3 - DataType q_o; // column 4 - DataType q_4; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType sigma_1; // column 11 - DataType sigma_2; // column 12 - DataType sigma_3; // column 13 - DataType sigma_4; // column 14 - DataType id_1; // column 15 - DataType id_2; // column 16 - DataType id_3; // column 17 - DataType id_4; // column 18 - DataType table_1; // column 19 - DataType table_2; // column 20 - DataType table_3; // column 21 - DataType table_4; // column 22 - DataType lagrange_first; // column 23 - DataType lagrange_last; // column 24 - - DEFINE_POINTER_VIEW(NUM_PRECOMPUTED_ENTITIES, - &q_m, - &q_c, - &q_l, - &q_r, - &q_o, - &q_4, - &q_arith, - &q_sort, - &q_elliptic, - &q_aux, - &q_lookup, - &sigma_1, - &sigma_2, - &sigma_3, - &sigma_4, - &id_1, - &id_2, - &id_3, - &id_4, - &table_1, - &table_2, - &table_3, - &table_4, - &lagrange_first, - &lagrange_last) + using DataType = DataType_; + DEFINE_FLAVOR_MEMBERS(DataType, + q_m, // column 0 + q_c, // column 1 + q_l, // column 2 + q_r, // column 3 + q_o, // column 4 + q_4, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + sigma_1, // column 11 + sigma_2, // column 12 + sigma_3, // column 13 + sigma_4, // column 14 + id_1, // column 15 + id_2, // column 16 + id_3, // column 17 + id_4, // column 18 + table_1, // column 19 + table_2, // column 20 + table_3, // column 21 + table_4, // column 22 + lagrange_first, // column 23 + lagrange_last) // column 24 static constexpr CircuitType CIRCUIT_TYPE = CircuitBuilder::CIRCUIT_TYPE; - std::vector get_selectors() override + RefVector get_selectors() { return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; }; - std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; - std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; + RefVector get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; + RefVector get_id_polynomials() { return { id_1, id_2, id_3, id_4 }; }; - std::vector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; + RefVector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; }; /** * @brief Container for all witness polynomials used/constructed by the prover. * @details Shifts are not included here since they do not occupy their own memory. */ - template - class WitnessEntities : public WitnessEntities_ { + template class WitnessEntities { public: - DataType w_l; // column 0 - DataType w_r; // column 1 - DataType w_o; // column 2 - DataType w_4; // column 3 - DataType sorted_1; // column 4 - DataType sorted_2; // column 5 - DataType sorted_3; // column 6 - DataType sorted_4; // column 7 - DataType sorted_accum; // column 8 - DataType z_perm; // column 9 - DataType z_lookup; // column 10 - - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_1, - &sorted_2, - &sorted_3, - &sorted_4, - &sorted_accum, - &z_perm, - &z_lookup) - - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; + DEFINE_FLAVOR_MEMBERS(DataType, + w_l, // column 0 + w_r, // column 1 + w_o, // column 2 + w_4, // column 3 + sorted_1, // column 4 + sorted_2, // column 5 + sorted_3, // column 6 + sorted_4, // column 7 + sorted_accum, // column 8 + z_perm, // column 9 + z_lookup) // column 10 + + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; // The sorted concatenations of table and witness data needed for plookup. - std::vector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; + RefVector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; }; /** @@ -193,101 +155,56 @@ class Ultra { * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be * implemented as such, but we have this now. */ - template - class AllEntities : public AllEntities_ { + template class AllEntities { public: - DataType q_c; // column 0 - DataType q_l; // column 1 - DataType q_r; // column 2 - DataType q_o; // column 3 - DataType q_4; // column 4 - DataType q_m; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType sigma_1; // column 11 - DataType sigma_2; // column 12 - DataType sigma_3; // column 13 - DataType sigma_4; // column 14 - DataType id_1; // column 15 - DataType id_2; // column 16 - DataType id_3; // column 17 - DataType id_4; // column 18 - DataType table_1; // column 19 - DataType table_2; // column 20 - DataType table_3; // column 21 - DataType table_4; // column 22 - DataType lagrange_first; // column 23 - DataType lagrange_last; // column 24 - DataType w_l; // column 25 - DataType w_r; // column 26 - DataType w_o; // column 27 - DataType w_4; // column 28 - DataType sorted_accum; // column 29 - DataType z_perm; // column 30 - DataType z_lookup; // column 31 - DataType table_1_shift; // column 32 - DataType table_2_shift; // column 33 - DataType table_3_shift; // column 34 - DataType table_4_shift; // column 35 - DataType w_l_shift; // column 36 - DataType w_r_shift; // column 37 - DataType w_o_shift; // column 38 - DataType w_4_shift; // column 39 - DataType sorted_accum_shift; // column 40 - DataType z_perm_shift; // column 41 - DataType z_lookup_shift; // column 42 - - // defines a method pointer_view that returns the following, with const and non-const variants - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &q_c, - &q_l, - &q_r, - &q_o, - &q_4, - &q_m, - &q_arith, - &q_sort, - &q_elliptic, - &q_aux, - &q_lookup, - &sigma_1, - &sigma_2, - &sigma_3, - &sigma_4, - &id_1, - &id_2, - &id_3, - &id_4, - &table_1, - &table_2, - &table_3, - &table_4, - &lagrange_first, - &lagrange_last, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_accum, - &z_perm, - &z_lookup, - &table_1_shift, - &table_2_shift, - &table_3_shift, - &table_4_shift, - &w_l_shift, - &w_r_shift, - &w_o_shift, - &w_4_shift, - &sorted_accum_shift, - &z_perm_shift, - &z_lookup_shift); - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; + DEFINE_FLAVOR_MEMBERS(DataType, + q_c, // column 0 + q_l, // column 1 + q_r, // column 2 + q_o, // column 3 + q_4, // column 4 + q_m, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + sigma_1, // column 11 + sigma_2, // column 12 + sigma_3, // column 13 + sigma_4, // column 14 + id_1, // column 15 + id_2, // column 16 + id_3, // column 17 + id_4, // column 18 + table_1, // column 19 + table_2, // column 20 + table_3, // column 21 + table_4, // column 22 + lagrange_first, // column 23 + lagrange_last, // column 24 + w_l, // column 25 + w_r, // column 26 + w_o, // column 27 + w_4, // column 28 + sorted_accum, // column 29 + z_perm, // column 30 + z_lookup, // column 31 + table_1_shift, // column 32 + table_2_shift, // column 33 + table_3_shift, // column 34 + table_4_shift, // column 35 + w_l_shift, // column 36 + w_r_shift, // column 37 + w_o_shift, // column 38 + w_4_shift, // column 39 + sorted_accum_shift, // column 40 + z_perm_shift, // column 41 + z_lookup_shift) // column 42 + + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; // Gemini-specific getters. - std::vector get_unshifted() override + RefVector get_unshifted() { return { q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, q_elliptic, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, @@ -296,11 +213,11 @@ class Ultra { }; }; - std::vector get_to_be_shifted() override + RefVector get_to_be_shifted() { return { table_1, table_2, table_3, table_4, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; }; - std::vector get_shifted() override + RefVector get_shifted() { return { table_1_shift, table_2_shift, table_3_shift, table_4_shift, w_l_shift, w_r_shift, w_o_shift, w_4_shift, sorted_accum_shift, z_perm_shift, z_lookup_shift }; @@ -313,12 +230,10 @@ class Ultra { * @note TODO(Cody): Maybe multiple inheritance is the right thing here. In that case, nothing should eve inherit * from ProvingKey. */ - class ProvingKey : public ProvingKey_, - WitnessEntities> { + class ProvingKey : public ProvingKey_, WitnessEntities> { public: // Expose constructors on the base class - using Base = ProvingKey_, - WitnessEntities>; + using Base = ProvingKey_, WitnessEntities>; using Base::Base; std::vector memory_read_records; @@ -336,22 +251,22 @@ class Ultra { * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our * circuits. */ - using VerificationKey = VerificationKey_>; + using VerificationKey = VerificationKey_>; /** * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated * at one point. */ - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; }; /** * @brief A container for polynomials handles; only stores spans. */ - class ProverPolynomials : public AllEntities { + class ProverPolynomials : public AllEntities { public: [[nodiscard]] size_t get_polynomial_size() const { return q_c.size(); } [[nodiscard]] AllValues get_row(const size_t row_idx) const @@ -367,7 +282,7 @@ class Ultra { /** * @brief A container for storing the partially evaluated multivariates produced by sumcheck. */ - class PartiallyEvaluatedMultivariates : public AllEntities { + class PartiallyEvaluatedMultivariates : public AllEntities { public: PartiallyEvaluatedMultivariates() = default; @@ -384,8 +299,7 @@ class Ultra { * @brief A container for univariates used during Protogalaxy folding and sumcheck. * @details During folding and sumcheck, the prover evaluates the relations on these univariates. */ - template - using ProverUnivariates = AllEntities, barretenberg::Univariate>; + template using ProverUnivariates = AllEntities>; /** * @brief A container for univariates produced during the hot loop in sumcheck. @@ -398,7 +312,7 @@ class Ultra { * has, however, been useful during debugging to have these labels available. * */ - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { public: CommitmentLabels() { @@ -439,7 +353,7 @@ class Ultra { }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { public: VerifierCommitments(std::shared_ptr verification_key, [[maybe_unused]] const BaseTranscript& transcript) @@ -530,7 +444,7 @@ class Ultra { * structure. Must be called in order to access the structure of the proof. * */ - void deserialize_full_transcript() override + void deserialize_full_transcript() { // take current proof and put them into the struct size_t num_bytes_read = 0; @@ -567,7 +481,7 @@ class Ultra { * deserialize_full_transcript() was called and some transcript variable was modified. * */ - void serialize_full_transcript() override + void serialize_full_transcript() { size_t old_proof_length = proof_data.size(); proof_data.clear(); // clear proof_data so the rest of the function can replace it diff --git a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp index e780007eb36b..def614604f92 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/ultra_recursive.hpp @@ -6,6 +6,7 @@ #include "barretenberg/polynomials/univariate.hpp" #include "barretenberg/flavor/flavor.hpp" +#include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/flavor/ultra.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" @@ -89,84 +90,74 @@ template class UltraRecursive_ { using TupleOfArraysOfValues = decltype(create_tuple_of_arrays_of_values()); private: - template + template /** * @brief A base class labelling precomputed entities and (ordered) subsets of interest. * @details Used to build the proving key and verification key. */ - class PrecomputedEntities : public PrecomputedEntities_ { + class PrecomputedEntities : public PrecomputedEntitiesBase { public: - DataType q_m; // column 0 - DataType q_c; // column 1 - DataType q_l; // column 2 - DataType q_r; // column 3 - DataType q_o; // column 4 - DataType q_4; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType sigma_1; // column 11 - DataType sigma_2; // column 12 - DataType sigma_3; // column 13 - DataType sigma_4; // column 14 - DataType id_1; // column 15 - DataType id_2; // column 16 - DataType id_3; // column 17 - DataType id_4; // column 18 - DataType table_1; // column 19 - DataType table_2; // column 20 - DataType table_3; // column 21 - DataType table_4; // column 22 - DataType lagrange_first; // column 23 - DataType lagrange_last; // column 24 - - std::vector get_selectors() override + DEFINE_FLAVOR_MEMBERS(DataType, + q_m, // column 0 + q_c, // column 1 + q_l, // column 2 + q_r, // column 3 + q_o, // column 4 + q_4, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + sigma_1, // column 11 + sigma_2, // column 12 + sigma_3, // column 13 + sigma_4, // column 14 + id_1, // column 15 + id_2, // column 16 + id_3, // column 17 + id_4, // column 18 + table_1, // column 19 + table_2, // column 20 + table_3, // column 21 + table_4, // column 22 + lagrange_first, // column 23 + lagrange_last); // column 24 + + RefVector get_selectors() { return { q_m, q_c, q_l, q_r, q_o, q_4, q_arith, q_sort, q_elliptic, q_aux, q_lookup }; }; - std::vector get_sigma_polynomials() override { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; - std::vector get_id_polynomials() override { return { id_1, id_2, id_3, id_4 }; }; + RefVector get_sigma_polynomials() { return { sigma_1, sigma_2, sigma_3, sigma_4 }; }; + RefVector get_id_polynomials() { return { id_1, id_2, id_3, id_4 }; }; - std::vector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; + RefVector get_table_polynomials() { return { table_1, table_2, table_3, table_4 }; }; }; /** * @brief Container for all witness polynomials used/constructed by the prover. * @details Shifts are not included here since they do not occupy their own memory. */ - template - class WitnessEntities : public WitnessEntities_ { + template class WitnessEntities { public: - DataType w_l; // column 0 - DataType w_r; // column 1 - DataType w_o; // column 2 - DataType w_4; // column 3 - DataType sorted_1; // column 4 - DataType sorted_2; // column 5 - DataType sorted_3; // column 6 - DataType sorted_4; // column 7 - DataType sorted_accum; // column 8 - DataType z_perm; // column 9 - DataType z_lookup; // column 10 - - DEFINE_POINTER_VIEW(NUM_WITNESS_ENTITIES, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_1, - &sorted_2, - &sorted_3, - &sorted_4, - &sorted_accum, - &z_perm, - &z_lookup, ) - - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; + DEFINE_FLAVOR_MEMBERS(DataType, + w_l, // column 0 + w_r, // column 1 + w_o, // column 2 + w_4, // column 3 + sorted_1, // column 4 + sorted_2, // column 5 + sorted_3, // column 6 + sorted_4, // column 7 + sorted_accum, // column 8 + z_perm, // column 9 + z_lookup // column 10 + + ); + + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; // The sorted concatenations of table and witness data needed for plookup. - std::vector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; + RefVector get_sorted_polynomials() { return { sorted_1, sorted_2, sorted_3, sorted_4 }; }; }; /** @@ -178,101 +169,57 @@ template class UltraRecursive_ { * Symbolically we have: AllEntities = PrecomputedEntities + WitnessEntities + "ShiftedEntities". It could be * implemented as such, but we have this now. */ - template - class AllEntities : public AllEntities_ { + template class AllEntities { public: - DataType q_c; // column 0 - DataType q_l; // column 1 - DataType q_r; // column 2 - DataType q_o; // column 3 - DataType q_4; // column 4 - DataType q_m; // column 5 - DataType q_arith; // column 6 - DataType q_sort; // column 7 - DataType q_elliptic; // column 8 - DataType q_aux; // column 9 - DataType q_lookup; // column 10 - DataType sigma_1; // column 11 - DataType sigma_2; // column 12 - DataType sigma_3; // column 13 - DataType sigma_4; // column 14 - DataType id_1; // column 15 - DataType id_2; // column 16 - DataType id_3; // column 17 - DataType id_4; // column 18 - DataType table_1; // column 19 - DataType table_2; // column 20 - DataType table_3; // column 21 - DataType table_4; // column 22 - DataType lagrange_first; // column 23 - DataType lagrange_last; // column 24 - DataType w_l; // column 25 - DataType w_r; // column 26 - DataType w_o; // column 27 - DataType w_4; // column 28 - DataType sorted_accum; // column 29 - DataType z_perm; // column 30 - DataType z_lookup; // column 31 - DataType table_1_shift; // column 32 - DataType table_2_shift; // column 33 - DataType table_3_shift; // column 34 - DataType table_4_shift; // column 35 - DataType w_l_shift; // column 36 - DataType w_r_shift; // column 37 - DataType w_o_shift; // column 38 - DataType w_4_shift; // column 39 - DataType sorted_accum_shift; // column 40 - DataType z_perm_shift; // column 41 - DataType z_lookup_shift; // column 42 - - DEFINE_POINTER_VIEW(NUM_ALL_ENTITIES, - &q_c, - &q_l, - &q_r, - &q_o, - &q_4, - &q_m, - &q_arith, - &q_sort, - &q_elliptic, - &q_aux, - &q_lookup, - &sigma_1, - &sigma_2, - &sigma_3, - &sigma_4, - &id_1, - &id_2, - &id_3, - &id_4, - &table_1, - &table_2, - &table_3, - &table_4, - &lagrange_first, - &lagrange_last, - &w_l, - &w_r, - &w_o, - &w_4, - &sorted_accum, - &z_perm, - &z_lookup, - &table_1_shift, - &table_2_shift, - &table_3_shift, - &table_4_shift, - &w_l_shift, - &w_r_shift, - &w_o_shift, - &w_4_shift, - &sorted_accum_shift, - &z_perm_shift, - &z_lookup_shift) - - std::vector get_wires() override { return { w_l, w_r, w_o, w_4 }; }; + DEFINE_FLAVOR_MEMBERS(DataType, + q_c, // column 0 + q_l, // column 1 + q_r, // column 2 + q_o, // column 3 + q_4, // column 4 + q_m, // column 5 + q_arith, // column 6 + q_sort, // column 7 + q_elliptic, // column 8 + q_aux, // column 9 + q_lookup, // column 10 + sigma_1, // column 11 + sigma_2, // column 12 + sigma_3, // column 13 + sigma_4, // column 14 + id_1, // column 15 + id_2, // column 16 + id_3, // column 17 + id_4, // column 18 + table_1, // column 19 + table_2, // column 20 + table_3, // column 21 + table_4, // column 22 + lagrange_first, // column 23 + lagrange_last, // column 24 + w_l, // column 25 + w_r, // column 26 + w_o, // column 27 + w_4, // column 28 + sorted_accum, // column 29 + z_perm, // column 30 + z_lookup, // column 31 + table_1_shift, // column 32 + table_2_shift, // column 33 + table_3_shift, // column 34 + table_4_shift, // column 35 + w_l_shift, // column 36 + w_r_shift, // column 37 + w_o_shift, // column 38 + w_4_shift, // column 39 + sorted_accum_shift, // column 40 + z_perm_shift, // column 41 + z_lookup_shift // column 42 + ); + + RefVector get_wires() { return { w_l, w_r, w_o, w_4 }; }; // Gemini-specific getters. - std::vector get_unshifted() override + RefVector get_unshifted() { return { q_c, q_l, q_r, q_o, q_4, q_m, q_arith, q_sort, q_elliptic, q_aux, q_lookup, sigma_1, sigma_2, sigma_3, sigma_4, id_1, @@ -281,11 +228,11 @@ template class UltraRecursive_ { }; }; - std::vector get_to_be_shifted() override + RefVector get_to_be_shifted() { return { table_1, table_2, table_3, table_4, w_l, w_r, w_o, w_4, sorted_accum, z_perm, z_lookup }; }; - std::vector get_shifted() override + RefVector get_shifted() { return { table_1_shift, table_2_shift, table_3_shift, table_4_shift, w_l_shift, w_r_shift, w_o_shift, w_4_shift, sorted_accum_shift, z_perm_shift, z_lookup_shift }; @@ -301,7 +248,7 @@ template class UltraRecursive_ { * that, and split out separate PrecomputedPolynomials/Commitments data for clarity but also for portability of our * circuits. */ - class VerificationKey : public VerificationKey_> { + class VerificationKey : public VerificationKey_> { public: /** * @brief Construct a new Verification Key with stdlib types from a provided native verification key @@ -310,8 +257,7 @@ template class UltraRecursive_ { * @param native_key Native verification key from which to extract the precomputed commitments */ VerificationKey(CircuitBuilder* builder, auto native_key) - : VerificationKey_>(native_key->circuit_size, - native_key->num_public_inputs) + : VerificationKey_>(native_key->circuit_size, native_key->num_public_inputs) { this->q_m = Commitment::from_witness(builder, native_key->q_m); this->q_l = Commitment::from_witness(builder, native_key->q_l); @@ -345,9 +291,9 @@ template class UltraRecursive_ { * @brief A field element for each entity of the flavor. These entities represent the prover polynomials evaluated * at one point. */ - class AllValues : public AllEntities { + class AllValues : public AllEntities { public: - using Base = AllEntities; + using Base = AllEntities; using Base::Base; AllValues(std::array _data_in) { this->_data = _data_in; } }; @@ -358,7 +304,7 @@ template class UltraRecursive_ { * has, however, been useful during debugging to have these labels available. * */ - class CommitmentLabels : public AllEntities { + class CommitmentLabels : public AllEntities { public: CommitmentLabels() { @@ -399,7 +345,7 @@ template class UltraRecursive_ { }; }; - class VerifierCommitments : public AllEntities { + class VerifierCommitments : public AllEntities { public: VerifierCommitments(std::shared_ptr verification_key) { @@ -482,7 +428,7 @@ template class UltraRecursive_ { * the structure. Must be called in order to access the structure of the proof. * */ - void deserialize_full_transcript() override + void deserialize_full_transcript() { // take current proof and put them into the struct size_t num_bytes_read = 0; @@ -520,7 +466,7 @@ template class UltraRecursive_ { * deserialize_full_transcript() was called and some transcript variable was modified. * */ - void serialize_full_transcript() override + void serialize_full_transcript() { size_t old_proof_length = BaseTranscript::proof_data.size(); BaseTranscript::proof_data.clear(); // clear proof_data so the rest of the function can replace it diff --git a/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp b/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp index e263cb329a46..095639870103 100644 --- a/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp +++ b/barretenberg/cpp/src/barretenberg/goblin/full_goblin_composer.test.cpp @@ -30,14 +30,9 @@ class FullGoblinComposerTests : public ::testing::Test { using Point = Curve::AffineElement; using CommitmentKey = pcs::CommitmentKey; using OpQueue = proof_system::ECCOpQueue; - using GoblinUltraBuilder = proof_system::GoblinUltraCircuitBuilder; using ECCVMFlavor = flavor::ECCVM; using ECCVMBuilder = proof_system::ECCVMCircuitBuilder; using ECCVMComposer = ECCVMComposer_; - using TranslatorFlavor = flavor::GoblinTranslator; - using TranslatorBuilder = proof_system::GoblinTranslatorCircuitBuilder; - using TranslatorComposer = GoblinTranslatorComposer; - using TranslatorConsistencyData = barretenberg::TranslationEvaluations; static constexpr size_t NUM_OP_QUEUE_COLUMNS = flavor::GoblinUltra::NUM_WIRES; @@ -46,7 +41,7 @@ class FullGoblinComposerTests : public ::testing::Test { * * @param builder */ - static void generate_test_circuit(GoblinUltraBuilder& builder) + static void generate_test_circuit(proof_system::GoblinUltraCircuitBuilder& builder) { // Add some arbitrary ecc op gates for (size_t i = 0; i < 3; ++i) { @@ -88,7 +83,7 @@ class FullGoblinComposerTests : public ::testing::Test { static void perform_op_queue_interactions_for_mock_first_circuit( std::shared_ptr& op_queue) { - auto builder = GoblinUltraBuilder{ op_queue }; + proof_system::GoblinUltraCircuitBuilder builder{ op_queue }; // Add a mul accum op and an equality op auto point = Point::one() * FF::random_element(); @@ -114,7 +109,8 @@ class FullGoblinComposerTests : public ::testing::Test { * @brief Construct and a verify a Honk proof * */ - static bool construct_and_verify_honk_proof(GoblinUltraComposer& composer, GoblinUltraBuilder& builder) + static bool construct_and_verify_honk_proof(GoblinUltraComposer& composer, + proof_system::GoblinUltraCircuitBuilder& builder) { auto instance = composer.create_instance(builder); auto prover = composer.create_prover(instance); @@ -157,12 +153,12 @@ TEST_F(FullGoblinComposerTests, SimpleCircuit) // Construct a series of simple Goblin circuits; generate and verify their proofs size_t NUM_CIRCUITS = 3; for (size_t circuit_idx = 0; circuit_idx < NUM_CIRCUITS; ++circuit_idx) { - auto builder = GoblinUltraBuilder{ op_queue }; + proof_system::GoblinUltraCircuitBuilder builder{ op_queue }; generate_test_circuit(builder); // The same composer is used to manage Honk and Merge prover/verifier - auto composer = GoblinUltraComposer(); + proof_system::honk::GoblinUltraComposer composer; // Construct and verify Ultra Goblin Honk proof bool honk_verified = construct_and_verify_honk_proof(composer, builder); @@ -187,11 +183,11 @@ TEST_F(FullGoblinComposerTests, SimpleCircuit) // TODO(https://github.com/AztecProtocol/barretenberg/issues/786) Properly derive batching_challenge auto batching_challenge = Fbase::random_element(); auto evaluation_input = eccvm_prover.evaluation_challenge_x; - auto translator_builder = TranslatorBuilder(batching_challenge, evaluation_input, op_queue); - auto translator_composer = TranslatorComposer(); - auto translator_prover = translator_composer.create_prover(translator_builder); - auto translator_verifier = translator_composer.create_verifier(translator_builder); - auto translator_proof = translator_prover.construct_proof(); + proof_system::GoblinTranslatorCircuitBuilder translator_builder{ batching_challenge, evaluation_input, op_queue }; + GoblinTranslatorComposer translator_composer; + GoblinTranslatorProver translator_prover = translator_composer.create_prover(translator_builder); + GoblinTranslatorVerifier translator_verifier = translator_composer.create_verifier(translator_builder); + proof_system::plonk::proof translator_proof = translator_prover.construct_proof(); bool accumulator_construction_verified = translator_verifier.verify_proof(translator_proof); bool translation_verified = translator_verifier.verify_translation(eccvm_prover.translation_evaluations); EXPECT_TRUE(accumulator_construction_verified && translation_verified); diff --git a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp index b4f4573c6f85..de07bda2534d 100644 --- a/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp +++ b/barretenberg/cpp/src/barretenberg/honk/proof_system/permutation_library.hpp @@ -1,4 +1,5 @@ #pragma once +#include "barretenberg/common/ref_vector.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include @@ -184,12 +185,14 @@ void compute_permutation_grand_products(std::shared_ptr void compute_concatenated_polynomials(StorageHandle* proving_key) { - using PolynomialHandle = typename Flavor::PolynomialHandle; + // TODO(AD): use RefVector here, see https://github.com/AztecProtocol/barretenberg/issues/743 + // RefVector makes PolynomialHandle now redundant. Can scale back use of auto then too. + // using PolynomialHandle = typename Flavor::PolynomialHandle; // Concatenation groups are vectors of polynomials that are concatenated together - std::vector> concatenation_groups = proving_key->get_concatenation_groups(); + auto concatenation_groups = proving_key->get_concatenation_groups(); // Resulting concatenated polynomials - std::vector targets = proving_key->get_concatenated_constraints(); + auto targets = proving_key->get_concatenated_constraints(); // A function that produces 1 concatenated polynomial // TODO(#756): This can be rewritten to use more cores. Currently uses at maximum the number of concatenated diff --git a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp index 0726a1ad5bfb..27dac50a0252 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp @@ -7,6 +7,7 @@ */ #pragma once +#include "barretenberg/common/ref_vector.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/flavor/flavor.hpp" #include "barretenberg/plonk/proof_system/proving_key/proving_key.hpp" @@ -280,7 +281,7 @@ PermutationMapping compute_permutation_mapping( */ template void compute_honk_style_permutation_lagrange_polynomials_from_mapping( - std::vector permutation_polynomials, // sigma or ID poly + const RefVector& permutation_polynomials, // sigma or ID poly std::array, Flavor::NUM_WIRES>& permutation_mappings, typename Flavor::ProvingKey* proving_key) { @@ -469,7 +470,7 @@ void compute_standard_plonk_sigma_permutations(const typename Flavor::CircuitBui * * @param key Proving key where we will save the polynomials */ -template inline void compute_first_and_last_lagrange_polynomials(auto proving_key) +template inline void compute_first_and_last_lagrange_polynomials(const auto& proving_key) { const size_t n = proving_key->circuit_size; typename Flavor::Polynomial lagrange_polynomial_0(n); diff --git a/barretenberg/cpp/src/barretenberg/relations/translator_vm/goblin_translator_relation_consistency.test.cpp b/barretenberg/cpp/src/barretenberg/relations/translator_vm/goblin_translator_relation_consistency.test.cpp index 4752810a600a..af65f0a8aa65 100644 --- a/barretenberg/cpp/src/barretenberg/relations/translator_vm/goblin_translator_relation_consistency.test.cpp +++ b/barretenberg/cpp/src/barretenberg/relations/translator_vm/goblin_translator_relation_consistency.test.cpp @@ -25,8 +25,8 @@ using InputElements = typename Flavor::AllValues; InputElements get_random_input() { InputElements result; - for (FF* element : result.pointer_view()) { - *element = FF::random_element(); + for (FF& element : result.get_all()) { + element = FF::random_element(); } return result; } @@ -35,9 +35,9 @@ InputElements get_special_input() // use non-random values { InputElements result; FF idx = 0; - for (FF* element : result.pointer_view()) { + for (FF& element : result.get_all()) { idx += FF(1); - *element = idx; + element = idx; } return result; } diff --git a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp index eb98b7898a7e..980afc3490b6 100644 --- a/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp +++ b/barretenberg/cpp/src/barretenberg/sumcheck/sumcheck.hpp @@ -145,7 +145,7 @@ template class SumcheckProver { auto pep_view = partially_evaluated_polynomials.pointer_view(); auto poly_view = polynomials.pointer_view(); // after the first round, operate in place on partially_evaluated_polynomials - parallel_for(polynomials.size(), [&](size_t j) { + parallel_for(poly_view.size(), [&](size_t j) { for (size_t i = 0; i < round_size; i += 2) { (*pep_view[j])[i >> 1] = (*poly_view[j])[i] + round_challenge * ((*poly_view[j])[i + 1] - (*poly_view[j])[i]); diff --git a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp index d280143e2f24..e16a91f1b5ba 100644 --- a/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/translator_vm/goblin_translator_verifier.cpp @@ -20,7 +20,7 @@ GoblinTranslatorVerifier::GoblinTranslatorVerifier(GoblinTranslatorVerifier&& ot GoblinTranslatorVerifier& GoblinTranslatorVerifier::operator=(GoblinTranslatorVerifier&& other) noexcept { - key = other.key; + key = std::move(other.key); pcs_verification_key = (std::move(other.pcs_verification_key)); commitments.clear(); pcs_fr_elements.clear(); @@ -65,15 +65,10 @@ void GoblinTranslatorVerifier::put_translation_data_in_relation_parameters(const */ bool GoblinTranslatorVerifier::verify_proof(const plonk::proof& proof) { - using Curve = typename Flavor::Curve; - using ZeroMorph = pcs::zeromorph::ZeroMorphVerifier_; - using VerifierCommitments = typename Flavor::VerifierCommitments; - using CommitmentLabels = typename Flavor::CommitmentLabels; - transcript = BaseTranscript{ proof.proof_data }; - auto commitments = VerifierCommitments(key, transcript); - auto commitment_labels = CommitmentLabels(); + Flavor::VerifierCommitments commitments{ key, transcript }; + Flavor::CommitmentLabels commitment_labels; // TODO(Adrian): Change the initialization of the transcript to take the VK hash? const auto circuit_size = transcript.template receive_from_prover("circuit_size"); @@ -260,14 +255,15 @@ bool GoblinTranslatorVerifier::verify_proof(const plonk::proof& proof) // Execute ZeroMorph rounds. See https://hackmd.io/dlf9xEwhTQyE3hiGbq4FsA?view for a complete description ofthe // unrolled protocol. - auto pairing_points = ZeroMorph::verify(commitments.get_unshifted(), - commitments.get_to_be_shifted(), - claimed_evaluations.get_unshifted(), - claimed_evaluations.get_shifted(), - multivariate_challenge, - transcript, - commitments.get_concatenation_groups(), - claimed_evaluations.get_concatenated_constraints()); + auto pairing_points = + pcs::zeromorph::ZeroMorphVerifier_::verify(commitments.get_unshifted(), + commitments.get_to_be_shifted(), + claimed_evaluations.get_unshifted(), + claimed_evaluations.get_shifted(), + multivariate_challenge, + transcript, + commitments.get_concatenation_groups(), + claimed_evaluations.get_concatenated_constraints()); auto verified = pcs_verification_key->pairing_check(pairing_points[0], pairing_points[1]); diff --git a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp index 063a18377304..d2f7bd8afb62 100644 --- a/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ultra_honk/relation_correctness.test.cpp @@ -246,8 +246,8 @@ class RelationCorrectnessTests : public ::testing::Test { * @details Check that the constraints encoded by the relations are satisfied by the polynomials produced by the * Ultra Honk Composer for a real circuit. * - * TODO(Kesha): We'll have to update this function once we add zk, since the relation will be incorrect for he first few - * indices + * TODO(Kesha): We'll have to update this function once we add zk, since the relation will be incorrect for the first + * few indices * */ // TODO(luke): Add a gate that sets q_arith = 3 to check secondary arithmetic relation @@ -390,7 +390,13 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorPermutationRelationCorrectness) ProverPolynomials prover_polynomials; std::vector polynomial_container; auto polynomial_pointer_view = prover_polynomials.pointer_view(); - for (size_t i = 0; i < prover_polynomials.size(); i++) { + size_t z_perm_index = 0; + for (size_t i = 0; i < polynomial_pointer_view.size(); i++) { + // TODO(https://github.com/AztecProtocol/barretenberg/issues/743) wouldn't be needed if ProverPolynomials held + // memory + if (&prover_polynomials.z_perm == polynomial_pointer_view[i]) { + z_perm_index = i; + } Polynomial temporary_polynomial(circuit_size); polynomial_container.push_back(temporary_polynomial); *polynomial_pointer_view[i] = polynomial_container[i]; @@ -483,8 +489,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorPermutationRelationCorrectness) // Compute the grand product polynomial grand_product_library::compute_grand_product>( circuit_size, prover_polynomials, params); - prover_polynomials.z_perm_shift = - polynomial_container[90].shifted(); // TODO(https://github.com/AztecProtocol/barretenberg/issues/784) + prover_polynomials.z_perm_shift = polynomial_container[z_perm_index].shifted(); using Relations = typename Flavor::Relations; @@ -511,9 +516,15 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorGenPermSortRelationCorrectness) std::vector polynomial_container; auto polynomial_pointer_view = prover_polynomials.pointer_view(); + size_t ordered_range_constraints_index = 0; // Allocate polynomials - for (size_t i = 0; i < prover_polynomials.size(); i++) { + for (size_t i = 0; i < polynomial_pointer_view.size(); i++) { Polynomial temporary_polynomial(circuit_size); + // TODO(https://github.com/AztecProtocol/barretenberg/issues/743) wouldn't be needed if ProverPolynomials held + // memory + if (&prover_polynomials.ordered_range_constraints_0 == polynomial_pointer_view[i]) { + ordered_range_constraints_index = i; + } polynomial_container.push_back(temporary_polynomial); *polynomial_pointer_view[i] = polynomial_container[i]; } @@ -559,20 +570,17 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorGenPermSortRelationCorrectness) polynomial_pointers[i + 1]->begin()); }); - // TODO(https://github.com/AztecProtocol/barretenberg/issues/784) - enum ORDERED_RANGE_CONSTRAINTS : size_t { C0 = 85, C1, C2, C3, C4 }; - // Get shifted polynomials prover_polynomials.ordered_range_constraints_0_shift = - polynomial_container[ORDERED_RANGE_CONSTRAINTS::C0].shifted(); + polynomial_container[ordered_range_constraints_index].shifted(); prover_polynomials.ordered_range_constraints_1_shift = - polynomial_container[ORDERED_RANGE_CONSTRAINTS::C1].shifted(); + polynomial_container[ordered_range_constraints_index + 1].shifted(); prover_polynomials.ordered_range_constraints_2_shift = - polynomial_container[ORDERED_RANGE_CONSTRAINTS::C2].shifted(); + polynomial_container[ordered_range_constraints_index + 2].shifted(); prover_polynomials.ordered_range_constraints_3_shift = - polynomial_container[ORDERED_RANGE_CONSTRAINTS::C3].shifted(); + polynomial_container[ordered_range_constraints_index + 3].shifted(); prover_polynomials.ordered_range_constraints_4_shift = - polynomial_container[ORDERED_RANGE_CONSTRAINTS::C4].shifted(); + polynomial_container[ordered_range_constraints_index + 4].shifted(); using Relations = typename Flavor::Relations; @@ -611,7 +619,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorExtraRelationsCorrectness) auto polynomial_id_pointer_view = prover_polynomial_ids.pointer_view(); std::vector polynomial_container; std::vector polynomial_ids; - for (size_t i = 0; i < prover_polynomials.size(); i++) { + for (size_t i = 0; i < polynomial_id_pointer_view.size(); i++) { Polynomial temporary_polynomial(circuit_size); // Allocate polynomials polynomial_container.push_back(temporary_polynomial); @@ -627,7 +635,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorExtraRelationsCorrectness) } // Assign spans to non-shifted prover polynomials auto polynomial_pointer_view = prover_polynomials.pointer_view(); - for (size_t i = 0; i < prover_polynomials.size(); i++) { + for (size_t i = 0; i < polynomial_pointer_view.size(); i++) { if (!shifted_id_set.contains(i)) { *polynomial_pointer_view[i] = polynomial_container[i]; } @@ -710,7 +718,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorDecompositionRelationCorrectnes std::vector polynomial_ids; auto polynomial_id_pointer_view = prover_polynomial_ids.pointer_view(); auto polynomial_pointer_view = prover_polynomials.pointer_view(); - for (size_t i = 0; i < prover_polynomials.size(); i++) { + for (size_t i = 0; i < polynomial_id_pointer_view.size(); i++) { Polynomial temporary_polynomial(circuit_size); // Allocate polynomials polynomial_container.push_back(temporary_polynomial); @@ -725,7 +733,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorDecompositionRelationCorrectnes shifted_id_set.emplace(id); } // Assign spans to non-shifted prover polynomials - for (size_t i = 0; i < prover_polynomials.size(); i++) { + for (size_t i = 0; i < polynomial_pointer_view.size(); i++) { if (!shifted_id_set.contains(i)) { *polynomial_pointer_view[i] = polynomial_container[i]; } @@ -1129,7 +1137,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorNonNativeRelationCorrectness) std::vector polynomial_ids; auto polynomial_pointer_view = prover_polynomials.pointer_view(); auto polynomial_id_pointer_view = prover_polynomial_ids.pointer_view(); - for (size_t i = 0; i < prover_polynomials.size(); i++) { + for (size_t i = 0; i < polynomial_pointer_view.size(); i++) { Polynomial temporary_polynomial(circuit_size); // Allocate polynomials polynomial_container.push_back(temporary_polynomial); @@ -1144,7 +1152,7 @@ TEST_F(RelationCorrectnessTests, GoblinTranslatorNonNativeRelationCorrectness) shifted_id_set.emplace(id); } // Assign spans to non-shifted prover polynomials - for (size_t i = 0; i < prover_polynomials.size(); i++) { + for (size_t i = 0; i < polynomial_pointer_view.size(); i++) { if (!shifted_id_set.contains(i)) { *polynomial_pointer_view[i] = polynomial_container[i]; } From d9a44dc2e655752e1c6503ac85b64169ec7e4754 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 30 Nov 2023 15:26:28 +0000 Subject: [PATCH 08/37] chore: typo fixes (#3488) --- barretenberg/cpp/src/barretenberg/common/thread.cpp | 6 +++--- barretenberg/cpp/src/barretenberg/ecc/groups/wnaf.hpp | 6 +++--- barretenberg/cpp/src/barretenberg/ecc/pippenger.md | 8 ++++---- .../plonk/proof_system/utils/generalized_permutation.hpp | 2 +- .../barretenberg/plonk/proof_system/utils/permutation.hpp | 2 +- .../circuit_builder/eccvm/eccvm_circuit_builder.hpp | 2 +- .../circuit_builder/ultra_circuit_builder.cpp | 4 ++-- .../proof_system/composer/permutation_lib.hpp | 2 +- .../proof_system/plookup_tables/keccak/keccak_rho.hpp | 4 ++-- .../cpp/src/barretenberg/smt_verification/README.md | 4 ++-- .../cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp | 2 +- 11 files changed, 21 insertions(+), 21 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/common/thread.cpp b/barretenberg/cpp/src/barretenberg/common/thread.cpp index 04a71f5746b6..6d3007c87396 100644 --- a/barretenberg/cpp/src/barretenberg/common/thread.cpp +++ b/barretenberg/cpp/src/barretenberg/common/thread.cpp @@ -9,11 +9,11 @@ * The first implementation was `parallel_for_spawning`. You can read a description of each implementation in the * relevant source file, but parallel_for_spawning is the simplest approach imaginable. * Once WASM was working, I checked its performance in native code by running it against the polynomials benchmarks. - * In doing so, OMP outperformed it significantly (at least for FFT algorithims). This set me on a course to try + * In doing so, OMP outperformed it significantly (at least for FFT algorithms). This set me on a course to try * and understand why and to provide a suitable alternative. Ultimately I found solutions that compared to OMP with * "moody" and "atomic_pool" solutions, although they were not *quite* as fast as OMP. However interestingly, when it * comes to actual "real world" testing (with proof construction), rather than raw benchmarking, most of the solutions - * performaed about the same, with OMP *actually slightly worse*. So maybe all this effort was a bit redundant. + * performed about the same, with OMP *actually slightly worse*. So maybe all this effort was a bit redundant. * Remember to always do real world testing... * * My theory as to why OMP performs so much better in benchmarks is because it runs the tests in a very tight loop, @@ -85,4 +85,4 @@ void parallel_for(size_t num_iterations, const std::function& func // parallel_for_queued(num_iterations, func); #endif #endif -} \ No newline at end of file +} diff --git a/barretenberg/cpp/src/barretenberg/ecc/groups/wnaf.hpp b/barretenberg/cpp/src/barretenberg/ecc/groups/wnaf.hpp index c6dbee10eada..846d11d64c0d 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/groups/wnaf.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/groups/wnaf.hpp @@ -239,12 +239,12 @@ inline uint64_t get_num_scalar_bits(const uint64_t* scalar) * * N.B. IN OUR STDLIB ALGORITHMS THE SKEW VALUE REPRESENTS AN ADDITION NOT A SUBTRACTION (i.e. we add +1 at the end of * the scalar mul algo we don't sub 1) (this is to eliminate situations which could produce the point at infinity as an - * output as our circuit logic cannot accomodate this edge case). + * output as our circuit logic cannot accommodate this edge case). * * Credits: Zac W. * * @param scalar Pointer to the 128-bit non-montgomery scalar that is supposed to be transformed into wnaf - * @param wnaf Pointer to output array that needs to accomodate enough 64-bit WNAF entries + * @param wnaf Pointer to output array that needs to accommodate enough 64-bit WNAF entries * @param skew_map Reference to output skew value, which if true shows that the point should be added once at the end of * computation * @param wnaf_round_counts Pointer to output array specifying the number of points participating in each round @@ -497,4 +497,4 @@ inline void fixed_wnaf_with_restricted_first_slice(uint64_t* scalar, // } } // namespace barretenberg::wnaf -// NOLINTEND(readability-implicit-bool-conversion) \ No newline at end of file +// NOLINTEND(readability-implicit-bool-conversion) diff --git a/barretenberg/cpp/src/barretenberg/ecc/pippenger.md b/barretenberg/cpp/src/barretenberg/ecc/pippenger.md index 18f8b85941f8..a7463663216e 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/pippenger.md +++ b/barretenberg/cpp/src/barretenberg/ecc/pippenger.md @@ -26,7 +26,7 @@ So, for example, if the most significant 6 bits of a scalar are `011001` (25), w At the end of each round, we then 'concatenate' all of the buckets into a sum. Let's represent each bucket accumulator in an array `A[num_buckets]`. The concatenation phase will compute `A[0] + 2A[1] + 3A[2] + 4A[3] + 5A[4] + ... = Sum`. -Finally, we add each `Sum` point into an overall accumulator. For example, for a set of 254 bit scalars, if we evaluate the most 6 significant bits of each scalar and accumulate the resulting point into `Sum`, we actually need `(2^{248}).Sum` to accomodate for the bit shift. +Finally, we add each `Sum` point into an overall accumulator. For example, for a set of 254 bit scalars, if we evaluate the most 6 significant bits of each scalar and accumulate the resulting point into `Sum`, we actually need `(2^{248}).Sum` to accommodate for the bit shift. This final step is similar to the 'double and add' algorithm in a traditional scalar multiplication algorithm - we start at the most significant bit slice and work our way down to minimize the number of doublings. At each round, we multiply the overall accumulator by 2^{bit slice size} - by the time we iterate over every round, we will have performed the total required number of doublings for every 'bit slice' that we add into our accumulator. @@ -38,7 +38,7 @@ Total run time = 16 * 2^{18} + 16 * 2^{15} = 18 * 2^{18}. So the aggregate numbe ## The problem with Pippenger's algorithm -As it is currently implemented, each round will iterate over the points to be added, and add each point into one of the round's buckets. Whilst point access is sequential in memory, bucket access is very much not. In fact, if the points being multiplied are from a zero-knowlege proof, bucket access is literally uniformly randomly distributed and therefore presents the worst-case scenario. +As it is currently implemented, each round will iterate over the points to be added, and add each point into one of the round's buckets. Whilst point access is sequential in memory, bucket access is very much not. In fact, if the points being multiplied are from a zero-knowledge proof, bucket access is literally uniformly randomly distributed and therefore presents the worst-case scenario. This makes it difficult to parallelize. It is not possible to simply assign threads a section of points to iterate over, because of race conditions when two threads access the same bucket. @@ -69,8 +69,8 @@ Drawbacks of this approach: ## Summary -By restructuring the memory heirarchy of our pippenger algorithm, we can create a parallelizable version of pippenger. This will significantly simplify the logic of our PLONK prover (instead of allocating threads for batches of multi-exponentations, we can multi-thread individual multi-exponentiations, simplifying our thread logic). +By restructuring the memory hierarchy of our pippenger algorithm, we can create a parallelizable version of pippenger. This will significantly simplify the logic of our PLONK prover (instead of allocating threads for batches of multi-exponentations, we can multi-thread individual multi-exponentiations, simplifying our thread logic). This will concretely reduce the number of pippenger rounds of our multi-exponentiations by approximately 1, giving a theoretical 15% speed-up. Some of this will be eaten by the run-time of the radix sort. -Longer term, this parallelizable algorithm will be significantly easier to adapt for GPUs, using OpenCL. \ No newline at end of file +Longer term, this parallelizable algorithm will be significantly easier to adapt for GPUs, using OpenCL. diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp index fbf08b9c1023..7741d113b063 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/generalized_permutation.hpp @@ -27,7 +27,7 @@ inline void compute_gen_permutation_lagrange_base_single(barretenberg::polynomia // here, 'index' refers to an element of our subgroup H // we can almost use permutation[i] to directly index our `roots` array, which contains our subgroup elements // we first have to mask off the 2 high bits, which describe which wire polynomial our permutation maps to (we'll - // deal with that in a bit) we then have to accomodate for the fact that, `roots` only contains *half* of our + // deal with that in a bit) we then have to accommodate for the fact that, `roots` only contains *half* of our // subgroup elements. this is because w^{n/2} = -w and we don't want to perform redundant work computing roots of // unity diff --git a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp index 5f3a78d1a11a..7d5565251b96 100644 --- a/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp +++ b/barretenberg/cpp/src/barretenberg/plonk/proof_system/utils/permutation.hpp @@ -65,7 +65,7 @@ inline void compute_permutation_lagrange_base_single(barretenberg::polynomial& o // `permutation[i]` will specify the 'index' that this wire value will map to. // Here, 'index' refers to an element of our subgroup H. // We can almost use `permutation[i]` to directly index our `roots` array, which contains our subgroup elements. - // We first have to accomodate for the fact that `roots` only contains *half* of our subgroup elements. This is + // We first have to accommodate for the fact that `roots` only contains *half* of our subgroup elements. This is // because ω^{n/2} = -ω and we don't want to perform redundant work computing roots of unity. size_t raw_idx = permutation[i].subgroup_index; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp index 6bee55c0d4c4..9468df3aa6e0 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/eccvm/eccvm_circuit_builder.hpp @@ -390,7 +390,7 @@ template class ECCVMCircuitBuilder { } } for (size_t i = 0; i < precompute_table_state.size(); ++i) { - // first row is always an empty row (to accomodate shifted polynomials which must have 0 as 1st + // first row is always an empty row (to accommodate shifted polynomials which must have 0 as 1st // coefficient). All other rows in the precompute_table_state represent active wnaf gates (i.e. // precompute_select = 1) polys.precompute_select[i] = (i != 0) ? 1 : 0; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index 047e3e8489e9..42ef656b8079 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -701,7 +701,7 @@ std::vector UltraCircuitBuilder_::decompose_into_defa * This is not strictly required iff num_bits <= target_range_bitnum. * However, this produces an edge-case where a variable is range-constrained but NOT present in an arithmetic gate. * This in turn produces an unsatisfiable circuit (see `create_new_range_constraint`). We would need to check for - * and accomodate/reject this edge case to support not adding addition gates here if not reqiured + * and accommodate/reject this edge case to support not adding addition gates here if not reqiured * if (num_bits <= target_range_bitnum) { * const uint64_t expected_range = (1ULL << num_bits) - 1ULL; * create_new_range_constraint(variable_index, expected_range); @@ -3454,4 +3454,4 @@ template class UltraCircuitBuilder_ // To enable this we need to template plookup // template class UltraCircuitBuilder_; -} // namespace proof_system \ No newline at end of file +} // namespace proof_system diff --git a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp index 27dac50a0252..90a7f0152f05 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/composer/permutation_lib.hpp @@ -347,7 +347,7 @@ inline void compute_standard_plonk_lagrange_polynomial(barretenberg::polynomial& // `permutation[i]` will specify the 'index' that this wire value will map to. // Here, 'index' refers to an element of our subgroup H. // We can almost use `permutation[i]` to directly index our `roots` array, which contains our subgroup elements. - // We first have to accomodate for the fact that `roots` only contains *half* of our subgroup elements. This is + // We first have to accommodate for the fact that `roots` only contains *half* of our subgroup elements. This is // because ω^{n/2} = -ω and we don't want to perform redundant work computing roots of unity. size_t raw_idx = permutation[i].row_index; diff --git a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/keccak/keccak_rho.hpp b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/keccak/keccak_rho.hpp index d29f4009b057..158c6119d614 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/keccak/keccak_rho.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/plookup_tables/keccak/keccak_rho.hpp @@ -40,7 +40,7 @@ namespace keccak_tables { * * We need multiple Rho tables in order to efficiently range-constrain our input slices. * - * The maximum number of bits we can accomodate in this lookup table is MAXIMUM_MULTITABLE_BITS (assume this is 8) + * The maximum number of bits we can accommodate in this lookup table is MAXIMUM_MULTITABLE_BITS (assume this is 8) * For example take a left-rotation by 1 bit. The right-slice will be a 63-bit integer. * 63 does not evenly divide 8. i.e. an 8-bit table cannot correctly range-constrain the input slice and we would need * additional range constraints. @@ -49,7 +49,7 @@ namespace keccak_tables { * We can stitch together a lookup table sequence that correctly range constrains the left/right slices for any of our * 25 rotation values * - * @tparam TABLE_BITS The number of bits each lookup table can accomodate + * @tparam TABLE_BITS The number of bits each lookup table can accommodate * @tparam LANE_INDEX Required by get_rho_output_table to produce the correct MultiTable */ template class Rho { diff --git a/barretenberg/cpp/src/barretenberg/smt_verification/README.md b/barretenberg/cpp/src/barretenberg/smt_verification/README.md index fdb6d1c20724..8dfe2fc15486 100644 --- a/barretenberg/cpp/src/barretenberg/smt_verification/README.md +++ b/barretenberg/cpp/src/barretenberg/smt_verification/README.md @@ -71,7 +71,7 @@ To store it on the disk just do `FFTerm` - the symbolic value that simulates finite field elements. - `FFTerm` - the symbolic value that simulates integer elements which behave like finite field ones. Usefull, when you want to create range constraints or perform operations like XOR. + `FFTerm` - the symbolic value that simulates integer elements which behave like finite field ones. Useful, when you want to create range constraints or perform operations like XOR. `Bool` - simulates the boolean values and mostly will be used only to simulate complex `if` statements if needed. @@ -250,4 +250,4 @@ void model_variables(Circuit& c, Solver* s, FFTerm& evaluatio } ``` -More examples can be found in *.test.cpp files \ No newline at end of file +More examples can be found in *.test.cpp files diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp index 72cc1dee046e..0effaca5ed41 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp @@ -110,7 +110,7 @@ uint uint::operator>>(const size_t shift) cons * * We have a special selector configuration in our arithmetic widget that extracts 6.b_x from given the two * relevant accumulators. The factor of 6 is for efficiency reasons. We need to scale our other gate - * coefficients by 6 to accomodate this. + * coefficients by 6 to accommodate this. **/ if ((shift & 1) == 0) { From d09d6f5a5f2c7e2a58658a640a6a6d6ba4294701 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Thu, 30 Nov 2023 17:42:25 +0000 Subject: [PATCH 09/37] feat: seperate pil files for sub machines (#3454) https://github.com/AztecProtocol/powdr/pull/22 depends on the above. - We now have multiple different pil files to represent different submachines in our main vm circuit - This pr updates the codegen to match this, now powdr will create a different relations file for each, this allows us to perform witness generation for the submachines in isolation if we want to, and means that only the machines that were edited will be in the resulting diff in future prs --------- Co-authored-by: jeanmon Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Cat McGee Co-authored-by: josh crites Co-authored-by: Alex Gherghisan Co-authored-by: Zachary James Williamson Co-authored-by: lucasxia01 Co-authored-by: PhilWindle <60546371+PhilWindle@users.noreply.github.com> --- barretenberg/cpp/pil/avm/avm_mini.pil | 47 +---- barretenberg/cpp/pil/avm/avm_mini_opt.pil | 25 ++- barretenberg/cpp/pil/avm/mem_trace.pil | 47 +++++ .../flavor/generated/AvmMini_flavor.hpp | 178 ++++++++++------- .../circuit_builder/AvmMini_helper.cpp | 19 +- .../circuit_builder/AvmMini_helper.hpp | 4 +- .../circuit_builder/AvmMini_trace.cpp | 21 +- .../circuit_builder/AvmMini_trace.hpp | 6 +- .../generated/AvmMini_circuit_builder.hpp | 65 ++++-- .../relations/generated/AvmMini.hpp | 185 ------------------ .../relations/generated/AvmMini/avm_mini.hpp | 106 ++++++++++ .../generated/AvmMini/declare_views.hpp | 29 +++ .../relations/generated/AvmMini/mem_trace.hpp | 79 ++++++++ .../vm/generated/AvmMini_composer.cpp | 13 +- .../vm/generated/AvmMini_prover.cpp | 25 ++- .../vm/generated/AvmMini_verifier.cpp | 17 +- 16 files changed, 483 insertions(+), 383 deletions(-) create mode 100644 barretenberg/cpp/pil/avm/mem_trace.pil delete mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/AvmMini.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp create mode 100644 barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp diff --git a/barretenberg/cpp/pil/avm/avm_mini.pil b/barretenberg/cpp/pil/avm/avm_mini.pil index 80103c910573..f9b8f2fe23a6 100644 --- a/barretenberg/cpp/pil/avm/avm_mini.pil +++ b/barretenberg/cpp/pil/avm/avm_mini.pil @@ -1,6 +1,7 @@ -constant %N = 256; -namespace avmMini(%N); +include "mem_trace.pil"; + +namespace avmMini(256); //===== CONSTANT POLYNOMIALS ================================================== pol constant clk(i) { i }; @@ -52,46 +53,4 @@ namespace avmMini(%N); // Relation for addition over the finite field subop * (ia + ib - ic) = 0; - // ========= Table MEM-TR ================= - pol commit m_clk; - pol commit m_sub_clk; - pol commit m_addr; - pol commit m_val; - pol commit m_lastAccess; // Boolean (1 when this row is the last of a given address) - pol commit m_rw; // Enum: 0 (read), 1 (write) - - // Type constraints - m_lastAccess * (1 - m_lastAccess) = 0; - m_rw * (1 - m_rw) = 0; - - // m_lastAccess == 0 ==> m_addr' == m_addr - (1 - first) * (1 - m_lastAccess) * (m_addr' - m_addr) = 0; - - // We need: m_lastAccess == 1 ==> m_addr' > m_addr - // The above implies: m_addr' == m_addr ==> m_lastAccess == 0 - // This condition does not apply on the last row. - // clk + 1 used as an expression for positive integers - // TODO: Uncomment when lookups are supported - // (1 - first) * (1 - last) * m_lastAccess { (m_addr' - m_addr) } in clk + 1; // Gated inclusion check. Is it supported? - - // TODO: following constraint - // m_addr' == m_addr && m_clk == m_clk' ==> m_sub_clk' - m_sub_clk > 0 - // Can be enforced with (1 - first) * (1 - last) * (1 - m_lastAccess) { 6 * (m_clk' - m_clk) + m_sub_clk' - m_sub_clk } in clk + 1 - - // Alternatively to the above, one could require - // that m_addr' - m_addr is 0 or 1 (needs to add placeholders m_addr values): - // (m_addr' - m_addr) * (m_addr' - m_addr) - (m_addr' - m_addr) = 0; - // if m_addr' - m_addr is 0 or 1, the following is equiv. to m_lastAccess - // (m_addr' - m_addr) - - // m_lastAccess == 0 && m_rw' == 0 ==> m_val == m_val' - // This condition does not apply on the last row. - // Note: in barretenberg, a shifted polynomial will be 0 on the last row (shift is not cyclic) - // Note2: in barretenberg, if a poynomial is shifted, its non-shifted equivalent must be 0 on the first row - - (1 - first) * (1 - last) * (1 - m_lastAccess) * (1 - m_rw') * (m_val' - m_val) = 0; - - // TODO: Constraint the first load from a given adress has value 0. (Consistency of memory initialization.) - // TODO: when introducing load/store as sub-operations, we will have to add consistency of intermediate - // register values ia, ib, ic \ No newline at end of file diff --git a/barretenberg/cpp/pil/avm/avm_mini_opt.pil b/barretenberg/cpp/pil/avm/avm_mini_opt.pil index 82a456a38ca3..ffa516ca9efa 100644 --- a/barretenberg/cpp/pil/avm/avm_mini_opt.pil +++ b/barretenberg/cpp/pil/avm/avm_mini_opt.pil @@ -1,7 +1,16 @@ -constant %N = 256; +namespace memTrace(256); + col witness m_clk; + col witness m_sub_clk; + col witness m_addr; + col witness m_val; + col witness m_lastAccess; + col witness m_rw; + (memTrace.m_lastAccess * (1 - memTrace.m_lastAccess)) = 0; + (memTrace.m_rw * (1 - memTrace.m_rw)) = 0; + (((1 - avmMini.first) * (1 - memTrace.m_lastAccess)) * (memTrace.m_addr' - memTrace.m_addr)) = 0; + (((((1 - avmMini.first) * (1 - avmMini.last)) * (1 - memTrace.m_lastAccess)) * (1 - memTrace.m_rw')) * (memTrace.m_val' - memTrace.m_val)) = 0; namespace avmMini(256); col fixed clk(i) { i }; - col fixed positive(i) { (i + 1) }; col fixed first = [1] + [0]*; col witness subop; col witness ia; @@ -24,14 +33,4 @@ namespace avmMini(256); (avmMini.rwa * (1 - avmMini.rwa)) = 0; (avmMini.rwb * (1 - avmMini.rwb)) = 0; (avmMini.rwc * (1 - avmMini.rwc)) = 0; - (avmMini.subop * ((avmMini.ia + avmMini.ib) - avmMini.ic)) = 0; - col witness m_clk; - col witness m_sub_clk; - col witness m_addr; - col witness m_val; - col witness m_lastAccess; - col witness m_rw; - (avmMini.m_lastAccess * (1 - avmMini.m_lastAccess)) = 0; - (avmMini.m_rw * (1 - avmMini.m_rw)) = 0; - (((1 - avmMini.first) * (1 - avmMini.m_lastAccess)) * (avmMini.m_addr' - avmMini.m_addr)) = 0; - (((((1 - avmMini.first) * (1 - avmMini.last)) * (1 - avmMini.m_lastAccess)) * (1 - avmMini.m_rw')) * (avmMini.m_val' - avmMini.m_val)) = 0; + (avmMini.subop * ((avmMini.ia + avmMini.ib) - avmMini.ic)) = 0; \ No newline at end of file diff --git a/barretenberg/cpp/pil/avm/mem_trace.pil b/barretenberg/cpp/pil/avm/mem_trace.pil new file mode 100644 index 000000000000..38cc0813d2c9 --- /dev/null +++ b/barretenberg/cpp/pil/avm/mem_trace.pil @@ -0,0 +1,47 @@ + + +include "avm_mini.pil"; + +namespace memTrace(256); + // ========= Table MEM-TR ================= + pol commit m_clk; + pol commit m_sub_clk; + pol commit m_addr; + pol commit m_val; + pol commit m_lastAccess; // Boolean (1 when this row is the last of a given address) + pol commit m_rw; // Enum: 0 (read), 1 (write) + + // Type constraints + m_lastAccess * (1 - m_lastAccess) = 0; + m_rw * (1 - m_rw) = 0; + + // m_lastAccess == 0 ==> m_addr' == m_addr + (1 - avmMini.first) * (1 - m_lastAccess) * (m_addr' - m_addr) = 0; + + // We need: m_lastAccess == 1 ==> m_addr' > m_addr + // The above implies: m_addr' == m_addr ==> m_lastAccess == 0 + // This condition does not apply on the last row. + // clk + 1 used as an expression for positive integers + // TODO: Uncomment when lookups are supported + // (1 - first) * (1 - last) * m_lastAccess { (m_addr' - m_addr) } in clk + 1; // Gated inclusion check. Is it supported? + + // TODO: following constraint + // m_addr' == m_addr && m_clk == m_clk' ==> m_sub_clk' - m_sub_clk > 0 + // Can be enforced with (1 - first) * (1 - last) * (1 - m_lastAccess) { 6 * (m_clk' - m_clk) + m_sub_clk' - m_sub_clk } in clk + 1 + + // Alternatively to the above, one could require + // that m_addr' - m_addr is 0 or 1 (needs to add placeholders m_addr values): + // (m_addr' - m_addr) * (m_addr' - m_addr) - (m_addr' - m_addr) = 0; + // if m_addr' - m_addr is 0 or 1, the following is equiv. to m_lastAccess + // (m_addr' - m_addr) + + // m_lastAccess == 0 && m_rw' == 0 ==> m_val == m_val' + // This condition does not apply on the last row. + // Note: in barretenberg, a shifted polynomial will be 0 on the last row (shift is not cyclic) + // Note2: in barretenberg, if a poynomial is shifted, its non-shifted equivalent must be 0 on the first row + + (1 - avmMini.first) * (1 - avmMini.last) * (1 - m_lastAccess) * (1 - m_rw') * (m_val' - m_val) = 0; + + // TODO: Constraint the first load from a given adress has value 0. (Consistency of memory initialization.) + // TODO: when introducing load/store as sub-operations, we will have to add consistency of intermediate + // register values ia, ib, ic \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp index 7f2b128a3f23..3216a9474832 100644 --- a/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp +++ b/barretenberg/cpp/src/barretenberg/flavor/generated/AvmMini_flavor.hpp @@ -11,7 +11,8 @@ #include "barretenberg/flavor/flavor_macros.hpp" #include "barretenberg/polynomials/evaluation_domain.hpp" #include "barretenberg/polynomials/polynomial.hpp" -#include "barretenberg/relations/generated/AvmMini.hpp" +#include "barretenberg/relations/generated/AvmMini/avm_mini.hpp" +#include "barretenberg/relations/generated/AvmMini/mem_trace.hpp" #include "barretenberg/transcript/transcript.hpp" namespace proof_system::honk { @@ -32,14 +33,14 @@ class AvmMiniFlavor { using CommitmentKey = pcs::CommitmentKey; using VerifierCommitmentKey = pcs::VerifierCommitmentKey; - static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 3; + static constexpr size_t NUM_PRECOMPUTED_ENTITIES = 2; static constexpr size_t NUM_WITNESS_ENTITIES = 20; static constexpr size_t NUM_WIRES = NUM_WITNESS_ENTITIES + NUM_PRECOMPUTED_ENTITIES; // We have two copies of the witness entities, so we subtract the number of fixed ones (they have no shift), one for // the unshifted and one for the shifted - static constexpr size_t NUM_ALL_ENTITIES = 26; + static constexpr size_t NUM_ALL_ENTITIES = 25; - using Relations = std::tuple>; + using Relations = std::tuple, AvmMini_vm::mem_trace>; static constexpr size_t MAX_PARTIAL_RELATION_LENGTH = compute_max_partial_relation_length(); @@ -61,13 +62,13 @@ class AvmMiniFlavor { template class PrecomputedEntities : public PrecomputedEntitiesBase { public: using DataType = DataType_; - DEFINE_FLAVOR_MEMBERS(DataType, avmMini_clk, avmMini_positive, avmMini_first); + + DEFINE_FLAVOR_MEMBERS(DataType, avmMini_clk, avmMini_first) RefVector get_selectors() { return { avmMini_clk, - avmMini_positive, avmMini_first, }; }; @@ -80,6 +81,12 @@ class AvmMiniFlavor { template class WitnessEntities { public: DEFINE_FLAVOR_MEMBERS(DataType, + memTrace_m_clk, + memTrace_m_sub_clk, + memTrace_m_addr, + memTrace_m_val, + memTrace_m_lastAccess, + memTrace_m_rw, avmMini_subop, avmMini_ia, avmMini_ib, @@ -93,21 +100,15 @@ class AvmMiniFlavor { avmMini_mem_idx_a, avmMini_mem_idx_b, avmMini_mem_idx_c, - avmMini_last, - avmMini_m_clk, - avmMini_m_sub_clk, - avmMini_m_addr, - avmMini_m_val, - avmMini_m_lastAccess, - avmMini_m_rw); + avmMini_last) RefVector get_wires() { return { - avmMini_subop, avmMini_ia, avmMini_ib, avmMini_ic, avmMini_mem_op_a, - avmMini_mem_op_b, avmMini_mem_op_c, avmMini_rwa, avmMini_rwb, avmMini_rwc, - avmMini_mem_idx_a, avmMini_mem_idx_b, avmMini_mem_idx_c, avmMini_last, avmMini_m_clk, - avmMini_m_sub_clk, avmMini_m_addr, avmMini_m_val, avmMini_m_lastAccess, avmMini_m_rw, + memTrace_m_clk, memTrace_m_sub_clk, memTrace_m_addr, memTrace_m_val, memTrace_m_lastAccess, + memTrace_m_rw, avmMini_subop, avmMini_ia, avmMini_ib, avmMini_ic, + avmMini_mem_op_a, avmMini_mem_op_b, avmMini_mem_op_c, avmMini_rwa, avmMini_rwb, + avmMini_rwc, avmMini_mem_idx_a, avmMini_mem_idx_b, avmMini_mem_idx_c, avmMini_last, }; }; @@ -119,9 +120,13 @@ class AvmMiniFlavor { public: DEFINE_FLAVOR_MEMBERS(DataType, avmMini_clk, - avmMini_positive, avmMini_first, - + memTrace_m_clk, + memTrace_m_sub_clk, + memTrace_m_addr, + memTrace_m_val, + memTrace_m_lastAccess, + memTrace_m_rw, avmMini_subop, avmMini_ia, avmMini_ib, @@ -136,26 +141,38 @@ class AvmMiniFlavor { avmMini_mem_idx_b, avmMini_mem_idx_c, avmMini_last, - avmMini_m_clk, - avmMini_m_sub_clk, - avmMini_m_addr, - avmMini_m_val, - avmMini_m_lastAccess, - avmMini_m_rw, - - avmMini_m_val_shift, - avmMini_m_addr_shift, - avmMini_m_rw_shift) + memTrace_m_rw_shift, + memTrace_m_addr_shift, + memTrace_m_val_shift) RefVector get_wires() { return { - avmMini_clk, avmMini_positive, avmMini_first, avmMini_subop, avmMini_ia, - avmMini_ib, avmMini_ic, avmMini_mem_op_a, avmMini_mem_op_b, avmMini_mem_op_c, - avmMini_rwa, avmMini_rwb, avmMini_rwc, avmMini_mem_idx_a, avmMini_mem_idx_b, - avmMini_mem_idx_c, avmMini_last, avmMini_m_clk, avmMini_m_sub_clk, avmMini_m_addr, - avmMini_m_val, avmMini_m_lastAccess, avmMini_m_rw, avmMini_m_val_shift, avmMini_m_addr_shift, - avmMini_m_rw_shift, + avmMini_clk, + avmMini_first, + memTrace_m_clk, + memTrace_m_sub_clk, + memTrace_m_addr, + memTrace_m_val, + memTrace_m_lastAccess, + memTrace_m_rw, + avmMini_subop, + avmMini_ia, + avmMini_ib, + avmMini_ic, + avmMini_mem_op_a, + avmMini_mem_op_b, + avmMini_mem_op_c, + avmMini_rwa, + avmMini_rwb, + avmMini_rwc, + avmMini_mem_idx_a, + avmMini_mem_idx_b, + avmMini_mem_idx_c, + avmMini_last, + memTrace_m_rw_shift, + memTrace_m_addr_shift, + memTrace_m_val_shift, }; }; @@ -163,11 +180,28 @@ class AvmMiniFlavor { RefVector get_unshifted() { return { - avmMini_clk, avmMini_positive, avmMini_first, avmMini_subop, avmMini_ia, - avmMini_ib, avmMini_ic, avmMini_mem_op_a, avmMini_mem_op_b, avmMini_mem_op_c, - avmMini_rwa, avmMini_rwb, avmMini_rwc, avmMini_mem_idx_a, avmMini_mem_idx_b, - avmMini_mem_idx_c, avmMini_last, avmMini_m_clk, avmMini_m_sub_clk, avmMini_m_addr, - avmMini_m_val, avmMini_m_lastAccess, avmMini_m_rw, + avmMini_clk, + avmMini_first, + memTrace_m_clk, + memTrace_m_sub_clk, + memTrace_m_addr, + memTrace_m_val, + memTrace_m_lastAccess, + memTrace_m_rw, + avmMini_subop, + avmMini_ia, + avmMini_ib, + avmMini_ic, + avmMini_mem_op_a, + avmMini_mem_op_b, + avmMini_mem_op_c, + avmMini_rwa, + avmMini_rwb, + avmMini_rwc, + avmMini_mem_idx_a, + avmMini_mem_idx_b, + avmMini_mem_idx_c, + avmMini_last, }; }; @@ -175,9 +209,9 @@ class AvmMiniFlavor { RefVector get_to_be_shifted() { return { - avmMini_m_val, - avmMini_m_addr, - avmMini_m_rw, + memTrace_m_rw, + memTrace_m_addr, + memTrace_m_val, }; }; @@ -185,9 +219,9 @@ class AvmMiniFlavor { RefVector get_shifted() { return { - avmMini_m_val_shift, - avmMini_m_addr_shift, - avmMini_m_rw_shift, + memTrace_m_rw_shift, + memTrace_m_addr_shift, + memTrace_m_val_shift, }; }; @@ -218,7 +252,7 @@ class AvmMiniFlavor { class AllPolynomials : public AllEntities { public: - [[nodiscard]] size_t get_polynomial_size() const { return this->avmMini_clk.size(); } + [[nodiscard]] size_t get_polynomial_size() const { return this->memTrace_m_clk.size(); } [[nodiscard]] AllValues get_row(const size_t row_idx) const { AllValues result; @@ -263,8 +297,13 @@ class AvmMiniFlavor { : AllEntities() { Base::avmMini_clk = "avmMini_clk"; - Base::avmMini_positive = "avmMini_positive"; Base::avmMini_first = "avmMini_first"; + Base::memTrace_m_clk = "memTrace_m_clk"; + Base::memTrace_m_sub_clk = "memTrace_m_sub_clk"; + Base::memTrace_m_addr = "memTrace_m_addr"; + Base::memTrace_m_val = "memTrace_m_val"; + Base::memTrace_m_lastAccess = "memTrace_m_lastAccess"; + Base::memTrace_m_rw = "memTrace_m_rw"; Base::avmMini_subop = "avmMini_subop"; Base::avmMini_ia = "avmMini_ia"; Base::avmMini_ib = "avmMini_ib"; @@ -279,12 +318,6 @@ class AvmMiniFlavor { Base::avmMini_mem_idx_b = "avmMini_mem_idx_b"; Base::avmMini_mem_idx_c = "avmMini_mem_idx_c"; Base::avmMini_last = "avmMini_last"; - Base::avmMini_m_clk = "avmMini_m_clk"; - Base::avmMini_m_sub_clk = "avmMini_m_sub_clk"; - Base::avmMini_m_addr = "avmMini_m_addr"; - Base::avmMini_m_val = "avmMini_m_val"; - Base::avmMini_m_lastAccess = "avmMini_m_lastAccess"; - Base::avmMini_m_rw = "avmMini_m_rw"; }; }; @@ -298,7 +331,6 @@ class AvmMiniFlavor { { static_cast(transcript); avmMini_clk = verification_key->avmMini_clk; - avmMini_positive = verification_key->avmMini_positive; avmMini_first = verification_key->avmMini_first; } }; @@ -307,6 +339,12 @@ class AvmMiniFlavor { public: uint32_t circuit_size; + Commitment memTrace_m_clk; + Commitment memTrace_m_sub_clk; + Commitment memTrace_m_addr; + Commitment memTrace_m_val; + Commitment memTrace_m_lastAccess; + Commitment memTrace_m_rw; Commitment avmMini_subop; Commitment avmMini_ia; Commitment avmMini_ib; @@ -321,12 +359,6 @@ class AvmMiniFlavor { Commitment avmMini_mem_idx_b; Commitment avmMini_mem_idx_c; Commitment avmMini_last; - Commitment avmMini_m_clk; - Commitment avmMini_m_sub_clk; - Commitment avmMini_m_addr; - Commitment avmMini_m_val; - Commitment avmMini_m_lastAccess; - Commitment avmMini_m_rw; std::vector> sumcheck_univariates; std::array sumcheck_evaluations; @@ -346,6 +378,12 @@ class AvmMiniFlavor { circuit_size = deserialize_from_buffer(proof_data, num_bytes_read); size_t log_n = numeric::get_msb(circuit_size); + memTrace_m_clk = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + memTrace_m_sub_clk = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + memTrace_m_addr = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + memTrace_m_val = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + memTrace_m_lastAccess = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); + memTrace_m_rw = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); avmMini_subop = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); avmMini_ia = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); avmMini_ib = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); @@ -360,12 +398,6 @@ class AvmMiniFlavor { avmMini_mem_idx_b = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); avmMini_mem_idx_c = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); avmMini_last = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - avmMini_m_clk = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - avmMini_m_sub_clk = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - avmMini_m_addr = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - avmMini_m_val = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - avmMini_m_lastAccess = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); - avmMini_m_rw = deserialize_from_buffer(BaseTranscript::proof_data, num_bytes_read); for (size_t i = 0; i < log_n; ++i) { sumcheck_univariates.emplace_back( @@ -389,6 +421,12 @@ class AvmMiniFlavor { serialize_to_buffer(circuit_size, BaseTranscript::proof_data); + serialize_to_buffer(memTrace_m_clk, BaseTranscript::proof_data); + serialize_to_buffer(memTrace_m_sub_clk, BaseTranscript::proof_data); + serialize_to_buffer(memTrace_m_addr, BaseTranscript::proof_data); + serialize_to_buffer(memTrace_m_val, BaseTranscript::proof_data); + serialize_to_buffer(memTrace_m_lastAccess, BaseTranscript::proof_data); + serialize_to_buffer(memTrace_m_rw, BaseTranscript::proof_data); serialize_to_buffer(avmMini_subop, BaseTranscript::proof_data); serialize_to_buffer(avmMini_ia, BaseTranscript::proof_data); serialize_to_buffer(avmMini_ib, BaseTranscript::proof_data); @@ -403,12 +441,6 @@ class AvmMiniFlavor { serialize_to_buffer(avmMini_mem_idx_b, BaseTranscript::proof_data); serialize_to_buffer(avmMini_mem_idx_c, BaseTranscript::proof_data); serialize_to_buffer(avmMini_last, BaseTranscript::proof_data); - serialize_to_buffer(avmMini_m_clk, BaseTranscript::proof_data); - serialize_to_buffer(avmMini_m_sub_clk, BaseTranscript::proof_data); - serialize_to_buffer(avmMini_m_addr, BaseTranscript::proof_data); - serialize_to_buffer(avmMini_m_val, BaseTranscript::proof_data); - serialize_to_buffer(avmMini_m_lastAccess, BaseTranscript::proof_data); - serialize_to_buffer(avmMini_m_rw, BaseTranscript::proof_data); for (size_t i = 0; i < log_n; ++i) { serialize_to_buffer(sumcheck_univariates[i], BaseTranscript::proof_data); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.cpp index cb6e71257603..401ad709c435 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.cpp @@ -1,10 +1,9 @@ #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/proof_system/circuit_builder/circuit_builder_base.hpp" -#include "barretenberg/flavor/generated/AvmMini_flavor.hpp" -#include "barretenberg/relations/generated/AvmMini.hpp" - #include "./AvmMini_helper.hpp" +#include "barretenberg/flavor/generated/AvmMini_flavor.hpp" +#include "barretenberg/relations/generated/AvmMini/avm_mini.hpp" namespace proof_system { @@ -24,13 +23,13 @@ void log_avmMini_trace(std::vector const& trace, size_t beg, size_t end) info("== ROW ", i); info("================================================================================"); - info("m_addr: ", trace.at(i).avmMini_m_addr); - info("m_clk: ", trace.at(i).avmMini_m_clk); - info("m_sub_clk: ", trace.at(i).avmMini_m_sub_clk); - info("m_val: ", trace.at(i).avmMini_m_val); - info("m_lastAccess: ", trace.at(i).avmMini_m_lastAccess); - info("m_rw: ", trace.at(i).avmMini_m_rw); - info("m_val_shift: ", trace.at(i).avmMini_m_val_shift); + info("m_addr: ", trace.at(i).memTrace_m_addr); + info("m_clk: ", trace.at(i).memTrace_m_clk); + info("m_sub_clk: ", trace.at(i).memTrace_m_sub_clk); + info("m_val: ", trace.at(i).memTrace_m_val); + info("m_lastAccess: ", trace.at(i).memTrace_m_lastAccess); + info("m_rw: ", trace.at(i).memTrace_m_rw); + info("m_val_shift: ", trace.at(i).memTrace_m_val_shift); info("first: ", trace.at(i).avmMini_first); info("last: ", trace.at(i).avmMini_last); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.hpp index c84b65b1dc68..491d597fa261 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_helper.hpp @@ -4,13 +4,13 @@ #include "barretenberg/proof_system/circuit_builder/circuit_builder_base.hpp" #include "barretenberg/flavor/generated/AvmMini_flavor.hpp" -#include "barretenberg/relations/generated/AvmMini.hpp" +#include "barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp" namespace proof_system { using Flavor = proof_system::honk::flavor::AvmMiniFlavor; using FF = Flavor::FF; -using Row = proof_system::AvmMini_vm::Row; +using Row = proof_system::AvmMiniFullRow; void log_avmMini_trace(std::vector const& trace, size_t beg, size_t end); diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp index 8e44891850aa..01089a783957 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.cpp @@ -9,8 +9,8 @@ #include #include "./AvmMini_trace.hpp" +#include "./generated/AvmMini_circuit_builder.hpp" -#include "barretenberg/relations/generated/AvmMini.hpp" namespace proof_system { /** @@ -82,10 +82,9 @@ void AvmMiniTraceBuilder::insertInMemTrace(uint32_t m_clk, uint32_t m_sub_clk, u } // Memory operations need to be performed before the addition of the corresponding row in -// mainTrace, otherwise the m_clk value will be wrong. This applies to: -// loadAInMemTrace, loadBInMemTrace, loadCInMemTrace +// ainTrace, otherwise the m_clk value will be wrong.This applies to : loadAInMemTrace, loadBInMemTrace, +// loadCInMemTrace // storeAInMemTrace, storeBInMemTrace, storeCInMemTrace - /** * @brief Add a memory trace entry corresponding to a memory load into the intermediate * register Ia. @@ -420,17 +419,17 @@ std::vector AvmMiniTraceBuilder::finalize() auto const& src = memTrace.at(i); auto& dest = mainTrace.at(i); - dest.avmMini_m_clk = FF(src.m_clk); - dest.avmMini_m_sub_clk = FF(src.m_sub_clk); - dest.avmMini_m_addr = FF(src.m_addr); - dest.avmMini_m_val = src.m_val; - dest.avmMini_m_rw = FF(static_cast(src.m_rw)); + dest.memTrace_m_clk = FF(src.m_clk); + dest.memTrace_m_sub_clk = FF(src.m_sub_clk); + dest.memTrace_m_addr = FF(src.m_addr); + dest.memTrace_m_val = src.m_val; + dest.memTrace_m_rw = FF(static_cast(src.m_rw)); if (i + 1 < memTraceSize) { auto const& next = memTrace.at(i + 1); - dest.avmMini_m_lastAccess = FF(static_cast(src.m_addr != next.m_addr)); + dest.memTrace_m_lastAccess = FF(static_cast(src.m_addr != next.m_addr)); } else { - dest.avmMini_m_lastAccess = FF(1); + dest.memTrace_m_lastAccess = FF(1); } } diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp index b1fc703544ed..781d798cd6e1 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/AvmMini_trace.hpp @@ -3,13 +3,15 @@ #include "barretenberg/common/throw_or_abort.hpp" #include "barretenberg/ecc/curves/bn254/fr.hpp" #include "barretenberg/proof_system/circuit_builder/circuit_builder_base.hpp" +#include "barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp" #include "barretenberg/flavor/generated/AvmMini_flavor.hpp" -#include "barretenberg/relations/generated/AvmMini.hpp" + +#include "barretenberg/relations/generated/AvmMini/avm_mini.hpp" using Flavor = proof_system::honk::flavor::AvmMiniFlavor; using FF = Flavor::FF; -using Row = proof_system::AvmMini_vm::Row; +using Row = proof_system::AvmMiniFullRow; namespace proof_system { diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp index 1bf6093681ea..336331b3e699 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/generated/AvmMini_circuit_builder.hpp @@ -8,24 +8,53 @@ #include "barretenberg/proof_system/circuit_builder/circuit_builder_base.hpp" #include "barretenberg/flavor/generated/AvmMini_flavor.hpp" -#include "barretenberg/relations/generated/AvmMini.hpp" +#include "barretenberg/relations/generated/AvmMini/avm_mini.hpp" +#include "barretenberg/relations/generated/AvmMini/mem_trace.hpp" using namespace barretenberg; namespace proof_system { +template struct AvmMiniFullRow { + FF avmMini_clk{}; + FF avmMini_first{}; + FF memTrace_m_clk{}; + FF memTrace_m_sub_clk{}; + FF memTrace_m_addr{}; + FF memTrace_m_val{}; + FF memTrace_m_lastAccess{}; + FF memTrace_m_rw{}; + FF avmMini_subop{}; + FF avmMini_ia{}; + FF avmMini_ib{}; + FF avmMini_ic{}; + FF avmMini_mem_op_a{}; + FF avmMini_mem_op_b{}; + FF avmMini_mem_op_c{}; + FF avmMini_rwa{}; + FF avmMini_rwb{}; + FF avmMini_rwc{}; + FF avmMini_mem_idx_a{}; + FF avmMini_mem_idx_b{}; + FF avmMini_mem_idx_c{}; + FF avmMini_last{}; + FF memTrace_m_addr_shift{}; + FF memTrace_m_rw_shift{}; + FF memTrace_m_val_shift{}; +}; + class AvmMiniCircuitBuilder { public: using Flavor = proof_system::honk::flavor::AvmMiniFlavor; using FF = Flavor::FF; - using Row = AvmMini_vm::Row; + using Row = AvmMiniFullRow; // TODO: template using Polynomial = Flavor::Polynomial; using AllPolynomials = Flavor::AllPolynomials; - static constexpr size_t num_fixed_columns = 26; - static constexpr size_t num_polys = 23; + static constexpr size_t num_fixed_columns = 25; + static constexpr size_t num_polys = 22; std::vector rows; void set_trace(std::vector&& trace) { rows = std::move(trace); } @@ -42,8 +71,13 @@ class AvmMiniCircuitBuilder { for (size_t i = 0; i < rows.size(); i++) { polys.avmMini_clk[i] = rows[i].avmMini_clk; - polys.avmMini_positive[i] = rows[i].avmMini_positive; polys.avmMini_first[i] = rows[i].avmMini_first; + polys.memTrace_m_clk[i] = rows[i].memTrace_m_clk; + polys.memTrace_m_sub_clk[i] = rows[i].memTrace_m_sub_clk; + polys.memTrace_m_addr[i] = rows[i].memTrace_m_addr; + polys.memTrace_m_val[i] = rows[i].memTrace_m_val; + polys.memTrace_m_lastAccess[i] = rows[i].memTrace_m_lastAccess; + polys.memTrace_m_rw[i] = rows[i].memTrace_m_rw; polys.avmMini_subop[i] = rows[i].avmMini_subop; polys.avmMini_ia[i] = rows[i].avmMini_ia; polys.avmMini_ib[i] = rows[i].avmMini_ib; @@ -58,17 +92,11 @@ class AvmMiniCircuitBuilder { polys.avmMini_mem_idx_b[i] = rows[i].avmMini_mem_idx_b; polys.avmMini_mem_idx_c[i] = rows[i].avmMini_mem_idx_c; polys.avmMini_last[i] = rows[i].avmMini_last; - polys.avmMini_m_clk[i] = rows[i].avmMini_m_clk; - polys.avmMini_m_sub_clk[i] = rows[i].avmMini_m_sub_clk; - polys.avmMini_m_addr[i] = rows[i].avmMini_m_addr; - polys.avmMini_m_val[i] = rows[i].avmMini_m_val; - polys.avmMini_m_lastAccess[i] = rows[i].avmMini_m_lastAccess; - polys.avmMini_m_rw[i] = rows[i].avmMini_m_rw; } - polys.avmMini_m_val_shift = Polynomial(polys.avmMini_m_val.shifted()); - polys.avmMini_m_addr_shift = Polynomial(polys.avmMini_m_addr.shifted()); - polys.avmMini_m_rw_shift = Polynomial(polys.avmMini_m_rw.shifted()); + polys.memTrace_m_addr_shift = Polynomial(polys.memTrace_m_addr.shifted()); + polys.memTrace_m_rw_shift = Polynomial(polys.memTrace_m_rw.shifted()); + polys.memTrace_m_val_shift = Polynomial(polys.memTrace_m_val.shifted()); return polys; } @@ -103,7 +131,14 @@ class AvmMiniCircuitBuilder { return true; }; - return evaluate_relation.template operator()>("AvmMini"); + if (!evaluate_relation.template operator()>("mem_trace")) { + return false; + } + if (!evaluate_relation.template operator()>("avm_mini")) { + return false; + } + + return true; } [[nodiscard]] size_t get_num_gates() const { return rows.size(); } diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini.hpp deleted file mode 100644 index 056d6464cf16..000000000000 --- a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini.hpp +++ /dev/null @@ -1,185 +0,0 @@ - -#pragma once -#include "../relation_parameters.hpp" -#include "../relation_types.hpp" - -namespace proof_system::AvmMini_vm { - -template struct Row { - FF avmMini_clk{}; - FF avmMini_positive{}; - FF avmMini_first{}; - FF avmMini_subop{}; - FF avmMini_ia{}; - FF avmMini_ib{}; - FF avmMini_ic{}; - FF avmMini_mem_op_a{}; - FF avmMini_mem_op_b{}; - FF avmMini_mem_op_c{}; - FF avmMini_rwa{}; - FF avmMini_rwb{}; - FF avmMini_rwc{}; - FF avmMini_mem_idx_a{}; - FF avmMini_mem_idx_b{}; - FF avmMini_mem_idx_c{}; - FF avmMini_last{}; - FF avmMini_m_clk{}; - FF avmMini_m_sub_clk{}; - FF avmMini_m_addr{}; - FF avmMini_m_val{}; - FF avmMini_m_lastAccess{}; - FF avmMini_m_rw{}; - FF avmMini_m_val_shift{}; - FF avmMini_m_addr_shift{}; - FF avmMini_m_rw_shift{}; -}; - -#define DECLARE_VIEWS(index) \ - using View = typename std::tuple_element::type; \ - [[maybe_unused]] auto avmMini_clk = View(new_term.avmMini_clk); \ - [[maybe_unused]] auto avmMini_positive = View(new_term.avmMini_positive); \ - [[maybe_unused]] auto avmMini_first = View(new_term.avmMini_first); \ - [[maybe_unused]] auto avmMini_subop = View(new_term.avmMini_subop); \ - [[maybe_unused]] auto avmMini_ia = View(new_term.avmMini_ia); \ - [[maybe_unused]] auto avmMini_ib = View(new_term.avmMini_ib); \ - [[maybe_unused]] auto avmMini_ic = View(new_term.avmMini_ic); \ - [[maybe_unused]] auto avmMini_mem_op_a = View(new_term.avmMini_mem_op_a); \ - [[maybe_unused]] auto avmMini_mem_op_b = View(new_term.avmMini_mem_op_b); \ - [[maybe_unused]] auto avmMini_mem_op_c = View(new_term.avmMini_mem_op_c); \ - [[maybe_unused]] auto avmMini_rwa = View(new_term.avmMini_rwa); \ - [[maybe_unused]] auto avmMini_rwb = View(new_term.avmMini_rwb); \ - [[maybe_unused]] auto avmMini_rwc = View(new_term.avmMini_rwc); \ - [[maybe_unused]] auto avmMini_mem_idx_a = View(new_term.avmMini_mem_idx_a); \ - [[maybe_unused]] auto avmMini_mem_idx_b = View(new_term.avmMini_mem_idx_b); \ - [[maybe_unused]] auto avmMini_mem_idx_c = View(new_term.avmMini_mem_idx_c); \ - [[maybe_unused]] auto avmMini_last = View(new_term.avmMini_last); \ - [[maybe_unused]] auto avmMini_m_clk = View(new_term.avmMini_m_clk); \ - [[maybe_unused]] auto avmMini_m_sub_clk = View(new_term.avmMini_m_sub_clk); \ - [[maybe_unused]] auto avmMini_m_addr = View(new_term.avmMini_m_addr); \ - [[maybe_unused]] auto avmMini_m_val = View(new_term.avmMini_m_val); \ - [[maybe_unused]] auto avmMini_m_lastAccess = View(new_term.avmMini_m_lastAccess); \ - [[maybe_unused]] auto avmMini_m_rw = View(new_term.avmMini_m_rw); \ - [[maybe_unused]] auto avmMini_m_val_shift = View(new_term.avmMini_m_val_shift); \ - [[maybe_unused]] auto avmMini_m_addr_shift = View(new_term.avmMini_m_addr_shift); \ - [[maybe_unused]] auto avmMini_m_rw_shift = View(new_term.avmMini_m_rw_shift); - -template class AvmMiniImpl { - public: - using FF = FF_; - - static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - }; - - template - void static accumulate(ContainerOverSubrelations& evals, - const AllEntities& new_term, - [[maybe_unused]] const RelationParameters&, - [[maybe_unused]] const FF& scaling_factor) - { - - // Contribution 0 - { - DECLARE_VIEWS(0); - - auto tmp = (avmMini_subop * (-avmMini_subop + FF(1))); - tmp *= scaling_factor; - std::get<0>(evals) += tmp; - } - // Contribution 1 - { - DECLARE_VIEWS(1); - - auto tmp = (avmMini_mem_op_a * (-avmMini_mem_op_a + FF(1))); - tmp *= scaling_factor; - std::get<1>(evals) += tmp; - } - // Contribution 2 - { - DECLARE_VIEWS(2); - - auto tmp = (avmMini_mem_op_b * (-avmMini_mem_op_b + FF(1))); - tmp *= scaling_factor; - std::get<2>(evals) += tmp; - } - // Contribution 3 - { - DECLARE_VIEWS(3); - - auto tmp = (avmMini_mem_op_c * (-avmMini_mem_op_c + FF(1))); - tmp *= scaling_factor; - std::get<3>(evals) += tmp; - } - // Contribution 4 - { - DECLARE_VIEWS(4); - - auto tmp = (avmMini_rwa * (-avmMini_rwa + FF(1))); - tmp *= scaling_factor; - std::get<4>(evals) += tmp; - } - // Contribution 5 - { - DECLARE_VIEWS(5); - - auto tmp = (avmMini_rwb * (-avmMini_rwb + FF(1))); - tmp *= scaling_factor; - std::get<5>(evals) += tmp; - } - // Contribution 6 - { - DECLARE_VIEWS(6); - - auto tmp = (avmMini_rwc * (-avmMini_rwc + FF(1))); - tmp *= scaling_factor; - std::get<6>(evals) += tmp; - } - // Contribution 7 - { - DECLARE_VIEWS(7); - - auto tmp = (avmMini_subop * ((avmMini_ia + avmMini_ib) - avmMini_ic)); - tmp *= scaling_factor; - std::get<7>(evals) += tmp; - } - // Contribution 8 - { - DECLARE_VIEWS(8); - - auto tmp = (avmMini_m_lastAccess * (-avmMini_m_lastAccess + FF(1))); - tmp *= scaling_factor; - std::get<8>(evals) += tmp; - } - // Contribution 9 - { - DECLARE_VIEWS(9); - - auto tmp = (avmMini_m_rw * (-avmMini_m_rw + FF(1))); - tmp *= scaling_factor; - std::get<9>(evals) += tmp; - } - // Contribution 10 - { - DECLARE_VIEWS(10); - - auto tmp = (((-avmMini_first + FF(1)) * (-avmMini_m_lastAccess + FF(1))) * - (avmMini_m_addr_shift - avmMini_m_addr)); - tmp *= scaling_factor; - std::get<10>(evals) += tmp; - } - // Contribution 11 - { - DECLARE_VIEWS(11); - - auto tmp = (((((-avmMini_first + FF(1)) * (-avmMini_last + FF(1))) * (-avmMini_m_lastAccess + FF(1))) * - (-avmMini_m_rw_shift + FF(1))) * - (avmMini_m_val_shift - avmMini_m_val)); - tmp *= scaling_factor; - std::get<11>(evals) += tmp; - } - } -}; - -template using AvmMini = Relation>; - -} // namespace proof_system::AvmMini_vm \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp new file mode 100644 index 000000000000..14909b98be35 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/avm_mini.hpp @@ -0,0 +1,106 @@ + +#pragma once +#include "../../relation_parameters.hpp" +#include "../../relation_types.hpp" +#include "./declare_views.hpp" + +namespace proof_system::AvmMini_vm { + +template struct Avm_miniRow { + FF avmMini_rwc{}; + FF avmMini_rwa{}; + FF avmMini_mem_op_b{}; + FF avmMini_ib{}; + FF avmMini_rwb{}; + FF avmMini_subop{}; + FF avmMini_mem_op_c{}; + FF avmMini_ia{}; + FF avmMini_ic{}; + FF avmMini_mem_op_a{}; +}; + +template class avm_miniImpl { + public: + using FF = FF_; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, 3, 3, 3, 3, 3, 3, 3, + }; + + template + void static accumulate(ContainerOverSubrelations& evals, + const AllEntities& new_term, + [[maybe_unused]] const RelationParameters&, + [[maybe_unused]] const FF& scaling_factor) + { + + // Contribution 0 + { + DECLARE_VIEWS(0); + + auto tmp = (avmMini_subop * (-avmMini_subop + FF(1))); + tmp *= scaling_factor; + std::get<0>(evals) += tmp; + } + // Contribution 1 + { + DECLARE_VIEWS(1); + + auto tmp = (avmMini_mem_op_a * (-avmMini_mem_op_a + FF(1))); + tmp *= scaling_factor; + std::get<1>(evals) += tmp; + } + // Contribution 2 + { + DECLARE_VIEWS(2); + + auto tmp = (avmMini_mem_op_b * (-avmMini_mem_op_b + FF(1))); + tmp *= scaling_factor; + std::get<2>(evals) += tmp; + } + // Contribution 3 + { + DECLARE_VIEWS(3); + + auto tmp = (avmMini_mem_op_c * (-avmMini_mem_op_c + FF(1))); + tmp *= scaling_factor; + std::get<3>(evals) += tmp; + } + // Contribution 4 + { + DECLARE_VIEWS(4); + + auto tmp = (avmMini_rwa * (-avmMini_rwa + FF(1))); + tmp *= scaling_factor; + std::get<4>(evals) += tmp; + } + // Contribution 5 + { + DECLARE_VIEWS(5); + + auto tmp = (avmMini_rwb * (-avmMini_rwb + FF(1))); + tmp *= scaling_factor; + std::get<5>(evals) += tmp; + } + // Contribution 6 + { + DECLARE_VIEWS(6); + + auto tmp = (avmMini_rwc * (-avmMini_rwc + FF(1))); + tmp *= scaling_factor; + std::get<6>(evals) += tmp; + } + // Contribution 7 + { + DECLARE_VIEWS(7); + + auto tmp = (avmMini_subop * ((avmMini_ia + avmMini_ib) - avmMini_ic)); + tmp *= scaling_factor; + std::get<7>(evals) += tmp; + } + } +}; + +template using avm_mini = Relation>; + +} // namespace proof_system::AvmMini_vm \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp new file mode 100644 index 000000000000..cad793a7b5f4 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/declare_views.hpp @@ -0,0 +1,29 @@ + +#define DECLARE_VIEWS(index) \ + using Accumulator = typename std::tuple_element::type; \ + using View = typename Accumulator::View; \ + [[maybe_unused]] auto avmMini_clk = View(new_term.avmMini_clk); \ + [[maybe_unused]] auto avmMini_first = View(new_term.avmMini_first); \ + [[maybe_unused]] auto memTrace_m_clk = View(new_term.memTrace_m_clk); \ + [[maybe_unused]] auto memTrace_m_sub_clk = View(new_term.memTrace_m_sub_clk); \ + [[maybe_unused]] auto memTrace_m_addr = View(new_term.memTrace_m_addr); \ + [[maybe_unused]] auto memTrace_m_val = View(new_term.memTrace_m_val); \ + [[maybe_unused]] auto memTrace_m_lastAccess = View(new_term.memTrace_m_lastAccess); \ + [[maybe_unused]] auto memTrace_m_rw = View(new_term.memTrace_m_rw); \ + [[maybe_unused]] auto avmMini_subop = View(new_term.avmMini_subop); \ + [[maybe_unused]] auto avmMini_ia = View(new_term.avmMini_ia); \ + [[maybe_unused]] auto avmMini_ib = View(new_term.avmMini_ib); \ + [[maybe_unused]] auto avmMini_ic = View(new_term.avmMini_ic); \ + [[maybe_unused]] auto avmMini_mem_op_a = View(new_term.avmMini_mem_op_a); \ + [[maybe_unused]] auto avmMini_mem_op_b = View(new_term.avmMini_mem_op_b); \ + [[maybe_unused]] auto avmMini_mem_op_c = View(new_term.avmMini_mem_op_c); \ + [[maybe_unused]] auto avmMini_rwa = View(new_term.avmMini_rwa); \ + [[maybe_unused]] auto avmMini_rwb = View(new_term.avmMini_rwb); \ + [[maybe_unused]] auto avmMini_rwc = View(new_term.avmMini_rwc); \ + [[maybe_unused]] auto avmMini_mem_idx_a = View(new_term.avmMini_mem_idx_a); \ + [[maybe_unused]] auto avmMini_mem_idx_b = View(new_term.avmMini_mem_idx_b); \ + [[maybe_unused]] auto avmMini_mem_idx_c = View(new_term.avmMini_mem_idx_c); \ + [[maybe_unused]] auto avmMini_last = View(new_term.avmMini_last); \ + [[maybe_unused]] auto memTrace_m_addr_shift = View(new_term.memTrace_m_addr_shift); \ + [[maybe_unused]] auto memTrace_m_rw_shift = View(new_term.memTrace_m_rw_shift); \ + [[maybe_unused]] auto memTrace_m_val_shift = View(new_term.memTrace_m_val_shift); diff --git a/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp new file mode 100644 index 000000000000..2a7960abd725 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/relations/generated/AvmMini/mem_trace.hpp @@ -0,0 +1,79 @@ + +#pragma once +#include "../../relation_parameters.hpp" +#include "../../relation_types.hpp" +#include "./declare_views.hpp" + +namespace proof_system::AvmMini_vm { + +template struct Mem_traceRow { + FF avmMini_last{}; + FF memTrace_m_addr{}; + FF memTrace_m_val{}; + FF avmMini_first{}; + FF memTrace_m_addr_shift{}; + FF memTrace_m_rw{}; + FF memTrace_m_rw_shift{}; + FF memTrace_m_val_shift{}; + FF memTrace_m_lastAccess{}; +}; + +template class mem_traceImpl { + public: + using FF = FF_; + + static constexpr std::array SUBRELATION_PARTIAL_LENGTHS{ + 3, + 3, + 4, + 6, + }; + + template + void static accumulate(ContainerOverSubrelations& evals, + const AllEntities& new_term, + [[maybe_unused]] const RelationParameters&, + [[maybe_unused]] const FF& scaling_factor) + { + + // Contribution 0 + { + DECLARE_VIEWS(0); + + auto tmp = (memTrace_m_lastAccess * (-memTrace_m_lastAccess + FF(1))); + tmp *= scaling_factor; + std::get<0>(evals) += tmp; + } + // Contribution 1 + { + DECLARE_VIEWS(1); + + auto tmp = (memTrace_m_rw * (-memTrace_m_rw + FF(1))); + tmp *= scaling_factor; + std::get<1>(evals) += tmp; + } + // Contribution 2 + { + DECLARE_VIEWS(2); + + auto tmp = (((-avmMini_first + FF(1)) * (-memTrace_m_lastAccess + FF(1))) * + (memTrace_m_addr_shift - memTrace_m_addr)); + tmp *= scaling_factor; + std::get<2>(evals) += tmp; + } + // Contribution 3 + { + DECLARE_VIEWS(3); + + auto tmp = (((((-avmMini_first + FF(1)) * (-avmMini_last + FF(1))) * (-memTrace_m_lastAccess + FF(1))) * + (-memTrace_m_rw_shift + FF(1))) * + (memTrace_m_val_shift - memTrace_m_val)); + tmp *= scaling_factor; + std::get<3>(evals) += tmp; + } + } +}; + +template using mem_trace = Relation>; + +} // namespace proof_system::AvmMini_vm \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_composer.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_composer.cpp index b0d8a1567112..6b6bb8f5550e 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_composer.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_composer.cpp @@ -18,8 +18,13 @@ void AvmMiniComposer::compute_witness(CircuitConstructor& circuit) auto polynomials = circuit.compute_polynomials(); proving_key->avmMini_clk = polynomials.avmMini_clk; - proving_key->avmMini_positive = polynomials.avmMini_positive; proving_key->avmMini_first = polynomials.avmMini_first; + proving_key->memTrace_m_clk = polynomials.memTrace_m_clk; + proving_key->memTrace_m_sub_clk = polynomials.memTrace_m_sub_clk; + proving_key->memTrace_m_addr = polynomials.memTrace_m_addr; + proving_key->memTrace_m_val = polynomials.memTrace_m_val; + proving_key->memTrace_m_lastAccess = polynomials.memTrace_m_lastAccess; + proving_key->memTrace_m_rw = polynomials.memTrace_m_rw; proving_key->avmMini_subop = polynomials.avmMini_subop; proving_key->avmMini_ia = polynomials.avmMini_ia; proving_key->avmMini_ib = polynomials.avmMini_ib; @@ -34,12 +39,6 @@ void AvmMiniComposer::compute_witness(CircuitConstructor& circuit) proving_key->avmMini_mem_idx_b = polynomials.avmMini_mem_idx_b; proving_key->avmMini_mem_idx_c = polynomials.avmMini_mem_idx_c; proving_key->avmMini_last = polynomials.avmMini_last; - proving_key->avmMini_m_clk = polynomials.avmMini_m_clk; - proving_key->avmMini_m_sub_clk = polynomials.avmMini_m_sub_clk; - proving_key->avmMini_m_addr = polynomials.avmMini_m_addr; - proving_key->avmMini_m_val = polynomials.avmMini_m_val; - proving_key->avmMini_m_lastAccess = polynomials.avmMini_m_lastAccess; - proving_key->avmMini_m_rw = polynomials.avmMini_m_rw; computed_witness = true; } diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp index 730aab4ba4f3..30aa284c9485 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_prover.cpp @@ -32,8 +32,13 @@ AvmMiniProver::AvmMiniProver(std::shared_ptr input_key, // TODO: take every polynomial and assign it to the key!! prover_polynomials.avmMini_clk = key->avmMini_clk; - prover_polynomials.avmMini_positive = key->avmMini_positive; prover_polynomials.avmMini_first = key->avmMini_first; + prover_polynomials.memTrace_m_clk = key->memTrace_m_clk; + prover_polynomials.memTrace_m_sub_clk = key->memTrace_m_sub_clk; + prover_polynomials.memTrace_m_addr = key->memTrace_m_addr; + prover_polynomials.memTrace_m_val = key->memTrace_m_val; + prover_polynomials.memTrace_m_lastAccess = key->memTrace_m_lastAccess; + prover_polynomials.memTrace_m_rw = key->memTrace_m_rw; prover_polynomials.avmMini_subop = key->avmMini_subop; prover_polynomials.avmMini_ia = key->avmMini_ia; prover_polynomials.avmMini_ib = key->avmMini_ib; @@ -48,21 +53,15 @@ AvmMiniProver::AvmMiniProver(std::shared_ptr input_key, prover_polynomials.avmMini_mem_idx_b = key->avmMini_mem_idx_b; prover_polynomials.avmMini_mem_idx_c = key->avmMini_mem_idx_c; prover_polynomials.avmMini_last = key->avmMini_last; - prover_polynomials.avmMini_m_clk = key->avmMini_m_clk; - prover_polynomials.avmMini_m_sub_clk = key->avmMini_m_sub_clk; - prover_polynomials.avmMini_m_addr = key->avmMini_m_addr; - prover_polynomials.avmMini_m_val = key->avmMini_m_val; - prover_polynomials.avmMini_m_lastAccess = key->avmMini_m_lastAccess; - prover_polynomials.avmMini_m_rw = key->avmMini_m_rw; - prover_polynomials.avmMini_m_val = key->avmMini_m_val; - prover_polynomials.avmMini_m_val_shift = key->avmMini_m_val.shifted(); + prover_polynomials.memTrace_m_addr = key->memTrace_m_addr; + prover_polynomials.memTrace_m_addr_shift = key->memTrace_m_addr.shifted(); - prover_polynomials.avmMini_m_addr = key->avmMini_m_addr; - prover_polynomials.avmMini_m_addr_shift = key->avmMini_m_addr.shifted(); + prover_polynomials.memTrace_m_rw = key->memTrace_m_rw; + prover_polynomials.memTrace_m_rw_shift = key->memTrace_m_rw.shifted(); - prover_polynomials.avmMini_m_rw = key->avmMini_m_rw; - prover_polynomials.avmMini_m_rw_shift = key->avmMini_m_rw.shifted(); + prover_polynomials.memTrace_m_val = key->memTrace_m_val; + prover_polynomials.memTrace_m_val_shift = key->memTrace_m_val.shifted(); // prover_polynomials.lookup_inverses = key->lookup_inverses; // key->z_perm = Polynomial(key->circuit_size); diff --git a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp index 575d55bd00c8..b5983e59892d 100644 --- a/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp +++ b/barretenberg/cpp/src/barretenberg/vm/generated/AvmMini_verifier.cpp @@ -55,6 +55,15 @@ bool AvmMiniVerifier::verify_proof(const plonk::proof& proof) } // Get commitments to VM wires + commitments.memTrace_m_clk = transcript.template receive_from_prover(commitment_labels.memTrace_m_clk); + commitments.memTrace_m_sub_clk = + transcript.template receive_from_prover(commitment_labels.memTrace_m_sub_clk); + commitments.memTrace_m_addr = + transcript.template receive_from_prover(commitment_labels.memTrace_m_addr); + commitments.memTrace_m_val = transcript.template receive_from_prover(commitment_labels.memTrace_m_val); + commitments.memTrace_m_lastAccess = + transcript.template receive_from_prover(commitment_labels.memTrace_m_lastAccess); + commitments.memTrace_m_rw = transcript.template receive_from_prover(commitment_labels.memTrace_m_rw); commitments.avmMini_subop = transcript.template receive_from_prover(commitment_labels.avmMini_subop); commitments.avmMini_ia = transcript.template receive_from_prover(commitment_labels.avmMini_ia); commitments.avmMini_ib = transcript.template receive_from_prover(commitment_labels.avmMini_ib); @@ -75,14 +84,6 @@ bool AvmMiniVerifier::verify_proof(const plonk::proof& proof) commitments.avmMini_mem_idx_c = transcript.template receive_from_prover(commitment_labels.avmMini_mem_idx_c); commitments.avmMini_last = transcript.template receive_from_prover(commitment_labels.avmMini_last); - commitments.avmMini_m_clk = transcript.template receive_from_prover(commitment_labels.avmMini_m_clk); - commitments.avmMini_m_sub_clk = - transcript.template receive_from_prover(commitment_labels.avmMini_m_sub_clk); - commitments.avmMini_m_addr = transcript.template receive_from_prover(commitment_labels.avmMini_m_addr); - commitments.avmMini_m_val = transcript.template receive_from_prover(commitment_labels.avmMini_m_val); - commitments.avmMini_m_lastAccess = - transcript.template receive_from_prover(commitment_labels.avmMini_m_lastAccess); - commitments.avmMini_m_rw = transcript.template receive_from_prover(commitment_labels.avmMini_m_rw); // Execute Sumcheck Verifier auto sumcheck = SumcheckVerifier(circuit_size); From 3ebd2f25646c7db170d22c62f41888d0c417d644 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Thu, 30 Nov 2023 14:54:55 -0300 Subject: [PATCH 10/37] chore: Add yellow paper build check to CI (#3490) Adds a step to the CI to build the yellow paper, in order to catch any build issues in our PRs. --- .circleci/config.yml | 14 ++++++++++++++ build_manifest.yml | 5 +++++ yellow-paper/Dockerfile | 4 ++++ 3 files changed, 23 insertions(+) create mode 100644 yellow-paper/Dockerfile diff --git a/.circleci/config.yml b/.circleci/config.yml index 06d72664280a..6a9bfbae5b97 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -897,6 +897,17 @@ jobs: echo "Skipping doc deploy (not on master)." fi + yellow-paper: + machine: + image: ubuntu-2204:2023.07.2 + resource_class: large + steps: + - *checkout + - *setup_env + - run: + name: "Build yellow paper" + command: build yellow-paper + e2e-join: docker: - image: cimg/base:2023.09 @@ -1057,6 +1068,8 @@ workflows: - mainnet-fork: *defaults + - yellow-paper: *defaults + # Yarn Project - yarn-project-base: requires: @@ -1175,6 +1188,7 @@ workflows: - guides-dapp-testing - guides-sample-dapp - guides-up-quick-start + - yellow-paper <<: *defaults # Benchmark jobs. diff --git a/build_manifest.yml b/build_manifest.yml index 09c96546ecb0..73c33d472de1 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -170,3 +170,8 @@ docs: - ^.*.nr$ dependencies: - yarn-project + +yellow-paper: + buildDir: yellow-paper + rebuildPatterns: + - ^yellow-paper/ \ No newline at end of file diff --git a/yellow-paper/Dockerfile b/yellow-paper/Dockerfile new file mode 100644 index 000000000000..1d9939128e93 --- /dev/null +++ b/yellow-paper/Dockerfile @@ -0,0 +1,4 @@ +FROM node:18-alpine +WORKDIR /usr/src +COPY . . +RUN yarn && yarn build --no-minify \ No newline at end of file From 8ff378005f78126260cb0950a8167ec40efd14aa Mon Sep 17 00:00:00 2001 From: Zachary James Williamson Date: Thu, 30 Nov 2023 18:05:19 +0000 Subject: [PATCH 11/37] chore: (yellow paper) public-vm section of yellow paper (#3493) Added in sections that describe the state model, note tagging and bytecode validation # Checklist: Remove the checklist to signal you've completed it. Enable auto-merge if the PR is ready to merge. - [ ] If the pull request requires a cryptography review (e.g. cryptographic algorithm implementations) I have added the 'crypto' tag. - [ ] I have reviewed my diff in github, line by line and removed unexpected formatting changes, testing logs, or commented-out code. - [ ] Every change is related to the PR description. - [ ] I have [linked](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) this pull request to relevant issues (if any exist). --- yellow-paper/docs/public-vm/alu.md | 35 ++++ .../public-vm/bytecode-validation-circuit.md | 190 ++++++++++++++++++ yellow-paper/docs/public-vm/control-flow.md | 32 +++ .../docs/public-vm/gen/images/alu/alu.png | Bin 0 -> 476263 bytes .../images/control-flow/avm-control-flow.png | Bin 0 -> 569552 bytes .../gen/images/state-model/memory.png | Bin 0 -> 43597 bytes yellow-paper/docs/public-vm/state-model.md | 105 ++++++++++ yellow-paper/docs/public-vm/tagged-memory.md | 60 ++++++ 8 files changed, 422 insertions(+) create mode 100644 yellow-paper/docs/public-vm/alu.md create mode 100644 yellow-paper/docs/public-vm/bytecode-validation-circuit.md create mode 100644 yellow-paper/docs/public-vm/control-flow.md create mode 100644 yellow-paper/docs/public-vm/gen/images/alu/alu.png create mode 100644 yellow-paper/docs/public-vm/gen/images/control-flow/avm-control-flow.png create mode 100644 yellow-paper/docs/public-vm/gen/images/state-model/memory.png create mode 100644 yellow-paper/docs/public-vm/state-model.md create mode 100644 yellow-paper/docs/public-vm/tagged-memory.md diff --git a/yellow-paper/docs/public-vm/alu.md b/yellow-paper/docs/public-vm/alu.md new file mode 100644 index 000000000000..bd83dde6a234 --- /dev/null +++ b/yellow-paper/docs/public-vm/alu.md @@ -0,0 +1,35 @@ +# Algebraic Logic Unit + +The algebraic logic unit performs operations analogous to an arithmetic unit in a CPU. + +This component of the VM circuit evaluates both base-2 arithmetic operations and prime-field operation. It takes its input/output from the intermediate registers in the state controller. + +The following block diagram maps out an draft of the internal components of the "ALU" + +![](./gen/images/alu/alu.png) + +Notes: + +For logic operations (e.g. AND/OR) we use lookup tables. The max. size of each lookup table cannot grow too large as the Prover pays a constant cost linear with the size of the lookup table. + +To this end we use lookup tables for logic operations that take _8-bit input operands_ for a total table size of 2^16. + +i.e. the table contains the output for every possible 8-bit combination of 2 input operands. + +#### Slice registers + +We need to slice our inputs into 8-bit chunks for logic operations, in order to index the lookup tables. + +As a simplification, we can say that _any_ operation that requires range-constraints will split the input operands into 8-bit slices, as we can then apply consistent range-checking logic. + +#### Carry flag + +Used to test for overflows. If we want the high-level instruction set to have "add with carry" we need to expose the carry flag to the state controller. + +## Example operation: 32-bit ADD(a, b, c) + +Assume we start with `a` in intermediate register `R1`, `b` in intermediate register `R2`, and `c` in intermediate register `R3` + +1. Store the first 32 bits of `a + b` in slice registers `s1, s2, s3, s4`, with the carry bit in `carry` +2. Validate $a + b = s_1 + 2^8s_2 + 2^{16}s_3 + 2^{24}s_4 + 2^{32}\text{carry}$ +3. Validate $c = s_1 + 2^8s_2 + 2^{16}s_3 + 2^{24}s_4$ diff --git a/yellow-paper/docs/public-vm/bytecode-validation-circuit.md b/yellow-paper/docs/public-vm/bytecode-validation-circuit.md new file mode 100644 index 000000000000..ccdd88cadc5b --- /dev/null +++ b/yellow-paper/docs/public-vm/bytecode-validation-circuit.md @@ -0,0 +1,190 @@ +# Bytecode Validation Circuit + +Goal: Validate that a polynomial commitment to AVM program opcodes maps to the bytecode representation of an AVM program of maximum size $n$. + +# Definitions - Curves and Fields + +The bytecode validation circuit is implemented over the BN254 elliptic curve with group elements defined via $\mathbb{G}_{bn254}$. + +The field $\mathbb{F}$ represents the finite field whose characteristic equals the number of points on the BN254 curve. + +# Bytecode representation + +Each opcode in the AVM can be described by an integer in the range $[0, \ldots, 256^{31}]$ (i.e. 31 bytes of data). All opcodes excluding `SET` require much less data than 31 bytes. + +In the AVM circuit architecture, multiple columns are used to define a VM operation. These columns describe the following quantities: + +1. the opcode to be executed (1 byte of data) +2. three parameter columns that define either literal values or memory indexes +3. three "flag" columns that define metadata associated with each parameter (e.g. whether the parameter a should be interpreted as a literal value or a memory index, or an indirect memory index) + +To both minimize the amount of information used to _define_ a given AVM program, the AVM posesses an additional column that describes the _packed_ opcode. i.e. the integer concatenation of all 6 of the above column values. We define this column via the vector of field elements $\mathbf{op} \in \mathbb{F}^n$ (where $n$ is the number of opcodes in the program). $\mathbf{op}$ is defined as the _column representation_ of an AVM program. + +## Packed bytecode representation + +When _broadcasting_ the data for AVM programs, we desire an encoding that minimizes the raw number of bytes broadcast, we call this the _packed representation_ of the program. + +The number of bytes required to represent an element in $\mathbf{op}$ in the AVM can be derived from the value of the 1st byte (e.g `ADD` requires 7 bytes of data - the ADD opcode (1 byte) and three memory indices (each of size 2 bytes)). + +See (ref: TODO!) for a table that describes the amount of data required for each opcode. + +Each field element in a BN254 circuit can represent _31_ bytes of bytecode data. The packed representation of an AVM program $\mathbf{b} \in \mathbb{F}^n$ is defined as the concatenation of $\mathbf{op}$ into 31-byte chunks, represented as field elements. + +There exists a mapping function $g$ that, given the packed representation $\mathbf{b}$, will produce the column representation $\mathbf{op}$. + +$$ +g(\mathbf{b}) = \mathbf{op} +$$ + +A full description of $g$ is provided [further down in this document](#Definition-of-mapping-function-g). + +## Committed representation + +The committed representation of an AVM program is an elliptic curve polynomial commitment $[P] \in \mathbb{G}_{bn254}$, created via the KZG polynomial commitment scheme (ref). + +$[P]$ is a commitment to $P(X) \in \mathbb{F}[X]^n$ where $P(X) = \sum_{i=0}^{n-1} op_i X^i$ + +# Bytecode validation logic + +Given inputs $\mathbf{b} \in \mathbb{F}^n$ and $[P] \in \mathbb{G}_{bn254}$, we must validate that $[P] = \text{commit}_{KZG}(g(\mathbf{b}))$. + +This requires the following _high level_ steps: + +1. For all $i \in [0, \ldots, n - 1]$, validate that $b_i < 256^{31} - 1$ +2. Compute $\mathbf{op} = g(\mathbf{b})$ +3. Perform a _polynomial consistency check_ between $\mathbb{op}$ and $[P]$ + +# Polynomial Consistency Check + +> The most straightforward way of validating $\mathbb{op}, [P]$ would be to directly construct $[P]$ from $\mathbb{op}$. +> We do not do this, as this would require a large multiscalar multiplication over the BN254 curve. This could only be performed efficiently over a Grumpkin SNARK circuit, which would add downstream complexity to the Aztec architecture (currently the only Grumpkin proofs being accumulated are elliptic-curve-virtual-machine circuits). The rollup circuit architecture already supports efficient recursive aggregation of BN254 proofs - the desire is for the bytecode validation circuit to be a canonical Honk SNARK over the BN254 field. + +To perform a polynomial consistency check between $\mathbb{op}$ and $[P]$, we perform the following: + +1. Generate a challenge $z \in \mathbb{F}$ by computing the Poseidon hash of $H(op_0, \ldots, op_{n-1}, [P])$ +2. Compute $\sum_{i=0}^{n-1} op_i z^i = r \in \mathbb{F}$ +3. Validate via a KZG opening proof that $[P]$ commits to a polynomial $P(X)$ such that $P(z) = r$ + +In the same manner that Honk pairings can be deferred via aggregating pairing inputs into an accumulator, the pairing required to validate the KZG opening proof can also be deferred. + +## Evaluating the polynomial consistency check within a circuit + +The direct computation of $r = \sum_{i=0}^{n-1} op_i z^i$ is trivial as the field is native to a BN254 SNARK circuit, and will require approx. 2 constraints per opcode. + +Validating a KZG opening proof will require approx. 3 non-native elliptic curve scalar multiplications, which will have a cost of approx. 30,000 constraints if using `stdlib::biggroup` from the PLONK standard library. + +The major cost of the consistency check is the Poseidon hash of the packed bytecode vector $\mathbb{b}$ and the commitment $[P]$ - this will incur approx. 22 constraints per element in $\mathbb{b}$ + +# Definition of mapping function $g$ + +The following is a pseudocode description of $g$, which can efficiently be described in a Honk circuit (i.e. no branches). + +We define a function `slice(element, idx, length)`. `element` is a field element interpreted as a length-31 byte array. `slice` computes the byte array `element[idx] : element[idx + length]`, converts into a field element and returns it. + +We define a size-256 lookup table `c` that maps an avm instruction byte to the byte length required to represent its respective opcode. + +``` +g(b) { + let i := 0; // index into bytecode array `b` + let j := 0; // byte offset of current bytecode element + let op := []; // vector of opcode values we need to populate + for k in [0, n]: + { + let f := b[i]; + let instruction_byte := f.slice(j, 1); + let opcode_length := c[instruction_byte]; + let bytes_remaining_in_f := 30 - j; + let op_split := opcode_length > bytes_remaining_in_f; + let bytes_from_f := op_split ? bytes_remaining_in_f : opcode_length; + let op_hi := f.slice(j, bytes_from_f); + + let f' := b[i+1]; + let bytes_from_f' := opcode_length - bytes_from_f; + let op_lo := f'.slice(0, bytes_in_f'); + + op[k] := op_lo + (op_hi << (bytes_in_f' * 8)); + i := i + op_split; + j := op_split ? bytes_in_f' : j + opcode_length; + } + return op; +} +``` + +Pseudocode definition of `slice` function constraints: + +We define `pow(x)` to be a size-31 lookup table that maps an input $x \in [0, \ldots, 31]$ into the value $2^{8x}$ + +We require the Prover has computed witness field elements `f_lo`, `f_hi`, `result` that satisfy the following constraints: + +``` +slice(f, index, length) +{ + assert(f_hi < pow(index)); + assert(f_lo < pow(31 - index - length)); + assert(result < pow(length)); + assert(f == f_lo + result * pow(31 - index - length) + f_hi * pow(31 - index)); + return result; +} +``` + +## Evaluating `g` within a Honk circuit + +The `g` function requires the contents of $\mathbb{b}$ be present via a lookup table. We can achieve this by instantiating elements of $\mathbb{b}$ via the ROM abstraction present in the Plonk standard library (table initialisation costs 2 constraints per element, table reads cost 2 constraints per element) + +We can instantiate tables `c` , `pow` as lookup tables via the same mechanism. + +The `slice` function requires 3 variable-length range checks. In Honk circuits we only can support fixed-length range checks. + +The following pseudocode defines how a variable-length range check can be composed of fixed-length range checks. Here we assume we have previously constrained all inputs to be less than $2^{248} - 1$ + +``` +less_than(a, b) { + // this block is not constrained and defines witness gneeration + let a_lo := a & (2^{124} - 1) + let b_lo := b & (2^{124} - 1) + let a_hi := (a >> 124) + let b_hi := (b >> 124) + let borrow := b_lo < a_lo + let r_lo := b_lo - a_lo + borrow*2^124 + let r_hi := b_hi - a_hi - borrow + + // this block defines constraints + assert(a_lo < 2^124) + assert(a_hi < 2^124) + assert(b_lo < 2^124) + assert(b_hi < 2^124) + assert(r_lo < 2^124) + assert(r_hi < 2^124) + assert(borrow*borrow - borrow = 0) // bool check + assert(a_lo + 2^{124}a_hi = a) + assert(b_lo + 2^{124}b_hi = b) + assert(r_lo = b_lo - a_lo + borrow*2^124) + assert(r_hi = b_hi - a_hi - borrow) +} +``` + +Each `slice` call requires three `less_than` calls, and each iteration of `g` requires 3 `slice` calls. In total this produces 36 size-124 range checks per iteration of `g`. Each size-124 range check requires approx. 5 constraints, producing 180 constraints of range checks per opcode processed. + +A rough estimate of the total constraints per opcode processed by the `g` function would be 200 constraints per opcdoe. + +# Bytecode Validation Circuit Summary + +The bytecode validation circuit takes, as public inputs, the packed bytecode array $\mathbf{b} \in \mathbb{F}$ and the bytecode commitment $[P] \in \mathbb{G}_{bn254}$ (represented via field elements). + +The circuit evaluates the following: + +1. For all $i \in [0, \ldots, n - 1]$, validate that $b_i < 256^{31} - 1$ +2. Compute $\mathbf{op} = g(\mathbf{b})$ +3. Perform a _polynomial consistency check_ between $\mathbf{op}$ and $[P]$ + +### Summary of main circuit costs + +The polynomial consistency check requires a Poseidon hash that includes the packed bytecode array $\mathbb{b}$. This requires approx. 22 Honk constraints per 31 bytes of bytecode. + +The `g` function will cost approx. 200 constraints per opcode. + +For a given length `n` , the approx. number of constraints required will be approx `222n`. + +A circuit of size 2^21 (2 million constraints) will be able to process a program containing approximately $n = 9,400$ steps. In contrast, a Soldity program can contain a maximum of 24kb of bytecode. + +Note: unless the efficiency of the validation circuit can be improved by a factor of ~4x, it will not be possible to construct bytecode validation proofs client-side in a web browser. Delegating proof construction to a 3rd party would be acceptable in this context because the 3rd party is untrusted and no secret information is leaked. diff --git a/yellow-paper/docs/public-vm/control-flow.md b/yellow-paper/docs/public-vm/control-flow.md new file mode 100644 index 000000000000..707e78ecf8b7 --- /dev/null +++ b/yellow-paper/docs/public-vm/control-flow.md @@ -0,0 +1,32 @@ +# VM Control Flow + High-level architecture + +This document breaks down the VM into internal components and defines how these components interact with one another. + +This can be considered an intermediate abstraction layer between the high-level VM definition and the explicit cirucit architecture. The intention is for this abstraction to be analogous to how CPU chips are broken down into discrete components. + +# Sub-operations + +> Notation note: I use the term "clock cycle" in a way that is analogous to "row in the execution trace". + +We wish to define a set of sub-operations our VM can execute. Multiple sub-operations can be executed per clock cycle. Each instruction in the instruction set exposed by the VM is composed of 1 or more sub-operations. + +The intention is for sub-operations to be implementable as independent VM circuit relations. + +# Control flow + +![](./gen/images/control-flow/avm-control-flow.png) + +> Notation note: whenever the VM "sends a signal" to one or more VM components, this is analogous to defining a boolean column in the execution trace that toggles on/off specific functionality + +- The instruction controller uses a program counter to read the current opcode to be executed, and send signals to downstream components to execute the opcode +- The state controller reads data from memory into the intermediate registers, using the opcode parameter values +- The VM "algebraic logic unit" executes the opcode given the intermediate register values, and writes output into the intermediate registers +- The state controller writes the output from an intermediate register into memory + +## Chiplets + +This borrows the chiplet nomenclature from the Miden VM - these components encapsulate functionality that can be effectively defined via an independent sub-circuit (analog in real world = specific part of a CPU chip die) + +Chiplets can be developed iteratively i.e. first draft of the AVM only needs a barebones algebraic logic unit. + +> We want apply the following design heuristic to chiplets: they are _loosely coupled_ to other AVM components. It should be possible to remove a chiplet and the AVM opcodes it implements, without requiring any upstream changes to the AVM architecture/implementation diff --git a/yellow-paper/docs/public-vm/gen/images/alu/alu.png b/yellow-paper/docs/public-vm/gen/images/alu/alu.png new file mode 100644 index 0000000000000000000000000000000000000000..b0aca4fe1e9f56c111941403e7bafe68fdae21fb GIT binary patch literal 476263 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

cMoXs4`e? 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�k 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�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%0AK}7-4|)xqnPy! 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%0D_8A(r(T521p+3anpDxl?fcXBd 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%0DDTSb-ta7q6mW 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

G?UF0DI8KZWOg+)X&Y%zT|wN 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