@aztec/simulator 0.0.1-commit.d431d1c → 0.0.1-commit.dbf9cec

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 (182) hide show
  1. package/README.md +4 -4
  2. package/dest/private/acvm/acvm.d.ts +4 -2
  3. package/dest/private/acvm/acvm.d.ts.map +1 -1
  4. package/dest/private/acvm/acvm.js +4 -3
  5. package/dest/private/acvm_native.d.ts +5 -3
  6. package/dest/private/acvm_native.d.ts.map +1 -1
  7. package/dest/private/acvm_native.js +8 -6
  8. package/dest/private/acvm_wasm.d.ts +4 -3
  9. package/dest/private/acvm_wasm.d.ts.map +1 -1
  10. package/dest/private/acvm_wasm.js +4 -4
  11. package/dest/private/circuit_recording/circuit_recorder.d.ts +4 -3
  12. package/dest/private/circuit_recording/circuit_recorder.d.ts.map +1 -1
  13. package/dest/private/circuit_recording/circuit_recorder.js +5 -3
  14. package/dest/private/circuit_recording/file_circuit_recorder.d.ts +3 -2
  15. package/dest/private/circuit_recording/file_circuit_recorder.d.ts.map +1 -1
  16. package/dest/private/circuit_recording/file_circuit_recorder.js +2 -2
  17. package/dest/private/circuit_recording/memory_circuit_recorder.d.ts +7 -2
  18. package/dest/private/circuit_recording/memory_circuit_recorder.d.ts.map +1 -1
  19. package/dest/private/circuit_recording/memory_circuit_recorder.js +4 -4
  20. package/dest/private/factory.d.ts +3 -3
  21. package/dest/private/factory.d.ts.map +1 -1
  22. package/dest/private/factory.js +7 -4
  23. package/dest/public/avm/avm_context.d.ts +3 -3
  24. package/dest/public/avm/avm_context.d.ts.map +1 -1
  25. package/dest/public/avm/avm_contract_call_result.d.ts +6 -6
  26. package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
  27. package/dest/public/avm/avm_contract_call_result.js +3 -3
  28. package/dest/public/avm/avm_execution_environment.d.ts +6 -5
  29. package/dest/public/avm/avm_execution_environment.d.ts.map +1 -1
  30. package/dest/public/avm/avm_gas.js +3 -3
  31. package/dest/public/avm/avm_machine_state.d.ts +6 -5
  32. package/dest/public/avm/avm_machine_state.d.ts.map +1 -1
  33. package/dest/public/avm/avm_machine_state.js +3 -2
  34. package/dest/public/avm/avm_memory_types.d.ts +1 -1
  35. package/dest/public/avm/avm_memory_types.d.ts.map +1 -1
  36. package/dest/public/avm/avm_memory_types.js +3 -0
  37. package/dest/public/avm/avm_simulator.d.ts +3 -2
  38. package/dest/public/avm/avm_simulator.d.ts.map +1 -1
  39. package/dest/public/avm/avm_simulator.js +5 -4
  40. package/dest/public/avm/calldata.d.ts +51 -0
  41. package/dest/public/avm/calldata.d.ts.map +1 -0
  42. package/dest/public/avm/calldata.js +63 -0
  43. package/dest/public/avm/fixtures/account_proof_fetcher.d.ts +2 -0
  44. package/dest/public/avm/fixtures/account_proof_fetcher.d.ts.map +1 -0
  45. package/dest/public/avm/fixtures/account_proof_fetcher.js +152 -0
  46. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +1 -1
  47. package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
  48. package/dest/public/avm/fixtures/avm_simulation_tester.js +3 -2
  49. package/dest/public/avm/fixtures/initializers.d.ts +1 -1
  50. package/dest/public/avm/fixtures/initializers.d.ts.map +1 -1
  51. package/dest/public/avm/fixtures/initializers.js +2 -1
  52. package/dest/public/avm/opcodes/accrued_substate.d.ts +4 -5
  53. package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
  54. package/dest/public/avm/opcodes/accrued_substate.js +15 -16
  55. package/dest/public/avm/opcodes/contract.d.ts +1 -1
  56. package/dest/public/avm/opcodes/contract.d.ts.map +1 -1
  57. package/dest/public/avm/opcodes/contract.js +4 -4
  58. package/dest/public/avm/opcodes/external_calls.d.ts +1 -1
  59. package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
  60. package/dest/public/avm/opcodes/external_calls.js +7 -7
  61. package/dest/public/avm/opcodes/memory.js +1 -1
  62. package/dest/public/avm/opcodes/storage.d.ts +13 -12
  63. package/dest/public/avm/opcodes/storage.d.ts.map +1 -1
  64. package/dest/public/avm/opcodes/storage.js +30 -20
  65. package/dest/public/avm/serialization/bytecode_serialization.js +3 -3
  66. package/dest/public/avm/serialization/instruction_serialization.d.ts +2 -2
  67. package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -1
  68. package/dest/public/avm/serialization/instruction_serialization.js +1 -1
  69. package/dest/public/debug_fn_name.d.ts +4 -4
  70. package/dest/public/debug_fn_name.d.ts.map +1 -1
  71. package/dest/public/debug_fn_name.js +7 -5
  72. package/dest/public/executor_metrics.d.ts +1 -1
  73. package/dest/public/executor_metrics.d.ts.map +1 -1
  74. package/dest/public/executor_metrics.js +7 -2
  75. package/dest/public/fixtures/amm_test.js +2 -2
  76. package/dest/public/fixtures/opcode_spammer.d.ts +3 -4
  77. package/dest/public/fixtures/opcode_spammer.d.ts.map +1 -1
  78. package/dest/public/fixtures/opcode_spammer.js +36 -64
  79. package/dest/public/fixtures/public_tx_simulation_tester.d.ts +1 -1
  80. package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
  81. package/dest/public/fixtures/public_tx_simulation_tester.js +29 -2
  82. package/dest/public/fixtures/utils.js +4 -4
  83. package/dest/public/fuzzing/avm_simulator_bin.js +7 -4
  84. package/dest/public/hinting_db_sources.d.ts +2 -2
  85. package/dest/public/hinting_db_sources.d.ts.map +1 -1
  86. package/dest/public/hinting_db_sources.js +1 -1
  87. package/dest/public/public_db_sources.d.ts +4 -3
  88. package/dest/public/public_db_sources.d.ts.map +1 -1
  89. package/dest/public/public_db_sources.js +4 -4
  90. package/dest/public/public_processor/guarded_merkle_tree.d.ts +2 -2
  91. package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -1
  92. package/dest/public/public_processor/guarded_merkle_tree.js +1 -1
  93. package/dest/public/public_processor/public_processor.d.ts +8 -4
  94. package/dest/public/public_processor/public_processor.d.ts.map +1 -1
  95. package/dest/public/public_processor/public_processor.js +24 -11
  96. package/dest/public/public_processor/public_processor_metrics.d.ts +2 -2
  97. package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -1
  98. package/dest/public/public_processor/public_processor_metrics.js +20 -4
  99. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts +3 -2
  100. package/dest/public/public_tx_simulator/contract_provider_for_cpp.d.ts.map +1 -1
  101. package/dest/public/public_tx_simulator/contract_provider_for_cpp.js +2 -2
  102. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts +5 -5
  103. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.d.ts.map +1 -1
  104. package/dest/public/public_tx_simulator/cpp_public_tx_simulator.js +10 -11
  105. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts +4 -4
  106. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.d.ts.map +1 -1
  107. package/dest/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.js +7 -7
  108. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts +4 -4
  109. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.d.ts.map +1 -1
  110. package/dest/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.js +6 -6
  111. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts +3 -2
  112. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.d.ts.map +1 -1
  113. package/dest/public/public_tx_simulator/dumping_cpp_public_tx_simulator.js +2 -2
  114. package/dest/public/public_tx_simulator/factories.d.ts +3 -2
  115. package/dest/public/public_tx_simulator/factories.d.ts.map +1 -1
  116. package/dest/public/public_tx_simulator/factories.js +4 -4
  117. package/dest/public/public_tx_simulator/public_tx_context.d.ts +4 -3
  118. package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
  119. package/dest/public/public_tx_simulator/public_tx_context.js +8 -8
  120. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +4 -3
  121. package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
  122. package/dest/public/public_tx_simulator/public_tx_simulator.js +11 -8
  123. package/dest/public/side_effect_trace.d.ts +4 -4
  124. package/dest/public/side_effect_trace.d.ts.map +1 -1
  125. package/dest/public/side_effect_trace.js +3 -3
  126. package/dest/public/state_manager/state_manager.d.ts +10 -4
  127. package/dest/public/state_manager/state_manager.d.ts.map +1 -1
  128. package/dest/public/state_manager/state_manager.js +12 -5
  129. package/dest/public/test_executor_metrics.d.ts +8 -2
  130. package/dest/public/test_executor_metrics.d.ts.map +1 -1
  131. package/dest/public/test_executor_metrics.js +24 -2
  132. package/package.json +16 -16
  133. package/src/private/acvm/acvm.ts +4 -3
  134. package/src/private/acvm_native.ts +11 -5
  135. package/src/private/acvm_wasm.ts +7 -3
  136. package/src/private/circuit_recording/circuit_recorder.ts +5 -3
  137. package/src/private/circuit_recording/file_circuit_recorder.ts +7 -2
  138. package/src/private/circuit_recording/memory_circuit_recorder.ts +6 -4
  139. package/src/private/factory.ts +7 -4
  140. package/src/public/avm/avm_context.ts +2 -2
  141. package/src/public/avm/avm_contract_call_result.ts +8 -6
  142. package/src/public/avm/avm_execution_environment.ts +9 -4
  143. package/src/public/avm/avm_gas.ts +2 -2
  144. package/src/public/avm/avm_machine_state.ts +6 -5
  145. package/src/public/avm/avm_memory_types.ts +4 -0
  146. package/src/public/avm/avm_simulator.ts +8 -5
  147. package/src/public/avm/calldata.ts +100 -0
  148. package/src/public/avm/fixtures/account_proof.json +553 -0
  149. package/src/public/avm/fixtures/account_proof_fetcher.ts +166 -0
  150. package/src/public/avm/fixtures/avm_simulation_tester.ts +8 -2
  151. package/src/public/avm/fixtures/initializers.ts +2 -1
  152. package/src/public/avm/opcodes/accrued_substate.ts +16 -19
  153. package/src/public/avm/opcodes/contract.ts +1 -4
  154. package/src/public/avm/opcodes/external_calls.ts +8 -7
  155. package/src/public/avm/opcodes/memory.ts +1 -1
  156. package/src/public/avm/opcodes/storage.ts +28 -20
  157. package/src/public/avm/serialization/bytecode_serialization.ts +2 -2
  158. package/src/public/avm/serialization/instruction_serialization.ts +1 -1
  159. package/src/public/debug_fn_name.ts +10 -8
  160. package/src/public/executor_metrics.ts +4 -1
  161. package/src/public/fixtures/amm_test.ts +2 -2
  162. package/src/public/fixtures/opcode_spammer.ts +55 -63
  163. package/src/public/fixtures/public_tx_simulation_tester.ts +34 -3
  164. package/src/public/fixtures/utils.ts +4 -4
  165. package/src/public/fuzzing/avm_fuzzer_simulator.ts +1 -1
  166. package/src/public/fuzzing/avm_simulator_bin.ts +11 -1
  167. package/src/public/hinting_db_sources.ts +1 -1
  168. package/src/public/public_db_sources.ts +15 -5
  169. package/src/public/public_processor/guarded_merkle_tree.ts +1 -1
  170. package/src/public/public_processor/public_processor.ts +42 -20
  171. package/src/public/public_processor/public_processor_metrics.ts +10 -4
  172. package/src/public/public_tx_simulator/contract_provider_for_cpp.ts +6 -3
  173. package/src/public/public_tx_simulator/cpp_public_tx_simulator.ts +10 -8
  174. package/src/public/public_tx_simulator/cpp_public_tx_simulator_with_hinted_dbs.ts +7 -5
  175. package/src/public/public_tx_simulator/cpp_vs_ts_public_tx_simulator.ts +7 -5
  176. package/src/public/public_tx_simulator/dumping_cpp_public_tx_simulator.ts +3 -1
  177. package/src/public/public_tx_simulator/factories.ts +6 -3
  178. package/src/public/public_tx_simulator/public_tx_context.ts +13 -6
  179. package/src/public/public_tx_simulator/public_tx_simulator.ts +17 -8
  180. package/src/public/side_effect_trace.ts +5 -2
  181. package/src/public/state_manager/state_manager.ts +27 -4
  182. package/src/public/test_executor_metrics.ts +27 -3
@@ -143,7 +143,7 @@
143
143
  * - `EMITNOTEHASH`: max 64 per TX
144
144
  * - `EMITNULLIFIER`: max 63 per TX (one reserved for TX nullifier)
145
145
  * - `SENDL2TOL1MSG`: max 8 per TX
146
- * - `EMITUNENCRYPTEDLOG`: limited by total log payload size
146
+ * - `EMITPUBLICLOG`: limited by total log payload size
147
147
  *
148
148
  * By having the inner contract REVERT after emitting side effects, those effects are discarded, allowing the outer contract to call it again. This enables thousands of opcode executions per TX instead of just the limit.
149
149
  *
@@ -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
 
@@ -182,7 +182,7 @@ import {
182
182
  EcAdd,
183
183
  EmitNoteHash,
184
184
  EmitNullifier,
185
- EmitUnencryptedLog,
185
+ EmitPublicLog,
186
186
  Eq,
187
187
  FieldDiv,
188
188
  GetContractInstance,
@@ -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);
@@ -966,34 +964,63 @@ export const SPAM_CONFIGS: Partial<Record<Opcode, SpamConfig[]>> = {
966
964
  [Opcode.SLOAD]: [
967
965
  {
968
966
  label: 'Cold read (slot not written)',
969
- setup: [{ offset: 0, value: new Field(Fr.random()) }], // random slot
970
- targetInstructions: () => [new SLoad(/*addressing_mode=*/ 0, /*slotOffset=*/ 0, /*dstOffset=*/ 1)],
967
+ setup: [
968
+ { offset: 0, value: new Field(Fr.random()) }, // random slot
969
+ () => [
970
+ // Get current contract address into offset 1
971
+ new GetEnvVar(/*addressing_mode=*/ 0, /*dstOffset=*/ 1, /*varEnum=*/ 0).as(
972
+ Opcode.GETENVVAR_16,
973
+ GetEnvVar.wireFormat16,
974
+ ),
975
+ ],
976
+ ],
977
+ targetInstructions: () => [
978
+ new SLoad(/*addressing_mode=*/ 0, /*slotOffset=*/ 0, /*contractAddressOffset=*/ 1, /*dstOffset=*/ 2),
979
+ ],
971
980
  },
972
981
  {
973
982
  label: 'Warm read (from tree)',
974
983
  // Uses pre-inserted storage from insertWarmTreeEntries() which is called after contract deployment
975
- setup: [{ offset: 0, value: new Field(WARM_STORAGE_SLOT) }], // pre-inserted slot
976
- targetInstructions: () => [new SLoad(/*addressing_mode=*/ 0, /*slotOffset=*/ 0, /*dstOffset=*/ 1)],
984
+ setup: [
985
+ { offset: 0, value: new Field(WARM_STORAGE_SLOT) }, // pre-inserted slot
986
+ () => [
987
+ // Get current contract address into offset 1
988
+ new GetEnvVar(/*addressing_mode=*/ 0, /*dstOffset=*/ 1, /*varEnum=*/ 0).as(
989
+ Opcode.GETENVVAR_16,
990
+ GetEnvVar.wireFormat16,
991
+ ),
992
+ ],
993
+ ],
994
+ targetInstructions: () => [
995
+ new SLoad(/*addressing_mode=*/ 0, /*slotOffset=*/ 0, /*contractAddressOffset=*/ 1, /*dstOffset=*/ 2),
996
+ ],
977
997
  },
978
998
  {
979
999
  label: 'Warm read (SSTORE first, unique slot per SLOAD)',
980
- // Memory layout: slot (incremented), value, constant 1, revertSize, loaded value
1000
+ // Memory layout: slot (incremented), value, constant 1, contract address (from GETENVVAR), revertSize, loaded value
981
1001
  setup: [
982
1002
  { offset: 0, value: new Field(Fr.random()) }, // slot (will be incremented)
983
1003
  { offset: 1, value: new Field(Fr.random()) }, // value to store
984
1004
  { offset: 2, value: new Field(1n) }, // constant 1 for ADD
985
- { offset: 3, value: new Uint32(0n) }, // revertSize
1005
+ () => [
1006
+ // Get current contract address into offset 3
1007
+ new GetEnvVar(/*addressing_mode=*/ 0, /*dstOffset=*/ 3, /*varEnum=*/ 0).as(
1008
+ Opcode.GETENVVAR_16,
1009
+ GetEnvVar.wireFormat16,
1010
+ ),
1011
+ ],
1012
+ { offset: 4, value: new Uint32(0n) }, // revertSize
986
1013
  ],
987
1014
  targetInstructions: () => [
988
1015
  new SStore(/*addressing_mode=*/ 0, /*srcOffset=*/ 1, /*slotOffset=*/ 0),
989
- new SLoad(/*addressing_mode=*/ 0, /*slotOffset=*/ 0, /*dstOffset=*/ 4),
1016
+ new SLoad(/*addressing_mode=*/ 0, /*slotOffset=*/ 0, /*contractAddressOffset=*/ 3, /*dstOffset=*/ 5),
990
1017
  new Add(/*addressing_mode=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 2, /*dstOffset=*/ 0).as(
991
1018
  Opcode.ADD_8,
992
1019
  Add.wireFormat8,
993
1020
  ), // slot++
994
1021
  ],
995
1022
  cleanupInstructions: () => [
996
- new Revert(/*addressing_mode=*/ 0, /*retSizeOffset=*/ 3, /*returnOffset=*/ 0).as(
1023
+ new Revert(/*addressing_mode=*/ 0, /*retSizeOffset=*/ 4, /*returnOffset=*/ 0).as(
997
1024
  Opcode.REVERT_8,
998
1025
  Revert.wireFormat8,
999
1026
  ),
@@ -1031,56 +1058,25 @@ export const SPAM_CONFIGS: Partial<Record<Opcode, SpamConfig[]>> = {
1031
1058
  [Opcode.NULLIFIEREXISTS]: [
1032
1059
  {
1033
1060
  label: 'Non-existent nullifier',
1061
+ // NULLIFIEREXISTS now takes a siloed nullifier directly (no address parameter)
1034
1062
  setup: [
1035
- { offset: 0, value: new Field(Fr.random()) }, // random nullifier
1036
- { offset: 1, value: new Field(Fr.random()) }, // random address
1063
+ { offset: 0, value: new Field(Fr.random()) }, // random siloed nullifier (won't exist)
1037
1064
  ],
1038
1065
  targetInstructions: () => [
1039
- new NullifierExists(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0, /*addressOffset=*/ 1, /*existsOffset=*/ 2),
1066
+ new NullifierExists(/*addressing_mode=*/ 0, /*siloedNullifierOffset=*/ 0, /*existsOffset=*/ 1),
1040
1067
  ],
1041
1068
  },
1042
1069
  {
1043
1070
  label: 'Existing nullifier (warm - from tree)',
1044
- // Uses pre-inserted nullifier from insertWarmTreeEntries()
1071
+ // Uses pre-inserted siloed nullifier from insertWarmTreeEntries()
1072
+ // NULLIFIEREXISTS now takes a siloed nullifier directly
1045
1073
  setup: [
1046
- { offset: 0, value: new Field(WARM_NULLIFIER) }, // pre-inserted nullifier
1047
- { 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
1048
1075
  ],
1049
1076
  targetInstructions: () => [
1050
- new NullifierExists(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0, /*addressOffset=*/ 1, /*existsOffset=*/ 2),
1077
+ new NullifierExists(/*addressing_mode=*/ 0, /*siloedNullifierOffset=*/ 0, /*existsOffset=*/ 1),
1051
1078
  ],
1052
1079
  },
1053
- {
1054
- label: 'Existing nullifier (warm - EMITNULLIFIER first)',
1055
- // Memory layout: nullifier (incremented), constant 1, current address (from GETENVVAR), revertSize, exists result
1056
- setup: [
1057
- { offset: 0, value: new Field(Fr.random()) }, // nullifier (will be incremented)
1058
- { offset: 1, value: new Field(1n) }, // constant 1 for ADD
1059
- () => [
1060
- // Get current contract address into offset 2
1061
- new GetEnvVar(/*addressing_mode=*/ 0, /*dstOffset=*/ 2, /*varEnum=*/ 0).as(
1062
- Opcode.GETENVVAR_16,
1063
- GetEnvVar.wireFormat16,
1064
- ),
1065
- ],
1066
- { offset: 3, value: new Uint32(0n) }, // revertSize
1067
- ],
1068
- targetInstructions: () => [
1069
- new EmitNullifier(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0),
1070
- new NullifierExists(/*addressing_mode=*/ 0, /*nullifierOffset=*/ 0, /*addressOffset=*/ 2, /*existsOffset=*/ 4),
1071
- new Add(/*addressing_mode=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 0).as(
1072
- Opcode.ADD_8,
1073
- Add.wireFormat8,
1074
- ), // nullifier++
1075
- ],
1076
- cleanupInstructions: () => [
1077
- new Revert(/*addressing_mode=*/ 0, /*retSizeOffset=*/ 3, /*returnOffset=*/ 0).as(
1078
- Opcode.REVERT_8,
1079
- Revert.wireFormat8,
1080
- ),
1081
- ],
1082
- limit: MAX_NULLIFIERS_PER_TX - 1,
1083
- },
1084
1080
  ],
1085
1081
 
1086
1082
  [Opcode.L1TOL2MSGEXISTS]: [
@@ -1246,17 +1242,15 @@ export const SPAM_CONFIGS: Partial<Record<Opcode, SpamConfig[]>> = {
1246
1242
  },
1247
1243
  ],
1248
1244
 
1249
- // EMITUNENCRYPTEDLOG - two configs: minimal (many small logs) and max-size (one large log)
1250
- [Opcode.EMITUNENCRYPTEDLOG]: [
1245
+ // EMITPUBLICLOG - two configs: minimal (many small logs) and max-size (one large log)
1246
+ [Opcode.EMITPUBLICLOG]: [
1251
1247
  {
1252
1248
  label: 'Many empty logs, revert, repeat',
1253
1249
  setup: [
1254
1250
  { offset: 0, value: new Uint32(0n) }, // logSize = 0 fields (minimal)
1255
1251
  { offset: 1, value: new Uint32(0n) }, // revertSize
1256
1252
  ],
1257
- targetInstructions: () => [
1258
- new EmitUnencryptedLog(/*addressing_mode=*/ 0, /*logSizeOffset=*/ 0, /*logOffset=*/ 1),
1259
- ], // logOffset doesn't matter when size is 0
1253
+ targetInstructions: () => [new EmitPublicLog(/*addressing_mode=*/ 0, /*logSizeOffset=*/ 0, /*logOffset=*/ 1)], // logOffset doesn't matter when size is 0
1260
1254
  cleanupInstructions: () => [
1261
1255
  new Revert(/*addressing_mode=*/ 0, /*retSizeOffset=*/ 1, /*returnOffset=*/ 0).as(
1262
1256
  Opcode.REVERT_8,
@@ -1280,9 +1274,7 @@ export const SPAM_CONFIGS: Partial<Record<Opcode, SpamConfig[]>> = {
1280
1274
  // value: new Field(0n),
1281
1275
  //})),
1282
1276
  ],
1283
- targetInstructions: () => [
1284
- new EmitUnencryptedLog(/*addressing_mode=*/ 0, /*logSizeOffset=*/ 0, /*logOffset=*/ 2),
1285
- ], // uses logOffset 2 (uninitialized Field(0))
1277
+ targetInstructions: () => [new EmitPublicLog(/*addressing_mode=*/ 0, /*logSizeOffset=*/ 0, /*logOffset=*/ 2)], // uses logOffset 2 (uninitialized Field(0))
1286
1278
  cleanupInstructions: () => [
1287
1279
  new Revert(/*addressing_mode=*/ 0, /*retSizeOffset=*/ 1, /*returnOffset=*/ 0).as(
1288
1280
  Opcode.REVERT_8,
@@ -1,4 +1,9 @@
1
- import { DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT } from '@aztec/constants';
1
+ import {
2
+ DEFAULT_TEARDOWN_DA_GAS_LIMIT,
3
+ DEFAULT_TEARDOWN_L2_GAS_LIMIT,
4
+ PUBLIC_TX_L2_GAS_OVERHEAD,
5
+ TX_DA_GAS_OVERHEAD,
6
+ } from '@aztec/constants';
2
7
  import { asyncMap } from '@aztec/foundation/async-map';
3
8
  import { BlockNumber } from '@aztec/foundation/branded-types';
4
9
  import { Fr } from '@aztec/foundation/curves/bn254';
@@ -131,8 +136,11 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
131
136
  teardownCallRequest,
132
137
  feePayer,
133
138
  /*gasUsedByPrivate*/ teardownCall
134
- ? new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT)
135
- : Gas.empty(),
139
+ ? new Gas(
140
+ DEFAULT_TEARDOWN_DA_GAS_LIMIT + TX_DA_GAS_OVERHEAD,
141
+ DEFAULT_TEARDOWN_L2_GAS_LIMIT + PUBLIC_TX_L2_GAS_OVERHEAD,
142
+ )
143
+ : new Gas(TX_DA_GAS_OVERHEAD, PUBLIC_TX_L2_GAS_OVERHEAD),
136
144
  defaultGlobals(),
137
145
  );
138
146
  }
@@ -161,6 +169,8 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
161
169
  }
162
170
  const avmResult = await this.simulator.simulate(tx, fullTxLabel);
163
171
 
172
+ await this.#recordBytecodeSizes(fullTxLabel, [...setupCalls, ...appCalls, ...(teardownCall ? [teardownCall] : [])]);
173
+
164
174
  // Something like this is often useful for debugging:
165
175
  //if (avmResult.revertReason) {
166
176
  // // resolve / enrich revert reason
@@ -277,6 +287,27 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
277
287
 
278
288
  return new PublicCallRequestWithCalldata(request, calldata);
279
289
  }
290
+
291
+ // WARNING: Deduplicates by artifact name, so two different artifacts with the same name
292
+ // in a single tx would only record the first one's bytecode size.
293
+ async #recordBytecodeSizes(txLabel: string, calls: TestEnqueuedCall[]) {
294
+ const seenArtifactNames = new Set<string>();
295
+ for (const call of calls) {
296
+ const artifact = await this.contractDataSource.getContractArtifact(call.address);
297
+ if (!artifact || seenArtifactNames.has(artifact.name)) {
298
+ continue;
299
+ }
300
+ seenArtifactNames.add(artifact.name);
301
+ const instance = await this.contractDataSource.getContract(call.address);
302
+ if (!instance) {
303
+ continue;
304
+ }
305
+ const contractClass = await this.contractDataSource.getContractClass(instance.currentContractClassId);
306
+ if (contractClass) {
307
+ this.metrics.recordBytecodeSize(txLabel, artifact.name, contractClass.packedBytecode.length);
308
+ }
309
+ }
310
+ }
280
311
  }
281
312
 
282
313
  export function defaultGlobals() {
@@ -134,13 +134,13 @@ export async function createTxForPublicCalls(
134
134
  const txContext = new TxContext(Fr.zero(), Fr.zero(), gasSettings);
135
135
  const header = BlockHeader.empty({ globalVariables: globals });
136
136
  const constantData = new TxConstantData(header, txContext, Fr.zero(), Fr.zero());
137
- const includeByTimestamp = 0n; // Not used in the simulator.
137
+ const expirationTimestamp = 0n; // Not used in the simulator.
138
138
 
139
139
  const txData = new PrivateKernelTailCircuitPublicInputs(
140
140
  constantData,
141
141
  /*gasUsed=*/ gasUsedByPrivate,
142
142
  feePayer,
143
- includeByTimestamp,
143
+ expirationTimestamp,
144
144
  forPublic,
145
145
  );
146
146
 
@@ -171,13 +171,13 @@ export async function createTxForPrivateOnly(
171
171
  const gasSettings = new GasSettings(gasLimits, Gas.empty(), maxFeesPerGas, GasFees.empty());
172
172
  const txContext = new TxContext(Fr.zero(), Fr.zero(), gasSettings);
173
173
  const constantData = new TxConstantData(BlockHeader.empty(), txContext, Fr.zero(), Fr.zero());
174
- const includeByTimestamp = 0n; // Not used in the simulator.
174
+ const expirationTimestamp = 0n; // Not used in the simulator.
175
175
 
176
176
  const txData = new PrivateKernelTailCircuitPublicInputs(
177
177
  constantData,
178
178
  /*gasUsed=*/ gasUsedByPrivate,
179
179
  feePayer,
180
- includeByTimestamp,
180
+ expirationTimestamp,
181
181
  /*forPublic=*/ undefined,
182
182
  forRollup,
183
183
  );
@@ -146,7 +146,7 @@ async function createTxFromHint(cppTx: AvmTxHint): Promise<Tx> {
146
146
  constants,
147
147
  cppTx.gasUsedByPrivate,
148
148
  cppTx.feePayer,
149
- 0n, // includeByTimestamp
149
+ 0n, // expirationTimestamp
150
150
  forPublic,
151
151
  undefined, // forRollup - not needed for public simulation
152
152
  );
@@ -3,6 +3,7 @@ import { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import {
4
4
  AvmCircuitPublicInputs,
5
5
  type AvmTxHint,
6
+ PublicTxEffect,
6
7
  deserializeFromMessagePack,
7
8
  serializeWithMessagePack,
8
9
  } from '@aztec/stdlib/avm';
@@ -58,7 +59,13 @@ async function simulateWithFuzzer(
58
59
  rawPublicDataWrites: any[], // Public data tree writes to apply before simulation
59
60
  rawNoteHashes: any[], // Note hashes to apply before simulation
60
61
  protocolContracts: ProtocolContracts, // Protocol contracts mapping from C++
61
- ): Promise<{ reverted: boolean; output: Fr[]; revertReason?: string; publicInputs: AvmCircuitPublicInputs }> {
62
+ ): Promise<{
63
+ reverted: boolean;
64
+ output: Fr[];
65
+ revertReason?: string;
66
+ publicInputs: AvmCircuitPublicInputs;
67
+ publicTxEffect: PublicTxEffect;
68
+ }> {
62
69
  const worldStateService = await openExistingWorldState(dataDir, mapSizeKb);
63
70
 
64
71
  const simulator = await AvmFuzzerSimulator.create(worldStateService, globals, protocolContracts);
@@ -90,6 +97,7 @@ async function simulateWithFuzzer(
90
97
  output,
91
98
  revertReason: result.findRevertReason()?.message,
92
99
  publicInputs: result.publicInputs!,
100
+ publicTxEffect: result.publicTxEffect,
93
101
  };
94
102
  }
95
103
 
@@ -119,6 +127,7 @@ async function execute(base64Line: string): Promise<void> {
119
127
  output: result.output,
120
128
  revertReason: result.revertReason ?? '',
121
129
  endTreeSnapshots: result.publicInputs.endTreeSnapshots,
130
+ publicTxEffect: result.publicTxEffect,
122
131
  });
123
132
  const base64Response = resultBuffer.toString('base64') + '\n';
124
133
  await writeOutput(base64Response);
@@ -129,6 +138,7 @@ async function execute(base64Line: string): Promise<void> {
129
138
  output: [] as Fr[],
130
139
  revertReason: `Unexpected Error ${error.message}`,
131
140
  endTreeSnapshots: TreeSnapshots.empty(),
141
+ publicTxEffect: PublicTxEffect.empty(),
132
142
  });
133
143
  await writeOutput(errorResult.toString('base64') + '\n');
134
144
  }
@@ -572,7 +572,7 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
572
572
  return await this.db.close();
573
573
  }
574
574
 
575
- async [Symbol.dispose](): Promise<void> {
575
+ async [Symbol.asyncDispose](): Promise<void> {
576
576
  await this.close();
577
577
  }
578
578
 
@@ -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();
@@ -82,7 +82,7 @@ export class GuardedMerkleTreeOperations implements MerkleTreeWriteOperations {
82
82
  return this.guardAndPush(() => this.target.close());
83
83
  }
84
84
 
85
- async [Symbol.dispose](): Promise<void> {
85
+ async [Symbol.asyncDispose](): Promise<void> {
86
86
  await this.close();
87
87
  }
88
88
  getTreeInfo(treeId: MerkleTreeId): Promise<TreeInfo> {
@@ -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';
@@ -25,6 +25,7 @@ import type {
25
25
  PublicProcessorValidator,
26
26
  SequencerConfig,
27
27
  } from '@aztec/stdlib/interfaces/server';
28
+ import { type DebugLog, type DebugLogStore, NullDebugLogStore } from '@aztec/stdlib/logs';
28
29
  import { ProvingRequestType } from '@aztec/stdlib/proofs';
29
30
  import { MerkleTreeId } from '@aztec/stdlib/trees';
30
31
  import {
@@ -62,11 +63,15 @@ import { PublicProcessorMetrics } from './public_processor_metrics.js';
62
63
  * Creates new instances of PublicProcessor given the provided merkle tree db and contract data source.
63
64
  */
64
65
  export class PublicProcessorFactory {
66
+ private log: Logger;
65
67
  constructor(
66
68
  private contractDataSource: ContractDataSource,
67
69
  private dateProvider: DateProvider = new DateProvider(),
68
70
  protected telemetryClient: TelemetryClient = getTelemetryClient(),
69
- ) {}
71
+ bindings?: LoggerBindings,
72
+ ) {
73
+ this.log = createLogger('simulator:public-processor-factory', bindings);
74
+ }
70
75
 
71
76
  /**
72
77
  * Creates a new instance of a PublicProcessor.
@@ -79,7 +84,8 @@ export class PublicProcessorFactory {
79
84
  globalVariables: GlobalVariables,
80
85
  config: PublicSimulatorConfig,
81
86
  ): PublicProcessor {
82
- const contractsDB = new PublicContractsDB(this.contractDataSource);
87
+ const bindings = this.log.getBindings();
88
+ const contractsDB = new PublicContractsDB(this.contractDataSource, bindings);
83
89
 
84
90
  const guardedFork = new GuardedMerkleTreeOperations(merkleTree);
85
91
  const publicTxSimulator = this.createPublicTxSimulator(guardedFork, contractsDB, globalVariables, config);
@@ -91,6 +97,7 @@ export class PublicProcessorFactory {
91
97
  publicTxSimulator,
92
98
  this.dateProvider,
93
99
  this.telemetryClient,
100
+ createLogger('simulator:public-processor', bindings),
94
101
  );
95
102
  }
96
103
 
@@ -100,7 +107,14 @@ export class PublicProcessorFactory {
100
107
  globalVariables: GlobalVariables,
101
108
  config?: Partial<PublicTxSimulatorConfig>,
102
109
  ): PublicTxSimulatorInterface {
103
- return new TelemetryCppPublicTxSimulator(merkleTree, contractsDB, globalVariables, this.telemetryClient, config);
110
+ return new TelemetryCppPublicTxSimulator(
111
+ merkleTree,
112
+ contractsDB,
113
+ globalVariables,
114
+ this.telemetryClient,
115
+ config,
116
+ this.log.getBindings(),
117
+ );
104
118
  }
105
119
  }
106
120
 
@@ -117,7 +131,6 @@ class PublicProcessorTimeoutError extends Error {
117
131
  */
118
132
  export class PublicProcessor implements Traceable {
119
133
  private metrics: PublicProcessorMetrics;
120
-
121
134
  constructor(
122
135
  protected globalVariables: GlobalVariables,
123
136
  private guardedMerkleTree: GuardedMerkleTreeOperations,
@@ -125,8 +138,9 @@ 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'> = {},
143
+ private debugLogStore: DebugLogStore = new NullDebugLogStore(),
130
144
  ) {
131
145
  this.metrics = new PublicProcessorMetrics(telemetryClient, 'PublicProcessor');
132
146
  }
@@ -146,12 +160,13 @@ export class PublicProcessor implements Traceable {
146
160
  txs: Iterable<Tx> | AsyncIterable<Tx>,
147
161
  limits: PublicProcessorLimits = {},
148
162
  validator: PublicProcessorValidator = {},
149
- ): Promise<[ProcessedTx[], FailedTx[], Tx[], NestedProcessReturnValues[], number]> {
163
+ ): Promise<[ProcessedTx[], FailedTx[], Tx[], NestedProcessReturnValues[], number, DebugLog[]]> {
150
164
  const { maxTransactions, maxBlockSize, deadline, maxBlockGas, maxBlobFields } = limits;
151
165
  const { preprocessValidator, nullifierCache } = validator;
152
166
  const result: ProcessedTx[] = [];
153
167
  const usedTxs: Tx[] = [];
154
168
  const failed: FailedTx[] = [];
169
+ const debugLogs: DebugLog[] = [];
155
170
  const timer = new Timer();
156
171
 
157
172
  let totalSizeInBytes = 0;
@@ -228,7 +243,7 @@ export class PublicProcessor implements Traceable {
228
243
  this.contractsDB.createCheckpoint();
229
244
 
230
245
  try {
231
- const [processedTx, returnValues] = await this.processTx(tx, deadline);
246
+ const [processedTx, returnValues, txDebugLogs] = await this.processTx(tx, deadline);
232
247
 
233
248
  // Inject a fake processing failure after N txs if requested
234
249
  const fakeThrowAfter = this.opts.fakeThrowAfterProcessingTxCount;
@@ -277,6 +292,9 @@ export class PublicProcessor implements Traceable {
277
292
  result.push(processedTx);
278
293
  usedTxs.push(tx);
279
294
  returns = returns.concat(returnValues);
295
+ debugLogs.push(...txDebugLogs);
296
+
297
+ this.debugLogStore.storeLogs(processedTx.hash.toString(), txDebugLogs);
280
298
 
281
299
  totalPublicGas = totalPublicGas.add(processedTx.gasUsed.publicGas);
282
300
  totalBlockGas = totalBlockGas.add(processedTx.gasUsed.totalGas);
@@ -350,7 +368,7 @@ export class PublicProcessor implements Traceable {
350
368
  totalSizeInBytes,
351
369
  });
352
370
 
353
- return [result, failed, usedTxs, returns, totalBlobFields];
371
+ return [result, failed, usedTxs, returns, totalBlobFields, debugLogs];
354
372
  }
355
373
 
356
374
  private async checkWorldStateUnchanged(
@@ -370,8 +388,13 @@ export class PublicProcessor implements Traceable {
370
388
  }
371
389
 
372
390
  @trackSpan('PublicProcessor.processTx', tx => ({ [Attributes.TX_HASH]: tx.getTxHash().toString() }))
373
- private async processTx(tx: Tx, deadline: Date | undefined): Promise<[ProcessedTx, NestedProcessReturnValues[]]> {
374
- const [time, [processedTx, returnValues]] = await elapsed(() => this.processTxWithinDeadline(tx, deadline));
391
+ private async processTx(
392
+ tx: Tx,
393
+ deadline: Date | undefined,
394
+ ): Promise<[ProcessedTx, NestedProcessReturnValues[], DebugLog[]]> {
395
+ const [time, [processedTx, returnValues, debugLogs]] = await elapsed(() =>
396
+ this.processTxWithinDeadline(tx, deadline),
397
+ );
375
398
 
376
399
  this.log.verbose(
377
400
  !tx.hasPublicCalls()
@@ -394,7 +417,7 @@ export class PublicProcessor implements Traceable {
394
417
  },
395
418
  );
396
419
 
397
- return [processedTx, returnValues ?? []];
420
+ return [processedTx, returnValues ?? [], debugLogs];
398
421
  }
399
422
 
400
423
  private async doTreeInsertionsForPrivateOnlyTx(processedTx: ProcessedTx): Promise<void> {
@@ -428,10 +451,9 @@ export class PublicProcessor implements Traceable {
428
451
  private async processTxWithinDeadline(
429
452
  tx: Tx,
430
453
  deadline: Date | undefined,
431
- ): Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined]> {
432
- const innerProcessFn: () => Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined]> = tx.hasPublicCalls()
433
- ? () => this.processTxWithPublicCalls(tx)
434
- : () => this.processPrivateOnlyTx(tx);
454
+ ): Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> {
455
+ const innerProcessFn: () => Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined, DebugLog[]]> =
456
+ tx.hasPublicCalls() ? () => this.processTxWithPublicCalls(tx) : () => this.processPrivateOnlyTx(tx);
435
457
 
436
458
  // Fake a delay per tx if instructed (used for tests)
437
459
  const fakeDelayPerTxMs = this.opts.fakeProcessingDelayPerTxMs;
@@ -499,7 +521,7 @@ export class PublicProcessor implements Traceable {
499
521
  @trackSpan('PublicProcessor.processPrivateOnlyTx', (tx: Tx) => ({
500
522
  [Attributes.TX_HASH]: tx.getTxHash().toString(),
501
523
  }))
502
- private async processPrivateOnlyTx(tx: Tx): Promise<[ProcessedTx, undefined]> {
524
+ private async processPrivateOnlyTx(tx: Tx): Promise<[ProcessedTx, undefined, DebugLog[]]> {
503
525
  const gasFees = this.globalVariables.gasFees;
504
526
  const transactionFee = computeTransactionFee(gasFees, tx.data.constants.txContext.gasSettings, tx.data.gasUsed);
505
527
 
@@ -524,13 +546,13 @@ export class PublicProcessor implements Traceable {
524
546
 
525
547
  await this.contractsDB.addNewContracts(tx);
526
548
 
527
- return [processedTx, undefined];
549
+ return [processedTx, undefined, []];
528
550
  }
529
551
 
530
552
  @trackSpan('PublicProcessor.processTxWithPublicCalls', tx => ({
531
553
  [Attributes.TX_HASH]: tx.getTxHash().toString(),
532
554
  }))
533
- private async processTxWithPublicCalls(tx: Tx): Promise<[ProcessedTx, NestedProcessReturnValues[]]> {
555
+ private async processTxWithPublicCalls(tx: Tx): Promise<[ProcessedTx, NestedProcessReturnValues[], DebugLog[]]> {
534
556
  const timer = new Timer();
535
557
 
536
558
  const result = await this.publicTxSimulator.simulate(tx);
@@ -568,7 +590,7 @@ export class PublicProcessor implements Traceable {
568
590
  revertReason,
569
591
  );
570
592
 
571
- return [processedTx, appLogicReturnValues];
593
+ return [processedTx, appLogicReturnValues, result.logs ?? []];
572
594
  }
573
595
 
574
596
  /**
@@ -1,6 +1,6 @@
1
1
  import type { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
2
2
  import type { Gas } from '@aztec/stdlib/gas';
3
- import type { TxExecutionPhase } from '@aztec/stdlib/tx';
3
+ import { TxExecutionPhase } from '@aztec/stdlib/tx';
4
4
  import {
5
5
  Attributes,
6
6
  type Gauge,
@@ -9,6 +9,7 @@ import {
9
9
  type TelemetryClient,
10
10
  type Tracer,
11
11
  type UpDownCounter,
12
+ createUpDownCounterWithDefault,
12
13
  } from '@aztec/telemetry-client';
13
14
 
14
15
  export class PublicProcessorMetrics {
@@ -35,13 +36,18 @@ export class PublicProcessorMetrics {
35
36
 
36
37
  this.txDuration = meter.createHistogram(Metrics.PUBLIC_PROCESSOR_TX_DURATION);
37
38
 
38
- this.txCount = meter.createUpDownCounter(Metrics.PUBLIC_PROCESSOR_TX_COUNT);
39
+ this.txCount = createUpDownCounterWithDefault(meter, Metrics.PUBLIC_PROCESSOR_TX_COUNT, {
40
+ [Attributes.OK]: [true, false],
41
+ });
39
42
 
40
- this.txPhaseCount = meter.createUpDownCounter(Metrics.PUBLIC_PROCESSOR_TX_PHASE_COUNT);
43
+ this.txPhaseCount = createUpDownCounterWithDefault(meter, Metrics.PUBLIC_PROCESSOR_TX_PHASE_COUNT);
41
44
 
42
45
  this.phaseDuration = meter.createHistogram(Metrics.PUBLIC_PROCESSOR_PHASE_DURATION);
43
46
 
44
- this.phaseCount = meter.createUpDownCounter(Metrics.PUBLIC_PROCESSOR_PHASE_COUNT);
47
+ this.phaseCount = createUpDownCounterWithDefault(meter, Metrics.PUBLIC_PROCESSOR_PHASE_COUNT, {
48
+ [Attributes.TX_PHASE_NAME]: [TxExecutionPhase.SETUP, TxExecutionPhase.APP_LOGIC, TxExecutionPhase.TEARDOWN],
49
+ [Attributes.OK]: [true, false],
50
+ });
45
51
 
46
52
  this.bytecodeDeployed = meter.createHistogram(Metrics.PUBLIC_PROCESSOR_DEPLOY_BYTECODE_SIZE);
47
53