@aztec/simulator 0.0.1-commit.b2a5d0dd1 → 0.0.1-commit.b3d3157a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/private/acvm_wasm.d.ts +1 -1
- package/dest/private/acvm_wasm.d.ts.map +1 -1
- package/dest/private/acvm_wasm.js +3 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +2 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.js +17 -2
- package/dest/public/avm/fixtures/utils.d.ts +1 -1
- package/dest/public/avm/fixtures/utils.d.ts.map +1 -1
- package/dest/public/avm/fixtures/utils.js +3 -0
- package/dest/public/avm/opcodes/contract.d.ts +3 -2
- package/dest/public/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/public/avm/opcodes/contract.js +5 -1
- package/dest/public/avm/opcodes/ec_add.d.ts +2 -4
- package/dest/public/avm/opcodes/ec_add.d.ts.map +1 -1
- package/dest/public/avm/opcodes/ec_add.js +13 -27
- package/dest/public/fixtures/bulk_test.d.ts +1 -1
- package/dest/public/fixtures/bulk_test.d.ts.map +1 -1
- package/dest/public/fixtures/bulk_test.js +27 -0
- package/dest/public/fixtures/custom_bytecode_tests.d.ts +3 -1
- package/dest/public/fixtures/custom_bytecode_tests.d.ts.map +1 -1
- package/dest/public/fixtures/custom_bytecode_tests.js +61 -1
- package/dest/public/fixtures/opcode_spammer.d.ts +1 -1
- package/dest/public/fixtures/opcode_spammer.d.ts.map +1 -1
- package/dest/public/fixtures/opcode_spammer.js +2 -10
- package/dest/public/fixtures/utils.d.ts +1 -1
- package/dest/public/fixtures/utils.d.ts.map +1 -1
- package/dest/public/fixtures/utils.js +9 -10
- package/dest/public/hinting_db_sources.d.ts +2 -1
- package/dest/public/hinting_db_sources.d.ts.map +1 -1
- package/dest/public/hinting_db_sources.js +4 -1
- package/dest/public/public_db_sources.d.ts +5 -2
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +9 -3
- package/dest/public/public_processor/guarded_merkle_tree.d.ts +4 -3
- package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -1
- package/dest/public/public_processor/guarded_merkle_tree.js +3 -0
- package/dest/public/public_processor/public_processor.d.ts +4 -3
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +57 -32
- package/dest/public/public_processor/public_processor_metrics.d.ts +4 -1
- package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor_metrics.js +8 -0
- package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +2 -2
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +1 -1
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +3 -8
- package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts +1 -1
- package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.js +3 -7
- package/dest/public/public_tx_simulator/public_tx_simulator.js +2 -2
- package/package.json +16 -15
- package/src/private/acvm_wasm.ts +4 -1
- package/src/public/avm/fixtures/base_avm_simulation_tester.ts +22 -2
- package/src/public/avm/fixtures/utils.ts +3 -0
- package/src/public/avm/opcodes/contract.ts +5 -1
- package/src/public/avm/opcodes/ec_add.ts +12 -31
- package/src/public/fixtures/bulk_test.ts +27 -0
- package/src/public/fixtures/custom_bytecode_tests.ts +139 -1
- package/src/public/fixtures/opcode_spammer.ts +4 -8
- package/src/public/fixtures/utils.ts +9 -10
- package/src/public/hinting_db_sources.ts +5 -0
- package/src/public/public_db_sources.ts +12 -3
- package/src/public/public_processor/guarded_merkle_tree.ts +5 -2
- package/src/public/public_processor/public_processor.ts +75 -39
- package/src/public/public_processor/public_processor_metrics.ts +12 -0
- package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +2 -2
- package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +3 -12
- package/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts +3 -10
- package/src/public/public_tx_simulator/public_tx_simulator.ts +2 -2
|
@@ -1339,20 +1339,16 @@ export const SPAM_CONFIGS: Partial<Record<Opcode, SpamConfig[]>> = {
|
|
|
1339
1339
|
setup: [
|
|
1340
1340
|
{ offset: 0, value: new Field(Grumpkin.generator.x) }, // p1X = G.x
|
|
1341
1341
|
{ offset: 1, value: new Field(Grumpkin.generator.y) }, // p1Y = G.y
|
|
1342
|
-
{ offset: 2, value: new
|
|
1343
|
-
{ offset: 3, value: new Field(Grumpkin.generator.
|
|
1344
|
-
{ offset: 4, value: new Field(Grumpkin.generator.y) }, // p2Y = G.y
|
|
1345
|
-
{ offset: 5, value: new Uint1(0n) }, // p2IsInfinite = false
|
|
1342
|
+
{ offset: 2, value: new Field(Grumpkin.generator.x) }, // p2X = G.x
|
|
1343
|
+
{ offset: 3, value: new Field(Grumpkin.generator.y) }, // p2Y = G.y
|
|
1346
1344
|
],
|
|
1347
1345
|
targetInstructions: () => [
|
|
1348
1346
|
new EcAdd(
|
|
1349
1347
|
/*addressing_mode=*/ 0,
|
|
1350
1348
|
/*p1XOffset=*/ 0,
|
|
1351
1349
|
/*p1YOffset=*/ 1,
|
|
1352
|
-
/*
|
|
1353
|
-
/*
|
|
1354
|
-
/*p2YOffset=*/ 4,
|
|
1355
|
-
/*p2IsInfiniteOffset=*/ 5,
|
|
1350
|
+
/*p2XOffset=*/ 2,
|
|
1351
|
+
/*p2YOffset=*/ 3,
|
|
1356
1352
|
/*dstOffset=*/ 0,
|
|
1357
1353
|
),
|
|
1358
1354
|
],
|
|
@@ -233,17 +233,15 @@ export async function addNewContractInstanceToTx(
|
|
|
233
233
|
contractInstance: ContractInstanceWithAddress,
|
|
234
234
|
skipNullifierInsertion = false,
|
|
235
235
|
) {
|
|
236
|
-
//
|
|
237
|
-
// is not broadcast in such private logs
|
|
236
|
+
// Only ivpk_m is broadcast as a point (x, y); the other five keys are hashes.
|
|
238
237
|
const publicKeysAsFields = [
|
|
239
|
-
contractInstance.publicKeys.
|
|
240
|
-
contractInstance.publicKeys.
|
|
241
|
-
contractInstance.publicKeys.
|
|
242
|
-
contractInstance.publicKeys.
|
|
243
|
-
contractInstance.publicKeys.
|
|
244
|
-
contractInstance.publicKeys.
|
|
245
|
-
contractInstance.publicKeys.
|
|
246
|
-
contractInstance.publicKeys.masterTaggingPublicKey.y,
|
|
238
|
+
contractInstance.publicKeys.npkMHash,
|
|
239
|
+
contractInstance.publicKeys.ivpkM.x,
|
|
240
|
+
contractInstance.publicKeys.ivpkM.y,
|
|
241
|
+
contractInstance.publicKeys.ovpkMHash,
|
|
242
|
+
contractInstance.publicKeys.tpkMHash,
|
|
243
|
+
contractInstance.publicKeys.mspkMHash,
|
|
244
|
+
contractInstance.publicKeys.fbpkMHash,
|
|
247
245
|
];
|
|
248
246
|
const logFields = [
|
|
249
247
|
CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG,
|
|
@@ -252,6 +250,7 @@ export async function addNewContractInstanceToTx(
|
|
|
252
250
|
new Fr(contractInstance.salt),
|
|
253
251
|
contractInstance.currentContractClassId,
|
|
254
252
|
contractInstance.initializationHash,
|
|
253
|
+
contractInstance.immutablesHash,
|
|
255
254
|
...publicKeysAsFields,
|
|
256
255
|
contractInstance.deployer.toField(),
|
|
257
256
|
];
|
|
@@ -83,6 +83,7 @@ export class HintingPublicContractsDB implements PublicContractsDBInterface {
|
|
|
83
83
|
instance.currentContractClassId,
|
|
84
84
|
instance.originalContractClassId,
|
|
85
85
|
instance.initializationHash,
|
|
86
|
+
instance.immutablesHash,
|
|
86
87
|
instance.publicKeys,
|
|
87
88
|
),
|
|
88
89
|
);
|
|
@@ -554,6 +555,10 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
|
|
|
554
555
|
return this.db.getRevision();
|
|
555
556
|
}
|
|
556
557
|
|
|
558
|
+
public getIpcPath(): string {
|
|
559
|
+
return this.db.getIpcPath();
|
|
560
|
+
}
|
|
561
|
+
|
|
557
562
|
public async updateArchive(header: any): Promise<void> {
|
|
558
563
|
return await this.db.updateArchive(header);
|
|
559
564
|
}
|
|
@@ -55,7 +55,8 @@ export class PublicContractsDB implements PublicContractsDBInterface {
|
|
|
55
55
|
this.log = createLogger('simulator:contracts-data-source', bindings);
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
/** Parses raw log data from the C++/NAPI bridge and inserts the resulting contracts into the current checkpoint. */
|
|
59
|
+
public addContractsFromLogs(contractDeploymentData: ContractDeploymentData): void {
|
|
59
60
|
const currentState = this.getCurrentState();
|
|
60
61
|
|
|
61
62
|
this.addContractClassesFromEvents(
|
|
@@ -71,8 +72,16 @@ export class PublicContractsDB implements PublicContractsDBInterface {
|
|
|
71
72
|
|
|
72
73
|
public addNewContracts(tx: Tx): void {
|
|
73
74
|
const contractDeploymentData = AllContractDeploymentData.fromTx(tx);
|
|
74
|
-
this.
|
|
75
|
-
this.
|
|
75
|
+
this.addContractsFromLogs(contractDeploymentData.getNonRevertibleContractDeploymentData());
|
|
76
|
+
this.addContractsFromLogs(contractDeploymentData.getRevertibleContractDeploymentData());
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Inserts typed contract instances directly into the current checkpoint. */
|
|
80
|
+
public addContracts(contractInstances?: ContractInstanceWithAddress[]): void {
|
|
81
|
+
const currentState = this.getCurrentState();
|
|
82
|
+
for (const instance of contractInstances ?? []) {
|
|
83
|
+
currentState.addInstance(instance.address, instance);
|
|
84
|
+
}
|
|
76
85
|
}
|
|
77
86
|
|
|
78
87
|
/**
|
|
@@ -12,7 +12,7 @@ import type {
|
|
|
12
12
|
TreeInfo,
|
|
13
13
|
} from '@aztec/stdlib/trees';
|
|
14
14
|
import type { BlockHeader, StateReference } from '@aztec/stdlib/tx';
|
|
15
|
-
import type { WorldStateRevision
|
|
15
|
+
import type { WorldStateRevision } from '@aztec/stdlib/world-state';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Wraps an instance of `MerkleTreeWriteOperations` to allow the sequencer to gate access.
|
|
@@ -94,9 +94,12 @@ export class GuardedMerkleTreeOperations implements MerkleTreeWriteOperations {
|
|
|
94
94
|
getInitialHeader(): BlockHeader {
|
|
95
95
|
return this.target.getInitialHeader();
|
|
96
96
|
}
|
|
97
|
-
public getRevision(): WorldStateRevision
|
|
97
|
+
public getRevision(): WorldStateRevision {
|
|
98
98
|
return this.target.getRevision();
|
|
99
99
|
}
|
|
100
|
+
public getIpcPath(): string {
|
|
101
|
+
return this.target.getIpcPath();
|
|
102
|
+
}
|
|
100
103
|
getSiblingPath<ID extends MerkleTreeId>(treeId: ID, index: bigint): Promise<SiblingPath<TreeHeights[ID]>> {
|
|
101
104
|
return this.guardAndPush(() => this.target.getSiblingPath(treeId, index));
|
|
102
105
|
}
|
|
@@ -3,7 +3,7 @@ import { padArrayEnd } from '@aztec/foundation/collection';
|
|
|
3
3
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
4
|
import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
|
|
5
5
|
import { sleep } from '@aztec/foundation/sleep';
|
|
6
|
-
import { DateProvider, Timer, elapsed,
|
|
6
|
+
import { DateProvider, Timer, elapsed, execWithSignal } from '@aztec/foundation/timer';
|
|
7
7
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
8
8
|
import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
|
|
9
9
|
import { computeFeePayerBalanceLeafSlot, computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
@@ -76,17 +76,15 @@ export class PublicProcessorFactory {
|
|
|
76
76
|
/**
|
|
77
77
|
* Creates a new instance of a PublicProcessor.
|
|
78
78
|
* @param globalVariables - The global variables for the block being processed.
|
|
79
|
-
* @param
|
|
79
|
+
* @param contractsDB - Optional pre-populated contracts DB; a fresh one is constructed if omitted.
|
|
80
80
|
* @returns A new instance of a PublicProcessor.
|
|
81
81
|
*/
|
|
82
82
|
public create(
|
|
83
83
|
merkleTree: MerkleTreeWriteOperations,
|
|
84
84
|
globalVariables: GlobalVariables,
|
|
85
85
|
config: PublicSimulatorConfig,
|
|
86
|
+
contractsDB: PublicContractsDB = new PublicContractsDB(this.contractDataSource, this.log.getBindings()),
|
|
86
87
|
): PublicProcessor {
|
|
87
|
-
const bindings = this.log.getBindings();
|
|
88
|
-
const contractsDB = new PublicContractsDB(this.contractDataSource, bindings);
|
|
89
|
-
|
|
90
88
|
const guardedFork = new GuardedMerkleTreeOperations(merkleTree);
|
|
91
89
|
const publicTxSimulator = this.createPublicTxSimulator(guardedFork, contractsDB, globalVariables, config);
|
|
92
90
|
|
|
@@ -97,7 +95,7 @@ export class PublicProcessorFactory {
|
|
|
97
95
|
publicTxSimulator,
|
|
98
96
|
this.dateProvider,
|
|
99
97
|
this.telemetryClient,
|
|
100
|
-
createLogger('simulator:public-processor',
|
|
98
|
+
createLogger('simulator:public-processor', this.log.getBindings()),
|
|
101
99
|
);
|
|
102
100
|
}
|
|
103
101
|
|
|
@@ -125,6 +123,17 @@ class PublicProcessorTimeoutError extends Error {
|
|
|
125
123
|
}
|
|
126
124
|
}
|
|
127
125
|
|
|
126
|
+
class PublicProcessorAbortError extends Error {
|
|
127
|
+
constructor(message: string = 'Aborted while processing tx') {
|
|
128
|
+
super(message);
|
|
129
|
+
this.name = 'PublicProcessorAbortError';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isPublicProcessorInterruptError(err: any) {
|
|
134
|
+
return err?.name === 'PublicProcessorTimeoutError' || err?.name === 'PublicProcessorAbortError';
|
|
135
|
+
}
|
|
136
|
+
|
|
128
137
|
/**
|
|
129
138
|
* Converts Txs lifted from the P2P module into ProcessedTx objects by executing
|
|
130
139
|
* any public function calls in them. Txs with private calls only are unaffected.
|
|
@@ -161,7 +170,7 @@ export class PublicProcessor implements Traceable {
|
|
|
161
170
|
limits: PublicProcessorLimits = {},
|
|
162
171
|
validator: PublicProcessorValidator = {},
|
|
163
172
|
): Promise<[ProcessedTx[], FailedTx[], Tx[], NestedProcessReturnValues[], DebugLog[]]> {
|
|
164
|
-
const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal } = limits;
|
|
173
|
+
const { maxTransactions, deadline, maxBlockGas, maxBlobFields, isBuildingProposal, signal } = limits;
|
|
165
174
|
const { preprocessValidator, nullifierCache } = validator;
|
|
166
175
|
const result: ProcessedTx[] = [];
|
|
167
176
|
const usedTxs: Tx[] = [];
|
|
@@ -174,6 +183,8 @@ export class PublicProcessor implements Traceable {
|
|
|
174
183
|
let totalPublicGas = new Gas(0, 0);
|
|
175
184
|
let totalBlockGas = new Gas(0, 0);
|
|
176
185
|
let totalBlobFields = 0;
|
|
186
|
+
let silentlySkippedCount = 0;
|
|
187
|
+
let totalSilentlySkippedDurationMs = 0;
|
|
177
188
|
|
|
178
189
|
for await (const tx of txs) {
|
|
179
190
|
// Only process up to the max tx limit
|
|
@@ -182,11 +193,15 @@ export class PublicProcessor implements Traceable {
|
|
|
182
193
|
break;
|
|
183
194
|
}
|
|
184
195
|
|
|
185
|
-
// Bail if we've hit the deadline
|
|
196
|
+
// Bail if we've hit the deadline or have been interrupted.
|
|
186
197
|
if (deadline && this.dateProvider.now() > +deadline) {
|
|
187
198
|
this.log.warn(`Stopping tx processing due to timeout.`);
|
|
188
199
|
break;
|
|
189
200
|
}
|
|
201
|
+
if (signal?.aborted) {
|
|
202
|
+
this.log.warn(`Stopping tx processing due to abort signal.`);
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
190
205
|
|
|
191
206
|
const txHash = tx.getTxHash().toString();
|
|
192
207
|
|
|
@@ -224,11 +239,6 @@ export class PublicProcessor implements Traceable {
|
|
|
224
239
|
failed.push({ tx, error: new Error(`Tx failed preprocess validation: ${reason}`) });
|
|
225
240
|
returns.push(new NestedProcessReturnValues([]));
|
|
226
241
|
continue;
|
|
227
|
-
} else if (result.result === 'skipped') {
|
|
228
|
-
const reason = result.reason.join(', ');
|
|
229
|
-
this.log.debug(`Skipping tx ${txHash.toString()} due to pre-process validation: ${reason}`);
|
|
230
|
-
returns.push(new NestedProcessReturnValues([]));
|
|
231
|
-
continue;
|
|
232
242
|
} else {
|
|
233
243
|
this.log.trace(`Tx ${txHash.toString()} is valid before processing.`);
|
|
234
244
|
}
|
|
@@ -244,7 +254,9 @@ export class PublicProcessor implements Traceable {
|
|
|
244
254
|
this.contractsDB.createCheckpoint();
|
|
245
255
|
|
|
246
256
|
try {
|
|
247
|
-
const [processedTx, returnValues, txDebugLogs] = await
|
|
257
|
+
const [txProcessingTimeMs, [processedTx, returnValues, txDebugLogs]] = await elapsed(() =>
|
|
258
|
+
this.processTx(tx, deadline, signal),
|
|
259
|
+
);
|
|
248
260
|
|
|
249
261
|
// Inject a fake processing failure after N txs if requested
|
|
250
262
|
const fakeThrowAfter = this.opts.fakeThrowAfterProcessingTxCount;
|
|
@@ -265,8 +277,12 @@ export class PublicProcessor implements Traceable {
|
|
|
265
277
|
txBlobFields,
|
|
266
278
|
totalBlobFields,
|
|
267
279
|
maxBlobFields,
|
|
280
|
+
txProcessingTimeMs,
|
|
268
281
|
},
|
|
269
282
|
);
|
|
283
|
+
silentlySkippedCount += 1;
|
|
284
|
+
totalSilentlySkippedDurationMs += txProcessingTimeMs;
|
|
285
|
+
this.metrics.recordSilentlySkipped(txProcessingTimeMs);
|
|
270
286
|
// Need to revert the checkpoint here and don't go any further
|
|
271
287
|
await checkpoint.revert();
|
|
272
288
|
this.contractsDB.revertCheckpoint();
|
|
@@ -310,15 +326,11 @@ export class PublicProcessor implements Traceable {
|
|
|
310
326
|
// Commit the tx-level contracts checkpoint on success
|
|
311
327
|
this.contractsDB.commitCheckpoint();
|
|
312
328
|
} catch (err: any) {
|
|
313
|
-
if (err
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
//
|
|
317
|
-
// Signal cancellation AND WAIT for the simulation to actually stop.
|
|
318
|
-
// This is critical because C++ might be in the middle of a slow operation (e.g., pad_trees)
|
|
319
|
-
// and won't check the cancellation flag until that operation completes.
|
|
320
|
-
// Without waiting, we'd proceed to revert checkpoints while C++ is still writing to state.
|
|
321
|
-
// Wait for C++ to stop gracefully.
|
|
329
|
+
if (isPublicProcessorInterruptError(err)) {
|
|
330
|
+
const interruptReason = err.name === 'PublicProcessorTimeoutError' ? 'timeout' : 'abort signal';
|
|
331
|
+
this.log.warn(`Stopping tx processing due to ${interruptReason}.`);
|
|
332
|
+
// The tx may still be executing on a worker thread (C++ via NAPI).
|
|
333
|
+
// Signal cancellation AND WAIT for the simulation to actually stop before touching fork checkpoints.
|
|
322
334
|
await this.publicTxSimulator.cancel?.();
|
|
323
335
|
|
|
324
336
|
// Now stop the guarded fork to prevent any further TS-side access to the world state.
|
|
@@ -364,13 +376,24 @@ export class PublicProcessor implements Traceable {
|
|
|
364
376
|
const rate = duration > 0 ? totalPublicGas.l2Gas / duration : 0;
|
|
365
377
|
this.metrics.recordAllTxs(totalPublicGas, rate);
|
|
366
378
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
379
|
+
const silentlySkippedDurationMs = Math.round(totalSilentlySkippedDurationMs);
|
|
380
|
+
this.log.info(
|
|
381
|
+
`Processed ${result.length} successful txs and ${failed.length} failed txs ` +
|
|
382
|
+
`(${silentlySkippedCount} silently skipped, ${silentlySkippedDurationMs}ms wasted) ` +
|
|
383
|
+
`in ${duration}s`,
|
|
384
|
+
{
|
|
385
|
+
blockNumber: this.globalVariables.blockNumber,
|
|
386
|
+
successfulCount: result.length,
|
|
387
|
+
failedCount: failed.length,
|
|
388
|
+
duration,
|
|
389
|
+
rate,
|
|
390
|
+
totalPublicGas,
|
|
391
|
+
totalBlockGas,
|
|
392
|
+
totalSizeInBytes,
|
|
393
|
+
silentlySkippedCount,
|
|
394
|
+
silentlySkippedDurationMs,
|
|
395
|
+
},
|
|
396
|
+
);
|
|
374
397
|
|
|
375
398
|
return [result, failed, usedTxs, returns, debugLogs];
|
|
376
399
|
}
|
|
@@ -395,9 +418,10 @@ export class PublicProcessor implements Traceable {
|
|
|
395
418
|
private async processTx(
|
|
396
419
|
tx: Tx,
|
|
397
420
|
deadline: Date | undefined,
|
|
421
|
+
signal: AbortSignal | undefined,
|
|
398
422
|
): Promise<[ProcessedTx, NestedProcessReturnValues[], DebugLog[]]> {
|
|
399
423
|
const [time, [processedTx, returnValues, debugLogs]] = await elapsed(() =>
|
|
400
|
-
this.processTxWithinDeadline(tx, deadline),
|
|
424
|
+
this.processTxWithinDeadline(tx, deadline, signal),
|
|
401
425
|
);
|
|
402
426
|
|
|
403
427
|
this.log.verbose(
|
|
@@ -451,10 +475,11 @@ export class PublicProcessor implements Traceable {
|
|
|
451
475
|
this.metrics.recordTreeInsertions(Number(treeInsertionEnd - treeInsertionStart) / 1_000);
|
|
452
476
|
}
|
|
453
477
|
|
|
454
|
-
/** Processes the given tx within deadline
|
|
478
|
+
/** Processes the given tx within deadline or until the signal is aborted. */
|
|
455
479
|
private async processTxWithinDeadline(
|
|
456
480
|
tx: Tx,
|
|
457
481
|
deadline: Date | undefined,
|
|
482
|
+
signal: AbortSignal | undefined,
|
|
458
483
|
): Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> {
|
|
459
484
|
const innerProcessFn: () => Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> =
|
|
460
485
|
tx.hasPublicCalls() ? () => this.processTxWithPublicCalls(tx) : () => this.processPrivateOnlyTx(tx);
|
|
@@ -471,27 +496,38 @@ export class PublicProcessor implements Traceable {
|
|
|
471
496
|
}
|
|
472
497
|
: innerProcessFn;
|
|
473
498
|
|
|
474
|
-
|
|
499
|
+
const processingSignal = this.getProcessingSignal(tx, deadline, signal);
|
|
500
|
+
if (!processingSignal) {
|
|
475
501
|
return await processFn();
|
|
476
502
|
}
|
|
477
503
|
|
|
478
|
-
|
|
504
|
+
return await execWithSignal(
|
|
505
|
+
() => processFn(),
|
|
506
|
+
processingSignal,
|
|
507
|
+
signal =>
|
|
508
|
+
signal.reason?.name === 'TimeoutError' ? new PublicProcessorTimeoutError() : new PublicProcessorAbortError(),
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
private getProcessingSignal(tx: Tx, deadline: Date | undefined, signal: AbortSignal | undefined) {
|
|
513
|
+
if (!deadline) {
|
|
514
|
+
return signal;
|
|
515
|
+
}
|
|
516
|
+
|
|
479
517
|
const timeout = +deadline - this.dateProvider.now();
|
|
480
518
|
if (timeout <= 0) {
|
|
481
519
|
throw new PublicProcessorTimeoutError();
|
|
482
520
|
}
|
|
483
521
|
|
|
522
|
+
const txHash = tx.getTxHash();
|
|
484
523
|
this.log.debug(`Processing tx ${txHash.toString()} within ${timeout}ms`, {
|
|
485
524
|
deadline: deadline.toISOString(),
|
|
486
525
|
now: new Date(this.dateProvider.now()).toISOString(),
|
|
487
526
|
txHash,
|
|
488
527
|
});
|
|
489
528
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
timeout,
|
|
493
|
-
() => new PublicProcessorTimeoutError(),
|
|
494
|
-
);
|
|
529
|
+
const timeoutSignal = AbortSignal.timeout(timeout);
|
|
530
|
+
return signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
|
|
495
531
|
}
|
|
496
532
|
|
|
497
533
|
/**
|
|
@@ -30,6 +30,9 @@ export class PublicProcessorMetrics {
|
|
|
30
30
|
|
|
31
31
|
private treeInsertionDuration: Histogram;
|
|
32
32
|
|
|
33
|
+
private silentlySkippedCount: UpDownCounter;
|
|
34
|
+
private silentlySkippedDuration: Histogram;
|
|
35
|
+
|
|
33
36
|
constructor(client: TelemetryClient, name = 'PublicProcessor') {
|
|
34
37
|
this.tracer = client.getTracer(name);
|
|
35
38
|
const meter = client.getMeter(name);
|
|
@@ -60,6 +63,10 @@ export class PublicProcessorMetrics {
|
|
|
60
63
|
this.gasRate = meter.createHistogram(Metrics.PUBLIC_PROCESSOR_GAS_RATE);
|
|
61
64
|
|
|
62
65
|
this.treeInsertionDuration = meter.createHistogram(Metrics.PUBLIC_PROCESSOR_TREE_INSERTION);
|
|
66
|
+
|
|
67
|
+
this.silentlySkippedCount = createUpDownCounterWithDefault(meter, Metrics.PUBLIC_PROCESSOR_SILENTLY_SKIPPED_COUNT);
|
|
68
|
+
|
|
69
|
+
this.silentlySkippedDuration = meter.createHistogram(Metrics.PUBLIC_PROCESSOR_SILENTLY_SKIPPED_DURATION);
|
|
63
70
|
}
|
|
64
71
|
|
|
65
72
|
recordPhaseDuration(phaseName: TxExecutionPhase, durationMs: number) {
|
|
@@ -123,4 +130,9 @@ export class PublicProcessorMetrics {
|
|
|
123
130
|
recordTreeInsertions(durationUs: number) {
|
|
124
131
|
this.treeInsertionDuration.record(Math.ceil(durationUs));
|
|
125
132
|
}
|
|
133
|
+
|
|
134
|
+
recordSilentlySkipped(durationMs: number) {
|
|
135
|
+
this.silentlySkippedCount.add(1);
|
|
136
|
+
this.silentlySkippedDuration.record(Math.ceil(durationMs));
|
|
137
|
+
}
|
|
126
138
|
}
|
|
@@ -62,8 +62,8 @@ export class ContractProviderForCpp implements ContractProvider {
|
|
|
62
62
|
const contractDeploymentData = ContractDeploymentData.fromPlainObject(rawData);
|
|
63
63
|
|
|
64
64
|
// Add contracts to the contracts DB
|
|
65
|
-
this.log.trace(`Calling contractsDB.
|
|
66
|
-
this.contractsDB.
|
|
65
|
+
this.log.trace(`Calling contractsDB.addContractsFromLogs`);
|
|
66
|
+
this.contractsDB.addContractsFromLogs(contractDeploymentData);
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
public getBytecodeCommitment = async (classId: string): Promise<Buffer | undefined> => {
|
|
@@ -12,11 +12,8 @@ import {
|
|
|
12
12
|
import { SimulationError } from '@aztec/stdlib/errors';
|
|
13
13
|
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
|
|
14
14
|
import type { GlobalVariables, Tx } from '@aztec/stdlib/tx';
|
|
15
|
-
import { WorldStateRevisionWithHandle } from '@aztec/stdlib/world-state';
|
|
16
15
|
import { type TelemetryClient, type Tracer, getTelemetryClient } from '@aztec/telemetry-client';
|
|
17
16
|
|
|
18
|
-
import { strict as assert } from 'assert';
|
|
19
|
-
|
|
20
17
|
import { ExecutorMetrics } from '../executor_metrics.js';
|
|
21
18
|
import type { ExecutorMetricsInterface } from '../executor_metrics_interface.js';
|
|
22
19
|
import type { PublicContractsDB } from '../public_db_sources.js';
|
|
@@ -62,14 +59,8 @@ export class CppPublicTxSimulator extends PublicTxSimulator implements PublicTxS
|
|
|
62
59
|
txHash,
|
|
63
60
|
});
|
|
64
61
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
assert(
|
|
68
|
-
wsRevision instanceof WorldStateRevisionWithHandle,
|
|
69
|
-
'CppPublicTxSimulator a real NativeWorldStateInstance with a handle to the C++ WorldState object',
|
|
70
|
-
);
|
|
71
|
-
const wsCppHandle = (wsRevision as WorldStateRevisionWithHandle).handle;
|
|
72
|
-
wsRevision = wsRevision.toWorldStateRevision(); // for msgpack serialization, we don't include the handle in the type
|
|
62
|
+
const wsRevision = this.merkleTree.getRevision();
|
|
63
|
+
const wsdbIpcPath = this.merkleTree.getIpcPath();
|
|
73
64
|
|
|
74
65
|
this.log.trace(`Running C++ simulation with world state revision ${JSON.stringify(wsRevision)}`);
|
|
75
66
|
|
|
@@ -99,7 +90,7 @@ export class CppPublicTxSimulator extends PublicTxSimulator implements PublicTxS
|
|
|
99
90
|
this.simulationPromise = avmSimulate(
|
|
100
91
|
inputBuffer,
|
|
101
92
|
contractProvider,
|
|
102
|
-
|
|
93
|
+
wsdbIpcPath,
|
|
103
94
|
this.log.level,
|
|
104
95
|
undefined,
|
|
105
96
|
this.cancellationToken,
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
import { SimulationError } from '@aztec/stdlib/errors';
|
|
12
12
|
import type { MerkleTreeWriteOperations } from '@aztec/stdlib/trees';
|
|
13
13
|
import type { GlobalVariables, StateReference, Tx } from '@aztec/stdlib/tx';
|
|
14
|
-
import { WorldStateRevisionWithHandle } from '@aztec/stdlib/world-state';
|
|
15
14
|
|
|
16
15
|
import { strict as assert } from 'assert';
|
|
17
16
|
|
|
@@ -81,14 +80,8 @@ export class CppVsTsPublicTxSimulator extends PublicTxSimulator implements Publi
|
|
|
81
80
|
|
|
82
81
|
this.log.debug(`Running C++ simulation for tx ${txHash}`);
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
assert(
|
|
87
|
-
wsRevision instanceof WorldStateRevisionWithHandle,
|
|
88
|
-
'CppPublicTxSimulator a real NativeWorldStateInstance with a handle to the C++ WorldState object',
|
|
89
|
-
);
|
|
90
|
-
const wsCppHandle = (wsRevision as WorldStateRevisionWithHandle).handle;
|
|
91
|
-
wsRevision = wsRevision.toWorldStateRevision(); // for msgpack serialization, we don't include the handle in the type
|
|
83
|
+
const wsRevision = this.merkleTree.getRevision();
|
|
84
|
+
const wsdbIpcPath = this.merkleTree.getIpcPath();
|
|
92
85
|
|
|
93
86
|
this.log.debug(`Running C++ simulation with world state revision ${JSON.stringify(wsRevision)}`);
|
|
94
87
|
|
|
@@ -113,7 +106,7 @@ export class CppVsTsPublicTxSimulator extends PublicTxSimulator implements Publi
|
|
|
113
106
|
let resultBuffer: Buffer;
|
|
114
107
|
try {
|
|
115
108
|
this.log.debug(`Calling C++ simulator for tx ${txHash}`);
|
|
116
|
-
resultBuffer = await avmSimulate(inputBuffer, contractProvider,
|
|
109
|
+
resultBuffer = await avmSimulate(inputBuffer, contractProvider, wsdbIpcPath, logLevel);
|
|
117
110
|
} catch (error: any) {
|
|
118
111
|
throw new SimulationError(`C++ simulation failed: ${error.message}`, []);
|
|
119
112
|
}
|
|
@@ -401,7 +401,7 @@ export class PublicTxSimulator implements PublicTxSimulatorInterface {
|
|
|
401
401
|
// However, things work as expected because later calls to getters on the hintingContractsDB
|
|
402
402
|
// will pick up the new contracts and will generate the necessary hints.
|
|
403
403
|
// So, a consumer of the hints will always see the new contracts.
|
|
404
|
-
this.contractsDB.
|
|
404
|
+
this.contractsDB.addContractsFromLogs(context.nonRevertibleContractDeploymentData);
|
|
405
405
|
}
|
|
406
406
|
|
|
407
407
|
/**
|
|
@@ -490,7 +490,7 @@ export class PublicTxSimulator implements PublicTxSimulatorInterface {
|
|
|
490
490
|
// However, things work as expected because later calls to getters on the hintingContractsDB
|
|
491
491
|
// will pick up the new contracts and will generate the necessary hints.
|
|
492
492
|
// So, a consumer of the hints will always see the new contracts.
|
|
493
|
-
this.contractsDB.
|
|
493
|
+
this.contractsDB.addContractsFromLogs(context.revertibleContractDeploymentData);
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
private async payFee(context: PublicTxContext) {
|