@aztec/simulator 0.82.2 → 0.82.3-nightly.20250403
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/README.md +6 -0
- package/dest/private/acvm/oracle/oracle.d.ts +3 -2
- package/dest/private/acvm/oracle/oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/oracle.js +9 -6
- package/dest/private/acvm/oracle/typed_oracle.d.ts +4 -3
- package/dest/private/acvm/oracle/typed_oracle.d.ts.map +1 -1
- package/dest/private/acvm/oracle/typed_oracle.js +4 -1
- package/dest/private/execution_data_provider.d.ts +20 -16
- package/dest/private/execution_data_provider.d.ts.map +1 -1
- package/dest/private/private_execution_oracle.d.ts +1 -1
- package/dest/private/private_execution_oracle.d.ts.map +1 -1
- package/dest/private/private_execution_oracle.js +2 -6
- package/dest/private/unconstrained_execution_oracle.d.ts +4 -2
- package/dest/private/unconstrained_execution_oracle.d.ts.map +1 -1
- package/dest/private/unconstrained_execution_oracle.js +5 -6
- package/dest/public/avm/avm_context.d.ts +3 -3
- package/dest/public/avm/avm_context.d.ts.map +1 -1
- package/dest/public/avm/avm_contract_call_result.d.ts +4 -2
- package/dest/public/avm/avm_contract_call_result.d.ts.map +1 -1
- package/dest/public/avm/avm_contract_call_result.js +9 -5
- package/dest/public/avm/avm_machine_state.d.ts +2 -0
- package/dest/public/avm/avm_machine_state.d.ts.map +1 -1
- package/dest/public/avm/avm_machine_state.js +2 -0
- package/dest/public/avm/avm_simulator.d.ts +2 -2
- package/dest/public/avm/avm_simulator.d.ts.map +1 -1
- package/dest/public/avm/avm_simulator.js +5 -6
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts +2 -2
- package/dest/public/avm/fixtures/avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/avm_simulation_tester.js +3 -4
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts +1 -2
- package/dest/public/avm/fixtures/base_avm_simulation_tester.d.ts.map +1 -1
- package/dest/public/avm/fixtures/base_avm_simulation_tester.js +0 -5
- package/dest/public/avm/fixtures/index.d.ts +6 -5
- package/dest/public/avm/fixtures/index.d.ts.map +1 -1
- package/dest/public/avm/fixtures/index.js +3 -3
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts +3 -2
- package/dest/public/avm/fixtures/simple_contract_data_source.d.ts.map +1 -1
- package/dest/public/avm/fixtures/simple_contract_data_source.js +30 -6
- package/dest/public/avm/index.d.ts +0 -1
- package/dest/public/avm/index.d.ts.map +1 -1
- package/dest/public/avm/index.js +0 -1
- package/dest/public/avm/opcodes/accrued_substate.d.ts.map +1 -1
- package/dest/public/avm/opcodes/accrued_substate.js +1 -1
- package/dest/public/avm/opcodes/external_calls.d.ts.map +1 -1
- package/dest/public/avm/opcodes/external_calls.js +2 -0
- package/dest/public/avm/opcodes/memory.d.ts.map +1 -1
- package/dest/public/avm/opcodes/memory.js +8 -10
- package/dest/public/avm/serialization/instruction_serialization.d.ts +5 -2
- package/dest/public/avm/serialization/instruction_serialization.d.ts.map +1 -1
- package/dest/public/avm/serialization/instruction_serialization.js +25 -7
- package/dest/public/avm/test_utils.d.ts +1 -1
- package/dest/public/avm/test_utils.d.ts.map +1 -1
- package/dest/public/executor_metrics.d.ts +11 -3
- package/dest/public/executor_metrics.d.ts.map +1 -1
- package/dest/public/executor_metrics.js +40 -6
- package/dest/public/executor_metrics_interface.d.ts +10 -0
- package/dest/public/executor_metrics_interface.d.ts.map +1 -0
- package/dest/public/executor_metrics_interface.js +1 -0
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts +12 -6
- package/dest/public/fixtures/public_tx_simulation_tester.d.ts.map +1 -1
- package/dest/public/fixtures/public_tx_simulation_tester.js +39 -19
- package/dest/public/hinting_db_sources.d.ts +26 -3
- package/dest/public/hinting_db_sources.d.ts.map +1 -1
- package/dest/public/hinting_db_sources.js +134 -1
- package/dest/public/index.d.ts +1 -1
- package/dest/public/index.d.ts.map +1 -1
- package/dest/public/index.js +1 -1
- package/dest/public/public_db_sources.d.ts +2 -3
- package/dest/public/public_db_sources.d.ts.map +1 -1
- package/dest/public/public_db_sources.js +26 -16
- package/dest/public/public_processor/public_processor.d.ts +4 -4
- package/dest/public/public_processor/public_processor.d.ts.map +1 -1
- package/dest/public/public_processor/public_processor.js +7 -28
- package/dest/public/public_tx_simulator/apps_tests/amm_test.d.ts +9 -0
- package/dest/public/public_tx_simulator/apps_tests/amm_test.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/apps_tests/amm_test.js +237 -0
- package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts +7 -0
- package/dest/public/public_tx_simulator/apps_tests/token_test.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/apps_tests/token_test.js +109 -0
- package/dest/public/public_tx_simulator/index.d.ts +3 -0
- package/dest/public/public_tx_simulator/index.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/index.js +2 -0
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts +23 -0
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/measured_public_tx_simulator.js +58 -0
- package/dest/public/public_tx_simulator/public_tx_context.d.ts +5 -5
- package/dest/public/public_tx_simulator/public_tx_context.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_context.js +10 -8
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts +16 -16
- package/dest/public/public_tx_simulator/public_tx_simulator.d.ts.map +1 -1
- package/dest/public/public_tx_simulator/public_tx_simulator.js +25 -65
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts +19 -0
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.d.ts.map +1 -0
- package/dest/public/public_tx_simulator/telemetry_public_tx_simulator.js +39 -0
- package/dest/public/state_manager/index.d.ts +2 -0
- package/dest/public/state_manager/index.d.ts.map +1 -0
- package/dest/public/state_manager/index.js +1 -0
- package/dest/public/{avm/journal → state_manager}/nullifiers.d.ts +1 -1
- package/dest/public/state_manager/nullifiers.d.ts.map +1 -0
- package/dest/public/{avm/journal → state_manager}/public_storage.d.ts +1 -1
- package/dest/public/state_manager/public_storage.d.ts.map +1 -0
- package/dest/public/{avm/journal/journal.d.ts → state_manager/state_manager.d.ts} +10 -10
- package/dest/public/state_manager/state_manager.d.ts.map +1 -0
- package/dest/public/{avm/journal/journal.js → state_manager/state_manager.js} +5 -5
- package/dest/public/test_executor_metrics.d.ts +43 -0
- package/dest/public/test_executor_metrics.d.ts.map +1 -0
- package/dest/public/test_executor_metrics.js +158 -0
- package/package.json +14 -14
- package/src/private/acvm/oracle/oracle.ts +26 -5
- package/src/private/acvm/oracle/typed_oracle.ts +14 -3
- package/src/private/execution_data_provider.ts +34 -18
- package/src/private/private_execution_oracle.ts +2 -13
- package/src/private/unconstrained_execution_oracle.ts +22 -15
- package/src/public/avm/avm_context.ts +2 -2
- package/src/public/avm/avm_contract_call_result.ts +15 -3
- package/src/public/avm/avm_machine_state.ts +5 -0
- package/src/public/avm/avm_simulator.ts +20 -9
- package/src/public/avm/fixtures/avm_simulation_tester.ts +4 -4
- package/src/public/avm/fixtures/base_avm_simulation_tester.ts +1 -7
- package/src/public/avm/fixtures/index.ts +7 -7
- package/src/public/avm/fixtures/simple_contract_data_source.ts +33 -6
- package/src/public/avm/index.ts +0 -1
- package/src/public/avm/opcodes/accrued_substate.ts +1 -1
- package/src/public/avm/opcodes/external_calls.ts +3 -0
- package/src/public/avm/opcodes/memory.ts +8 -10
- package/src/public/avm/serialization/instruction_serialization.ts +24 -9
- package/src/public/avm/test_utils.ts +1 -1
- package/src/public/executor_metrics.ts +54 -6
- package/src/public/executor_metrics_interface.ts +15 -0
- package/src/public/fixtures/public_tx_simulation_tester.ts +74 -18
- package/src/public/hinting_db_sources.ts +228 -3
- package/src/public/index.ts +1 -1
- package/src/public/public_db_sources.ts +36 -23
- package/src/public/public_processor/public_processor.ts +8 -28
- package/src/public/public_tx_simulator/apps_tests/amm_test.ts +316 -0
- package/src/public/public_tx_simulator/apps_tests/token_test.ts +138 -0
- package/src/public/public_tx_simulator/index.ts +2 -0
- package/src/public/public_tx_simulator/measured_public_tx_simulator.ts +111 -0
- package/src/public/public_tx_simulator/public_tx_context.ts +13 -17
- package/src/public/public_tx_simulator/public_tx_simulator.ts +35 -79
- package/src/public/public_tx_simulator/telemetry_public_tx_simulator.ts +62 -0
- package/src/public/state_manager/index.ts +1 -0
- package/src/public/{avm/journal → state_manager}/nullifiers.ts +1 -1
- package/src/public/{avm/journal → state_manager}/public_storage.ts +1 -1
- package/src/public/{avm/journal/journal.ts → state_manager/state_manager.ts} +20 -13
- package/src/public/test_executor_metrics.ts +222 -0
- package/dest/public/avm/journal/index.d.ts +0 -2
- package/dest/public/avm/journal/index.d.ts.map +0 -1
- package/dest/public/avm/journal/index.js +0 -1
- package/dest/public/avm/journal/journal.d.ts.map +0 -1
- package/dest/public/avm/journal/nullifiers.d.ts.map +0 -1
- package/dest/public/avm/journal/public_storage.d.ts.map +0 -1
- package/src/public/avm/journal/index.ts +0 -1
- /package/dest/public/{avm/journal → state_manager}/nullifiers.js +0 -0
- /package/dest/public/{avm/journal → state_manager}/public_storage.js +0 -0
|
@@ -1,21 +1,45 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import type { IndexedTreeLeafPreimage, SiblingPath } from '@aztec/foundation/trees';
|
|
2
4
|
import type { FunctionSelector } from '@aztec/stdlib/abi';
|
|
3
5
|
import {
|
|
4
6
|
AvmBytecodeCommitmentHint,
|
|
5
7
|
AvmContractClassHint,
|
|
6
8
|
AvmContractInstanceHint,
|
|
7
9
|
type AvmExecutionHints,
|
|
10
|
+
AvmGetLeafPreimageHintNullifierTree,
|
|
11
|
+
AvmGetLeafPreimageHintPublicDataTree,
|
|
12
|
+
AvmGetLeafValueHint,
|
|
13
|
+
AvmGetPreviousValueIndexHint,
|
|
14
|
+
AvmGetSiblingPathHint,
|
|
15
|
+
AvmSequentialInsertHintNullifierTree,
|
|
16
|
+
AvmSequentialInsertHintPublicDataTree,
|
|
8
17
|
} from '@aztec/stdlib/avm';
|
|
9
18
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
10
19
|
import type { ContractClassPublic, ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
20
|
+
import {
|
|
21
|
+
AppendOnlyTreeSnapshot,
|
|
22
|
+
type IndexedTreeId,
|
|
23
|
+
MerkleTreeId,
|
|
24
|
+
type MerkleTreeLeafType,
|
|
25
|
+
NullifierLeaf,
|
|
26
|
+
NullifierLeafPreimage,
|
|
27
|
+
PublicDataTreeLeaf,
|
|
28
|
+
PublicDataTreeLeafPreimage,
|
|
29
|
+
type SequentialInsertionResult,
|
|
30
|
+
getTreeName,
|
|
31
|
+
} from '@aztec/stdlib/trees';
|
|
32
|
+
|
|
33
|
+
import { strict as assert } from 'assert';
|
|
11
34
|
|
|
12
|
-
import type { PublicContractsDBInterface } from '../
|
|
35
|
+
import type { PublicContractsDBInterface } from '../common/db_interfaces.js';
|
|
36
|
+
import { PublicTreesDB } from './public_db_sources.js';
|
|
13
37
|
|
|
14
38
|
/**
|
|
15
39
|
* A public contracts database that forwards requests and collects AVM hints.
|
|
16
40
|
*/
|
|
17
41
|
export class HintingPublicContractsDB implements PublicContractsDBInterface {
|
|
18
|
-
constructor(private readonly db: PublicContractsDBInterface,
|
|
42
|
+
constructor(private readonly db: PublicContractsDBInterface, private hints: AvmExecutionHints) {}
|
|
19
43
|
|
|
20
44
|
public async getContractInstance(
|
|
21
45
|
address: AztecAddress,
|
|
@@ -69,3 +93,204 @@ export class HintingPublicContractsDB implements PublicContractsDBInterface {
|
|
|
69
93
|
return await this.db.getDebugFunctionName(contractAddress, selector);
|
|
70
94
|
}
|
|
71
95
|
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* A public trees database that forwards requests and collects AVM hints.
|
|
99
|
+
*/
|
|
100
|
+
export class HintingPublicTreesDB extends PublicTreesDB {
|
|
101
|
+
private static readonly log: Logger = createLogger('HintingPublicTreesDB');
|
|
102
|
+
|
|
103
|
+
constructor(db: PublicTreesDB, private hints: AvmExecutionHints) {
|
|
104
|
+
super(db);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Getters.
|
|
108
|
+
public override async getSiblingPath<N extends number>(treeId: MerkleTreeId, index: bigint): Promise<SiblingPath<N>> {
|
|
109
|
+
const path = await super.getSiblingPath<N>(treeId, index);
|
|
110
|
+
const key = await this.getHintKey(treeId);
|
|
111
|
+
this.hints.getSiblingPathHints.push(new AvmGetSiblingPathHint(key, treeId, index, path.toFields()));
|
|
112
|
+
return Promise.resolve(path);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public override async getPreviousValueIndex<ID extends IndexedTreeId>(
|
|
116
|
+
treeId: ID,
|
|
117
|
+
value: bigint,
|
|
118
|
+
): Promise<
|
|
119
|
+
| {
|
|
120
|
+
index: bigint;
|
|
121
|
+
alreadyPresent: boolean;
|
|
122
|
+
}
|
|
123
|
+
| undefined
|
|
124
|
+
> {
|
|
125
|
+
const result = await super.getPreviousValueIndex(treeId, value);
|
|
126
|
+
if (result === undefined) {
|
|
127
|
+
throw new Error(
|
|
128
|
+
`getPreviousValueIndex(${getTreeName(
|
|
129
|
+
treeId,
|
|
130
|
+
)}, ${value}}) returned undefined. Possible wrong tree setup or corrupted state.`,
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
const key = await this.getHintKey(treeId);
|
|
134
|
+
this.hints.getPreviousValueIndexHints.push(
|
|
135
|
+
new AvmGetPreviousValueIndexHint(key, treeId, new Fr(value), result.index, result.alreadyPresent),
|
|
136
|
+
);
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
public override async getLeafPreimage<ID extends IndexedTreeId>(
|
|
141
|
+
treeId: ID,
|
|
142
|
+
index: bigint,
|
|
143
|
+
): Promise<IndexedTreeLeafPreimage | undefined> {
|
|
144
|
+
const preimage = await super.getLeafPreimage<ID>(treeId, index);
|
|
145
|
+
if (preimage) {
|
|
146
|
+
const key = await this.getHintKey(treeId);
|
|
147
|
+
|
|
148
|
+
switch (treeId) {
|
|
149
|
+
case MerkleTreeId.PUBLIC_DATA_TREE:
|
|
150
|
+
this.hints.getLeafPreimageHintsPublicDataTree.push(
|
|
151
|
+
new AvmGetLeafPreimageHintPublicDataTree(key, index, preimage as PublicDataTreeLeafPreimage),
|
|
152
|
+
);
|
|
153
|
+
break;
|
|
154
|
+
case MerkleTreeId.NULLIFIER_TREE:
|
|
155
|
+
this.hints.getLeafPreimageHintsNullifierTree.push(
|
|
156
|
+
new AvmGetLeafPreimageHintNullifierTree(key, index, preimage as NullifierLeafPreimage),
|
|
157
|
+
);
|
|
158
|
+
break;
|
|
159
|
+
default:
|
|
160
|
+
// Use getLeafValue for the other trees.
|
|
161
|
+
throw new Error('getLeafPreimage only supported for PublicDataTree and NullifierTree!');
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return preimage;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public override async getLeafValue<ID extends MerkleTreeId>(
|
|
170
|
+
treeId: ID,
|
|
171
|
+
index: bigint,
|
|
172
|
+
): Promise<MerkleTreeLeafType<typeof treeId> | undefined> {
|
|
173
|
+
// Use getLeafPreimage for PublicDataTree and NullifierTree.
|
|
174
|
+
assert(treeId == MerkleTreeId.NOTE_HASH_TREE || treeId == MerkleTreeId.L1_TO_L2_MESSAGE_TREE);
|
|
175
|
+
|
|
176
|
+
const value = await super.getLeafValue<ID>(treeId, index);
|
|
177
|
+
if (value) {
|
|
178
|
+
const key = await this.getHintKey(treeId);
|
|
179
|
+
// We can cast to Fr because we know the type of the tree.
|
|
180
|
+
this.hints.getLeafValueHints.push(new AvmGetLeafValueHint(key, treeId, index, value as Fr));
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return value;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// State modification.
|
|
187
|
+
// FIXME(fcarreiro): This is a horrible interface (in the merkle ops). It's receiving the leaves as buffers,
|
|
188
|
+
// from a leaf class that is NOT the one that will be used to write. Make this type safe.
|
|
189
|
+
public override async sequentialInsert<TreeHeight extends number, ID extends IndexedTreeId>(
|
|
190
|
+
treeId: ID,
|
|
191
|
+
leaves: Buffer[],
|
|
192
|
+
): Promise<SequentialInsertionResult<TreeHeight>> {
|
|
193
|
+
// Use appendLeaf for NoteHashTree and L1ToL2MessageTree.
|
|
194
|
+
assert(treeId == MerkleTreeId.PUBLIC_DATA_TREE || treeId == MerkleTreeId.NULLIFIER_TREE);
|
|
195
|
+
// We only support 1 leaf at a time for now. Can easily be extended.
|
|
196
|
+
assert(leaves.length === 1, 'sequentialInsert supports only one leaf at a time!');
|
|
197
|
+
|
|
198
|
+
const beforeState = await this.getHintKey(treeId);
|
|
199
|
+
|
|
200
|
+
const result = await super.sequentialInsert<TreeHeight, ID>(treeId, leaves);
|
|
201
|
+
|
|
202
|
+
const afterState = await this.getHintKey(treeId);
|
|
203
|
+
HintingPublicTreesDB.log.debug(
|
|
204
|
+
`Evolved tree state (${getTreeName(treeId)}): ${beforeState.root}, ${beforeState.nextAvailableLeafIndex} -> ${
|
|
205
|
+
afterState.root
|
|
206
|
+
}, ${afterState.nextAvailableLeafIndex}.`,
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
switch (treeId) {
|
|
210
|
+
case MerkleTreeId.PUBLIC_DATA_TREE:
|
|
211
|
+
this.hints.sequentialInsertHintsPublicDataTree.push(
|
|
212
|
+
new AvmSequentialInsertHintPublicDataTree(
|
|
213
|
+
beforeState,
|
|
214
|
+
afterState,
|
|
215
|
+
treeId,
|
|
216
|
+
PublicDataTreeLeaf.fromBuffer(leaves[0]),
|
|
217
|
+
{
|
|
218
|
+
leaf: result.lowLeavesWitnessData[0].leafPreimage as PublicDataTreeLeafPreimage,
|
|
219
|
+
index: result.lowLeavesWitnessData[0].index,
|
|
220
|
+
path: result.lowLeavesWitnessData[0].siblingPath.toFields(),
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
leaf: result.insertionWitnessData[0].leafPreimage as PublicDataTreeLeafPreimage,
|
|
224
|
+
index: result.insertionWitnessData[0].index,
|
|
225
|
+
path: result.insertionWitnessData[0].siblingPath.toFields(),
|
|
226
|
+
},
|
|
227
|
+
),
|
|
228
|
+
);
|
|
229
|
+
break;
|
|
230
|
+
case MerkleTreeId.NULLIFIER_TREE:
|
|
231
|
+
this.hints.sequentialInsertHintsNullifierTree.push(
|
|
232
|
+
new AvmSequentialInsertHintNullifierTree(
|
|
233
|
+
beforeState,
|
|
234
|
+
afterState,
|
|
235
|
+
treeId,
|
|
236
|
+
NullifierLeaf.fromBuffer(leaves[0]),
|
|
237
|
+
{
|
|
238
|
+
leaf: result.lowLeavesWitnessData[0].leafPreimage as NullifierLeafPreimage,
|
|
239
|
+
index: result.lowLeavesWitnessData[0].index,
|
|
240
|
+
path: result.lowLeavesWitnessData[0].siblingPath.toFields(),
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
leaf: result.insertionWitnessData[0].leafPreimage as NullifierLeafPreimage,
|
|
244
|
+
index: result.insertionWitnessData[0].index,
|
|
245
|
+
path: result.insertionWitnessData[0].siblingPath.toFields(),
|
|
246
|
+
},
|
|
247
|
+
),
|
|
248
|
+
);
|
|
249
|
+
break;
|
|
250
|
+
default:
|
|
251
|
+
throw new Error('sequentialInsert only supported for PublicDataTree and NullifierTree!');
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public override async revertCheckpoint(): Promise<void> {
|
|
259
|
+
HintingPublicTreesDB.log.debug('revertCheckpoint not hinted yet!');
|
|
260
|
+
// TODO(fcarreiro): we probably want to hint on StateReference hash.
|
|
261
|
+
// WARNING: is this enough? we might actually need the number of the checkpoint or similar...
|
|
262
|
+
// We will need to keep a stack of checkpoints on the C++ side.
|
|
263
|
+
const beforeState = {
|
|
264
|
+
[MerkleTreeId.PUBLIC_DATA_TREE]: await this.getHintKey(MerkleTreeId.PUBLIC_DATA_TREE),
|
|
265
|
+
[MerkleTreeId.NULLIFIER_TREE]: await this.getHintKey(MerkleTreeId.NULLIFIER_TREE),
|
|
266
|
+
[MerkleTreeId.NOTE_HASH_TREE]: await this.getHintKey(MerkleTreeId.NOTE_HASH_TREE),
|
|
267
|
+
[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]: await this.getHintKey(MerkleTreeId.L1_TO_L2_MESSAGE_TREE),
|
|
268
|
+
[MerkleTreeId.ARCHIVE]: await this.getHintKey(MerkleTreeId.ARCHIVE),
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
await super.revertCheckpoint();
|
|
272
|
+
|
|
273
|
+
const afterState = {
|
|
274
|
+
[MerkleTreeId.PUBLIC_DATA_TREE]: await this.getHintKey(MerkleTreeId.PUBLIC_DATA_TREE),
|
|
275
|
+
[MerkleTreeId.NULLIFIER_TREE]: await this.getHintKey(MerkleTreeId.NULLIFIER_TREE),
|
|
276
|
+
[MerkleTreeId.NOTE_HASH_TREE]: await this.getHintKey(MerkleTreeId.NOTE_HASH_TREE),
|
|
277
|
+
[MerkleTreeId.L1_TO_L2_MESSAGE_TREE]: await this.getHintKey(MerkleTreeId.L1_TO_L2_MESSAGE_TREE),
|
|
278
|
+
[MerkleTreeId.ARCHIVE]: await this.getHintKey(MerkleTreeId.ARCHIVE),
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
HintingPublicTreesDB.log.debug('Evolved tree state:');
|
|
282
|
+
for (const treeId of Object.keys(beforeState)) {
|
|
283
|
+
const id: MerkleTreeId = treeId as unknown as MerkleTreeId;
|
|
284
|
+
const treeName = getTreeName(id);
|
|
285
|
+
HintingPublicTreesDB.log.debug(
|
|
286
|
+
`${treeName}: ${beforeState[id].root}, ${beforeState[id].nextAvailableLeafIndex} -> ${afterState[id].root}, ${afterState[id].nextAvailableLeafIndex}.`,
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Private methods.
|
|
292
|
+
private async getHintKey(treeId: MerkleTreeId): Promise<AppendOnlyTreeSnapshot> {
|
|
293
|
+
const treeInfo = await super.getTreeInfo(treeId);
|
|
294
|
+
return new AppendOnlyTreeSnapshot(Fr.fromBuffer(treeInfo.root), Number(treeInfo.size));
|
|
295
|
+
}
|
|
296
|
+
}
|
package/src/public/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from '../common/db_interfaces.js';
|
|
2
|
-
export * from './public_tx_simulator/
|
|
2
|
+
export * from './public_tx_simulator/index.js';
|
|
3
3
|
export * from './public_db_sources.js';
|
|
4
4
|
export { PublicProcessor, PublicProcessorFactory } from './public_processor/public_processor.js';
|
|
5
5
|
export { SideEffectTrace } from './side_effect_trace.js';
|
|
@@ -18,7 +18,6 @@ import type {
|
|
|
18
18
|
BatchInsertionResult,
|
|
19
19
|
IndexedTreeId,
|
|
20
20
|
MerkleTreeLeafType,
|
|
21
|
-
MerkleTreeReadOperations,
|
|
22
21
|
MerkleTreeWriteOperations,
|
|
23
22
|
SequentialInsertionResult,
|
|
24
23
|
TreeInfo,
|
|
@@ -393,7 +392,7 @@ class ForwardMerkleTree implements MerkleTreeWriteOperations {
|
|
|
393
392
|
export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInterface {
|
|
394
393
|
private logger = createLogger('simulator:public-trees-db');
|
|
395
394
|
|
|
396
|
-
constructor(
|
|
395
|
+
constructor(private readonly db: MerkleTreeWriteOperations) {
|
|
397
396
|
super(db);
|
|
398
397
|
}
|
|
399
398
|
|
|
@@ -404,7 +403,22 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
404
403
|
* @returns The current value in the storage slot.
|
|
405
404
|
*/
|
|
406
405
|
public async storageRead(contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
407
|
-
|
|
406
|
+
const leafSlot = (await computePublicDataTreeLeafSlot(contract, slot)).toBigInt();
|
|
407
|
+
|
|
408
|
+
const lowLeafResult = await this.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
409
|
+
if (!lowLeafResult) {
|
|
410
|
+
throw new Error('Low leaf not found');
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
|
|
414
|
+
await this.getSiblingPath(MerkleTreeId.PUBLIC_DATA_TREE, lowLeafResult.index);
|
|
415
|
+
// Unconditionally fetching the preimage for the hints. Move it to the hinting layer?
|
|
416
|
+
const preimage = (await this.getLeafPreimage(
|
|
417
|
+
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
418
|
+
lowLeafResult.index,
|
|
419
|
+
)) as PublicDataTreeLeafPreimage;
|
|
420
|
+
|
|
421
|
+
return lowLeafResult.alreadyPresent ? preimage.leaf.value : Fr.ZERO;
|
|
408
422
|
}
|
|
409
423
|
|
|
410
424
|
/**
|
|
@@ -417,12 +431,15 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
417
431
|
public async storageWrite(contract: AztecAddress, slot: Fr, newValue: Fr): Promise<void> {
|
|
418
432
|
const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
|
|
419
433
|
const publicDataWrite = new PublicDataWrite(leafSlot, newValue);
|
|
420
|
-
await this.
|
|
434
|
+
await this.sequentialInsert(MerkleTreeId.PUBLIC_DATA_TREE, [publicDataWrite.toBuffer()]);
|
|
421
435
|
}
|
|
422
436
|
|
|
423
437
|
public async getL1ToL2LeafValue(leafIndex: bigint): Promise<Fr | undefined> {
|
|
424
438
|
const timer = new Timer();
|
|
425
|
-
const leafValue = await this.
|
|
439
|
+
const leafValue = await this.getLeafValue(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
440
|
+
// TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
|
|
441
|
+
await this.getSiblingPath(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, leafIndex);
|
|
442
|
+
|
|
426
443
|
this.logger.debug(`[DB] Fetched L1 to L2 message leaf value`, {
|
|
427
444
|
eventName: 'public-db-access',
|
|
428
445
|
duration: timer.ms(),
|
|
@@ -433,7 +450,10 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
433
450
|
|
|
434
451
|
public async getNoteHash(leafIndex: bigint): Promise<Fr | undefined> {
|
|
435
452
|
const timer = new Timer();
|
|
436
|
-
const leafValue = await this.
|
|
453
|
+
const leafValue = await this.getLeafValue(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
454
|
+
// TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
|
|
455
|
+
await this.getSiblingPath(MerkleTreeId.NOTE_HASH_TREE, leafIndex);
|
|
456
|
+
|
|
437
457
|
this.logger.debug(`[DB] Fetched note hash leaf value`, {
|
|
438
458
|
eventName: 'public-db-access',
|
|
439
459
|
duration: timer.ms(),
|
|
@@ -444,7 +464,16 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
444
464
|
|
|
445
465
|
public async getNullifierIndex(nullifier: Fr): Promise<bigint | undefined> {
|
|
446
466
|
const timer = new Timer();
|
|
447
|
-
const
|
|
467
|
+
const lowLeafResult = await this.getPreviousValueIndex(MerkleTreeId.NULLIFIER_TREE, nullifier.toBigInt());
|
|
468
|
+
if (!lowLeafResult) {
|
|
469
|
+
throw new Error('Low leaf not found');
|
|
470
|
+
}
|
|
471
|
+
// TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
|
|
472
|
+
await this.getSiblingPath(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
|
|
473
|
+
// TODO(fcarreiro): We need this for the hints. Might move it to the hinting layer.
|
|
474
|
+
await this.getLeafPreimage(MerkleTreeId.NULLIFIER_TREE, lowLeafResult.index);
|
|
475
|
+
const index = lowLeafResult.alreadyPresent ? lowLeafResult.index : undefined;
|
|
476
|
+
|
|
448
477
|
this.logger.debug(`[DB] Fetched nullifier index`, {
|
|
449
478
|
eventName: 'public-db-access',
|
|
450
479
|
duration: timer.ms(),
|
|
@@ -453,19 +482,3 @@ export class PublicTreesDB extends ForwardMerkleTree implements PublicStateDBInt
|
|
|
453
482
|
return index;
|
|
454
483
|
}
|
|
455
484
|
}
|
|
456
|
-
|
|
457
|
-
export async function readPublicState(db: MerkleTreeReadOperations, contract: AztecAddress, slot: Fr): Promise<Fr> {
|
|
458
|
-
const leafSlot = (await computePublicDataTreeLeafSlot(contract, slot)).toBigInt();
|
|
459
|
-
|
|
460
|
-
const lowLeafResult = await db.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot);
|
|
461
|
-
if (!lowLeafResult || !lowLeafResult.alreadyPresent) {
|
|
462
|
-
return Fr.ZERO;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
const preimage = (await db.getLeafPreimage(
|
|
466
|
-
MerkleTreeId.PUBLIC_DATA_TREE,
|
|
467
|
-
lowLeafResult.index,
|
|
468
|
-
)) as PublicDataTreeLeafPreimage;
|
|
469
|
-
|
|
470
|
-
return preimage.value;
|
|
471
|
-
}
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
import { ForkCheckpoint } from '@aztec/world-state/native';
|
|
35
35
|
|
|
36
36
|
import { PublicContractsDB, PublicTreesDB } from '../public_db_sources.js';
|
|
37
|
-
import { PublicTxSimulator } from '../public_tx_simulator/
|
|
37
|
+
import { type PublicTxSimulator, TelemetryPublicTxSimulator } from '../public_tx_simulator/index.js';
|
|
38
38
|
import { PublicProcessorMetrics } from './public_processor_metrics.js';
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -87,8 +87,8 @@ export class PublicProcessorFactory {
|
|
|
87
87
|
doMerkleOperations: boolean,
|
|
88
88
|
skipFeeEnforcement: boolean,
|
|
89
89
|
telemetryClient: TelemetryClient,
|
|
90
|
-
) {
|
|
91
|
-
return new
|
|
90
|
+
): PublicTxSimulator {
|
|
91
|
+
return new TelemetryPublicTxSimulator(
|
|
92
92
|
treesDB,
|
|
93
93
|
contractsDB,
|
|
94
94
|
globalVariables,
|
|
@@ -131,7 +131,8 @@ export class PublicProcessor implements Traceable {
|
|
|
131
131
|
/**
|
|
132
132
|
* Run each tx through the public circuit and the public kernel circuit if needed.
|
|
133
133
|
* @param txs - Txs to process.
|
|
134
|
-
* @param
|
|
134
|
+
* @param limits - Limits for processing the txs.
|
|
135
|
+
* @param validator - Pre-process validator and nullifier cache to use for processing the txs.
|
|
135
136
|
* @returns The list of processed txs with their circuit simulation outputs.
|
|
136
137
|
*/
|
|
137
138
|
public async process(
|
|
@@ -142,14 +143,13 @@ export class PublicProcessor implements Traceable {
|
|
|
142
143
|
maxBlockGas?: Gas;
|
|
143
144
|
deadline?: Date;
|
|
144
145
|
} = {},
|
|
145
|
-
|
|
146
|
+
validator: {
|
|
146
147
|
preprocessValidator?: TxValidator<Tx>;
|
|
147
|
-
postprocessValidator?: TxValidator<ProcessedTx>;
|
|
148
148
|
nullifierCache?: { addNullifiers: (nullifiers: Buffer[]) => void };
|
|
149
149
|
} = {},
|
|
150
150
|
): Promise<[ProcessedTx[], FailedTx[], NestedProcessReturnValues[]]> {
|
|
151
151
|
const { maxTransactions, maxBlockSize, deadline, maxBlockGas } = limits;
|
|
152
|
-
const { preprocessValidator,
|
|
152
|
+
const { preprocessValidator, nullifierCache } = validator;
|
|
153
153
|
const result: ProcessedTx[] = [];
|
|
154
154
|
const failed: FailedTx[] = [];
|
|
155
155
|
const timer = new Timer();
|
|
@@ -242,26 +242,6 @@ export class PublicProcessor implements Traceable {
|
|
|
242
242
|
continue;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
// Re-validate the transaction
|
|
246
|
-
if (postprocessValidator) {
|
|
247
|
-
// Only accept processed transactions that are not double-spends,
|
|
248
|
-
// public functions emitting nullifiers would pass earlier check but fail here.
|
|
249
|
-
// Note that we're checking all nullifiers generated in the private execution twice,
|
|
250
|
-
// we could store the ones already checked and skip them here as an optimization.
|
|
251
|
-
// TODO(palla/txs): Can we get into this case? AVM validates this. We should be able to remove it.
|
|
252
|
-
const result = await postprocessValidator.validateTx(processedTx);
|
|
253
|
-
if (result.result !== 'valid') {
|
|
254
|
-
const reason = result.reason.join(', ');
|
|
255
|
-
this.log.error(`Rejecting tx ${processedTx.hash} after processing: ${reason}.`);
|
|
256
|
-
failed.push({ tx, error: new Error(`Tx failed post-process validation: ${reason}`) });
|
|
257
|
-
// Need to revert the checkpoint here and don't go any further
|
|
258
|
-
await checkpoint.revert();
|
|
259
|
-
continue;
|
|
260
|
-
} else {
|
|
261
|
-
this.log.trace(`Tx ${txHash.toString()} is valid post processing.`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
245
|
if (!tx.hasPublicCalls()) {
|
|
266
246
|
// If there are no public calls, perform all tree insertions for side effects from private
|
|
267
247
|
// When there are public calls, the PublicTxSimulator & AVM handle tree insertions.
|
|
@@ -488,7 +468,7 @@ export class PublicProcessor implements Traceable {
|
|
|
488
468
|
if (phase.reverted) {
|
|
489
469
|
this.metrics.recordRevertedPhase(phase.phase);
|
|
490
470
|
} else {
|
|
491
|
-
this.metrics.recordPhaseDuration(phase.phase, phase.durationMs);
|
|
471
|
+
this.metrics.recordPhaseDuration(phase.phase, phase.durationMs ?? 0);
|
|
492
472
|
}
|
|
493
473
|
});
|
|
494
474
|
|