@aztec/simulator 0.70.0 → 0.72.1
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/deserialize.d.ts +9 -0
- package/dest/acvm/deserialize.d.ts.map +1 -1
- package/dest/acvm/deserialize.js +12 -1
- package/dest/acvm/oracle/oracle.d.ts +5 -10
- package/dest/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/acvm/oracle/oracle.js +25 -32
- 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 +14 -8
- package/dest/avm/errors.d.ts +6 -0
- package/dest/avm/errors.d.ts.map +1 -1
- package/dest/avm/errors.js +10 -1
- package/dest/avm/journal/journal.d.ts +2 -3
- package/dest/avm/journal/journal.d.ts.map +1 -1
- package/dest/avm/journal/journal.js +5 -6
- package/dest/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/avm/opcodes/accrued_substate.js +3 -2
- package/dest/avm/opcodes/conversion.d.ts.map +1 -1
- package/dest/avm/opcodes/conversion.js +10 -7
- package/dest/avm/opcodes/ec_add.js +2 -2
- package/dest/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/avm/opcodes/memory.js +9 -5
- package/dest/avm/opcodes/multi_scalar_mul.d.ts.map +1 -1
- package/dest/avm/opcodes/multi_scalar_mul.js +9 -7
- package/dest/client/client_execution_context.d.ts +1 -5
- package/dest/client/client_execution_context.d.ts.map +1 -1
- package/dest/client/client_execution_context.js +3 -9
- package/dest/client/db_oracle.d.ts +43 -12
- package/dest/client/db_oracle.d.ts.map +1 -1
- package/dest/client/private_execution.js +2 -2
- package/dest/client/simulator.js +2 -2
- package/dest/client/unconstrained_execution.d.ts.map +1 -1
- package/dest/client/unconstrained_execution.js +5 -2
- package/dest/client/view_data_oracle.d.ts +5 -2
- package/dest/client/view_data_oracle.d.ts.map +1 -1
- package/dest/client/view_data_oracle.js +32 -11
- package/dest/public/enqueued_call_side_effect_trace.d.ts +7 -10
- package/dest/public/enqueued_call_side_effect_trace.d.ts.map +1 -1
- package/dest/public/enqueued_call_side_effect_trace.js +21 -28
- package/dest/public/execution.d.ts +7 -25
- package/dest/public/execution.d.ts.map +1 -1
- package/dest/public/execution.js +1 -1
- package/dest/public/fixtures/index.d.ts +3 -3
- package/dest/public/fixtures/index.d.ts.map +1 -1
- package/dest/public/fixtures/index.js +52 -50
- package/dest/public/public_processor.d.ts +5 -6
- package/dest/public/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor.js +17 -18
- package/dest/public/public_tx_context.js +2 -2
- package/dest/public/public_tx_simulator.d.ts +1 -1
- package/dest/public/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator.js +5 -8
- package/dest/public/side_effect_trace_interface.d.ts +3 -4
- package/dest/public/side_effect_trace_interface.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/acvm/deserialize.ts +12 -0
- package/src/acvm/oracle/oracle.ts +70 -34
- package/src/acvm/oracle/typed_oracle.ts +25 -8
- package/src/avm/errors.ts +10 -0
- package/src/avm/journal/journal.ts +4 -5
- package/src/avm/opcodes/accrued_substate.ts +2 -1
- package/src/avm/opcodes/conversion.ts +15 -6
- package/src/avm/opcodes/ec_add.ts +1 -1
- package/src/avm/opcodes/memory.ts +8 -4
- package/src/avm/opcodes/multi_scalar_mul.ts +8 -6
- package/src/client/client_execution_context.ts +2 -9
- package/src/client/db_oracle.ts +55 -12
- package/src/client/private_execution.ts +1 -1
- package/src/client/simulator.ts +1 -1
- package/src/client/unconstrained_execution.ts +4 -1
- package/src/client/view_data_oracle.ts +44 -14
- package/src/public/enqueued_call_side_effect_trace.ts +22 -34
- package/src/public/execution.ts +7 -31
- package/src/public/fixtures/index.ts +66 -66
- package/src/public/public_processor.ts +21 -19
- package/src/public/public_tx_context.ts +1 -1
- package/src/public/public_tx_simulator.ts +3 -10
- package/src/public/side_effect_trace_interface.ts +3 -3
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { UnencryptedFunctionL2Logs, UnencryptedL2Log } from '@aztec/circuit-types';
|
|
2
1
|
import {
|
|
3
2
|
AvmAccumulatedData,
|
|
4
3
|
AvmAppendTreeHint,
|
|
@@ -19,15 +18,14 @@ import {
|
|
|
19
18
|
type GlobalVariables,
|
|
20
19
|
L1_TO_L2_MSG_TREE_HEIGHT,
|
|
21
20
|
L2ToL1Message,
|
|
22
|
-
LogHash,
|
|
23
21
|
MAX_ENQUEUED_CALLS_PER_TX,
|
|
24
22
|
MAX_L2_TO_L1_MSGS_PER_TX,
|
|
25
23
|
MAX_NOTE_HASHES_PER_TX,
|
|
26
24
|
MAX_NULLIFIERS_PER_TX,
|
|
27
25
|
MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS,
|
|
28
26
|
MAX_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
27
|
+
MAX_PUBLIC_LOGS_PER_TX,
|
|
29
28
|
MAX_TOTAL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
30
|
-
MAX_UNENCRYPTED_LOGS_PER_TX,
|
|
31
29
|
NOTE_HASH_TREE_HEIGHT,
|
|
32
30
|
NULLIFIER_TREE_HEIGHT,
|
|
33
31
|
NoteHash,
|
|
@@ -35,14 +33,15 @@ import {
|
|
|
35
33
|
NullifierLeafPreimage,
|
|
36
34
|
PROTOCOL_PUBLIC_DATA_UPDATE_REQUESTS_PER_TX,
|
|
37
35
|
PUBLIC_DATA_TREE_HEIGHT,
|
|
36
|
+
PUBLIC_LOG_DATA_SIZE_IN_FIELDS,
|
|
38
37
|
PrivateToAvmAccumulatedData,
|
|
39
38
|
PrivateToAvmAccumulatedDataArrayLengths,
|
|
40
39
|
PublicCallRequest,
|
|
41
40
|
PublicDataTreeLeafPreimage,
|
|
42
41
|
PublicDataUpdateRequest,
|
|
43
42
|
PublicDataWrite,
|
|
43
|
+
PublicLog,
|
|
44
44
|
ScopedL2ToL1Message,
|
|
45
|
-
ScopedLogHash,
|
|
46
45
|
SerializableContractInstance,
|
|
47
46
|
type TreeSnapshots,
|
|
48
47
|
} from '@aztec/circuits.js';
|
|
@@ -79,8 +78,7 @@ export type SideEffects = {
|
|
|
79
78
|
nullifiers: Nullifier[];
|
|
80
79
|
l2ToL1Msgs: ScopedL2ToL1Message[];
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
unencryptedLogsHashes: ScopedLogHash[];
|
|
81
|
+
publicLogs: PublicLog[];
|
|
84
82
|
};
|
|
85
83
|
|
|
86
84
|
export class SideEffectArrayLengths {
|
|
@@ -90,7 +88,7 @@ export class SideEffectArrayLengths {
|
|
|
90
88
|
public readonly noteHashes: number,
|
|
91
89
|
public readonly nullifiers: number,
|
|
92
90
|
public readonly l2ToL1Msgs: number,
|
|
93
|
-
public readonly
|
|
91
|
+
public readonly publicLogs: number,
|
|
94
92
|
) {}
|
|
95
93
|
|
|
96
94
|
static empty() {
|
|
@@ -115,8 +113,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
115
113
|
private noteHashes: NoteHash[] = [];
|
|
116
114
|
private nullifiers: Nullifier[] = [];
|
|
117
115
|
private l2ToL1Messages: ScopedL2ToL1Message[] = [];
|
|
118
|
-
private
|
|
119
|
-
private unencryptedLogsHashes: ScopedLogHash[] = [];
|
|
116
|
+
private publicLogs: PublicLog[] = [];
|
|
120
117
|
|
|
121
118
|
private avmCircuitHints: AvmExecutionHints;
|
|
122
119
|
|
|
@@ -147,7 +144,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
147
144
|
this.previousSideEffectArrayLengths.noteHashes + this.noteHashes.length,
|
|
148
145
|
this.previousSideEffectArrayLengths.nullifiers + this.nullifiers.length,
|
|
149
146
|
this.previousSideEffectArrayLengths.l2ToL1Msgs + this.l2ToL1Messages.length,
|
|
150
|
-
this.previousSideEffectArrayLengths.
|
|
147
|
+
this.previousSideEffectArrayLengths.publicLogs + this.publicLogs.length,
|
|
151
148
|
),
|
|
152
149
|
this.gotBytecodeFromClassIds.fork(),
|
|
153
150
|
);
|
|
@@ -169,8 +166,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
169
166
|
this.noteHashes.push(...forkedTrace.noteHashes);
|
|
170
167
|
this.nullifiers.push(...forkedTrace.nullifiers);
|
|
171
168
|
this.l2ToL1Messages.push(...forkedTrace.l2ToL1Messages);
|
|
172
|
-
this.
|
|
173
|
-
this.unencryptedLogsHashes.push(...forkedTrace.unencryptedLogsHashes);
|
|
169
|
+
this.publicLogs.push(...forkedTrace.publicLogs);
|
|
174
170
|
}
|
|
175
171
|
this.mergeHints(forkedTrace);
|
|
176
172
|
}
|
|
@@ -359,23 +355,17 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
359
355
|
this.incrementSideEffectCounter();
|
|
360
356
|
}
|
|
361
357
|
|
|
362
|
-
public
|
|
363
|
-
if (
|
|
364
|
-
|
|
365
|
-
MAX_UNENCRYPTED_LOGS_PER_TX
|
|
366
|
-
) {
|
|
367
|
-
throw new SideEffectLimitReachedError('unencrypted log', MAX_UNENCRYPTED_LOGS_PER_TX);
|
|
358
|
+
public tracePublicLog(contractAddress: AztecAddress, log: Fr[]) {
|
|
359
|
+
if (this.publicLogs.length + this.previousSideEffectArrayLengths.publicLogs >= MAX_PUBLIC_LOGS_PER_TX) {
|
|
360
|
+
throw new SideEffectLimitReachedError('public log', MAX_PUBLIC_LOGS_PER_TX);
|
|
368
361
|
}
|
|
369
362
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
this.
|
|
376
|
-
new LogHash(basicLogHash, this.sideEffectCounter, new Fr(ulog.length + 4)).scope(contractAddress),
|
|
377
|
-
);
|
|
378
|
-
this.log.debug(`NEW_UNENCRYPTED_LOG cnt: ${this.sideEffectCounter}`);
|
|
363
|
+
if (log.length > PUBLIC_LOG_DATA_SIZE_IN_FIELDS) {
|
|
364
|
+
throw new Error(`Emitted public log is too large, max: ${PUBLIC_LOG_DATA_SIZE_IN_FIELDS}, passed: ${log.length}`);
|
|
365
|
+
}
|
|
366
|
+
const publicLog = new PublicLog(contractAddress, padArrayEnd(log, Fr.ZERO, PUBLIC_LOG_DATA_SIZE_IN_FIELDS));
|
|
367
|
+
this.publicLogs.push(publicLog);
|
|
368
|
+
this.log.debug(`NEW_PUBLIC_LOG cnt: ${this.sideEffectCounter}`);
|
|
379
369
|
this.incrementSideEffectCounter();
|
|
380
370
|
}
|
|
381
371
|
|
|
@@ -518,8 +508,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
518
508
|
noteHashes: this.noteHashes,
|
|
519
509
|
nullifiers: this.nullifiers,
|
|
520
510
|
l2ToL1Msgs: this.l2ToL1Messages,
|
|
521
|
-
|
|
522
|
-
unencryptedLogsHashes: this.unencryptedLogsHashes,
|
|
511
|
+
publicLogs: this.publicLogs,
|
|
523
512
|
};
|
|
524
513
|
}
|
|
525
514
|
|
|
@@ -541,8 +530,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
541
530
|
noteHashes: this.noteHashes,
|
|
542
531
|
nullifiers: this.nullifiers,
|
|
543
532
|
l2ToL1Messages: this.l2ToL1Messages,
|
|
544
|
-
|
|
545
|
-
unencryptedLogs: new UnencryptedFunctionL2Logs(this.unencryptedLogs),
|
|
533
|
+
publicLogs: this.publicLogs,
|
|
546
534
|
},
|
|
547
535
|
};
|
|
548
536
|
}
|
|
@@ -612,8 +600,8 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
612
600
|
throw new Error('Not implemented');
|
|
613
601
|
}
|
|
614
602
|
|
|
615
|
-
public
|
|
616
|
-
return this.
|
|
603
|
+
public getPublicLogs() {
|
|
604
|
+
return this.publicLogs;
|
|
617
605
|
}
|
|
618
606
|
|
|
619
607
|
public getAvmCircuitHints() {
|
|
@@ -633,7 +621,7 @@ export class PublicEnqueuedCallSideEffectTrace implements PublicSideEffectTraceI
|
|
|
633
621
|
MAX_NULLIFIERS_PER_TX,
|
|
634
622
|
),
|
|
635
623
|
padArrayEnd(this.l2ToL1Messages, ScopedL2ToL1Message.empty(), MAX_L2_TO_L1_MSGS_PER_TX),
|
|
636
|
-
padArrayEnd(this.
|
|
624
|
+
padArrayEnd(this.publicLogs, PublicLog.empty(), MAX_PUBLIC_LOGS_PER_TX),
|
|
637
625
|
padArrayEnd(
|
|
638
626
|
this.publicDataWrites.map(w => new PublicDataWrite(w.leafSlot, w.newValue)),
|
|
639
627
|
PublicDataWrite.empty(),
|
package/src/public/execution.ts
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type PublicExecutionRequest,
|
|
3
|
-
type SimulationError,
|
|
4
|
-
type UnencryptedFunctionL2Logs,
|
|
5
|
-
} from '@aztec/circuit-types';
|
|
1
|
+
import { type PublicExecutionRequest, type SimulationError } from '@aztec/circuit-types';
|
|
6
2
|
import {
|
|
7
3
|
type AvmExecutionHints,
|
|
8
4
|
type ContractStorageRead,
|
|
@@ -10,16 +6,15 @@ import {
|
|
|
10
6
|
type Fr,
|
|
11
7
|
Gas,
|
|
12
8
|
type L2ToL1Message,
|
|
13
|
-
type LogHash,
|
|
14
9
|
type NoteHash,
|
|
15
10
|
type Nullifier,
|
|
16
11
|
PublicCallStackItemCompressed,
|
|
17
12
|
type PublicDataUpdateRequest,
|
|
18
13
|
PublicInnerCallRequest,
|
|
14
|
+
type PublicLog,
|
|
19
15
|
type ReadRequest,
|
|
20
16
|
RevertCode,
|
|
21
17
|
type ScopedL2ToL1Message,
|
|
22
|
-
type ScopedLogHash,
|
|
23
18
|
type TreeLeafReadRequest,
|
|
24
19
|
} from '@aztec/circuits.js';
|
|
25
20
|
import { computeVarArgsHash } from '@aztec/circuits.js/hash';
|
|
@@ -33,16 +28,8 @@ export interface PublicSideEffects {
|
|
|
33
28
|
nullifiers: Nullifier[];
|
|
34
29
|
/** The new l2 to l1 messages generated to be inserted into the messages tree. */
|
|
35
30
|
l2ToL1Messages: ScopedL2ToL1Message[];
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
* Note: required as we don't track the counter anywhere else.
|
|
39
|
-
*/
|
|
40
|
-
unencryptedLogsHashes: ScopedLogHash[];
|
|
41
|
-
/**
|
|
42
|
-
* Unencrypted logs emitted during execution.
|
|
43
|
-
* Note: These are preimages to `unencryptedLogsHashes`.
|
|
44
|
-
*/
|
|
45
|
-
unencryptedLogs: UnencryptedFunctionL2Logs;
|
|
31
|
+
/** Public logs emitted during execution. */
|
|
32
|
+
publicLogs: PublicLog[];
|
|
46
33
|
}
|
|
47
34
|
|
|
48
35
|
export interface EnqueuedPublicCallExecutionResult {
|
|
@@ -124,21 +111,10 @@ export interface PublicFunctionCallResult {
|
|
|
124
111
|
/** L1 to L2 message read requests emitted in this call. */
|
|
125
112
|
l1ToL2MsgReadRequests: TreeLeafReadRequest[];
|
|
126
113
|
/**
|
|
127
|
-
* The
|
|
128
|
-
* Note:
|
|
114
|
+
* The public logs emitted in this call.
|
|
115
|
+
* Note: PublicLog has no counter - unsure if this is needed bc this struct is unused
|
|
129
116
|
*/
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Unencrypted logs emitted during execution of this function call.
|
|
133
|
-
* Note: These are preimages to `unencryptedLogsHashes`.
|
|
134
|
-
*/
|
|
135
|
-
unencryptedLogs: UnencryptedFunctionL2Logs;
|
|
136
|
-
/**
|
|
137
|
-
* Unencrypted logs emitted during this call AND any nested calls.
|
|
138
|
-
* Useful for maintaining correct ordering in ts.
|
|
139
|
-
*/
|
|
140
|
-
allUnencryptedLogs: UnencryptedFunctionL2Logs;
|
|
141
|
-
|
|
117
|
+
publicLogs: PublicLog[];
|
|
142
118
|
/** The requests to call public functions made by this call. */
|
|
143
119
|
publicCallRequests: PublicInnerCallRequest[];
|
|
144
120
|
/** The results of nested calls. */
|
|
@@ -32,7 +32,6 @@ import { AztecAddress } from '@aztec/foundation/aztec-address';
|
|
|
32
32
|
import { Fr, Point } from '@aztec/foundation/fields';
|
|
33
33
|
import { openTmpStore } from '@aztec/kv-store/lmdb';
|
|
34
34
|
import { AvmTestContractArtifact } from '@aztec/noir-contracts.js/AvmTest';
|
|
35
|
-
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
36
35
|
import { MerkleTrees } from '@aztec/world-state';
|
|
37
36
|
|
|
38
37
|
import { strict as assert } from 'assert';
|
|
@@ -53,25 +52,22 @@ export async function simulateAvmTestContractGenerateCircuitInputs(
|
|
|
53
52
|
teardownFunctionName?: string,
|
|
54
53
|
teardownArgs: Fr[] = [],
|
|
55
54
|
expectRevert: boolean = false,
|
|
56
|
-
contractDataSource
|
|
55
|
+
contractDataSource?: MockedAvmTestContractDataSource,
|
|
57
56
|
assertionErrString?: string,
|
|
58
57
|
): Promise<AvmCircuitInputs> {
|
|
59
58
|
const globals = GlobalVariables.empty();
|
|
60
59
|
globals.timestamp = TIMESTAMP;
|
|
61
60
|
|
|
62
|
-
const merkleTrees = await (await MerkleTrees.new(openTmpStore()
|
|
61
|
+
const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork();
|
|
62
|
+
if (!contractDataSource) {
|
|
63
|
+
contractDataSource = await MockedAvmTestContractDataSource.create();
|
|
64
|
+
}
|
|
63
65
|
await contractDataSource.deployContracts(merkleTrees);
|
|
64
66
|
const worldStateDB = new WorldStateDB(merkleTrees, contractDataSource);
|
|
65
67
|
|
|
66
|
-
const simulator = new PublicTxSimulator(
|
|
67
|
-
merkleTrees,
|
|
68
|
-
worldStateDB,
|
|
69
|
-
new NoopTelemetryClient(),
|
|
70
|
-
globals,
|
|
71
|
-
/*doMerkleOperations=*/ true,
|
|
72
|
-
);
|
|
68
|
+
const simulator = new PublicTxSimulator(merkleTrees, worldStateDB, globals, /*doMerkleOperations=*/ true);
|
|
73
69
|
|
|
74
|
-
const sender = AztecAddress.random();
|
|
70
|
+
const sender = await AztecAddress.random();
|
|
75
71
|
const callContext = new CallContext(
|
|
76
72
|
sender,
|
|
77
73
|
contractDataSource.firstContractInstance.address,
|
|
@@ -79,16 +75,14 @@ export async function simulateAvmTestContractGenerateCircuitInputs(
|
|
|
79
75
|
/*isStaticCall=*/ false,
|
|
80
76
|
);
|
|
81
77
|
const setupExecutionRequests: PublicExecutionRequest[] = [];
|
|
82
|
-
|
|
83
|
-
for (let i = setupFunctionNames.length - 1; i >= 0; i--) {
|
|
78
|
+
for (let i = 0; i < setupFunctionNames.length; i++) {
|
|
84
79
|
const functionSelector = getAvmTestContractFunctionSelector(setupFunctionNames[i]);
|
|
85
80
|
const fnArgs = [functionSelector.toField(), ...setupArgs[i]];
|
|
86
81
|
const executionRequest = new PublicExecutionRequest(callContext, fnArgs);
|
|
87
82
|
setupExecutionRequests.push(executionRequest);
|
|
88
83
|
}
|
|
89
84
|
const appExecutionRequests: PublicExecutionRequest[] = [];
|
|
90
|
-
|
|
91
|
-
for (let i = appFunctionNames.length - 1; i >= 0; i--) {
|
|
85
|
+
for (let i = 0; i < appFunctionNames.length; i++) {
|
|
92
86
|
const functionSelector = getAvmTestContractFunctionSelector(appFunctionNames[i]);
|
|
93
87
|
const fnArgs = [functionSelector.toField(), ...appArgs[i]];
|
|
94
88
|
const executionRequest = new PublicExecutionRequest(callContext, fnArgs);
|
|
@@ -102,7 +96,12 @@ export async function simulateAvmTestContractGenerateCircuitInputs(
|
|
|
102
96
|
teardownExecutionRequest = new PublicExecutionRequest(callContext, fnArgs);
|
|
103
97
|
}
|
|
104
98
|
|
|
105
|
-
const tx: Tx = createTxForPublicCalls(
|
|
99
|
+
const tx: Tx = createTxForPublicCalls(
|
|
100
|
+
setupExecutionRequests,
|
|
101
|
+
appExecutionRequests,
|
|
102
|
+
Fr.random(),
|
|
103
|
+
teardownExecutionRequest,
|
|
104
|
+
);
|
|
106
105
|
|
|
107
106
|
const avmResult = await simulator.simulate(tx);
|
|
108
107
|
|
|
@@ -125,12 +124,16 @@ export async function simulateAvmTestContractCall(
|
|
|
125
124
|
functionName: string,
|
|
126
125
|
args: Fr[] = [],
|
|
127
126
|
expectRevert: boolean = false,
|
|
128
|
-
contractDataSource
|
|
127
|
+
contractDataSource?: MockedAvmTestContractDataSource,
|
|
129
128
|
) {
|
|
130
129
|
const globals = GlobalVariables.empty();
|
|
131
130
|
globals.timestamp = TIMESTAMP;
|
|
132
131
|
|
|
133
|
-
|
|
132
|
+
if (!contractDataSource) {
|
|
133
|
+
contractDataSource = await MockedAvmTestContractDataSource.create();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const merkleTrees = await (await MerkleTrees.new(openTmpStore())).fork();
|
|
134
137
|
await contractDataSource.deployContracts(merkleTrees);
|
|
135
138
|
const worldStateDB = new WorldStateDB(merkleTrees, contractDataSource);
|
|
136
139
|
|
|
@@ -143,7 +146,7 @@ export async function simulateAvmTestContractCall(
|
|
|
143
146
|
doMerkleOperations: true,
|
|
144
147
|
});
|
|
145
148
|
|
|
146
|
-
const sender = AztecAddress.random();
|
|
149
|
+
const sender = await AztecAddress.random();
|
|
147
150
|
const functionSelector = getAvmTestContractFunctionSelector(functionName);
|
|
148
151
|
args = [functionSelector.toField(), ...args];
|
|
149
152
|
const environment = initExecutionEnvironment({
|
|
@@ -167,6 +170,7 @@ export async function simulateAvmTestContractCall(
|
|
|
167
170
|
export function createTxForPublicCalls(
|
|
168
171
|
setupExecutionRequests: PublicExecutionRequest[],
|
|
169
172
|
appExecutionRequests: PublicExecutionRequest[],
|
|
173
|
+
firstNullifier: Fr,
|
|
170
174
|
teardownExecutionRequest?: PublicExecutionRequest,
|
|
171
175
|
gasUsedByPrivate: Gas = Gas.empty(),
|
|
172
176
|
): Tx {
|
|
@@ -181,12 +185,13 @@ export function createTxForPublicCalls(
|
|
|
181
185
|
|
|
182
186
|
const forPublic = PartialPrivateTailPublicInputsForPublic.empty();
|
|
183
187
|
// TODO(#9269): Remove this fake nullifier method as we move away from 1st nullifier as hash.
|
|
184
|
-
forPublic.nonRevertibleAccumulatedData.nullifiers[0] =
|
|
188
|
+
forPublic.nonRevertibleAccumulatedData.nullifiers[0] = firstNullifier; // fake tx nullifier
|
|
185
189
|
|
|
186
|
-
|
|
190
|
+
// We reverse order because the simulator expects it to be like a "stack" of calls to pop from
|
|
191
|
+
for (let i = setupCallRequests.length - 1; i >= 0; i--) {
|
|
187
192
|
forPublic.nonRevertibleAccumulatedData.publicCallRequests[i] = setupCallRequests[i];
|
|
188
193
|
}
|
|
189
|
-
for (let i =
|
|
194
|
+
for (let i = appCallRequests.length - 1; i >= 0; i--) {
|
|
190
195
|
forPublic.revertibleAccumulatedData.publicCallRequests[i] = appCallRequests[i];
|
|
191
196
|
}
|
|
192
197
|
if (teardownExecutionRequest) {
|
|
@@ -207,12 +212,14 @@ export function createTxForPublicCalls(
|
|
|
207
212
|
);
|
|
208
213
|
const tx = Tx.newWithTxData(txData, teardownExecutionRequest);
|
|
209
214
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
for (let i = 0; i < appExecutionRequests.length; i++) {
|
|
215
|
+
// Reverse order because the simulator expects it to be like a "stack" of calls to pop from.
|
|
216
|
+
// Also push app calls before setup calls for this reason.
|
|
217
|
+
for (let i = appExecutionRequests.length - 1; i >= 0; i--) {
|
|
214
218
|
tx.enqueuedPublicFunctionCalls.push(appExecutionRequests[i]);
|
|
215
219
|
}
|
|
220
|
+
for (let i = setupExecutionRequests.length - 1; i >= 0; i--) {
|
|
221
|
+
tx.enqueuedPublicFunctionCalls.push(setupExecutionRequests[i]);
|
|
222
|
+
}
|
|
216
223
|
|
|
217
224
|
return tx;
|
|
218
225
|
}
|
|
@@ -234,45 +241,13 @@ export class MockedAvmTestContractDataSource implements ContractDataSource {
|
|
|
234
241
|
);
|
|
235
242
|
public instanceSameClassAsFirstContract: ContractInstanceWithAddress =
|
|
236
243
|
SerializableContractInstance.default().withAddress(AztecAddress.fromNumber(0));
|
|
237
|
-
public otherContractInstance
|
|
244
|
+
public otherContractInstance!: ContractInstanceWithAddress;
|
|
238
245
|
|
|
239
|
-
constructor(private skipContractDeployments: boolean
|
|
246
|
+
private constructor(private skipContractDeployments: boolean) {
|
|
240
247
|
this.bytecode = getAvmTestContractBytecode(this.fnName);
|
|
241
248
|
this.fnSelector = getAvmTestContractFunctionSelector(this.fnName);
|
|
242
249
|
this.publicFn = { bytecode: this.bytecode, selector: this.fnSelector };
|
|
243
250
|
this.bytecodeCommitment = computePublicBytecodeCommitment(this.bytecode);
|
|
244
|
-
|
|
245
|
-
// create enough unique classes to hit the limit (plus two extra)
|
|
246
|
-
for (let i = 0; i < MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS + 1; i++) {
|
|
247
|
-
const contractClass = makeContractClassPublic(/*seed=*/ i, this.publicFn);
|
|
248
|
-
const contractInstance = makeContractInstanceFromClassId(contractClass.id, /*seed=*/ i);
|
|
249
|
-
this.contractClasses.set(contractClass.id.toString(), contractClass);
|
|
250
|
-
this.contractInstances.set(contractInstance.address.toString(), contractInstance);
|
|
251
|
-
if (i === 0) {
|
|
252
|
-
this.firstContractInstance = contractInstance;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
// a contract with the same class but different instance/address as the first contract
|
|
256
|
-
this.instanceSameClassAsFirstContract = makeContractInstanceFromClassId(
|
|
257
|
-
this.firstContractInstance.contractClassId,
|
|
258
|
-
/*seed=*/ 1000,
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
// The values here should match those in `avm_simulator.test.ts`
|
|
262
|
-
// Used for GETCONTRACTINSTANCE test
|
|
263
|
-
this.otherContractInstance = new SerializableContractInstance({
|
|
264
|
-
version: 1,
|
|
265
|
-
salt: new Fr(0x123),
|
|
266
|
-
deployer: new AztecAddress(new Fr(0x456)),
|
|
267
|
-
contractClassId: new Fr(0x789),
|
|
268
|
-
initializationHash: new Fr(0x101112),
|
|
269
|
-
publicKeys: new PublicKeys(
|
|
270
|
-
new Point(new Fr(0x131415), new Fr(0x161718), false),
|
|
271
|
-
new Point(new Fr(0x192021), new Fr(0x222324), false),
|
|
272
|
-
new Point(new Fr(0x252627), new Fr(0x282930), false),
|
|
273
|
-
new Point(new Fr(0x313233), new Fr(0x343536), false),
|
|
274
|
-
),
|
|
275
|
-
}).withAddress(AztecAddress.fromNumber(0x4444));
|
|
276
251
|
}
|
|
277
252
|
|
|
278
253
|
async deployContracts(merkleTrees: MerkleTreeWriteOperations) {
|
|
@@ -304,14 +279,39 @@ export class MockedAvmTestContractDataSource implements ContractDataSource {
|
|
|
304
279
|
}
|
|
305
280
|
}
|
|
306
281
|
|
|
307
|
-
public static async create(
|
|
308
|
-
merkleTrees: MerkleTreeWriteOperations,
|
|
309
|
-
skipContractDeployments: boolean = false,
|
|
310
|
-
): Promise<MockedAvmTestContractDataSource> {
|
|
282
|
+
public static async create(skipContractDeployments: boolean = false): Promise<MockedAvmTestContractDataSource> {
|
|
311
283
|
const dataSource = new MockedAvmTestContractDataSource(skipContractDeployments);
|
|
312
|
-
|
|
313
|
-
|
|
284
|
+
// create enough unique classes to hit the limit (plus two extra)
|
|
285
|
+
for (let i = 0; i < MAX_PUBLIC_CALLS_TO_UNIQUE_CONTRACT_CLASS_IDS + 1; i++) {
|
|
286
|
+
const contractClass = makeContractClassPublic(/*seed=*/ i, dataSource.publicFn);
|
|
287
|
+
const contractInstance = await makeContractInstanceFromClassId(contractClass.id, /*seed=*/ i);
|
|
288
|
+
dataSource.contractClasses.set(contractClass.id.toString(), contractClass);
|
|
289
|
+
dataSource.contractInstances.set(contractInstance.address.toString(), contractInstance);
|
|
290
|
+
if (i === 0) {
|
|
291
|
+
dataSource.firstContractInstance = contractInstance;
|
|
292
|
+
}
|
|
314
293
|
}
|
|
294
|
+
// a contract with the same class but different instance/address as the first contract
|
|
295
|
+
dataSource.instanceSameClassAsFirstContract = await makeContractInstanceFromClassId(
|
|
296
|
+
dataSource.firstContractInstance.contractClassId,
|
|
297
|
+
/*seed=*/ 1000,
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
// The values here should match those in `avm_simulator.test.ts`
|
|
301
|
+
// Used for GETCONTRACTINSTANCE test
|
|
302
|
+
dataSource.otherContractInstance = new SerializableContractInstance({
|
|
303
|
+
version: 1,
|
|
304
|
+
salt: new Fr(0x123),
|
|
305
|
+
deployer: new AztecAddress(new Fr(0x456)),
|
|
306
|
+
contractClassId: new Fr(0x789),
|
|
307
|
+
initializationHash: new Fr(0x101112),
|
|
308
|
+
publicKeys: new PublicKeys(
|
|
309
|
+
new Point(new Fr(0x131415), new Fr(0x161718), false),
|
|
310
|
+
new Point(new Fr(0x192021), new Fr(0x222324), false),
|
|
311
|
+
new Point(new Fr(0x252627), new Fr(0x282930), false),
|
|
312
|
+
new Point(new Fr(0x313233), new Fr(0x343536), false),
|
|
313
|
+
),
|
|
314
|
+
}).withAddress(AztecAddress.fromNumber(0x4444));
|
|
315
315
|
return dataSource;
|
|
316
316
|
}
|
|
317
317
|
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
} from '@aztec/circuit-types';
|
|
13
13
|
import {
|
|
14
14
|
type AztecAddress,
|
|
15
|
-
type BlockHeader,
|
|
16
15
|
type ContractDataSource,
|
|
17
16
|
Fr,
|
|
18
17
|
Gas,
|
|
@@ -27,7 +26,14 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
27
26
|
import { type DateProvider, Timer, elapsed, executeTimeout } from '@aztec/foundation/timer';
|
|
28
27
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
29
28
|
import { ContractClassRegisteredEvent } from '@aztec/protocol-contracts/class-registerer';
|
|
30
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
Attributes,
|
|
31
|
+
type TelemetryClient,
|
|
32
|
+
type Traceable,
|
|
33
|
+
type Tracer,
|
|
34
|
+
getTelemetryClient,
|
|
35
|
+
trackSpan,
|
|
36
|
+
} from '@aztec/telemetry-client';
|
|
31
37
|
|
|
32
38
|
import { computeFeePayerBalanceLeafSlot, computeFeePayerBalanceStorageSlot } from './fee_payment.js';
|
|
33
39
|
import { WorldStateDB } from './public_db_sources.js';
|
|
@@ -41,7 +47,7 @@ export class PublicProcessorFactory {
|
|
|
41
47
|
constructor(
|
|
42
48
|
private contractDataSource: ContractDataSource,
|
|
43
49
|
private dateProvider: DateProvider,
|
|
44
|
-
private telemetryClient: TelemetryClient,
|
|
50
|
+
private telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
45
51
|
) {}
|
|
46
52
|
|
|
47
53
|
/**
|
|
@@ -53,26 +59,22 @@ export class PublicProcessorFactory {
|
|
|
53
59
|
*/
|
|
54
60
|
public create(
|
|
55
61
|
merkleTree: MerkleTreeWriteOperations,
|
|
56
|
-
maybeHistoricalHeader: BlockHeader | undefined,
|
|
57
62
|
globalVariables: GlobalVariables,
|
|
58
63
|
enforceFeePayment: boolean,
|
|
59
64
|
): PublicProcessor {
|
|
60
|
-
const historicalHeader = maybeHistoricalHeader ?? merkleTree.getInitialHeader();
|
|
61
|
-
|
|
62
65
|
const worldStateDB = new WorldStateDB(merkleTree, this.contractDataSource);
|
|
63
66
|
const publicTxSimulator = this.createPublicTxSimulator(
|
|
64
67
|
merkleTree,
|
|
65
68
|
worldStateDB,
|
|
66
|
-
this.telemetryClient,
|
|
67
69
|
globalVariables,
|
|
68
70
|
/*doMerkleOperations=*/ true,
|
|
69
71
|
enforceFeePayment,
|
|
72
|
+
this.telemetryClient,
|
|
70
73
|
);
|
|
71
74
|
|
|
72
75
|
return new PublicProcessor(
|
|
73
76
|
merkleTree,
|
|
74
77
|
globalVariables,
|
|
75
|
-
historicalHeader,
|
|
76
78
|
worldStateDB,
|
|
77
79
|
publicTxSimulator,
|
|
78
80
|
this.dateProvider,
|
|
@@ -83,18 +85,18 @@ export class PublicProcessorFactory {
|
|
|
83
85
|
protected createPublicTxSimulator(
|
|
84
86
|
db: MerkleTreeWriteOperations,
|
|
85
87
|
worldStateDB: WorldStateDB,
|
|
86
|
-
telemetryClient: TelemetryClient,
|
|
87
88
|
globalVariables: GlobalVariables,
|
|
88
89
|
doMerkleOperations: boolean,
|
|
89
90
|
enforceFeePayment: boolean,
|
|
91
|
+
telemetryClient: TelemetryClient,
|
|
90
92
|
) {
|
|
91
93
|
return new PublicTxSimulator(
|
|
92
94
|
db,
|
|
93
95
|
worldStateDB,
|
|
94
|
-
telemetryClient,
|
|
95
96
|
globalVariables,
|
|
96
97
|
doMerkleOperations,
|
|
97
98
|
enforceFeePayment,
|
|
99
|
+
telemetryClient,
|
|
98
100
|
);
|
|
99
101
|
}
|
|
100
102
|
}
|
|
@@ -115,11 +117,10 @@ export class PublicProcessor implements Traceable {
|
|
|
115
117
|
constructor(
|
|
116
118
|
protected db: MerkleTreeWriteOperations,
|
|
117
119
|
protected globalVariables: GlobalVariables,
|
|
118
|
-
protected historicalHeader: BlockHeader,
|
|
119
120
|
protected worldStateDB: WorldStateDB,
|
|
120
121
|
protected publicTxSimulator: PublicTxSimulator,
|
|
121
122
|
private dateProvider: DateProvider,
|
|
122
|
-
telemetryClient: TelemetryClient,
|
|
123
|
+
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
123
124
|
private log = createLogger('simulator:public-processor'),
|
|
124
125
|
) {
|
|
125
126
|
this.metrics = new PublicProcessorMetrics(telemetryClient, 'PublicProcessor');
|
|
@@ -279,7 +280,7 @@ export class PublicProcessor implements Traceable {
|
|
|
279
280
|
const rate = duration > 0 ? totalPublicGas.l2Gas / duration : 0;
|
|
280
281
|
this.metrics.recordAllTxs(totalPublicGas, rate);
|
|
281
282
|
|
|
282
|
-
this.log.info(`Processed ${result.length}
|
|
283
|
+
this.log.info(`Processed ${result.length} successful txs and ${failed.length} txs in ${duration}s`, {
|
|
283
284
|
duration,
|
|
284
285
|
rate,
|
|
285
286
|
totalPublicGas,
|
|
@@ -308,7 +309,7 @@ export class PublicProcessor implements Traceable {
|
|
|
308
309
|
nullifierCount: processedTx.txEffect.nullifiers.length,
|
|
309
310
|
noteHashCount: processedTx.txEffect.noteHashes.length,
|
|
310
311
|
contractClassLogCount: processedTx.txEffect.contractClassLogs.getTotalLogCount(),
|
|
311
|
-
|
|
312
|
+
publicLogCount: processedTx.txEffect.publicLogs.length,
|
|
312
313
|
privateLogCount: processedTx.txEffect.privateLogs.length,
|
|
313
314
|
l2ToL1MessageCount: processedTx.txEffect.l2ToL1Msgs.length,
|
|
314
315
|
durationMs: time,
|
|
@@ -371,17 +372,18 @@ export class PublicProcessor implements Traceable {
|
|
|
371
372
|
return await processFn();
|
|
372
373
|
}
|
|
373
374
|
|
|
375
|
+
const txHash = tx.getTxHash().toString();
|
|
374
376
|
const timeout = +deadline - this.dateProvider.now();
|
|
377
|
+
if (timeout <= 0) {
|
|
378
|
+
throw new PublicProcessorTimeoutError();
|
|
379
|
+
}
|
|
380
|
+
|
|
375
381
|
this.log.debug(`Processing tx ${tx.getTxHash().toString()} within ${timeout}ms`, {
|
|
376
382
|
deadline: deadline.toISOString(),
|
|
377
383
|
now: new Date(this.dateProvider.now()).toISOString(),
|
|
378
|
-
txHash
|
|
384
|
+
txHash,
|
|
379
385
|
});
|
|
380
386
|
|
|
381
|
-
if (timeout < 0) {
|
|
382
|
-
throw new PublicProcessorTimeoutError();
|
|
383
|
-
}
|
|
384
|
-
|
|
385
387
|
return await executeTimeout(
|
|
386
388
|
() => processFn(),
|
|
387
389
|
timeout,
|
|
@@ -97,7 +97,7 @@ export class PublicTxContext {
|
|
|
97
97
|
/*noteHashes*/ 0,
|
|
98
98
|
/*nullifiers=*/ 0,
|
|
99
99
|
countAccumulatedItems(nonRevertibleAccumulatedDataFromPrivate.l2ToL1Msgs),
|
|
100
|
-
/*
|
|
100
|
+
/*publicLogs*/ 0,
|
|
101
101
|
);
|
|
102
102
|
const enqueuedCallTrace = new PublicEnqueuedCallSideEffectTrace(
|
|
103
103
|
/*startSideEffectCounter=*/ 0,
|
|
@@ -7,14 +7,13 @@ import {
|
|
|
7
7
|
type SimulationError,
|
|
8
8
|
type Tx,
|
|
9
9
|
TxExecutionPhase,
|
|
10
|
-
UnencryptedFunctionL2Logs,
|
|
11
10
|
} from '@aztec/circuit-types';
|
|
12
11
|
import { type AvmSimulationStats } from '@aztec/circuit-types/stats';
|
|
13
12
|
import { type Fr, type Gas, type GlobalVariables, type PublicCallRequest, type RevertCode } from '@aztec/circuits.js';
|
|
14
13
|
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
15
14
|
import { Timer } from '@aztec/foundation/timer';
|
|
16
15
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
17
|
-
import { Attributes, type TelemetryClient, type Tracer, trackSpan } from '@aztec/telemetry-client';
|
|
16
|
+
import { Attributes, type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
18
17
|
|
|
19
18
|
import { strict as assert } from 'assert';
|
|
20
19
|
|
|
@@ -53,10 +52,10 @@ export class PublicTxSimulator {
|
|
|
53
52
|
constructor(
|
|
54
53
|
private db: MerkleTreeReadOperations,
|
|
55
54
|
private worldStateDB: WorldStateDB,
|
|
56
|
-
telemetryClient: TelemetryClient,
|
|
57
55
|
private globalVariables: GlobalVariables,
|
|
58
56
|
private doMerkleOperations: boolean = false,
|
|
59
57
|
private enforceFeePayment: boolean = true,
|
|
58
|
+
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
60
59
|
) {
|
|
61
60
|
this.log = createLogger(`simulator:public_tx_simulator`);
|
|
62
61
|
this.metrics = new ExecutorMetrics(telemetryClient, 'PublicTxSimulator');
|
|
@@ -121,7 +120,6 @@ export class PublicTxSimulator {
|
|
|
121
120
|
const endStateReference = await this.db.getStateReference();
|
|
122
121
|
|
|
123
122
|
const avmProvingRequest = context.generateProvingRequest(endStateReference);
|
|
124
|
-
const avmCircuitPublicInputs = avmProvingRequest.inputs.output!;
|
|
125
123
|
|
|
126
124
|
const revertCode = context.getFinalRevertCode();
|
|
127
125
|
if (!revertCode.isOK()) {
|
|
@@ -131,13 +129,8 @@ export class PublicTxSimulator {
|
|
|
131
129
|
// FIXME: we shouldn't need to directly modify worldStateDb here!
|
|
132
130
|
await this.worldStateDB.removeNewContracts(tx);
|
|
133
131
|
// FIXME(dbanks12): should not be changing immutable tx
|
|
134
|
-
tx.filterRevertedLogs(
|
|
135
|
-
tx.data.forPublic!.nonRevertibleAccumulatedData,
|
|
136
|
-
avmCircuitPublicInputs.accumulatedData.unencryptedLogsHashes,
|
|
137
|
-
);
|
|
132
|
+
tx.filterRevertedLogs(tx.data.forPublic!.nonRevertibleAccumulatedData);
|
|
138
133
|
}
|
|
139
|
-
// FIXME(dbanks12): should not be changing immutable tx
|
|
140
|
-
tx.unencryptedLogs.addFunctionLogs([new UnencryptedFunctionL2Logs(context.trace.getUnencryptedLogs())]);
|
|
141
134
|
|
|
142
135
|
return {
|
|
143
136
|
avmProvingRequest,
|