Skip to content

Commit

Permalink
Remove EOAs in all e2e tests (#842)
Browse files Browse the repository at this point in the history
* Remove EOAs in all e2e tests

* Increase timeout for e2e test

* Add helper for deploying multiple L2 contracts in parallel

* Fix private kernel and enqueued public executions

* Revert helper due to incomprehensible CI error

* Re-enable test moving dev dep to production dependency (I'll never understand build system)

* Do not assume address is derived from pubkey in cross chain test

* Use EOAs for p2p test

* Add comment on private kernel fix
  • Loading branch information
spalladino authored Jun 14, 2023
1 parent 27dc70f commit 72524f8
Show file tree
Hide file tree
Showing 27 changed files with 399 additions and 197 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,9 @@ KernelCircuitPublicInputs<NT> native_private_kernel_circuit_inner(DummyComposer&
validate_inputs(composer, private_inputs);

// TODO(jeanmon) Resuscitate after issue 499 is fixed as explained below.
// Remove the array_pop below when uncommenting this validation.
// validate_this_private_call_hash(composer, private_inputs, public_inputs);
array_pop(public_inputs.end.private_call_stack);

// TODO(dbanks12): may need to comment out hash check in here according to TODO above
// TODO(jeanmon) FIXME - https://github.com/AztecProtocol/aztec-packages/issues/671
Expand Down
14 changes: 11 additions & 3 deletions yarn-project/acir-simulator/src/acvm/acvm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
import { createDebugLogger } from '@aztec/foundation/log';
import { solve_intermediate_witness as solveIntermediateWitness } from '@noir-lang/aztec_backend_wasm';

/**
Expand Down Expand Up @@ -60,13 +61,20 @@ export interface ACIRExecutionResult {
export type execute = (acir: Buffer, initialWitness: ACVMWitness, oracle: ACIRCallback) => Promise<ACIRExecutionResult>;

export const acvm: execute = async (acir, initialWitness, callback) => {
const logger = createDebugLogger('aztec:simulator:acvm');
const partialWitness = await solveIntermediateWitness(
acir,
initialWitness,
async (name: string, args: ACVMField[]) => {
if (!(name in callback)) throw new Error(`Callback ${name} not found`);
const result = await callback[name as keyof ACIRCallback](args);
return result;
try {
logger(`Oracle callback ${name}`);
if (!(name in callback)) throw new Error(`Callback ${name} not found`);
const result = await callback[name as keyof ACIRCallback](args);
return result;
} catch (err: any) {
logger(`Error in ACVM callback ${name}: ${err.message ?? err ?? 'Unknown'}`);
throw err;
}
},
);
return Promise.resolve({ partialWitness });
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/acir-simulator/src/client/db_oracle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr } from '@aztec/foundation/fields';
import { Fr, Point } from '@aztec/foundation/fields';
import { FunctionAbi } from '@aztec/foundation/abi';
import { CommitmentsDB } from '../index.js';

Expand Down Expand Up @@ -57,7 +57,7 @@ export interface CommitmentDataOracleInputs {
* The database oracle interface.
*/
export interface DBOracle extends CommitmentsDB {
getSecretKey(contractAddress: AztecAddress, address: AztecAddress): Promise<Buffer>;
getSecretKey(contractAddress: AztecAddress, pubKey: Point): Promise<Buffer>;
getNotes(
contractAddress: AztecAddress,
storageSlot: Fr,
Expand Down
96 changes: 96 additions & 0 deletions yarn-project/acir-simulator/src/client/execution_result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { PrivateCallStackItem, PublicCallRequest } from '@aztec/circuits.js';
import { Fr } from '@aztec/foundation/fields';
import { FunctionL2Logs } from '@aztec/types';
import { ACVMField } from '../acvm/index.js';

/**
* The contents of a new note.
*/
export interface NewNoteData {
/** The preimage of the note. */
preimage: Fr[];
/** The storage slot of the note. */
storageSlot: Fr;
/** The note owner. */
owner: {
/** The x coordinate. */
x: Fr;
/** The y coordinate. */
y: Fr;
};
}

/**
* The contents of a nullified commitment.
*/
export interface NewNullifierData {
/** The preimage of the nullified commitment. */
preimage: Fr[];
/** The storage slot of the nullified commitment. */
storageSlot: Fr;
/** The nullifier. */
nullifier: Fr;
}

/**
* The preimages of the executed function.
*/
export interface ExecutionPreimages {
/** The preimages of the new notes. */
newNotes: NewNoteData[];
/** The preimages of the nullified commitments. */
nullifiedNotes: NewNullifierData[];
}

/**
* The result of executing a private function.
*/
export interface ExecutionResult {
// Needed for prover
/** The ACIR bytecode. */
acir: Buffer;
/** The verification key. */
vk: Buffer;
/** The partial witness. */
partialWitness: Map<number, ACVMField>;
// Needed for the verifier (kernel)
/** The call stack item. */
callStackItem: PrivateCallStackItem;
/** The indices (in private data tree) for commitments corresponding to read requests. */
readRequestCommitmentIndices: bigint[];
// Needed for the user
/** The preimages of the executed function. */
preimages: ExecutionPreimages;
/** The decoded return values of the executed function. */
returnValues: any[];
/** The nested executions. */
nestedExecutions: this[];
/** Enqueued public function execution requests to be picked up by the sequencer. */
enqueuedPublicFunctionCalls: PublicCallRequest[];
/**
* Encrypted logs emitted during execution of this function call.
* Note: These are preimages to `encryptedLogsHash`.
*/
encryptedLogs: FunctionL2Logs;
}

/**
* Collect all encrypted logs across all nested executions.
* @param execResult - The topmost execution result.
* @returns All encrypted logs.
*/
export function collectEncryptedLogs(execResult: ExecutionResult): FunctionL2Logs[] {
return [execResult.encryptedLogs, ...execResult.nestedExecutions.flatMap(collectEncryptedLogs)];
}

/**
* Collect all enqueued public function calls across all nested executions.
* @param execResult - The topmost execution result.
* @returns All enqueued public function calls.
*/
export function collectEnqueuedPublicFunctionCalls(execResult: ExecutionResult): PublicCallRequest[] {
return [
...execResult.enqueuedPublicFunctionCalls,
...execResult.nestedExecutions.flatMap(collectEnqueuedPublicFunctionCalls),
];
}
1 change: 1 addition & 0 deletions yarn-project/acir-simulator/src/client/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './private_execution.js';
export * from './simulator.js';
export * from './db_oracle.js';
export * from './execution_result.js';
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Grumpkin, pedersenCompressInputs } from '@aztec/circuits.js/barretenberg';
import {
ARGS_LENGTH,
CallContext,
Expand All @@ -13,12 +12,14 @@ import {
TxContext,
} from '@aztec/circuits.js';
import { computeSecretMessageHash, siloCommitment } from '@aztec/circuits.js/abis';
import { Grumpkin, pedersenCompressInputs } from '@aztec/circuits.js/barretenberg';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { toBigIntBE, toBufferBE } from '@aztec/foundation/bigint-buffer';
import { padArrayEnd } from '@aztec/foundation/collection';
import { sha256 } from '@aztec/foundation/crypto';
import { EthAddress } from '@aztec/foundation/eth-address';
import { Fr, Point } from '@aztec/foundation/fields';
import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';
import { AppendOnlyTree, Pedersen, StandardTree, newTree } from '@aztec/merkle-tree';
import {
ChildAbi,
Expand All @@ -36,7 +37,6 @@ import { encodeArguments } from '../abi_coder/index.js';
import { NoirPoint, computeSlotForMapping, toPublicKey } from '../utils.js';
import { DBOracle } from './db_oracle.js';
import { AcirSimulator } from './simulator.js';
import { DebugLogger, createDebugLogger } from '@aztec/foundation/log';

const createMemDown = () => (memdown as any)() as MemDown<any, any>;

Expand Down Expand Up @@ -437,7 +437,7 @@ describe('Private Execution test suite', () => {
AztecAddress.random(),
contractAddress,
new FunctionData(Buffer.alloc(4), true, true),
encodeArguments(abi, [bridgedAmount, recipient, messageKey, secret, canceller.toField()]),
encodeArguments(abi, [bridgedAmount, recipient, recipient.x, messageKey, secret, canceller.toField()]),
Fr.random(),
txContext,
Fr.ZERO,
Expand Down
96 changes: 15 additions & 81 deletions yarn-project/acir-simulator/src/client/private_execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ import {
PublicCallRequest,
} from '@aztec/circuits.js';
import { computeCallStackItemHash, computeVarArgsHash } from '@aztec/circuits.js/abis';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';
import { FunctionAbi } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { padArrayEnd } from '@aztec/foundation/collection';
import { Fr, Point } from '@aztec/foundation/fields';
import { createDebugLogger } from '@aztec/foundation/log';
import { Tuple, assertLength } from '@aztec/foundation/serialize';
import { FunctionL2Logs, NotePreimage, NoteSpendingInfo } from '@aztec/types';
import { decodeReturnValues } from '../abi_coder/decoder.js';
import { extractPublicInputs, frToAztecAddress, frToSelector } from '../acvm/deserialize.js';
import {
Expand All @@ -27,83 +30,9 @@ import {
toAcvmCallPrivateStackItem,
toAcvmEnqueuePublicFunctionResult,
} from '../acvm/index.js';
import { sizeOfType } from '../index.js';
import { fieldsToFormattedStr } from './debug.js';
import { ExecutionResult, NewNoteData, NewNullifierData, sizeOfType } from '../index.js';
import { ClientTxExecutionContext } from './client_execution_context.js';
import { Tuple, assertLength } from '@aztec/foundation/serialize';
import { NotePreimage, NoteSpendingInfo, FunctionL2Logs } from '@aztec/types';
import { Grumpkin } from '@aztec/circuits.js/barretenberg';

/**
* The contents of a new note.
*/
export interface NewNoteData {
/** The preimage of the note. */
preimage: Fr[];
/** The storage slot of the note. */
storageSlot: Fr;
/** The note owner. */
owner: {
/** The x coordinate. */
x: Fr;
/** The y coordinate. */
y: Fr;
};
}

/**
* The contents of a nullified commitment.
*/
export interface NewNullifierData {
/** The preimage of the nullified commitment. */
preimage: Fr[];
/** The storage slot of the nullified commitment. */
storageSlot: Fr;
/** The nullifier. */
nullifier: Fr;
}

/**
* The preimages of the executed function.
*/
export interface ExecutionPreimages {
/** The preimages of the new notes. */
newNotes: NewNoteData[];
/** The preimages of the nullified commitments. */
nullifiedNotes: NewNullifierData[];
}

/**
* The result of executing a private function.
*/
export interface ExecutionResult {
// Needed for prover
/** The ACIR bytecode. */
acir: Buffer;
/** The verification key. */
vk: Buffer;
/** The partial witness. */
partialWitness: Map<number, ACVMField>;
// Needed for the verifier (kernel)
/** The call stack item. */
callStackItem: PrivateCallStackItem;
/** The indices (in private data tree) for commitments corresponding to read requests. */
readRequestCommitmentIndices: bigint[];
// Needed for the user
/** The preimages of the executed function. */
preimages: ExecutionPreimages;
/** The decoded return values of the executed function. */
returnValues: any[];
/** The nested executions. */
nestedExecutions: this[];
/** Enqueued public function execution requests to be picked up by the sequencer. */
enqueuedPublicFunctionCalls: PublicCallRequest[];
/**
* Encrypted logs emitted during execution of this function call.
* Note: These are preimages to `encryptedLogsHash`.
*/
encryptedLogs: FunctionL2Logs;
}
import { fieldsToFormattedStr } from './debug.js';

const notAvailable = () => {
return Promise.reject(new Error(`Not available for private function execution`));
Expand All @@ -130,7 +59,7 @@ export class PrivateFunctionExecution {
*/
public async run(): Promise<ExecutionResult> {
const selector = this.functionData.functionSelectorBuffer.toString('hex');
this.log(`Executing external function ${this.contractAddress.toShortString()}:${selector}`);
this.log(`Executing external function ${this.contractAddress.toString()}:${selector}`);

const acir = Buffer.from(this.abi.bytecode, 'hex');
const initialWitness = this.writeInputs();
Expand All @@ -143,8 +72,13 @@ export class PrivateFunctionExecution {
const encryptedLogs = new FunctionL2Logs([]);

const { partialWitness } = await acvm(acir, initialWitness, {
getSecretKey: async ([address]: ACVMField[]) => [
toACVMField(await this.context.db.getSecretKey(this.contractAddress, frToAztecAddress(fromACVMField(address)))),
getSecretKey: async ([ownerX, ownerY]: ACVMField[]) => [
toACVMField(
await this.context.db.getSecretKey(
this.contractAddress,
Point.fromCoordinates(fromACVMField(ownerX), fromACVMField(ownerY)),
),
),
],
getNotes2: async ([storageSlot]: ACVMField[]) => {
const { preimages, indices } = await this.context.getNotes(this.contractAddress, storageSlot, 2);
Expand Down Expand Up @@ -180,7 +114,7 @@ export class PrivateFunctionExecution {
const contractAddress = fromACVMField(acvmContractAddress);
const functionSelector = fromACVMField(acvmFunctionSelector);
this.log(
`Calling private function ${contractAddress.toShortString()}:${functionSelector} from ${this.callContext.storageContractAddress.toShortString()}`,
`Calling private function ${contractAddress.toString()}:${functionSelector} from ${this.callContext.storageContractAddress.toString()}`,
);

const childExecutionResult = await this.callPrivateFunction(
Expand Down Expand Up @@ -274,7 +208,7 @@ export class PrivateFunctionExecution {
publicInputs.contractDeploymentData.deployerPublicKey =
this.context.txContext.contractDeploymentData.deployerPublicKey;

this.log(`Returning from call to ${this.contractAddress.toShortString()}:${selector}`);
this.log(`Returning from call to ${this.contractAddress.toString()}:${selector}`);

return {
acir,
Expand Down
3 changes: 2 additions & 1 deletion yarn-project/acir-simulator/src/client/simulator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import { Fr } from '@aztec/foundation/fields';
import { ExecutionRequest, TxExecutionRequest } from '@aztec/types';
import { ClientTxExecutionContext } from './client_execution_context.js';
import { DBOracle } from './db_oracle.js';
import { ExecutionResult, PrivateFunctionExecution } from './private_execution.js';
import { PrivateFunctionExecution } from './private_execution.js';
import { UnconstrainedFunctionExecution } from './unconstrained_execution.js';
import { ExecutionResult } from './execution_result.js';

export const NOTE_PEDERSEN_CONSTANT = new Fr(2n);
export const MAPPING_SLOT_PEDERSEN_CONSTANT = new Fr(4n);
Expand Down
19 changes: 12 additions & 7 deletions yarn-project/acir-simulator/src/client/unconstrained_execution.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { ACVMField, ZERO_ACVM_FIELD, acvm, fromACVMField, toACVMField, toACVMWitness } from '../acvm/index.js';
import { CallContext, FunctionData } from '@aztec/circuits.js';
import { frToAztecAddress, frToNumber } from '../acvm/deserialize.js';
import { FunctionAbi } from '@aztec/foundation/abi';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr, Point } from '@aztec/foundation/fields';
import { createDebugLogger } from '@aztec/foundation/log';
import { select_return_flattened as selectReturnFlattened } from '@noir-lang/noir_util_wasm';
import { decodeReturnValues } from '../abi_coder/decoder.js';
import { frToNumber } from '../acvm/deserialize.js';
import { ACVMField, ZERO_ACVM_FIELD, acvm, fromACVMField, toACVMField, toACVMWitness } from '../acvm/index.js';
import { ClientTxExecutionContext } from './client_execution_context.js';
import { select_return_flattened as selectReturnFlattened } from '@noir-lang/noir_util_wasm';
import { AztecAddress } from '@aztec/foundation/aztec-address';
import { Fr } from '@aztec/foundation/fields';
import { fieldsToFormattedStr } from './debug.js';

const notAvailable = () => {
Expand Down Expand Up @@ -44,8 +44,13 @@ export class UnconstrainedFunctionExecution {
const initialWitness = toACVMWitness(1, this.args);

const { partialWitness } = await acvm(acir, initialWitness, {
getSecretKey: async ([address]: ACVMField[]) => [
toACVMField(await this.context.db.getSecretKey(this.contractAddress, frToAztecAddress(fromACVMField(address)))),
getSecretKey: async ([ownerX, ownerY]: ACVMField[]) => [
toACVMField(
await this.context.db.getSecretKey(
this.contractAddress,
Point.fromCoordinates(fromACVMField(ownerX), fromACVMField(ownerY)),
),
),
],
getNotes2: async ([storageSlot]: ACVMField[]) => {
const { preimages } = await this.context.getNotes(this.contractAddress, storageSlot, 2);
Expand Down
Loading

0 comments on commit 72524f8

Please sign in to comment.