@aztec/simulator 1.2.0 → 2.0.0-nightly.20250813
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/private/circuit_recording/circuit_recorder.js +2 -2
- package/dest/public/avm/fixtures/base_avm_simulation_tester.js +2 -2
- package/dest/public/avm/fixtures/utils.js +2 -2
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/public/avm/opcodes/accrued_substate.js +5 -3
- package/dest/public/avm/opcodes/comparators.js +1 -1
- package/dest/public/avm/opcodes/environment_getters.d.ts +2 -2
- package/dest/public/avm/opcodes/environment_getters.d.ts.map +1 -1
- package/dest/public/avm/opcodes/environment_getters.js +6 -6
- package/dest/public/avm/opcodes/misc.js +1 -1
- package/dest/public/avm/test_utils.d.ts +2 -2
- package/dest/public/avm/test_utils.d.ts.map +1 -1
- package/dest/public/avm/test_utils.js +2 -2
- package/dest/public/executor_metrics.d.ts +0 -1
- package/dest/public/executor_metrics.d.ts.map +1 -1
- package/dest/public/executor_metrics.js +0 -3
- package/dest/public/executor_metrics_interface.d.ts +0 -1
- package/dest/public/executor_metrics_interface.d.ts.map +1 -1
- package/dest/public/fixtures/index.d.ts +1 -0
- package/dest/public/fixtures/index.d.ts.map +1 -1
- package/dest/public/fixtures/index.js +1 -0
- package/dest/public/fixtures/minimal_public_tx.d.ts.map +1 -1
- package/dest/public/fixtures/minimal_public_tx.js +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +2 -1
- package/dest/public/fixtures/utils.d.ts +5 -2
- package/dest/public/fixtures/utils.d.ts.map +1 -1
- package/dest/public/fixtures/utils.js +37 -13
- package/dest/public/public_db_sources.js +4 -4
- package/dest/public/public_processor/public_processor.d.ts +3 -2
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +30 -19
- package/dest/public/public_processor/public_processor_metrics.d.ts +2 -2
- package/dest/public/public_processor/public_processor_metrics.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor_metrics.js +1 -1
- package/dest/public/public_tx_simulator/apps_tests/amm_test.js +4 -4
- package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts +1 -1
- package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/apps_tests/token_test.js +2 -2
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +0 -1
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +0 -6
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +6 -12
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +1 -20
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +49 -81
- package/dest/public/side_effect_trace.d.ts.map +1 -1
- package/dest/public/side_effect_trace.js +17 -11
- package/dest/public/state_manager/state_manager.d.ts +1 -1
- package/dest/public/state_manager/state_manager.d.ts.map +1 -1
- package/dest/public/state_manager/state_manager.js +16 -16
- package/dest/public/test_executor_metrics.d.ts +13 -3
- package/dest/public/test_executor_metrics.d.ts.map +1 -1
- package/dest/public/test_executor_metrics.js +159 -47
- package/package.json +15 -15
- package/src/private/circuit_recording/circuit_recorder.ts +2 -2
- package/src/public/avm/fixtures/base_avm_simulation_tester.ts +2 -2
- package/src/public/avm/fixtures/utils.ts +2 -2
- package/src/public/avm/opcodes/accrued_substate.ts +6 -3
- package/src/public/avm/opcodes/comparators.ts +1 -1
- package/src/public/avm/opcodes/environment_getters.ts +8 -8
- package/src/public/avm/opcodes/misc.ts +1 -1
- package/src/public/avm/test_utils.ts +4 -4
- package/src/public/executor_metrics.ts +0 -4
- package/src/public/executor_metrics_interface.ts +0 -1
- package/src/public/fixtures/index.ts +1 -0
- package/src/public/fixtures/minimal_public_tx.ts +2 -0
- package/src/public/fixtures/public_tx_simulation_tester.ts +3 -2
- package/src/public/fixtures/utils.ts +45 -16
- package/src/public/public_db_sources.ts +7 -7
- package/src/public/public_processor/public_processor.ts +38 -29
- package/src/public/public_processor/public_processor_metrics.ts +2 -2
- package/src/public/public_tx_simulator/apps_tests/amm_test.ts +4 -4
- package/src/public/public_tx_simulator/apps_tests/token_test.ts +2 -2
- package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +0 -7
- package/src/public/public_tx_simulator/public_tx_context.ts +13 -19
- package/src/public/public_tx_simulator/public_tx_simulator.ts +63 -105
- package/src/public/side_effect_trace.ts +29 -23
- package/src/public/state_manager/state_manager.ts +23 -21
- package/src/public/test_executor_metrics.ts +172 -46
|
@@ -41,12 +41,12 @@ export class DebugLog extends Instruction {
|
|
|
41
41
|
|
|
42
42
|
const operands = [this.messageOffset, this.fieldsOffset, this.fieldsSizeOffset];
|
|
43
43
|
const [messageOffset, fieldsOffset, fieldsSizeOffset] = addressing.resolve(operands, memory);
|
|
44
|
-
memory.checkTag(TypeTag.UINT32, fieldsSizeOffset);
|
|
45
44
|
|
|
46
45
|
// DebugLog is a no-op except when doing client-initiated simulation with debug logging enabled.
|
|
47
46
|
// Note that we still do address resolution and basic tag-checking (above)
|
|
48
47
|
// To avoid a special-case in the witness generator and circuit.
|
|
49
48
|
if (context.environment.clientInitiatedSimulation && DebugLog.logger.isLevelEnabled('verbose')) {
|
|
49
|
+
memory.checkTag(TypeTag.UINT32, fieldsSizeOffset);
|
|
50
50
|
const fieldsSize = memory.get(fieldsSizeOffset).toNumber();
|
|
51
51
|
|
|
52
52
|
const rawMessage = memory.getSlice(messageOffset, this.messageSize);
|
|
@@ -27,9 +27,9 @@ export function mockStorageReadWithMap(worldStateDB: PublicTreesDB, mockedStorag
|
|
|
27
27
|
);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
export function mockNoteHashExists(worldStateDB: PublicTreesDB, _leafIndex:
|
|
30
|
+
export function mockNoteHashExists(worldStateDB: PublicTreesDB, _leafIndex: bigint, value?: Fr) {
|
|
31
31
|
(worldStateDB as jest.Mocked<PublicTreesDB>).getNoteHash.mockImplementation((index: bigint) => {
|
|
32
|
-
if (index == _leafIndex
|
|
32
|
+
if (index == _leafIndex) {
|
|
33
33
|
return Promise.resolve(value);
|
|
34
34
|
} else {
|
|
35
35
|
// This is ok for now since the traceing functions handle it
|
|
@@ -44,12 +44,12 @@ export function mockCheckNullifierExists(worldStateDB: PublicTreesDB, exists: bo
|
|
|
44
44
|
|
|
45
45
|
export function mockL1ToL2MessageExists(
|
|
46
46
|
worldStateDB: PublicTreesDB,
|
|
47
|
-
leafIndex:
|
|
47
|
+
leafIndex: bigint,
|
|
48
48
|
value: Fr,
|
|
49
49
|
valueAtOtherIndices?: Fr,
|
|
50
50
|
) {
|
|
51
51
|
(worldStateDB as jest.Mocked<PublicTreesDB>).getL1ToL2LeafValue.mockImplementation((index: bigint) => {
|
|
52
|
-
if (index == leafIndex
|
|
52
|
+
if (index == leafIndex) {
|
|
53
53
|
return Promise.resolve(value);
|
|
54
54
|
} else {
|
|
55
55
|
// any indices other than mockAtLeafIndex will return a different value
|
|
@@ -112,10 +112,6 @@ export class ExecutorMetrics implements ExecutorMetricsInterface {
|
|
|
112
112
|
});
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
recordTxHashComputation(durationMs: number) {
|
|
116
|
-
this.txHashing.record(Math.ceil(durationMs));
|
|
117
|
-
}
|
|
118
|
-
|
|
119
115
|
recordPrivateEffectsInsertion(durationUs: number, type: 'revertible' | 'non-revertible') {
|
|
120
116
|
this.privateEffectsInsertions.record(Math.ceil(durationUs), {
|
|
121
117
|
[Attributes.REVERTIBILITY]: type,
|
|
@@ -10,6 +10,5 @@ export interface ExecutorMetricsInterface {
|
|
|
10
10
|
manaUsed: number,
|
|
11
11
|
totalInstructionsExecuted: number,
|
|
12
12
|
): void;
|
|
13
|
-
recordTxHashComputation(durationMs: number): void;
|
|
14
13
|
recordPrivateEffectsInsertion(durationUs: number, type: 'revertible' | 'non-revertible'): void;
|
|
15
14
|
}
|
|
@@ -2,3 +2,4 @@ export * from './public_tx_simulation_tester.js';
|
|
|
2
2
|
export * from './utils.js';
|
|
3
3
|
export * from './simple_contract_data_source.js';
|
|
4
4
|
export { readAvmMinimalPublicTxInputsFromFile, createAvmMinimalPublicTx } from './minimal_public_tx.js';
|
|
5
|
+
export { TestExecutorMetrics } from '../test_executor_metrics.js';
|
|
@@ -39,7 +39,7 @@ export type TestEnqueuedCall = {
|
|
|
39
39
|
* transactions.
|
|
40
40
|
*/
|
|
41
41
|
export class PublicTxSimulationTester extends BaseAvmSimulationTester {
|
|
42
|
-
|
|
42
|
+
protected txCount: number = 0;
|
|
43
43
|
private simulator: MeasuredPublicTxSimulator;
|
|
44
44
|
private metricsPrefix?: string;
|
|
45
45
|
|
|
@@ -83,7 +83,7 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
|
|
|
83
83
|
teardownCall?: TestEnqueuedCall,
|
|
84
84
|
feePayer: AztecAddress = sender,
|
|
85
85
|
/* need some unique first nullifier for note-nonce computations */
|
|
86
|
-
privateInsertions: TestPrivateInsertions = { nonRevertible: { nullifiers: [new Fr(420000 + this.txCount
|
|
86
|
+
privateInsertions: TestPrivateInsertions = { nonRevertible: { nullifiers: [new Fr(420000 + this.txCount)] } },
|
|
87
87
|
): Promise<Tx> {
|
|
88
88
|
const setupCallRequests = await asyncMap(setupCalls, call =>
|
|
89
89
|
this.#createPubicCallRequestForCall(call, call.sender ?? sender),
|
|
@@ -95,6 +95,7 @@ export class PublicTxSimulationTester extends BaseAvmSimulationTester {
|
|
|
95
95
|
? await this.#createPubicCallRequestForCall(teardownCall, teardownCall.sender ?? sender)
|
|
96
96
|
: undefined;
|
|
97
97
|
|
|
98
|
+
this.txCount++;
|
|
98
99
|
return createTxForPublicCalls(
|
|
99
100
|
privateInsertions,
|
|
100
101
|
setupCallRequests,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE,
|
|
3
|
+
CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS,
|
|
4
|
+
CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
|
|
2
5
|
DEFAULT_GAS_LIMIT,
|
|
3
|
-
DEPLOYER_CONTRACT_ADDRESS,
|
|
4
6
|
MAX_L2_GAS_PER_TX_PUBLIC_PORTION,
|
|
5
7
|
PRIVATE_LOG_SIZE_IN_FIELDS,
|
|
6
|
-
REGISTERER_CONTRACT_ADDRESS,
|
|
7
|
-
REGISTERER_CONTRACT_CLASS_REGISTERED_MAGIC_VALUE,
|
|
8
8
|
} from '@aztec/constants';
|
|
9
9
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
10
10
|
import { Fr } from '@aztec/foundation/fields';
|
|
11
|
-
import {
|
|
11
|
+
import { CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG } from '@aztec/protocol-contracts';
|
|
12
12
|
import { bufferAsFields } from '@aztec/stdlib/abi';
|
|
13
13
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
14
14
|
import type { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
@@ -19,10 +19,10 @@ import {
|
|
|
19
19
|
PartialPrivateTailPublicInputsForPublic,
|
|
20
20
|
PartialPrivateTailPublicInputsForRollup,
|
|
21
21
|
PrivateKernelTailCircuitPublicInputs,
|
|
22
|
-
RollupValidationRequests,
|
|
23
22
|
countAccumulatedItems,
|
|
24
23
|
} from '@aztec/stdlib/kernel';
|
|
25
24
|
import { ContractClassLogFields, PrivateLog } from '@aztec/stdlib/logs';
|
|
25
|
+
import type { ScopedL2ToL1Message } from '@aztec/stdlib/messaging';
|
|
26
26
|
import { ClientIvcProof } from '@aztec/stdlib/proofs';
|
|
27
27
|
import {
|
|
28
28
|
BlockHeader,
|
|
@@ -40,17 +40,19 @@ export type TestPrivateInsertions = {
|
|
|
40
40
|
revertible?: {
|
|
41
41
|
nullifiers?: Fr[];
|
|
42
42
|
noteHashes?: Fr[];
|
|
43
|
+
l2ToL1Msgs?: ScopedL2ToL1Message[];
|
|
43
44
|
};
|
|
44
45
|
nonRevertible?: {
|
|
45
46
|
nullifiers?: Fr[];
|
|
46
47
|
noteHashes?: Fr[];
|
|
48
|
+
l2ToL1Msgs?: ScopedL2ToL1Message[];
|
|
47
49
|
};
|
|
48
50
|
};
|
|
49
51
|
|
|
50
52
|
/**
|
|
51
53
|
* Craft a carrier transaction for some public calls for simulation by PublicTxSimulator.
|
|
52
54
|
*/
|
|
53
|
-
export function createTxForPublicCalls(
|
|
55
|
+
export async function createTxForPublicCalls(
|
|
54
56
|
privateInsertions: TestPrivateInsertions,
|
|
55
57
|
setupCallRequests: PublicCallRequestWithCalldata[],
|
|
56
58
|
appCallRequests: PublicCallRequestWithCalldata[],
|
|
@@ -58,7 +60,7 @@ export function createTxForPublicCalls(
|
|
|
58
60
|
feePayer = AztecAddress.zero(),
|
|
59
61
|
gasUsedByPrivate: Gas = Gas.empty(),
|
|
60
62
|
globals: GlobalVariables = GlobalVariables.empty(),
|
|
61
|
-
): Tx {
|
|
63
|
+
): Promise<Tx> {
|
|
62
64
|
assert(
|
|
63
65
|
setupCallRequests.length > 0 || appCallRequests.length > 0 || teardownCallRequest !== undefined,
|
|
64
66
|
"Can't create public tx with no enqueued calls",
|
|
@@ -83,6 +85,12 @@ export function createTxForPublicCalls(
|
|
|
83
85
|
forPublic.nonRevertibleAccumulatedData.noteHashes[i] = privateInsertions.nonRevertible.noteHashes[i];
|
|
84
86
|
}
|
|
85
87
|
}
|
|
88
|
+
if (privateInsertions.nonRevertible.l2ToL1Msgs) {
|
|
89
|
+
for (let i = 0; i < privateInsertions.nonRevertible.l2ToL1Msgs.length; i++) {
|
|
90
|
+
assert(i < forPublic.nonRevertibleAccumulatedData.l2ToL1Msgs.length, 'L2 to L1 message index out of bounds');
|
|
91
|
+
forPublic.nonRevertibleAccumulatedData.l2ToL1Msgs[i] = privateInsertions.nonRevertible.l2ToL1Msgs[i];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
86
94
|
|
|
87
95
|
// Revertible private insertions
|
|
88
96
|
if (privateInsertions.revertible) {
|
|
@@ -98,6 +106,12 @@ export function createTxForPublicCalls(
|
|
|
98
106
|
forPublic.revertibleAccumulatedData.nullifiers[i] = privateInsertions.revertible.nullifiers[i];
|
|
99
107
|
}
|
|
100
108
|
}
|
|
109
|
+
if (privateInsertions.revertible.l2ToL1Msgs) {
|
|
110
|
+
for (let i = 0; i < privateInsertions.revertible.l2ToL1Msgs.length; i++) {
|
|
111
|
+
assert(i < forPublic.revertibleAccumulatedData.l2ToL1Msgs.length, 'L2 to L1 message index out of bounds');
|
|
112
|
+
forPublic.revertibleAccumulatedData.l2ToL1Msgs[i] = privateInsertions.revertible.l2ToL1Msgs[i];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
101
115
|
}
|
|
102
116
|
|
|
103
117
|
for (let i = 0; i < setupCallRequests.length; i++) {
|
|
@@ -117,12 +131,13 @@ export function createTxForPublicCalls(
|
|
|
117
131
|
const header = BlockHeader.empty();
|
|
118
132
|
header.globalVariables = globals;
|
|
119
133
|
const constantData = new TxConstantData(header, txContext, Fr.zero(), Fr.zero());
|
|
134
|
+
const includeByTimestamp = 0n; // Not used in the simulator.
|
|
120
135
|
|
|
121
136
|
const txData = new PrivateKernelTailCircuitPublicInputs(
|
|
122
137
|
constantData,
|
|
123
|
-
RollupValidationRequests.empty(),
|
|
124
138
|
/*gasUsed=*/ gasUsedByPrivate,
|
|
125
139
|
feePayer,
|
|
140
|
+
includeByTimestamp,
|
|
126
141
|
forPublic,
|
|
127
142
|
);
|
|
128
143
|
|
|
@@ -132,10 +147,18 @@ export function createTxForPublicCalls(
|
|
|
132
147
|
...(teardownCallRequest ? [teardownCallRequest] : []),
|
|
133
148
|
].map(r => new HashedValues(r.calldata, r.request.calldataHash));
|
|
134
149
|
|
|
135
|
-
return
|
|
150
|
+
return await Tx.create({
|
|
151
|
+
data: txData,
|
|
152
|
+
clientIvcProof: ClientIvcProof.empty(),
|
|
153
|
+
contractClassLogFields: [],
|
|
154
|
+
publicFunctionCalldata: calldata,
|
|
155
|
+
});
|
|
136
156
|
}
|
|
137
157
|
|
|
138
|
-
export function createTxForPrivateOnly(
|
|
158
|
+
export async function createTxForPrivateOnly(
|
|
159
|
+
feePayer = AztecAddress.zero(),
|
|
160
|
+
gasUsedByPrivate: Gas = new Gas(10, 10),
|
|
161
|
+
): Promise<Tx> {
|
|
139
162
|
// use max limits
|
|
140
163
|
const gasLimits = new Gas(DEFAULT_GAS_LIMIT, MAX_L2_GAS_PER_TX_PUBLIC_PORTION);
|
|
141
164
|
|
|
@@ -145,16 +168,22 @@ export function createTxForPrivateOnly(feePayer = AztecAddress.zero(), gasUsedBy
|
|
|
145
168
|
const gasSettings = new GasSettings(gasLimits, Gas.empty(), maxFeesPerGas, GasFees.empty());
|
|
146
169
|
const txContext = new TxContext(Fr.zero(), Fr.zero(), gasSettings);
|
|
147
170
|
const constantData = new TxConstantData(BlockHeader.empty(), txContext, Fr.zero(), Fr.zero());
|
|
171
|
+
const includeByTimestamp = 0n; // Not used in the simulator.
|
|
148
172
|
|
|
149
173
|
const txData = new PrivateKernelTailCircuitPublicInputs(
|
|
150
174
|
constantData,
|
|
151
|
-
RollupValidationRequests.empty(),
|
|
152
175
|
/*gasUsed=*/ gasUsedByPrivate,
|
|
153
176
|
feePayer,
|
|
177
|
+
includeByTimestamp,
|
|
154
178
|
/*forPublic=*/ undefined,
|
|
155
179
|
forRollup,
|
|
156
180
|
);
|
|
157
|
-
return
|
|
181
|
+
return await Tx.create({
|
|
182
|
+
data: txData,
|
|
183
|
+
clientIvcProof: ClientIvcProof.empty(),
|
|
184
|
+
contractClassLogFields: [],
|
|
185
|
+
publicFunctionCalldata: [],
|
|
186
|
+
});
|
|
158
187
|
}
|
|
159
188
|
|
|
160
189
|
export async function addNewContractClassToTx(
|
|
@@ -163,14 +192,14 @@ export async function addNewContractClassToTx(
|
|
|
163
192
|
skipNullifierInsertion = false,
|
|
164
193
|
) {
|
|
165
194
|
const contractClassLogFields = [
|
|
166
|
-
new Fr(
|
|
195
|
+
new Fr(CONTRACT_CLASS_PUBLISHED_MAGIC_VALUE),
|
|
167
196
|
contractClass.id,
|
|
168
197
|
new Fr(contractClass.version),
|
|
169
198
|
new Fr(contractClass.artifactHash),
|
|
170
199
|
new Fr(contractClass.privateFunctionsRoot),
|
|
171
200
|
...bufferAsFields(contractClass.packedBytecode, Math.ceil(contractClass.packedBytecode.length / 31) + 1),
|
|
172
201
|
];
|
|
173
|
-
const contractAddress = new AztecAddress(new Fr(
|
|
202
|
+
const contractAddress = new AztecAddress(new Fr(CONTRACT_CLASS_REGISTRY_CONTRACT_ADDRESS));
|
|
174
203
|
const emittedLength = contractClassLogFields.length;
|
|
175
204
|
const logFields = ContractClassLogFields.fromEmittedFields(contractClassLogFields);
|
|
176
205
|
|
|
@@ -209,7 +238,7 @@ export async function addNewContractInstanceToTx(
|
|
|
209
238
|
contractInstance.publicKeys.masterTaggingPublicKey.y,
|
|
210
239
|
];
|
|
211
240
|
const logFields = [
|
|
212
|
-
|
|
241
|
+
CONTRACT_INSTANCE_PUBLISHED_EVENT_TAG,
|
|
213
242
|
contractInstance.address.toField(),
|
|
214
243
|
new Fr(contractInstance.version),
|
|
215
244
|
new Fr(contractInstance.salt),
|
|
@@ -224,7 +253,7 @@ export async function addNewContractInstanceToTx(
|
|
|
224
253
|
);
|
|
225
254
|
|
|
226
255
|
const contractAddressNullifier = await siloNullifier(
|
|
227
|
-
AztecAddress.fromNumber(
|
|
256
|
+
AztecAddress.fromNumber(CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS),
|
|
228
257
|
contractInstance.address.toField(),
|
|
229
258
|
);
|
|
230
259
|
|
|
@@ -2,8 +2,8 @@ import { NULLIFIER_SUBTREE_HEIGHT, PUBLIC_DATA_SUBTREE_HEIGHT } from '@aztec/con
|
|
|
2
2
|
import { Fr } from '@aztec/foundation/fields';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { Timer } from '@aztec/foundation/timer';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
|
|
6
|
+
import { ContractInstancePublishedEvent } from '@aztec/protocol-contracts/instance-registry';
|
|
7
7
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
8
8
|
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
9
9
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -143,12 +143,12 @@ export class PublicContractsDB implements PublicContractsDBInterface {
|
|
|
143
143
|
cacheType: string,
|
|
144
144
|
) {
|
|
145
145
|
const contractClassEvents = siloedContractClassLogs
|
|
146
|
-
.filter((log: ContractClassLog) =>
|
|
147
|
-
.map((log: ContractClassLog) =>
|
|
146
|
+
.filter((log: ContractClassLog) => ContractClassPublishedEvent.isContractClassPublishedEvent(log))
|
|
147
|
+
.map((log: ContractClassLog) => ContractClassPublishedEvent.fromLog(log));
|
|
148
148
|
|
|
149
149
|
// Cache contract classes
|
|
150
150
|
await Promise.all(
|
|
151
|
-
contractClassEvents.map(async (event:
|
|
151
|
+
contractClassEvents.map(async (event: ContractClassPublishedEvent) => {
|
|
152
152
|
this.log.debug(`Adding class ${event.contractClassId.toString()} to contract's ${cacheType} tx cache`);
|
|
153
153
|
const contractClass = await event.toContractClassPublic();
|
|
154
154
|
|
|
@@ -165,8 +165,8 @@ export class PublicContractsDB implements PublicContractsDBInterface {
|
|
|
165
165
|
*/
|
|
166
166
|
private addContractInstancesFromLogs(contractInstanceLogs: PrivateLog[], cache: TxContractCache, cacheType: string) {
|
|
167
167
|
const contractInstanceEvents = contractInstanceLogs
|
|
168
|
-
.filter(log =>
|
|
169
|
-
.map(log =>
|
|
168
|
+
.filter(log => ContractInstancePublishedEvent.isContractInstancePublishedEvent(log))
|
|
169
|
+
.map(log => ContractInstancePublishedEvent.fromLog(log));
|
|
170
170
|
|
|
171
171
|
// Cache contract instances
|
|
172
172
|
contractInstanceEvents.forEach(e => {
|
|
@@ -2,9 +2,10 @@ import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX, NULLIFIER_SUBTREE_HEIGHT
|
|
|
2
2
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
3
3
|
import { Fr } from '@aztec/foundation/fields';
|
|
4
4
|
import { createLogger } from '@aztec/foundation/log';
|
|
5
|
+
import { sleep } from '@aztec/foundation/sleep';
|
|
5
6
|
import { DateProvider, Timer, elapsed, executeTimeout } from '@aztec/foundation/timer';
|
|
6
7
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
7
|
-
import {
|
|
8
|
+
import { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
|
|
8
9
|
import { computeFeePayerBalanceLeafSlot, computeFeePayerBalanceStorageSlot } from '@aztec/protocol-contracts/fee-juice';
|
|
9
10
|
import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
10
11
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -14,6 +15,7 @@ import type {
|
|
|
14
15
|
MerkleTreeWriteOperations,
|
|
15
16
|
PublicProcessorLimits,
|
|
16
17
|
PublicProcessorValidator,
|
|
18
|
+
SequencerConfig,
|
|
17
19
|
} from '@aztec/stdlib/interfaces/server';
|
|
18
20
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
19
21
|
import {
|
|
@@ -130,6 +132,7 @@ export class PublicProcessor implements Traceable {
|
|
|
130
132
|
private dateProvider: DateProvider,
|
|
131
133
|
telemetryClient: TelemetryClient = getTelemetryClient(),
|
|
132
134
|
private log = createLogger('simulator:public-processor'),
|
|
135
|
+
private opts: Pick<SequencerConfig, 'fakeProcessingDelayPerTxMs'> = {},
|
|
133
136
|
) {
|
|
134
137
|
this.metrics = new PublicProcessorMetrics(telemetryClient, 'PublicProcessor');
|
|
135
138
|
}
|
|
@@ -176,7 +179,7 @@ export class PublicProcessor implements Traceable {
|
|
|
176
179
|
}
|
|
177
180
|
|
|
178
181
|
// Skip this tx if it'd exceed max block size
|
|
179
|
-
const txHash =
|
|
182
|
+
const txHash = origTx.getTxHash().toString();
|
|
180
183
|
const preTxSizeInBytes = origTx.getEstimatedPrivateTxEffectsSize();
|
|
181
184
|
if (maxBlockSize !== undefined && totalSizeInBytes + preTxSizeInBytes > maxBlockSize) {
|
|
182
185
|
this.log.warn(`Skipping processing of tx ${txHash} sized ${preTxSizeInBytes} bytes due to block size limit`, {
|
|
@@ -206,16 +209,16 @@ export class PublicProcessor implements Traceable {
|
|
|
206
209
|
// We validate the tx before processing it, to avoid unnecessary work.
|
|
207
210
|
if (preprocessValidator) {
|
|
208
211
|
const result = await preprocessValidator.validateTx(tx);
|
|
209
|
-
const txHash =
|
|
212
|
+
const txHash = tx.getTxHash();
|
|
210
213
|
if (result.result === 'invalid') {
|
|
211
214
|
const reason = result.reason.join(', ');
|
|
212
|
-
this.log.
|
|
215
|
+
this.log.debug(`Rejecting tx ${txHash.toString()} due to pre-process validation fail: ${reason}`);
|
|
213
216
|
failed.push({ tx, error: new Error(`Tx failed preprocess validation: ${reason}`) });
|
|
214
217
|
returns.push(new NestedProcessReturnValues([]));
|
|
215
218
|
continue;
|
|
216
219
|
} else if (result.result === 'skipped') {
|
|
217
220
|
const reason = result.reason.join(', ');
|
|
218
|
-
this.log.
|
|
221
|
+
this.log.debug(`Skipping tx ${txHash.toString()} due to pre-process validation: ${reason}`);
|
|
219
222
|
returns.push(new NestedProcessReturnValues([]));
|
|
220
223
|
continue;
|
|
221
224
|
} else {
|
|
@@ -237,7 +240,7 @@ export class PublicProcessor implements Traceable {
|
|
|
237
240
|
// If the actual size of this tx would exceed block size, skip it
|
|
238
241
|
const txSize = processedTx.txEffect.getDASize();
|
|
239
242
|
if (maxBlockSize !== undefined && totalSizeInBytes + txSize > maxBlockSize) {
|
|
240
|
-
this.log.
|
|
243
|
+
this.log.debug(`Skipping processed tx ${txHash} sized ${txSize} due to max block size.`, {
|
|
241
244
|
txHash,
|
|
242
245
|
sizeInBytes: txSize,
|
|
243
246
|
totalSizeInBytes,
|
|
@@ -334,8 +337,8 @@ export class PublicProcessor implements Traceable {
|
|
|
334
337
|
}
|
|
335
338
|
}
|
|
336
339
|
|
|
337
|
-
@trackSpan('PublicProcessor.processTx',
|
|
338
|
-
private async processTx(tx: Tx, deadline
|
|
340
|
+
@trackSpan('PublicProcessor.processTx', tx => ({ [Attributes.TX_HASH]: tx.getTxHash().toString() }))
|
|
341
|
+
private async processTx(tx: Tx, deadline: Date | undefined): Promise<[ProcessedTx, NestedProcessReturnValues[]]> {
|
|
339
342
|
const [time, [processedTx, returnValues]] = await elapsed(() => this.processTxWithinDeadline(tx, deadline));
|
|
340
343
|
|
|
341
344
|
this.log.verbose(
|
|
@@ -401,17 +404,29 @@ export class PublicProcessor implements Traceable {
|
|
|
401
404
|
/** Processes the given tx within deadline. Returns timeout if deadline is hit. */
|
|
402
405
|
private async processTxWithinDeadline(
|
|
403
406
|
tx: Tx,
|
|
404
|
-
deadline
|
|
407
|
+
deadline: Date | undefined,
|
|
405
408
|
): Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined]> {
|
|
406
|
-
const
|
|
409
|
+
const innerProcessFn: () => Promise<[ProcessedTx, NestedProcessReturnValues[] | undefined]> = tx.hasPublicCalls()
|
|
407
410
|
? () => this.processTxWithPublicCalls(tx)
|
|
408
411
|
: () => this.processPrivateOnlyTx(tx);
|
|
409
412
|
|
|
413
|
+
// Fake a delay per tx if instructed (used for tests)
|
|
414
|
+
const fakeDelayPerTxMs = this.opts.fakeProcessingDelayPerTxMs;
|
|
415
|
+
const processFn =
|
|
416
|
+
fakeDelayPerTxMs && fakeDelayPerTxMs > 0
|
|
417
|
+
? async () => {
|
|
418
|
+
const result = await innerProcessFn();
|
|
419
|
+
this.log.warn(`Sleeping ${fakeDelayPerTxMs}ms after processing tx ${tx.getTxHash().toString()}`);
|
|
420
|
+
await sleep(fakeDelayPerTxMs);
|
|
421
|
+
return result;
|
|
422
|
+
}
|
|
423
|
+
: innerProcessFn;
|
|
424
|
+
|
|
410
425
|
if (!deadline) {
|
|
411
426
|
return await processFn();
|
|
412
427
|
}
|
|
413
428
|
|
|
414
|
-
const txHash =
|
|
429
|
+
const txHash = tx.getTxHash();
|
|
415
430
|
const timeout = +deadline - this.dateProvider.now();
|
|
416
431
|
if (timeout <= 0) {
|
|
417
432
|
throw new PublicProcessorTimeoutError();
|
|
@@ -458,8 +473,8 @@ export class PublicProcessor implements Traceable {
|
|
|
458
473
|
return new PublicDataWrite(leafSlot, updatedBalance);
|
|
459
474
|
}
|
|
460
475
|
|
|
461
|
-
@trackSpan('PublicProcessor.processPrivateOnlyTx',
|
|
462
|
-
[Attributes.TX_HASH]:
|
|
476
|
+
@trackSpan('PublicProcessor.processPrivateOnlyTx', (tx: Tx) => ({
|
|
477
|
+
[Attributes.TX_HASH]: tx.getTxHash().toString(),
|
|
463
478
|
}))
|
|
464
479
|
private async processPrivateOnlyTx(tx: Tx): Promise<[ProcessedTx, undefined]> {
|
|
465
480
|
const gasFees = this.globalVariables.gasFees;
|
|
@@ -467,18 +482,18 @@ export class PublicProcessor implements Traceable {
|
|
|
467
482
|
|
|
468
483
|
const feePaymentPublicDataWrite = await this.performFeePaymentPublicDataWrite(transactionFee, tx.data.feePayer);
|
|
469
484
|
|
|
470
|
-
const processedTx =
|
|
485
|
+
const processedTx = makeProcessedTxFromPrivateOnlyTx(
|
|
471
486
|
tx,
|
|
472
487
|
transactionFee,
|
|
473
488
|
feePaymentPublicDataWrite,
|
|
474
489
|
this.globalVariables,
|
|
475
490
|
);
|
|
476
491
|
|
|
477
|
-
this.metrics.
|
|
492
|
+
this.metrics.recordClassPublication(
|
|
478
493
|
...tx
|
|
479
494
|
.getContractClassLogs()
|
|
480
|
-
.filter(log =>
|
|
481
|
-
.map(log =>
|
|
495
|
+
.filter(log => ContractClassPublishedEvent.isContractClassPublishedEvent(log))
|
|
496
|
+
.map(log => ContractClassPublishedEvent.fromLog(log)),
|
|
482
497
|
);
|
|
483
498
|
|
|
484
499
|
// Fee payment insertion has already been done. Do the rest.
|
|
@@ -492,8 +507,8 @@ export class PublicProcessor implements Traceable {
|
|
|
492
507
|
return [processedTx, undefined];
|
|
493
508
|
}
|
|
494
509
|
|
|
495
|
-
@trackSpan('PublicProcessor.processTxWithPublicCalls',
|
|
496
|
-
[Attributes.TX_HASH]:
|
|
510
|
+
@trackSpan('PublicProcessor.processTxWithPublicCalls', tx => ({
|
|
511
|
+
[Attributes.TX_HASH]: tx.getTxHash().toString(),
|
|
497
512
|
}))
|
|
498
513
|
private async processTxWithPublicCalls(tx: Tx): Promise<[ProcessedTx, NestedProcessReturnValues[]]> {
|
|
499
514
|
const timer = new Timer();
|
|
@@ -517,23 +532,17 @@ export class PublicProcessor implements Traceable {
|
|
|
517
532
|
const contractClassLogs = revertCode.isOK()
|
|
518
533
|
? tx.getContractClassLogs()
|
|
519
534
|
: tx.getSplitContractClassLogs(false /* revertible */);
|
|
520
|
-
this.metrics.
|
|
535
|
+
this.metrics.recordClassPublication(
|
|
521
536
|
...contractClassLogs
|
|
522
|
-
.filter(log =>
|
|
523
|
-
.map(log =>
|
|
537
|
+
.filter(log => ContractClassPublishedEvent.isContractClassPublishedEvent(log))
|
|
538
|
+
.map(log => ContractClassPublishedEvent.fromLog(log)),
|
|
524
539
|
);
|
|
525
540
|
|
|
526
541
|
const phaseCount = processedPhases.length;
|
|
527
542
|
const durationMs = timer.ms();
|
|
528
543
|
this.metrics.recordTx(phaseCount, durationMs, gasUsed.publicGas);
|
|
529
544
|
|
|
530
|
-
const processedTx =
|
|
531
|
-
tx,
|
|
532
|
-
avmProvingRequest,
|
|
533
|
-
gasUsed,
|
|
534
|
-
revertCode,
|
|
535
|
-
revertReason,
|
|
536
|
-
);
|
|
545
|
+
const processedTx = makeProcessedTxFromTxWithPublicCalls(tx, avmProvingRequest, gasUsed, revertCode, revertReason);
|
|
537
546
|
|
|
538
547
|
const returnValues = processedPhases.find(({ phase }) => phase === TxExecutionPhase.APP_LOGIC)?.returnValues ?? [];
|
|
539
548
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ContractClassPublishedEvent } from '@aztec/protocol-contracts/class-registry';
|
|
2
2
|
import type { Gas } from '@aztec/stdlib/gas';
|
|
3
3
|
import type { TxExecutionPhase } from '@aztec/stdlib/tx';
|
|
4
4
|
import {
|
|
@@ -137,7 +137,7 @@ export class PublicProcessorMetrics {
|
|
|
137
137
|
this.phaseCount.add(1, { [Attributes.TX_PHASE_NAME]: phaseName, [Attributes.OK]: false });
|
|
138
138
|
}
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
recordClassPublication(...events: ContractClassPublishedEvent[]) {
|
|
141
141
|
let totalBytecode = 0;
|
|
142
142
|
for (const event of events) {
|
|
143
143
|
totalBytecode += event.packedPublicBytecode.length;
|
|
@@ -7,7 +7,7 @@ import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
7
7
|
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
8
8
|
|
|
9
9
|
import { PublicTxSimulationTester } from '../../fixtures/public_tx_simulation_tester.js';
|
|
10
|
-
import {
|
|
10
|
+
import { setUpToken } from './token_test.js';
|
|
11
11
|
|
|
12
12
|
const INITIAL_TOKEN_BALANCE = 1_000_000_000n;
|
|
13
13
|
/**
|
|
@@ -22,9 +22,9 @@ export async function ammTest(tester: PublicTxSimulationTester, logger: Logger)
|
|
|
22
22
|
const sender = AztecAddress.fromNumber(111);
|
|
23
23
|
|
|
24
24
|
logger.debug(`Deploying tokens`);
|
|
25
|
-
const token0 = await
|
|
26
|
-
const token1 = await
|
|
27
|
-
const liquidityToken = await
|
|
25
|
+
const token0 = await setUpToken(tester, admin, /*seed=*/ 0);
|
|
26
|
+
const token1 = await setUpToken(tester, admin, /*seed=*/ 1);
|
|
27
|
+
const liquidityToken = await setUpToken(tester, admin, /*seed=*/ 2);
|
|
28
28
|
logger.debug(`Deploying AMM`);
|
|
29
29
|
const constructorArgs = [token0, token1, liquidityToken];
|
|
30
30
|
const amm = await tester.registerAndDeployContract(
|
|
@@ -13,7 +13,7 @@ export async function tokenTest(tester: PublicTxSimulationTester, logger: Logger
|
|
|
13
13
|
const sender = AztecAddress.fromNumber(111);
|
|
14
14
|
const receiver = AztecAddress.fromNumber(222);
|
|
15
15
|
|
|
16
|
-
const token = await
|
|
16
|
+
const token = await setUpToken(tester, admin);
|
|
17
17
|
|
|
18
18
|
const mintAmount = 100n;
|
|
19
19
|
const mintResult = await tester.simulateTxWithLabel(
|
|
@@ -84,7 +84,7 @@ export async function tokenTest(tester: PublicTxSimulationTester, logger: Logger
|
|
|
84
84
|
logger.info(`TokenContract public tx simulator test took ${endTime - startTime}ms\n`);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
export async function
|
|
87
|
+
export async function setUpToken(tester: PublicTxSimulationTester, admin: AztecAddress, seed = 0) {
|
|
88
88
|
const constructorArgs = [admin, /*name=*/ 'Token', /*symbol=*/ 'TOK', /*decimals=*/ new Fr(18)];
|
|
89
89
|
const token = await tester.registerAndDeployContract(
|
|
90
90
|
constructorArgs,
|
|
@@ -39,13 +39,6 @@ export class MeasuredPublicTxSimulator extends PublicTxSimulator {
|
|
|
39
39
|
return avmResult;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
protected override async computeTxHash(tx: Tx) {
|
|
43
|
-
const timer = new Timer();
|
|
44
|
-
const txHash = await super.computeTxHash(tx);
|
|
45
|
-
this.metrics.recordTxHashComputation(timer.ms());
|
|
46
|
-
return txHash;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
42
|
protected override async insertNonRevertiblesFromPrivate(context: PublicTxContext, tx: Tx) {
|
|
50
43
|
const timer = new Timer();
|
|
51
44
|
await super.insertNonRevertiblesFromPrivate(context, tx);
|
|
@@ -119,7 +119,7 @@ export class PublicTxContext {
|
|
|
119
119
|
const gasAllocatedToPublicTeardown = clampedGasSettings.teardownGasLimits;
|
|
120
120
|
|
|
121
121
|
return new PublicTxContext(
|
|
122
|
-
|
|
122
|
+
tx.getTxHash(),
|
|
123
123
|
new PhaseStateManager(txStateManager),
|
|
124
124
|
await txStateManager.getTreeSnapshots(),
|
|
125
125
|
globalVariables,
|
|
@@ -143,10 +143,8 @@ export class PublicTxContext {
|
|
|
143
143
|
* All phases have been processed.
|
|
144
144
|
* Actual transaction fee and actual total consumed gas can now be queried.
|
|
145
145
|
*/
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
await this.state.mergeForkedState();
|
|
149
|
-
}
|
|
146
|
+
halt() {
|
|
147
|
+
assert(!this.state.isForked(), 'Cannot halt when state is forked');
|
|
150
148
|
this.halted = true;
|
|
151
149
|
}
|
|
152
150
|
|
|
@@ -165,11 +163,6 @@ export class PublicTxContext {
|
|
|
165
163
|
}
|
|
166
164
|
if (phase === TxExecutionPhase.SETUP) {
|
|
167
165
|
this.log.warn(`Setup phase reverted! The transaction will be thrown out.`);
|
|
168
|
-
if (revertReason) {
|
|
169
|
-
throw revertReason;
|
|
170
|
-
} else {
|
|
171
|
-
throw new Error(`Setup phase reverted! The transaction will be thrown out. ${culprit} failed`);
|
|
172
|
-
}
|
|
173
166
|
} else if (phase === TxExecutionPhase.APP_LOGIC) {
|
|
174
167
|
this.revertCode = RevertCode.APP_LOGIC_REVERTED;
|
|
175
168
|
} else if (phase === TxExecutionPhase.TEARDOWN) {
|
|
@@ -338,6 +331,15 @@ export class PublicTxContext {
|
|
|
338
331
|
);
|
|
339
332
|
})();
|
|
340
333
|
|
|
334
|
+
// Count before padding.
|
|
335
|
+
const accumulatedDataArrayLengths = new AvmAccumulatedDataArrayLengths(
|
|
336
|
+
avmNoteHashes.length,
|
|
337
|
+
avmNullifiers.length,
|
|
338
|
+
avmL2ToL1Msgs.length,
|
|
339
|
+
finalPublicLogs.length,
|
|
340
|
+
finalPublicDataWrites.length,
|
|
341
|
+
);
|
|
342
|
+
|
|
341
343
|
const accumulatedData = new AvmAccumulatedData(
|
|
342
344
|
/*noteHashes=*/ padArrayEnd(
|
|
343
345
|
avmNoteHashes.map(n => n.value),
|
|
@@ -376,14 +378,6 @@ export class PublicTxContext {
|
|
|
376
378
|
countAccumulatedItems(from.nullifiers),
|
|
377
379
|
countAccumulatedItems(from.l2ToL1Msgs),
|
|
378
380
|
);
|
|
379
|
-
const getAvmAccumulatedDataArrayLengths = (from: AvmAccumulatedData) =>
|
|
380
|
-
new AvmAccumulatedDataArrayLengths(
|
|
381
|
-
from.noteHashes.length,
|
|
382
|
-
from.nullifiers.length,
|
|
383
|
-
from.l2ToL1Msgs.length,
|
|
384
|
-
from.publicLogs.length,
|
|
385
|
-
from.publicDataWrites.length,
|
|
386
|
-
);
|
|
387
381
|
|
|
388
382
|
return new AvmCircuitPublicInputs(
|
|
389
383
|
this.globalVariables,
|
|
@@ -416,7 +410,7 @@ export class PublicTxContext {
|
|
|
416
410
|
convertAccumulatedData(this.revertibleAccumulatedDataFromPrivate),
|
|
417
411
|
endTreeSnapshots,
|
|
418
412
|
this.getTotalGasUsed(),
|
|
419
|
-
|
|
413
|
+
accumulatedDataArrayLengths,
|
|
420
414
|
accumulatedData,
|
|
421
415
|
/*transactionFee=*/ this.getTransactionFeeUnsafe(),
|
|
422
416
|
/*isReverted=*/ !this.revertCode.isOK(),
|