Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add aztec node to client execution and nuke state info provider #4320 #4401

Merged
merged 9 commits into from
Feb 5, 2024
14 changes: 12 additions & 2 deletions yarn-project/acir-simulator/src/client/client_execution_context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { AuthWitness, FunctionL2Logs, L1NotePayload, Note, NoteStatus, UnencryptedL2Log } from '@aztec/circuit-types';
import {
AuthWitness,
AztecNode,
FunctionL2Logs,
L1NotePayload,
Note,
NoteStatus,
UnencryptedL2Log,
} from '@aztec/circuit-types';
import {
CallContext,
ContractDeploymentData,
Expand Down Expand Up @@ -66,9 +74,10 @@ export class ClientExecutionContext extends ViewDataOracle {
private readonly noteCache: ExecutionNoteCache,
protected readonly db: DBOracle,
private readonly curve: Grumpkin,
private node: AztecNode,
protected log = createDebugLogger('aztec:simulator:client_execution_context'),
) {
super(contractAddress, authWitnesses, db, undefined, log);
super(contractAddress, authWitnesses, db, node, log);
}

// We still need this function until we can get user-defined ordering of structs for fn arguments
Expand Down Expand Up @@ -344,6 +353,7 @@ export class ClientExecutionContext extends ViewDataOracle {
this.noteCache,
this.db,
this.curve,
this.node,
);

const childExecutionResult = await executePrivateFunction(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { L1ToL2Message, Note, PackedArguments, TxExecutionRequest } from '@aztec/circuit-types';
import { AztecNode, L1ToL2Message, Note, PackedArguments, TxExecutionRequest } from '@aztec/circuit-types';
import {
AppendOnlyTreeSnapshot,
CallContext,
Expand Down Expand Up @@ -68,6 +68,8 @@ jest.setTimeout(60_000);

describe('Private Execution test suite', () => {
let oracle: MockProxy<DBOracle>;
let node: MockProxy<AztecNode>;

let acirSimulator: AcirSimulator;

let header = Header.empty();
Expand Down Expand Up @@ -220,7 +222,7 @@ describe('Private Execution test suite', () => {
});
oracle.getHeader.mockResolvedValue(header);

acirSimulator = new AcirSimulator(oracle);
acirSimulator = new AcirSimulator(oracle, node);
});

describe('empty constructor', () => {
Expand Down
7 changes: 5 additions & 2 deletions yarn-project/acir-simulator/src/client/simulator.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Note } from '@aztec/circuit-types';
import { AztecNode, Note } from '@aztec/circuit-types';
import { CompleteAddress } from '@aztec/circuits.js';
import { computeUniqueCommitment, siloCommitment } from '@aztec/circuits.js/abis';
import { ABIParameterVisibility, FunctionArtifactWithDebugMetadata, getFunctionArtifact } from '@aztec/foundation/abi';
Expand All @@ -14,6 +14,8 @@ import { AcirSimulator } from './simulator.js';

describe('Simulator', () => {
let oracle: MockProxy<DBOracle>;
let node: MockProxy<AztecNode>;

let simulator: AcirSimulator;
const ownerPk = GrumpkinScalar.fromString('2dcc5485a58316776299be08c78fa3788a1a7961ae30dc747fb1be17692a8d32');
const ownerCompleteAddress = CompleteAddress.fromPrivateKeyAndPartialAddress(ownerPk, Fr.random());
Expand All @@ -25,13 +27,14 @@ describe('Simulator', () => {

beforeEach(() => {
oracle = mock<DBOracle>();
node = mock<AztecNode>();
oracle.getNullifierKeyPair.mockResolvedValue({
secretKey: ownerNullifierSecretKey,
publicKey: ownerNullifierPublicKey,
});
oracle.getCompleteAddress.mockResolvedValue(ownerCompleteAddress);

simulator = new AcirSimulator(oracle);
simulator = new AcirSimulator(oracle, node);
});

describe('computeNoteHashAndNullifier', () => {
Expand Down
6 changes: 3 additions & 3 deletions yarn-project/acir-simulator/src/client/simulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class AcirSimulator {
private static solver: Promise<WasmBlackBoxFunctionSolver>; // ACVM's backend
private log: DebugLogger;

constructor(private db: DBOracle) {
constructor(private db: DBOracle, private node: AztecNode) {
this.log = createDebugLogger('aztec:simulator');
}

Expand Down Expand Up @@ -107,6 +107,7 @@ export class AcirSimulator {
new ExecutionNoteCache(),
this.db,
curve,
this.node,
);

try {
Expand All @@ -133,13 +134,12 @@ export class AcirSimulator {
request: FunctionCall,
entryPointArtifact: FunctionArtifactWithDebugMetadata,
contractAddress: AztecAddress,
aztecNode?: AztecNode,
) {
if (entryPointArtifact.functionType !== FunctionType.UNCONSTRAINED) {
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as constrained`);
}

const context = new ViewDataOracle(contractAddress, [], this.db, aztecNode);
const context = new ViewDataOracle(contractAddress, [], this.db, this.node);

try {
return await executeUnconstrainedFunction(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FunctionCall, Note } from '@aztec/circuit-types';
import { AztecNode, FunctionCall, Note } from '@aztec/circuit-types';
import { CompleteAddress, FunctionData, Header } from '@aztec/circuits.js';
import { FunctionSelector, encodeArguments } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
Expand All @@ -12,11 +12,12 @@ import { AcirSimulator } from './simulator.js';

describe('Unconstrained Execution test suite', () => {
let oracle: ReturnType<typeof mock<DBOracle>>;
let node: ReturnType<typeof mock<AztecNode>>;
let acirSimulator: AcirSimulator;

beforeEach(() => {
oracle = mock<DBOracle>();
acirSimulator = new AcirSimulator(oracle);
acirSimulator = new AcirSimulator(oracle, node);
});

describe('private token contract', () => {
Expand Down
6 changes: 1 addition & 5 deletions yarn-project/acir-simulator/src/client/view_data_oracle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class ViewDataOracle extends TypedOracle {
/** List of transient auth witnesses to be used during this simulation */
protected readonly authWitnesses: AuthWitness[],
protected readonly db: DBOracle,
protected readonly aztecNode: AztecNode | undefined,
protected readonly aztecNode: AztecNode,
protected log = createDebugLogger('aztec:simulator:client_view_context'),
) {
super();
Expand Down Expand Up @@ -230,10 +230,6 @@ export class ViewDataOracle extends TypedOracle {
* @param numberOfElements - Number of elements to read from the starting storage slot.
*/
public async storageRead(startStorageSlot: Fr, numberOfElements: number) {
if (!this.aztecNode) {
throw new Error('Aztec node is undefined, cannot read storage.');
}

const values = [];
for (let i = 0n; i < numberOfElements; i++) {
const storageSlot = new Fr(startStorageSlot.value + i);
Expand Down
149 changes: 146 additions & 3 deletions yarn-project/circuit-types/src/interfaces/aztec-node.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,165 @@
import { Header } from '@aztec/circuits.js';
import {
ARCHIVE_HEIGHT,
CONTRACT_TREE_HEIGHT,
Header,
L1_TO_L2_MSG_TREE_HEIGHT,
NOTE_HASH_TREE_HEIGHT,
NULLIFIER_TREE_HEIGHT,
PUBLIC_DATA_TREE_HEIGHT,
} from '@aztec/circuits.js';
import { L1ContractAddresses } from '@aztec/ethereum';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
import { ContractClassPublic } from '@aztec/types/contracts';

import { ContractData, ExtendedContractData } from '../contract_data.js';
import { L1ToL2MessageAndIndex } from '../l1_to_l2_message.js';
import { L2Block } from '../l2_block.js';
import { L2Tx } from '../l2_tx.js';
import { GetUnencryptedLogsResponse, L2BlockL2Logs, LogFilter, LogType } from '../logs/index.js';
import { MerkleTreeId } from '../merkle_tree_id.js';
import { SiblingPath } from '../sibling_path/index.js';
import { Tx, TxHash } from '../tx/index.js';
import { SequencerConfig } from './configs.js';
import { StateInfoProvider } from './state_info_provider.js';
import { NullifierMembershipWitness } from './nullifier_tree.js';
import { PublicDataWitness } from './public_data_tree.js';

/** Helper type for a specific L2 block number or the latest block number */
type BlockNumber = number | 'latest';

/**
* The aztec node.
* We will probably implement the additional interfaces by means other than Aztec Node as it's currently a privacy leak
*/
export interface AztecNode extends StateInfoProvider {
export interface AztecNode {
/**
* Find the index of the given leaf in the given tree.
* @param blockNumber - The block number at which to get the data or 'latest' for latest data
* @param treeId - The tree to search in.
* @param leafValue - The value to search for
* @returns The index of the given leaf in the given tree or undefined if not found.
*/
findLeafIndex(blockNumber: BlockNumber, treeId: MerkleTreeId, leafValue: Fr): Promise<bigint | undefined>;

/**
* Returns a sibling path for the given index in the contract tree.
* @param blockNumber - The block number at which to get the data.
* @param leafIndex - The index of the leaf for which the sibling path is required.
* @returns The sibling path for the leaf index.
*/
getContractSiblingPath(
blockNumber: BlockNumber,
leafIndex: bigint,
): Promise<SiblingPath<typeof CONTRACT_TREE_HEIGHT>>;

/**
* Returns a sibling path for the given index in the nullifier tree.
* @param blockNumber - The block number at which to get the data.
* @param leafIndex - The index of the leaf for which the sibling path is required.
* @returns The sibling path for the leaf index.
*/
getNullifierSiblingPath(
blockNumber: BlockNumber,
leafIndex: bigint,
): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>>;

/**
* Returns a sibling path for the given index in the note hash tree.
* @param blockNumber - The block number at which to get the data.
* @param leafIndex - The index of the leaf for which the sibling path is required.
* @returns The sibling path for the leaf index.
*/
getNoteHashSiblingPath(
blockNumber: BlockNumber,
leafIndex: bigint,
): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>>;

/**
* Gets a confirmed/consumed L1 to L2 message for the given message key (throws if not found).
* and its index in the merkle tree
* @param messageKey - The message key.
* @returns The map containing the message and index.
*/
getL1ToL2MessageAndIndex(messageKey: Fr): Promise<L1ToL2MessageAndIndex>;

/**
* Returns a sibling path for a leaf in the committed l1 to l2 data tree.
* @param blockNumber - The block number at which to get the data.
* @param leafIndex - Index of the leaf in the tree.
* @returns The sibling path.
*/
getL1ToL2MessageSiblingPath(
blockNumber: BlockNumber,
leafIndex: bigint,
): Promise<SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>>;

/**
* Returns a sibling path for a leaf in the committed historic blocks tree.
* @param blockNumber - The block number at which to get the data.
* @param leafIndex - Index of the leaf in the tree.
* @returns The sibling path.
*/
getArchiveSiblingPath(blockNumber: BlockNumber, leafIndex: bigint): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>>;

/**
* Returns a sibling path for a leaf in the committed public data tree.
* @param blockNumber - The block number at which to get the data.
* @param leafIndex - Index of the leaf in the tree.
* @returns The sibling path.
*/
getPublicDataSiblingPath(
blockNumber: BlockNumber,
leafIndex: bigint,
): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>>;

/**
* Returns a nullifier membership witness for a given nullifier at a given block.
* @param blockNumber - The block number at which to get the data.
* @param nullifier - Nullifier we try to find witness for.
* @returns The nullifier membership witness (if found).
*/
getNullifierMembershipWitness(
blockNumber: BlockNumber,
nullifier: Fr,
): Promise<NullifierMembershipWitness | undefined>;

/**
* Returns a low nullifier membership witness for a given nullifier at a given block.
* @param blockNumber - The block number at which to get the data.
* @param nullifier - Nullifier we try to find the low nullifier witness for.
* @returns The low nullifier membership witness (if found).
* @remarks Low nullifier witness can be used to perform a nullifier non-inclusion proof by leveraging the "linked
* list structure" of leaves and proving that a lower nullifier is pointing to a bigger next value than the nullifier
* we are trying to prove non-inclusion for.
*/
getLowNullifierMembershipWitness(
blockNumber: BlockNumber,
nullifier: Fr,
): Promise<NullifierMembershipWitness | undefined>;

/**
* Returns a public data tree witness for a given leaf slot at a given block.
* @param blockNumber - The block number at which to get the data.
* @param leafSlot - The leaf slot we try to find the witness for.
* @returns The public data witness (if found).
* @remarks The witness can be used to compute the current value of the public data tree leaf. If the low leaf preimage corresponds to an
* "in range" slot, means that the slot doesn't exist and the value is 0. If the low leaf preimage corresponds to the exact slot, the current value
* is contained in the leaf preimage.
*/
getPublicDataTreeWitness(blockNumber: BlockNumber, leafSlot: Fr): Promise<PublicDataWitness | undefined>;

/**
* Get a block specified by its number.
* @param number - The block number being requested.
* @returns The requested block.
*/
getBlock(number: number): Promise<L2Block | undefined>;

/**
* Fetches the current block number.
* @returns The block number.
*/
getBlockNumber(): Promise<number>;
/**
* Method to determine if the node is ready to accept transactions.
* @returns - Flag indicating the readiness for tx submission.
Expand Down
1 change: 0 additions & 1 deletion yarn-project/circuit-types/src/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './state_info_provider.js';
export * from './aztec-node.js';
export * from './pxe.js';
export * from './deployed-contract.js';
Expand Down
Loading
Loading