Skip to content

Commit 9643dcd

Browse files
authored
refactor: remove PublicExecutor (#10028)
- Pulls what the PublicExecutor did into an internal function of the PublicTxSimulator - Modifies the TXE to craft a carrier TX for public calls and just call `publicTxSimulator.simulate(tx)` so that we only need to maintain that interface for external use of the simulator - Adds `gasLeft` to `AvmContractCallResult`, removes gasLeft as an extra param to functions that accept call result. - Introduces `AvmFinalizedCallResult` which is just like `AvmContractCallResult` but is friendlier for use externally to the AVM. Uses standard Gas type, and uses `SimulationError` type for `revertReason`. - Note that we might want to only have one gas type eventually, but even just having this dedicated result type with revertReason of type SimulationError led to some cleanup - Removes bytecode size metering that was done in PublicExector (it wasn't useful anymore) - Removes unused/stale SimulationProvider paramters
1 parent e1ef998 commit 9643dcd

37 files changed

+620
-510
lines changed

noir-projects/noir-contracts/contracts/token_contract/src/test/refunds.nr

+17-7
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
use crate::{test::utils, Token};
22
use aztec::oracle::random::random;
3+
use aztec::protocol_types::abis::gas::Gas;
4+
use aztec::protocol_types::abis::gas_fees::GasFees;
35

46
use dep::authwit::cheatcodes as authwit_cheatcodes;
57
use std::test::OracleMock;
68

79
#[test]
810
unconstrained fn setup_refund_success() {
11+
// Gas used to compute transaction fee
12+
// TXE oracle uses gas_used = Gas(1,1) when crafting TX
13+
let txe_expected_gas_used = Gas::new(1, 1);
14+
// TXE oracle uses default gas fees
15+
let txe_gas_fees = GasFees::default();
16+
let expected_tx_fee = txe_expected_gas_used.compute_fee(txe_gas_fees);
17+
18+
// Fund account with enough to cover tx fee plus some
19+
let funded_amount = 1_000 + expected_tx_fee;
20+
921
let (env, token_contract_address, owner, recipient, mint_amount) =
10-
utils::setup_and_mint_to_private(true);
22+
utils::setup_and_mint_amount_to_private(true, funded_amount);
1123

1224
// Renaming owner and recipient to match naming in Token
1325
let user = owner;
1426
let fee_payer = recipient;
1527

16-
let funded_amount = 1_000;
17-
1828
// We use the same randomness for both the fee payer, the user and the nonce as we currently don't have
1929
// `OracleMock::mock_once()`
2030
let fee_payer_randomness = 123;
@@ -44,19 +54,19 @@ unconstrained fn setup_refund_success() {
4454
env,
4555
token_contract_address,
4656
fee_payer,
47-
1,
57+
expected_tx_fee,
4858
fee_payer_randomness,
4959
);
5060
utils::add_token_note(
5161
env,
5262
token_contract_address,
5363
user,
54-
funded_amount - 1,
64+
funded_amount - expected_tx_fee,
5565
user_randomness,
5666
);
5767

58-
utils::check_private_balance(token_contract_address, user, mint_amount - 1);
59-
utils::check_private_balance(token_contract_address, fee_payer, 1)
68+
utils::check_private_balance(token_contract_address, user, mint_amount - expected_tx_fee);
69+
utils::check_private_balance(token_contract_address, fee_payer, expected_tx_fee)
6070
}
6171

6272
// This test should be reworked when final support for partial notes is in

noir-projects/noir-contracts/contracts/token_contract/src/test/utils.nr

+8-2
Original file line numberDiff line numberDiff line change
@@ -56,19 +56,25 @@ pub unconstrained fn setup_and_mint_to_public(
5656
(env, token_contract_address, owner, recipient, mint_amount)
5757
}
5858

59-
pub unconstrained fn setup_and_mint_to_private(
59+
pub unconstrained fn setup_and_mint_amount_to_private(
6060
with_account_contracts: bool,
61+
mint_amount: Field,
6162
) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) {
6263
// Setup the tokens and mint public balance
6364
let (env, token_contract_address, owner, recipient) = setup(with_account_contracts);
6465

6566
// Mint some tokens
66-
let mint_amount = 10000;
6767
mint_to_private(env, token_contract_address, owner, mint_amount);
6868

6969
(env, token_contract_address, owner, recipient, mint_amount)
7070
}
7171

72+
pub unconstrained fn setup_and_mint_to_private(
73+
with_account_contracts: bool,
74+
) -> (&mut TestEnvironment, AztecAddress, AztecAddress, AztecAddress, Field) {
75+
setup_and_mint_amount_to_private(with_account_contracts, 10000)
76+
}
77+
7278
pub unconstrained fn mint_to_private(
7379
env: &mut TestEnvironment,
7480
token_contract_address: AztecAddress,

yarn-project/aztec-node/src/aztec-node/server.ts

+1-4
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ import {
7171
} from '@aztec/p2p';
7272
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
7373
import { GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client';
74-
import { PublicProcessorFactory, createSimulationProvider } from '@aztec/simulator';
74+
import { PublicProcessorFactory } from '@aztec/simulator';
7575
import { type TelemetryClient } from '@aztec/telemetry-client';
7676
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
7777
import { createValidatorClient } from '@aztec/validator-client';
@@ -160,8 +160,6 @@ export class AztecNodeService implements AztecNode {
160160
// start both and wait for them to sync from the block source
161161
await Promise.all([p2pClient.start(), worldStateSynchronizer.start()]);
162162

163-
const simulationProvider = await createSimulationProvider(config, log);
164-
165163
const validatorClient = createValidatorClient(config, p2pClient, telemetry);
166164

167165
// now create the sequencer
@@ -175,7 +173,6 @@ export class AztecNodeService implements AztecNode {
175173
archiver,
176174
archiver,
177175
archiver,
178-
simulationProvider,
179176
telemetry,
180177
);
181178

yarn-project/bb-prover/src/avm_proving.test.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,8 @@ const proveAndVerifyAvmTestContract = async (
147147
const pxResult = trace.toPublicFunctionCallResult(
148148
environment,
149149
startGas,
150-
/*endGasLeft=*/ Gas.from(context.machineState.gasLeft),
151150
/*bytecode=*/ simulator.getBytecode()!,
152-
avmResult,
151+
avmResult.finalize(),
153152
functionName,
154153
);
155154

yarn-project/circuit-types/src/public_execution_request.ts

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { CallContext, type PublicCallRequest, Vector } from '@aztec/circuits.js';
1+
import { CallContext, PublicCallRequest, Vector } from '@aztec/circuits.js';
22
import { computeVarArgsHash } from '@aztec/circuits.js/hash';
33
import { Fr } from '@aztec/foundation/fields';
44
import { schemas } from '@aztec/foundation/schemas';
@@ -82,9 +82,19 @@ export class PublicExecutionRequest {
8282
);
8383
}
8484

85+
toCallRequest(): PublicCallRequest {
86+
return new PublicCallRequest(
87+
this.callContext.msgSender,
88+
this.callContext.contractAddress,
89+
this.callContext.functionSelector,
90+
this.callContext.isStaticCall,
91+
computeVarArgsHash(this.args),
92+
);
93+
}
94+
8595
[inspect.custom]() {
8696
return `PublicExecutionRequest {
87-
callContext: ${this.callContext}
97+
callContext: ${inspect(this.callContext)}
8898
args: ${this.args}
8999
}`;
90100
}

yarn-project/circuit-types/src/stats/metrics.ts

-6
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,6 @@ export const Metrics = [
3737
description: 'Time to simulate an AVM program.',
3838
events: ['avm-simulation'],
3939
},
40-
{
41-
name: 'avm_simulation_bytecode_size_in_bytes',
42-
groupBy: 'app-circuit-name',
43-
description: 'Uncompressed bytecode size for an AVM program.',
44-
events: ['avm-simulation'],
45-
},
4640
{
4741
name: 'proof_construction_time_sha256_ms',
4842
groupBy: 'threads',

yarn-project/circuit-types/src/stats/stats.ts

-2
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,6 @@ export type AvmSimulationStats = {
123123
appCircuitName: string;
124124
/** Duration in ms. */
125125
duration: number;
126-
/** Uncompressed bytecode size. */
127-
bytecodeSize: number;
128126
};
129127

130128
/** Stats for witness generation. */

yarn-project/circuit-types/src/tx/tx.ts

+16
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,22 @@ export class Tx extends Gossipable {
119119
);
120120
}
121121

122+
static newWithTxData(
123+
data: PrivateKernelTailCircuitPublicInputs,
124+
publicTeardownExecutionRequest?: PublicExecutionRequest,
125+
) {
126+
return new Tx(
127+
data,
128+
ClientIvcProof.empty(),
129+
EncryptedNoteTxL2Logs.empty(),
130+
EncryptedTxL2Logs.empty(),
131+
UnencryptedTxL2Logs.empty(),
132+
ContractClassTxL2Logs.empty(),
133+
[],
134+
publicTeardownExecutionRequest ? publicTeardownExecutionRequest : PublicExecutionRequest.empty(),
135+
);
136+
}
137+
122138
/**
123139
* Serializes the Tx object into a Buffer.
124140
* @returns Buffer representation of the Tx object.

yarn-project/circuits.js/src/structs/call_context.ts

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { schemas } from '@aztec/foundation/schemas';
55
import { BufferReader, FieldReader, serializeToBuffer, serializeToFields } from '@aztec/foundation/serialize';
66
import { type FieldsOf } from '@aztec/foundation/types';
77

8+
import { inspect } from 'util';
89
import { z } from 'zod';
910

1011
import { CALL_CONTEXT_LENGTH } from '../constants.gen.js';
@@ -125,4 +126,13 @@ export class CallContext {
125126
callContext.isStaticCall === this.isStaticCall
126127
);
127128
}
129+
130+
[inspect.custom]() {
131+
return `CallContext {
132+
msgSender: ${this.msgSender}
133+
contractAddress: ${this.contractAddress}
134+
functionSelector: ${this.functionSelector}
135+
isStaticCall: ${this.isStaticCall}
136+
}`;
137+
}
128138
}

yarn-project/ivc-integration/src/avm_integration.test.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,8 @@ const proveAvmTestContract = async (
238238
const pxResult = trace.toPublicFunctionCallResult(
239239
environment,
240240
startGas,
241-
/*endGasLeft=*/ Gas.from(context.machineState.gasLeft),
242241
/*bytecode=*/ simulator.getBytecode()!,
243-
avmResult,
242+
avmResult.finalize(),
244243
functionName,
245244
);
246245

yarn-project/prover-client/src/mocks/test_context.ts

+37-23
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ import { type Fr } from '@aztec/foundation/fields';
1313
import { type DebugLogger } from '@aztec/foundation/log';
1414
import { openTmpStore } from '@aztec/kv-store/utils';
1515
import {
16-
type PublicExecutionResult,
17-
PublicExecutionResultBuilder,
18-
type PublicExecutor,
1916
PublicProcessor,
17+
PublicTxSimulator,
2018
type SimulationProvider,
2119
WASMSimulator,
2220
type WorldStateDB,
@@ -25,10 +23,12 @@ import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
2523
import { MerkleTrees } from '@aztec/world-state';
2624
import { NativeWorldStateService } from '@aztec/world-state/native';
2725

26+
import { jest } from '@jest/globals';
2827
import * as fs from 'fs/promises';
2928
import { type MockProxy, mock } from 'jest-mock-extended';
3029

3130
import { TestCircuitProver } from '../../../bb-prover/src/test/test_circuit_prover.js';
31+
import { AvmFinalizedCallResult } from '../../../simulator/src/avm/avm_contract_call_result.js';
3232
import { type AvmPersistableStateManager } from '../../../simulator/src/avm/journal/journal.js';
3333
import { ProvingOrchestrator } from '../orchestrator/index.js';
3434
import { MemoryProvingQueue } from '../prover-agent/memory-proving-queue.js';
@@ -37,7 +37,7 @@ import { getEnvironmentConfig, getSimulationProvider, makeGlobals } from './fixt
3737

3838
export class TestContext {
3939
constructor(
40-
public publicExecutor: MockProxy<PublicExecutor>,
40+
public publicTxSimulator: PublicTxSimulator,
4141
public worldStateDB: MockProxy<WorldStateDB>,
4242
public publicProcessor: PublicProcessor,
4343
public simulationProvider: SimulationProvider,
@@ -66,7 +66,6 @@ export class TestContext {
6666
const directoriesToCleanup: string[] = [];
6767
const globalVariables = makeGlobals(blockNumber);
6868

69-
const publicExecutor = mock<PublicExecutor>();
7069
const worldStateDB = mock<WorldStateDB>();
7170
const telemetry = new NoopTelemetryClient();
7271

@@ -84,12 +83,13 @@ export class TestContext {
8483
proverDb = await ws.getLatest();
8584
}
8685

87-
const processor = PublicProcessor.create(
86+
const publicTxSimulator = new PublicTxSimulator(publicDb, worldStateDB, telemetry, globalVariables);
87+
const processor = new PublicProcessor(
8888
publicDb,
89-
publicExecutor,
9089
globalVariables,
9190
Header.empty(),
9291
worldStateDB,
92+
publicTxSimulator,
9393
telemetry,
9494
);
9595

@@ -124,7 +124,7 @@ export class TestContext {
124124
agent.start(queue);
125125

126126
return new this(
127-
publicExecutor,
127+
publicTxSimulator,
128128
worldStateDB,
129129
processor,
130130
simulationProvider,
@@ -154,25 +154,24 @@ export class TestContext {
154154
) {
155155
const defaultExecutorImplementation = (
156156
_stateManager: AvmPersistableStateManager,
157-
execution: PublicExecutionRequest,
158-
_globalVariables: GlobalVariables,
157+
executionRequest: PublicExecutionRequest,
159158
allocatedGas: Gas,
160-
_transactionFee?: Fr,
159+
_transactionFee: Fr,
160+
_fnName: string,
161161
) => {
162162
for (const tx of txs) {
163163
const allCalls = tx.publicTeardownFunctionCall.isEmpty()
164164
? tx.enqueuedPublicFunctionCalls
165165
: [...tx.enqueuedPublicFunctionCalls, tx.publicTeardownFunctionCall];
166166
for (const request of allCalls) {
167-
if (execution.callContext.equals(request.callContext)) {
168-
const result = PublicExecutionResultBuilder.empty().build({
169-
endGasLeft: allocatedGas,
170-
});
171-
return Promise.resolve(result);
167+
if (executionRequest.callContext.equals(request.callContext)) {
168+
return Promise.resolve(
169+
new AvmFinalizedCallResult(/*reverted=*/ false, /*output=*/ [], /*gasLeft=*/ allocatedGas),
170+
);
172171
}
173172
}
174173
}
175-
throw new Error(`Unexpected execution request: ${execution}`);
174+
throw new Error(`Unexpected execution request: ${executionRequest}`);
176175
};
177176
return await this.processPublicFunctionsWithMockExecutorImplementation(
178177
txs,
@@ -183,21 +182,36 @@ export class TestContext {
183182
);
184183
}
185184

186-
public async processPublicFunctionsWithMockExecutorImplementation(
185+
private async processPublicFunctionsWithMockExecutorImplementation(
187186
txs: Tx[],
188187
maxTransactions: number,
189188
txHandler?: ProcessedTxHandler,
190189
txValidator?: TxValidator<ProcessedTx>,
191190
executorMock?: (
192191
stateManager: AvmPersistableStateManager,
193-
execution: PublicExecutionRequest,
194-
globalVariables: GlobalVariables,
192+
executionRequest: PublicExecutionRequest,
195193
allocatedGas: Gas,
196-
transactionFee?: Fr,
197-
) => Promise<PublicExecutionResult>,
194+
transactionFee: Fr,
195+
fnName: string,
196+
) => Promise<AvmFinalizedCallResult>,
198197
) {
198+
// Mock the internal private function. Borrowed from https://stackoverflow.com/a/71033167
199+
const simulateInternal: jest.SpiedFunction<
200+
(
201+
stateManager: AvmPersistableStateManager,
202+
executionResult: any,
203+
allocatedGas: Gas,
204+
transactionFee: any,
205+
fnName: any,
206+
) => Promise<AvmFinalizedCallResult>
207+
> = jest.spyOn(
208+
this.publicTxSimulator as unknown as {
209+
simulateEnqueuedCallInternal: PublicTxSimulator['simulateEnqueuedCallInternal'];
210+
},
211+
'simulateEnqueuedCallInternal',
212+
);
199213
if (executorMock) {
200-
this.publicExecutor.simulate.mockImplementation(executorMock);
214+
simulateInternal.mockImplementation(executorMock);
201215
}
202216
return await this.publicProcessor.process(txs, maxTransactions, txHandler, txValidator);
203217
}

yarn-project/prover-node/src/factory.ts

-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { type DataStoreConfig } from '@aztec/kv-store/config';
77
import { RollupAbi } from '@aztec/l1-artifacts';
88
import { createProverClient } from '@aztec/prover-client';
99
import { L1Publisher } from '@aztec/sequencer-client';
10-
import { createSimulationProvider } from '@aztec/simulator';
1110
import { type TelemetryClient } from '@aztec/telemetry-client';
1211
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
1312
import { createWorldStateSynchronizer } from '@aztec/world-state';
@@ -43,8 +42,6 @@ export async function createProverNode(
4342
const worldStateSynchronizer = await createWorldStateSynchronizer(worldStateConfig, archiver, telemetry);
4443
await worldStateSynchronizer.start();
4544

46-
const simulationProvider = await createSimulationProvider(config, log);
47-
4845
const prover = await createProverClient(config, telemetry);
4946

5047
// REFACTOR: Move publisher out of sequencer package and into an L1-related package
@@ -82,7 +79,6 @@ export async function createProverNode(
8279
archiver,
8380
worldStateSynchronizer,
8481
proverCoordination,
85-
simulationProvider,
8682
quoteProvider,
8783
quoteSigner,
8884
claimsMonitor,

0 commit comments

Comments
 (0)