@aztec/simulator 0.38.0 → 0.39.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 (131) hide show
  1. package/dest/acvm/oracle/oracle.d.ts +1 -1
  2. package/dest/acvm/oracle/oracle.d.ts.map +1 -1
  3. package/dest/acvm/oracle/oracle.js +8 -23
  4. package/dest/acvm/oracle/typed_oracle.d.ts +2 -3
  5. package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
  6. package/dest/acvm/oracle/typed_oracle.js +4 -7
  7. package/dest/avm/avm_execution_environment.d.ts +4 -3
  8. package/dest/avm/avm_execution_environment.d.ts.map +1 -1
  9. package/dest/avm/avm_execution_environment.js +17 -11
  10. package/dest/avm/avm_gas.d.ts.map +1 -1
  11. package/dest/avm/avm_gas.js +3 -1
  12. package/dest/avm/avm_machine_state.d.ts +5 -8
  13. package/dest/avm/avm_machine_state.d.ts.map +1 -1
  14. package/dest/avm/avm_machine_state.js +10 -22
  15. package/dest/avm/avm_message_call_result.d.ts +5 -8
  16. package/dest/avm/avm_message_call_result.d.ts.map +1 -1
  17. package/dest/avm/avm_message_call_result.js +1 -4
  18. package/dest/avm/avm_simulator.d.ts.map +1 -1
  19. package/dest/avm/avm_simulator.js +17 -13
  20. package/dest/avm/errors.d.ts +43 -2
  21. package/dest/avm/errors.d.ts.map +1 -1
  22. package/dest/avm/errors.js +86 -4
  23. package/dest/avm/journal/journal.d.ts.map +1 -1
  24. package/dest/avm/journal/journal.js +4 -3
  25. package/dest/avm/opcodes/conversion.d.ts +16 -0
  26. package/dest/avm/opcodes/conversion.d.ts.map +1 -0
  27. package/dest/avm/opcodes/conversion.js +48 -0
  28. package/dest/avm/opcodes/environment_getters.d.ts +12 -13
  29. package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
  30. package/dest/avm/opcodes/environment_getters.js +13 -49
  31. package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
  32. package/dest/avm/opcodes/external_calls.js +11 -1
  33. package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
  34. package/dest/avm/serialization/bytecode_serialization.js +4 -1
  35. package/dest/avm/serialization/instruction_serialization.d.ts +2 -1
  36. package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
  37. package/dest/avm/serialization/instruction_serialization.js +3 -1
  38. package/dest/client/client_execution_context.d.ts +28 -1
  39. package/dest/client/client_execution_context.d.ts.map +1 -1
  40. package/dest/client/client_execution_context.js +50 -15
  41. package/dest/client/db_oracle.d.ts +1 -8
  42. package/dest/client/db_oracle.d.ts.map +1 -1
  43. package/dest/client/execution_result.d.ts +4 -1
  44. package/dest/client/execution_result.d.ts.map +1 -1
  45. package/dest/client/execution_result.js +16 -3
  46. package/dest/client/private_execution.d.ts.map +1 -1
  47. package/dest/client/private_execution.js +3 -1
  48. package/dest/client/simulator.d.ts +1 -31
  49. package/dest/client/simulator.d.ts.map +1 -1
  50. package/dest/client/simulator.js +3 -42
  51. package/dest/client/view_data_oracle.d.ts +0 -7
  52. package/dest/client/view_data_oracle.d.ts.map +1 -1
  53. package/dest/client/view_data_oracle.js +1 -10
  54. package/dest/common/errors.d.ts +5 -0
  55. package/dest/common/errors.d.ts.map +1 -1
  56. package/dest/common/errors.js +6 -1
  57. package/dest/index.d.ts +1 -0
  58. package/dest/index.d.ts.map +1 -1
  59. package/dest/index.js +2 -1
  60. package/dest/public/abstract_phase_manager.d.ts +8 -4
  61. package/dest/public/abstract_phase_manager.d.ts.map +1 -1
  62. package/dest/public/abstract_phase_manager.js +38 -14
  63. package/dest/public/app_logic_phase_manager.d.ts +1 -0
  64. package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
  65. package/dest/public/app_logic_phase_manager.js +3 -3
  66. package/dest/public/executor.d.ts.map +1 -1
  67. package/dest/public/executor.js +1 -4
  68. package/dest/public/hints_builder.d.ts +3 -3
  69. package/dest/public/hints_builder.d.ts.map +1 -1
  70. package/dest/public/hints_builder.js +3 -3
  71. package/dest/public/public_processor.d.ts.map +1 -1
  72. package/dest/public/public_processor.js +5 -3
  73. package/dest/public/setup_phase_manager.d.ts +1 -0
  74. package/dest/public/setup_phase_manager.d.ts.map +1 -1
  75. package/dest/public/setup_phase_manager.js +3 -2
  76. package/dest/public/tail_phase_manager.d.ts +1 -0
  77. package/dest/public/tail_phase_manager.d.ts.map +1 -1
  78. package/dest/public/tail_phase_manager.js +2 -1
  79. package/dest/public/teardown_phase_manager.d.ts +1 -0
  80. package/dest/public/teardown_phase_manager.d.ts.map +1 -1
  81. package/dest/public/teardown_phase_manager.js +3 -2
  82. package/dest/public/transitional_adaptors.d.ts.map +1 -1
  83. package/dest/public/transitional_adaptors.js +1 -1
  84. package/dest/rollup/index.d.ts +2 -0
  85. package/dest/rollup/index.d.ts.map +1 -0
  86. package/dest/rollup/index.js +2 -0
  87. package/dest/rollup/rollup.d.ts +77 -0
  88. package/dest/rollup/rollup.d.ts.map +1 -0
  89. package/dest/rollup/rollup.js +78 -0
  90. package/dest/stats/index.d.ts +2 -0
  91. package/dest/stats/index.d.ts.map +1 -0
  92. package/dest/stats/index.js +2 -0
  93. package/dest/stats/stats.d.ts +4 -0
  94. package/dest/stats/stats.d.ts.map +1 -0
  95. package/dest/stats/stats.js +11 -0
  96. package/package.json +8 -8
  97. package/src/acvm/oracle/oracle.ts +23 -27
  98. package/src/acvm/oracle/typed_oracle.ts +12 -9
  99. package/src/avm/avm_execution_environment.ts +34 -42
  100. package/src/avm/avm_gas.ts +2 -0
  101. package/src/avm/avm_machine_state.ts +14 -25
  102. package/src/avm/avm_message_call_result.ts +3 -14
  103. package/src/avm/avm_simulator.ts +22 -12
  104. package/src/avm/errors.ts +94 -4
  105. package/src/avm/journal/journal.ts +3 -2
  106. package/src/avm/opcodes/conversion.ts +59 -0
  107. package/src/avm/opcodes/environment_getters.ts +13 -66
  108. package/src/avm/opcodes/external_calls.ts +11 -0
  109. package/src/avm/serialization/bytecode_serialization.ts +3 -0
  110. package/src/avm/serialization/instruction_serialization.ts +2 -0
  111. package/src/client/client_execution_context.ts +87 -15
  112. package/src/client/db_oracle.ts +1 -9
  113. package/src/client/execution_result.ts +21 -2
  114. package/src/client/private_execution.ts +2 -0
  115. package/src/client/simulator.ts +2 -80
  116. package/src/client/view_data_oracle.ts +0 -10
  117. package/src/common/errors.ts +5 -0
  118. package/src/index.ts +1 -0
  119. package/src/public/abstract_phase_manager.ts +46 -18
  120. package/src/public/app_logic_phase_manager.ts +2 -1
  121. package/src/public/executor.ts +0 -4
  122. package/src/public/hints_builder.ts +5 -5
  123. package/src/public/public_processor.ts +8 -2
  124. package/src/public/setup_phase_manager.ts +16 -8
  125. package/src/public/tail_phase_manager.ts +6 -1
  126. package/src/public/teardown_phase_manager.ts +16 -8
  127. package/src/public/transitional_adaptors.ts +1 -0
  128. package/src/rollup/index.ts +1 -0
  129. package/src/rollup/rollup.ts +160 -0
  130. package/src/stats/index.ts +1 -0
  131. package/src/stats/stats.ts +20 -0
@@ -2,7 +2,6 @@ import { type Fr } from '@aztec/circuits.js';
2
2
 
3
3
  import { type Gas, GasDimensions } from './avm_gas.js';
4
4
  import { TaggedMemory } from './avm_memory_types.js';
5
- import { AvmContractCallResults } from './avm_message_call_result.js';
6
5
  import { OutOfGasError } from './errors.js';
7
6
 
8
7
  /**
@@ -36,7 +35,7 @@ export class AvmMachineState {
36
35
  * Signals that execution should end.
37
36
  * AvmContext execution continues executing instructions until the machine state signals "halted"
38
37
  */
39
- public halted: boolean = false;
38
+ private halted: boolean = false;
40
39
  /** Signals that execution has reverted normally (this does not cover exceptional halts) */
41
40
  private reverted: boolean = false;
42
41
  /** Output data must NOT be modified once it is set */
@@ -118,34 +117,24 @@ export class AvmMachineState {
118
117
  this.output = output;
119
118
  }
120
119
 
120
+ public getHalted(): boolean {
121
+ return this.halted;
122
+ }
123
+
124
+ public getReverted(): boolean {
125
+ return this.reverted;
126
+ }
127
+
128
+ public getOutput(): Fr[] {
129
+ return this.output;
130
+ }
131
+
121
132
  /**
122
133
  * Flag an exceptional halt. Clears gas left and sets the reverted flag. No output data.
123
134
  */
124
- protected exceptionalHalt() {
135
+ private exceptionalHalt() {
125
136
  GasDimensions.forEach(dimension => (this[`${dimension}Left`] = 0));
126
137
  this.reverted = true;
127
138
  this.halted = true;
128
139
  }
129
-
130
- /**
131
- * Get a summary of execution results for a halted machine state
132
- * @returns summary of execution results
133
- */
134
- public getResults(): AvmContractCallResults {
135
- if (!this.halted) {
136
- throw new Error('Execution results are not ready! Execution is ongoing.');
137
- }
138
- let revertReason = undefined;
139
- if (this.reverted && this.output.length > 0) {
140
- try {
141
- // Try to interpret the output as a text string.
142
- revertReason = new Error(
143
- 'Reverted with output: ' + String.fromCharCode(...this.output.slice(1).map(fr => fr.toNumber())),
144
- );
145
- } catch (e) {
146
- revertReason = new Error('Reverted with non-string output');
147
- }
148
- }
149
- return new AvmContractCallResults(this.reverted, this.output, revertReason);
150
- }
151
140
  }
@@ -1,24 +1,13 @@
1
1
  import { type Fr } from '@aztec/foundation/fields';
2
2
 
3
+ import { type AvmRevertReason } from './errors.js';
4
+
3
5
  /**
4
6
  * Results of an contract call's execution in the AVM.
5
7
  */
6
8
  export class AvmContractCallResults {
7
- public readonly reverted: boolean;
8
- public readonly output: Fr[];
9
-
10
- /** For exceptional halts */
11
- public readonly revertReason: Error | undefined;
12
-
13
- constructor(reverted: boolean, output: Fr[], revertReason?: Error) {
14
- this.reverted = reverted;
15
- this.output = output;
16
- this.revertReason = revertReason;
17
- }
9
+ constructor(public reverted: boolean, public output: Fr[], public revertReason?: AvmRevertReason) {}
18
10
 
19
- /**
20
- * Generate a string representation of call results.
21
- */
22
11
  toString(): string {
23
12
  let resultsStr = `reverted: ${this.reverted}, output: ${this.output}`;
24
13
  if (this.revertReason) {
@@ -5,7 +5,13 @@ import { strict as assert } from 'assert';
5
5
  import { isAvmBytecode } from '../public/transitional_adaptors.js';
6
6
  import type { AvmContext } from './avm_context.js';
7
7
  import { AvmContractCallResults } from './avm_message_call_result.js';
8
- import { AvmExecutionError, InvalidProgramCounterError, NoBytecodeForContractError } from './errors.js';
8
+ import {
9
+ AvmExecutionError,
10
+ InvalidProgramCounterError,
11
+ NoBytecodeForContractError,
12
+ revertReasonFromExceptionalHalt,
13
+ revertReasonFromExplicitRevert,
14
+ } from './errors.js';
9
15
  import type { Instruction } from './opcodes/index.js';
10
16
  import { decodeFromBytecode } from './serialization/bytecode_serialization.js';
11
17
 
@@ -56,7 +62,7 @@ export class AvmSimulator {
56
62
  try {
57
63
  // Execute instruction pointed to by the current program counter
58
64
  // continuing until the machine state signifies a halt
59
- while (!machineState.halted) {
65
+ while (!machineState.getHalted()) {
60
66
  const instruction = instructions[machineState.pc];
61
67
  assert(
62
68
  !!instruction,
@@ -76,21 +82,25 @@ export class AvmSimulator {
76
82
  }
77
83
  }
78
84
 
79
- // Return results for processing by calling context
80
- const results = machineState.getResults();
85
+ const output = machineState.getOutput();
86
+ const reverted = machineState.getReverted();
87
+ const revertReason = reverted ? revertReasonFromExplicitRevert(output, this.context) : undefined;
88
+ const results = new AvmContractCallResults(reverted, output, revertReason);
81
89
  this.log.debug(`Context execution results: ${results.toString()}`);
90
+ // Return results for processing by calling context
82
91
  return results;
83
- } catch (e) {
84
- this.log.verbose('Exceptional halt');
85
- if (!(e instanceof AvmExecutionError)) {
86
- this.log.verbose(`Unknown error thrown by avm: ${e}`);
87
- throw e;
92
+ } catch (err: any) {
93
+ this.log.verbose('Exceptional halt (revert by something other than REVERT opcode)');
94
+ if (!(err instanceof AvmExecutionError)) {
95
+ this.log.verbose(`Unknown error thrown by AVM: ${err}`);
96
+ throw err;
88
97
  }
89
98
 
90
- // Return results for processing by calling context
91
- // Note: "exceptional halts" cannot return data
92
- const results = new AvmContractCallResults(/*reverted=*/ true, /*output=*/ [], /*revertReason=*/ e);
99
+ const revertReason = revertReasonFromExceptionalHalt(err, this.context);
100
+ // Note: "exceptional halts" cannot return data, hence []
101
+ const results = new AvmContractCallResults(/*reverted=*/ true, /*output=*/ [], revertReason);
93
102
  this.log.debug(`Context execution results: ${results.toString()}`);
103
+ // Return results for processing by calling context
94
104
  return results;
95
105
  }
96
106
  }
package/src/avm/errors.ts CHANGED
@@ -1,12 +1,16 @@
1
- import { type AztecAddress } from '@aztec/circuits.js';
1
+ import { type FailingFunction, type NoirCallStack } from '@aztec/circuit-types';
2
+ import { type AztecAddress, type Fr } from '@aztec/circuits.js';
3
+
4
+ import { ExecutionError } from '../common/errors.js';
5
+ import { type AvmContext } from './avm_context.js';
2
6
 
3
7
  /**
4
8
  * Avm-specific errors should derive from this
5
9
  */
6
10
  export abstract class AvmExecutionError extends Error {
7
- constructor(message: string, ...rest: any[]) {
8
- super(message, ...rest);
9
- this.name = 'AvmInterpreterError';
11
+ constructor(message: string) {
12
+ super(message);
13
+ this.name = 'AvmExecutionError';
10
14
  }
11
15
  }
12
16
 
@@ -63,3 +67,89 @@ export class OutOfGasError extends AvmExecutionError {
63
67
  this.name = 'OutOfGasError';
64
68
  }
65
69
  }
70
+
71
+ /**
72
+ * Error thrown to propagate a nested call's revert.
73
+ * @param message - the error's message
74
+ * @param nestedError - the revert reason of the nested call
75
+ */
76
+ export class RethrownError extends AvmExecutionError {
77
+ constructor(message: string, public nestedError: AvmRevertReason) {
78
+ super(message);
79
+ this.name = 'RethrownError';
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Meaningfully named alias for ExecutionError when used in the context of the AVM.
85
+ * Maintains a recursive structure reflecting the AVM's external callstack/errorstack, where
86
+ * options.cause is the error that caused this error (if this is not the root-cause itself).
87
+ */
88
+ export class AvmRevertReason extends ExecutionError {
89
+ constructor(message: string, failingFunction: FailingFunction, noirCallStack: NoirCallStack, options?: ErrorOptions) {
90
+ super(message, failingFunction, noirCallStack, options);
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Helper to create a "revert reason" error optionally with a nested error cause.
96
+ *
97
+ * @param message - the error message
98
+ * @param context - the context of the AVM execution used to extract the failingFunction and noirCallStack
99
+ * @param nestedError - the error that caused this one (if this is not the root-cause itself)
100
+ */
101
+ function createRevertReason(message: string, context: AvmContext, nestedError?: AvmRevertReason): AvmRevertReason {
102
+ return new AvmRevertReason(
103
+ message,
104
+ /*failingFunction=*/ {
105
+ contractAddress: context.environment.address,
106
+ functionSelector: context.environment.temporaryFunctionSelector,
107
+ },
108
+ /*noirCallStack=*/ [...context.machineState.internalCallStack, context.machineState.pc].map(pc => `0.${pc}`),
109
+ /*options=*/ { cause: nestedError },
110
+ );
111
+ }
112
+
113
+ /**
114
+ * Create a "revert reason" error for an exceptional halt,
115
+ * creating the recursive structure if the halt was a RethrownError.
116
+ *
117
+ * @param haltingError - the lower-level error causing the exceptional halt
118
+ * @param context - the context of the AVM execution used to extract the failingFunction and noirCallStack
119
+ */
120
+ export function revertReasonFromExceptionalHalt(haltingError: AvmExecutionError, context: AvmContext): AvmRevertReason {
121
+ // A RethrownError has a nested/child AvmRevertReason
122
+ const nestedError = haltingError instanceof RethrownError ? haltingError.nestedError : undefined;
123
+ return createRevertReason(haltingError.message, context, nestedError);
124
+ }
125
+
126
+ /**
127
+ * Create a "revert reason" error for an explicit revert (a root cause).
128
+ *
129
+ * @param revertData - output data of the explicit REVERT instruction
130
+ * @param context - the context of the AVM execution used to extract the failingFunction and noirCallStack
131
+ */
132
+ export function revertReasonFromExplicitRevert(revertData: Fr[], context: AvmContext): AvmRevertReason {
133
+ const revertMessage = decodeRevertDataAsMessage(revertData);
134
+ return createRevertReason(revertMessage, context);
135
+ }
136
+
137
+ /**
138
+ * Interpret revert data as a message string.
139
+ *
140
+ * @param revertData - output data of an explicit REVERT instruction
141
+ */
142
+ export function decodeRevertDataAsMessage(revertData: Fr[]): string {
143
+ if (revertData.length === 0) {
144
+ return 'Assertion failed.';
145
+ } else {
146
+ try {
147
+ // We remove the first element which is the 'error selector'.
148
+ const revertOutput = revertData.slice(1);
149
+ // Try to interpret the output as a text string.
150
+ return 'Assertion failed: ' + String.fromCharCode(...revertOutput.map(fr => fr.toNumber()));
151
+ } catch (e) {
152
+ return 'Assertion failed: <cannot interpret as string>';
153
+ }
154
+ }
155
+ }
@@ -119,7 +119,8 @@ export class AvmPersistableStateManager {
119
119
  contractStorageUpdateRequests: [],
120
120
  unencryptedLogsHashes: [],
121
121
  unencryptedLogs: [],
122
- unencryptedLogPreimagesLength: new Fr(0),
122
+ // The length starts at 4 because it will always include the size.
123
+ unencryptedLogPreimagesLength: new Fr(4),
123
124
  allUnencryptedLogs: [],
124
125
  nestedExecutions: [],
125
126
  };
@@ -285,7 +286,7 @@ export class AvmPersistableStateManager {
285
286
  public writeL1Message(recipient: EthAddress | Fr, content: Fr) {
286
287
  this.log.debug(`L1Messages(${recipient}) += ${content}.`);
287
288
  const recipientAddress = recipient instanceof EthAddress ? recipient : EthAddress.fromField(recipient);
288
- const message = new L2ToL1Message(recipientAddress, content);
289
+ const message = new L2ToL1Message(recipientAddress, content, 0);
289
290
  this.newL1Messages.push(message);
290
291
 
291
292
  // TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
@@ -0,0 +1,59 @@
1
+ import { strict as assert } from 'assert';
2
+
3
+ import { type AvmContext } from '../avm_context.js';
4
+ import { TypeTag, Uint8 } from '../avm_memory_types.js';
5
+ import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
6
+ import { Addressing } from './addressing_mode.js';
7
+ import { Instruction } from './instruction.js';
8
+
9
+ export class ToRadixLE extends Instruction {
10
+ static type: string = 'TORADIXLE';
11
+ static readonly opcode: Opcode = Opcode.TORADIXLE;
12
+
13
+ // Informs (de)serialization. See Instruction.deserialize.
14
+ static readonly wireFormat: OperandType[] = [
15
+ OperandType.UINT8, // Opcode
16
+ OperandType.UINT8, // Indirect
17
+ OperandType.UINT32, // src memory address
18
+ OperandType.UINT32, // dst memory address
19
+ OperandType.UINT32, // radix (immediate)
20
+ OperandType.UINT32, // number of limbs (Immediate)
21
+ ];
22
+
23
+ constructor(
24
+ private indirect: number,
25
+ private srcOffset: number,
26
+ private dstOffset: number,
27
+ private radix: number,
28
+ private numLimbs: number,
29
+ ) {
30
+ assert(radix <= 256, 'Radix cannot be greater than 256');
31
+ super();
32
+ }
33
+
34
+ public async execute(context: AvmContext): Promise<void> {
35
+ const memory = context.machineState.memory.track(this.type);
36
+ const [srcOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.srcOffset, this.dstOffset], memory);
37
+ const memoryOperations = { reads: 1, writes: this.numLimbs, indirect: this.indirect };
38
+ context.machineState.consumeGas(this.gasCost(memoryOperations));
39
+
40
+ // The radix gadget only takes in a Field
41
+ memory.checkTag(TypeTag.FIELD, srcOffset);
42
+
43
+ let value: bigint = memory.get(srcOffset).toBigInt();
44
+ const radixBN: bigint = BigInt(this.radix);
45
+ const limbArray = [];
46
+
47
+ for (let i = 0; i < this.numLimbs; i++) {
48
+ const limb = value % radixBN;
49
+ limbArray.push(limb);
50
+ value /= radixBN;
51
+ }
52
+
53
+ const res = [...limbArray].map(byte => new Uint8(byte));
54
+ memory.setSlice(dstOffset, res);
55
+
56
+ memory.assert(memoryOperations);
57
+ context.machineState.incrementPc();
58
+ }
59
+ }
@@ -1,17 +1,15 @@
1
- import { type Fr } from '@aztec/circuits.js';
2
-
3
1
  import type { AvmContext } from '../avm_context.js';
4
2
  import type { AvmExecutionEnvironment } from '../avm_execution_environment.js';
5
- import { Field, type MemoryValue } from '../avm_memory_types.js';
3
+ import { Field, type MemoryValue, Uint64 } from '../avm_memory_types.js';
6
4
  import { Opcode } from '../serialization/instruction_serialization.js';
7
5
  import { GetterInstruction } from './instruction_impl.js';
8
6
 
9
7
  abstract class EnvironmentGetterInstruction extends GetterInstruction {
10
8
  protected getValue(context: AvmContext): MemoryValue {
11
- return new Field(this.getEnvironmentValue(context.environment));
9
+ return this.getEnvironmentValue(context.environment);
12
10
  }
13
11
 
14
- protected abstract getEnvironmentValue(env: AvmExecutionEnvironment): Fr | number | bigint;
12
+ protected abstract getEnvironmentValue(env: AvmExecutionEnvironment): MemoryValue;
15
13
  }
16
14
 
17
15
  export class Address extends EnvironmentGetterInstruction {
@@ -19,7 +17,7 @@ export class Address extends EnvironmentGetterInstruction {
19
17
  static readonly opcode: Opcode = Opcode.ADDRESS;
20
18
 
21
19
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
22
- return env.address;
20
+ return new Field(env.address.toField());
23
21
  }
24
22
  }
25
23
 
@@ -28,7 +26,7 @@ export class StorageAddress extends EnvironmentGetterInstruction {
28
26
  static readonly opcode: Opcode = Opcode.STORAGEADDRESS;
29
27
 
30
28
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
31
- return env.storageAddress;
29
+ return new Field(env.storageAddress.toField());
32
30
  }
33
31
  }
34
32
 
@@ -37,7 +35,7 @@ export class Sender extends EnvironmentGetterInstruction {
37
35
  static readonly opcode: Opcode = Opcode.SENDER;
38
36
 
39
37
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
40
- return env.sender;
38
+ return new Field(env.sender.toField());
41
39
  }
42
40
  }
43
41
 
@@ -46,7 +44,7 @@ export class FeePerL2Gas extends EnvironmentGetterInstruction {
46
44
  static readonly opcode: Opcode = Opcode.FEEPERL2GAS;
47
45
 
48
46
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
49
- return env.feePerL2Gas;
47
+ return new Field(env.feePerL2Gas);
50
48
  }
51
49
  }
52
50
 
@@ -55,7 +53,7 @@ export class FeePerDAGas extends EnvironmentGetterInstruction {
55
53
  static readonly opcode: Opcode = Opcode.FEEPERDAGAS;
56
54
 
57
55
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
58
- return env.feePerDaGas;
56
+ return new Field(env.feePerDaGas);
59
57
  }
60
58
  }
61
59
 
@@ -64,7 +62,7 @@ export class TransactionFee extends EnvironmentGetterInstruction {
64
62
  static readonly opcode: Opcode = Opcode.TRANSACTIONFEE;
65
63
 
66
64
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
67
- return env.transactionFee;
65
+ return new Field(env.transactionFee);
68
66
  }
69
67
  }
70
68
 
@@ -73,7 +71,7 @@ export class ChainId extends EnvironmentGetterInstruction {
73
71
  static readonly opcode: Opcode = Opcode.CHAINID;
74
72
 
75
73
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
76
- return env.globals.chainId;
74
+ return new Field(env.globals.chainId);
77
75
  }
78
76
  }
79
77
 
@@ -82,7 +80,7 @@ export class Version extends EnvironmentGetterInstruction {
82
80
  static readonly opcode: Opcode = Opcode.VERSION;
83
81
 
84
82
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
85
- return env.globals.version;
83
+ return new Field(env.globals.version);
86
84
  }
87
85
  }
88
86
 
@@ -91,7 +89,7 @@ export class BlockNumber extends EnvironmentGetterInstruction {
91
89
  static readonly opcode: Opcode = Opcode.BLOCKNUMBER;
92
90
 
93
91
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
94
- return env.globals.blockNumber;
92
+ return new Field(env.globals.blockNumber);
95
93
  }
96
94
  }
97
95
 
@@ -100,57 +98,6 @@ export class Timestamp extends EnvironmentGetterInstruction {
100
98
  static readonly opcode: Opcode = Opcode.TIMESTAMP;
101
99
 
102
100
  protected getEnvironmentValue(env: AvmExecutionEnvironment) {
103
- return env.globals.timestamp;
101
+ return new Uint64(env.globals.timestamp.toBigInt());
104
102
  }
105
103
  }
106
-
107
- // export class Coinbase extends EnvironmentGetterInstruction {
108
- // static type: string = 'COINBASE';
109
- // static numberOfOperands = 1;
110
-
111
- // constructor(private destOffset: number) {
112
- // super();
113
- // }
114
-
115
- // async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise<void> {
116
- // const {coinbase} = machineState.executionEnvironment.globals;
117
-
118
- // machineState.memory.set(this.destOffset, coinbase);
119
-
120
- // this.incrementPc(machineState);
121
- // }
122
- // }
123
-
124
- // export class BlockL2GasLimit extends EnvironmentGetterInstruction {
125
- // static type: string = 'BLOCKL2GASLIMIT';
126
- // static numberOfOperands = 1;
127
-
128
- // constructor(private destOffset: number) {
129
- // super();
130
- // }
131
-
132
- // async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise<void> {
133
- // const {blockL2GasLimit} = machineState.executionEnvironment.globals;
134
-
135
- // machineState.memory.set(this.destOffset, blockL2GasLimit);
136
-
137
- // this.incrementPc(machineState);
138
- // }
139
- // }
140
-
141
- // export class BlockDAGasLimit extends EnvironmentGetterInstruction {
142
- // static type: string = 'BLOCKDAGASLIMIT';
143
- // static numberOfOperands = 1;
144
-
145
- // constructor(private destOffset: number) {
146
- // super();
147
- // }
148
-
149
- // async execute(machineState: AvmMachineState, _journal: AvmJournal): Promise<void> {
150
- // const {blockDAGasLimit} = machineState.executionEnvironment.globals;
151
-
152
- // machineState.memory.set(this.destOffset, blockDAGasLimit);
153
-
154
- // this.incrementPc(machineState);
155
- // }
156
- // }
@@ -7,6 +7,7 @@ import { gasLeftToGas, sumGas } from '../avm_gas.js';
7
7
  import { Field, Uint8 } from '../avm_memory_types.js';
8
8
  import { type AvmContractCallResults } from '../avm_message_call_result.js';
9
9
  import { AvmSimulator } from '../avm_simulator.js';
10
+ import { RethrownError } from '../errors.js';
10
11
  import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
11
12
  import { Addressing } from './addressing_mode.js';
12
13
  import { Instruction } from './instruction.js';
@@ -99,6 +100,16 @@ abstract class ExternalCall extends Instruction {
99
100
 
100
101
  const success = !nestedCallResults.reverted;
101
102
 
103
+ // TRANSITIONAL: We rethrow here so that the MESSAGE gets propagated.
104
+ // This means that for now, the caller cannot recover from errors.
105
+ if (!success) {
106
+ if (!nestedCallResults.revertReason) {
107
+ throw new Error('A reverted nested call should be assigned a revert reason in the AVM execution loop');
108
+ }
109
+ // The nested call's revertReason will be used to track the stack of error causes down to the root.
110
+ throw new RethrownError(nestedCallResults.revertReason.message, nestedCallResults.revertReason);
111
+ }
112
+
102
113
  // We only take as much data as was specified in the return size and pad with zeroes if the return data is smaller
103
114
  // than the specified size in order to prevent that memory to be left with garbage
104
115
  const returnData = nestedCallResults.output.slice(0, this.retSize);
@@ -1,4 +1,5 @@
1
1
  import { DAGasLeft, L2GasLeft } from '../opcodes/context_getters.js';
2
+ import { ToRadixLE } from '../opcodes/conversion.js';
2
3
  import { Keccak, Pedersen, Poseidon2, Sha256 } from '../opcodes/hashing.js';
3
4
  import type { Instruction } from '../opcodes/index.js';
4
5
  import {
@@ -136,6 +137,8 @@ const INSTRUCTION_SET = () =>
136
137
  [Poseidon2.opcode, Poseidon2],
137
138
  [Sha256.opcode, Sha256],
138
139
  [Pedersen.opcode, Pedersen],
140
+ // Conversions
141
+ [ToRadixLE.opcode, ToRadixLE],
139
142
  ]);
140
143
 
141
144
  interface Serializable {
@@ -74,6 +74,8 @@ export enum Opcode {
74
74
  POSEIDON2,
75
75
  SHA256, // temp - may be removed, but alot of contracts rely on it
76
76
  PEDERSEN, // temp - may be removed, but alot of contracts rely on it
77
+ // Conversion
78
+ TORADIXLE,
77
79
  }
78
80
 
79
81
  // Possible types for an instruction's operand in its wire format. (Keep in sync with CPP code.