@aztec/txe 0.0.1-commit.1bea0213 → 0.0.1-commit.21ecf947b
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/oracle/interfaces.d.ts +2 -2
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +2 -2
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +3 -4
- package/dest/oracle/txe_oracle_top_level_context.d.ts +2 -2
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +87 -26
- package/dest/rpc_translator.d.ts +8 -8
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +40 -29
- package/dest/state_machine/archiver.d.ts +1 -1
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +2 -0
- package/dest/state_machine/dummy_p2p_client.d.ts +11 -8
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +21 -12
- package/dest/state_machine/index.d.ts +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +14 -9
- package/dest/state_machine/mock_epoch_cache.d.ts +3 -1
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +4 -0
- package/dest/txe_session.d.ts +1 -1
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +68 -9
- package/dest/utils/block_creation.d.ts +1 -1
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +3 -1
- package/package.json +15 -15
- package/src/oracle/interfaces.ts +1 -1
- package/src/oracle/txe_oracle_public_context.ts +3 -5
- package/src/oracle/txe_oracle_top_level_context.ts +106 -74
- package/src/rpc_translator.ts +42 -24
- package/src/state_machine/archiver.ts +2 -0
- package/src/state_machine/dummy_p2p_client.ts +29 -15
- package/src/state_machine/index.ts +24 -9
- package/src/state_machine/mock_epoch_cache.ts +5 -0
- package/src/txe_session.ts +70 -66
- package/src/utils/block_creation.ts +3 -1
package/dest/txe_session.js
CHANGED
|
@@ -3,7 +3,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { KeyStore } from '@aztec/key-store';
|
|
5
5
|
import { openTmpStore } from '@aztec/kv-store/lmdb-v2';
|
|
6
|
-
import { AddressStore, CapsuleStore, JobCoordinator, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
|
|
6
|
+
import { AddressStore, AnchorBlockStore, CapsuleStore, JobCoordinator, NoteService, NoteStore, PrivateEventStore, RecipientTaggingStore, SenderAddressBookStore, SenderTaggingStore } from '@aztec/pxe/server';
|
|
7
7
|
import { ExecutionNoteCache, ExecutionTaggingIndexCache, HashedValuesCache, Oracle, PrivateExecutionOracle, UtilityExecutionOracle } from '@aztec/pxe/simulator';
|
|
8
8
|
import { ExecutionError, WASMSimulator, createSimulationError, extractCallStack, resolveAssertionMessageFromError, toACVMWitness } from '@aztec/simulator/client';
|
|
9
9
|
import { FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
@@ -17,6 +17,7 @@ import { DEFAULT_ADDRESS } from './constants.js';
|
|
|
17
17
|
import { TXEOraclePublicContext } from './oracle/txe_oracle_public_context.js';
|
|
18
18
|
import { TXEOracleTopLevelContext } from './oracle/txe_oracle_top_level_context.js';
|
|
19
19
|
import { RPCTranslator } from './rpc_translator.js';
|
|
20
|
+
import { TXEArchiver } from './state_machine/archiver.js';
|
|
20
21
|
import { TXEStateMachine } from './state_machine/index.js';
|
|
21
22
|
import { TXEAccountStore } from './util/txe_account_store.js';
|
|
22
23
|
import { TXEContractStore } from './util/txe_contract_store.js';
|
|
@@ -96,7 +97,9 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
|
|
|
96
97
|
await contractStore.addContractArtifact(contractClass.id, artifact);
|
|
97
98
|
await contractStore.addContractInstance(instance);
|
|
98
99
|
}
|
|
99
|
-
const
|
|
100
|
+
const archiver = new TXEArchiver(store);
|
|
101
|
+
const anchorBlockStore = new AnchorBlockStore(store);
|
|
102
|
+
const stateMachine = await TXEStateMachine.create(archiver, anchorBlockStore, contractStore, noteStore);
|
|
100
103
|
const nextBlockTimestamp = BigInt(Math.floor(new Date().getTime() / 1000));
|
|
101
104
|
const version = new Fr(await stateMachine.node.getVersion());
|
|
102
105
|
const chainId = new Fr(await stateMachine.node.getChainId());
|
|
@@ -163,11 +166,11 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
|
|
|
163
166
|
}
|
|
164
167
|
async enterPrivateState(contractAddress = DEFAULT_ADDRESS, anchorBlockNumber) {
|
|
165
168
|
this.exitTopLevelState();
|
|
166
|
-
await new NoteService(this.noteStore, this.stateMachine.node, this.stateMachine.anchorBlockStore, this.currentJobId).syncNoteNullifiers(contractAddress);
|
|
167
169
|
// Private execution has two associated block numbers: the anchor block (i.e. the historical block that is used to
|
|
168
170
|
// build the proof), and the *next* block, i.e. the one we'll create once the execution ends, and which will contain
|
|
169
171
|
// a single transaction with the effects of what was done in the test.
|
|
170
172
|
const anchorBlock = await this.stateMachine.node.getBlockHeader(anchorBlockNumber ?? 'latest');
|
|
173
|
+
await new NoteService(this.noteStore, this.stateMachine.node, anchorBlock, this.currentJobId).syncNoteNullifiers(contractAddress, 'ALL_SCOPES');
|
|
171
174
|
const latestBlock = await this.stateMachine.node.getBlockHeader('latest');
|
|
172
175
|
const nextBlockGlobalVariables = makeGlobalVariables(undefined, {
|
|
173
176
|
blockNumber: BlockNumber(latestBlock.globalVariables.blockNumber + 1),
|
|
@@ -180,7 +183,31 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
|
|
|
180
183
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
181
184
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
182
185
|
const utilityExecutor = this.utilityExecutorForContractSync(anchorBlock);
|
|
183
|
-
this.oracleHandler = new PrivateExecutionOracle(
|
|
186
|
+
this.oracleHandler = new PrivateExecutionOracle({
|
|
187
|
+
argsHash: Fr.ZERO,
|
|
188
|
+
txContext: new TxContext(this.chainId, this.version, GasSettings.empty()),
|
|
189
|
+
callContext: new CallContext(AztecAddress.ZERO, contractAddress, FunctionSelector.empty(), false),
|
|
190
|
+
anchorBlockHeader: anchorBlock,
|
|
191
|
+
utilityExecutor,
|
|
192
|
+
authWitnesses: [],
|
|
193
|
+
capsules: [],
|
|
194
|
+
executionCache: new HashedValuesCache(),
|
|
195
|
+
noteCache,
|
|
196
|
+
taggingIndexCache,
|
|
197
|
+
contractStore: this.contractStore,
|
|
198
|
+
noteStore: this.noteStore,
|
|
199
|
+
keyStore: this.keyStore,
|
|
200
|
+
addressStore: this.addressStore,
|
|
201
|
+
aztecNode: this.stateMachine.node,
|
|
202
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
203
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
204
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
205
|
+
capsuleStore: this.capsuleStore,
|
|
206
|
+
privateEventStore: this.privateEventStore,
|
|
207
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
208
|
+
jobId: this.currentJobId,
|
|
209
|
+
scopes: 'ALL_SCOPES'
|
|
210
|
+
});
|
|
184
211
|
// We store the note and tagging index caches fed into the PrivateExecutionOracle (along with some other auxiliary
|
|
185
212
|
// data) in order to refer to it later, mimicking the way this object is used by the ContractFunctionSimulator. The
|
|
186
213
|
// difference resides in that the simulator has all information needed in order to run the simulation, while ours
|
|
@@ -214,14 +241,30 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
|
|
|
214
241
|
}
|
|
215
242
|
async enterUtilityState(contractAddress = DEFAULT_ADDRESS) {
|
|
216
243
|
this.exitTopLevelState();
|
|
244
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
217
245
|
// There is no automatic message discovery and contract-driven syncing process in inlined private or utility
|
|
218
246
|
// contexts, which means that known nullifiers are also not searched for, since it is during the tagging sync that
|
|
219
247
|
// we perform this. We therefore search for known nullifiers now, as otherwise notes that were nullified would not
|
|
220
248
|
// be removed from the database.
|
|
221
249
|
// TODO(#12553): make the synchronizer sync here instead and remove this
|
|
222
|
-
await new NoteService(this.noteStore, this.stateMachine.node,
|
|
223
|
-
|
|
224
|
-
|
|
250
|
+
await new NoteService(this.noteStore, this.stateMachine.node, anchorBlockHeader, this.currentJobId).syncNoteNullifiers(contractAddress, 'ALL_SCOPES');
|
|
251
|
+
this.oracleHandler = new UtilityExecutionOracle({
|
|
252
|
+
contractAddress,
|
|
253
|
+
authWitnesses: [],
|
|
254
|
+
capsules: [],
|
|
255
|
+
anchorBlockHeader,
|
|
256
|
+
contractStore: this.contractStore,
|
|
257
|
+
noteStore: this.noteStore,
|
|
258
|
+
keyStore: this.keyStore,
|
|
259
|
+
addressStore: this.addressStore,
|
|
260
|
+
aztecNode: this.stateMachine.node,
|
|
261
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
262
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
263
|
+
capsuleStore: this.capsuleStore,
|
|
264
|
+
privateEventStore: this.privateEventStore,
|
|
265
|
+
jobId: this.currentJobId,
|
|
266
|
+
scopes: 'ALL_SCOPES'
|
|
267
|
+
});
|
|
225
268
|
this.state = {
|
|
226
269
|
name: 'UTILITY'
|
|
227
270
|
};
|
|
@@ -278,13 +321,29 @@ import { makeTxEffect } from './utils/tx_effect_creation.js';
|
|
|
278
321
|
}
|
|
279
322
|
}
|
|
280
323
|
utilityExecutorForContractSync(anchorBlock) {
|
|
281
|
-
return async (call)=>{
|
|
324
|
+
return async (call, scopes)=>{
|
|
282
325
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
283
326
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
284
327
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
285
328
|
}
|
|
286
329
|
try {
|
|
287
|
-
const oracle = new UtilityExecutionOracle(
|
|
330
|
+
const oracle = new UtilityExecutionOracle({
|
|
331
|
+
contractAddress: call.to,
|
|
332
|
+
authWitnesses: [],
|
|
333
|
+
capsules: [],
|
|
334
|
+
anchorBlockHeader: anchorBlock,
|
|
335
|
+
contractStore: this.contractStore,
|
|
336
|
+
noteStore: this.noteStore,
|
|
337
|
+
keyStore: this.keyStore,
|
|
338
|
+
addressStore: this.addressStore,
|
|
339
|
+
aztecNode: this.stateMachine.node,
|
|
340
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
341
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
342
|
+
capsuleStore: this.capsuleStore,
|
|
343
|
+
privateEventStore: this.privateEventStore,
|
|
344
|
+
jobId: this.currentJobId,
|
|
345
|
+
scopes
|
|
346
|
+
});
|
|
288
347
|
await new WASMSimulator().executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback()).catch((err)=>{
|
|
289
348
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
290
349
|
throw new ExecutionError(err.message, {
|
|
@@ -25,4 +25,4 @@ export declare function makeTXEBlockHeader(worldTrees: MerkleTreeWriteOperations
|
|
|
25
25
|
* @returns The created L2Block with proper archive chaining
|
|
26
26
|
*/
|
|
27
27
|
export declare function makeTXEBlock(worldTrees: MerkleTreeWriteOperations, globalVariables: GlobalVariables, txEffects: TxEffect[]): Promise<L2Block>;
|
|
28
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
28
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfY3JlYXRpb24uZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9ibG9ja19jcmVhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFNQSxPQUFPLEVBQUUsV0FBVyxFQUEyQyxNQUFNLGlDQUFpQyxDQUFDO0FBRXZHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQVEsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEQsT0FBTyxFQUF3QyxLQUFLLHlCQUF5QixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDM0csT0FBTyxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFMUU7Ozs7R0FJRztBQUNILHdCQUFnQiwyQkFBMkIsQ0FBQyxXQUFXLEVBQUUsV0FBVyxHQUFHLEVBQUUsQ0FFeEU7QUFFRCx3QkFBc0IsNEJBQTRCLENBQ2hELFFBQVEsRUFBRSxRQUFRLEVBQ2xCLFVBQVUsRUFBRSx5QkFBeUIsR0FDcEMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQWtCZjtBQUVELHdCQUFzQixrQkFBa0IsQ0FDdEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxHQUMvQixPQUFPLENBQUMsV0FBVyxDQUFDLENBWXRCO0FBRUQ7Ozs7Ozs7Ozs7OztHQVlHO0FBQ0gsd0JBQXNCLFlBQVksQ0FDaEMsVUFBVSxFQUFFLHlCQUF5QixFQUNyQyxlQUFlLEVBQUUsZUFBZSxFQUNoQyxTQUFTLEVBQUUsUUFBUSxFQUFFLEdBQ3BCLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FpQmxCIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block_creation.d.ts","sourceRoot":"","sources":["../../src/utils/block_creation.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAA2C,MAAM,iCAAiC,CAAC;AAEvG,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAQ,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAwC,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,GAAG,EAAE,CAExE;AAED,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,yBAAyB,GACpC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,QAAQ,EAAE,GACpB,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"block_creation.d.ts","sourceRoot":"","sources":["../../src/utils/block_creation.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAA2C,MAAM,iCAAiC,CAAC;AAEvG,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAQ,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAwC,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,WAAW,EAAE,WAAW,GAAG,EAAE,CAExE;AAED,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,yBAAyB,GACpC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,WAAW,CAAC,CAYtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,yBAAyB,EACrC,eAAe,EAAE,eAAe,EAChC,SAAS,EAAE,QAAQ,EAAE,GACpB,OAAO,CAAC,OAAO,CAAC,CAiBlB"}
|
|
@@ -49,7 +49,9 @@ export async function makeTXEBlockHeader(worldTrees, globalVariables) {
|
|
|
49
49
|
// Get the new archive state after updating
|
|
50
50
|
const newArchiveInfo = await worldTrees.getTreeInfo(MerkleTreeId.ARCHIVE);
|
|
51
51
|
const newArchive = new AppendOnlyTreeSnapshot(new Fr(newArchiveInfo.root), Number(newArchiveInfo.size));
|
|
52
|
-
// L2Block requires checkpointNumber and indexWithinCheckpoint
|
|
52
|
+
// L2Block requires checkpointNumber and indexWithinCheckpoint.
|
|
53
|
+
// TXE uses 1-block-per-checkpoint for testing simplicity, so we can use block number as checkpoint number.
|
|
54
|
+
// This uses the deprecated fromBlockNumber method intentionally for the TXE testing environment.
|
|
53
55
|
const checkpointNumber = CheckpointNumber.fromBlockNumber(globalVariables.blockNumber);
|
|
54
56
|
const indexWithinCheckpoint = IndexWithinCheckpoint(0);
|
|
55
57
|
return new L2Block(newArchive, header, new Body(txEffects), checkpointNumber, indexWithinCheckpoint);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/txe",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.21ecf947b",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"bin": "./dest/bin/index.js",
|
|
@@ -61,20 +61,20 @@
|
|
|
61
61
|
]
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@aztec/accounts": "0.0.1-commit.
|
|
65
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
66
|
-
"@aztec/aztec-node": "0.0.1-commit.
|
|
67
|
-
"@aztec/aztec.js": "0.0.1-commit.
|
|
68
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
69
|
-
"@aztec/constants": "0.0.1-commit.
|
|
70
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
71
|
-
"@aztec/key-store": "0.0.1-commit.
|
|
72
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
73
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
74
|
-
"@aztec/pxe": "0.0.1-commit.
|
|
75
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
76
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
77
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
64
|
+
"@aztec/accounts": "0.0.1-commit.21ecf947b",
|
|
65
|
+
"@aztec/archiver": "0.0.1-commit.21ecf947b",
|
|
66
|
+
"@aztec/aztec-node": "0.0.1-commit.21ecf947b",
|
|
67
|
+
"@aztec/aztec.js": "0.0.1-commit.21ecf947b",
|
|
68
|
+
"@aztec/bb-prover": "0.0.1-commit.21ecf947b",
|
|
69
|
+
"@aztec/constants": "0.0.1-commit.21ecf947b",
|
|
70
|
+
"@aztec/foundation": "0.0.1-commit.21ecf947b",
|
|
71
|
+
"@aztec/key-store": "0.0.1-commit.21ecf947b",
|
|
72
|
+
"@aztec/kv-store": "0.0.1-commit.21ecf947b",
|
|
73
|
+
"@aztec/protocol-contracts": "0.0.1-commit.21ecf947b",
|
|
74
|
+
"@aztec/pxe": "0.0.1-commit.21ecf947b",
|
|
75
|
+
"@aztec/simulator": "0.0.1-commit.21ecf947b",
|
|
76
|
+
"@aztec/stdlib": "0.0.1-commit.21ecf947b",
|
|
77
|
+
"@aztec/world-state": "0.0.1-commit.21ecf947b",
|
|
78
78
|
"zod": "^3.23.8"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
package/src/oracle/interfaces.ts
CHANGED
|
@@ -33,7 +33,7 @@ export interface IAvmExecutionOracle {
|
|
|
33
33
|
avmOpcodeVersion(): Promise<Fr>;
|
|
34
34
|
avmOpcodeEmitNullifier(nullifier: Fr): Promise<void>;
|
|
35
35
|
avmOpcodeEmitNoteHash(noteHash: Fr): Promise<void>;
|
|
36
|
-
avmOpcodeNullifierExists(
|
|
36
|
+
avmOpcodeNullifierExists(siloedNullifier: Fr): Promise<boolean>;
|
|
37
37
|
avmOpcodeStorageWrite(slot: Fr, value: Fr): Promise<void>;
|
|
38
38
|
avmOpcodeStorageRead(slot: Fr, contractAddress: AztecAddress): Promise<Fr>;
|
|
39
39
|
}
|
|
@@ -78,13 +78,11 @@ export class TXEOraclePublicContext implements IAvmExecutionOracle {
|
|
|
78
78
|
this.transientUniqueNoteHashes.push(siloedNoteHash);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
async avmOpcodeNullifierExists(
|
|
82
|
-
const nullifier = await siloNullifier(targetAddress, innerNullifier!);
|
|
83
|
-
|
|
81
|
+
async avmOpcodeNullifierExists(siloedNullifier: Fr): Promise<boolean> {
|
|
84
82
|
const treeIndex = (
|
|
85
|
-
await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [
|
|
83
|
+
await this.forkedWorldTrees.findLeafIndices(MerkleTreeId.NULLIFIER_TREE, [siloedNullifier.toBuffer()])
|
|
86
84
|
)[0];
|
|
87
|
-
const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(
|
|
85
|
+
const transientIndex = this.transientSiloedNullifiers.find(n => n.equals(siloedNullifier));
|
|
88
86
|
|
|
89
87
|
return treeIndex !== undefined || transientIndex !== undefined;
|
|
90
88
|
}
|
|
@@ -12,6 +12,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
12
12
|
import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
13
13
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
14
14
|
import type { KeyStore } from '@aztec/key-store';
|
|
15
|
+
import type { AccessScopes } from '@aztec/pxe/client/lazy';
|
|
15
16
|
import {
|
|
16
17
|
AddressStore,
|
|
17
18
|
CapsuleStore,
|
|
@@ -22,7 +23,6 @@ import {
|
|
|
22
23
|
SenderAddressBookStore,
|
|
23
24
|
SenderTaggingStore,
|
|
24
25
|
enrichPublicSimulationError,
|
|
25
|
-
syncState,
|
|
26
26
|
} from '@aztec/pxe/server';
|
|
27
27
|
import {
|
|
28
28
|
ExecutionNoteCache,
|
|
@@ -132,13 +132,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
135
|
-
|
|
135
|
+
utilityLog(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
136
136
|
if (!LogLevels[level]) {
|
|
137
|
-
throw new Error(`Invalid
|
|
137
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
138
138
|
}
|
|
139
139
|
const levelName = LogLevels[level];
|
|
140
140
|
|
|
141
141
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
142
|
+
return Promise.resolve();
|
|
142
143
|
}
|
|
143
144
|
|
|
144
145
|
txeGetDefaultAddress(): AztecAddress {
|
|
@@ -297,12 +298,24 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
297
298
|
throw new Error(message);
|
|
298
299
|
}
|
|
299
300
|
|
|
301
|
+
// When `from` is the zero address (e.g. when deploying a new account contract), we return an
|
|
302
|
+
// empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
|
|
303
|
+
const effectiveScopes = from.isZero() ? [] : [from];
|
|
304
|
+
|
|
300
305
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
301
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
302
|
-
await this.executeUtilityCall(call);
|
|
306
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AccessScopes) => {
|
|
307
|
+
await this.executeUtilityCall(call, execScopes);
|
|
303
308
|
};
|
|
304
309
|
|
|
305
|
-
await
|
|
310
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
311
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
312
|
+
targetContractAddress,
|
|
313
|
+
functionSelector,
|
|
314
|
+
utilityExecutor,
|
|
315
|
+
blockHeader,
|
|
316
|
+
this.jobId,
|
|
317
|
+
effectiveScopes,
|
|
318
|
+
);
|
|
306
319
|
|
|
307
320
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
308
321
|
|
|
@@ -314,8 +327,6 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
314
327
|
|
|
315
328
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
316
329
|
|
|
317
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
318
|
-
|
|
319
330
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
320
331
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
321
332
|
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
@@ -327,43 +338,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
327
338
|
|
|
328
339
|
const simulator = new WASMSimulator();
|
|
329
340
|
|
|
330
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
341
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
331
342
|
argsHash,
|
|
332
343
|
txContext,
|
|
333
344
|
callContext,
|
|
334
|
-
|
|
335
|
-
blockHeader,
|
|
345
|
+
anchorBlockHeader: blockHeader,
|
|
336
346
|
utilityExecutor,
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
[],
|
|
341
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
347
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
348
|
+
capsules: [],
|
|
349
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
342
350
|
noteCache,
|
|
343
351
|
taggingIndexCache,
|
|
344
|
-
this.contractStore,
|
|
345
|
-
this.noteStore,
|
|
346
|
-
this.keyStore,
|
|
347
|
-
this.addressStore,
|
|
348
|
-
this.stateMachine.node,
|
|
349
|
-
this.
|
|
350
|
-
this.
|
|
351
|
-
this.
|
|
352
|
-
this.
|
|
353
|
-
this.
|
|
354
|
-
this.
|
|
355
|
-
this.jobId,
|
|
356
|
-
0,
|
|
357
|
-
minRevertibleSideEffectCounter,
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
* contract would perform, including setting senderForTags.
|
|
363
|
-
*/
|
|
364
|
-
from,
|
|
352
|
+
contractStore: this.contractStore,
|
|
353
|
+
noteStore: this.noteStore,
|
|
354
|
+
keyStore: this.keyStore,
|
|
355
|
+
addressStore: this.addressStore,
|
|
356
|
+
aztecNode: this.stateMachine.node,
|
|
357
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
358
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
359
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
360
|
+
capsuleStore: this.capsuleStore,
|
|
361
|
+
privateEventStore: this.privateEventStore,
|
|
362
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
363
|
+
jobId: this.jobId,
|
|
364
|
+
totalPublicCalldataCount: 0,
|
|
365
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
366
|
+
scopes: effectiveScopes,
|
|
367
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
368
|
+
// contract would perform, including setting senderForTags.
|
|
369
|
+
senderForTags: from,
|
|
365
370
|
simulator,
|
|
366
|
-
);
|
|
371
|
+
});
|
|
367
372
|
|
|
368
373
|
// Note: This is a slight modification of simulator.run without any of the checks. Maybe we should modify simulator.run with a boolean value to skip checks.
|
|
369
374
|
let result: PrivateExecutionResult;
|
|
@@ -402,7 +407,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
402
407
|
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
403
408
|
const { publicInputs } = await generateSimulatedProvingResult(
|
|
404
409
|
result,
|
|
405
|
-
this.contractStore,
|
|
410
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
411
|
+
this.stateMachine.node,
|
|
406
412
|
minRevertibleSideEffectCounter,
|
|
407
413
|
);
|
|
408
414
|
|
|
@@ -415,7 +421,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
415
421
|
|
|
416
422
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
417
423
|
|
|
418
|
-
const
|
|
424
|
+
const bindings = this.logger.getBindings();
|
|
425
|
+
const contractsDB = new PublicContractsDB(
|
|
426
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
427
|
+
bindings,
|
|
428
|
+
);
|
|
419
429
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
420
430
|
const config = PublicSimulatorConfig.from({
|
|
421
431
|
skipFeeEnforcement: true,
|
|
@@ -428,8 +438,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
428
438
|
globals,
|
|
429
439
|
guardedMerkleTrees,
|
|
430
440
|
contractsDB,
|
|
431
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
441
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
432
442
|
new TestDateProvider(),
|
|
443
|
+
undefined,
|
|
444
|
+
createLogger('simulator:public-processor', bindings),
|
|
433
445
|
);
|
|
434
446
|
|
|
435
447
|
const tx = await Tx.create({
|
|
@@ -526,7 +538,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
526
538
|
|
|
527
539
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
528
540
|
|
|
529
|
-
const
|
|
541
|
+
const bindings2 = this.logger.getBindings();
|
|
542
|
+
const contractsDB = new PublicContractsDB(
|
|
543
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
544
|
+
bindings2,
|
|
545
|
+
);
|
|
530
546
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
531
547
|
const config = PublicSimulatorConfig.from({
|
|
532
548
|
skipFeeEnforcement: true,
|
|
@@ -535,8 +551,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
535
551
|
collectStatistics: false,
|
|
536
552
|
collectCallMetadata: true,
|
|
537
553
|
});
|
|
538
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
539
|
-
const processor = new PublicProcessor(
|
|
554
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
555
|
+
const processor = new PublicProcessor(
|
|
556
|
+
globals,
|
|
557
|
+
guardedMerkleTrees,
|
|
558
|
+
contractsDB,
|
|
559
|
+
simulator,
|
|
560
|
+
new TestDateProvider(),
|
|
561
|
+
undefined,
|
|
562
|
+
createLogger('simulator:public-processor', bindings2),
|
|
563
|
+
);
|
|
540
564
|
|
|
541
565
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
542
566
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -567,7 +591,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
567
591
|
constantData,
|
|
568
592
|
/*gasUsed=*/ new Gas(0, 0),
|
|
569
593
|
/*feePayer=*/ AztecAddress.zero(),
|
|
570
|
-
/*
|
|
594
|
+
/*expirationTimestamp=*/ 0n,
|
|
571
595
|
inputsForPublic,
|
|
572
596
|
undefined,
|
|
573
597
|
);
|
|
@@ -646,25 +670,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
646
670
|
}
|
|
647
671
|
|
|
648
672
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
649
|
-
await
|
|
650
|
-
|
|
651
|
-
});
|
|
652
|
-
|
|
653
|
-
const call = new FunctionCall(
|
|
654
|
-
artifact.name,
|
|
673
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
674
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
655
675
|
targetContractAddress,
|
|
656
676
|
functionSelector,
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
677
|
+
async (call, execScopes) => {
|
|
678
|
+
await this.executeUtilityCall(call, execScopes);
|
|
679
|
+
},
|
|
680
|
+
blockHeader,
|
|
681
|
+
this.jobId,
|
|
682
|
+
'ALL_SCOPES',
|
|
662
683
|
);
|
|
663
684
|
|
|
664
|
-
|
|
685
|
+
const call = FunctionCall.from({
|
|
686
|
+
name: artifact.name,
|
|
687
|
+
to: targetContractAddress,
|
|
688
|
+
selector: functionSelector,
|
|
689
|
+
type: FunctionType.UTILITY,
|
|
690
|
+
hideMsgSender: false,
|
|
691
|
+
isStatic: false,
|
|
692
|
+
args,
|
|
693
|
+
returnTypes: [],
|
|
694
|
+
});
|
|
695
|
+
|
|
696
|
+
return this.executeUtilityCall(call, 'ALL_SCOPES');
|
|
665
697
|
}
|
|
666
698
|
|
|
667
|
-
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
699
|
+
private async executeUtilityCall(call: FunctionCall, scopes: AccessScopes): Promise<Fr[]> {
|
|
668
700
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
669
701
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
670
702
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -677,23 +709,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
677
709
|
|
|
678
710
|
try {
|
|
679
711
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
680
|
-
const oracle = new UtilityExecutionOracle(
|
|
681
|
-
call.to,
|
|
682
|
-
[],
|
|
683
|
-
[],
|
|
712
|
+
const oracle = new UtilityExecutionOracle({
|
|
713
|
+
contractAddress: call.to,
|
|
714
|
+
authWitnesses: [],
|
|
715
|
+
capsules: [],
|
|
684
716
|
anchorBlockHeader,
|
|
685
|
-
this.contractStore,
|
|
686
|
-
this.noteStore,
|
|
687
|
-
this.keyStore,
|
|
688
|
-
this.addressStore,
|
|
689
|
-
this.stateMachine.node,
|
|
690
|
-
this.
|
|
691
|
-
this.
|
|
692
|
-
this.
|
|
693
|
-
this.
|
|
694
|
-
this.
|
|
695
|
-
|
|
696
|
-
);
|
|
717
|
+
contractStore: this.contractStore,
|
|
718
|
+
noteStore: this.noteStore,
|
|
719
|
+
keyStore: this.keyStore,
|
|
720
|
+
addressStore: this.addressStore,
|
|
721
|
+
aztecNode: this.stateMachine.node,
|
|
722
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
723
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
724
|
+
capsuleStore: this.capsuleStore,
|
|
725
|
+
privateEventStore: this.privateEventStore,
|
|
726
|
+
jobId: this.jobId,
|
|
727
|
+
scopes,
|
|
728
|
+
});
|
|
697
729
|
const acirExecutionResult = await new WASMSimulator()
|
|
698
730
|
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
699
731
|
.catch((err: Error) => {
|