@aztec/simulator 0.60.0 → 0.62.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 (133) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +3 -0
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +12 -1
  4. package/dest/acvm/oracle/typed_oracle.d.ts +4 -1
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +10 -1
  7. package/dest/avm/avm_gas.d.ts.map +1 -1
  8. package/dest/avm/avm_gas.js +8 -5
  9. package/dest/avm/avm_machine_state.d.ts +2 -0
  10. package/dest/avm/avm_machine_state.d.ts.map +1 -1
  11. package/dest/avm/avm_machine_state.js +3 -1
  12. package/dest/avm/avm_simulator.d.ts +15 -0
  13. package/dest/avm/avm_simulator.d.ts.map +1 -1
  14. package/dest/avm/avm_simulator.js +45 -4
  15. package/dest/avm/fixtures/index.d.ts +1 -1
  16. package/dest/avm/fixtures/index.d.ts.map +1 -1
  17. package/dest/avm/fixtures/index.js +7 -7
  18. package/dest/avm/journal/journal.d.ts +5 -6
  19. package/dest/avm/journal/journal.d.ts.map +1 -1
  20. package/dest/avm/journal/journal.js +42 -17
  21. package/dest/avm/opcodes/contract.d.ts +8 -1
  22. package/dest/avm/opcodes/contract.d.ts.map +1 -1
  23. package/dest/avm/opcodes/contract.js +41 -21
  24. package/dest/avm/opcodes/control_flow.js +5 -5
  25. package/dest/avm/opcodes/conversion.d.ts +1 -1
  26. package/dest/avm/opcodes/conversion.d.ts.map +1 -1
  27. package/dest/avm/opcodes/conversion.js +12 -9
  28. package/dest/avm/opcodes/environment_getters.d.ts +1 -1
  29. package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
  30. package/dest/avm/opcodes/environment_getters.js +5 -1
  31. package/dest/avm/opcodes/external_calls.d.ts +3 -6
  32. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  33. package/dest/avm/opcodes/external_calls.js +23 -43
  34. package/dest/avm/opcodes/memory.d.ts +20 -0
  35. package/dest/avm/opcodes/memory.d.ts.map +1 -1
  36. package/dest/avm/opcodes/memory.js +59 -3
  37. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  38. package/dest/avm/serialization/bytecode_serialization.js +5 -3
  39. package/dest/avm/serialization/instruction_serialization.d.ts +36 -34
  40. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  41. package/dest/avm/serialization/instruction_serialization.js +37 -35
  42. package/dest/avm/test_utils.d.ts +2 -1
  43. package/dest/avm/test_utils.d.ts.map +1 -1
  44. package/dest/avm/test_utils.js +4 -1
  45. package/dest/client/client_execution_context.d.ts +1 -8
  46. package/dest/client/client_execution_context.d.ts.map +1 -1
  47. package/dest/client/client_execution_context.js +4 -18
  48. package/dest/client/db_oracle.d.ts +24 -1
  49. package/dest/client/db_oracle.d.ts.map +1 -1
  50. package/dest/client/db_oracle.js +1 -1
  51. package/dest/client/view_data_oracle.d.ts +17 -1
  52. package/dest/client/view_data_oracle.d.ts.map +1 -1
  53. package/dest/client/view_data_oracle.js +21 -1
  54. package/dest/common/index.d.ts +0 -1
  55. package/dest/common/index.d.ts.map +1 -1
  56. package/dest/common/index.js +1 -2
  57. package/dest/public/dual_side_effect_trace.d.ts +3 -5
  58. package/dest/public/dual_side_effect_trace.d.ts.map +1 -1
  59. package/dest/public/dual_side_effect_trace.js +8 -4
  60. package/dest/public/enqueued_call_side_effect_trace.d.ts +4 -6
  61. package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
  62. package/dest/public/enqueued_call_side_effect_trace.js +19 -7
  63. package/dest/public/enqueued_call_simulator.d.ts +2 -2
  64. package/dest/public/enqueued_call_simulator.d.ts.map +1 -1
  65. package/dest/public/enqueued_call_simulator.js +21 -29
  66. package/dest/public/enqueued_calls_processor.d.ts +2 -3
  67. package/dest/public/enqueued_calls_processor.d.ts.map +1 -1
  68. package/dest/public/enqueued_calls_processor.js +18 -25
  69. package/dest/public/public_db_sources.d.ts.map +1 -1
  70. package/dest/public/public_db_sources.js +10 -15
  71. package/dest/public/public_kernel.d.ts +0 -1
  72. package/dest/public/public_kernel.d.ts.map +1 -1
  73. package/dest/public/public_kernel.js +5 -8
  74. package/dest/public/public_kernel_tail_simulator.d.ts +1 -5
  75. package/dest/public/public_kernel_tail_simulator.d.ts.map +1 -1
  76. package/dest/public/public_kernel_tail_simulator.js +6 -12
  77. package/dest/public/public_processor.js +4 -4
  78. package/dest/public/side_effect_trace.d.ts +4 -3
  79. package/dest/public/side_effect_trace.d.ts.map +1 -1
  80. package/dest/public/side_effect_trace.js +27 -16
  81. package/dest/public/side_effect_trace_interface.d.ts +3 -3
  82. package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
  83. package/dest/test/utils.d.ts +2 -2
  84. package/dest/test/utils.d.ts.map +1 -1
  85. package/dest/test/utils.js +4 -4
  86. package/package.json +9 -9
  87. package/src/acvm/oracle/oracle.ts +20 -0
  88. package/src/acvm/oracle/typed_oracle.ts +13 -0
  89. package/src/avm/avm_gas.ts +7 -4
  90. package/src/avm/avm_machine_state.ts +2 -0
  91. package/src/avm/avm_simulator.ts +69 -6
  92. package/src/avm/fixtures/index.ts +7 -7
  93. package/src/avm/journal/journal.ts +62 -19
  94. package/src/avm/opcodes/contract.ts +45 -21
  95. package/src/avm/opcodes/control_flow.ts +5 -5
  96. package/src/avm/opcodes/conversion.ts +9 -6
  97. package/src/avm/opcodes/environment_getters.ts +7 -2
  98. package/src/avm/opcodes/external_calls.ts +21 -45
  99. package/src/avm/opcodes/memory.ts +69 -2
  100. package/src/avm/serialization/bytecode_serialization.ts +6 -2
  101. package/src/avm/serialization/instruction_serialization.ts +5 -3
  102. package/src/avm/test_utils.ts +5 -1
  103. package/src/client/client_execution_context.ts +4 -27
  104. package/src/client/db_oracle.ts +38 -0
  105. package/src/client/view_data_oracle.ts +31 -1
  106. package/src/common/index.ts +0 -1
  107. package/src/public/dual_side_effect_trace.ts +20 -6
  108. package/src/public/enqueued_call_side_effect_trace.ts +46 -8
  109. package/src/public/enqueued_call_simulator.ts +42 -26
  110. package/src/public/enqueued_calls_processor.ts +26 -38
  111. package/src/public/public_db_sources.ts +10 -15
  112. package/src/public/public_kernel.ts +9 -12
  113. package/src/public/public_kernel_tail_simulator.ts +6 -15
  114. package/src/public/public_processor.ts +3 -3
  115. package/src/public/side_effect_trace.ts +54 -15
  116. package/src/public/side_effect_trace_interface.ts +9 -4
  117. package/src/test/utils.ts +9 -2
  118. package/dest/client/test_utils.d.ts +0 -9
  119. package/dest/client/test_utils.d.ts.map +0 -1
  120. package/dest/client/test_utils.js +0 -27
  121. package/dest/common/side_effect_counter.d.ts +0 -10
  122. package/dest/common/side_effect_counter.d.ts.map +0 -1
  123. package/dest/common/side_effect_counter.js +0 -18
  124. package/dest/rollup/index.d.ts +0 -2
  125. package/dest/rollup/index.d.ts.map +0 -1
  126. package/dest/rollup/index.js +0 -2
  127. package/dest/rollup/rollup.d.ts +0 -101
  128. package/dest/rollup/rollup.d.ts.map +0 -1
  129. package/dest/rollup/rollup.js +0 -100
  130. package/src/client/test_utils.ts +0 -57
  131. package/src/common/side_effect_counter.ts +0 -17
  132. package/src/rollup/index.ts +0 -1
  133. package/src/rollup/rollup.ts +0 -228
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,aAAa,EAAW,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,KAAK,YAAY,EAAc,KAAK,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAI5E;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,aACnB,MAAM,mBACC,EAAE,EAAE,kBACL,YAAY,UACpB,EAAE,kBASX,CAAC"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,aAAa,EAAW,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,KAAK,YAAY,EAAc,EAAE,EAAE,MAAM,oBAAoB,CAAC;AAIvE;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,aACnB,MAAM,mBACC,EAAE,EAAE,kBACL,YAAY,UACpB,EAAE,YACA,EAAE,GAAG,MAAM,kBAetB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { L1Actor, L1ToL2Message, L2Actor } from '@aztec/circuit-types';
2
- import { EthAddress } from '@aztec/circuits.js';
2
+ import { EthAddress, Fr } from '@aztec/circuits.js';
3
3
  import { computeSecretHash } from '@aztec/circuits.js/hash';
4
4
  import { sha256ToField } from '@aztec/foundation/crypto';
5
5
  /**
@@ -10,11 +10,11 @@ import { sha256ToField } from '@aztec/foundation/crypto';
10
10
  * @param secret - The secret to unlock the message.
11
11
  * @returns The L1 to L2 message.
12
12
  */
13
- export const buildL1ToL2Message = (selector, contentPreimage, targetContract, secret) => {
13
+ export const buildL1ToL2Message = (selector, contentPreimage, targetContract, secret, msgIndex) => {
14
14
  // Write the selector into a buffer.
15
15
  const selectorBuf = Buffer.from(selector, 'hex');
16
16
  const content = sha256ToField([selectorBuf, ...contentPreimage]);
17
17
  const secretHash = computeSecretHash(secret);
18
- return new L1ToL2Message(new L1Actor(EthAddress.random(), 1), new L2Actor(targetContract, 1), content, secretHash);
18
+ return new L1ToL2Message(new L1Actor(EthAddress.random(), 1), new L2Actor(targetContract, 1), content, secretHash, new Fr(msgIndex));
19
19
  };
20
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RSxPQUFPLEVBQXFCLFVBQVUsRUFBVyxNQUFNLG9CQUFvQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzVELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUV6RDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsQ0FDaEMsUUFBZ0IsRUFDaEIsZUFBcUIsRUFDckIsY0FBNEIsRUFDNUIsTUFBVSxFQUNWLEVBQUU7SUFDRixvQ0FBb0M7SUFDcEMsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFakQsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLENBQUMsV0FBVyxFQUFFLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBQztJQUNqRSxNQUFNLFVBQVUsR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUU3QyxPQUFPLElBQUksYUFBYSxDQUFDLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ3JILENBQUMsQ0FBQyJ9
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdGVzdC91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN2RSxPQUFPLEVBQXFCLFVBQVUsRUFBRSxFQUFFLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUN2RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFFekQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQ2hDLFFBQWdCLEVBQ2hCLGVBQXFCLEVBQ3JCLGNBQTRCLEVBQzVCLE1BQVUsRUFDVixRQUFxQixFQUNyQixFQUFFO0lBQ0Ysb0NBQW9DO0lBQ3BDLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBRWpELE1BQU0sT0FBTyxHQUFHLGFBQWEsQ0FBQyxDQUFDLFdBQVcsRUFBRSxHQUFHLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDakUsTUFBTSxVQUFVLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFN0MsT0FBTyxJQUFJLGFBQWEsQ0FDdEIsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUNuQyxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLEVBQzlCLE9BQU8sRUFDUCxVQUFVLEVBQ1YsSUFBSSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQ2pCLENBQUM7QUFDSixDQUFDLENBQUMifQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/simulator",
3
- "version": "0.60.0",
3
+ "version": "0.62.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -59,14 +59,14 @@
59
59
  ]
60
60
  },
61
61
  "dependencies": {
62
- "@aztec/circuit-types": "0.60.0",
63
- "@aztec/circuits.js": "0.60.0",
64
- "@aztec/foundation": "0.60.0",
65
- "@aztec/noir-protocol-circuits-types": "0.60.0",
66
- "@aztec/protocol-contracts": "0.60.0",
67
- "@aztec/telemetry-client": "0.60.0",
68
- "@aztec/types": "0.60.0",
69
- "@aztec/world-state": "0.60.0",
62
+ "@aztec/circuit-types": "0.62.0",
63
+ "@aztec/circuits.js": "0.62.0",
64
+ "@aztec/foundation": "0.62.0",
65
+ "@aztec/noir-protocol-circuits-types": "0.62.0",
66
+ "@aztec/protocol-contracts": "0.62.0",
67
+ "@aztec/telemetry-client": "0.62.0",
68
+ "@aztec/types": "0.62.0",
69
+ "@aztec/world-state": "0.62.0",
70
70
  "@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js",
71
71
  "@noir-lang/types": "portal:../../noir/packages/types",
72
72
  "levelup": "^5.1.1",
@@ -408,4 +408,24 @@ export class Oracle {
408
408
  notifySetMinRevertibleSideEffectCounter([minRevertibleSideEffectCounter]: ACVMField[]) {
409
409
  this.typedOracle.notifySetMinRevertibleSideEffectCounter(frToNumber(fromACVMField(minRevertibleSideEffectCounter)));
410
410
  }
411
+
412
+ async getAppTaggingSecret([sender]: ACVMField[], [recipient]: ACVMField[]): Promise<ACVMField[]> {
413
+ const taggingSecret = await this.typedOracle.getAppTaggingSecret(
414
+ AztecAddress.fromString(sender),
415
+ AztecAddress.fromString(recipient),
416
+ );
417
+ return taggingSecret.toFields().map(toACVMField);
418
+ }
419
+
420
+ async incrementAppTaggingSecret([sender]: ACVMField[], [recipient]: ACVMField[]) {
421
+ await this.typedOracle.incrementAppTaggingSecret(
422
+ AztecAddress.fromString(sender),
423
+ AztecAddress.fromString(recipient),
424
+ );
425
+ }
426
+
427
+ async getAppTaggingSecretsForSenders([recipient]: ACVMField[]): Promise<ACVMField[]> {
428
+ const taggingSecrets = await this.typedOracle.getAppTaggingSecretsForSenders(AztecAddress.fromString(recipient));
429
+ return taggingSecrets.flatMap(taggingSecret => taggingSecret.toFields().map(toACVMField));
430
+ }
411
431
  }
@@ -11,6 +11,7 @@ import {
11
11
  import {
12
12
  type ContractInstance,
13
13
  type Header,
14
+ type IndexedTaggingSecret,
14
15
  type KeyValidationRequest,
15
16
  type L1_TO_L2_MSG_TREE_HEIGHT,
16
17
  } from '@aztec/circuits.js';
@@ -252,4 +253,16 @@ export abstract class TypedOracle {
252
253
  debugLog(_message: string, _fields: Fr[]): void {
253
254
  throw new OracleMethodNotAvailableError('debugLog');
254
255
  }
256
+
257
+ getAppTaggingSecret(_sender: AztecAddress, _recipient: AztecAddress): Promise<IndexedTaggingSecret> {
258
+ throw new OracleMethodNotAvailableError('getAppTaggingSecret');
259
+ }
260
+
261
+ incrementAppTaggingSecret(_sender: AztecAddress, _recipient: AztecAddress): Promise<void> {
262
+ throw new OracleMethodNotAvailableError('incrementAppTaggingSecret');
263
+ }
264
+
265
+ getAppTaggingSecretsForSenders(_recipient: AztecAddress): Promise<IndexedTaggingSecret[]> {
266
+ throw new OracleMethodNotAvailableError('getAppTaggingSecretsForSenders');
267
+ }
255
268
  }
@@ -89,8 +89,10 @@ const BASE_GAS_COSTS: Record<Opcode, Gas> = {
89
89
  [Opcode.CAST_16]: makeCost(c.AVM_CAST_BASE_L2_GAS, 0),
90
90
  [Opcode.GETENVVAR_16]: makeCost(c.AVM_GETENVVAR_BASE_L2_GAS, 0),
91
91
  [Opcode.CALLDATACOPY]: makeCost(c.AVM_CALLDATACOPY_BASE_L2_GAS, 0),
92
- [Opcode.JUMP_16]: makeCost(c.AVM_JUMP_BASE_L2_GAS, 0),
93
- [Opcode.JUMPI_16]: makeCost(c.AVM_JUMPI_BASE_L2_GAS, 0),
92
+ [Opcode.RETURNDATASIZE]: makeCost(c.AVM_RETURNDATASIZE_BASE_L2_GAS, 0),
93
+ [Opcode.RETURNDATACOPY]: makeCost(c.AVM_RETURNDATACOPY_BASE_L2_GAS, 0),
94
+ [Opcode.JUMP_32]: makeCost(c.AVM_JUMP_BASE_L2_GAS, 0),
95
+ [Opcode.JUMPI_32]: makeCost(c.AVM_JUMPI_BASE_L2_GAS, 0),
94
96
  [Opcode.INTERNALCALL]: makeCost(c.AVM_INTERNALCALL_BASE_L2_GAS, 0),
95
97
  [Opcode.INTERNALRETURN]: makeCost(c.AVM_INTERNALRETURN_BASE_L2_GAS, 0),
96
98
  [Opcode.SET_8]: makeCost(c.AVM_SET_BASE_L2_GAS, 0),
@@ -122,11 +124,12 @@ const BASE_GAS_COSTS: Record<Opcode, Gas> = {
122
124
  [Opcode.KECCAKF1600]: makeCost(c.AVM_KECCAKF1600_BASE_L2_GAS, 0),
123
125
  [Opcode.ECADD]: makeCost(c.AVM_ECADD_BASE_L2_GAS, 0),
124
126
  [Opcode.MSM]: makeCost(c.AVM_MSM_BASE_L2_GAS, 0),
125
- [Opcode.TORADIXLE]: makeCost(c.AVM_TORADIXLE_BASE_L2_GAS, 0),
127
+ [Opcode.TORADIXBE]: makeCost(c.AVM_TORADIXBE_BASE_L2_GAS, 0),
126
128
  };
127
129
 
128
130
  const DYNAMIC_GAS_COSTS = new Map<Opcode, Gas>([
129
131
  [Opcode.CALLDATACOPY, makeCost(c.AVM_CALLDATACOPY_DYN_L2_GAS, 0)],
132
+ [Opcode.RETURNDATACOPY, makeCost(c.AVM_RETURNDATACOPY_DYN_L2_GAS, 0)],
130
133
  [Opcode.EMITUNENCRYPTEDLOG, makeCost(c.AVM_EMITUNENCRYPTEDLOG_DYN_L2_GAS, c.AVM_EMITUNENCRYPTEDLOG_DYN_DA_GAS)],
131
134
  [Opcode.CALL, makeCost(c.AVM_CALL_DYN_L2_GAS, 0)],
132
135
  [Opcode.STATICCALL, makeCost(c.AVM_STATICCALL_DYN_L2_GAS, 0)],
@@ -134,7 +137,7 @@ const DYNAMIC_GAS_COSTS = new Map<Opcode, Gas>([
134
137
  [Opcode.REVERT_8, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)],
135
138
  [Opcode.REVERT_16, makeCost(c.AVM_REVERT_DYN_L2_GAS, 0)],
136
139
  [Opcode.MSM, makeCost(c.AVM_MSM_DYN_L2_GAS, 0)],
137
- [Opcode.TORADIXLE, makeCost(c.AVM_TORADIXLE_DYN_L2_GAS, 0)],
140
+ [Opcode.TORADIXBE, makeCost(c.AVM_TORADIXBE_DYN_L2_GAS, 0)],
138
141
  ]);
139
142
 
140
143
  /** Returns the fixed base gas cost for a given opcode. */
@@ -21,6 +21,8 @@ export class AvmMachineState {
21
21
  public daGasLeft: number;
22
22
  /** program counter */
23
23
  public pc: number = 0;
24
+ /** return/revertdata of the last nested call. */
25
+ public nestedReturndata: Fr[] = [];
24
26
 
25
27
  /**
26
28
  * On INTERNALCALL, internal call stack is pushed to with the current pc + 1
@@ -6,6 +6,7 @@ import { strict as assert } from 'assert';
6
6
  import { SideEffectLimitReachedError } from '../public/side_effect_errors.js';
7
7
  import type { AvmContext } from './avm_context.js';
8
8
  import { AvmContractCallResult } from './avm_contract_call_result.js';
9
+ import { type Gas } from './avm_gas.js';
9
10
  import { isAvmBytecode } from './bytecode_utils.js';
10
11
  import {
11
12
  AvmExecutionError,
@@ -17,9 +18,21 @@ import {
17
18
  import type { Instruction } from './opcodes/index.js';
18
19
  import { decodeFromBytecode } from './serialization/bytecode_serialization.js';
19
20
 
21
+ type OpcodeTally = {
22
+ count: number;
23
+ gas: Gas;
24
+ };
25
+ type PcTally = {
26
+ opcode: string;
27
+ count: number;
28
+ gas: Gas;
29
+ };
30
+
20
31
  export class AvmSimulator {
21
32
  private log: DebugLogger;
22
33
  private bytecode: Buffer | undefined;
34
+ public opcodeTallies: Map<string, OpcodeTally> = new Map();
35
+ public pcTallies: Map<number, PcTally> = new Map();
23
36
 
24
37
  constructor(private context: AvmContext) {
25
38
  assert(
@@ -33,10 +46,7 @@ export class AvmSimulator {
33
46
  * Fetch the bytecode and execute it in the current context.
34
47
  */
35
48
  public async execute(): Promise<AvmContractCallResult> {
36
- const bytecode = await this.context.persistableState.getBytecode(
37
- this.context.environment.address,
38
- this.context.environment.functionSelector,
39
- );
49
+ const bytecode = await this.context.persistableState.getBytecode(this.context.environment.address);
40
50
 
41
51
  // This assumes that we will not be able to send messages to accounts without code
42
52
  // Pending classes and instances impl details
@@ -75,6 +85,7 @@ export class AvmSimulator {
75
85
  try {
76
86
  // Execute instruction pointed to by the current program counter
77
87
  // continuing until the machine state signifies a halt
88
+ let instrCounter = 0;
78
89
  while (!machineState.getHalted()) {
79
90
  const instruction = instructions[machineState.pc];
80
91
  assert(
@@ -82,13 +93,26 @@ export class AvmSimulator {
82
93
  'AVM attempted to execute non-existent instruction. This should never happen (invalid bytecode or AVM simulator bug)!',
83
94
  );
84
95
 
85
- const gasLeft = `l2=${machineState.l2GasLeft} da=${machineState.daGasLeft}`;
86
- this.log.debug(`@${machineState.pc} ${instruction.toString()} (${gasLeft})`);
96
+ const instrStartGas = machineState.gasLeft; // Save gas before executing instruction (for profiling)
97
+ const instrPc = machineState.pc; // Save PC before executing instruction (for profiling)
98
+
99
+ this.log.debug(
100
+ `[PC:${machineState.pc}] [IC:${instrCounter++}] ${instruction.toString()} (gasLeft l2=${
101
+ machineState.l2GasLeft
102
+ } da=${machineState.daGasLeft})`,
103
+ );
87
104
  // Execute the instruction.
88
105
  // Normal returns and reverts will return normally here.
89
106
  // "Exceptional halts" will throw.
90
107
  await instruction.execute(this.context);
91
108
 
109
+ // gas used by this instruction - used for profiling/tallying
110
+ const gasUsed: Gas = {
111
+ l2Gas: instrStartGas.l2Gas - machineState.l2GasLeft,
112
+ daGas: instrStartGas.daGas - machineState.daGasLeft,
113
+ };
114
+ this.tallyInstruction(instrPc, instruction.constructor.name, gasUsed);
115
+
92
116
  if (machineState.pc >= instructions.length) {
93
117
  this.log.warn('Passed end of program');
94
118
  throw new InvalidProgramCounterError(machineState.pc, /*max=*/ instructions.length);
@@ -100,6 +124,8 @@ export class AvmSimulator {
100
124
  const revertReason = reverted ? revertReasonFromExplicitRevert(output, this.context) : undefined;
101
125
  const results = new AvmContractCallResult(reverted, output, revertReason);
102
126
  this.log.debug(`Context execution results: ${results.toString()}`);
127
+
128
+ this.printOpcodeTallies();
103
129
  // Return results for processing by calling context
104
130
  return results;
105
131
  } catch (err: any) {
@@ -113,8 +139,45 @@ export class AvmSimulator {
113
139
  // Note: "exceptional halts" cannot return data, hence []
114
140
  const results = new AvmContractCallResult(/*reverted=*/ true, /*output=*/ [], revertReason);
115
141
  this.log.debug(`Context execution results: ${results.toString()}`);
142
+
143
+ this.printOpcodeTallies();
116
144
  // Return results for processing by calling context
117
145
  return results;
118
146
  }
119
147
  }
148
+
149
+ private tallyInstruction(pc: number, opcode: string, gasUsed: Gas) {
150
+ const opcodeTally = this.opcodeTallies.get(opcode) || ({ count: 0, gas: { l2Gas: 0, daGas: 0 } } as OpcodeTally);
151
+ opcodeTally.count++;
152
+ opcodeTally.gas.l2Gas += gasUsed.l2Gas;
153
+ opcodeTally.gas.daGas += gasUsed.daGas;
154
+ this.opcodeTallies.set(opcode, opcodeTally);
155
+
156
+ const pcTally = this.pcTallies.get(pc) || ({ opcode: opcode, count: 0, gas: { l2Gas: 0, daGas: 0 } } as PcTally);
157
+ pcTally.count++;
158
+ pcTally.gas.l2Gas += gasUsed.l2Gas;
159
+ pcTally.gas.daGas += gasUsed.daGas;
160
+ this.pcTallies.set(pc, pcTally);
161
+ }
162
+
163
+ private printOpcodeTallies() {
164
+ this.log.debug(`Printing tallies per opcode sorted by gas...`);
165
+ // sort descending by L2 gas consumed
166
+ const sortedOpcodes = Array.from(this.opcodeTallies.entries()).sort((a, b) => b[1].gas.l2Gas - a[1].gas.l2Gas);
167
+ for (const [opcode, tally] of sortedOpcodes) {
168
+ // NOTE: don't care to clutter the logs with DA gas for now
169
+ this.log.debug(`${opcode} executed ${tally.count} times consuming a total of ${tally.gas.l2Gas} L2 gas`);
170
+ }
171
+
172
+ this.log.debug(`Printing tallies per PC sorted by #times each PC was executed...`);
173
+ const sortedPcs = Array.from(this.pcTallies.entries())
174
+ .sort((a, b) => b[1].count - a[1].count)
175
+ .filter((_, i) => i < 20);
176
+ for (const [pc, tally] of sortedPcs) {
177
+ // NOTE: don't care to clutter the logs with DA gas for now
178
+ this.log.debug(
179
+ `PC:${pc} containing opcode ${tally.opcode} executed ${tally.count} times consuming a total of ${tally.gas.l2Gas} L2 gas`,
180
+ );
181
+ }
182
+ }
120
183
  }
@@ -117,6 +117,13 @@ export function randomMemoryFields(length: number): Field[] {
117
117
  return [...Array(length)].map(_ => new Field(Fr.random()));
118
118
  }
119
119
 
120
+ export function getAvmTestContractFunctionSelector(functionName: string): FunctionSelector {
121
+ const artifact = AvmTestContractArtifact.functions.find(f => f.name === functionName)!;
122
+ assert(!!artifact, `Function ${functionName} not found in AvmTestContractArtifact`);
123
+ const params = artifact.parameters;
124
+ return FunctionSelector.fromNameAndParameters(artifact.name, params);
125
+ }
126
+
120
127
  export function getAvmTestContractBytecode(functionName: string): Buffer {
121
128
  const artifact = AvmTestContractArtifact.functions.find(f => f.name === functionName)!;
122
129
  assert(
@@ -147,10 +154,3 @@ export function resolveAvmTestContractAssertionMessage(
147
154
 
148
155
  return resolveAssertionMessage(revertReason.noirCallStack, debugMetadata);
149
156
  }
150
-
151
- export function getAvmTestContractFunctionSelector(functionName: string): FunctionSelector {
152
- const artifact = AvmTestContractArtifact.functions.find(f => f.name === functionName)!;
153
- assert(!!artifact, `Function ${functionName} not found in AvmTestContractArtifact`);
154
- const params = artifact.parameters;
155
- return FunctionSelector.fromNameAndParameters(artifact.name, params);
156
- }
@@ -1,10 +1,16 @@
1
- import { AztecAddress, type FunctionSelector, type Gas, SerializableContractInstance } from '@aztec/circuits.js';
1
+ import {
2
+ AztecAddress,
3
+ type Gas,
4
+ SerializableContractInstance,
5
+ computePublicBytecodeCommitment,
6
+ } from '@aztec/circuits.js';
2
7
  import { Fr } from '@aztec/foundation/fields';
3
8
  import { createDebugLogger } from '@aztec/foundation/log';
4
9
 
10
+ import assert from 'assert';
11
+
5
12
  import { getPublicFunctionDebugName } from '../../common/debug_fn_name.js';
6
13
  import { type WorldStateDB } from '../../public/public_db_sources.js';
7
- import { type TracedContractInstance } from '../../public/side_effect_trace.js';
8
14
  import { type PublicSideEffectTraceInterface } from '../../public/side_effect_trace_interface.js';
9
15
  import { type AvmContractCallResult } from '../avm_contract_call_result.js';
10
16
  import { type AvmExecutionEnvironment } from '../avm_execution_environment.js';
@@ -210,22 +216,26 @@ export class AvmPersistableStateManager {
210
216
  /**
211
217
  * Get a contract instance.
212
218
  * @param contractAddress - address of the contract instance to retrieve.
213
- * @returns the contract instance with an "exists" flag
219
+ * @returns the contract instance or undefined if it does not exist.
214
220
  */
215
- public async getContractInstance(contractAddress: Fr): Promise<TracedContractInstance> {
216
- let exists = true;
217
- const aztecAddress = AztecAddress.fromField(contractAddress);
218
- let instance = await this.worldStateDB.getContractInstance(aztecAddress);
219
- if (instance === undefined) {
220
- instance = SerializableContractInstance.default().withAddress(aztecAddress);
221
- exists = false;
221
+ public async getContractInstance(contractAddress: Fr): Promise<SerializableContractInstance | undefined> {
222
+ this.log.debug(`Getting contract instance for address ${contractAddress}`);
223
+ const instanceWithAddress = await this.worldStateDB.getContractInstance(AztecAddress.fromField(contractAddress));
224
+ const exists = instanceWithAddress !== undefined;
225
+
226
+ if (exists) {
227
+ const instance = new SerializableContractInstance(instanceWithAddress);
228
+ this.log.debug(
229
+ `Got contract instance (address=${contractAddress}): exists=${exists}, instance=${JSON.stringify(instance)}`,
230
+ );
231
+ this.trace.traceGetContractInstance(contractAddress, exists, instance);
232
+
233
+ return Promise.resolve(instance);
234
+ } else {
235
+ this.log.debug(`Contract instance NOT FOUND (address=${contractAddress})`);
236
+ this.trace.traceGetContractInstance(contractAddress, exists);
237
+ return Promise.resolve(undefined);
222
238
  }
223
- this.log.debug(
224
- `Get Contract instance (address=${contractAddress}): exists=${exists}, instance=${JSON.stringify(instance)}`,
225
- );
226
- const tracedInstance = { ...instance, exists };
227
- this.trace.traceGetContractInstance(tracedInstance);
228
- return Promise.resolve(tracedInstance);
229
239
  }
230
240
 
231
241
  /**
@@ -237,10 +247,43 @@ export class AvmPersistableStateManager {
237
247
  }
238
248
 
239
249
  /**
240
- * Get a contract's bytecode from the contracts DB
250
+ * Get a contract's bytecode from the contracts DB, also trace the contract class and instance
241
251
  */
242
- public async getBytecode(contractAddress: AztecAddress, selector: FunctionSelector): Promise<Buffer | undefined> {
243
- return await this.worldStateDB.getBytecode(contractAddress, selector);
252
+ public async getBytecode(contractAddress: AztecAddress): Promise<Buffer | undefined> {
253
+ this.log.debug(`Getting bytecode for contract address ${contractAddress}`);
254
+ const instanceWithAddress = await this.worldStateDB.getContractInstance(contractAddress);
255
+ const exists = instanceWithAddress !== undefined;
256
+
257
+ if (exists) {
258
+ const instance = new SerializableContractInstance(instanceWithAddress);
259
+
260
+ const contractClass = await this.worldStateDB.getContractClass(instance.contractClassId);
261
+ assert(
262
+ contractClass,
263
+ `Contract class not found in DB, but a contract instance was found with this class ID (${instance.contractClassId}). This should not happen!`,
264
+ );
265
+
266
+ const contractClassPreimage = {
267
+ artifactHash: contractClass.artifactHash,
268
+ privateFunctionsRoot: contractClass.privateFunctionsRoot,
269
+ publicBytecodeCommitment: computePublicBytecodeCommitment(contractClass.packedBytecode),
270
+ };
271
+
272
+ this.trace.traceGetBytecode(
273
+ contractAddress,
274
+ exists,
275
+ contractClass.packedBytecode,
276
+ instance,
277
+ contractClassPreimage,
278
+ );
279
+ return contractClass.packedBytecode;
280
+ } else {
281
+ // If the contract instance is not found, we assume it has not been deployed.
282
+ // It doesnt matter what the values of the contract instance are in this case, as long as we tag it with exists=false.
283
+ // This will hint to the avm circuit to just perform the non-membership check on the address and disregard the bytecode hash
284
+ this.trace.traceGetBytecode(contractAddress, exists); // bytecode, instance, class undefined
285
+ return undefined;
286
+ }
244
287
  }
245
288
 
246
289
  /**
@@ -1,23 +1,36 @@
1
- import { Fr } from '@aztec/circuits.js';
2
-
3
1
  import type { AvmContext } from '../avm_context.js';
4
- import { Field, TypeTag } from '../avm_memory_types.js';
2
+ import { Field, TypeTag, Uint1 } from '../avm_memory_types.js';
3
+ import { InstructionExecutionError } from '../errors.js';
5
4
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
6
5
  import { Addressing } from './addressing_mode.js';
7
6
  import { Instruction } from './instruction.js';
8
7
 
8
+ export enum ContractInstanceMember {
9
+ DEPLOYER,
10
+ CLASS_ID,
11
+ INIT_HASH,
12
+ }
13
+
9
14
  export class GetContractInstance extends Instruction {
10
15
  static readonly type: string = 'GETCONTRACTINSTANCE';
11
16
  static readonly opcode: Opcode = Opcode.GETCONTRACTINSTANCE;
12
17
  // Informs (de)serialization. See Instruction.deserialize.
13
18
  static readonly wireFormat: OperandType[] = [
14
- OperandType.UINT8,
15
- OperandType.UINT8,
16
- OperandType.UINT32,
17
- OperandType.UINT32,
19
+ OperandType.UINT8, // opcode
20
+ OperandType.UINT8, // indirect bits
21
+ OperandType.UINT8, // member enum (immediate)
22
+ OperandType.UINT16, // addressOffset
23
+ OperandType.UINT16, // dstOffset
24
+ OperandType.UINT16, // existsOfsset
18
25
  ];
19
26
 
20
- constructor(private indirect: number, private addressOffset: number, private dstOffset: number) {
27
+ constructor(
28
+ private indirect: number,
29
+ private memberEnum: number,
30
+ private addressOffset: number,
31
+ private dstOffset: number,
32
+ private existsOffset: number,
33
+ ) {
21
34
  super();
22
35
  }
23
36
 
@@ -25,27 +38,38 @@ export class GetContractInstance extends Instruction {
25
38
  const memory = context.machineState.memory.track(this.type);
26
39
  context.machineState.consumeGas(this.gasCost());
27
40
 
28
- const operands = [this.addressOffset, this.dstOffset];
41
+ if (!(this.memberEnum in ContractInstanceMember)) {
42
+ throw new InstructionExecutionError(`Invalid GETCONSTRACTINSTANCE member enum ${this.memberEnum}`);
43
+ }
44
+
45
+ const operands = [this.addressOffset, this.dstOffset, this.existsOffset];
29
46
  const addressing = Addressing.fromWire(this.indirect, operands.length);
30
- const [addressOffset, dstOffset] = addressing.resolve(operands, memory);
47
+ const [addressOffset, dstOffset, existsOffset] = addressing.resolve(operands, memory);
31
48
  memory.checkTag(TypeTag.FIELD, addressOffset);
32
49
 
33
50
  const address = memory.get(addressOffset).toFr();
34
51
  const instance = await context.persistableState.getContractInstance(address);
52
+ const exists = instance !== undefined;
35
53
 
36
- const data = [
37
- new Fr(instance.exists),
38
- instance.salt,
39
- instance.deployer.toField(),
40
- instance.contractClassId,
41
- instance.initializationHash,
42
- // This this okay ?
43
- ...instance.publicKeys.toFields(),
44
- ].map(f => new Field(f));
54
+ let memberValue = new Field(0);
55
+ if (exists) {
56
+ switch (this.memberEnum as ContractInstanceMember) {
57
+ case ContractInstanceMember.DEPLOYER:
58
+ memberValue = new Field(instance.deployer.toField());
59
+ break;
60
+ case ContractInstanceMember.CLASS_ID:
61
+ memberValue = new Field(instance.contractClassId.toField());
62
+ break;
63
+ case ContractInstanceMember.INIT_HASH:
64
+ memberValue = new Field(instance.initializationHash);
65
+ break;
66
+ }
67
+ }
45
68
 
46
- memory.setSlice(dstOffset, data);
69
+ memory.set(existsOffset, new Uint1(exists ? 1 : 0));
70
+ memory.set(dstOffset, memberValue);
47
71
 
48
- memory.assert({ reads: 1, writes: 17, addressing });
72
+ memory.assert({ reads: 1, writes: 2, addressing });
49
73
  context.machineState.incrementPc();
50
74
  }
51
75
  }
@@ -7,9 +7,9 @@ import { Instruction } from './instruction.js';
7
7
 
8
8
  export class Jump extends Instruction {
9
9
  static type: string = 'JUMP';
10
- static readonly opcode: Opcode = Opcode.JUMP_16;
10
+ static readonly opcode: Opcode = Opcode.JUMP_32;
11
11
  // Informs (de)serialization. See Instruction.deserialize.
12
- static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT16];
12
+ static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT32];
13
13
 
14
14
  constructor(private jumpOffset: number) {
15
15
  super();
@@ -26,13 +26,13 @@ export class Jump extends Instruction {
26
26
 
27
27
  export class JumpI extends Instruction {
28
28
  static type: string = 'JUMPI';
29
- static readonly opcode: Opcode = Opcode.JUMPI_16;
29
+ static readonly opcode: Opcode = Opcode.JUMPI_32;
30
30
 
31
31
  // Instruction wire format with opcode.
32
32
  static readonly wireFormat: OperandType[] = [
33
33
  OperandType.UINT8,
34
34
  OperandType.UINT8,
35
- OperandType.UINT16,
35
+ OperandType.UINT32,
36
36
  OperandType.UINT16,
37
37
  ];
38
38
 
@@ -63,7 +63,7 @@ export class InternalCall extends Instruction {
63
63
  static readonly type: string = 'INTERNALCALL';
64
64
  static readonly opcode: Opcode = Opcode.INTERNALCALL;
65
65
  // Informs (de)serialization. See Instruction.deserialize.
66
- static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT16];
66
+ static readonly wireFormat: OperandType[] = [OperandType.UINT8, OperandType.UINT32];
67
67
 
68
68
  constructor(private loc: number) {
69
69
  super();
@@ -5,9 +5,9 @@ import { Opcode, OperandType } from '../serialization/instruction_serialization.
5
5
  import { Addressing } from './addressing_mode.js';
6
6
  import { Instruction } from './instruction.js';
7
7
 
8
- export class ToRadixLE extends Instruction {
8
+ export class ToRadixBE extends Instruction {
9
9
  static type: string = 'TORADIXLE';
10
- static readonly opcode: Opcode = Opcode.TORADIXLE;
10
+ static readonly opcode: Opcode = Opcode.TORADIXBE;
11
11
 
12
12
  // Informs (de)serialization. See Instruction.deserialize.
13
13
  static readonly wireFormat: OperandType[] = [
@@ -44,15 +44,18 @@ export class ToRadixLE extends Instruction {
44
44
 
45
45
  let value: bigint = memory.get(srcOffset).toBigInt();
46
46
  const radix: bigint = memory.get(radixOffset).toBigInt();
47
+ if (this.numLimbs < 1) {
48
+ throw new InstructionExecutionError(`ToRadixBE instruction's numLimbs should be > 0 (was ${this.numLimbs})`);
49
+ }
47
50
  if (radix > 256) {
48
- throw new InstructionExecutionError(`ToRadixLE instruction's radix should be <= 256 (was ${radix})`);
51
+ throw new InstructionExecutionError(`ToRadixBE instruction's radix should be <= 256 (was ${radix})`);
49
52
  }
50
53
  const radixBN: bigint = BigInt(radix);
51
- const limbArray = [];
54
+ const limbArray = new Array(this.numLimbs);
52
55
 
53
- for (let i = 0; i < this.numLimbs; i++) {
56
+ for (let i = this.numLimbs - 1; i >= 0; i--) {
54
57
  const limb = value % radixBN;
55
- limbArray.push(limb);
58
+ limbArray[i] = limb;
56
59
  value /= radixBN;
57
60
  }
58
61
 
@@ -1,5 +1,6 @@
1
1
  import type { AvmContext } from '../avm_context.js';
2
2
  import { Field, Uint32, Uint64 } from '../avm_memory_types.js';
3
+ import { InstructionExecutionError } from '../errors.js';
3
4
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
4
5
  import { Addressing } from './addressing_mode.js';
5
6
  import { Instruction } from './instruction.js';
@@ -63,7 +64,7 @@ export class GetEnvVar extends Instruction {
63
64
  OperandType.UINT16, // dstOffset
64
65
  ];
65
66
 
66
- constructor(private indirect: number, private varEnum: EnvironmentVariable, private dstOffset: number) {
67
+ constructor(private indirect: number, private varEnum: number, private dstOffset: number) {
67
68
  super();
68
69
  }
69
70
 
@@ -71,11 +72,15 @@ export class GetEnvVar extends Instruction {
71
72
  const memory = context.machineState.memory.track(this.type);
72
73
  context.machineState.consumeGas(this.gasCost());
73
74
 
75
+ if (!(this.varEnum in EnvironmentVariable)) {
76
+ throw new InstructionExecutionError(`Invalid GETENVVAR var enum ${this.varEnum}`);
77
+ }
78
+
74
79
  const operands = [this.dstOffset];
75
80
  const addressing = Addressing.fromWire(this.indirect, operands.length);
76
81
  const [dstOffset] = addressing.resolve(operands, memory);
77
82
 
78
- memory.set(dstOffset, getValue(this.varEnum, context));
83
+ memory.set(dstOffset, getValue(this.varEnum as EnvironmentVariable, context));
79
84
 
80
85
  memory.assert({ writes: 1, addressing });
81
86
  context.machineState.incrementPc();