@aztec/txe 3.0.0-rc.5 → 4.0.0-nightly.20260107
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/constants.d.ts +3 -0
- package/dest/constants.d.ts.map +1 -0
- package/dest/constants.js +2 -0
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -2
- package/dest/oracle/interfaces.d.ts +4 -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 -5
- package/dest/oracle/txe_oracle_top_level_context.d.ts +18 -10
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +83 -52
- package/dest/rpc_translator.d.ts +9 -3
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +33 -3
- package/dest/state_machine/archiver.d.ts +19 -7
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +93 -15
- package/dest/state_machine/dummy_p2p_client.d.ts +1 -1
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +3 -1
- package/dest/state_machine/global_variable_builder.d.ts +3 -2
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +12 -0
- 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 +13 -19
- package/dest/txe_session.d.ts +15 -9
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +72 -42
- package/dest/util/encoding.d.ts +601 -2
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/txe_account_store.d.ts +10 -0
- package/dest/util/txe_account_store.d.ts.map +1 -0
- package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
- package/dest/util/txe_contract_store.d.ts +12 -0
- package/dest/util/txe_contract_store.d.ts.map +1 -0
- package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
- package/dest/util/txe_public_contract_data_source.d.ts +4 -4
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +10 -10
- package/dest/utils/block_creation.d.ts +16 -2
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +22 -1
- package/package.json +15 -15
- package/src/constants.ts +3 -0
- package/src/index.ts +15 -12
- package/src/oracle/interfaces.ts +3 -1
- package/src/oracle/txe_oracle_public_context.ts +3 -8
- package/src/oracle/txe_oracle_top_level_context.ts +125 -76
- package/src/rpc_translator.ts +45 -3
- package/src/state_machine/archiver.ts +119 -21
- package/src/state_machine/dummy_p2p_client.ts +3 -1
- package/src/state_machine/global_variable_builder.ts +18 -1
- package/src/state_machine/index.ts +18 -17
- package/src/txe_session.ts +157 -69
- package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
- package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
- package/src/util/txe_public_contract_data_source.ts +9 -9
- package/src/utils/block_creation.ts +31 -1
- package/dest/util/txe_account_data_provider.d.ts +0 -10
- package/dest/util/txe_account_data_provider.d.ts.map +0 -1
- package/dest/util/txe_contract_data_provider.d.ts +0 -12
- package/dest/util/txe_contract_data_provider.d.ts.map +0 -1
|
@@ -13,9 +13,14 @@ import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@az
|
|
|
13
13
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
14
14
|
import type { KeyStore } from '@aztec/key-store';
|
|
15
15
|
import {
|
|
16
|
-
|
|
16
|
+
AddressStore,
|
|
17
|
+
CapsuleStore,
|
|
18
|
+
NoteStore,
|
|
17
19
|
ORACLE_VERSION,
|
|
18
|
-
|
|
20
|
+
PrivateEventStore,
|
|
21
|
+
RecipientTaggingStore,
|
|
22
|
+
SenderAddressBookStore,
|
|
23
|
+
SenderTaggingStore,
|
|
19
24
|
enrichPublicSimulationError,
|
|
20
25
|
} from '@aztec/pxe/server';
|
|
21
26
|
import {
|
|
@@ -44,11 +49,10 @@ import {
|
|
|
44
49
|
PublicContractsDB,
|
|
45
50
|
PublicProcessor,
|
|
46
51
|
} from '@aztec/simulator/server';
|
|
47
|
-
import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
52
|
+
import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
48
53
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
49
54
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
50
55
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
51
|
-
import { Body, L2Block } from '@aztec/stdlib/block';
|
|
52
56
|
import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
|
|
53
57
|
import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
|
|
54
58
|
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
@@ -59,7 +63,7 @@ import {
|
|
|
59
63
|
PublicCallRequest,
|
|
60
64
|
} from '@aztec/stdlib/kernel';
|
|
61
65
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
62
|
-
import {
|
|
66
|
+
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
63
67
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
64
68
|
import {
|
|
65
69
|
CallContext,
|
|
@@ -76,15 +80,12 @@ import {
|
|
|
76
80
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
77
81
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
78
82
|
|
|
83
|
+
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
79
84
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
80
|
-
import type {
|
|
81
|
-
import type {
|
|
85
|
+
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
86
|
+
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
82
87
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
83
|
-
import {
|
|
84
|
-
getSingleTxBlockRequestHash,
|
|
85
|
-
insertTxEffectIntoWorldTrees,
|
|
86
|
-
makeTXEBlockHeader,
|
|
87
|
-
} from '../utils/block_creation.js';
|
|
88
|
+
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
88
89
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
89
90
|
|
|
90
91
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
@@ -95,11 +96,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
95
96
|
|
|
96
97
|
constructor(
|
|
97
98
|
private stateMachine: TXEStateMachine,
|
|
98
|
-
private
|
|
99
|
+
private contractStore: TXEContractStore,
|
|
100
|
+
private noteStore: NoteStore,
|
|
99
101
|
private keyStore: KeyStore,
|
|
100
|
-
private
|
|
101
|
-
private
|
|
102
|
-
private
|
|
102
|
+
private addressStore: AddressStore,
|
|
103
|
+
private accountStore: TXEAccountStore,
|
|
104
|
+
private senderTaggingStore: SenderTaggingStore,
|
|
105
|
+
private recipientTaggingStore: RecipientTaggingStore,
|
|
106
|
+
private senderAddressBookStore: SenderAddressBookStore,
|
|
107
|
+
private capsuleStore: CapsuleStore,
|
|
108
|
+
private privateEventStore: PrivateEventStore,
|
|
103
109
|
private nextBlockTimestamp: bigint,
|
|
104
110
|
private version: Fr,
|
|
105
111
|
private chainId: Fr,
|
|
@@ -133,6 +139,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
133
139
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
134
140
|
}
|
|
135
141
|
|
|
142
|
+
txeGetDefaultAddress(): AztecAddress {
|
|
143
|
+
return DEFAULT_ADDRESS;
|
|
144
|
+
}
|
|
145
|
+
|
|
136
146
|
async txeGetNextBlockNumber(): Promise<BlockNumber> {
|
|
137
147
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
138
148
|
}
|
|
@@ -146,7 +156,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
146
156
|
}
|
|
147
157
|
|
|
148
158
|
async txeGetLastTxEffects() {
|
|
149
|
-
const block = await this.stateMachine.archiver.
|
|
159
|
+
const block = await this.stateMachine.archiver.getL2Block('latest');
|
|
150
160
|
|
|
151
161
|
if (block!.body.txEffects.length != 1) {
|
|
152
162
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -158,6 +168,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
158
168
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
159
169
|
}
|
|
160
170
|
|
|
171
|
+
async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
172
|
+
return (
|
|
173
|
+
await this.privateEventStore.getPrivateEvents(selector, {
|
|
174
|
+
contractAddress,
|
|
175
|
+
scopes: [scope],
|
|
176
|
+
fromBlock: 0,
|
|
177
|
+
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
178
|
+
})
|
|
179
|
+
).map(e => e.packedEvent);
|
|
180
|
+
}
|
|
181
|
+
|
|
161
182
|
async txeAdvanceBlocksBy(blocks: number) {
|
|
162
183
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
163
184
|
|
|
@@ -185,8 +206,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
185
206
|
if (!secret.equals(Fr.ZERO)) {
|
|
186
207
|
await this.txeAddAccount(artifact, instance, secret);
|
|
187
208
|
} else {
|
|
188
|
-
await this.
|
|
189
|
-
await this.
|
|
209
|
+
await this.contractStore.addContractInstance(instance);
|
|
210
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
190
211
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
191
212
|
}
|
|
192
213
|
}
|
|
@@ -195,29 +216,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
195
216
|
const partialAddress = await computePartialAddress(instance);
|
|
196
217
|
|
|
197
218
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
198
|
-
await this.
|
|
199
|
-
await this.
|
|
219
|
+
await this.contractStore.addContractInstance(instance);
|
|
220
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
200
221
|
|
|
201
222
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
202
|
-
await this.
|
|
203
|
-
await this.
|
|
223
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
224
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
204
225
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
205
226
|
|
|
206
227
|
return completeAddress;
|
|
207
228
|
}
|
|
208
229
|
|
|
209
230
|
async txeCreateAccount(secret: Fr) {
|
|
210
|
-
// This is a
|
|
231
|
+
// This is a foot gun !
|
|
211
232
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
212
|
-
await this.
|
|
213
|
-
await this.
|
|
233
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
234
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
214
235
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
215
236
|
|
|
216
237
|
return completeAddress;
|
|
217
238
|
}
|
|
218
239
|
|
|
219
240
|
async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
220
|
-
const account = await this.
|
|
241
|
+
const account = await this.accountStore.getAccount(address);
|
|
221
242
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
222
243
|
|
|
223
244
|
const schnorr = new Schnorr();
|
|
@@ -238,19 +259,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
238
259
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
239
260
|
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
240
261
|
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
version: this.version,
|
|
249
|
-
chainId: this.chainId,
|
|
250
|
-
}),
|
|
251
|
-
),
|
|
252
|
-
new Body([txEffect]),
|
|
253
|
-
);
|
|
262
|
+
const globals = makeGlobalVariables(undefined, {
|
|
263
|
+
blockNumber,
|
|
264
|
+
timestamp: this.nextBlockTimestamp,
|
|
265
|
+
version: this.version,
|
|
266
|
+
chainId: this.chainId,
|
|
267
|
+
});
|
|
268
|
+
const block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
254
269
|
|
|
255
270
|
await forkedWorldTrees.close();
|
|
256
271
|
|
|
@@ -268,10 +283,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
268
283
|
isStaticCall: boolean = false,
|
|
269
284
|
) {
|
|
270
285
|
this.logger.verbose(
|
|
271
|
-
`Executing external function ${await this.
|
|
286
|
+
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
272
287
|
);
|
|
273
288
|
|
|
274
|
-
const artifact = await this.
|
|
289
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
275
290
|
if (!artifact) {
|
|
276
291
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
277
292
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -279,19 +294,24 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
279
294
|
throw new Error(message);
|
|
280
295
|
}
|
|
281
296
|
|
|
297
|
+
// Sync notes before executing private function to discover notes from previous transactions
|
|
298
|
+
const utilityExecutor = async (call: FunctionCall) => {
|
|
299
|
+
await this.executeUtilityCall(call);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, utilityExecutor);
|
|
303
|
+
|
|
282
304
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
283
305
|
|
|
284
306
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
285
307
|
|
|
286
308
|
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
287
|
-
|
|
288
309
|
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
289
|
-
|
|
290
310
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
291
311
|
|
|
292
312
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
293
313
|
|
|
294
|
-
const blockHeader = await this.
|
|
314
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
295
315
|
|
|
296
316
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
297
317
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
@@ -305,6 +325,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
305
325
|
callContext,
|
|
306
326
|
/** Header of a block whose state is used during private execution (not the block the transaction is included in). */
|
|
307
327
|
blockHeader,
|
|
328
|
+
utilityExecutor,
|
|
308
329
|
/** List of transient auth witnesses to be used during this simulation */
|
|
309
330
|
Array.from(this.authwits.values()),
|
|
310
331
|
/** List of transient auth witnesses to be used during this simulation */
|
|
@@ -312,7 +333,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
312
333
|
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
313
334
|
noteCache,
|
|
314
335
|
taggingIndexCache,
|
|
315
|
-
this.
|
|
336
|
+
this.contractStore,
|
|
337
|
+
this.noteStore,
|
|
338
|
+
this.keyStore,
|
|
339
|
+
this.addressStore,
|
|
340
|
+
this.stateMachine.node,
|
|
341
|
+
this.stateMachine.anchorBlockStore,
|
|
342
|
+
this.senderTaggingStore,
|
|
343
|
+
this.recipientTaggingStore,
|
|
344
|
+
this.senderAddressBookStore,
|
|
345
|
+
this.capsuleStore,
|
|
346
|
+
this.privateEventStore,
|
|
316
347
|
0,
|
|
317
348
|
1,
|
|
318
349
|
undefined, // log
|
|
@@ -362,7 +393,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
362
393
|
// can either be the first nullifier in the tx or the hash of the initial tx request
|
|
363
394
|
// if there are none.
|
|
364
395
|
const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? protocolNullifier : result.firstNullifier;
|
|
365
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.
|
|
396
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractStore);
|
|
366
397
|
|
|
367
398
|
const globals = makeGlobalVariables();
|
|
368
399
|
globals.blockNumber = blockNumber;
|
|
@@ -373,7 +404,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
373
404
|
|
|
374
405
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
375
406
|
|
|
376
|
-
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.
|
|
407
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
|
|
377
408
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
378
409
|
const config = PublicSimulatorConfig.from({
|
|
379
410
|
skipFeeEnforcement: true,
|
|
@@ -412,7 +443,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
412
443
|
} else if (!processedTx.revertCode.isOK()) {
|
|
413
444
|
if (processedTx.revertReason) {
|
|
414
445
|
try {
|
|
415
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
446
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
416
447
|
// eslint-disable-next-line no-empty
|
|
417
448
|
} catch {}
|
|
418
449
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -441,13 +472,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
441
472
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
442
473
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
443
474
|
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
const l2Block = new L2Block(
|
|
447
|
-
makeAppendOnlyTreeSnapshot(),
|
|
448
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
449
|
-
body,
|
|
450
|
-
);
|
|
475
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
451
476
|
|
|
452
477
|
await this.stateMachine.handleL2Block(l2Block);
|
|
453
478
|
|
|
@@ -463,7 +488,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
463
488
|
isStaticCall: boolean,
|
|
464
489
|
) {
|
|
465
490
|
this.logger.verbose(
|
|
466
|
-
`Executing public function ${await this.
|
|
491
|
+
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
467
492
|
);
|
|
468
493
|
|
|
469
494
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
@@ -476,7 +501,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
476
501
|
|
|
477
502
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
478
503
|
|
|
479
|
-
const anchorBlockHeader = await this.
|
|
504
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
480
505
|
|
|
481
506
|
const calldataHash = await computeCalldataHash(calldata);
|
|
482
507
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
@@ -490,7 +515,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
490
515
|
|
|
491
516
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
492
517
|
|
|
493
|
-
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.
|
|
518
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
|
|
494
519
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
495
520
|
const config = PublicSimulatorConfig.from({
|
|
496
521
|
skipFeeEnforcement: true,
|
|
@@ -558,7 +583,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
558
583
|
} else if (!processedTx.revertCode.isOK()) {
|
|
559
584
|
if (processedTx.revertReason) {
|
|
560
585
|
try {
|
|
561
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
586
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
562
587
|
// eslint-disable-next-line no-empty
|
|
563
588
|
} catch {}
|
|
564
589
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -590,13 +615,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
590
615
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
591
616
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
592
617
|
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
const l2Block = new L2Block(
|
|
596
|
-
makeAppendOnlyTreeSnapshot(),
|
|
597
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
598
|
-
body,
|
|
599
|
-
);
|
|
618
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
600
619
|
|
|
601
620
|
await this.stateMachine.handleL2Block(l2Block);
|
|
602
621
|
|
|
@@ -610,18 +629,32 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
610
629
|
functionSelector: FunctionSelector,
|
|
611
630
|
args: Fr[],
|
|
612
631
|
) {
|
|
613
|
-
const artifact = await this.
|
|
632
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
614
633
|
if (!artifact) {
|
|
615
634
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
616
635
|
}
|
|
617
636
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
};
|
|
637
|
+
// Sync notes before executing utility function to discover notes from previous transactions
|
|
638
|
+
await this.contractStore.syncPrivateState(targetContractAddress, functionSelector, async call => {
|
|
639
|
+
await this.executeUtilityCall(call);
|
|
640
|
+
});
|
|
623
641
|
|
|
624
|
-
const
|
|
642
|
+
const call = new FunctionCall(
|
|
643
|
+
artifact.name,
|
|
644
|
+
targetContractAddress,
|
|
645
|
+
functionSelector,
|
|
646
|
+
FunctionType.UTILITY,
|
|
647
|
+
false,
|
|
648
|
+
false,
|
|
649
|
+
args,
|
|
650
|
+
[],
|
|
651
|
+
);
|
|
652
|
+
|
|
653
|
+
return this.executeUtilityCall(call);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
657
|
+
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
625
658
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
626
659
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
627
660
|
}
|
|
@@ -632,9 +665,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
632
665
|
});
|
|
633
666
|
|
|
634
667
|
try {
|
|
635
|
-
const
|
|
668
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
669
|
+
const oracle = new UtilityExecutionOracle(
|
|
670
|
+
call.to,
|
|
671
|
+
[],
|
|
672
|
+
[],
|
|
673
|
+
anchorBlockHeader,
|
|
674
|
+
this.contractStore,
|
|
675
|
+
this.noteStore,
|
|
676
|
+
this.keyStore,
|
|
677
|
+
this.addressStore,
|
|
678
|
+
this.stateMachine.node,
|
|
679
|
+
this.stateMachine.anchorBlockStore,
|
|
680
|
+
this.recipientTaggingStore,
|
|
681
|
+
this.senderAddressBookStore,
|
|
682
|
+
this.capsuleStore,
|
|
683
|
+
this.privateEventStore,
|
|
684
|
+
);
|
|
636
685
|
const acirExecutionResult = await new WASMSimulator()
|
|
637
|
-
.executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
686
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
638
687
|
.catch((err: Error) => {
|
|
639
688
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
640
689
|
throw new ExecutionError(
|
package/src/rpc_translator.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
type IUtilityExecutionOracle,
|
|
9
9
|
packAsRetrievedNote,
|
|
10
10
|
} from '@aztec/pxe/simulator';
|
|
11
|
-
import { type ContractArtifact, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
11
|
+
import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
12
12
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
13
13
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
14
14
|
|
|
@@ -30,6 +30,9 @@ import {
|
|
|
30
30
|
toSingle,
|
|
31
31
|
} from './util/encoding.js';
|
|
32
32
|
|
|
33
|
+
const MAX_EVENT_LEN = 12; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_RESERVED_FIELDS
|
|
34
|
+
const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
|
|
35
|
+
|
|
33
36
|
export class UnavailableOracleError extends Error {
|
|
34
37
|
constructor(oracleName: string) {
|
|
35
38
|
super(`${oracleName} oracles not available with the current handler`);
|
|
@@ -156,6 +159,12 @@ export class RPCTranslator {
|
|
|
156
159
|
|
|
157
160
|
// TXE-specific oracles
|
|
158
161
|
|
|
162
|
+
txeGetDefaultAddress() {
|
|
163
|
+
const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
|
|
164
|
+
|
|
165
|
+
return toForeignCallResult([toSingle(defaultAddress)]);
|
|
166
|
+
}
|
|
167
|
+
|
|
159
168
|
async txeGetNextBlockNumber() {
|
|
160
169
|
const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
|
|
161
170
|
|
|
@@ -267,6 +276,39 @@ export class RPCTranslator {
|
|
|
267
276
|
]);
|
|
268
277
|
}
|
|
269
278
|
|
|
279
|
+
async txeGetPrivateEvents(
|
|
280
|
+
foreignSelector: ForeignCallSingle,
|
|
281
|
+
foreignContractAddress: ForeignCallSingle,
|
|
282
|
+
foreignScope: ForeignCallSingle,
|
|
283
|
+
) {
|
|
284
|
+
const selector = EventSelector.fromField(fromSingle(foreignSelector));
|
|
285
|
+
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
286
|
+
const scope = addressFromSingle(foreignScope);
|
|
287
|
+
|
|
288
|
+
const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
|
|
289
|
+
|
|
290
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
291
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (events.some(e => e.length > MAX_EVENT_LEN)) {
|
|
295
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_EVENT_LEN}`);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// This is a workaround as Noir does not currently let us return nested structs with arrays. We instead return a raw
|
|
299
|
+
// multidimensional array in get_private_events_oracle and create the BoundedVecs here.
|
|
300
|
+
const rawArrayStorage = events
|
|
301
|
+
.map(e => e.concat(Array(MAX_EVENT_LEN - e.length).fill(new Fr(0))))
|
|
302
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_EVENT_LEN).fill(new Fr(0))))
|
|
303
|
+
.flat();
|
|
304
|
+
const eventLengths = events
|
|
305
|
+
.map(e => new Fr(e.length))
|
|
306
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(new Fr(0)));
|
|
307
|
+
const queryLength = new Fr(events.length);
|
|
308
|
+
|
|
309
|
+
return toForeignCallResult([toArray(rawArrayStorage), toArray(eventLengths), toSingle(queryLength)]);
|
|
310
|
+
}
|
|
311
|
+
|
|
270
312
|
privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
|
|
271
313
|
const values = fromArray(foreignValues);
|
|
272
314
|
const hash = fromSingle(foreignHash);
|
|
@@ -580,8 +622,8 @@ export class RPCTranslator {
|
|
|
580
622
|
return toForeignCallResult([toSingle(new Fr(isRevertible))]);
|
|
581
623
|
}
|
|
582
624
|
|
|
583
|
-
|
|
584
|
-
const context =
|
|
625
|
+
utilityGetUtilityContext() {
|
|
626
|
+
const context = this.handlerAsUtility().utilityGetUtilityContext();
|
|
585
627
|
|
|
586
628
|
return toForeignCallResult(context.toNoirRepresentation());
|
|
587
629
|
}
|