@aztec/simulator 0.0.1-commit.e6bd8901 → 0.0.1-commit.f146247c

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 (137) hide show
  1. package/dest/private/acvm/acvm.d.ts +4 -2
  2. package/dest/private/acvm/acvm.d.ts.map +1 -1
  3. package/dest/private/acvm/acvm.js +4 -3
  4. package/dest/private/acvm_native.d.ts +5 -3
  5. package/dest/private/acvm_native.d.ts.map +1 -1
  6. package/dest/private/acvm_native.js +8 -6
  7. package/dest/private/acvm_wasm.d.ts +4 -3
  8. package/dest/private/acvm_wasm.d.ts.map +1 -1
  9. package/dest/private/acvm_wasm.js +4 -4
  10. package/dest/private/circuit_recording/circuit_recorder.d.ts +4 -3
  11. package/dest/private/circuit_recording/circuit_recorder.d.ts.map +1 -1
  12. package/dest/private/circuit_recording/circuit_recorder.js +5 -3
  13. package/dest/private/circuit_recording/file_circuit_recorder.d.ts +3 -2
  14. package/dest/private/circuit_recording/file_circuit_recorder.d.ts.map +1 -1
  15. package/dest/private/circuit_recording/file_circuit_recorder.js +2 -2
  16. package/dest/private/circuit_recording/memory_circuit_recorder.d.ts +7 -2
  17. package/dest/private/circuit_recording/memory_circuit_recorder.d.ts.map +1 -1
  18. package/dest/private/circuit_recording/memory_circuit_recorder.js +4 -4
  19. package/dest/private/factory.d.ts +3 -3
  20. package/dest/private/factory.d.ts.map +1 -1
  21. package/dest/private/factory.js +7 -4
  22. package/dest/public/avm/avm_context.d.ts +3 -3
  23. package/dest/public/avm/avm_context.d.ts.map +1 -1
  24. package/dest/public/avm/avm_contract_call_result.d.ts +6 -6
  25. package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
  26. package/dest/public/avm/avm_contract_call_result.js +3 -3
  27. package/dest/public/avm/avm_execution_environment.d.ts +6 -5
  28. package/dest/public/avm/avm_execution_environment.d.ts.map +1 -1
  29. package/dest/public/avm/avm_machine_state.d.ts +6 -5
  30. package/dest/public/avm/avm_machine_state.d.ts.map +1 -1
  31. package/dest/public/avm/avm_machine_state.js +3 -2
  32. package/dest/public/avm/avm_simulator.d.ts +3 -2
  33. package/dest/public/avm/avm_simulator.d.ts.map +1 -1
  34. package/dest/public/avm/avm_simulator.js +5 -4
  35. package/dest/public/avm/calldata.d.ts +51 -0
  36. package/dest/public/avm/calldata.d.ts.map +1 -0
  37. package/dest/public/avm/calldata.js +63 -0
  38. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +1 -1
  39. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
  40. package/dest/public/avm/fixtures/avm_simulation_tester.js +3 -2
  41. package/dest/public/avm/fixtures/initializers.d.ts +1 -1
  42. package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
  43. package/dest/public/avm/fixtures/initializers.js +2 -1
  44. package/dest/public/avm/opcodes/accrued_substate.d.ts +3 -4
  45. package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
  46. package/dest/public/avm/opcodes/accrued_substate.js +12 -12
  47. package/dest/public/avm/opcodes/external_calls.d.ts +1 -1
  48. package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
  49. package/dest/public/avm/opcodes/external_calls.js +7 -7
  50. package/dest/public/avm/opcodes/memory.js +1 -1
  51. package/dest/public/debug_fn_name.d.ts +4 -4
  52. package/dest/public/debug_fn_name.d.ts.map +1 -1
  53. package/dest/public/debug_fn_name.js +7 -5
  54. package/dest/public/executor_metrics.d.ts +1 -1
  55. package/dest/public/executor_metrics.d.ts.map +1 -1
  56. package/dest/public/executor_metrics.js +7 -2
  57. package/dest/public/fixtures/opcode_spammer.d.ts +3 -4
  58. package/dest/public/fixtures/opcode_spammer.d.ts.map +1 -1
  59. package/dest/public/fixtures/opcode_spammer.js +10 -50
  60. package/dest/public/public_db_sources.d.ts +4 -3
  61. package/dest/public/public_db_sources.d.ts.map +1 -1
  62. package/dest/public/public_db_sources.js +4 -4
  63. package/dest/public/public_processor/public_processor.d.ts +5 -3
  64. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  65. package/dest/public/public_processor/public_processor.js +8 -5
  66. package/dest/public/public_processor/public_processor_metrics.d.ts +2 -2
  67. package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -1
  68. package/dest/public/public_processor/public_processor_metrics.js +20 -4
  69. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts +3 -2
  70. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts.map +1 -1
  71. package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +2 -2
  72. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +5 -5
  73. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -1
  74. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +8 -8
  75. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts +4 -4
  76. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts.map +1 -1
  77. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.js +5 -5
  78. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts +4 -4
  79. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts.map +1 -1
  80. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.js +6 -6
  81. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts +3 -2
  82. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts.map +1 -1
  83. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.js +2 -2
  84. package/dest/public/public_tx_simulator/factories.d.ts +3 -2
  85. package/dest/public/public_tx_simulator/factories.d.ts.map +1 -1
  86. package/dest/public/public_tx_simulator/factories.js +3 -3
  87. package/dest/public/public_tx_simulator/public_tx_context.d.ts +4 -3
  88. package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
  89. package/dest/public/public_tx_simulator/public_tx_context.js +8 -8
  90. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +4 -3
  91. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
  92. package/dest/public/public_tx_simulator/public_tx_simulator.js +9 -6
  93. package/dest/public/side_effect_trace.d.ts +4 -4
  94. package/dest/public/side_effect_trace.d.ts.map +1 -1
  95. package/dest/public/side_effect_trace.js +3 -3
  96. package/dest/public/state_manager/state_manager.d.ts +10 -4
  97. package/dest/public/state_manager/state_manager.d.ts.map +1 -1
  98. package/dest/public/state_manager/state_manager.js +12 -5
  99. package/dest/public/test_executor_metrics.d.ts +3 -2
  100. package/dest/public/test_executor_metrics.d.ts.map +1 -1
  101. package/dest/public/test_executor_metrics.js +2 -2
  102. package/package.json +16 -16
  103. package/src/private/acvm/acvm.ts +4 -3
  104. package/src/private/acvm_native.ts +11 -5
  105. package/src/private/acvm_wasm.ts +7 -3
  106. package/src/private/circuit_recording/circuit_recorder.ts +5 -3
  107. package/src/private/circuit_recording/file_circuit_recorder.ts +7 -2
  108. package/src/private/circuit_recording/memory_circuit_recorder.ts +6 -4
  109. package/src/private/factory.ts +7 -4
  110. package/src/public/avm/avm_context.ts +2 -2
  111. package/src/public/avm/avm_contract_call_result.ts +8 -6
  112. package/src/public/avm/avm_execution_environment.ts +9 -4
  113. package/src/public/avm/avm_machine_state.ts +6 -5
  114. package/src/public/avm/avm_simulator.ts +8 -5
  115. package/src/public/avm/calldata.ts +100 -0
  116. package/src/public/avm/fixtures/avm_simulation_tester.ts +8 -2
  117. package/src/public/avm/fixtures/initializers.ts +2 -1
  118. package/src/public/avm/opcodes/accrued_substate.ts +13 -15
  119. package/src/public/avm/opcodes/external_calls.ts +8 -7
  120. package/src/public/avm/opcodes/memory.ts +1 -1
  121. package/src/public/debug_fn_name.ts +10 -8
  122. package/src/public/executor_metrics.ts +4 -1
  123. package/src/public/fixtures/opcode_spammer.ts +12 -45
  124. package/src/public/public_db_sources.ts +15 -5
  125. package/src/public/public_processor/public_processor.ts +18 -5
  126. package/src/public/public_processor/public_processor_metrics.ts +10 -4
  127. package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +6 -3
  128. package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +9 -6
  129. package/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts +6 -4
  130. package/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts +7 -5
  131. package/src/public/public_tx_simulator/dumping_cpp_public_tx_simulator.ts +3 -1
  132. package/src/public/public_tx_simulator/factories.ts +4 -2
  133. package/src/public/public_tx_simulator/public_tx_context.ts +13 -6
  134. package/src/public/public_tx_simulator/public_tx_simulator.ts +14 -5
  135. package/src/public/side_effect_trace.ts +5 -2
  136. package/src/public/state_manager/state_manager.ts +27 -4
  137. package/src/public/test_executor_metrics.ts +3 -3
@@ -2,6 +2,7 @@ import type { Fr } from '@aztec/foundation/curves/bn254';
2
2
 
3
3
  import type { Gas } from './avm_gas.js';
4
4
  import { TaggedMemory } from './avm_memory_types.js';
5
+ import { type ReturnData, ReturnDataArray } from './calldata.js';
5
6
  import { type AvmRevertReason, OutOfGasError } from './errors.js';
6
7
 
7
8
  /**
@@ -39,7 +40,7 @@ export class AvmMachineState {
39
40
  /** program counter of the next instruction, byte based */
40
41
  public nextPc: number = 0;
41
42
  /** return/revertdata of the last nested call. */
42
- public nestedReturndata: Fr[] = [];
43
+ public nestedReturndata: ReturnData = new ReturnDataArray([]);
43
44
  /** Tracks whether the last external call was successful */
44
45
  public nestedCallSuccess: boolean = false;
45
46
  /**
@@ -66,7 +67,7 @@ export class AvmMachineState {
66
67
  /** Signals that execution has reverted normally (this does not cover exceptional halts) */
67
68
  private reverted: boolean = false;
68
69
  /** Output data must NOT be modified once it is set */
69
- private output: Fr[] = [];
70
+ private output: ReturnData = new ReturnDataArray([]);
70
71
 
71
72
  // Metrics only - not needed for execution
72
73
  /** instruction counter, including nested calls */
@@ -129,7 +130,7 @@ export class AvmMachineState {
129
130
  * Output data must NOT be modified once it is set
130
131
  * @param output
131
132
  */
132
- public return(output: Fr[]) {
133
+ public return(output: ReturnData) {
133
134
  this.halted = true;
134
135
  this.output = output;
135
136
  }
@@ -139,7 +140,7 @@ export class AvmMachineState {
139
140
  * Output data must NOT be modified once it is set
140
141
  * @param output
141
142
  */
142
- public revert(output: Fr[]) {
143
+ public revert(output: ReturnData) {
143
144
  this.halted = true;
144
145
  this.reverted = true;
145
146
  this.output = output;
@@ -153,7 +154,7 @@ export class AvmMachineState {
153
154
  return this.reverted;
154
155
  }
155
156
 
156
- public getOutput(): Fr[] {
157
+ public getOutput(): ReturnData {
157
158
  return this.output;
158
159
  }
159
160
 
@@ -15,6 +15,7 @@ import { AvmExecutionEnvironment } from './avm_execution_environment.js';
15
15
  import type { Gas } from './avm_gas.js';
16
16
  import { AvmMachineState } from './avm_machine_state.js';
17
17
  import type { AvmSimulatorInterface } from './avm_simulator_interface.js';
18
+ import { type CallData, ReturnDataArray } from './calldata.js';
18
19
  import { AvmRevertReason, InvalidProgramCounterError } from './errors.js';
19
20
  import type { Instruction } from './opcodes/instruction.js';
20
21
  import { revertReasonFromExceptionalHalt, revertReasonFromExplicitRevert } from './revert_reason.js';
@@ -49,7 +50,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
49
50
  // This will be used by the CALL opcode to create a new simulator. It is required to
50
51
  // avoid a dependency cycle.
51
52
  context.provideSimulator = AvmSimulator.build;
52
- this.log = createLogger(`simulator:avm(calldata[0]: ${context.environment.calldata[0]})`);
53
+ this.log = createLogger(`simulator:avm(calldata[0]: ${context.environment.calldata.read(0)})`);
53
54
  // Turn on tallying if explicitly enabled or if trace logging
54
55
  if (enableTallying || this.log.isLevelEnabled('trace')) {
55
56
  this.tallyPrintFunction = this.printOpcodeTallies;
@@ -74,7 +75,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
74
75
  transactionFee: Fr,
75
76
  globals: GlobalVariables,
76
77
  isStaticCall: boolean,
77
- calldata: Fr[],
78
+ calldata: CallData,
78
79
  allocatedGas: Gas,
79
80
  config: PublicSimulatorConfig,
80
81
  ) {
@@ -183,7 +184,9 @@ export class AvmSimulator implements AvmSimulatorInterface {
183
184
 
184
185
  const output = machineState.getOutput();
185
186
  const reverted = machineState.getReverted();
186
- const revertReason = reverted ? await revertReasonFromExplicitRevert(output, this.context) : undefined;
187
+ const revertReason = reverted
188
+ ? await revertReasonFromExplicitRevert(output.bestEffortReadAll(), this.context)
189
+ : undefined;
187
190
  const results = new AvmContractCallResult(
188
191
  reverted,
189
192
  output,
@@ -220,7 +223,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
220
223
  // Note: "exceptional halts" cannot return data, hence [].
221
224
  const results = new AvmContractCallResult(
222
225
  /*reverted=*/ true,
223
- /*output=*/ [],
226
+ /*output=*/ new ReturnDataArray([]),
224
227
  noGasLeft,
225
228
  revertReason,
226
229
  machineState.instrCounter,
@@ -250,7 +253,7 @@ export class AvmSimulator implements AvmSimulatorInterface {
250
253
  this.log.warn(message);
251
254
  return new AvmContractCallResult(
252
255
  /*reverted=*/ true,
253
- /*output=*/ [],
256
+ /*output=*/ new ReturnDataArray([]),
254
257
  /*gasLeft=*/ { l2Gas: 0, daGas: 0 }, // consumes all allocated gas
255
258
  revertReason,
256
259
  );
@@ -0,0 +1,100 @@
1
+ import type { Fr } from '@aztec/foundation/schemas';
2
+
3
+ import { TaggedMemory } from './avm_memory_types.js';
4
+
5
+ // Allow reading up to 300 kB of return data when unspecified.
6
+ const DEFAULT_BEST_EFFORT_READ_CAP = 10000;
7
+
8
+ export interface LazyReader {
9
+ bestEffortReadAll(readCap?: number): Fr[];
10
+ readAll(): Fr[];
11
+ read(idx: number): Fr | undefined;
12
+ slice(start: number, end: number): Fr[];
13
+ length(): number;
14
+ }
15
+
16
+ export class LazyReaderMemory implements LazyReader {
17
+ constructor(
18
+ private memory: TaggedMemory,
19
+ private offset: number,
20
+ private size: number,
21
+ ) {}
22
+
23
+ public bestEffortReadAll(readCap = DEFAULT_BEST_EFFORT_READ_CAP): Fr[] {
24
+ const size = Math.min(this.size, readCap, TaggedMemory.MAX_MEMORY_SIZE - this.offset);
25
+ return this.memory.getSlice(this.offset, size).map(word => word.toFr());
26
+ }
27
+
28
+ public read(idx: number): Fr | undefined {
29
+ if (idx >= this.size) {
30
+ return undefined;
31
+ }
32
+ return this.memory.get(this.offset + idx).toFr();
33
+ }
34
+
35
+ public slice(start: number, end: number): Fr[] {
36
+ const clampedEnd = Math.min(end, this.size);
37
+ const length = Math.max(0, clampedEnd - start);
38
+ return this.memory.getSlice(this.offset + start, length).map(word => word.toFr());
39
+ }
40
+
41
+ public readAll(): Fr[] {
42
+ return this.memory.getSlice(this.offset, this.size).map(word => word.toFr());
43
+ }
44
+
45
+ public length(): number {
46
+ return this.size;
47
+ }
48
+ }
49
+
50
+ export class LazyReaderArray implements LazyReader {
51
+ constructor(private array: Fr[]) {}
52
+
53
+ public bestEffortReadAll(readCap = DEFAULT_BEST_EFFORT_READ_CAP): Fr[] {
54
+ return this.array.slice(0, readCap);
55
+ }
56
+
57
+ public read(idx: number): Fr | undefined {
58
+ return this.array[idx];
59
+ }
60
+
61
+ public slice(start: number, end: number): Fr[] {
62
+ return this.array.slice(start, end);
63
+ }
64
+
65
+ public readAll(): Fr[] {
66
+ return this.array;
67
+ }
68
+
69
+ public length(): number {
70
+ return this.array.length;
71
+ }
72
+ }
73
+
74
+ // Compile time branding to avoid swapping CallData and ReturnData by accident.
75
+ declare const CallDataBrand: unique symbol;
76
+ declare const ReturnDataBrand: unique symbol;
77
+
78
+ export type CallData = LazyReader & {
79
+ readonly [CallDataBrand]: true;
80
+ };
81
+
82
+ export type ReturnData = LazyReader & {
83
+ readonly [ReturnDataBrand]: true;
84
+ };
85
+
86
+ export class CallDataArray extends LazyReaderArray implements CallData {
87
+ declare readonly [CallDataBrand]: true;
88
+ }
89
+
90
+ export class CallDataMemory extends LazyReaderMemory implements CallData {
91
+ declare readonly [CallDataBrand]: true;
92
+ }
93
+
94
+ export class ReturnDataArray extends LazyReaderArray implements ReturnData {
95
+ declare readonly [ReturnDataBrand]: true;
96
+ }
97
+
98
+ export class ReturnDataMemory extends LazyReaderMemory implements ReturnData {
99
+ declare readonly [ReturnDataBrand]: true;
100
+ }
@@ -13,6 +13,7 @@ import { SimpleContractDataSource } from '../../fixtures/simple_contract_data_so
13
13
  import { PublicContractsDB, PublicTreesDB } from '../../public_db_sources.js';
14
14
  import { PublicPersistableStateManager } from '../../state_manager/state_manager.js';
15
15
  import { AvmSimulator } from '../avm_simulator.js';
16
+ import { CallDataArray } from '../calldata.js';
16
17
  import { BaseAvmSimulationTester } from './base_avm_simulation_tester.js';
17
18
  import { initContext, initExecutionEnvironment } from './initializers.js';
18
19
  import {
@@ -89,7 +90,7 @@ export class AvmSimulationTester extends BaseAvmSimulationTester {
89
90
  collectCallMetadata: true,
90
91
  });
91
92
  const environment = initExecutionEnvironment({
92
- calldata,
93
+ calldata: new CallDataArray(calldata),
93
94
  globals,
94
95
  address,
95
96
  sender,
@@ -105,7 +106,12 @@ export class AvmSimulationTester extends BaseAvmSimulationTester {
105
106
  if (result.reverted) {
106
107
  this.logger.error(`Error in ${fnName}:`);
107
108
  this.logger.error(
108
- resolveContractAssertionMessage(fnName, result.revertReason!, result.output, contractArtifact)!,
109
+ resolveContractAssertionMessage(
110
+ fnName,
111
+ result.revertReason!,
112
+ result.output.bestEffortReadAll(),
113
+ contractArtifact,
114
+ )!,
109
115
  );
110
116
  } else {
111
117
  this.logger.info(`Simulation of function ${fnName} succeeded!`);
@@ -19,6 +19,7 @@ import { AvmContext } from '../avm_context.js';
19
19
  import { AvmExecutionEnvironment } from '../avm_execution_environment.js';
20
20
  import { AvmMachineState } from '../avm_machine_state.js';
21
21
  import { AvmSimulator } from '../avm_simulator.js';
22
+ import { CallDataArray } from '../calldata.js';
22
23
  import { DEFAULT_TIMESTAMP } from './utils.js';
23
24
 
24
25
  /**
@@ -70,7 +71,7 @@ export function initExecutionEnvironment(overrides?: Partial<AvmExecutionEnviron
70
71
  overrides?.transactionFee ?? Fr.zero(),
71
72
  overrides?.globals ?? GlobalVariables.empty(),
72
73
  overrides?.isStaticCall ?? false,
73
- overrides?.calldata ?? [],
74
+ overrides?.calldata ?? new CallDataArray([]),
74
75
  overrides?.config ?? PublicSimulatorConfig.empty(),
75
76
  );
76
77
  }
@@ -1,3 +1,5 @@
1
+ import { MAX_ETH_ADDRESS_VALUE } from '@aztec/constants';
2
+
1
3
  import { NullifierCollisionError } from '../../side_effect_errors.js';
2
4
  import type { AvmContext } from '../avm_context.js';
3
5
  import { TypeTag, Uint1 } from '../avm_memory_types.js';
@@ -86,18 +88,11 @@ export class NullifierExists extends Instruction {
86
88
  static type: string = 'NULLIFIEREXISTS';
87
89
  static readonly opcode: Opcode = Opcode.NULLIFIEREXISTS;
88
90
  // Informs (de)serialization. See Instruction.deserialize.
89
- static readonly wireFormat = [
90
- OperandType.UINT8,
91
- OperandType.UINT8,
92
- OperandType.UINT16,
93
- OperandType.UINT16,
94
- OperandType.UINT16,
95
- ];
91
+ static readonly wireFormat = [OperandType.UINT8, OperandType.UINT8, OperandType.UINT16, OperandType.UINT16];
96
92
 
97
93
  constructor(
98
94
  private addressingMode: number,
99
- private nullifierOffset: number,
100
- private addressOffset: number,
95
+ private siloedNullifierOffset: number,
101
96
  private existsOffset: number,
102
97
  ) {
103
98
  super();
@@ -111,13 +106,12 @@ export class NullifierExists extends Instruction {
111
106
  this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
112
107
  );
113
108
 
114
- const operands = [this.nullifierOffset, this.addressOffset, this.existsOffset];
115
- const [nullifierOffset, addressOffset, existsOffset] = addressing.resolve(operands, memory);
116
- memory.checkTags(TypeTag.FIELD, nullifierOffset, addressOffset);
109
+ const operands = [this.siloedNullifierOffset, this.existsOffset];
110
+ const [siloedNullifierOffset, existsOffset] = addressing.resolve(operands, memory);
111
+ memory.checkTag(TypeTag.FIELD, siloedNullifierOffset);
117
112
 
118
- const nullifier = memory.get(nullifierOffset).toFr();
119
- const address = memory.get(addressOffset).toAztecAddress();
120
- const exists = await context.persistableState.checkNullifierExists(address, nullifier);
113
+ const siloedNullifier = memory.get(siloedNullifierOffset).toFr();
114
+ const exists = await context.persistableState.checkSiloedNullifierExists(siloedNullifier);
121
115
 
122
116
  memory.set(existsOffset, exists ? new Uint1(1) : new Uint1(0));
123
117
  }
@@ -282,6 +276,10 @@ export class SendL2ToL1Message extends Instruction {
282
276
  memory.checkTags(TypeTag.FIELD, recipientOffset, contentOffset);
283
277
 
284
278
  const recipient = memory.get(recipientOffset).toFr();
279
+
280
+ if (recipient.toBigInt() > MAX_ETH_ADDRESS_VALUE) {
281
+ throw new InstructionExecutionError(`SENDL2TOL1MSG: Recipient address is too large`);
282
+ }
285
283
  const content = memory.get(contentOffset).toFr();
286
284
  context.persistableState.writeL2ToL1Message(context.environment.address, recipient, content);
287
285
  }
@@ -1,6 +1,7 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
2
  import type { AvmContractCallResult } from '../avm_contract_call_result.js';
3
3
  import { type Field, TypeTag, Uint1 } from '../avm_memory_types.js';
4
+ import { CallDataMemory, ReturnDataMemory } from '../calldata.js';
4
5
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
5
6
  import { Addressing } from './addressing_mode.js';
6
7
  import { Instruction } from './instruction.js';
@@ -45,8 +46,8 @@ abstract class ExternalCall extends Instruction {
45
46
  memory.checkTag(TypeTag.UINT32, argsSizeOffset);
46
47
 
47
48
  const calldataSize = memory.get(argsSizeOffset).toNumber();
48
- // This is a DOS vector. CalldataSize is chosen by the bytecode, and can be arbitrarily large leading to a OOM here.
49
- const calldata = memory.getSlice(argsOffset, calldataSize).map(f => f.toFr());
49
+
50
+ const calldata = new CallDataMemory(memory, argsOffset, calldataSize);
50
51
 
51
52
  const callAddress = memory.getAs<Field>(addrOffset);
52
53
  // If we are already in a static call, we propagate the environment.
@@ -73,8 +74,8 @@ abstract class ExternalCall extends Instruction {
73
74
  const success = !nestedCallResults.reverted;
74
75
 
75
76
  // Save return/revert data for later.
76
- const fullReturnData = nestedCallResults.output;
77
- context.machineState.nestedReturndata = fullReturnData;
77
+ const returnData = nestedCallResults.output;
78
+ context.machineState.nestedReturndata = returnData;
78
79
 
79
80
  // Track the success status directly
80
81
  context.machineState.nestedCallSuccess = success;
@@ -89,7 +90,7 @@ abstract class ExternalCall extends Instruction {
89
90
  // (in Noir code).
90
91
  if (!success) {
91
92
  context.machineState.collectedRevertInfo = {
92
- revertDataRepresentative: fullReturnData,
93
+ revertDataRepresentative: returnData.bestEffortReadAll(),
93
94
  recursiveRevertReason: nestedCallResults.revertReason!,
94
95
  };
95
96
  }
@@ -195,7 +196,7 @@ export class Return extends Instruction {
195
196
  memory.checkTag(TypeTag.UINT32, returnSizeOffset);
196
197
  const returnSize = memory.get(returnSizeOffset).toNumber();
197
198
 
198
- const output = memory.getSlice(returnOffset, returnSize).map(word => word.toFr());
199
+ const output = new ReturnDataMemory(memory, returnOffset, returnSize);
199
200
 
200
201
  context.machineState.return(output);
201
202
  }
@@ -243,7 +244,7 @@ export class Revert extends Instruction {
243
244
 
244
245
  memory.checkTag(TypeTag.UINT32, retSizeOffset);
245
246
  const retSize = memory.get(retSizeOffset).toNumber();
246
- const output = memory.getSlice(returnOffset, retSize).map(word => word.toFr());
247
+ const output = new ReturnDataMemory(memory, returnOffset, retSize);
247
248
 
248
249
  context.machineState.revert(output);
249
250
  }
@@ -242,7 +242,7 @@ export class ReturndataSize extends Instruction {
242
242
  const operands = [this.dstOffset];
243
243
  const [dstOffset] = addressing.resolve(operands, memory);
244
244
 
245
- memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length));
245
+ memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length()));
246
246
  }
247
247
  }
248
248
 
@@ -1,20 +1,21 @@
1
- import type { Fr } from '@aztec/foundation/curves/bn254';
2
1
  import { FunctionSelector } from '@aztec/stdlib/abi';
3
2
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
3
 
4
+ import type { CallData } from './avm/calldata.js';
5
5
  import type { PublicContractsDBInterface } from './db_interfaces.js';
6
6
 
7
7
  export async function getPublicFunctionDebugName(
8
8
  db: PublicContractsDBInterface,
9
9
  contractAddress: AztecAddress,
10
- calldata: Fr[],
10
+ calldata: CallData,
11
11
  ): Promise<string> {
12
12
  // Public function is dispatched and therefore the target function is passed in the first argument.
13
- if (!calldata[0]) {
13
+ const selectorField = calldata.read(0);
14
+ if (!selectorField) {
14
15
  return `<calldata[0] undefined> (Contract Address: ${contractAddress})`;
15
16
  }
16
- const fallbackName = `<calldata[0]:${calldata[0].toString()}> (Contract Address: ${contractAddress})`;
17
- const selector = FunctionSelector.fromFieldOrUndefined(calldata[0]);
17
+ const fallbackName = `<calldata[0]:${selectorField.toString()}> (Contract Address: ${contractAddress})`;
18
+ const selector = FunctionSelector.fromFieldOrUndefined(selectorField);
18
19
  if (!selector) {
19
20
  return fallbackName;
20
21
  }
@@ -32,13 +33,14 @@ export async function getPublicFunctionDebugName(
32
33
  export async function getPublicFunctionSelectorAndName(
33
34
  db: PublicContractsDBInterface,
34
35
  contractAddress: AztecAddress,
35
- calldata: Fr[],
36
+ calldata: CallData,
36
37
  ): Promise<{ functionSelector?: FunctionSelector; functionName?: string }> {
37
38
  // Public function is dispatched and therefore the target function is passed in the first argument.
38
- if (!calldata[0]) {
39
+ const selectorField = calldata.read(0);
40
+ if (!selectorField) {
39
41
  return {};
40
42
  }
41
- const selector = FunctionSelector.fromFieldOrUndefined(calldata[0]);
43
+ const selector = FunctionSelector.fromFieldOrUndefined(selectorField);
42
44
  if (!selector) {
43
45
  return {};
44
46
  }
@@ -7,6 +7,7 @@ import {
7
7
  type TelemetryClient,
8
8
  type Tracer,
9
9
  type UpDownCounter,
10
+ createUpDownCounterWithDefault,
10
11
  } from '@aztec/telemetry-client';
11
12
 
12
13
  import type { ExecutorMetricsInterface } from './executor_metrics_interface.js';
@@ -25,7 +26,9 @@ export class ExecutorMetrics implements ExecutorMetricsInterface {
25
26
  this.tracer = client.getTracer(name);
26
27
  const meter = client.getMeter(name);
27
28
 
28
- this.fnCount = meter.createUpDownCounter(Metrics.PUBLIC_EXECUTOR_SIMULATION_COUNT);
29
+ this.fnCount = createUpDownCounterWithDefault(meter, Metrics.PUBLIC_EXECUTOR_SIMULATION_COUNT, {
30
+ [Attributes.OK]: [true, false],
31
+ });
29
32
 
30
33
  this.fnDuration = meter.createHistogram(Metrics.PUBLIC_EXECUTOR_SIMULATION_DURATION);
31
34
 
@@ -164,7 +164,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
164
164
  import type { Bufferable } from '@aztec/foundation/serialize';
165
165
  import { type CallStackMetadata, PublicDataWrite, type PublicTxResult } from '@aztec/stdlib/avm';
166
166
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
167
- import { computePublicDataTreeLeafSlot, siloNullifier } from '@aztec/stdlib/hash';
167
+ import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
168
168
  import type { MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
169
169
  import { MerkleTreeId } from '@aztec/stdlib/trees';
170
170
 
@@ -295,9 +295,8 @@ export interface SpamConfigsForOpcode {
295
295
  export const WARM_NOTE_HASH = new Fr(0xdeadbeefn);
296
296
  export const WARM_L1_TO_L2_MSG = new Fr(0xcafebabedeadbeefn);
297
297
 
298
- /** Warm nullifier constants - uses a fixed address since NULLIFIEREXISTS takes address as parameter */
299
- export const WARM_NULLIFIER = new Fr(0xdeadbeef0001n);
300
- export const WARM_NULLIFIER_ADDRESS = AztecAddress.fromNumber(0xbeef);
298
+ /** Warm nullifier constant - a pre-siloed nullifier value inserted directly into the tree */
299
+ export const WARM_SILOED_NULLIFIER = new Fr(0xdeadbeef0001n);
301
300
 
302
301
  /** Warm storage constants - storage is inserted for the deployed contract's address */
303
302
  export const WARM_STORAGE_SLOT = new Fr(0xdeadbeef0002n);
@@ -331,9 +330,8 @@ export async function insertWarmTreeEntries(
331
330
  // Insert into L1 to L2 message tree
332
331
  await merkleTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, [WARM_L1_TO_L2_MSG]);
333
332
 
334
- // Insert siloed nullifier into nullifier tree
335
- const siloedNullifier = await siloNullifier(WARM_NULLIFIER_ADDRESS, WARM_NULLIFIER);
336
- await merkleTrees.sequentialInsert(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()]);
333
+ // Insert siloed nullifier into nullifier tree (already siloed - used directly by NULLIFIEREXISTS)
334
+ await merkleTrees.sequentialInsert(MerkleTreeId.NULLIFIER_TREE, [WARM_SILOED_NULLIFIER.toBuffer()]);
337
335
 
338
336
  // Insert storage value into public data tree
339
337
  const leafSlot = await computePublicDataTreeLeafSlot(contractAddress, WARM_STORAGE_SLOT);
@@ -1060,56 +1058,25 @@ export const SPAM_CONFIGS: Partial<Record<Opcode, SpamConfig[]>> = {
1060
1058
  [Opcode.NULLIFIEREXISTS]: [
1061
1059
  {
1062
1060
  label: 'Non-existent nullifier',
1061
+ // NULLIFIEREXISTS now takes a siloed nullifier directly (no address parameter)
1063
1062
  setup: [
1064
- { offset: 0, value: new Field(Fr.random()) }, // random nullifier
1065
- { offset: 1, value: new Field(Fr.random()) }, // random address
1063
+ { offset: 0, value: new Field(Fr.random()) }, // random siloed nullifier (won't exist)
1066
1064
  ],
1067
1065
  targetInstructions: () => [
1068
- new NullifierExists(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0, /*addressOffset=*/ 1, /*existsOffset=*/ 2),
1066
+ new NullifierExists(/*addressing_mode=*/ 0, /*siloedNullifierOffset=*/ 0, /*existsOffset=*/ 1),
1069
1067
  ],
1070
1068
  },
1071
1069
  {
1072
1070
  label: 'Existing nullifier (warm - from tree)',
1073
- // Uses pre-inserted nullifier from insertWarmTreeEntries()
1071
+ // Uses pre-inserted siloed nullifier from insertWarmTreeEntries()
1072
+ // NULLIFIEREXISTS now takes a siloed nullifier directly
1074
1073
  setup: [
1075
- { offset: 0, value: new Field(WARM_NULLIFIER) }, // pre-inserted nullifier
1076
- { offset: 1, value: new Field(WARM_NULLIFIER_ADDRESS.toField()) }, // address it was siloed with
1074
+ { offset: 0, value: new Field(WARM_SILOED_NULLIFIER) }, // pre-inserted siloed nullifier
1077
1075
  ],
1078
1076
  targetInstructions: () => [
1079
- new NullifierExists(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0, /*addressOffset=*/ 1, /*existsOffset=*/ 2),
1077
+ new NullifierExists(/*addressing_mode=*/ 0, /*siloedNullifierOffset=*/ 0, /*existsOffset=*/ 1),
1080
1078
  ],
1081
1079
  },
1082
- {
1083
- label: 'Existing nullifier (warm - EMITNULLIFIER first)',
1084
- // Memory layout: nullifier (incremented), constant 1, current address (from GETENVVAR), revertSize, exists result
1085
- setup: [
1086
- { offset: 0, value: new Field(Fr.random()) }, // nullifier (will be incremented)
1087
- { offset: 1, value: new Field(1n) }, // constant 1 for ADD
1088
- () => [
1089
- // Get current contract address into offset 2
1090
- new GetEnvVar(/*addressing_mode=*/ 0, /*dstOffset=*/ 2, /*varEnum=*/ 0).as(
1091
- Opcode.GETENVVAR_16,
1092
- GetEnvVar.wireFormat16,
1093
- ),
1094
- ],
1095
- { offset: 3, value: new Uint32(0n) }, // revertSize
1096
- ],
1097
- targetInstructions: () => [
1098
- new EmitNullifier(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0),
1099
- new NullifierExists(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0, /*addressOffset=*/ 2, /*existsOffset=*/ 4),
1100
- new Add(/*addressing_mode=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 0).as(
1101
- Opcode.ADD_8,
1102
- Add.wireFormat8,
1103
- ), // nullifier++
1104
- ],
1105
- cleanupInstructions: () => [
1106
- new Revert(/*addressing_mode=*/ 0, /*retSizeOffset=*/ 3, /*returnOffset=*/ 0).as(
1107
- Opcode.REVERT_8,
1108
- Revert.wireFormat8,
1109
- ),
1110
- ],
1111
- limit: MAX_NULLIFIERS_PER_TX - 1,
1112
- },
1113
1080
  ],
1114
1081
 
1115
1082
  [Opcode.L1TOL2MSGEXISTS]: [
@@ -5,7 +5,7 @@ import {
5
5
  PUBLIC_DATA_SUBTREE_HEIGHT,
6
6
  } from '@aztec/constants';
7
7
  import { Fr } from '@aztec/foundation/curves/bn254';
8
- import { createLogger } from '@aztec/foundation/log';
8
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
9
9
  import { Timer } from '@aztec/foundation/timer';
10
10
  import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
11
11
  import { ContractInstancePublishedEvent } from '@aztec/protocol-contracts/instance-registry';
@@ -46,9 +46,14 @@ import { L1ToL2MessageIndexOutOfRangeError, NoteHashIndexOutOfRangeError } from
46
46
  export class PublicContractsDB implements PublicContractsDBInterface {
47
47
  private contractStateStack: ContractsDbCheckpoint[] = [new ContractsDbCheckpoint()];
48
48
 
49
- private log = createLogger('simulator:contracts-data-source');
49
+ private log: Logger;
50
50
 
51
- constructor(private dataSource: ContractDataSource) {}
51
+ constructor(
52
+ private dataSource: ContractDataSource,
53
+ bindings?: LoggerBindings,
54
+ ) {
55
+ this.log = createLogger('simulator:contracts-data-source', bindings);
56
+ }
52
57
 
53
58
  public async addContracts(contractDeploymentData: ContractDeploymentData): Promise<void> {
54
59
  const currentState = this.getCurrentState();
@@ -208,9 +213,14 @@ export class PublicContractsDB implements PublicContractsDBInterface {
208
213
  * to decide whether to use hints or not (same with tracing, etc).
209
214
  */
210
215
  export class PublicTreesDB implements PublicStateDBInterface {
211
- private logger = createLogger('simulator:public-trees-db');
216
+ private logger: Logger;
212
217
 
213
- constructor(private readonly db: MerkleTreeWriteOperations) {}
218
+ constructor(
219
+ private readonly db: MerkleTreeWriteOperations,
220
+ bindings?: LoggerBindings,
221
+ ) {
222
+ this.logger = createLogger('simulator:public-trees-db', bindings);
223
+ }
214
224
 
215
225
  public async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
216
226
  const timer = new Timer();
@@ -1,7 +1,7 @@
1
1
  import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT } from '@aztec/constants';
2
2
  import { padArrayEnd } from '@aztec/foundation/collection';
3
3
  import { Fr } from '@aztec/foundation/curves/bn254';
4
- import { createLogger } from '@aztec/foundation/log';
4
+ import { type Logger, type LoggerBindings, createLogger } from '@aztec/foundation/log';
5
5
  import { sleep } from '@aztec/foundation/sleep';
6
6
  import { DateProvider, Timer, elapsed, executeTimeout } from '@aztec/foundation/timer';
7
7
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
@@ -62,11 +62,15 @@ import { PublicProcessorMetrics } from './public_processor_metrics.js';
62
62
  * Creates new instances of PublicProcessor given the provided merkle tree db and contract data source.
63
63
  */
64
64
  export class PublicProcessorFactory {
65
+ private log: Logger;
65
66
  constructor(
66
67
  private contractDataSource: ContractDataSource,
67
68
  private dateProvider: DateProvider = new DateProvider(),
68
69
  protected telemetryClient: TelemetryClient = getTelemetryClient(),
69
- ) {}
70
+ bindings?: LoggerBindings,
71
+ ) {
72
+ this.log = createLogger('simulator:public-processor-factory', bindings);
73
+ }
70
74
 
71
75
  /**
72
76
  * Creates a new instance of a PublicProcessor.
@@ -79,7 +83,8 @@ export class PublicProcessorFactory {
79
83
  globalVariables: GlobalVariables,
80
84
  config: PublicSimulatorConfig,
81
85
  ): PublicProcessor {
82
- const contractsDB = new PublicContractsDB(this.contractDataSource);
86
+ const bindings = this.log.getBindings();
87
+ const contractsDB = new PublicContractsDB(this.contractDataSource, bindings);
83
88
 
84
89
  const guardedFork = new GuardedMerkleTreeOperations(merkleTree);
85
90
  const publicTxSimulator = this.createPublicTxSimulator(guardedFork, contractsDB, globalVariables, config);
@@ -91,6 +96,7 @@ export class PublicProcessorFactory {
91
96
  publicTxSimulator,
92
97
  this.dateProvider,
93
98
  this.telemetryClient,
99
+ createLogger('simulator:public-processor', bindings),
94
100
  );
95
101
  }
96
102
 
@@ -100,7 +106,14 @@ export class PublicProcessorFactory {
100
106
  globalVariables: GlobalVariables,
101
107
  config?: Partial<PublicTxSimulatorConfig>,
102
108
  ): PublicTxSimulatorInterface {
103
- return new TelemetryCppPublicTxSimulator(merkleTree, contractsDB, globalVariables, this.telemetryClient, config);
109
+ return new TelemetryCppPublicTxSimulator(
110
+ merkleTree,
111
+ contractsDB,
112
+ globalVariables,
113
+ this.telemetryClient,
114
+ config,
115
+ this.log.getBindings(),
116
+ );
104
117
  }
105
118
  }
106
119
 
@@ -125,7 +138,7 @@ export class PublicProcessor implements Traceable {
125
138
  protected publicTxSimulator: PublicTxSimulatorInterface,
126
139
  private dateProvider: DateProvider,
127
140
  telemetryClient: TelemetryClient = getTelemetryClient(),
128
- private log = createLogger('simulator:public-processor'),
141
+ private log: Logger,
129
142
  private opts: Pick<SequencerConfig, 'fakeProcessingDelayPerTxMs' | 'fakeThrowAfterProcessingTxCount'> = {},
130
143
  ) {
131
144
  this.metrics = new PublicProcessorMetrics(telemetryClient, 'PublicProcessor');