@aztec/simulator 5.0.0-rc.1 → 5.0.0

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.
Files changed (41) hide show
  1. package/dest/client.d.ts +1 -3
  2. package/dest/client.d.ts.map +1 -1
  3. package/dest/client.js +0 -2
  4. package/dest/private/circuit_recording/circuit_recorder.d.ts +36 -23
  5. package/dest/private/circuit_recording/circuit_recorder.d.ts.map +1 -1
  6. package/dest/private/circuit_recording/circuit_recorder.js +65 -69
  7. package/dest/private/circuit_recording/file_circuit_recorder.d.ts +7 -19
  8. package/dest/private/circuit_recording/file_circuit_recorder.d.ts.map +1 -1
  9. package/dest/private/circuit_recording/file_circuit_recorder.js +38 -42
  10. package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts +1 -1
  11. package/dest/private/circuit_recording/simulator_recorder_wrapper.d.ts.map +1 -1
  12. package/dest/private/circuit_recording/simulator_recorder_wrapper.js +11 -14
  13. package/dest/public/avm/fixtures/base_avm_simulation_tester.js +1 -1
  14. package/dest/public/avm/fixtures/utils.js +1 -1
  15. package/dest/public/fixtures/amm_test.js +2 -2
  16. package/dest/public/fixtures/bulk_test.js +2 -2
  17. package/dest/public/fixtures/custom_bytecode_tester.d.ts +1 -1
  18. package/dest/public/fixtures/custom_bytecode_tester.d.ts.map +1 -1
  19. package/dest/public/fixtures/custom_bytecode_tester.js +2 -2
  20. package/dest/public/fixtures/custom_bytecode_tests.d.ts +6 -1
  21. package/dest/public/fixtures/custom_bytecode_tests.d.ts.map +1 -1
  22. package/dest/public/fixtures/custom_bytecode_tests.js +31 -2
  23. package/dest/public/fixtures/token_test.js +3 -3
  24. package/dest/public/fixtures/utils.js +1 -1
  25. package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +2 -2
  26. package/dest/public/state_manager/state_manager.js +1 -1
  27. package/package.json +16 -16
  28. package/src/client.ts +0 -2
  29. package/src/private/circuit_recording/circuit_recorder.ts +84 -78
  30. package/src/private/circuit_recording/file_circuit_recorder.ts +38 -48
  31. package/src/private/circuit_recording/simulator_recorder_wrapper.ts +9 -15
  32. package/src/public/avm/fixtures/base_avm_simulation_tester.ts +1 -1
  33. package/src/public/avm/fixtures/utils.ts +1 -1
  34. package/src/public/fixtures/amm_test.ts +2 -2
  35. package/src/public/fixtures/bulk_test.ts +2 -2
  36. package/src/public/fixtures/custom_bytecode_tester.ts +2 -2
  37. package/src/public/fixtures/custom_bytecode_tests.ts +71 -2
  38. package/src/public/fixtures/token_test.ts +3 -3
  39. package/src/public/fixtures/utils.ts +1 -1
  40. package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +2 -2
  41. package/src/public/state_manager/state_manager.ts +1 -1
@@ -58,24 +58,18 @@ export class SimulatorRecorderWrapper implements CircuitSimulator {
58
58
  functionName: string,
59
59
  callback: C,
60
60
  ): Promise<T> {
61
- // Start recording circuit execution
62
- await this.recorder.start(input, bytecode, contractName, functionName);
63
-
64
- // If callback was provided, we wrap it in a circuit recorder callback wrapper
61
+ // If a callback was provided, we wrap it so that its oracle calls are recorded. The wrapped callback reads the
62
+ // active recording lazily, so it picks up the recording opened by record() below.
65
63
  const wrappedCallback = this.recorder.wrapCallback(callback);
66
- let result: T;
67
- try {
68
- result = await simulateFn(wrappedCallback as C);
69
- } catch (error) {
70
- // If an error occurs, we finalize the recording file with the error
71
- await this.recorder.finishWithError(error);
72
- throw error;
73
- }
74
64
 
75
- // Witness generation is complete so we finish the circuit recorder
76
- const recording = await this.recorder.finish();
65
+ // record() opens a recording for this circuit, runs the simulation within it, and finalizes it. A simulation
66
+ // failure is re-thrown unchanged, so recorder bookkeeping never masks the underlying error.
67
+ const { result, recording } = await this.recorder.record(
68
+ { input, bytecode, circuitName: contractName, functionName },
69
+ () => simulateFn(wrappedCallback as C),
70
+ );
77
71
 
78
- (result as ACIRExecutionResult).oracles = recording.oracleCalls?.reduce(
72
+ (result as ACIRExecutionResult).oracles = recording.oracleCalls.reduce(
79
73
  (acc, { time, name }) => {
80
74
  if (!acc[name]) {
81
75
  acc[name] = { times: [] };
@@ -149,7 +149,7 @@ export abstract class BaseAvmSimulationTester {
149
149
 
150
150
  private async insertContractAddressNullifier(contractAddress: AztecAddress) {
151
151
  const contractAddressNullifier = await siloNullifier(
152
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
152
+ AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
153
153
  contractAddress.toField(),
154
154
  );
155
155
  await this.merkleTrees.sequentialInsert(MerkleTreeId.NULLIFIER_TREE, [contractAddressNullifier.toBuffer()]);
@@ -146,7 +146,7 @@ export async function createContractClassAndInstance(
146
146
  });
147
147
 
148
148
  const contractAddressNullifier = await siloNullifier(
149
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
149
+ AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
150
150
  contractInstance.address.toField(),
151
151
  );
152
152
 
@@ -25,8 +25,8 @@ export async function ammTest(
25
25
  ) {
26
26
  const timer = new Timer();
27
27
 
28
- const admin = AztecAddress.fromNumber(42);
29
- const sender = AztecAddress.fromNumber(111);
28
+ const admin = AztecAddress.fromNumberUnsafe(42);
29
+ const sender = AztecAddress.fromNumberUnsafe(111);
30
30
 
31
31
  logger.debug(`Deploying tokens`);
32
32
  const token0 = await setUpToken(tester, tokenArtifact, admin, expectToBeTrue, /*seed=*/ 0);
@@ -13,7 +13,7 @@ export async function bulkTest(
13
13
  ) {
14
14
  const timer = new Timer();
15
15
 
16
- const deployer = AztecAddress.fromNumber(42);
16
+ const deployer = AztecAddress.fromNumberUnsafe(42);
17
17
  const avmTestContract = await tester.registerAndDeployContract(
18
18
  /*constructorArgs=*/ [],
19
19
  deployer,
@@ -114,7 +114,7 @@ export async function megaBulkTest(
114
114
  ) {
115
115
  const timer = new Timer();
116
116
 
117
- const deployer = AztecAddress.fromNumber(42);
117
+ const deployer = AztecAddress.fromNumberUnsafe(42);
118
118
  const avmTestContract = await tester.registerAndDeployContract(
119
119
  /*constructorArgs=*/ [],
120
120
  deployer,
@@ -17,7 +17,7 @@ export async function deployCustomBytecode(
17
17
  bytecode: Buffer,
18
18
  tester: PublicTxSimulationTester,
19
19
  contractName: string = 'CustomBytecodeContract',
20
- deployer: AztecAddress = AztecAddress.fromNumber(42),
20
+ deployer: AztecAddress = AztecAddress.fromNumberUnsafe(42),
21
21
  ): Promise<ContractInstanceWithAddress> {
22
22
  const contractArtifact = emptyContractArtifact();
23
23
  contractArtifact.name = contractName;
@@ -75,7 +75,7 @@ export async function deployAndExecuteCustomBytecode(
75
75
  tester: PublicTxSimulationTester,
76
76
  txLabel: string = 'CustomBytecodeTest',
77
77
  contractName: string = 'CustomBytecodeContract',
78
- deployer: AztecAddress = AztecAddress.fromNumber(42),
78
+ deployer: AztecAddress = AztecAddress.fromNumberUnsafe(42),
79
79
  calldata: any[] = [],
80
80
  ): Promise<PublicTxResult> {
81
81
  const testContract = await deployCustomBytecode(bytecode, tester, contractName, deployer);
@@ -1,8 +1,10 @@
1
+ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
2
+
1
3
  import { strict as assert } from 'assert';
2
4
 
3
5
  import { TypeTag } from '../avm/avm_memory_types.js';
4
6
  import { Addressing, AddressingMode } from '../avm/opcodes/addressing_mode.js';
5
- import { Add, CalldataCopy, Cast, Jump, Return, Set } from '../avm/opcodes/index.js';
7
+ import { Add, Call, CalldataCopy, Cast, Jump, Return, Set, Sha256Compression, Xor } from '../avm/opcodes/index.js';
6
8
  import { encodeToBytecode } from '../avm/serialization/bytecode_serialization.js';
7
9
  import {
8
10
  MAX_OPCODE_VALUE,
@@ -10,7 +12,7 @@ import {
10
12
  OperandType,
11
13
  getOperandSize,
12
14
  } from '../avm/serialization/instruction_serialization.js';
13
- import { deployAndExecuteCustomBytecode } from './custom_bytecode_tester.js';
15
+ import { deployAndExecuteCustomBytecode, deployCustomBytecode } from './custom_bytecode_tester.js';
14
16
  import { PublicTxSimulationTester } from './public_tx_simulation_tester.js';
15
17
 
16
18
  // First instruction resolved a base address (offset 0) which is uninitialized and therefore
@@ -364,3 +366,70 @@ function getTagOffsetInInstruction(wireFormat: OperandType[]): number {
364
366
  }
365
367
  return offset;
366
368
  }
369
+
370
+ export async function deployBitwiseSha256ErrorRowCollisionContracts(
371
+ tester: PublicTxSimulationTester,
372
+ ): Promise<{ innerContract: ContractInstanceWithAddress; outerContract: ContractInstanceWithAddress }> {
373
+ const innerBytecode = encodeToBytecode([
374
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
375
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 1, TypeTag.UINT16, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
376
+ new Xor(/*addressing_mode=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2).as(Opcode.XOR_8, Xor.wireFormat8),
377
+ new Return(/*addressing_mode=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0),
378
+ ]);
379
+
380
+ const outerInstructions = [
381
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 0, TypeTag.UINT32, /*value=*/ 0).as(Opcode.SET_8, Set.wireFormat8),
382
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 1, TypeTag.UINT32, /*value=*/ 1).as(Opcode.SET_8, Set.wireFormat8),
383
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 2, TypeTag.UINT32, /*value=*/ 100_000).as(
384
+ Opcode.SET_32,
385
+ Set.wireFormat32,
386
+ ),
387
+ new CalldataCopy(/*addressing_mode=*/ 0, /*copySizeOffset=*/ 1, /*cdStartOffset=*/ 0, /*dstOffset=*/ 3),
388
+ new Call(
389
+ /*addressing_mode=*/ 0,
390
+ /*l2GasOffset=*/ 2,
391
+ /*daGasOffset=*/ 2,
392
+ /*addrOffset=*/ 3,
393
+ /*argsSizeOffset=*/ 0,
394
+ /*argsOffset=*/ 0,
395
+ ),
396
+ ];
397
+
398
+ for (let i = 0; i < 8; i++) {
399
+ outerInstructions.push(
400
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 10 + i, TypeTag.UINT32, /*value=*/ 0).as(
401
+ Opcode.SET_8,
402
+ Set.wireFormat8,
403
+ ),
404
+ );
405
+ }
406
+
407
+ outerInstructions.push(
408
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 18, TypeTag.UINT32, /*value=*/ 0x61626364).as(
409
+ Opcode.SET_32,
410
+ Set.wireFormat32,
411
+ ),
412
+ );
413
+
414
+ for (let i = 0; i < 15; i++) {
415
+ outerInstructions.push(
416
+ new Set(/*addressing_mode=*/ 0, /*dstOffset=*/ 19 + i, TypeTag.UINT32, /*value=*/ 0).as(
417
+ Opcode.SET_8,
418
+ Set.wireFormat8,
419
+ ),
420
+ );
421
+ }
422
+
423
+ outerInstructions.push(
424
+ new Sha256Compression(/*addressing_mode=*/ 0, /*outputOffset=*/ 34, /*stateOffset=*/ 10, /*inputsOffset=*/ 18),
425
+ new Return(/*addressing_mode=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 0),
426
+ );
427
+
428
+ const innerContract = await deployCustomBytecode(innerBytecode, tester, 'BitwiseSha256CollisionInner');
429
+ const outerContract = await deployCustomBytecode(
430
+ encodeToBytecode(outerInstructions),
431
+ tester,
432
+ 'BitwiseSha256CollisionOuter',
433
+ );
434
+ return { innerContract, outerContract };
435
+ }
@@ -21,9 +21,9 @@ export async function tokenTest(
21
21
  ) {
22
22
  const timer = new Timer();
23
23
 
24
- const admin = AztecAddress.fromNumber(42);
25
- const sender = AztecAddress.fromNumber(111);
26
- const receiver = AztecAddress.fromNumber(222);
24
+ const admin = AztecAddress.fromNumberUnsafe(42);
25
+ const sender = AztecAddress.fromNumberUnsafe(111);
26
+ const receiver = AztecAddress.fromNumberUnsafe(222);
27
27
 
28
28
  const token = await setUpToken(tester, tokenArtifact, admin, expectToBeTrue);
29
29
 
@@ -255,7 +255,7 @@ export async function addNewContractInstanceToTx(
255
255
  );
256
256
 
257
257
  const contractAddressNullifier = await siloNullifier(
258
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
258
+ AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
259
259
  contractInstance.address.toField(),
260
260
  );
261
261
 
@@ -23,7 +23,7 @@ export class ContractProviderForCpp implements ContractProvider {
23
23
  public getContractInstance = async (address: string): Promise<Buffer | undefined> => {
24
24
  this.log.trace(`Contract provider callback: getContractInstance(${address})`);
25
25
 
26
- const aztecAddr = AztecAddress.fromString(address);
26
+ const aztecAddr = AztecAddress.fromStringUnsafe(address);
27
27
 
28
28
  const instance = await this.contractsDB.getContractInstance(aztecAddr, this.globalVariables.timestamp);
29
29
 
@@ -88,7 +88,7 @@ export class ContractProviderForCpp implements ContractProvider {
88
88
  this.log.trace(`Contract provider callback: getDebugFunctionName(${address}, ${selector})`);
89
89
 
90
90
  // Parse address and selector strings
91
- const aztecAddr = AztecAddress.fromString(address);
91
+ const aztecAddr = AztecAddress.fromStringUnsafe(address);
92
92
  const selectorFr = Fr.fromString(selector);
93
93
  const functionSelector = FunctionSelector.fromFieldOrUndefined(selectorFr);
94
94
 
@@ -402,7 +402,7 @@ export class PublicPersistableStateManager {
402
402
 
403
403
  // This will internally decide whether to check the nullifier tree or not depending on doMerkleOperations.
404
404
  const nullifierExistsInTree = await this.checkNullifierExists(
405
- AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
405
+ AztecAddress.fromNumberUnsafe(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
406
406
  contractAddress.toField(),
407
407
  );
408
408
  assert(