Skip to content

Commit

Permalink
fix: simulateTx does not prove (#6930)
Browse files Browse the repository at this point in the history
This PR changes `pxe.simulateTx` to use a fake proof creator when
executing the private kernel.
  • Loading branch information
alexghr authored Jun 6, 2024
1 parent 1fa7d84 commit d3d6b9e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
9 changes: 8 additions & 1 deletion yarn-project/cli/src/cmds/call.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type AztecAddress, ContractFunctionInteraction, SignerlessWallet } from '@aztec/aztec.js';
import { DefaultMultiCallEntrypoint } from '@aztec/aztec.js/entrypoint';
import { type DebugLogger, type LogFn } from '@aztec/foundation/log';

import { format } from 'util';
Expand Down Expand Up @@ -26,7 +27,13 @@ export async function call(
}

const client = await createCompatibleClient(rpcUrl, debugLogger);
const call = new ContractFunctionInteraction(new SignerlessWallet(client), contractAddress, fnArtifact, functionArgs);
const { chainId, protocolVersion } = await client.getNodeInfo();
const call = new ContractFunctionInteraction(
new SignerlessWallet(client, new DefaultMultiCallEntrypoint(chainId, protocolVersion)),
contractAddress,
fnArtifact,
functionArgs,
);
const from = await getTxSender(client, fromAddress);
const result = await call.simulate({ from });
log(format('\nView result: ', result, '\n'));
Expand Down
36 changes: 24 additions & 12 deletions yarn-project/pxe/src/pxe_service/pxe_service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { IncomingNoteDao } from '../database/incoming_note_dao.js';
import { type PxeDatabase } from '../database/index.js';
import { KernelOracle } from '../kernel_oracle/index.js';
import { KernelProver } from '../kernel_prover/kernel_prover.js';
import { TestProofCreator } from '../kernel_prover/test/test_circuit_prover.js';
import { getAcirSimulator } from '../simulator/index.js';
import { Synchronizer } from '../synchronizer/index.js';

Expand All @@ -77,6 +78,8 @@ export class PXEService implements PXE {
// ensures that state is not changed while simulating
private jobQueue = new SerialQueue();

private fakeProofCreator = new TestProofCreator();

constructor(
private keyStore: KeyStore,
private node: AztecNode,
Expand Down Expand Up @@ -409,8 +412,14 @@ export class PXEService implements PXE {
return await this.node.getBlock(blockNumber);
}

public async proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean) {
return (await this.simulateTx(txRequest, simulatePublic)).tx;
public proveTx(txRequest: TxExecutionRequest, simulatePublic: boolean): Promise<Tx> {
return this.jobQueue.put(async () => {
const simulatedTx = await this.#simulateAndProve(txRequest, this.proofCreator, undefined);
if (simulatePublic) {
simulatedTx.publicOutput = await this.#simulatePublicCalls(simulatedTx.tx);
}
return simulatedTx.tx;
});
}

public async simulateTx(
Expand All @@ -419,16 +428,15 @@ export class PXEService implements PXE {
msgSender: AztecAddress | undefined = undefined,
): Promise<SimulatedTx> {
return await this.jobQueue.put(async () => {
const simulatedTx = await this.#simulateAndProve(txRequest, msgSender);
// We log only if the msgSender is undefined, as simulating with a different msgSender
// is unlikely to be a real transaction, and likely to be only used to read data.
// Meaning that it will not necessarily have produced a nullifier (and thus have no TxHash)
// If we log, the `getTxHash` function will throw.

const simulatedTx = await this.#simulateAndProve(txRequest, this.fakeProofCreator, msgSender);
if (simulatePublic) {
simulatedTx.publicOutput = await this.#simulatePublicCalls(simulatedTx.tx);
}

// We log only if the msgSender is undefined, as simulating with a different msgSender
// is unlikely to be a real transaction, and likely to be only used to read data.
// Meaning that it will not necessarily have produced a nullifier (and thus have no TxHash)
// If we log, the `getTxHash` function will throw.
if (!msgSender) {
this.log.info(`Executed local simulation for ${simulatedTx.tx.getTxHash()}`);
}
Expand Down Expand Up @@ -645,18 +653,22 @@ export class PXEService implements PXE {
* the function will also include the new contract's public functions in the transaction object.
*
* @param txExecutionRequest - The transaction request to be simulated and proved.
* @param signature - The ECDSA signature for the transaction request.
* @param proofCreator - The proof creator to use for proving the execution.
* @param msgSender - (Optional) The message sender to use for the simulation.
* @returns An object tract contains:
* @returns An object that contains:
* A private transaction object containing the proof, public inputs, and encrypted logs.
* The return values of the private execution
*/
async #simulateAndProve(txExecutionRequest: TxExecutionRequest, msgSender?: AztecAddress) {
async #simulateAndProve(
txExecutionRequest: TxExecutionRequest,
proofCreator: ProofCreator,
msgSender?: AztecAddress,
): Promise<SimulatedTx> {
// Get values that allow us to reconstruct the block hash
const executionResult = await this.#simulate(txExecutionRequest, msgSender);

const kernelOracle = new KernelOracle(this.contractDataOracle, this.keyStore, this.node);
const kernelProver = new KernelProver(kernelOracle, this.proofCreator);
const kernelProver = new KernelProver(kernelOracle, proofCreator);
this.log.debug(`Executing kernel prover...`);
const { proof, publicInputs } = await kernelProver.prove(txExecutionRequest.toTxRequest(), executionResult);

Expand Down

0 comments on commit d3d6b9e

Please sign in to comment.