@aztec/simulator 0.42.0 → 0.43.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.
- package/dest/acvm/oracle/oracle.d.ts +3 -2
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +17 -6
- package/dest/acvm/oracle/typed_oracle.d.ts +3 -2
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +8 -5
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +3 -1
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_memory_types.js +2 -4
- package/dest/avm/fixtures/index.d.ts +4 -1
- package/dest/avm/fixtures/index.d.ts.map +1 -1
- package/dest/avm/fixtures/index.js +11 -6
- package/dest/avm/journal/journal.d.ts +3 -3
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +18 -13
- package/dest/avm/journal/trace.d.ts +3 -3
- package/dest/avm/journal/trace.d.ts.map +1 -1
- package/dest/avm/journal/trace.js +7 -6
- package/dest/avm/journal/trace_types.d.ts +4 -0
- package/dest/avm/journal/trace_types.d.ts.map +1 -1
- package/dest/avm/journal/trace_types.js +1 -5
- package/dest/avm/opcodes/accrued_substate.d.ts +2 -2
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +36 -21
- package/dest/avm/opcodes/arithmetic.d.ts.map +1 -1
- package/dest/avm/opcodes/arithmetic.js +12 -9
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +11 -8
- package/dest/avm/opcodes/comparators.d.ts.map +1 -1
- package/dest/avm/opcodes/comparators.js +7 -5
- package/dest/avm/opcodes/contract.d.ts.map +1 -1
- package/dest/avm/opcodes/contract.js +20 -24
- package/dest/avm/opcodes/control_flow.d.ts.map +1 -1
- package/dest/avm/opcodes/control_flow.js +4 -2
- package/dest/avm/opcodes/ec_add.d.ts +19 -0
- package/dest/avm/opcodes/ec_add.d.ts.map +1 -0
- package/dest/avm/opcodes/ec_add.js +78 -0
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +8 -3
- package/dest/avm/opcodes/hashing.d.ts.map +1 -1
- package/dest/avm/opcodes/hashing.js +10 -2
- package/dest/avm/opcodes/instruction_impl.d.ts.map +1 -1
- package/dest/avm/opcodes/instruction_impl.js +4 -2
- package/dest/avm/opcodes/memory.d.ts +1 -1
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +14 -12
- package/dest/avm/opcodes/multi_scalar_mul.d.ts +16 -0
- package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -0
- package/dest/avm/opcodes/multi_scalar_mul.js +95 -0
- package/dest/avm/opcodes/storage.d.ts +1 -1
- package/dest/avm/opcodes/storage.d.ts.map +1 -1
- package/dest/avm/opcodes/storage.js +11 -8
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +5 -1
- package/dest/avm/serialization/instruction_serialization.d.ts +3 -1
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +4 -2
- package/dest/client/client_execution_context.d.ts +15 -3
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +31 -17
- package/dest/client/simulator.d.ts +2 -1
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +17 -9
- package/dest/public/abstract_phase_manager.d.ts +10 -11
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +75 -53
- package/dest/public/app_logic_phase_manager.d.ts +3 -3
- package/dest/public/app_logic_phase_manager.d.ts.map +1 -1
- package/dest/public/app_logic_phase_manager.js +3 -3
- package/dest/public/db_interfaces.d.ts +1 -0
- package/dest/public/db_interfaces.d.ts.map +1 -1
- package/dest/public/execution.d.ts +1 -15
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -51
- package/dest/public/executor.d.ts +1 -1
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +15 -8
- package/dest/public/hints_builder.d.ts +1 -1
- package/dest/public/index.d.ts +6 -6
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +7 -7
- package/dest/public/phase_manager_factory.d.ts +3 -3
- package/dest/public/phase_manager_factory.d.ts.map +1 -1
- package/dest/public/phase_manager_factory.js +5 -5
- package/dest/public/public_db_sources.d.ts +3 -1
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +54 -8
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +4 -5
- package/dest/public/setup_phase_manager.d.ts +3 -3
- package/dest/public/setup_phase_manager.d.ts.map +1 -1
- package/dest/public/setup_phase_manager.js +3 -3
- package/dest/public/tail_phase_manager.d.ts +3 -3
- package/dest/public/tail_phase_manager.d.ts.map +1 -1
- package/dest/public/tail_phase_manager.js +3 -3
- package/dest/public/teardown_phase_manager.d.ts +3 -3
- package/dest/public/teardown_phase_manager.d.ts.map +1 -1
- package/dest/public/teardown_phase_manager.js +3 -3
- package/dest/public/transitional_adaptors.d.ts +1 -1
- package/dest/public/transitional_adaptors.d.ts.map +1 -1
- package/dest/public/transitional_adaptors.js +9 -3
- package/package.json +8 -8
- package/src/acvm/oracle/oracle.ts +35 -6
- package/src/acvm/oracle/typed_oracle.ts +20 -4
- package/src/avm/avm_gas.ts +2 -0
- package/src/avm/avm_memory_types.ts +1 -3
- package/src/avm/fixtures/index.ts +12 -8
- package/src/avm/journal/journal.ts +26 -21
- package/src/avm/journal/trace.ts +8 -11
- package/src/avm/journal/trace_types.ts +3 -0
- package/src/avm/opcodes/accrued_substate.ts +53 -20
- package/src/avm/opcodes/arithmetic.ts +17 -8
- package/src/avm/opcodes/bitwise.ts +13 -8
- package/src/avm/opcodes/comparators.ts +9 -4
- package/src/avm/opcodes/contract.ts +22 -26
- package/src/avm/opcodes/control_flow.ts +3 -1
- package/src/avm/opcodes/ec_add.ts +92 -0
- package/src/avm/opcodes/external_calls.ts +8 -2
- package/src/avm/opcodes/hashing.ts +11 -1
- package/src/avm/opcodes/instruction_impl.ts +4 -1
- package/src/avm/opcodes/memory.ts +18 -11
- package/src/avm/opcodes/multi_scalar_mul.ts +114 -0
- package/src/avm/opcodes/storage.ts +10 -10
- package/src/avm/serialization/bytecode_serialization.ts +4 -0
- package/src/avm/serialization/instruction_serialization.ts +2 -0
- package/src/client/client_execution_context.ts +46 -18
- package/src/client/simulator.ts +18 -8
- package/src/public/abstract_phase_manager.ts +77 -59
- package/src/public/app_logic_phase_manager.ts +2 -2
- package/src/public/db_interfaces.ts +2 -0
- package/src/public/execution.ts +0 -69
- package/src/public/executor.ts +17 -8
- package/src/public/index.ts +6 -12
- package/src/public/phase_manager_factory.ts +6 -6
- package/src/public/public_db_sources.ts +62 -7
- package/src/public/public_processor.ts +4 -7
- package/src/public/setup_phase_manager.ts +2 -2
- package/src/public/tail_phase_manager.ts +2 -2
- package/src/public/teardown_phase_manager.ts +2 -2
- package/src/public/transitional_adaptors.ts +42 -2
- package/dest/public/utils.d.ts +0 -8
- package/dest/public/utils.d.ts.map +0 -1
- package/dest/public/utils.js +0 -38
- package/src/public/utils.ts +0 -39
|
@@ -184,15 +184,31 @@ export abstract class TypedOracle {
|
|
|
184
184
|
throw new OracleMethodNotAvailableError('storageWrite');
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
|
|
188
|
-
|
|
187
|
+
emitEncryptedEventLog(
|
|
188
|
+
_contractAddress: AztecAddress,
|
|
189
|
+
_randomness: Fr,
|
|
190
|
+
_encryptedEvent: Buffer,
|
|
191
|
+
_counter: number,
|
|
192
|
+
): void {
|
|
193
|
+
throw new OracleMethodNotAvailableError('emitEncryptedEventLog');
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
emitEncryptedNoteLog(_noteHashCounter: number, _encryptedNote: Buffer, _counter: number): void {
|
|
192
197
|
throw new OracleMethodNotAvailableError('emitEncryptedNoteLog');
|
|
193
198
|
}
|
|
194
199
|
|
|
195
|
-
|
|
200
|
+
computeEncryptedEventLog(
|
|
201
|
+
_contractAddress: AztecAddress,
|
|
202
|
+
_randomness: Fr,
|
|
203
|
+
_eventTypeId: Fr,
|
|
204
|
+
_ovKeys: KeyValidationRequest,
|
|
205
|
+
_ivpkM: PublicKey,
|
|
206
|
+
_preimage: Fr[],
|
|
207
|
+
): Buffer {
|
|
208
|
+
throw new OracleMethodNotAvailableError('computeEncryptedEventLog');
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
computeEncryptedNoteLog(
|
|
196
212
|
_contractAddress: AztecAddress,
|
|
197
213
|
_storageSlot: Fr,
|
|
198
214
|
_noteTypeId: Fr,
|
|
@@ -200,7 +216,7 @@ export abstract class TypedOracle {
|
|
|
200
216
|
_ivpkM: PublicKey,
|
|
201
217
|
_preimage: Fr[],
|
|
202
218
|
): Buffer {
|
|
203
|
-
throw new OracleMethodNotAvailableError('
|
|
219
|
+
throw new OracleMethodNotAvailableError('computeEncryptedNoteLog');
|
|
204
220
|
}
|
|
205
221
|
|
|
206
222
|
emitUnencryptedLog(_log: UnencryptedL2Log, _counter: number): void {
|
package/src/avm/avm_gas.ts
CHANGED
|
@@ -122,6 +122,8 @@ const BaseGasCosts: Record<Opcode, Gas> = {
|
|
|
122
122
|
[Opcode.POSEIDON2]: DefaultBaseGasCost,
|
|
123
123
|
[Opcode.SHA256]: DefaultBaseGasCost,
|
|
124
124
|
[Opcode.PEDERSEN]: DefaultBaseGasCost,
|
|
125
|
+
[Opcode.ECADD]: DefaultBaseGasCost,
|
|
126
|
+
[Opcode.MSM]: DefaultBaseGasCost,
|
|
125
127
|
// Conversions
|
|
126
128
|
[Opcode.TORADIXLE]: DefaultBaseGasCost,
|
|
127
129
|
};
|
|
@@ -298,9 +298,7 @@ export class TaggedMemory implements TaggedMemoryInterface {
|
|
|
298
298
|
}
|
|
299
299
|
|
|
300
300
|
public checkIsValidMemoryOffsetTag(offset: number) {
|
|
301
|
-
|
|
302
|
-
throw TagCheckError.forOffset(offset, TypeTag[this.getTag(offset)], 'UINT64');
|
|
303
|
-
}
|
|
301
|
+
this.checkTag(TypeTag.UINT32, offset);
|
|
304
302
|
}
|
|
305
303
|
|
|
306
304
|
public static checkIsIntegralTag(tag: TypeTag) {
|
|
@@ -3,7 +3,8 @@ import { FunctionSelector } from '@aztec/foundation/abi';
|
|
|
3
3
|
import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
4
4
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
5
5
|
import { Fr } from '@aztec/foundation/fields';
|
|
6
|
-
import {
|
|
6
|
+
import { AvmTestContractArtifact } from '@aztec/noir-contracts.js';
|
|
7
|
+
import { SerializableContractInstance } from '@aztec/types/contracts';
|
|
7
8
|
|
|
8
9
|
import { strict as assert } from 'assert';
|
|
9
10
|
import { mock } from 'jest-mock-extended';
|
|
@@ -16,6 +17,7 @@ import { AvmMachineState } from '../avm_machine_state.js';
|
|
|
16
17
|
import { Field, Uint8 } from '../avm_memory_types.js';
|
|
17
18
|
import { HostStorage } from '../journal/host_storage.js';
|
|
18
19
|
import { AvmPersistableStateManager } from '../journal/journal.js';
|
|
20
|
+
import { type TracedContractInstance } from '../journal/trace_types.js';
|
|
19
21
|
|
|
20
22
|
/**
|
|
21
23
|
* Create a new AVM context with default values.
|
|
@@ -137,11 +139,13 @@ export function getAvmTestContractBytecode(functionName: string): Buffer {
|
|
|
137
139
|
return artifact.bytecode;
|
|
138
140
|
}
|
|
139
141
|
|
|
140
|
-
export function
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
142
|
+
export function randomTracedContractInstance(): TracedContractInstance {
|
|
143
|
+
const instance = SerializableContractInstance.random();
|
|
144
|
+
const address = AztecAddress.random();
|
|
145
|
+
return { exists: true, ...instance, address };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function emptyTracedContractInstance(withAddress?: AztecAddress): TracedContractInstance {
|
|
149
|
+
const instance = SerializableContractInstance.empty().withAddress(withAddress ?? AztecAddress.zero());
|
|
150
|
+
return { exists: false, ...instance };
|
|
147
151
|
}
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
import { EventSelector } from '@aztec/foundation/abi';
|
|
15
15
|
import { Fr } from '@aztec/foundation/fields';
|
|
16
16
|
import { type DebugLogger, createDebugLogger } from '@aztec/foundation/log';
|
|
17
|
+
import { SerializableContractInstance } from '@aztec/types/contracts';
|
|
17
18
|
|
|
18
19
|
import { type PublicExecutionResult } from '../../index.js';
|
|
19
20
|
import { type HostStorage } from './host_storage.js';
|
|
@@ -21,6 +22,7 @@ import { Nullifiers } from './nullifiers.js';
|
|
|
21
22
|
import { PublicStorage } from './public_storage.js';
|
|
22
23
|
import { WorldStateAccessTrace } from './trace.js';
|
|
23
24
|
import {
|
|
25
|
+
type TracedContractInstance,
|
|
24
26
|
type TracedL1toL2MessageCheck,
|
|
25
27
|
type TracedNoteHash,
|
|
26
28
|
type TracedNoteHashCheck,
|
|
@@ -55,7 +57,7 @@ export type JournalData = {
|
|
|
55
57
|
};
|
|
56
58
|
|
|
57
59
|
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
58
|
-
type PartialPublicExecutionResult = {
|
|
60
|
+
export type PartialPublicExecutionResult = {
|
|
59
61
|
noteHashReadRequests: ReadRequest[];
|
|
60
62
|
nullifierReadRequests: ReadRequest[];
|
|
61
63
|
nullifierNonExistentReadRequests: ReadRequest[];
|
|
@@ -147,15 +149,6 @@ export class AvmPersistableStateManager {
|
|
|
147
149
|
this.publicStorage.write(storageAddress, slot, value);
|
|
148
150
|
|
|
149
151
|
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
150
|
-
// The current info to the kernel clears any previous read or write request.
|
|
151
|
-
this.transitionalExecutionResult.contractStorageReads =
|
|
152
|
-
this.transitionalExecutionResult.contractStorageReads.filter(
|
|
153
|
-
read => !read.storageSlot.equals(slot) || !read.contractAddress!.equals(storageAddress),
|
|
154
|
-
);
|
|
155
|
-
this.transitionalExecutionResult.contractStorageUpdateRequests =
|
|
156
|
-
this.transitionalExecutionResult.contractStorageUpdateRequests.filter(
|
|
157
|
-
update => !update.storageSlot.equals(slot) || !update.contractAddress!.equals(storageAddress),
|
|
158
|
-
);
|
|
159
152
|
this.transitionalExecutionResult.contractStorageUpdateRequests.push(
|
|
160
153
|
new ContractStorageUpdateRequest(slot, value, this.trace.accessCounter, storageAddress),
|
|
161
154
|
);
|
|
@@ -178,17 +171,9 @@ export class AvmPersistableStateManager {
|
|
|
178
171
|
);
|
|
179
172
|
|
|
180
173
|
// TRANSITIONAL: This should be removed once the kernel handles and entire enqueued call per circuit
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
this.transitionalExecutionResult.contractStorageReads =
|
|
185
|
-
this.transitionalExecutionResult.contractStorageReads.filter(
|
|
186
|
-
read => !read.storageSlot.equals(slot) || !read.contractAddress!.equals(storageAddress),
|
|
187
|
-
);
|
|
188
|
-
this.transitionalExecutionResult.contractStorageReads.push(
|
|
189
|
-
new ContractStorageRead(slot, value, this.trace.accessCounter, storageAddress),
|
|
190
|
-
);
|
|
191
|
-
}
|
|
174
|
+
this.transitionalExecutionResult.contractStorageReads.push(
|
|
175
|
+
new ContractStorageRead(slot, value, this.trace.accessCounter, storageAddress),
|
|
176
|
+
);
|
|
192
177
|
|
|
193
178
|
// We want to keep track of all performed reads (even reverted ones)
|
|
194
179
|
this.trace.tracePublicStorageRead(storageAddress, slot, value, exists, cached);
|
|
@@ -208,6 +193,10 @@ export class AvmPersistableStateManager {
|
|
|
208
193
|
const gotLeafIndex = await this.hostStorage.commitmentsDb.getCommitmentIndex(noteHash);
|
|
209
194
|
const exists = gotLeafIndex === leafIndex.toBigInt();
|
|
210
195
|
this.log.debug(`noteHashes(${storageAddress})@${noteHash} ?? leafIndex: ${leafIndex}, exists: ${exists}.`);
|
|
196
|
+
|
|
197
|
+
// TODO: include exists here also - This can for sure come from the trace???
|
|
198
|
+
this.transitionalExecutionResult.noteHashReadRequests.push(new ReadRequest(noteHash, this.trace.accessCounter));
|
|
199
|
+
|
|
211
200
|
this.trace.traceNoteHashCheck(storageAddress, noteHash, exists, leafIndex);
|
|
212
201
|
return Promise.resolve(exists);
|
|
213
202
|
}
|
|
@@ -279,6 +268,9 @@ export class AvmPersistableStateManager {
|
|
|
279
268
|
this.log.debug(
|
|
280
269
|
`l1ToL2Messages(@${msgLeafIndex}) ?? exists: ${exists}, expected: ${msgHash}, found: ${valueAtIndex}.`,
|
|
281
270
|
);
|
|
271
|
+
|
|
272
|
+
this.transitionalExecutionResult.l1ToL2MsgReadRequests.push(new ReadRequest(msgHash, this.trace.accessCounter));
|
|
273
|
+
|
|
282
274
|
this.trace.traceL1ToL2MessageCheck(msgHash, msgLeafIndex, exists);
|
|
283
275
|
return Promise.resolve(exists);
|
|
284
276
|
}
|
|
@@ -322,6 +314,19 @@ export class AvmPersistableStateManager {
|
|
|
322
314
|
this.trace.traceNewLog(logHash);
|
|
323
315
|
}
|
|
324
316
|
|
|
317
|
+
public async getContractInstance(contractAddress: Fr): Promise<TracedContractInstance> {
|
|
318
|
+
let exists = true;
|
|
319
|
+
const aztecAddress = AztecAddress.fromField(contractAddress);
|
|
320
|
+
let instance = await this.hostStorage.contractsDb.getContractInstance(aztecAddress);
|
|
321
|
+
if (instance === undefined) {
|
|
322
|
+
instance = SerializableContractInstance.empty().withAddress(aztecAddress);
|
|
323
|
+
exists = false;
|
|
324
|
+
}
|
|
325
|
+
const tracedInstance = { ...instance, exists };
|
|
326
|
+
this.trace.traceGetContractInstance(tracedInstance);
|
|
327
|
+
return Promise.resolve(tracedInstance);
|
|
328
|
+
}
|
|
329
|
+
|
|
325
330
|
/**
|
|
326
331
|
* Accept nested world state modifications, merging in its trace and accrued substate
|
|
327
332
|
*/
|
package/src/avm/journal/trace.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { AvmExecutionHints, AvmHint, Vector } from '@aztec/circuits.js';
|
|
2
1
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
2
|
|
|
4
3
|
import {
|
|
4
|
+
type TracedContractInstance,
|
|
5
5
|
type TracedL1toL2MessageCheck,
|
|
6
6
|
type TracedNoteHash,
|
|
7
7
|
type TracedNoteHashCheck,
|
|
@@ -24,6 +24,7 @@ export class WorldStateAccessTrace {
|
|
|
24
24
|
public newNullifiers: TracedNullifier[] = [];
|
|
25
25
|
public l1ToL2MessageChecks: TracedL1toL2MessageCheck[] = [];
|
|
26
26
|
public newLogsHashes: TracedUnencryptedL2Log[] = [];
|
|
27
|
+
public gotContractInstances: TracedContractInstance[] = [];
|
|
27
28
|
|
|
28
29
|
//public contractCalls: TracedContractCall[] = [];
|
|
29
30
|
//public archiveChecks: TracedArchiveLeafCheck[] = [];
|
|
@@ -148,6 +149,11 @@ export class WorldStateAccessTrace {
|
|
|
148
149
|
this.incrementAccessCounter();
|
|
149
150
|
}
|
|
150
151
|
|
|
152
|
+
public traceGetContractInstance(instance: TracedContractInstance) {
|
|
153
|
+
this.gotContractInstances.push(instance);
|
|
154
|
+
this.incrementAccessCounter();
|
|
155
|
+
}
|
|
156
|
+
|
|
151
157
|
private incrementAccessCounter() {
|
|
152
158
|
this.accessCounter++;
|
|
153
159
|
}
|
|
@@ -168,17 +174,8 @@ export class WorldStateAccessTrace {
|
|
|
168
174
|
this.newNullifiers.push(...incomingTrace.newNullifiers);
|
|
169
175
|
this.l1ToL2MessageChecks.push(...incomingTrace.l1ToL2MessageChecks);
|
|
170
176
|
this.newLogsHashes.push(...incomingTrace.newLogsHashes);
|
|
177
|
+
this.gotContractInstances.push(...incomingTrace.gotContractInstances);
|
|
171
178
|
// it is assumed that the incoming trace was initialized with this as parent, so accept counter
|
|
172
179
|
this.accessCounter = incomingTrace.accessCounter;
|
|
173
180
|
}
|
|
174
|
-
|
|
175
|
-
// TODO(dbanks12): should only return hints for one call.... shouldn't include nested calls (merged in traces)
|
|
176
|
-
public toHints(): AvmExecutionHints {
|
|
177
|
-
return new AvmExecutionHints(
|
|
178
|
-
new Vector(this.publicStorageReads.map(read => new AvmHint(read.counter, read.value))),
|
|
179
|
-
new Vector(this.noteHashChecks.map(check => new AvmHint(check.counter, new Fr(check.exists ? 1 : 0)))),
|
|
180
|
-
new Vector(this.nullifierChecks.map(check => new AvmHint(check.counter, new Fr(check.exists ? 1 : 0)))),
|
|
181
|
-
new Vector(this.l1ToL2MessageChecks.map(check => new AvmHint(check.counter, new Fr(check.exists ? 1 : 0)))),
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
181
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { type ContractInstanceWithAddress } from '@aztec/types/contracts';
|
|
2
3
|
|
|
3
4
|
//export type TracedContractCall = {
|
|
4
5
|
// callPointer: Fr;
|
|
@@ -86,3 +87,5 @@ export type TracedUnencryptedL2Log = {
|
|
|
86
87
|
// leafIndex: Fr;
|
|
87
88
|
// leaf: Fr;
|
|
88
89
|
//};
|
|
90
|
+
|
|
91
|
+
export type TracedContractInstance = { exists: boolean } & ContractInstanceWithAddress;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
|
-
import { Uint8 } from '../avm_memory_types.js';
|
|
2
|
+
import { TypeTag, Uint8 } from '../avm_memory_types.js';
|
|
3
3
|
import { InstructionExecutionError, StaticCallAlterationError } from '../errors.js';
|
|
4
4
|
import { NullifierCollisionError } from '../journal/nullifiers.js';
|
|
5
5
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
@@ -31,17 +31,22 @@ export class NoteHashExists extends Instruction {
|
|
|
31
31
|
const memoryOperations = { reads: 2, writes: 1, indirect: this.indirect };
|
|
32
32
|
const memory = context.machineState.memory.track(this.type);
|
|
33
33
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
34
|
+
const [noteHashOffset, leafIndexOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
35
|
+
[this.noteHashOffset, this.leafIndexOffset, this.existsOffset],
|
|
36
|
+
memory,
|
|
37
|
+
);
|
|
38
|
+
memory.checkTags(TypeTag.FIELD, noteHashOffset, leafIndexOffset);
|
|
34
39
|
|
|
35
40
|
// Note that this instruction accepts any type in memory, and converts to Field.
|
|
36
|
-
const noteHash = memory.get(
|
|
37
|
-
const leafIndex = memory.get(
|
|
41
|
+
const noteHash = memory.get(noteHashOffset).toFr();
|
|
42
|
+
const leafIndex = memory.get(leafIndexOffset).toFr();
|
|
38
43
|
|
|
39
44
|
const exists = await context.persistableState.checkNoteHashExists(
|
|
40
45
|
context.environment.storageAddress,
|
|
41
46
|
noteHash,
|
|
42
47
|
leafIndex,
|
|
43
48
|
);
|
|
44
|
-
memory.set(
|
|
49
|
+
memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
45
50
|
|
|
46
51
|
memory.assert(memoryOperations);
|
|
47
52
|
context.machineState.incrementPc();
|
|
@@ -63,11 +68,14 @@ export class EmitNoteHash extends Instruction {
|
|
|
63
68
|
const memory = context.machineState.memory.track(this.type);
|
|
64
69
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
65
70
|
|
|
71
|
+
const [noteHashOffset] = Addressing.fromWire(this.indirect).resolve([this.noteHashOffset], memory);
|
|
72
|
+
memory.checkTag(TypeTag.FIELD, noteHashOffset);
|
|
73
|
+
|
|
66
74
|
if (context.environment.isStaticCall) {
|
|
67
75
|
throw new StaticCallAlterationError();
|
|
68
76
|
}
|
|
69
77
|
|
|
70
|
-
const noteHash = memory.get(
|
|
78
|
+
const noteHash = memory.get(noteHashOffset).toFr();
|
|
71
79
|
context.persistableState.writeNoteHash(context.environment.storageAddress, noteHash);
|
|
72
80
|
|
|
73
81
|
memory.assert(memoryOperations);
|
|
@@ -101,11 +109,17 @@ export class NullifierExists extends Instruction {
|
|
|
101
109
|
const memory = context.machineState.memory.track(this.type);
|
|
102
110
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
103
111
|
|
|
104
|
-
const
|
|
105
|
-
|
|
112
|
+
const [nullifierOffset, addressOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
113
|
+
[this.nullifierOffset, this.addressOffset, this.existsOffset],
|
|
114
|
+
memory,
|
|
115
|
+
);
|
|
116
|
+
memory.checkTags(TypeTag.FIELD, nullifierOffset, addressOffset);
|
|
117
|
+
|
|
118
|
+
const nullifier = memory.get(nullifierOffset).toFr();
|
|
119
|
+
const address = memory.get(addressOffset).toFr();
|
|
106
120
|
const exists = await context.persistableState.checkNullifierExists(address, nullifier);
|
|
107
121
|
|
|
108
|
-
memory.set(
|
|
122
|
+
memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
109
123
|
|
|
110
124
|
memory.assert(memoryOperations);
|
|
111
125
|
context.machineState.incrementPc();
|
|
@@ -131,7 +145,10 @@ export class EmitNullifier extends Instruction {
|
|
|
131
145
|
const memory = context.machineState.memory.track(this.type);
|
|
132
146
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
133
147
|
|
|
134
|
-
const
|
|
148
|
+
const [nullifierOffset] = Addressing.fromWire(this.indirect).resolve([this.nullifierOffset], memory);
|
|
149
|
+
memory.checkTag(TypeTag.FIELD, nullifierOffset);
|
|
150
|
+
|
|
151
|
+
const nullifier = memory.get(nullifierOffset).toFr();
|
|
135
152
|
try {
|
|
136
153
|
await context.persistableState.writeNullifier(context.environment.storageAddress, nullifier);
|
|
137
154
|
} catch (e) {
|
|
@@ -176,10 +193,16 @@ export class L1ToL2MessageExists extends Instruction {
|
|
|
176
193
|
const memory = context.machineState.memory.track(this.type);
|
|
177
194
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
178
195
|
|
|
179
|
-
const
|
|
180
|
-
|
|
196
|
+
const [msgHashOffset, msgLeafIndexOffset, existsOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
197
|
+
[this.msgHashOffset, this.msgLeafIndexOffset, this.existsOffset],
|
|
198
|
+
memory,
|
|
199
|
+
);
|
|
200
|
+
memory.checkTags(TypeTag.FIELD, msgHashOffset, msgLeafIndexOffset);
|
|
201
|
+
|
|
202
|
+
const msgHash = memory.get(msgHashOffset).toFr();
|
|
203
|
+
const msgLeafIndex = memory.get(msgLeafIndexOffset).toFr();
|
|
181
204
|
const exists = await context.persistableState.checkL1ToL2MessageExists(msgHash, msgLeafIndex);
|
|
182
|
-
memory.set(
|
|
205
|
+
memory.set(existsOffset, exists ? new Uint8(1) : new Uint8(0));
|
|
183
206
|
|
|
184
207
|
memory.assert(memoryOperations);
|
|
185
208
|
context.machineState.incrementPc();
|
|
@@ -202,7 +225,7 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
202
225
|
private indirect: number,
|
|
203
226
|
private eventSelectorOffset: number,
|
|
204
227
|
private logOffset: number,
|
|
205
|
-
private
|
|
228
|
+
private logSizeOffset: number,
|
|
206
229
|
) {
|
|
207
230
|
super();
|
|
208
231
|
}
|
|
@@ -212,18 +235,23 @@ export class EmitUnencryptedLog extends Instruction {
|
|
|
212
235
|
throw new StaticCallAlterationError();
|
|
213
236
|
}
|
|
214
237
|
|
|
215
|
-
const memoryOperations = { reads: 1 + this.logSize, indirect: this.indirect };
|
|
216
238
|
const memory = context.machineState.memory.track(this.type);
|
|
217
|
-
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
218
239
|
|
|
219
|
-
const [eventSelectorOffset, logOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
220
|
-
[this.eventSelectorOffset, this.logOffset],
|
|
240
|
+
const [eventSelectorOffset, logOffset, logSizeOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
241
|
+
[this.eventSelectorOffset, this.logOffset, this.logSizeOffset],
|
|
221
242
|
memory,
|
|
222
243
|
);
|
|
244
|
+
memory.checkTag(TypeTag.FIELD, eventSelectorOffset);
|
|
245
|
+
memory.checkTag(TypeTag.UINT32, logSizeOffset);
|
|
246
|
+
const logSize = memory.get(logSizeOffset).toNumber();
|
|
247
|
+
memory.checkTagsRange(TypeTag.FIELD, logOffset, logSize);
|
|
223
248
|
|
|
224
249
|
const contractAddress = context.environment.address;
|
|
225
250
|
const event = memory.get(eventSelectorOffset).toFr();
|
|
226
|
-
|
|
251
|
+
|
|
252
|
+
const memoryOperations = { reads: 2 + logSize, indirect: this.indirect };
|
|
253
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
254
|
+
const log = memory.getSlice(logOffset, logSize).map(f => f.toFr());
|
|
227
255
|
context.persistableState.writeLog(contractAddress, event, log);
|
|
228
256
|
|
|
229
257
|
memory.assert(memoryOperations);
|
|
@@ -250,8 +278,13 @@ export class SendL2ToL1Message extends Instruction {
|
|
|
250
278
|
const memory = context.machineState.memory.track(this.type);
|
|
251
279
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
252
280
|
|
|
253
|
-
const
|
|
254
|
-
|
|
281
|
+
const [recipientOffset, contentOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
282
|
+
[this.recipientOffset, this.contentOffset],
|
|
283
|
+
memory,
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
const recipient = memory.get(recipientOffset).toFr();
|
|
287
|
+
const content = memory.get(contentOffset).toFr();
|
|
255
288
|
context.persistableState.writeL1Message(recipient, content);
|
|
256
289
|
|
|
257
290
|
memory.assert(memoryOperations);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
2
|
import { type Field, type MemoryValue, TypeTag } from '../avm_memory_types.js';
|
|
3
3
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
4
|
+
import { Addressing } from './addressing_mode.js';
|
|
4
5
|
import { Instruction } from './instruction.js';
|
|
5
6
|
import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
6
7
|
|
|
@@ -10,13 +11,17 @@ export abstract class ThreeOperandArithmeticInstruction extends ThreeOperandInst
|
|
|
10
11
|
const memory = context.machineState.memory.track(this.type);
|
|
11
12
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
15
|
+
[this.aOffset, this.bOffset, this.dstOffset],
|
|
16
|
+
memory,
|
|
17
|
+
);
|
|
18
|
+
memory.checkTags(this.inTag, aOffset, bOffset);
|
|
14
19
|
|
|
15
|
-
const a = memory.get(
|
|
16
|
-
const b = memory.get(
|
|
20
|
+
const a = memory.get(aOffset);
|
|
21
|
+
const b = memory.get(bOffset);
|
|
17
22
|
|
|
18
23
|
const dest = this.compute(a, b);
|
|
19
|
-
memory.set(
|
|
24
|
+
memory.set(dstOffset, dest);
|
|
20
25
|
|
|
21
26
|
memory.assert(memoryOperations);
|
|
22
27
|
context.machineState.incrementPc();
|
|
@@ -83,13 +88,17 @@ export class FieldDiv extends Instruction {
|
|
|
83
88
|
const memory = context.machineState.memory.track(this.type);
|
|
84
89
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
85
90
|
|
|
86
|
-
|
|
91
|
+
const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
92
|
+
[this.aOffset, this.bOffset, this.dstOffset],
|
|
93
|
+
memory,
|
|
94
|
+
);
|
|
95
|
+
memory.checkTags(TypeTag.FIELD, aOffset, bOffset);
|
|
87
96
|
|
|
88
|
-
const a = memory.getAs<Field>(
|
|
89
|
-
const b = memory.getAs<Field>(
|
|
97
|
+
const a = memory.getAs<Field>(aOffset);
|
|
98
|
+
const b = memory.getAs<Field>(bOffset);
|
|
90
99
|
|
|
91
100
|
const dest = a.fdiv(b);
|
|
92
|
-
memory.set(
|
|
101
|
+
memory.set(dstOffset, dest);
|
|
93
102
|
|
|
94
103
|
memory.assert(memoryOperations);
|
|
95
104
|
context.machineState.incrementPc();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
2
|
import { type IntegralValue, type TaggedMemoryInterface, TypeTag } from '../avm_memory_types.js';
|
|
3
3
|
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
4
|
+
import { Addressing } from './addressing_mode.js';
|
|
4
5
|
import { ThreeOperandInstruction, TwoOperandInstruction } from './instruction_impl.js';
|
|
5
6
|
|
|
6
7
|
abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
|
|
@@ -9,13 +10,17 @@ abstract class ThreeOperandBitwiseInstruction extends ThreeOperandInstruction {
|
|
|
9
10
|
const memory = context.machineState.memory.track(this.type);
|
|
10
11
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
14
|
+
[this.aOffset, this.bOffset, this.dstOffset],
|
|
15
|
+
memory,
|
|
16
|
+
);
|
|
17
|
+
this.checkTags(memory, this.inTag, aOffset, bOffset);
|
|
13
18
|
|
|
14
|
-
const a = memory.getAs<IntegralValue>(
|
|
15
|
-
const b = memory.getAs<IntegralValue>(
|
|
19
|
+
const a = memory.getAs<IntegralValue>(aOffset);
|
|
20
|
+
const b = memory.getAs<IntegralValue>(bOffset);
|
|
16
21
|
|
|
17
22
|
const res = this.compute(a, b);
|
|
18
|
-
memory.set(
|
|
23
|
+
memory.set(dstOffset, res);
|
|
19
24
|
|
|
20
25
|
memory.assert(memoryOperations);
|
|
21
26
|
context.machineState.incrementPc();
|
|
@@ -93,12 +98,12 @@ export class Not extends TwoOperandInstruction {
|
|
|
93
98
|
const memory = context.machineState.memory.track(this.type);
|
|
94
99
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
95
100
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
const a = memory.getAs<IntegralValue>(
|
|
101
|
+
const [aOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve([this.aOffset, this.dstOffset], memory);
|
|
102
|
+
memory.checkTags(this.inTag, aOffset);
|
|
103
|
+
const a = memory.getAs<IntegralValue>(aOffset);
|
|
99
104
|
|
|
100
105
|
const res = a.not();
|
|
101
|
-
memory.set(
|
|
106
|
+
memory.set(dstOffset, res);
|
|
102
107
|
|
|
103
108
|
memory.assert(memoryOperations);
|
|
104
109
|
context.machineState.incrementPc();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AvmContext } from '../avm_context.js';
|
|
2
2
|
import { type MemoryValue, Uint8 } from '../avm_memory_types.js';
|
|
3
3
|
import { Opcode } from '../serialization/instruction_serialization.js';
|
|
4
|
+
import { Addressing } from './addressing_mode.js';
|
|
4
5
|
import { ThreeOperandInstruction } from './instruction_impl.js';
|
|
5
6
|
|
|
6
7
|
abstract class ComparatorInstruction extends ThreeOperandInstruction {
|
|
@@ -9,13 +10,17 @@ abstract class ComparatorInstruction extends ThreeOperandInstruction {
|
|
|
9
10
|
const memory = context.machineState.memory.track(this.type);
|
|
10
11
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
const [aOffset, bOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
14
|
+
[this.aOffset, this.bOffset, this.dstOffset],
|
|
15
|
+
memory,
|
|
16
|
+
);
|
|
17
|
+
memory.checkTags(this.inTag, aOffset, bOffset);
|
|
13
18
|
|
|
14
|
-
const a = memory.get(
|
|
15
|
-
const b = memory.get(
|
|
19
|
+
const a = memory.get(aOffset);
|
|
20
|
+
const b = memory.get(bOffset);
|
|
16
21
|
|
|
17
22
|
const dest = new Uint8(this.compare(a, b) ? 1 : 0);
|
|
18
|
-
memory.set(
|
|
23
|
+
memory.set(dstOffset, dest);
|
|
19
24
|
|
|
20
25
|
memory.assert(memoryOperations);
|
|
21
26
|
context.machineState.incrementPc();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fr } from '@aztec/circuits.js';
|
|
2
2
|
|
|
3
3
|
import type { AvmContext } from '../avm_context.js';
|
|
4
|
-
import { Field } from '../avm_memory_types.js';
|
|
4
|
+
import { Field, TypeTag } from '../avm_memory_types.js';
|
|
5
5
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
6
6
|
import { Addressing } from './addressing_mode.js';
|
|
7
7
|
import { Instruction } from './instruction.js';
|
|
@@ -22,35 +22,31 @@ export class GetContractInstance extends Instruction {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
async execute(context: AvmContext): Promise<void> {
|
|
25
|
+
const memoryOperations = { reads: 1, writes: 6, indirect: this.indirect };
|
|
26
|
+
const memory = context.machineState.memory.track(this.type);
|
|
27
|
+
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
28
|
+
|
|
25
29
|
const [addressOffset, dstOffset] = Addressing.fromWire(this.indirect).resolve(
|
|
26
30
|
[this.addressOffset, this.dstOffset],
|
|
27
|
-
|
|
31
|
+
memory,
|
|
28
32
|
);
|
|
33
|
+
memory.checkTag(TypeTag.FIELD, addressOffset);
|
|
34
|
+
|
|
35
|
+
const address = memory.get(addressOffset).toFr();
|
|
36
|
+
const instance = await context.persistableState.getContractInstance(address);
|
|
37
|
+
|
|
38
|
+
const data = [
|
|
39
|
+
new Fr(instance.exists),
|
|
40
|
+
instance.salt,
|
|
41
|
+
instance.deployer.toField(),
|
|
42
|
+
instance.contractClassId,
|
|
43
|
+
instance.initializationHash,
|
|
44
|
+
instance.publicKeysHash,
|
|
45
|
+
].map(f => new Field(f));
|
|
29
46
|
|
|
30
|
-
|
|
31
|
-
const instance = await context.persistableState.hostStorage.contractsDb.getContractInstance(address);
|
|
32
|
-
|
|
33
|
-
const data =
|
|
34
|
-
instance === undefined
|
|
35
|
-
? [
|
|
36
|
-
new Field(0), // not found
|
|
37
|
-
new Field(0),
|
|
38
|
-
new Field(0),
|
|
39
|
-
new Field(0),
|
|
40
|
-
new Field(0),
|
|
41
|
-
new Field(0),
|
|
42
|
-
]
|
|
43
|
-
: [
|
|
44
|
-
new Fr(1), // found
|
|
45
|
-
instance.salt,
|
|
46
|
-
instance.deployer.toField(),
|
|
47
|
-
instance.contractClassId,
|
|
48
|
-
instance.initializationHash,
|
|
49
|
-
instance.publicKeysHash,
|
|
50
|
-
].map(f => new Field(f));
|
|
51
|
-
|
|
52
|
-
context.machineState.memory.setSlice(dstOffset, data);
|
|
47
|
+
memory.setSlice(dstOffset, data);
|
|
53
48
|
|
|
49
|
+
memory.assert(memoryOperations);
|
|
54
50
|
context.machineState.incrementPc();
|
|
55
51
|
}
|
|
56
52
|
}
|
|
@@ -2,6 +2,7 @@ import type { AvmContext } from '../avm_context.js';
|
|
|
2
2
|
import { type IntegralValue } from '../avm_memory_types.js';
|
|
3
3
|
import { InstructionExecutionError } from '../errors.js';
|
|
4
4
|
import { Opcode, OperandType } from '../serialization/instruction_serialization.js';
|
|
5
|
+
import { Addressing } from './addressing_mode.js';
|
|
5
6
|
import { Instruction } from './instruction.js';
|
|
6
7
|
|
|
7
8
|
export class Jump extends Instruction {
|
|
@@ -44,7 +45,8 @@ export class JumpI extends Instruction {
|
|
|
44
45
|
const memory = context.machineState.memory.track(this.type);
|
|
45
46
|
context.machineState.consumeGas(this.gasCost(memoryOperations));
|
|
46
47
|
|
|
47
|
-
const
|
|
48
|
+
const [condOffset] = Addressing.fromWire(this.indirect).resolve([this.condOffset], memory);
|
|
49
|
+
const condition = memory.getAs<IntegralValue>(condOffset);
|
|
48
50
|
|
|
49
51
|
// TODO: reconsider this casting
|
|
50
52
|
if (condition.toBigInt() == 0n) {
|