@aztec/simulator 0.36.0 → 0.38.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/acvm.d.ts +1 -1
- package/dest/acvm/acvm.d.ts.map +1 -1
- package/dest/acvm/acvm.js +2 -2
- package/dest/acvm/oracle/oracle.d.ts +6 -4
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +39 -8
- package/dest/acvm/oracle/typed_oracle.d.ts +5 -3
- package/dest/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/typed_oracle.js +9 -3
- package/dest/avm/avm_gas.d.ts.map +1 -1
- package/dest/avm/avm_gas.js +2 -1
- package/dest/avm/avm_memory_types.d.ts +1 -1
- package/dest/avm/avm_memory_types.d.ts.map +1 -1
- package/dest/avm/avm_simulator.d.ts.map +1 -1
- package/dest/avm/avm_simulator.js +3 -1
- package/dest/avm/journal/journal.d.ts +20 -1
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +69 -9
- package/dest/avm/journal/nullifiers.d.ts +3 -1
- package/dest/avm/journal/nullifiers.d.ts.map +1 -1
- package/dest/avm/journal/nullifiers.js +14 -6
- package/dest/avm/journal/public_storage.d.ts +10 -1
- package/dest/avm/journal/public_storage.d.ts.map +1 -1
- package/dest/avm/journal/public_storage.js +17 -2
- package/dest/avm/journal/trace.d.ts +1 -4
- package/dest/avm/journal/trace.d.ts.map +1 -1
- package/dest/avm/journal/trace.js +4 -5
- package/dest/avm/journal/trace_types.d.ts +1 -0
- package/dest/avm/journal/trace_types.d.ts.map +1 -1
- package/dest/avm/journal/trace_types.js +1 -1
- package/dest/avm/opcodes/bitwise.d.ts +4 -1
- package/dest/avm/opcodes/bitwise.d.ts.map +1 -1
- package/dest/avm/opcodes/bitwise.js +14 -2
- package/dest/avm/opcodes/environment_getters.d.ts +5 -0
- package/dest/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/avm/opcodes/environment_getters.js +8 -1
- package/dest/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/avm/opcodes/external_calls.js +14 -13
- package/dest/avm/serialization/bytecode_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/bytecode_serialization.js +3 -2
- package/dest/avm/serialization/instruction_serialization.d.ts +39 -38
- package/dest/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/avm/serialization/instruction_serialization.js +40 -39
- package/dest/client/client_execution_context.d.ts +31 -18
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +48 -31
- package/dest/client/db_oracle.d.ts +11 -4
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/execution_result.d.ts +19 -15
- package/dest/client/execution_result.d.ts.map +1 -1
- package/dest/client/execution_result.js +45 -12
- package/dest/client/logs_cache.d.ts +33 -0
- package/dest/client/logs_cache.d.ts.map +1 -0
- package/dest/client/logs_cache.js +59 -0
- package/dest/client/private_execution.d.ts +2 -2
- package/dest/client/private_execution.d.ts.map +1 -1
- package/dest/client/private_execution.js +3 -7
- package/dest/client/simulator.d.ts +3 -3
- package/dest/client/simulator.d.ts.map +1 -1
- package/dest/client/simulator.js +3 -2
- package/dest/client/unconstrained_execution.d.ts +2 -2
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +1 -1
- package/dest/client/view_data_oracle.d.ts +7 -0
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +10 -1
- package/dest/mocks/fixtures.d.ts.map +1 -1
- package/dest/mocks/fixtures.js +3 -1
- package/dest/public/abstract_phase_manager.d.ts +2 -0
- package/dest/public/abstract_phase_manager.d.ts.map +1 -1
- package/dest/public/abstract_phase_manager.js +13 -6
- package/dest/public/execution.d.ts +9 -0
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -1
- package/dest/public/executor.d.ts +2 -2
- package/dest/public/executor.d.ts.map +1 -1
- package/dest/public/executor.js +34 -14
- package/dest/public/public_execution_context.d.ts +10 -4
- package/dest/public/public_execution_context.d.ts.map +1 -1
- package/dest/public/public_execution_context.js +19 -6
- package/dest/public/tail_phase_manager.d.ts +0 -1
- package/dest/public/tail_phase_manager.d.ts.map +1 -1
- package/dest/public/tail_phase_manager.js +3 -26
- package/dest/public/transitional_adaptors.d.ts +4 -17
- package/dest/public/transitional_adaptors.d.ts.map +1 -1
- package/dest/public/transitional_adaptors.js +27 -119
- package/package.json +8 -8
- package/src/acvm/acvm.ts +2 -2
- package/src/acvm/oracle/oracle.ts +63 -10
- package/src/acvm/oracle/typed_oracle.ts +12 -3
- package/src/avm/avm_gas.ts +1 -0
- package/src/avm/avm_memory_types.ts +1 -1
- package/src/avm/avm_simulator.ts +2 -0
- package/src/avm/journal/journal.ts +133 -9
- package/src/avm/journal/nullifiers.ts +19 -8
- package/src/avm/journal/public_storage.ts +23 -2
- package/src/avm/journal/trace.ts +3 -4
- package/src/avm/journal/trace_types.ts +1 -0
- package/src/avm/opcodes/bitwise.ts +18 -7
- package/src/avm/opcodes/environment_getters.ts +9 -0
- package/src/avm/opcodes/external_calls.ts +21 -16
- package/src/avm/serialization/bytecode_serialization.ts +2 -0
- package/src/avm/serialization/instruction_serialization.ts +1 -0
- package/src/client/client_execution_context.ts +55 -31
- package/src/client/db_oracle.ts +12 -10
- package/src/client/execution_result.ts +55 -24
- package/src/client/logs_cache.ts +65 -0
- package/src/client/private_execution.ts +4 -10
- package/src/client/simulator.ts +6 -4
- package/src/client/unconstrained_execution.ts +2 -2
- package/src/client/view_data_oracle.ts +10 -0
- package/src/mocks/fixtures.ts +2 -0
- package/src/public/abstract_phase_manager.ts +13 -5
- package/src/public/execution.ts +9 -0
- package/src/public/executor.ts +47 -10
- package/src/public/public_execution_context.ts +18 -4
- package/src/public/tail_phase_manager.ts +2 -34
- package/src/public/transitional_adaptors.ts +39 -178
|
@@ -15,10 +15,8 @@ import {
|
|
|
15
15
|
FunctionData,
|
|
16
16
|
FunctionSelector,
|
|
17
17
|
type Header,
|
|
18
|
-
NoteHashReadRequestMembershipWitness,
|
|
19
18
|
PrivateContextInputs,
|
|
20
19
|
PublicCallRequest,
|
|
21
|
-
type SideEffect,
|
|
22
20
|
type TxContext,
|
|
23
21
|
} from '@aztec/circuits.js';
|
|
24
22
|
import { Aes128 } from '@aztec/circuits.js/barretenberg';
|
|
@@ -32,7 +30,8 @@ import { type NoteData, toACVMWitness } from '../acvm/index.js';
|
|
|
32
30
|
import { type PackedValuesCache } from '../common/packed_values_cache.js';
|
|
33
31
|
import { type DBOracle } from './db_oracle.js';
|
|
34
32
|
import { type ExecutionNoteCache } from './execution_note_cache.js';
|
|
35
|
-
import { type ExecutionResult, type NoteAndSlot
|
|
33
|
+
import { CountedLog, type ExecutionResult, type NoteAndSlot } from './execution_result.js';
|
|
34
|
+
import { type LogsCache } from './logs_cache.js';
|
|
36
35
|
import { pickNotes } from './pick_notes.js';
|
|
37
36
|
import { executePrivateFunction } from './private_execution.js';
|
|
38
37
|
import { ViewDataOracle } from './view_data_oracle.js';
|
|
@@ -58,10 +57,10 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
58
57
|
* because these notes are meant to be maintained on a per-call basis
|
|
59
58
|
* They should act as references for the read requests output by an app circuit via public inputs.
|
|
60
59
|
*/
|
|
61
|
-
private
|
|
62
|
-
private nullifiedNoteHashCounters:
|
|
63
|
-
private encryptedLogs: EncryptedL2Log[] = [];
|
|
64
|
-
private unencryptedLogs: UnencryptedL2Log[] = [];
|
|
60
|
+
private noteHashLeafIndexMap: Map<bigint, bigint> = new Map();
|
|
61
|
+
private nullifiedNoteHashCounters: Map<number, number> = new Map();
|
|
62
|
+
private encryptedLogs: CountedLog<EncryptedL2Log>[] = [];
|
|
63
|
+
private unencryptedLogs: CountedLog<UnencryptedL2Log>[] = [];
|
|
65
64
|
private nestedExecutions: ExecutionResult[] = [];
|
|
66
65
|
private enqueuedPublicFunctionCalls: PublicCallRequest[] = [];
|
|
67
66
|
|
|
@@ -76,6 +75,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
76
75
|
authWitnesses: AuthWitness[],
|
|
77
76
|
private readonly packedValuesCache: PackedValuesCache,
|
|
78
77
|
private readonly noteCache: ExecutionNoteCache,
|
|
78
|
+
private readonly logsCache: LogsCache,
|
|
79
79
|
db: DBOracle,
|
|
80
80
|
private node: AztecNode,
|
|
81
81
|
protected sideEffectCounter: number = 0,
|
|
@@ -112,23 +112,11 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
/**
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* or to flag non-transient reads with their leafIndex.
|
|
118
|
-
* The KernelProver will use this to fully populate witnesses and provide hints to
|
|
119
|
-
* the kernel regarding which commitments each transient read request corresponds to.
|
|
120
|
-
* @param noteHashReadRequests - SideEffect containing Note hashed of the notes being read and counter.
|
|
121
|
-
* @returns An array of partially filled in read request membership witnesses.
|
|
115
|
+
* The KernelProver will use this to fully populate witnesses and provide hints to the kernel circuit
|
|
116
|
+
* regarding which note hash each settled read request corresponds to.
|
|
122
117
|
*/
|
|
123
|
-
public
|
|
124
|
-
return
|
|
125
|
-
.filter(r => !r.isEmpty())
|
|
126
|
-
.map(r => {
|
|
127
|
-
const index = this.gotNotes.get(r.value.toBigInt());
|
|
128
|
-
return index !== undefined
|
|
129
|
-
? NoteHashReadRequestMembershipWitness.empty(index)
|
|
130
|
-
: NoteHashReadRequestMembershipWitness.emptyTransient();
|
|
131
|
-
});
|
|
118
|
+
public getNoteHashLeafIndexMap() {
|
|
119
|
+
return this.noteHashLeafIndexMap;
|
|
132
120
|
}
|
|
133
121
|
|
|
134
122
|
/**
|
|
@@ -147,14 +135,28 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
147
135
|
* Return the encrypted logs emitted during this execution.
|
|
148
136
|
*/
|
|
149
137
|
public getEncryptedLogs() {
|
|
150
|
-
return
|
|
138
|
+
return this.encryptedLogs;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Return the encrypted logs emitted during this execution and nested executions.
|
|
143
|
+
*/
|
|
144
|
+
public getAllEncryptedLogs() {
|
|
145
|
+
return new EncryptedFunctionL2Logs(this.logsCache.getEncryptedLogs());
|
|
151
146
|
}
|
|
152
147
|
|
|
153
148
|
/**
|
|
154
149
|
* Return the encrypted logs emitted during this execution.
|
|
155
150
|
*/
|
|
156
151
|
public getUnencryptedLogs() {
|
|
157
|
-
return
|
|
152
|
+
return this.unencryptedLogs;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Return the unencrypted logs emitted during this execution and nested executions.
|
|
157
|
+
*/
|
|
158
|
+
public getAllUnencryptedLogs() {
|
|
159
|
+
return new UnencryptedFunctionL2Logs(this.logsCache.getUnencryptedLogs());
|
|
158
160
|
}
|
|
159
161
|
|
|
160
162
|
/**
|
|
@@ -265,7 +267,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
265
267
|
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1386)
|
|
266
268
|
// Should always be uniqueSiloedNoteHash when publicly created notes include nonces.
|
|
267
269
|
const noteHashForReadRequest = n.nonce.isZero() ? siloedNoteHash : uniqueSiloedNoteHash;
|
|
268
|
-
this.
|
|
270
|
+
this.noteHashLeafIndexMap.set(noteHashForReadRequest.toBigInt(), n.index);
|
|
269
271
|
}
|
|
270
272
|
});
|
|
271
273
|
|
|
@@ -321,7 +323,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
321
323
|
innerNoteHash,
|
|
322
324
|
);
|
|
323
325
|
if (nullifiedNoteHashCounter !== undefined) {
|
|
324
|
-
this.nullifiedNoteHashCounters.
|
|
326
|
+
this.nullifiedNoteHashCounters.set(nullifiedNoteHashCounter, counter);
|
|
325
327
|
}
|
|
326
328
|
return Promise.resolve();
|
|
327
329
|
}
|
|
@@ -340,24 +342,45 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
340
342
|
noteTypeId: Fr,
|
|
341
343
|
publicKey: Point,
|
|
342
344
|
log: Fr[],
|
|
345
|
+
counter: number,
|
|
343
346
|
) {
|
|
344
347
|
const note = new Note(log);
|
|
345
348
|
const l1NotePayload = new L1NotePayload(note, contractAddress, storageSlot, noteTypeId);
|
|
346
349
|
const taggedNote = new TaggedNote(l1NotePayload);
|
|
347
350
|
const encryptedNote = taggedNote.toEncryptedBuffer(publicKey);
|
|
348
351
|
const encryptedLog = new EncryptedL2Log(encryptedNote);
|
|
349
|
-
this.encryptedLogs.push(encryptedLog);
|
|
350
|
-
|
|
352
|
+
this.encryptedLogs.push(new CountedLog(encryptedLog, counter));
|
|
353
|
+
this.logsCache.addEncryptedLog(encryptedLog);
|
|
354
|
+
return encryptedNote;
|
|
351
355
|
}
|
|
352
356
|
|
|
353
357
|
/**
|
|
354
358
|
* Emit an unencrypted log.
|
|
355
359
|
* @param log - The unencrypted log to be emitted.
|
|
356
360
|
*/
|
|
357
|
-
public override emitUnencryptedLog(log: UnencryptedL2Log) {
|
|
358
|
-
this.unencryptedLogs.push(log);
|
|
361
|
+
public override emitUnencryptedLog(log: UnencryptedL2Log, counter: number) {
|
|
362
|
+
this.unencryptedLogs.push(new CountedLog(log, counter));
|
|
363
|
+
this.logsCache.addUnencryptedLog(log);
|
|
359
364
|
const text = log.toHumanReadable();
|
|
360
365
|
this.log.verbose(`Emitted unencrypted log: "${text.length > 100 ? text.slice(0, 100) + '...' : text}"`);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Emit a contract class unencrypted log.
|
|
370
|
+
* This fn exists separately from emitUnencryptedLog because sha hashing the preimage
|
|
371
|
+
* is too large to compile (16,200 fields, 518,400 bytes) => the oracle hashes it.
|
|
372
|
+
* See private_context.nr
|
|
373
|
+
* @param log - The unencrypted log to be emitted.
|
|
374
|
+
*/
|
|
375
|
+
public override emitContractClassUnencryptedLog(log: UnencryptedL2Log, counter: number) {
|
|
376
|
+
this.unencryptedLogs.push(new CountedLog(log, counter));
|
|
377
|
+
this.logsCache.addUnencryptedLog(log);
|
|
378
|
+
const text = log.toHumanReadable();
|
|
379
|
+
this.log.verbose(
|
|
380
|
+
`Emitted unencrypted log from ContractClassRegisterer: "${
|
|
381
|
+
text.length > 100 ? text.slice(0, 100) + '...' : text
|
|
382
|
+
}"`,
|
|
383
|
+
);
|
|
361
384
|
return Fr.fromBuffer(log.hash());
|
|
362
385
|
}
|
|
363
386
|
|
|
@@ -419,6 +442,7 @@ export class ClientExecutionContext extends ViewDataOracle {
|
|
|
419
442
|
this.authWitnesses,
|
|
420
443
|
this.packedValuesCache,
|
|
421
444
|
this.noteCache,
|
|
445
|
+
this.logsCache,
|
|
422
446
|
this.db,
|
|
423
447
|
this.node,
|
|
424
448
|
sideEffectCounter,
|
package/src/client/db_oracle.ts
CHANGED
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
type PublicDataWitness,
|
|
7
7
|
} from '@aztec/circuit-types';
|
|
8
8
|
import { type CompleteAddress, type Header } from '@aztec/circuits.js';
|
|
9
|
-
import { type
|
|
9
|
+
import { type FunctionArtifact, type FunctionSelector } from '@aztec/foundation/abi';
|
|
10
10
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
11
|
-
import { type Fr } from '@aztec/foundation/fields';
|
|
11
|
+
import { type Fr, type Point } from '@aztec/foundation/fields';
|
|
12
12
|
import { type ContractInstance } from '@aztec/types/contracts';
|
|
13
13
|
|
|
14
14
|
import { type NoteData, type NullifierKeys } from '../acvm/index.js';
|
|
@@ -64,6 +64,14 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
64
64
|
*/
|
|
65
65
|
popCapsule(): Promise<Fr[]>;
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Gets public keys for an address.
|
|
69
|
+
* @param The address to look up
|
|
70
|
+
* @returns The public keys for a specific address
|
|
71
|
+
* TODO(#5834): Replace with `getCompleteAddress`.
|
|
72
|
+
*/
|
|
73
|
+
getPublicKeysForAddress(address: AztecAddress): Promise<Point[]>;
|
|
74
|
+
|
|
67
75
|
/**
|
|
68
76
|
* Retrieve nullifier keys associated with a specific account and app/contract address.
|
|
69
77
|
*
|
|
@@ -94,10 +102,7 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
94
102
|
* @param selector - The corresponding function selector.
|
|
95
103
|
* @returns A Promise that resolves to a FunctionArtifact object.
|
|
96
104
|
*/
|
|
97
|
-
getFunctionArtifact(
|
|
98
|
-
contractAddress: AztecAddress,
|
|
99
|
-
selector: FunctionSelector,
|
|
100
|
-
): Promise<FunctionArtifactWithDebugMetadata>;
|
|
105
|
+
getFunctionArtifact(contractAddress: AztecAddress, selector: FunctionSelector): Promise<FunctionArtifact>;
|
|
101
106
|
|
|
102
107
|
/**
|
|
103
108
|
* Retrieves the artifact of a specified function within a given contract.
|
|
@@ -107,10 +112,7 @@ export interface DBOracle extends CommitmentsDB {
|
|
|
107
112
|
* @param functionName - The name of the function.
|
|
108
113
|
* @returns The corresponding function's artifact as an object.
|
|
109
114
|
*/
|
|
110
|
-
getFunctionArtifactByName(
|
|
111
|
-
contractAddress: AztecAddress,
|
|
112
|
-
functionName: string,
|
|
113
|
-
): Promise<FunctionArtifactWithDebugMetadata | undefined>;
|
|
115
|
+
getFunctionArtifactByName(contractAddress: AztecAddress, functionName: string): Promise<FunctionArtifact | undefined>;
|
|
114
116
|
|
|
115
117
|
/**
|
|
116
118
|
* Gets the index of a nullifier in the nullifier tree.
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { type EncryptedFunctionL2Logs, type Note, type UnencryptedFunctionL2Logs } from '@aztec/circuit-types';
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
type
|
|
5
|
-
type
|
|
6
|
-
|
|
2
|
+
EncryptedFunctionL2Logs,
|
|
3
|
+
type EncryptedL2Log,
|
|
4
|
+
type Note,
|
|
5
|
+
UnencryptedFunctionL2Logs,
|
|
6
|
+
type UnencryptedL2Log,
|
|
7
|
+
} from '@aztec/circuit-types';
|
|
8
|
+
import { type IsEmpty, type PrivateCallStackItem, type PublicCallRequest, sortByCounter } from '@aztec/circuits.js';
|
|
7
9
|
import { type Fr } from '@aztec/foundation/fields';
|
|
8
10
|
|
|
9
11
|
import { type ACVMField } from '../acvm/index.js';
|
|
@@ -20,9 +22,12 @@ export interface NoteAndSlot {
|
|
|
20
22
|
noteTypeId: Fr;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
|
-
export
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
export class CountedLog<TLog extends UnencryptedL2Log | EncryptedL2Log> implements IsEmpty {
|
|
26
|
+
constructor(public log: TLog, public counter: number) {}
|
|
27
|
+
|
|
28
|
+
isEmpty(): boolean {
|
|
29
|
+
return !this.log.data.length && !this.counter;
|
|
30
|
+
}
|
|
26
31
|
}
|
|
27
32
|
|
|
28
33
|
/**
|
|
@@ -39,11 +44,12 @@ export interface ExecutionResult {
|
|
|
39
44
|
// Needed for the verifier (kernel)
|
|
40
45
|
/** The call stack item. */
|
|
41
46
|
callStackItem: PrivateCallStackItem;
|
|
42
|
-
/**
|
|
43
|
-
|
|
47
|
+
/** Mapping of note hash to its index in the note hash tree. Used for building hints for note hash read requests. */
|
|
48
|
+
noteHashLeafIndexMap: Map<bigint, bigint>;
|
|
44
49
|
/** The notes created in the executed function. */
|
|
45
50
|
newNotes: NoteAndSlot[];
|
|
46
|
-
|
|
51
|
+
/** Mapping of note hash counter to the counter of its nullifier. */
|
|
52
|
+
nullifiedNoteHashCounters: Map<number, number>;
|
|
47
53
|
/** The raw return values of the executed function. */
|
|
48
54
|
returnValues: Fr[];
|
|
49
55
|
/** The nested executions. */
|
|
@@ -54,19 +60,24 @@ export interface ExecutionResult {
|
|
|
54
60
|
* Encrypted logs emitted during execution of this function call.
|
|
55
61
|
* Note: These are preimages to `encryptedLogsHashes`.
|
|
56
62
|
*/
|
|
57
|
-
encryptedLogs:
|
|
63
|
+
encryptedLogs: CountedLog<EncryptedL2Log>[];
|
|
58
64
|
/**
|
|
59
65
|
* Unencrypted logs emitted during execution of this function call.
|
|
60
66
|
* Note: These are preimages to `unencryptedLogsHashes`.
|
|
61
67
|
*/
|
|
62
|
-
unencryptedLogs:
|
|
68
|
+
unencryptedLogs: CountedLog<UnencryptedL2Log>[];
|
|
63
69
|
}
|
|
64
70
|
|
|
65
|
-
export function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
export function collectNoteHashLeafIndexMap(execResult: ExecutionResult, accum: Map<bigint, bigint> = new Map()) {
|
|
72
|
+
execResult.noteHashLeafIndexMap.forEach((value, key) => accum.set(key, value));
|
|
73
|
+
execResult.nestedExecutions.forEach(nested => collectNoteHashLeafIndexMap(nested, accum));
|
|
74
|
+
return accum;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export function collectNullifiedNoteHashCounters(execResult: ExecutionResult, accum: Map<number, number> = new Map()) {
|
|
78
|
+
execResult.nullifiedNoteHashCounters.forEach((value, key) => accum.set(key, value));
|
|
79
|
+
execResult.nestedExecutions.forEach(nested => collectNullifiedNoteHashCounters(nested, accum));
|
|
80
|
+
return accum;
|
|
70
81
|
}
|
|
71
82
|
|
|
72
83
|
/**
|
|
@@ -74,9 +85,19 @@ export function collectNullifiedNoteHashCounters(execResult: ExecutionResult): N
|
|
|
74
85
|
* @param execResult - The topmost execution result.
|
|
75
86
|
* @returns All encrypted logs.
|
|
76
87
|
*/
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
88
|
+
function collectEncryptedLogs(execResult: ExecutionResult): CountedLog<EncryptedL2Log>[] {
|
|
89
|
+
return [execResult.encryptedLogs, ...[...execResult.nestedExecutions].flatMap(collectEncryptedLogs)].flat();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Collect all encrypted logs across all nested executions and sorts by counter.
|
|
94
|
+
* @param execResult - The topmost execution result.
|
|
95
|
+
* @returns All encrypted logs.
|
|
96
|
+
*/
|
|
97
|
+
export function collectSortedEncryptedLogs(execResult: ExecutionResult): EncryptedFunctionL2Logs {
|
|
98
|
+
const allLogs = collectEncryptedLogs(execResult);
|
|
99
|
+
const sortedLogs = sortByCounter(allLogs);
|
|
100
|
+
return new EncryptedFunctionL2Logs(sortedLogs.map(l => l.log));
|
|
80
101
|
}
|
|
81
102
|
|
|
82
103
|
/**
|
|
@@ -84,9 +105,19 @@ export function collectEncryptedLogs(execResult: ExecutionResult): EncryptedFunc
|
|
|
84
105
|
* @param execResult - The topmost execution result.
|
|
85
106
|
* @returns All unencrypted logs.
|
|
86
107
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
108
|
+
function collectUnencryptedLogs(execResult: ExecutionResult): CountedLog<UnencryptedL2Log>[] {
|
|
109
|
+
return [execResult.unencryptedLogs, ...[...execResult.nestedExecutions].flatMap(collectUnencryptedLogs)].flat();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Collect all unencrypted logs across all nested executions and sorts by counter.
|
|
114
|
+
* @param execResult - The topmost execution result.
|
|
115
|
+
* @returns All unencrypted logs.
|
|
116
|
+
*/
|
|
117
|
+
export function collectSortedUnencryptedLogs(execResult: ExecutionResult): UnencryptedFunctionL2Logs {
|
|
118
|
+
const allLogs = collectUnencryptedLogs(execResult);
|
|
119
|
+
const sortedLogs = sortByCounter(allLogs);
|
|
120
|
+
return new UnencryptedFunctionL2Logs(sortedLogs.map(l => l.log));
|
|
90
121
|
}
|
|
91
122
|
|
|
92
123
|
/**
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type EncryptedL2Log, type UnencryptedL2Log } from '@aztec/circuit-types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Log data that's accessible by all the function calls in an execution.
|
|
5
|
+
* This class exists to:
|
|
6
|
+
* 1. Keep track of logs emitted through nested calls in the correct order.
|
|
7
|
+
* 2. TODO(1641): Remove encrypted logs based on notes nullified in the same scope.
|
|
8
|
+
*/
|
|
9
|
+
export class LogsCache {
|
|
10
|
+
/**
|
|
11
|
+
* Logs notes created in this transaction.
|
|
12
|
+
*/
|
|
13
|
+
private encryptedLogs: EncryptedL2Log[] = [];
|
|
14
|
+
private unencryptedLogs: UnencryptedL2Log[] = [];
|
|
15
|
+
|
|
16
|
+
// TODO Separate encrypted logs linked to note hashes and arbitrary logs:
|
|
17
|
+
|
|
18
|
+
// Maps from note hash to encrypted log - useful for removing transient logs
|
|
19
|
+
// private encryptedLogsLinkedToNotes: Map<bigint, EncryptedL2Log> = new Map();
|
|
20
|
+
|
|
21
|
+
// /**
|
|
22
|
+
// * Remove the encrypted log for a nullified note.
|
|
23
|
+
// * This fn should only be called if the note's innerNoteHash != 0.
|
|
24
|
+
// * @param noteHashCounter - Side effect counter of the note.
|
|
25
|
+
// */
|
|
26
|
+
// public nullifyNote(noteHashCounter: Fr) {
|
|
27
|
+
// // Find and remove the matching new note if the emitted innerNoteHash is not empty.
|
|
28
|
+
// const log = this.encryptedLogsLinkedToNotes.get(noteHashCounter.toBigInt()) ?? false;
|
|
29
|
+
// // TODO: throw here? Will the log always be here?
|
|
30
|
+
// if (!log) {
|
|
31
|
+
// throw new Error('Attempt to remove a pending note log that does not exist.');
|
|
32
|
+
// }
|
|
33
|
+
// this.encryptedLogsLinkedToNotes.delete(noteHashCounter.toBigInt());
|
|
34
|
+
// }
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Add a new encrypted log to cache.
|
|
38
|
+
* @param log - New log created during execution.
|
|
39
|
+
*/
|
|
40
|
+
public addEncryptedLog(log: EncryptedL2Log) {
|
|
41
|
+
this.encryptedLogs.push(log);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Add a new unencrypted log to cache.
|
|
46
|
+
* @param log - New log created during execution.
|
|
47
|
+
*/
|
|
48
|
+
public addUnencryptedLog(log: UnencryptedL2Log) {
|
|
49
|
+
this.unencryptedLogs.push(log);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Return the encrypted logs.
|
|
54
|
+
*/
|
|
55
|
+
public getEncryptedLogs() {
|
|
56
|
+
return this.encryptedLogs;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Return the encrypted logs.
|
|
61
|
+
*/
|
|
62
|
+
public getUnencryptedLogs() {
|
|
63
|
+
return this.unencryptedLogs;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type FunctionData, PrivateCallStackItem, PrivateCircuitPublicInputs } from '@aztec/circuits.js';
|
|
2
|
-
import { type
|
|
2
|
+
import { type FunctionArtifact } from '@aztec/foundation/abi';
|
|
3
3
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
4
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
5
4
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
6
5
|
|
|
7
6
|
import { witnessMapToFields } from '../acvm/deserialize.js';
|
|
@@ -16,7 +15,7 @@ import { AcirSimulator } from './simulator.js';
|
|
|
16
15
|
*/
|
|
17
16
|
export async function executePrivateFunction(
|
|
18
17
|
context: ClientExecutionContext,
|
|
19
|
-
artifact:
|
|
18
|
+
artifact: FunctionArtifact,
|
|
20
19
|
contractAddress: AztecAddress,
|
|
21
20
|
functionData: FunctionData,
|
|
22
21
|
log = createDebugLogger('aztec:simulator:secret_execution'),
|
|
@@ -45,17 +44,12 @@ export async function executePrivateFunction(
|
|
|
45
44
|
|
|
46
45
|
const encryptedLogs = context.getEncryptedLogs();
|
|
47
46
|
const unencryptedLogs = context.getUnencryptedLogs();
|
|
48
|
-
// TODO(https://github.com/AztecProtocol/aztec-packages/issues/1165) --> set this in Noir
|
|
49
|
-
publicInputs.encryptedLogPreimagesLength = new Fr(encryptedLogs.getSerializedLength());
|
|
50
|
-
publicInputs.unencryptedLogPreimagesLength = new Fr(unencryptedLogs.getSerializedLength());
|
|
51
47
|
|
|
52
48
|
const callStackItem = new PrivateCallStackItem(contractAddress, functionData, publicInputs);
|
|
53
49
|
|
|
54
50
|
const rawReturnValues = await context.unpackReturns(publicInputs.returnsHash);
|
|
55
51
|
|
|
56
|
-
const
|
|
57
|
-
publicInputs.noteHashReadRequests,
|
|
58
|
-
);
|
|
52
|
+
const noteHashLeafIndexMap = context.getNoteHashLeafIndexMap();
|
|
59
53
|
const newNotes = context.getNewNotes();
|
|
60
54
|
const nullifiedNoteHashCounters = context.getNullifiedNoteHashCounters();
|
|
61
55
|
const nestedExecutions = context.getNestedExecutions();
|
|
@@ -68,7 +62,7 @@ export async function executePrivateFunction(
|
|
|
68
62
|
partialWitness,
|
|
69
63
|
callStackItem,
|
|
70
64
|
returnValues: rawReturnValues,
|
|
71
|
-
|
|
65
|
+
noteHashLeafIndexMap,
|
|
72
66
|
newNotes,
|
|
73
67
|
nullifiedNoteHashCounters,
|
|
74
68
|
vk: Buffer.from(artifact.verificationKey!, 'hex'),
|
package/src/client/simulator.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type AztecNode, type FunctionCall, type Note, type TxExecutionRequest }
|
|
|
2
2
|
import { CallContext, FunctionData } from '@aztec/circuits.js';
|
|
3
3
|
import {
|
|
4
4
|
type ArrayType,
|
|
5
|
-
type
|
|
5
|
+
type FunctionArtifact,
|
|
6
6
|
FunctionSelector,
|
|
7
7
|
FunctionType,
|
|
8
8
|
encodeArguments,
|
|
@@ -19,6 +19,7 @@ import { ClientExecutionContext } from './client_execution_context.js';
|
|
|
19
19
|
import { type DBOracle } from './db_oracle.js';
|
|
20
20
|
import { ExecutionNoteCache } from './execution_note_cache.js';
|
|
21
21
|
import { type ExecutionResult } from './execution_result.js';
|
|
22
|
+
import { LogsCache } from './logs_cache.js';
|
|
22
23
|
import { executePrivateFunction } from './private_execution.js';
|
|
23
24
|
import { executeUnconstrainedFunction } from './unconstrained_execution.js';
|
|
24
25
|
import { ViewDataOracle } from './view_data_oracle.js';
|
|
@@ -64,7 +65,7 @@ export class AcirSimulator {
|
|
|
64
65
|
*/
|
|
65
66
|
public async run(
|
|
66
67
|
request: TxExecutionRequest,
|
|
67
|
-
entryPointArtifact:
|
|
68
|
+
entryPointArtifact: FunctionArtifact,
|
|
68
69
|
contractAddress: AztecAddress,
|
|
69
70
|
msgSender = AztecAddress.ZERO,
|
|
70
71
|
): Promise<ExecutionResult> {
|
|
@@ -100,6 +101,7 @@ export class AcirSimulator {
|
|
|
100
101
|
request.authWitnesses,
|
|
101
102
|
PackedValuesCache.create(request.argsOfCalls),
|
|
102
103
|
new ExecutionNoteCache(),
|
|
104
|
+
new LogsCache(),
|
|
103
105
|
this.db,
|
|
104
106
|
this.node,
|
|
105
107
|
startSideEffectCounter,
|
|
@@ -127,7 +129,7 @@ export class AcirSimulator {
|
|
|
127
129
|
*/
|
|
128
130
|
public async runUnconstrained(
|
|
129
131
|
request: FunctionCall,
|
|
130
|
-
entryPointArtifact:
|
|
132
|
+
entryPointArtifact: FunctionArtifact,
|
|
131
133
|
contractAddress: AztecAddress,
|
|
132
134
|
) {
|
|
133
135
|
if (entryPointArtifact.functionType !== FunctionType.UNCONSTRAINED) {
|
|
@@ -165,7 +167,7 @@ export class AcirSimulator {
|
|
|
165
167
|
noteTypeId: Fr,
|
|
166
168
|
note: Note,
|
|
167
169
|
) {
|
|
168
|
-
const artifact:
|
|
170
|
+
const artifact: FunctionArtifact | undefined = await this.db.getFunctionArtifactByName(
|
|
169
171
|
contractAddress,
|
|
170
172
|
'compute_note_hash_and_nullifier',
|
|
171
173
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FunctionData } from '@aztec/circuits.js';
|
|
2
|
-
import { type DecodedReturn, type
|
|
2
|
+
import { type DecodedReturn, type FunctionArtifact, decodeReturnValues } from '@aztec/foundation/abi';
|
|
3
3
|
import { type AztecAddress } from '@aztec/foundation/aztec-address';
|
|
4
4
|
import { type Fr } from '@aztec/foundation/fields';
|
|
5
5
|
import { createDebugLogger } from '@aztec/foundation/log';
|
|
@@ -16,7 +16,7 @@ import { type ViewDataOracle } from './view_data_oracle.js';
|
|
|
16
16
|
*/
|
|
17
17
|
export async function executeUnconstrainedFunction(
|
|
18
18
|
oracle: ViewDataOracle,
|
|
19
|
-
artifact:
|
|
19
|
+
artifact: FunctionArtifact,
|
|
20
20
|
contractAddress: AztecAddress,
|
|
21
21
|
functionData: FunctionData,
|
|
22
22
|
args: Fr[],
|
|
@@ -166,6 +166,16 @@ export class ViewDataOracle extends TypedOracle {
|
|
|
166
166
|
return this.db.popCapsule();
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Gets public keys for an address.
|
|
171
|
+
* @param The address to look up
|
|
172
|
+
* @returns The public keys for a specific address
|
|
173
|
+
* TODO(#5834): Replace with `getCompleteAddress`.
|
|
174
|
+
*/
|
|
175
|
+
public override getPublicKeysForAddress(address: AztecAddress) {
|
|
176
|
+
return this.db.getPublicKeysForAddress(address);
|
|
177
|
+
}
|
|
178
|
+
|
|
169
179
|
/**
|
|
170
180
|
* Gets some notes for a contract address and storage slot.
|
|
171
181
|
* Returns a flattened array containing filtered notes.
|
package/src/mocks/fixtures.ts
CHANGED
|
@@ -116,6 +116,8 @@ export class PublicExecutionResultBuilder {
|
|
|
116
116
|
contractStorageReads: [],
|
|
117
117
|
unencryptedLogsHashes: [],
|
|
118
118
|
unencryptedLogs: UnencryptedFunctionL2Logs.empty(),
|
|
119
|
+
unencryptedLogPreimagesLength: new Fr(4n), // empty logs have len 4
|
|
120
|
+
allUnencryptedLogs: UnencryptedFunctionL2Logs.empty(),
|
|
119
121
|
startSideEffectCounter: Fr.ZERO,
|
|
120
122
|
endSideEffectCounter: Fr.ZERO,
|
|
121
123
|
reverted: this._reverted,
|
|
@@ -246,8 +246,10 @@ export abstract class AbstractPhaseManager {
|
|
|
246
246
|
while (executionStack.length) {
|
|
247
247
|
const current = executionStack.pop()!;
|
|
248
248
|
const isExecutionRequest = !isPublicExecutionResult(current);
|
|
249
|
+
// TODO(6052): Extract correct new counter from nested calls
|
|
249
250
|
const sideEffectCounter = lastSideEffectCounter(tx) + 1;
|
|
250
|
-
const availableGas = this.getAvailableGas(tx,
|
|
251
|
+
const availableGas = this.getAvailableGas(tx, kernelOutput);
|
|
252
|
+
const pendingNullifiers = this.getSiloedPendingNullifiers(kernelOutput);
|
|
251
253
|
|
|
252
254
|
const result = isExecutionRequest
|
|
253
255
|
? await this.publicExecutor.simulate(
|
|
@@ -255,6 +257,7 @@ export abstract class AbstractPhaseManager {
|
|
|
255
257
|
this.globalVariables,
|
|
256
258
|
availableGas,
|
|
257
259
|
tx.data.constants.txContext,
|
|
260
|
+
pendingNullifiers,
|
|
258
261
|
transactionFee,
|
|
259
262
|
sideEffectCounter,
|
|
260
263
|
)
|
|
@@ -270,7 +273,9 @@ export abstract class AbstractPhaseManager {
|
|
|
270
273
|
throw result.revertReason;
|
|
271
274
|
}
|
|
272
275
|
|
|
273
|
-
|
|
276
|
+
if (isExecutionRequest) {
|
|
277
|
+
newUnencryptedFunctionLogs.push(result.allUnencryptedLogs);
|
|
278
|
+
}
|
|
274
279
|
|
|
275
280
|
this.log.debug(
|
|
276
281
|
`Running public kernel circuit for ${result.execution.contractAddress.toString()}:${functionSelector}`,
|
|
@@ -320,6 +325,11 @@ export abstract class AbstractPhaseManager {
|
|
|
320
325
|
return [publicKernelInputs, kernelOutput, kernelProof, newUnencryptedFunctionLogs, undefined, returns];
|
|
321
326
|
}
|
|
322
327
|
|
|
328
|
+
/** Returns all pending private and public nullifiers. */
|
|
329
|
+
private getSiloedPendingNullifiers(ko: PublicKernelCircuitPublicInputs) {
|
|
330
|
+
return [...ko.end.newNullifiers, ...ko.endNonRevertibleData.newNullifiers].filter(n => !n.isEmpty());
|
|
331
|
+
}
|
|
332
|
+
|
|
323
333
|
protected getAvailableGas(tx: Tx, previousPublicKernelOutput: PublicKernelCircuitPublicInputs) {
|
|
324
334
|
return tx.data.constants.txContext.gasSettings
|
|
325
335
|
.getLimits() // No need to subtract teardown limits since they are already included in end.gasUsed
|
|
@@ -382,8 +392,6 @@ export abstract class AbstractPhaseManager {
|
|
|
382
392
|
MAX_PUBLIC_CALL_STACK_LENGTH_PER_CALL,
|
|
383
393
|
);
|
|
384
394
|
|
|
385
|
-
const unencryptedLogPreimagesLength = new Fr(result.unencryptedLogs.getSerializedLength());
|
|
386
|
-
|
|
387
395
|
const publicCircuitPublicInputs = PublicCircuitPublicInputs.from({
|
|
388
396
|
callContext: result.execution.callContext,
|
|
389
397
|
proverAddress: AztecAddress.ZERO,
|
|
@@ -420,7 +428,7 @@ export abstract class AbstractPhaseManager {
|
|
|
420
428
|
SideEffect.empty(),
|
|
421
429
|
MAX_UNENCRYPTED_LOGS_PER_CALL,
|
|
422
430
|
),
|
|
423
|
-
unencryptedLogPreimagesLength,
|
|
431
|
+
unencryptedLogPreimagesLength: result.unencryptedLogPreimagesLength,
|
|
424
432
|
historicalHeader: this.historicalHeader,
|
|
425
433
|
globalVariables: this.globalVariables,
|
|
426
434
|
startGasLeft: Gas.from(result.startGasLeft),
|
package/src/public/execution.ts
CHANGED
|
@@ -54,6 +54,15 @@ export interface PublicExecutionResult {
|
|
|
54
54
|
* Note: These are preimages to `unencryptedLogsHashes`.
|
|
55
55
|
*/
|
|
56
56
|
unencryptedLogs: UnencryptedFunctionL2Logs;
|
|
57
|
+
/**
|
|
58
|
+
* Length of the unencrypted log preimages emitted in this function call.
|
|
59
|
+
*/
|
|
60
|
+
unencryptedLogPreimagesLength: Fr;
|
|
61
|
+
/**
|
|
62
|
+
* Unencrypted logs emitted during this call AND any nested calls.
|
|
63
|
+
* Useful for maintaining correct ordering in ts.
|
|
64
|
+
*/
|
|
65
|
+
allUnencryptedLogs: UnencryptedFunctionL2Logs;
|
|
57
66
|
/**
|
|
58
67
|
* Whether the execution reverted.
|
|
59
68
|
*/
|