@aztec/simulator 0.87.1 → 0.87.2-nightly.20250524
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/private/acvm/oracle/oracle.d.ts +1 -1
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.js +2 -2
- package/dest/private/acvm/oracle/typed_oracle.d.ts +1 -1
- package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/typed_oracle.js +2 -2
- package/dest/private/private_execution_oracle.d.ts +1 -1
- package/dest/private/private_execution_oracle.d.ts.map +1 -1
- package/dest/private/private_execution_oracle.js +1 -1
- package/dest/private/providers/circuit_recording/circuit_recorder.d.ts +1 -1
- package/dest/private/providers/circuit_recording/circuit_recorder.js +1 -1
- package/dest/private/utility_execution_oracle.d.ts +1 -1
- package/dest/private/utility_execution_oracle.d.ts.map +1 -1
- package/dest/private/utility_execution_oracle.js +1 -1
- 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 +28 -18
- 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/public_tx_simulator/apps_tests/amm_test.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/apps_tests/amm_test.js +32 -18
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +1 -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 +5 -4
- 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/private/acvm/oracle/oracle.ts +2 -2
- package/src/private/acvm/oracle/typed_oracle.ts +2 -2
- package/src/private/private_execution_oracle.ts +1 -1
- package/src/private/providers/circuit_recording/circuit_recorder.ts +1 -1
- package/src/private/utility_execution_oracle.ts +1 -1
- package/src/public/avm/avm_gas.ts +20 -14
- 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/public_tx_simulator/apps_tests/amm_test.ts +51 -20
- package/src/public/public_tx_simulator/public_tx_context.ts +26 -5
- 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
|
@@ -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
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { GeneratorIndex } from '@aztec/constants';
|
|
2
|
+
import { poseidon2HashWithSeparator } from '@aztec/foundation/crypto';
|
|
1
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
2
4
|
import type { Logger } from '@aztec/foundation/log';
|
|
3
5
|
import { AMMContractArtifact } from '@aztec/noir-contracts.js/AMM';
|
|
@@ -137,7 +139,18 @@ async function addLiquidity(
|
|
|
137
139
|
const liquidityPartialNote = {
|
|
138
140
|
commitment: new Fr(99),
|
|
139
141
|
};
|
|
140
|
-
|
|
142
|
+
const refundToken0PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
|
|
143
|
+
refundToken0PartialNote,
|
|
144
|
+
amm.address,
|
|
145
|
+
);
|
|
146
|
+
const refundToken1PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
|
|
147
|
+
refundToken1PartialNote,
|
|
148
|
+
amm.address,
|
|
149
|
+
);
|
|
150
|
+
const liquidityPartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
|
|
151
|
+
liquidityPartialNote,
|
|
152
|
+
amm.address,
|
|
153
|
+
);
|
|
141
154
|
return await tester.simulateTxWithLabel(
|
|
142
155
|
/*txLabel=*/ 'AMM/add_liquidity',
|
|
143
156
|
/*sender=*/ sender,
|
|
@@ -150,11 +163,11 @@ async function addLiquidity(
|
|
|
150
163
|
args: [/*to=*/ amm.address, /*amount=*/ amount0Max],
|
|
151
164
|
address: token0.address,
|
|
152
165
|
},
|
|
153
|
-
// token0.prepare_private_balance_increase enqueues a call to
|
|
166
|
+
// token0.prepare_private_balance_increase enqueues a call to _set_uint_partial_note_validity
|
|
154
167
|
{
|
|
155
168
|
sender: token0.address, // INTERNAL FUNCTION! Sender must be 'this'.
|
|
156
|
-
fnName: '
|
|
157
|
-
args: [
|
|
169
|
+
fnName: '_set_uint_partial_note_validity',
|
|
170
|
+
args: [refundToken0PartialNoteValidityCommitment],
|
|
158
171
|
address: token0.address,
|
|
159
172
|
},
|
|
160
173
|
// token1.transfer_to_public enqueues a call to _increase_public_balance
|
|
@@ -164,18 +177,18 @@ async function addLiquidity(
|
|
|
164
177
|
args: [/*to=*/ amm.address, /*amount=*/ amount1Max],
|
|
165
178
|
address: token1.address,
|
|
166
179
|
},
|
|
167
|
-
// token1.prepare_private_balance_increase enqueues a call to
|
|
180
|
+
// token1.prepare_private_balance_increase enqueues a call to _set_uint_partial_note_validity
|
|
168
181
|
{
|
|
169
182
|
sender: token1.address, // INTERNAL FUNCTION! Sender must be 'this'.
|
|
170
|
-
fnName: '
|
|
171
|
-
args: [
|
|
183
|
+
fnName: '_set_uint_partial_note_validity',
|
|
184
|
+
args: [refundToken1PartialNoteValidityCommitment],
|
|
172
185
|
address: token1.address,
|
|
173
186
|
},
|
|
174
|
-
// liquidityToken.prepare_private_balance_increase enqueues a call to
|
|
187
|
+
// liquidityToken.prepare_private_balance_increase enqueues a call to _set_uint_partial_note_validity
|
|
175
188
|
{
|
|
176
189
|
sender: liquidityToken.address, // INTERNAL FUNCTION! Sender must be 'this'.
|
|
177
|
-
fnName: '
|
|
178
|
-
args: [
|
|
190
|
+
fnName: '_set_uint_partial_note_validity',
|
|
191
|
+
args: [liquidityPartialNoteValidityCommitment],
|
|
179
192
|
address: liquidityToken.address,
|
|
180
193
|
},
|
|
181
194
|
// amm.add_liquidity enqueues a call to _add_liquidity
|
|
@@ -216,6 +229,10 @@ async function swapExactTokensForTokens(
|
|
|
216
229
|
const tokenOutPartialNote = {
|
|
217
230
|
commitment: new Fr(66),
|
|
218
231
|
};
|
|
232
|
+
const tokenOutPartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
|
|
233
|
+
tokenOutPartialNote,
|
|
234
|
+
amm.address,
|
|
235
|
+
);
|
|
219
236
|
|
|
220
237
|
return await tester.simulateTxWithLabel(
|
|
221
238
|
/*txLabel=*/ 'AMM/swap_exact_tokens_for_tokens',
|
|
@@ -229,11 +246,11 @@ async function swapExactTokensForTokens(
|
|
|
229
246
|
args: [/*to=*/ amm.address, /*amount=*/ amountIn],
|
|
230
247
|
address: tokenIn.address,
|
|
231
248
|
},
|
|
232
|
-
// tokenOut.prepare_private_balance_increase enqueues a call to
|
|
249
|
+
// tokenOut.prepare_private_balance_increase enqueues a call to _set_uint_partial_note_validity
|
|
233
250
|
{
|
|
234
251
|
sender: tokenOut.address, // INTERNAL FUNCTION! Sender must be 'this'.
|
|
235
|
-
fnName: '
|
|
236
|
-
args: [
|
|
252
|
+
fnName: '_set_uint_partial_note_validity',
|
|
253
|
+
args: [tokenOutPartialNoteValidityCommitment],
|
|
237
254
|
address: tokenOut.address,
|
|
238
255
|
},
|
|
239
256
|
|
|
@@ -265,7 +282,14 @@ async function removeLiquidity(
|
|
|
265
282
|
const token1PartialNote = {
|
|
266
283
|
commitment: new Fr(222),
|
|
267
284
|
};
|
|
268
|
-
|
|
285
|
+
const token0PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
|
|
286
|
+
token0PartialNote,
|
|
287
|
+
amm.address,
|
|
288
|
+
);
|
|
289
|
+
const token1PartialNoteValidityCommitment = await computePartialNoteValidityCommitment(
|
|
290
|
+
token1PartialNote,
|
|
291
|
+
amm.address,
|
|
292
|
+
);
|
|
269
293
|
return await tester.simulateTxWithLabel(
|
|
270
294
|
/*txLabel=*/ 'AMM/remove_liquidity',
|
|
271
295
|
/*sender=*/ sender,
|
|
@@ -278,18 +302,18 @@ async function removeLiquidity(
|
|
|
278
302
|
args: [/*to=*/ amm.address, /*amount=*/ liquidity],
|
|
279
303
|
address: liquidityToken.address,
|
|
280
304
|
},
|
|
281
|
-
// token0.prepare_private_balance_increase enqueues a call to
|
|
305
|
+
// token0.prepare_private_balance_increase enqueues a call to _set_uint_partial_note_validity
|
|
282
306
|
{
|
|
283
307
|
sender: token0.address, // INTERNAL FUNCTION! Sender must be 'this'.
|
|
284
|
-
fnName: '
|
|
285
|
-
args: [
|
|
308
|
+
fnName: '_set_uint_partial_note_validity',
|
|
309
|
+
args: [token0PartialNoteValidityCommitment],
|
|
286
310
|
address: token0.address,
|
|
287
311
|
},
|
|
288
|
-
// token1.prepare_private_balance_increase enqueues a call to
|
|
312
|
+
// token1.prepare_private_balance_increase enqueues a call to _set_uint_partial_note_validity
|
|
289
313
|
{
|
|
290
314
|
sender: token1.address, // INTERNAL FUNCTION! Sender must be 'this'.
|
|
291
|
-
fnName: '
|
|
292
|
-
args: [
|
|
315
|
+
fnName: '_set_uint_partial_note_validity',
|
|
316
|
+
args: [token1PartialNoteValidityCommitment],
|
|
293
317
|
address: token1.address,
|
|
294
318
|
},
|
|
295
319
|
// amm.remove_liquidity enqueues a call to _remove_liquidity
|
|
@@ -314,3 +338,10 @@ async function removeLiquidity(
|
|
|
314
338
|
],
|
|
315
339
|
);
|
|
316
340
|
}
|
|
341
|
+
|
|
342
|
+
async function computePartialNoteValidityCommitment(partialNote: { commitment: Fr }, completer: AztecAddress) {
|
|
343
|
+
return await poseidon2HashWithSeparator(
|
|
344
|
+
[partialNote.commitment, completer],
|
|
345
|
+
GeneratorIndex.PARTIAL_NOTE_VALIDITY_COMMITMENT,
|
|
346
|
+
);
|
|
347
|
+
}
|
|
@@ -10,7 +10,13 @@ import {
|
|
|
10
10
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
11
11
|
import { Fr } from '@aztec/foundation/fields';
|
|
12
12
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
13
|
-
import {
|
|
13
|
+
import {
|
|
14
|
+
AvmAccumulatedData,
|
|
15
|
+
AvmAccumulatedDataArrayLengths,
|
|
16
|
+
AvmCircuitPublicInputs,
|
|
17
|
+
PublicDataWrite,
|
|
18
|
+
RevertCode,
|
|
19
|
+
} from '@aztec/stdlib/avm';
|
|
14
20
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
15
21
|
import type { SimulationError } from '@aztec/stdlib/errors';
|
|
16
22
|
import { computeTransactionFee } from '@aztec/stdlib/fees';
|
|
@@ -18,8 +24,9 @@ import { Gas, GasSettings } from '@aztec/stdlib/gas';
|
|
|
18
24
|
import {
|
|
19
25
|
PrivateToAvmAccumulatedData,
|
|
20
26
|
PrivateToAvmAccumulatedDataArrayLengths,
|
|
21
|
-
|
|
27
|
+
PrivateToPublicAccumulatedData,
|
|
22
28
|
PublicCallRequest,
|
|
29
|
+
PublicCallRequestArrayLengths,
|
|
23
30
|
countAccumulatedItems,
|
|
24
31
|
} from '@aztec/stdlib/kernel';
|
|
25
32
|
import { PublicLog } from '@aztec/stdlib/logs';
|
|
@@ -356,12 +363,20 @@ export class PublicTxContext {
|
|
|
356
363
|
// This converts the private accumulated data to the avm accumulated data format.
|
|
357
364
|
const convertAccumulatedData = (from: PrivateToPublicAccumulatedData) =>
|
|
358
365
|
new PrivateToAvmAccumulatedData(from.noteHashes, from.nullifiers, from.l2ToL1Msgs);
|
|
359
|
-
const
|
|
366
|
+
const getPreviousAccumulatedDataArrayLengths = (from: PrivateToPublicAccumulatedData) =>
|
|
360
367
|
new PrivateToAvmAccumulatedDataArrayLengths(
|
|
361
368
|
countAccumulatedItems(from.noteHashes),
|
|
362
369
|
countAccumulatedItems(from.nullifiers),
|
|
363
370
|
countAccumulatedItems(from.l2ToL1Msgs),
|
|
364
371
|
);
|
|
372
|
+
const getAvmAccumulatedDataArrayLengths = (from: AvmAccumulatedData) =>
|
|
373
|
+
new AvmAccumulatedDataArrayLengths(
|
|
374
|
+
from.noteHashes.length,
|
|
375
|
+
from.nullifiers.length,
|
|
376
|
+
from.l2ToL1Msgs.length,
|
|
377
|
+
from.publicLogs.length,
|
|
378
|
+
from.publicDataWrites.length,
|
|
379
|
+
);
|
|
365
380
|
|
|
366
381
|
return new AvmCircuitPublicInputs(
|
|
367
382
|
this.globalVariables,
|
|
@@ -369,6 +384,11 @@ export class PublicTxContext {
|
|
|
369
384
|
/*startGasUsed=*/ this.gasUsedByPrivate,
|
|
370
385
|
this.gasSettings,
|
|
371
386
|
this.feePayer,
|
|
387
|
+
/*publicCallRequestArrayLengths=*/ new PublicCallRequestArrayLengths(
|
|
388
|
+
this.setupCallRequests.length,
|
|
389
|
+
this.appLogicCallRequests.length,
|
|
390
|
+
this.teardownCallRequests.length > 0,
|
|
391
|
+
),
|
|
372
392
|
/*publicSetupCallRequests=*/ padArrayEnd(
|
|
373
393
|
this.setupCallRequests.map(r => r.request),
|
|
374
394
|
PublicCallRequest.empty(),
|
|
@@ -382,12 +402,13 @@ export class PublicTxContext {
|
|
|
382
402
|
/*publicTeardownCallRequests=*/ this.teardownCallRequests.length > 0
|
|
383
403
|
? this.teardownCallRequests[0].request
|
|
384
404
|
: PublicCallRequest.empty(),
|
|
385
|
-
|
|
386
|
-
|
|
405
|
+
getPreviousAccumulatedDataArrayLengths(this.nonRevertibleAccumulatedDataFromPrivate),
|
|
406
|
+
getPreviousAccumulatedDataArrayLengths(this.revertibleAccumulatedDataFromPrivate),
|
|
387
407
|
convertAccumulatedData(this.nonRevertibleAccumulatedDataFromPrivate),
|
|
388
408
|
convertAccumulatedData(this.revertibleAccumulatedDataFromPrivate),
|
|
389
409
|
endTreeSnapshots,
|
|
390
410
|
this.getTotalGasUsed(),
|
|
411
|
+
getAvmAccumulatedDataArrayLengths(accumulatedData),
|
|
391
412
|
accumulatedData,
|
|
392
413
|
/*transactionFee=*/ this.getTransactionFeeUnsafe(),
|
|
393
414
|
/*isReverted=*/ !this.revertCode.isOK(),
|
|
@@ -82,6 +82,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
82
82
|
private readonly previousSideEffectArrayLengths: SideEffectArrayLengths = SideEffectArrayLengths.empty(),
|
|
83
83
|
/** We need to track the set of class IDs used, to enforce limits. */
|
|
84
84
|
private uniqueClassIds: UniqueClassIds = new UniqueClassIds(),
|
|
85
|
+
private writtenPublicDataSlots: Set<string> = new Set(),
|
|
85
86
|
) {
|
|
86
87
|
this.sideEffectCounter = startSideEffectCounter;
|
|
87
88
|
}
|
|
@@ -98,6 +99,7 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
98
99
|
this.previousSideEffectArrayLengths.publicLogs + this.publicLogs.length,
|
|
99
100
|
),
|
|
100
101
|
this.uniqueClassIds.fork(),
|
|
102
|
+
new Set(this.writtenPublicDataSlots),
|
|
101
103
|
);
|
|
102
104
|
}
|
|
103
105
|
|
|
@@ -111,6 +113,8 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
111
113
|
|
|
112
114
|
this.sideEffectCounter = forkedTrace.sideEffectCounter;
|
|
113
115
|
this.uniqueClassIds.acceptAndMerge(forkedTrace.uniqueClassIds);
|
|
116
|
+
// Accept even if reverted, since the user already paid for the writes
|
|
117
|
+
this.writtenPublicDataSlots = new Set(forkedTrace.writtenPublicDataSlots);
|
|
114
118
|
|
|
115
119
|
if (!reverted) {
|
|
116
120
|
this.publicDataWrites.push(...forkedTrace.publicDataWrites);
|
|
@@ -170,6 +174,15 @@ export class SideEffectTrace implements PublicSideEffectTraceInterface {
|
|
|
170
174
|
`Traced public data write (address=${contractAddress}, slot=${slot}): value=${value} (counter=${this.sideEffectCounter}, isProtocol:${protocolWrite})`,
|
|
171
175
|
);
|
|
172
176
|
this.incrementSideEffectCounter();
|
|
177
|
+
this.writtenPublicDataSlots.add(this.computePublicDataSlotKey(contractAddress, slot));
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private computePublicDataSlotKey(contractAddress: AztecAddress, slot: Fr): string {
|
|
181
|
+
return `${contractAddress.toString()}:${slot.toString()}`;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
public isStorageCold(contractAddress: AztecAddress, slot: Fr): boolean {
|
|
185
|
+
return !this.writtenPublicDataSlots.has(this.computePublicDataSlotKey(contractAddress, slot));
|
|
173
186
|
}
|
|
174
187
|
|
|
175
188
|
public traceNewNoteHash(noteHash: Fr) {
|
|
@@ -12,6 +12,7 @@ export interface PublicSideEffectTraceInterface {
|
|
|
12
12
|
value: Fr,
|
|
13
13
|
protocolWrite: boolean,
|
|
14
14
|
): Promise<void>;
|
|
15
|
+
isStorageCold(contractAddress: AztecAddress, slot: Fr): boolean;
|
|
15
16
|
traceNewNoteHash(uniqueNoteHash: Fr): void;
|
|
16
17
|
getNoteHashCount(): number;
|
|
17
18
|
traceNewNullifier(siloedNullifier: Fr): void;
|
|
@@ -148,6 +148,10 @@ export class PublicPersistableStateManager {
|
|
|
148
148
|
await this.trace.tracePublicStorageWrite(contractAddress, slot, value, protocolWrite);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
public isStorageCold(contractAddress: AztecAddress, slot: Fr): boolean {
|
|
152
|
+
return this.trace.isStorageCold(contractAddress, slot);
|
|
153
|
+
}
|
|
154
|
+
|
|
151
155
|
/**
|
|
152
156
|
* Read from public storage.
|
|
153
157
|
*
|