@aztec/txe 0.0.1-commit.9b94fc1 → 0.0.1-commit.c7c42ec
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/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 +9 -6
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +5 -5
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +4 -6
- package/dest/oracle/txe_oracle_top_level_context.d.ts +20 -12
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +77 -54
- package/dest/rpc_translator.d.ts +11 -5
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +57 -15
- package/dest/state_machine/archiver.d.ts +26 -10
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +105 -17
- 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 +5 -4
- 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 +14 -20
- package/dest/state_machine/synchronizer.d.ts +5 -4
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +5 -4
- package/dest/txe_session.d.ts +19 -13
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +50 -38
- package/dest/util/encoding.d.ts +610 -11
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +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 +7 -6
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +11 -11
- package/dest/utils/block_creation.d.ts +19 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +23 -2
- package/dest/utils/tx_effect_creation.d.ts +4 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +1 -1
- package/package.json +17 -17
- package/src/index.ts +15 -12
- package/src/oracle/interfaces.ts +8 -5
- package/src/oracle/txe_oracle_public_context.ts +6 -11
- package/src/oracle/txe_oracle_top_level_context.ts +109 -80
- package/src/rpc_translator.ts +82 -12
- package/src/state_machine/archiver.ts +136 -25
- package/src/state_machine/dummy_p2p_client.ts +3 -1
- package/src/state_machine/global_variable_builder.ts +20 -3
- package/src/state_machine/index.ts +19 -18
- package/src/state_machine/synchronizer.ts +8 -7
- package/src/txe_session.ts +107 -68
- package/src/util/encoding.ts +1 -1
- 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 +13 -12
- package/src/utils/block_creation.ts +34 -3
- package/src/utils/tx_effect_creation.ts +3 -2
- 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
|
@@ -6,15 +6,21 @@ import {
|
|
|
6
6
|
DEFAULT_TEARDOWN_L2_GAS_LIMIT,
|
|
7
7
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
8
8
|
} from '@aztec/constants';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
9
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
10
|
+
import { Schnorr } from '@aztec/foundation/crypto/schnorr';
|
|
11
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
11
12
|
import { LogLevels, type Logger, applyStringFormatting, createLogger } from '@aztec/foundation/log';
|
|
12
13
|
import { TestDateProvider } from '@aztec/foundation/timer';
|
|
13
14
|
import type { KeyStore } from '@aztec/key-store';
|
|
14
15
|
import {
|
|
15
|
-
|
|
16
|
+
AddressStore,
|
|
17
|
+
CapsuleStore,
|
|
18
|
+
NoteStore,
|
|
16
19
|
ORACLE_VERSION,
|
|
17
|
-
|
|
20
|
+
PrivateEventStore,
|
|
21
|
+
RecipientTaggingStore,
|
|
22
|
+
SenderAddressBookStore,
|
|
23
|
+
SenderTaggingStore,
|
|
18
24
|
enrichPublicSimulationError,
|
|
19
25
|
} from '@aztec/pxe/server';
|
|
20
26
|
import {
|
|
@@ -38,16 +44,15 @@ import {
|
|
|
38
44
|
witnessMapToFields,
|
|
39
45
|
} from '@aztec/simulator/client';
|
|
40
46
|
import {
|
|
47
|
+
CppPublicTxSimulator,
|
|
41
48
|
GuardedMerkleTreeOperations,
|
|
42
49
|
PublicContractsDB,
|
|
43
50
|
PublicProcessor,
|
|
44
|
-
PublicTxSimulator,
|
|
45
51
|
} from '@aztec/simulator/server';
|
|
46
|
-
import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
52
|
+
import { type ContractArtifact, EventSelector, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
47
53
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
48
54
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
49
55
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
50
|
-
import { Body, L2Block } from '@aztec/stdlib/block';
|
|
51
56
|
import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
|
|
52
57
|
import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
|
|
53
58
|
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
@@ -58,7 +63,7 @@ import {
|
|
|
58
63
|
PublicCallRequest,
|
|
59
64
|
} from '@aztec/stdlib/kernel';
|
|
60
65
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
61
|
-
import {
|
|
66
|
+
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
62
67
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
63
68
|
import {
|
|
64
69
|
CallContext,
|
|
@@ -76,14 +81,11 @@ import type { UInt64 } from '@aztec/stdlib/types';
|
|
|
76
81
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
77
82
|
|
|
78
83
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
79
|
-
import
|
|
80
|
-
import type {
|
|
84
|
+
import { DEFAULT_ADDRESS } from '../txe_session.js';
|
|
85
|
+
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
86
|
+
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
81
87
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
82
|
-
import {
|
|
83
|
-
getSingleTxBlockRequestHash,
|
|
84
|
-
insertTxEffectIntoWorldTrees,
|
|
85
|
-
makeTXEBlockHeader,
|
|
86
|
-
} from '../utils/block_creation.js';
|
|
88
|
+
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
87
89
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
88
90
|
|
|
89
91
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
@@ -94,11 +96,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
94
96
|
|
|
95
97
|
constructor(
|
|
96
98
|
private stateMachine: TXEStateMachine,
|
|
97
|
-
private
|
|
99
|
+
private contractStore: TXEContractStore,
|
|
100
|
+
private noteStore: NoteStore,
|
|
98
101
|
private keyStore: KeyStore,
|
|
99
|
-
private
|
|
100
|
-
private
|
|
101
|
-
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,
|
|
102
109
|
private nextBlockTimestamp: bigint,
|
|
103
110
|
private version: Fr,
|
|
104
111
|
private chainId: Fr,
|
|
@@ -132,8 +139,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
132
139
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
133
140
|
}
|
|
134
141
|
|
|
135
|
-
|
|
136
|
-
return
|
|
142
|
+
txeGetDefaultAddress(): AztecAddress {
|
|
143
|
+
return DEFAULT_ADDRESS;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async txeGetNextBlockNumber(): Promise<BlockNumber> {
|
|
147
|
+
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
137
148
|
}
|
|
138
149
|
|
|
139
150
|
txeGetNextBlockTimestamp(): Promise<bigint> {
|
|
@@ -145,7 +156,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
145
156
|
}
|
|
146
157
|
|
|
147
158
|
async txeGetLastTxEffects() {
|
|
148
|
-
const block = await this.stateMachine.archiver.
|
|
159
|
+
const block = await this.stateMachine.archiver.getL2Block('latest');
|
|
149
160
|
|
|
150
161
|
if (block!.body.txEffects.length != 1) {
|
|
151
162
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -157,6 +168,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
157
168
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
158
169
|
}
|
|
159
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
|
+
|
|
160
182
|
async txeAdvanceBlocksBy(blocks: number) {
|
|
161
183
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
162
184
|
|
|
@@ -184,8 +206,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
184
206
|
if (!secret.equals(Fr.ZERO)) {
|
|
185
207
|
await this.txeAddAccount(artifact, instance, secret);
|
|
186
208
|
} else {
|
|
187
|
-
await this.
|
|
188
|
-
await this.
|
|
209
|
+
await this.contractStore.addContractInstance(instance);
|
|
210
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
189
211
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
190
212
|
}
|
|
191
213
|
}
|
|
@@ -194,29 +216,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
194
216
|
const partialAddress = await computePartialAddress(instance);
|
|
195
217
|
|
|
196
218
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
197
|
-
await this.
|
|
198
|
-
await this.
|
|
219
|
+
await this.contractStore.addContractInstance(instance);
|
|
220
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
199
221
|
|
|
200
222
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
201
|
-
await this.
|
|
202
|
-
await this.
|
|
223
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
224
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
203
225
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
204
226
|
|
|
205
227
|
return completeAddress;
|
|
206
228
|
}
|
|
207
229
|
|
|
208
230
|
async txeCreateAccount(secret: Fr) {
|
|
209
|
-
// This is a
|
|
231
|
+
// This is a foot gun !
|
|
210
232
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
211
|
-
await this.
|
|
212
|
-
await this.
|
|
233
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
234
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
213
235
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
214
236
|
|
|
215
237
|
return completeAddress;
|
|
216
238
|
}
|
|
217
239
|
|
|
218
240
|
async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
219
|
-
const account = await this.
|
|
241
|
+
const account = await this.accountStore.getAccount(address);
|
|
220
242
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
221
243
|
|
|
222
244
|
const schnorr = new Schnorr();
|
|
@@ -237,19 +259,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
237
259
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
238
260
|
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
239
261
|
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
version: this.version,
|
|
248
|
-
chainId: this.chainId,
|
|
249
|
-
}),
|
|
250
|
-
),
|
|
251
|
-
new Body([txEffect]),
|
|
252
|
-
);
|
|
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]);
|
|
253
269
|
|
|
254
270
|
await forkedWorldTrees.close();
|
|
255
271
|
|
|
@@ -267,10 +283,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
267
283
|
isStaticCall: boolean = false,
|
|
268
284
|
) {
|
|
269
285
|
this.logger.verbose(
|
|
270
|
-
`Executing external function ${await this.
|
|
286
|
+
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
271
287
|
);
|
|
272
288
|
|
|
273
|
-
const artifact = await this.
|
|
289
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
274
290
|
if (!artifact) {
|
|
275
291
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
276
292
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -290,7 +306,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
290
306
|
|
|
291
307
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
292
308
|
|
|
293
|
-
const blockHeader = await this.
|
|
309
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
294
310
|
|
|
295
311
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
296
312
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
@@ -311,7 +327,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
311
327
|
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
312
328
|
noteCache,
|
|
313
329
|
taggingIndexCache,
|
|
314
|
-
this.
|
|
330
|
+
this.contractStore,
|
|
331
|
+
this.noteStore,
|
|
332
|
+
this.keyStore,
|
|
333
|
+
this.addressStore,
|
|
334
|
+
this.stateMachine.node,
|
|
335
|
+
this.stateMachine.anchorBlockStore,
|
|
336
|
+
this.senderTaggingStore,
|
|
337
|
+
this.recipientTaggingStore,
|
|
338
|
+
this.senderAddressBookStore,
|
|
339
|
+
this.capsuleStore,
|
|
340
|
+
this.privateEventStore,
|
|
315
341
|
0,
|
|
316
342
|
1,
|
|
317
343
|
undefined, // log
|
|
@@ -361,7 +387,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
361
387
|
// can either be the first nullifier in the tx or the hash of the initial tx request
|
|
362
388
|
// if there are none.
|
|
363
389
|
const nonceGenerator = result.firstNullifier.equals(Fr.ZERO) ? protocolNullifier : result.firstNullifier;
|
|
364
|
-
const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.
|
|
390
|
+
const { publicInputs } = await generateSimulatedProvingResult(result, nonceGenerator, this.contractStore);
|
|
365
391
|
|
|
366
392
|
const globals = makeGlobalVariables();
|
|
367
393
|
globals.blockNumber = blockNumber;
|
|
@@ -372,7 +398,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
372
398
|
|
|
373
399
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
374
400
|
|
|
375
|
-
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.
|
|
401
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
|
|
376
402
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
377
403
|
const config = PublicSimulatorConfig.from({
|
|
378
404
|
skipFeeEnforcement: true,
|
|
@@ -385,7 +411,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
385
411
|
globals,
|
|
386
412
|
guardedMerkleTrees,
|
|
387
413
|
contractsDB,
|
|
388
|
-
new
|
|
414
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
389
415
|
new TestDateProvider(),
|
|
390
416
|
);
|
|
391
417
|
|
|
@@ -411,7 +437,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
411
437
|
} else if (!processedTx.revertCode.isOK()) {
|
|
412
438
|
if (processedTx.revertReason) {
|
|
413
439
|
try {
|
|
414
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
440
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
415
441
|
// eslint-disable-next-line no-empty
|
|
416
442
|
} catch {}
|
|
417
443
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -440,13 +466,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
440
466
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
441
467
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
442
468
|
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
const l2Block = new L2Block(
|
|
446
|
-
makeAppendOnlyTreeSnapshot(),
|
|
447
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
448
|
-
body,
|
|
449
|
-
);
|
|
469
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
450
470
|
|
|
451
471
|
await this.stateMachine.handleL2Block(l2Block);
|
|
452
472
|
|
|
@@ -462,7 +482,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
462
482
|
isStaticCall: boolean,
|
|
463
483
|
) {
|
|
464
484
|
this.logger.verbose(
|
|
465
|
-
`Executing public function ${await this.
|
|
485
|
+
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
466
486
|
);
|
|
467
487
|
|
|
468
488
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
@@ -475,7 +495,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
475
495
|
|
|
476
496
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
477
497
|
|
|
478
|
-
const anchorBlockHeader = await this.
|
|
498
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
479
499
|
|
|
480
500
|
const calldataHash = await computeCalldataHash(calldata);
|
|
481
501
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
@@ -489,7 +509,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
489
509
|
|
|
490
510
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
491
511
|
|
|
492
|
-
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.
|
|
512
|
+
const contractsDB = new PublicContractsDB(new TXEPublicContractDataSource(blockNumber, this.contractStore));
|
|
493
513
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
494
514
|
const config = PublicSimulatorConfig.from({
|
|
495
515
|
skipFeeEnforcement: true,
|
|
@@ -498,7 +518,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
498
518
|
collectStatistics: false,
|
|
499
519
|
collectCallMetadata: true,
|
|
500
520
|
});
|
|
501
|
-
const simulator = new
|
|
521
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
502
522
|
const processor = new PublicProcessor(globals, guardedMerkleTrees, contractsDB, simulator, new TestDateProvider());
|
|
503
523
|
|
|
504
524
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
@@ -506,9 +526,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
506
526
|
// side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
|
|
507
527
|
// unique.
|
|
508
528
|
const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
509
|
-
|
|
510
|
-
nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
|
|
511
|
-
}
|
|
529
|
+
nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
|
|
512
530
|
|
|
513
531
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
514
532
|
// may require producing reverts.
|
|
@@ -559,7 +577,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
559
577
|
} else if (!processedTx.revertCode.isOK()) {
|
|
560
578
|
if (processedTx.revertReason) {
|
|
561
579
|
try {
|
|
562
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
580
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
563
581
|
// eslint-disable-next-line no-empty
|
|
564
582
|
} catch {}
|
|
565
583
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -591,13 +609,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
591
609
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
592
610
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
593
611
|
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
const l2Block = new L2Block(
|
|
597
|
-
makeAppendOnlyTreeSnapshot(),
|
|
598
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
599
|
-
body,
|
|
600
|
-
);
|
|
612
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
601
613
|
|
|
602
614
|
await this.stateMachine.handleL2Block(l2Block);
|
|
603
615
|
|
|
@@ -611,7 +623,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
611
623
|
functionSelector: FunctionSelector,
|
|
612
624
|
args: Fr[],
|
|
613
625
|
) {
|
|
614
|
-
const artifact = await this.
|
|
626
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
615
627
|
if (!artifact) {
|
|
616
628
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
617
629
|
}
|
|
@@ -622,7 +634,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
622
634
|
to: targetContractAddress,
|
|
623
635
|
};
|
|
624
636
|
|
|
625
|
-
const entryPointArtifact = await this.
|
|
637
|
+
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
626
638
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
627
639
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
628
640
|
}
|
|
@@ -633,7 +645,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
633
645
|
});
|
|
634
646
|
|
|
635
647
|
try {
|
|
636
|
-
const
|
|
648
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
649
|
+
const oracle = new UtilityExecutionOracle(
|
|
650
|
+
call.to,
|
|
651
|
+
[],
|
|
652
|
+
[],
|
|
653
|
+
anchorBlockHeader,
|
|
654
|
+
this.contractStore,
|
|
655
|
+
this.noteStore,
|
|
656
|
+
this.keyStore,
|
|
657
|
+
this.addressStore,
|
|
658
|
+
this.stateMachine.node,
|
|
659
|
+
this.stateMachine.anchorBlockStore,
|
|
660
|
+
this.recipientTaggingStore,
|
|
661
|
+
this.senderAddressBookStore,
|
|
662
|
+
this.capsuleStore,
|
|
663
|
+
this.privateEventStore,
|
|
664
|
+
);
|
|
637
665
|
const acirExecutionResult = await new WASMSimulator()
|
|
638
666
|
.executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
639
667
|
.catch((err: Error) => {
|
|
@@ -661,7 +689,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
661
689
|
return [this.nextBlockTimestamp, this.authwits];
|
|
662
690
|
}
|
|
663
691
|
|
|
664
|
-
private async getLastBlockNumber(): Promise<
|
|
665
|
-
|
|
692
|
+
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
693
|
+
const header = await this.stateMachine.node.getBlockHeader('latest');
|
|
694
|
+
return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
666
695
|
}
|
|
667
696
|
}
|
package/src/rpc_translator.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
|
|
2
2
|
import { Fr, Point } from '@aztec/aztec.js/fields';
|
|
3
3
|
import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
|
|
4
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
4
5
|
import {
|
|
5
6
|
type IMiscOracle,
|
|
6
7
|
type IPrivateExecutionOracle,
|
|
7
8
|
type IUtilityExecutionOracle,
|
|
8
9
|
packAsRetrievedNote,
|
|
9
10
|
} from '@aztec/pxe/simulator';
|
|
10
|
-
import { type ContractArtifact, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
11
|
+
import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
11
12
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
13
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
13
14
|
|
|
@@ -29,6 +30,9 @@ import {
|
|
|
29
30
|
toSingle,
|
|
30
31
|
} from './util/encoding.js';
|
|
31
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
|
+
|
|
32
36
|
export class UnavailableOracleError extends Error {
|
|
33
37
|
constructor(oracleName: string) {
|
|
34
38
|
super(`${oracleName} oracles not available with the current handler`);
|
|
@@ -117,7 +121,7 @@ export class RPCTranslator {
|
|
|
117
121
|
: undefined;
|
|
118
122
|
|
|
119
123
|
const anchorBlockNumber = fromSingle(foreignAnchorBlockNumberIsSome).toBool()
|
|
120
|
-
? fromSingle(foreignAnchorBlockNumberValue).toNumber()
|
|
124
|
+
? BlockNumber(fromSingle(foreignAnchorBlockNumberValue).toNumber())
|
|
121
125
|
: undefined;
|
|
122
126
|
|
|
123
127
|
const privateContextInputs = await this.stateHandler.enterPrivateState(contractAddress, anchorBlockNumber);
|
|
@@ -155,6 +159,12 @@ export class RPCTranslator {
|
|
|
155
159
|
|
|
156
160
|
// TXE-specific oracles
|
|
157
161
|
|
|
162
|
+
txeGetDefaultAddress() {
|
|
163
|
+
const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
|
|
164
|
+
|
|
165
|
+
return toForeignCallResult([toSingle(defaultAddress)]);
|
|
166
|
+
}
|
|
167
|
+
|
|
158
168
|
async txeGetNextBlockNumber() {
|
|
159
169
|
const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
|
|
160
170
|
|
|
@@ -266,6 +276,39 @@ export class RPCTranslator {
|
|
|
266
276
|
]);
|
|
267
277
|
}
|
|
268
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
|
+
|
|
269
312
|
privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
|
|
270
313
|
const values = fromArray(foreignValues);
|
|
271
314
|
const hash = fromSingle(foreignHash);
|
|
@@ -310,7 +353,7 @@ export class RPCTranslator {
|
|
|
310
353
|
) {
|
|
311
354
|
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
312
355
|
const startStorageSlot = fromSingle(foreignStartStorageSlot);
|
|
313
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
356
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
314
357
|
const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
|
|
315
358
|
|
|
316
359
|
const values = await this.handlerAsUtility().utilityStorageRead(
|
|
@@ -324,7 +367,7 @@ export class RPCTranslator {
|
|
|
324
367
|
}
|
|
325
368
|
|
|
326
369
|
async utilityGetPublicDataWitness(foreignBlockNumber: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
|
|
327
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
370
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
328
371
|
const leafSlot = fromSingle(foreignLeafSlot);
|
|
329
372
|
|
|
330
373
|
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockNumber, leafSlot);
|
|
@@ -336,6 +379,8 @@ export class RPCTranslator {
|
|
|
336
379
|
}
|
|
337
380
|
|
|
338
381
|
async utilityGetNotes(
|
|
382
|
+
foreignOwnerIsSome: ForeignCallSingle,
|
|
383
|
+
foreignOwnerValue: ForeignCallSingle,
|
|
339
384
|
foreignStorageSlot: ForeignCallSingle,
|
|
340
385
|
foreignNumSelects: ForeignCallSingle,
|
|
341
386
|
foreignSelectByIndexes: ForeignCallArray,
|
|
@@ -353,6 +398,10 @@ export class RPCTranslator {
|
|
|
353
398
|
foreignMaxNotes: ForeignCallSingle,
|
|
354
399
|
foreignPackedRetrievedNoteLength: ForeignCallSingle,
|
|
355
400
|
) {
|
|
401
|
+
// Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
|
|
402
|
+
const owner = fromSingle(foreignOwnerIsSome).toBool()
|
|
403
|
+
? AztecAddress.fromField(fromSingle(foreignOwnerValue))
|
|
404
|
+
: undefined;
|
|
356
405
|
const storageSlot = fromSingle(foreignStorageSlot);
|
|
357
406
|
const numSelects = fromSingle(foreignNumSelects).toNumber();
|
|
358
407
|
const selectByIndexes = fromArray(foreignSelectByIndexes).map(fr => fr.toNumber());
|
|
@@ -371,6 +420,7 @@ export class RPCTranslator {
|
|
|
371
420
|
const packedRetrievedNoteLength = fromSingle(foreignPackedRetrievedNoteLength).toNumber();
|
|
372
421
|
|
|
373
422
|
const noteDatas = await this.handlerAsUtility().utilityGetNotes(
|
|
423
|
+
owner,
|
|
374
424
|
storageSlot,
|
|
375
425
|
numSelects,
|
|
376
426
|
selectByIndexes,
|
|
@@ -387,7 +437,17 @@ export class RPCTranslator {
|
|
|
387
437
|
status,
|
|
388
438
|
);
|
|
389
439
|
|
|
390
|
-
const returnDataAsArrayOfArrays = noteDatas.map(
|
|
440
|
+
const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
|
|
441
|
+
packAsRetrievedNote({
|
|
442
|
+
contractAddress: noteData.contractAddress,
|
|
443
|
+
owner: noteData.owner,
|
|
444
|
+
randomness: noteData.randomness,
|
|
445
|
+
storageSlot: noteData.storageSlot,
|
|
446
|
+
noteNonce: noteData.noteNonce,
|
|
447
|
+
index: noteData.index,
|
|
448
|
+
note: noteData.note,
|
|
449
|
+
}),
|
|
450
|
+
);
|
|
391
451
|
|
|
392
452
|
// Now we convert each sub-array to an array of ForeignCallSingles
|
|
393
453
|
const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray =>
|
|
@@ -405,6 +465,7 @@ export class RPCTranslator {
|
|
|
405
465
|
}
|
|
406
466
|
|
|
407
467
|
privateNotifyCreatedNote(
|
|
468
|
+
foreignOwner: ForeignCallSingle,
|
|
408
469
|
foreignStorageSlot: ForeignCallSingle,
|
|
409
470
|
foreignRandomness: ForeignCallSingle,
|
|
410
471
|
foreignNoteTypeId: ForeignCallSingle,
|
|
@@ -412,6 +473,7 @@ export class RPCTranslator {
|
|
|
412
473
|
foreignNoteHash: ForeignCallSingle,
|
|
413
474
|
foreignCounter: ForeignCallSingle,
|
|
414
475
|
) {
|
|
476
|
+
const owner = addressFromSingle(foreignOwner);
|
|
415
477
|
const storageSlot = fromSingle(foreignStorageSlot);
|
|
416
478
|
const randomness = fromSingle(foreignRandomness);
|
|
417
479
|
const noteTypeId = NoteSelector.fromField(fromSingle(foreignNoteTypeId));
|
|
@@ -419,7 +481,15 @@ export class RPCTranslator {
|
|
|
419
481
|
const noteHash = fromSingle(foreignNoteHash);
|
|
420
482
|
const counter = fromSingle(foreignCounter).toNumber();
|
|
421
483
|
|
|
422
|
-
this.handlerAsPrivate().privateNotifyCreatedNote(
|
|
484
|
+
this.handlerAsPrivate().privateNotifyCreatedNote(
|
|
485
|
+
owner,
|
|
486
|
+
storageSlot,
|
|
487
|
+
randomness,
|
|
488
|
+
noteTypeId,
|
|
489
|
+
note,
|
|
490
|
+
noteHash,
|
|
491
|
+
counter,
|
|
492
|
+
);
|
|
423
493
|
|
|
424
494
|
return toForeignCallResult([]);
|
|
425
495
|
}
|
|
@@ -502,7 +572,7 @@ export class RPCTranslator {
|
|
|
502
572
|
foreignBlockNumber: ForeignCallSingle,
|
|
503
573
|
foreignNullifier: ForeignCallSingle,
|
|
504
574
|
) {
|
|
505
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
575
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
506
576
|
const nullifier = fromSingle(foreignNullifier);
|
|
507
577
|
|
|
508
578
|
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockNumber, nullifier);
|
|
@@ -552,14 +622,14 @@ export class RPCTranslator {
|
|
|
552
622
|
return toForeignCallResult([toSingle(new Fr(isRevertible))]);
|
|
553
623
|
}
|
|
554
624
|
|
|
555
|
-
|
|
556
|
-
const context =
|
|
625
|
+
utilityGetUtilityContext() {
|
|
626
|
+
const context = this.handlerAsUtility().utilityGetUtilityContext();
|
|
557
627
|
|
|
558
628
|
return toForeignCallResult(context.toNoirRepresentation());
|
|
559
629
|
}
|
|
560
630
|
|
|
561
631
|
async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
|
|
562
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
632
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
563
633
|
|
|
564
634
|
const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
|
|
565
635
|
|
|
@@ -574,7 +644,7 @@ export class RPCTranslator {
|
|
|
574
644
|
foreignTreeId: ForeignCallSingle,
|
|
575
645
|
foreignLeafValue: ForeignCallSingle,
|
|
576
646
|
) {
|
|
577
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
647
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
578
648
|
const treeId = fromSingle(foreignTreeId).toNumber();
|
|
579
649
|
const leafValue = fromSingle(foreignLeafValue);
|
|
580
650
|
|
|
@@ -592,7 +662,7 @@ export class RPCTranslator {
|
|
|
592
662
|
foreignBlockNumber: ForeignCallSingle,
|
|
593
663
|
foreignNullifier: ForeignCallSingle,
|
|
594
664
|
) {
|
|
595
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
665
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
596
666
|
const nullifier = fromSingle(foreignNullifier);
|
|
597
667
|
|
|
598
668
|
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);
|