@aztec/simulator 0.87.7 → 1.0.0-nightly.20250605
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.
- package/dest/public/avm/avm_gas.d.ts +4 -5
- package/dest/public/avm/avm_gas.d.ts.map +1 -1
- package/dest/public/avm/avm_gas.js +29 -19
- package/dest/public/avm/fixtures/utils.js +1 -1
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/public/avm/opcodes/accrued_substate.js +8 -7
- package/dest/public/avm/opcodes/addressing_mode.d.ts +2 -0
- package/dest/public/avm/opcodes/addressing_mode.d.ts.map +1 -1
- package/dest/public/avm/opcodes/addressing_mode.js +6 -0
- package/dest/public/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/public/avm/opcodes/arithmetic.js +1 -1
- package/dest/public/avm/opcodes/bitwise.d.ts +5 -1
- package/dest/public/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/public/avm/opcodes/bitwise.js +17 -2
- package/dest/public/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/public/avm/opcodes/comparators.js +1 -1
- package/dest/public/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/public/avm/opcodes/contract.js +1 -1
- package/dest/public/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/public/avm/opcodes/control_flow.js +4 -4
- package/dest/public/avm/opcodes/conversion.d.ts +1 -0
- package/dest/public/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/public/avm/opcodes/conversion.js +263 -2
- package/dest/public/avm/opcodes/ec_add.d.ts.map +1 -1
- package/dest/public/avm/opcodes/ec_add.js +1 -1
- package/dest/public/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/public/avm/opcodes/environment_getters.js +1 -1
- package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/public/avm/opcodes/external_calls.js +6 -8
- package/dest/public/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/public/avm/opcodes/hashing.js +3 -3
- package/dest/public/avm/opcodes/instruction.d.ts +9 -3
- package/dest/public/avm/opcodes/instruction.d.ts.map +1 -1
- package/dest/public/avm/opcodes/instruction.js +12 -7
- package/dest/public/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/public/avm/opcodes/memory.js +8 -6
- package/dest/public/avm/opcodes/misc.js +1 -3
- package/dest/public/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/public/avm/opcodes/storage.js +5 -3
- package/dest/public/fixtures/index.d.ts +1 -0
- package/dest/public/fixtures/index.d.ts.map +1 -1
- package/dest/public/fixtures/index.js +1 -0
- package/dest/public/fixtures/minimal_public_tx.d.ts +9 -0
- package/dest/public/fixtures/minimal_public_tx.d.ts.map +1 -0
- package/dest/public/fixtures/minimal_public_tx.js +43 -0
- package/dest/public/fixtures/utils.js +3 -3
- package/dest/public/hinting_db_sources.d.ts +3 -0
- package/dest/public/hinting_db_sources.d.ts.map +1 -1
- package/dest/public/hinting_db_sources.js +9 -0
- package/dest/public/index.d.ts +2 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +2 -1
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +2 -2
- package/dest/public/public_processor/guarded_merkle_tree.d.ts +44 -0
- package/dest/public/public_processor/guarded_merkle_tree.d.ts.map +1 -0
- package/dest/public/public_processor/guarded_merkle_tree.js +105 -0
- package/dest/public/public_processor/public_processor.d.ts +6 -16
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +32 -16
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +3 -1
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +18 -15
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +0 -3
- package/dest/public/side_effect_trace.d.ts +4 -1
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +13 -2
- package/dest/public/side_effect_trace_interface.d.ts +1 -0
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.d.ts +1 -0
- package/dest/public/state_manager/state_manager.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.js +3 -0
- package/package.json +15 -15
- package/src/public/avm/avm_gas.ts +21 -15
- package/src/public/avm/fixtures/utils.ts +1 -1
- package/src/public/avm/opcodes/accrued_substate.ts +23 -7
- package/src/public/avm/opcodes/addressing_mode.ts +8 -0
- package/src/public/avm/opcodes/arithmetic.ts +3 -1
- package/src/public/avm/opcodes/bitwise.ts +26 -2
- package/src/public/avm/opcodes/comparators.ts +3 -1
- package/src/public/avm/opcodes/contract.ts +3 -1
- package/src/public/avm/opcodes/control_flow.ts +6 -4
- package/src/public/avm/opcodes/conversion.ts +21 -2
- package/src/public/avm/opcodes/ec_add.ts +3 -1
- package/src/public/avm/opcodes/environment_getters.ts +3 -1
- package/src/public/avm/opcodes/external_calls.ts +16 -8
- package/src/public/avm/opcodes/hashing.ts +11 -3
- package/src/public/avm/opcodes/instruction.ts +14 -7
- package/src/public/avm/opcodes/memory.ts +23 -6
- package/src/public/avm/opcodes/misc.ts +4 -4
- package/src/public/avm/opcodes/storage.ts +13 -3
- package/src/public/fixtures/index.ts +1 -0
- package/src/public/fixtures/minimal_public_tx.ts +57 -0
- package/src/public/fixtures/utils.ts +3 -3
- package/src/public/hinting_db_sources.ts +15 -0
- package/src/public/index.ts +2 -1
- package/src/public/public_db_sources.ts +3 -13
- package/src/public/public_processor/guarded_merkle_tree.ts +148 -0
- package/src/public/public_processor/public_processor.ts +47 -34
- package/src/public/public_tx_simulator/public_tx_context.ts +39 -20
- package/src/public/public_tx_simulator/public_tx_simulator.ts +0 -3
- package/src/public/side_effect_trace.ts +13 -0
- package/src/public/side_effect_trace_interface.ts +1 -0
- package/src/public/state_manager/state_manager.ts +4 -0
|
@@ -16,7 +16,7 @@ export class Jump extends Instruction {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
public async execute(context: AvmContext): Promise<void> {
|
|
19
|
-
context.machineState.consumeGas(this.
|
|
19
|
+
context.machineState.consumeGas(this.baseGasCost(0, 0));
|
|
20
20
|
|
|
21
21
|
context.machineState.pc = this.jumpOffset;
|
|
22
22
|
}
|
|
@@ -50,7 +50,9 @@ export class JumpI extends Instruction {
|
|
|
50
50
|
const memory = context.machineState.memory;
|
|
51
51
|
const addressing = Addressing.fromWire(this.indirect);
|
|
52
52
|
|
|
53
|
-
context.machineState.consumeGas(
|
|
53
|
+
context.machineState.consumeGas(
|
|
54
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
55
|
+
);
|
|
54
56
|
|
|
55
57
|
const operands = [this.condOffset];
|
|
56
58
|
const [condOffset] = addressing.resolve(operands, memory);
|
|
@@ -79,7 +81,7 @@ export class InternalCall extends Instruction {
|
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
public async execute(context: AvmContext): Promise<void> {
|
|
82
|
-
context.machineState.consumeGas(this.
|
|
84
|
+
context.machineState.consumeGas(this.baseGasCost(0, 0));
|
|
83
85
|
|
|
84
86
|
context.machineState.internalCallStack.push({
|
|
85
87
|
callPc: context.machineState.pc,
|
|
@@ -104,7 +106,7 @@ export class InternalReturn extends Instruction {
|
|
|
104
106
|
}
|
|
105
107
|
|
|
106
108
|
public async execute(context: AvmContext): Promise<void> {
|
|
107
|
-
context.machineState.consumeGas(this.
|
|
109
|
+
context.machineState.consumeGas(this.baseGasCost(0, 0));
|
|
108
110
|
|
|
109
111
|
const stackEntry = context.machineState.internalCallStack.pop();
|
|
110
112
|
if (stackEntry === undefined) {
|
|
@@ -35,6 +35,10 @@ export class ToRadixBE extends Instruction {
|
|
|
35
35
|
const memory = context.machineState.memory;
|
|
36
36
|
const addressing = Addressing.fromWire(this.indirect);
|
|
37
37
|
|
|
38
|
+
context.machineState.consumeGas(
|
|
39
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
40
|
+
);
|
|
41
|
+
|
|
38
42
|
const operands = [this.srcOffset, this.radixOffset, this.numLimbsOffset, this.outputBitsOffset, this.dstOffset];
|
|
39
43
|
const [srcOffset, radixOffset, numLimbsOffset, outputBitsOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
40
44
|
|
|
@@ -45,11 +49,13 @@ export class ToRadixBE extends Instruction {
|
|
|
45
49
|
memory.checkTag(TypeTag.UINT1, outputBitsOffset);
|
|
46
50
|
|
|
47
51
|
const numLimbs = memory.get(numLimbsOffset).toNumber();
|
|
48
|
-
|
|
52
|
+
const radix: bigint = memory.get(radixOffset).toBigInt();
|
|
53
|
+
context.machineState.consumeGas(
|
|
54
|
+
this.dynamicGasCost(Math.max(numLimbs, radix > 256n ? 32 : MODULUS_LIMBS_PER_RADIX[Number(radix)])),
|
|
55
|
+
);
|
|
49
56
|
const outputBits = memory.get(outputBitsOffset).toNumber();
|
|
50
57
|
|
|
51
58
|
let value: bigint = memory.get(srcOffset).toBigInt();
|
|
52
|
-
const radix: bigint = memory.get(radixOffset).toBigInt();
|
|
53
59
|
|
|
54
60
|
if (radix < 2 || radix > 256) {
|
|
55
61
|
throw new InvalidToRadixInputsError(`ToRadixBE instruction's radix should be in range [2,256] (was ${radix}).`);
|
|
@@ -79,3 +85,16 @@ export class ToRadixBE extends Instruction {
|
|
|
79
85
|
memory.setSlice(dstOffset, res);
|
|
80
86
|
}
|
|
81
87
|
}
|
|
88
|
+
|
|
89
|
+
// First two are for radix = 0 and 1, which are invalid, so we have 0 limbs for those cases.
|
|
90
|
+
export const MODULUS_LIMBS_PER_RADIX: number[] = [
|
|
91
|
+
0, 0, 254, 161, 127, 110, 99, 91, 85, 81, 77, 74, 71, 69, 67, 65, 64, 63, 61, 60, 59, 58, 57, 57, 56, 55, 54, 54, 53,
|
|
92
|
+
53, 52, 52, 51, 51, 50, 50, 50, 49, 49, 48, 48, 48, 48, 47, 47, 47, 46, 46, 46, 46, 45, 45, 45, 45, 45, 44, 44, 44,
|
|
93
|
+
44, 44, 43, 43, 43, 43, 43, 43, 42, 42, 42, 42, 42, 42, 42, 41, 41, 41, 41, 41, 41, 41, 41, 41, 40, 40, 40, 40, 40,
|
|
94
|
+
40, 40, 40, 40, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
|
|
95
|
+
37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
|
|
96
|
+
36, 36, 36, 36, 36, 36, 36, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
|
|
97
|
+
35, 35, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
|
|
98
|
+
34, 34, 34, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33,
|
|
99
|
+
33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
|
100
|
+
];
|
|
@@ -41,7 +41,9 @@ export class EcAdd extends Instruction {
|
|
|
41
41
|
const memory = context.machineState.memory;
|
|
42
42
|
const addressing = Addressing.fromWire(this.indirect);
|
|
43
43
|
|
|
44
|
-
context.machineState.consumeGas(
|
|
44
|
+
context.machineState.consumeGas(
|
|
45
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
46
|
+
);
|
|
45
47
|
|
|
46
48
|
const operands = [
|
|
47
49
|
this.p1XOffset,
|
|
@@ -73,7 +73,9 @@ export class GetEnvVar extends Instruction {
|
|
|
73
73
|
const memory = context.machineState.memory;
|
|
74
74
|
const addressing = Addressing.fromWire(this.indirect);
|
|
75
75
|
|
|
76
|
-
context.machineState.consumeGas(
|
|
76
|
+
context.machineState.consumeGas(
|
|
77
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
78
|
+
);
|
|
77
79
|
|
|
78
80
|
if (!(this.varEnum in EnvironmentVariable)) {
|
|
79
81
|
throw new InstructionExecutionError(`Invalid GETENVVAR var enum ${this.varEnum}`);
|
|
@@ -32,11 +32,15 @@ abstract class ExternalCall extends Instruction {
|
|
|
32
32
|
const memory = context.machineState.memory;
|
|
33
33
|
const addressing = Addressing.fromWire(this.indirect);
|
|
34
34
|
|
|
35
|
+
context.machineState.consumeGas(
|
|
36
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
37
|
+
);
|
|
38
|
+
|
|
35
39
|
const operands = [this.l2GasOffset, this.daGasOffset, this.addrOffset, this.argsSizeOffset, this.argsOffset];
|
|
36
40
|
const [l2GasOffset, daGasOffset, addrOffset, argsSizeOffset, argsOffset] = addressing.resolve(operands, memory);
|
|
37
|
-
|
|
38
|
-
memory.checkTags(TypeTag.
|
|
39
|
-
memory.checkTags(TypeTag.
|
|
41
|
+
|
|
42
|
+
memory.checkTags(TypeTag.UINT32, l2GasOffset);
|
|
43
|
+
memory.checkTags(TypeTag.UINT32, daGasOffset);
|
|
40
44
|
memory.checkTag(TypeTag.FIELD, addrOffset);
|
|
41
45
|
memory.checkTag(TypeTag.UINT32, argsSizeOffset);
|
|
42
46
|
|
|
@@ -48,9 +52,7 @@ abstract class ExternalCall extends Instruction {
|
|
|
48
52
|
// If we are already in a static call, we propagate the environment.
|
|
49
53
|
const callType = context.environment.isStaticCall ? 'STATICCALL' : this.type;
|
|
50
54
|
|
|
51
|
-
//
|
|
52
|
-
context.machineState.consumeGas(this.gasCost(calldataSize));
|
|
53
|
-
// Then we consume the gas allocated for the nested call. The excess will be refunded later.
|
|
55
|
+
// We consume the gas allocated for the nested call. The excess will be refunded later.
|
|
54
56
|
// Gas allocation is capped by the amount of gas left in the current context.
|
|
55
57
|
// We have to do some dancing here because the gas allocation is a field,
|
|
56
58
|
// but in the machine state we track gas as a number.
|
|
@@ -179,12 +181,15 @@ export class Return extends Instruction {
|
|
|
179
181
|
const memory = context.machineState.memory;
|
|
180
182
|
const addressing = Addressing.fromWire(this.indirect);
|
|
181
183
|
|
|
184
|
+
context.machineState.consumeGas(
|
|
185
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
186
|
+
);
|
|
187
|
+
|
|
182
188
|
const operands = [this.returnSizeOffset, this.returnOffset];
|
|
183
189
|
const [returnSizeOffset, returnOffset] = addressing.resolve(operands, memory);
|
|
184
190
|
|
|
185
191
|
memory.checkTag(TypeTag.UINT32, returnSizeOffset);
|
|
186
192
|
const returnSize = memory.get(returnSizeOffset).toNumber();
|
|
187
|
-
context.machineState.consumeGas(this.gasCost(returnSize));
|
|
188
193
|
|
|
189
194
|
const output = memory.getSlice(returnOffset, returnSize).map(word => word.toFr());
|
|
190
195
|
|
|
@@ -225,12 +230,15 @@ export class Revert extends Instruction {
|
|
|
225
230
|
const memory = context.machineState.memory;
|
|
226
231
|
const addressing = Addressing.fromWire(this.indirect);
|
|
227
232
|
|
|
233
|
+
context.machineState.consumeGas(
|
|
234
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
235
|
+
);
|
|
236
|
+
|
|
228
237
|
const operands = [this.retSizeOffset, this.returnOffset];
|
|
229
238
|
const [retSizeOffset, returnOffset] = addressing.resolve(operands, memory);
|
|
230
239
|
|
|
231
240
|
memory.checkTag(TypeTag.UINT32, retSizeOffset);
|
|
232
241
|
const retSize = memory.get(retSizeOffset).toNumber();
|
|
233
|
-
context.machineState.consumeGas(this.gasCost(retSize));
|
|
234
242
|
const output = memory.getSlice(returnOffset, retSize).map(word => word.toFr());
|
|
235
243
|
|
|
236
244
|
context.machineState.revert(output);
|
|
@@ -31,7 +31,9 @@ export class Poseidon2 extends Instruction {
|
|
|
31
31
|
const memory = context.machineState.memory;
|
|
32
32
|
const addressing = Addressing.fromWire(this.indirect);
|
|
33
33
|
|
|
34
|
-
context.machineState.consumeGas(
|
|
34
|
+
context.machineState.consumeGas(
|
|
35
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
36
|
+
);
|
|
35
37
|
|
|
36
38
|
const operands = [this.inputStateOffset, this.outputStateOffset];
|
|
37
39
|
|
|
@@ -74,9 +76,12 @@ export class KeccakF1600 extends Instruction {
|
|
|
74
76
|
const memory = context.machineState.memory;
|
|
75
77
|
const addressing = Addressing.fromWire(this.indirect);
|
|
76
78
|
|
|
79
|
+
context.machineState.consumeGas(
|
|
80
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
81
|
+
);
|
|
82
|
+
|
|
77
83
|
const operands = [this.dstOffset, this.inputOffset];
|
|
78
84
|
const [dstOffset, inputOffset] = addressing.resolve(operands, memory);
|
|
79
|
-
context.machineState.consumeGas(this.gasCost());
|
|
80
85
|
|
|
81
86
|
const stateData = memory.getSlice(inputOffset, inputSize).map(word => word.toBigInt());
|
|
82
87
|
memory.checkTagsRange(TypeTag.UINT64, inputOffset, inputSize);
|
|
@@ -117,11 +122,14 @@ export class Sha256Compression extends Instruction {
|
|
|
117
122
|
const memory = context.machineState.memory;
|
|
118
123
|
const addressing = Addressing.fromWire(this.indirect);
|
|
119
124
|
|
|
125
|
+
context.machineState.consumeGas(
|
|
126
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
127
|
+
);
|
|
128
|
+
|
|
120
129
|
const operands = [this.outputOffset, this.stateOffset, this.inputsOffset];
|
|
121
130
|
const [outputOffset, stateOffset, inputsOffset] = addressing.resolve(operands, memory);
|
|
122
131
|
|
|
123
132
|
// Note: size of output is same as size of state
|
|
124
|
-
context.machineState.consumeGas(this.gasCost());
|
|
125
133
|
const inputs = Uint32Array.from(memory.getSlice(inputsOffset, INPUTS_SIZE).map(word => word.toNumber()));
|
|
126
134
|
const state = Uint32Array.from(memory.getSlice(stateOffset, STATE_SIZE).map(word => word.toNumber()));
|
|
127
135
|
|
|
@@ -3,7 +3,7 @@ import type { Bufferable } from '@aztec/foundation/serialize';
|
|
|
3
3
|
import { strict as assert } from 'assert';
|
|
4
4
|
|
|
5
5
|
import type { AvmContext } from '../avm_context.js';
|
|
6
|
-
import { type Gas, getBaseGasCost, getDynamicGasCost, mulGas, sumGas } from '../avm_gas.js';
|
|
6
|
+
import { type Gas, computeAddressingCost, getBaseGasCost, getDynamicGasCost, mulGas, sumGas } from '../avm_gas.js';
|
|
7
7
|
import type { BufferCursor } from '../serialization/buffer_cursor.js';
|
|
8
8
|
import { Opcode, type OperandType, deserialize, serializeAs } from '../serialization/instruction_serialization.js';
|
|
9
9
|
|
|
@@ -92,13 +92,20 @@ export abstract class Instruction {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
|
-
*
|
|
96
|
-
* @returns
|
|
95
|
+
* Returns the base gas cost for the instruction.
|
|
96
|
+
* @returns The base gas cost.
|
|
97
97
|
*/
|
|
98
|
-
protected
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
protected baseGasCost(indirectOperandsCount: number, relativeOperandsCount: number): Gas {
|
|
99
|
+
return sumGas(getBaseGasCost(this.opcode), computeAddressingCost(indirectOperandsCount, relativeOperandsCount));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Computes the dynamic gas cost for the instruction
|
|
104
|
+
* @param dynMultiplier - The multiplier for the dynamic gas cost.
|
|
105
|
+
* @returns The dynamic gas cost.
|
|
106
|
+
*/
|
|
107
|
+
protected dynamicGasCost(dynMultiplier: number = 0): Gas {
|
|
108
|
+
return mulGas(getDynamicGasCost(this.opcode), dynMultiplier);
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
/**
|
|
@@ -68,7 +68,9 @@ export class Set extends Instruction {
|
|
|
68
68
|
const memory = context.machineState.memory;
|
|
69
69
|
const addressing = Addressing.fromWire(this.indirect);
|
|
70
70
|
|
|
71
|
-
context.machineState.consumeGas(
|
|
71
|
+
context.machineState.consumeGas(
|
|
72
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
73
|
+
);
|
|
72
74
|
|
|
73
75
|
const operands = [this.dstOffset];
|
|
74
76
|
const [dstOffset] = addressing.resolve(operands, memory);
|
|
@@ -108,7 +110,9 @@ export class Cast extends Instruction {
|
|
|
108
110
|
const memory = context.machineState.memory;
|
|
109
111
|
const addressing = Addressing.fromWire(this.indirect);
|
|
110
112
|
|
|
111
|
-
context.machineState.consumeGas(
|
|
113
|
+
context.machineState.consumeGas(
|
|
114
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
115
|
+
);
|
|
112
116
|
|
|
113
117
|
const operands = [this.srcOffset, this.dstOffset];
|
|
114
118
|
const [srcOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
@@ -151,7 +155,9 @@ export class Mov extends Instruction {
|
|
|
151
155
|
const memory = context.machineState.memory;
|
|
152
156
|
const addressing = Addressing.fromWire(this.indirect);
|
|
153
157
|
|
|
154
|
-
context.machineState.consumeGas(
|
|
158
|
+
context.machineState.consumeGas(
|
|
159
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
160
|
+
);
|
|
155
161
|
|
|
156
162
|
const operands = [this.srcOffset, this.dstOffset];
|
|
157
163
|
const [srcOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
@@ -185,13 +191,17 @@ export class CalldataCopy extends Instruction {
|
|
|
185
191
|
const memory = context.machineState.memory;
|
|
186
192
|
const addressing = Addressing.fromWire(this.indirect);
|
|
187
193
|
|
|
194
|
+
context.machineState.consumeGas(
|
|
195
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
196
|
+
);
|
|
197
|
+
|
|
188
198
|
const operands = [this.copySizeOffset, this.cdStartOffset, this.dstOffset];
|
|
189
199
|
const [copySizeOffset, cdStartOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
190
200
|
|
|
191
201
|
memory.checkTags(TypeTag.UINT32, cdStartOffset, copySizeOffset);
|
|
192
202
|
const cdStart = memory.get(cdStartOffset).toNumber();
|
|
193
203
|
const copySize = memory.get(copySizeOffset).toNumber();
|
|
194
|
-
context.machineState.consumeGas(this.
|
|
204
|
+
context.machineState.consumeGas(this.dynamicGasCost(copySize));
|
|
195
205
|
|
|
196
206
|
// Values which are out-of-range of the calldata array will be set with Field(0);
|
|
197
207
|
const slice = context.environment.calldata.slice(cdStart, cdStart + copySize).map(f => new Field(f));
|
|
@@ -219,9 +229,12 @@ export class ReturndataSize extends Instruction {
|
|
|
219
229
|
const memory = context.machineState.memory;
|
|
220
230
|
const addressing = Addressing.fromWire(this.indirect);
|
|
221
231
|
|
|
232
|
+
context.machineState.consumeGas(
|
|
233
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
234
|
+
);
|
|
235
|
+
|
|
222
236
|
const operands = [this.dstOffset];
|
|
223
237
|
const [dstOffset] = addressing.resolve(operands, memory);
|
|
224
|
-
context.machineState.consumeGas(this.gasCost());
|
|
225
238
|
|
|
226
239
|
memory.set(dstOffset, new Uint32(context.machineState.nestedReturndata.length));
|
|
227
240
|
}
|
|
@@ -252,13 +265,17 @@ export class ReturndataCopy extends Instruction {
|
|
|
252
265
|
const memory = context.machineState.memory;
|
|
253
266
|
const addressing = Addressing.fromWire(this.indirect);
|
|
254
267
|
|
|
268
|
+
context.machineState.consumeGas(
|
|
269
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
270
|
+
);
|
|
271
|
+
|
|
255
272
|
const operands = [this.copySizeOffset, this.rdStartOffset, this.dstOffset];
|
|
256
273
|
const [copySizeOffset, rdStartOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
257
274
|
|
|
258
275
|
memory.checkTags(TypeTag.UINT32, rdStartOffset, copySizeOffset);
|
|
259
276
|
const rdStart = memory.get(rdStartOffset).toNumber();
|
|
260
277
|
const copySize = memory.get(copySizeOffset).toNumber();
|
|
261
|
-
context.machineState.consumeGas(this.
|
|
278
|
+
context.machineState.consumeGas(this.dynamicGasCost(copySize));
|
|
262
279
|
|
|
263
280
|
// Values which are out-of-range of the returndata array will be set with Field(0);
|
|
264
281
|
const slice = context.machineState.nestedReturndata.slice(rdStart, rdStart + copySize).map(f => new Field(f));
|
|
@@ -35,6 +35,10 @@ export class DebugLog extends Instruction {
|
|
|
35
35
|
const memory = context.machineState.memory;
|
|
36
36
|
const addressing = Addressing.fromWire(this.indirect);
|
|
37
37
|
|
|
38
|
+
context.machineState.consumeGas(
|
|
39
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
40
|
+
);
|
|
41
|
+
|
|
38
42
|
const operands = [this.messageOffset, this.fieldsOffset, this.fieldsSizeOffset];
|
|
39
43
|
const [messageOffset, fieldsOffset, fieldsSizeOffset] = addressing.resolve(operands, memory);
|
|
40
44
|
memory.checkTag(TypeTag.UINT32, fieldsSizeOffset);
|
|
@@ -60,9 +64,5 @@ export class DebugLog extends Instruction {
|
|
|
60
64
|
|
|
61
65
|
DebugLog.logger.verbose(formattedStr);
|
|
62
66
|
}
|
|
63
|
-
|
|
64
|
-
// Despite having dynamic "size" operands, the gas cost is fixed because
|
|
65
|
-
// this opcode is a no-op except during client-initiated simulation
|
|
66
|
-
context.machineState.consumeGas(this.gasCost());
|
|
67
67
|
}
|
|
68
68
|
}
|
|
@@ -39,14 +39,22 @@ export class SStore extends BaseStorageInstruction {
|
|
|
39
39
|
const memory = context.machineState.memory;
|
|
40
40
|
const addressing = Addressing.fromWire(this.indirect);
|
|
41
41
|
|
|
42
|
-
context.machineState.consumeGas(
|
|
42
|
+
context.machineState.consumeGas(
|
|
43
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
44
|
+
);
|
|
43
45
|
|
|
44
46
|
const operands = [this.aOffset, this.bOffset];
|
|
45
47
|
const [srcOffset, slotOffset] = addressing.resolve(operands, memory);
|
|
48
|
+
// We read before tag checking since it's needed for gas cost calculation
|
|
49
|
+
const slot = memory.get(slotOffset).toFr();
|
|
50
|
+
|
|
51
|
+
context.machineState.consumeGas(
|
|
52
|
+
this.dynamicGasCost(Number(context.persistableState.isStorageCold(context.environment.address, slot))),
|
|
53
|
+
);
|
|
54
|
+
|
|
46
55
|
memory.checkTag(TypeTag.FIELD, slotOffset);
|
|
47
56
|
memory.checkTag(TypeTag.FIELD, srcOffset);
|
|
48
57
|
|
|
49
|
-
const slot = memory.get(slotOffset).toFr();
|
|
50
58
|
const value = memory.get(srcOffset).toFr();
|
|
51
59
|
await context.persistableState.writeStorage(context.environment.address, slot, value);
|
|
52
60
|
}
|
|
@@ -64,7 +72,9 @@ export class SLoad extends BaseStorageInstruction {
|
|
|
64
72
|
const memory = context.machineState.memory;
|
|
65
73
|
const addressing = Addressing.fromWire(this.indirect);
|
|
66
74
|
|
|
67
|
-
context.machineState.consumeGas(
|
|
75
|
+
context.machineState.consumeGas(
|
|
76
|
+
this.baseGasCost(addressing.indirectOperandsCount(), addressing.relativeOperandsCount()),
|
|
77
|
+
);
|
|
68
78
|
|
|
69
79
|
const operands = [this.aOffset, this.bOffset];
|
|
70
80
|
const [slotOffset, dstOffset] = addressing.resolve(operands, memory);
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { FunctionType, emptyContractArtifact, emptyFunctionArtifact } from '@aztec/stdlib/abi';
|
|
2
|
+
import { AvmCircuitInputs } from '@aztec/stdlib/avm';
|
|
3
|
+
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
4
|
+
|
|
5
|
+
import avmMinimalCircuitInputsJson from '../../../artifacts/avm_minimal_inputs.json' with { type: 'json' };
|
|
6
|
+
import { TypeTag } from '../avm/avm_memory_types.js';
|
|
7
|
+
import { Add, Return, Set } from '../avm/opcodes/index.js';
|
|
8
|
+
import { encodeToBytecode } from '../avm/serialization/bytecode_serialization.js';
|
|
9
|
+
import { Opcode } from '../avm/serialization/instruction_serialization.js';
|
|
10
|
+
import type { PublicTxResult } from '../public_tx_simulator/public_tx_simulator.js';
|
|
11
|
+
import { PublicTxSimulationTester } from './public_tx_simulation_tester.js';
|
|
12
|
+
|
|
13
|
+
export async function createAvmMinimalPublicTx(): Promise<PublicTxResult> {
|
|
14
|
+
const deployer = AztecAddress.fromNumber(42);
|
|
15
|
+
|
|
16
|
+
const simTester = await PublicTxSimulationTester.create();
|
|
17
|
+
|
|
18
|
+
const minimalBytecode = encodeToBytecode([
|
|
19
|
+
new Set(/*indirect*/ 0, /*dstOffset*/ 0, TypeTag.UINT32, /*value*/ 1).as(Opcode.SET_8, Set.wireFormat8),
|
|
20
|
+
new Set(/*indirect*/ 0, /*dstOffset*/ 1, TypeTag.UINT32, /*value*/ 2).as(Opcode.SET_8, Set.wireFormat8),
|
|
21
|
+
new Add(/*indirect=*/ 0, /*aOffset=*/ 0, /*bOffset=*/ 1, /*dstOffset=*/ 2).as(Opcode.ADD_8, Add.wireFormat8),
|
|
22
|
+
new Return(/*indirect=*/ 0, /*copySizeOffset=*/ 0, /*returnOffset=*/ 2),
|
|
23
|
+
]);
|
|
24
|
+
|
|
25
|
+
const minimalContractArtifact = emptyContractArtifact();
|
|
26
|
+
minimalContractArtifact.name = 'MinimalContract';
|
|
27
|
+
minimalContractArtifact.functions = [emptyFunctionArtifact()];
|
|
28
|
+
minimalContractArtifact.functions[0].name = 'public_dispatch';
|
|
29
|
+
minimalContractArtifact.functions[0].functionType = FunctionType.PUBLIC;
|
|
30
|
+
minimalContractArtifact.functions[0].bytecode = minimalBytecode;
|
|
31
|
+
|
|
32
|
+
const minimalTestContract = await simTester.registerAndDeployContract(
|
|
33
|
+
/*constructorArgs=*/ [],
|
|
34
|
+
deployer,
|
|
35
|
+
/*contractArtifact=*/ minimalContractArtifact,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
return await simTester.simulateTx(
|
|
39
|
+
/*sender=*/ deployer,
|
|
40
|
+
/*setupCalls=*/ [],
|
|
41
|
+
/*appCalls=*/ [
|
|
42
|
+
{
|
|
43
|
+
address: minimalTestContract.address,
|
|
44
|
+
fnName: 'public_dispatch',
|
|
45
|
+
args: [],
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Reads the AVM circuit inputs for the minimal public tx from a pre-generated JSON file.
|
|
53
|
+
* @returns The AvmCircuitInputs for the minimal public tx.
|
|
54
|
+
*/
|
|
55
|
+
export function readAvmMinimalPublicTxInputsFromFile(): AvmCircuitInputs {
|
|
56
|
+
return AvmCircuitInputs.schema.parse(avmMinimalCircuitInputsJson);
|
|
57
|
+
}
|
|
@@ -127,10 +127,10 @@ export async function addNewContractClassToTx(
|
|
|
127
127
|
];
|
|
128
128
|
const contractAddress = new AztecAddress(new Fr(REGISTERER_CONTRACT_ADDRESS));
|
|
129
129
|
const emittedLength = contractClassLogFields.length;
|
|
130
|
-
const
|
|
130
|
+
const logFields = ContractClassLogFields.fromEmittedFields(contractClassLogFields);
|
|
131
131
|
|
|
132
132
|
const contractClassLogHash = LogHash.from({
|
|
133
|
-
value: await
|
|
133
|
+
value: await logFields.hash(),
|
|
134
134
|
length: emittedLength,
|
|
135
135
|
}).scope(contractAddress);
|
|
136
136
|
|
|
@@ -143,7 +143,7 @@ export async function addNewContractClassToTx(
|
|
|
143
143
|
const nextLogIndex = countAccumulatedItems(accumulatedData.contractClassLogsHashes);
|
|
144
144
|
accumulatedData.contractClassLogsHashes[nextLogIndex] = contractClassLogHash;
|
|
145
145
|
|
|
146
|
-
tx.
|
|
146
|
+
tx.contractClassLogFields.push(logFields);
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
export async function addNewContractInstanceToTx(
|
|
@@ -318,6 +318,14 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
|
|
|
318
318
|
);
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
+
public commitAllCheckpoints(): Promise<void> {
|
|
322
|
+
throw new Error('commitAllCheckpoints is not supported in HintingMerkleWriteOperations.');
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
public revertAllCheckpoints(): Promise<void> {
|
|
326
|
+
throw new Error('revertAllCheckpoints is not supported in HintingMerkleWriteOperations.');
|
|
327
|
+
}
|
|
328
|
+
|
|
321
329
|
public async commitCheckpoint(): Promise<void> {
|
|
322
330
|
const actionCounter = this.checkpointActionCounter++;
|
|
323
331
|
const oldCheckpointId = this.getCurrentCheckpointId();
|
|
@@ -459,6 +467,13 @@ export class HintingMerkleWriteOperations implements MerkleTreeWriteOperations {
|
|
|
459
467
|
return await this.db.findLeafIndices(treeId, values);
|
|
460
468
|
}
|
|
461
469
|
|
|
470
|
+
public async findSiblingPaths<ID extends MerkleTreeId, N extends number>(
|
|
471
|
+
treeId: ID,
|
|
472
|
+
values: MerkleTreeLeafType<ID>[],
|
|
473
|
+
): Promise<(SiblingPath<N> | undefined)[]> {
|
|
474
|
+
return await this.db.findSiblingPaths(treeId, values);
|
|
475
|
+
}
|
|
476
|
+
|
|
462
477
|
public async findLeafIndicesAfter<ID extends MerkleTreeId>(
|
|
463
478
|
treeId: ID,
|
|
464
479
|
values: MerkleTreeLeafType<ID>[],
|
package/src/public/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { PublicContractsDB } from './public_db_sources.js';
|
|
2
|
-
export {
|
|
2
|
+
export { GuardedMerkleTreeOperations } from './public_processor/guarded_merkle_tree.js';
|
|
3
3
|
export { PublicProcessor, PublicProcessorFactory } from './public_processor/public_processor.js';
|
|
4
|
+
export { PublicTxSimulator, TelemetryPublicTxSimulator, type PublicTxResult } from './public_tx_simulator/index.js';
|
|
4
5
|
export { getCallRequestsWithCalldataByPhase } from './utils.js';
|
|
@@ -89,12 +89,8 @@ export class PublicContractsDB implements PublicContractsDBInterface {
|
|
|
89
89
|
*/
|
|
90
90
|
private async addNonRevertibleContractClasses(tx: Tx) {
|
|
91
91
|
const siloedContractClassLogs = tx.data.forPublic
|
|
92
|
-
?
|
|
93
|
-
|
|
94
|
-
/*siloed=*/ true,
|
|
95
|
-
)
|
|
96
|
-
: await tx.filterContractClassLogs(tx.data.forRollup!.end.contractClassLogsHashes, /*siloed=*/ true);
|
|
97
|
-
|
|
92
|
+
? tx.getSplitContractClassLogs(false /* revertible */)
|
|
93
|
+
: tx.getContractClassLogs();
|
|
98
94
|
await this.addContractClassesFromLogs(siloedContractClassLogs, this.currentTxNonRevertibleCache, 'non-revertible');
|
|
99
95
|
}
|
|
100
96
|
|
|
@@ -104,13 +100,7 @@ export class PublicContractsDB implements PublicContractsDBInterface {
|
|
|
104
100
|
* @param tx - The transaction to add revertible contract classes from.
|
|
105
101
|
*/
|
|
106
102
|
private async addRevertibleContractClasses(tx: Tx) {
|
|
107
|
-
const siloedContractClassLogs = tx.data.forPublic
|
|
108
|
-
? await tx.filterContractClassLogs(
|
|
109
|
-
tx.data.forPublic!.revertibleAccumulatedData.contractClassLogsHashes,
|
|
110
|
-
/*siloed=*/ true,
|
|
111
|
-
)
|
|
112
|
-
: [];
|
|
113
|
-
|
|
103
|
+
const siloedContractClassLogs = tx.data.forPublic ? tx.getSplitContractClassLogs(true /* revertible */) : [];
|
|
114
104
|
await this.addContractClassesFromLogs(siloedContractClassLogs, this.currentTxRevertibleCache, 'revertible');
|
|
115
105
|
}
|
|
116
106
|
|