@aztec/txe 3.0.3 → 4.0.0-devnet.1-patch.1
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 +6 -4
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +4 -4
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +9 -11
- package/dest/oracle/txe_oracle_top_level_context.d.ts +20 -11
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +164 -65
- package/dest/rpc_translator.d.ts +27 -15
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +108 -53
- package/dest/state_machine/archiver.d.ts +20 -55
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +62 -103
- package/dest/state_machine/dummy_p2p_client.d.ts +14 -12
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +29 -21
- package/dest/state_machine/global_variable_builder.d.ts +4 -3
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +13 -1
- package/dest/state_machine/index.d.ts +7 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +40 -23
- package/dest/state_machine/mock_epoch_cache.d.ts +9 -6
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +14 -7
- package/dest/state_machine/synchronizer.d.ts +3 -3
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/txe_session.d.ts +17 -9
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +147 -45
- package/dest/util/encoding.d.ts +617 -18
- 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 +18 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +37 -3
- package/dest/utils/tx_effect_creation.d.ts +2 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +3 -6
- package/package.json +16 -16
- package/src/constants.ts +3 -0
- package/src/index.ts +15 -12
- package/src/oracle/interfaces.ts +5 -3
- package/src/oracle/txe_oracle_public_context.ts +9 -16
- package/src/oracle/txe_oracle_top_level_context.ts +196 -105
- package/src/rpc_translator.ts +123 -55
- package/src/state_machine/archiver.ts +58 -126
- package/src/state_machine/dummy_p2p_client.ts +40 -27
- package/src/state_machine/global_variable_builder.ts +19 -2
- package/src/state_machine/index.ts +60 -22
- package/src/state_machine/mock_epoch_cache.ts +15 -11
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +197 -87
- 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 +47 -14
- package/src/utils/tx_effect_creation.ts +3 -11
- 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,17 @@ 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,
|
|
109
|
+
private jobId: string,
|
|
103
110
|
private nextBlockTimestamp: bigint,
|
|
104
111
|
private version: Fr,
|
|
105
112
|
private chainId: Fr,
|
|
@@ -124,13 +131,18 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
124
131
|
}
|
|
125
132
|
|
|
126
133
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
127
|
-
utilityDebugLog(level: number, message: string, fields: Fr[]): void {
|
|
134
|
+
utilityDebugLog(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
128
135
|
if (!LogLevels[level]) {
|
|
129
136
|
throw new Error(`Invalid debug log level: ${level}`);
|
|
130
137
|
}
|
|
131
138
|
const levelName = LogLevels[level];
|
|
132
139
|
|
|
133
140
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
141
|
+
return Promise.resolve();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
txeGetDefaultAddress(): AztecAddress {
|
|
145
|
+
return DEFAULT_ADDRESS;
|
|
134
146
|
}
|
|
135
147
|
|
|
136
148
|
async txeGetNextBlockNumber(): Promise<BlockNumber> {
|
|
@@ -146,7 +158,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
146
158
|
}
|
|
147
159
|
|
|
148
160
|
async txeGetLastTxEffects() {
|
|
149
|
-
const
|
|
161
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
+
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
150
163
|
|
|
151
164
|
if (block!.body.txEffects.length != 1) {
|
|
152
165
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -158,6 +171,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
158
171
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
159
172
|
}
|
|
160
173
|
|
|
174
|
+
async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
175
|
+
return (
|
|
176
|
+
await this.privateEventStore.getPrivateEvents(selector, {
|
|
177
|
+
contractAddress,
|
|
178
|
+
scopes: [scope],
|
|
179
|
+
fromBlock: 0,
|
|
180
|
+
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
181
|
+
})
|
|
182
|
+
).map(e => e.packedEvent);
|
|
183
|
+
}
|
|
184
|
+
|
|
161
185
|
async txeAdvanceBlocksBy(blocks: number) {
|
|
162
186
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
163
187
|
|
|
@@ -185,8 +209,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
185
209
|
if (!secret.equals(Fr.ZERO)) {
|
|
186
210
|
await this.txeAddAccount(artifact, instance, secret);
|
|
187
211
|
} else {
|
|
188
|
-
await this.
|
|
189
|
-
await this.
|
|
212
|
+
await this.contractStore.addContractInstance(instance);
|
|
213
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
190
214
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
191
215
|
}
|
|
192
216
|
}
|
|
@@ -195,29 +219,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
195
219
|
const partialAddress = await computePartialAddress(instance);
|
|
196
220
|
|
|
197
221
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
198
|
-
await this.
|
|
199
|
-
await this.
|
|
222
|
+
await this.contractStore.addContractInstance(instance);
|
|
223
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
200
224
|
|
|
201
225
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
202
|
-
await this.
|
|
203
|
-
await this.
|
|
226
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
227
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
204
228
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
205
229
|
|
|
206
230
|
return completeAddress;
|
|
207
231
|
}
|
|
208
232
|
|
|
209
233
|
async txeCreateAccount(secret: Fr) {
|
|
210
|
-
// This is a
|
|
234
|
+
// This is a foot gun !
|
|
211
235
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
212
|
-
await this.
|
|
213
|
-
await this.
|
|
236
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
237
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
214
238
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
215
239
|
|
|
216
240
|
return completeAddress;
|
|
217
241
|
}
|
|
218
242
|
|
|
219
243
|
async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
220
|
-
const account = await this.
|
|
244
|
+
const account = await this.accountStore.getAccount(address);
|
|
221
245
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
222
246
|
|
|
223
247
|
const schnorr = new Schnorr();
|
|
@@ -238,19 +262,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
238
262
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
239
263
|
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
240
264
|
|
|
241
|
-
const
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
version: this.version,
|
|
249
|
-
chainId: this.chainId,
|
|
250
|
-
}),
|
|
251
|
-
),
|
|
252
|
-
new Body([txEffect]),
|
|
253
|
-
);
|
|
265
|
+
const globals = makeGlobalVariables(undefined, {
|
|
266
|
+
blockNumber,
|
|
267
|
+
timestamp: this.nextBlockTimestamp,
|
|
268
|
+
version: this.version,
|
|
269
|
+
chainId: this.chainId,
|
|
270
|
+
});
|
|
271
|
+
const block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
254
272
|
|
|
255
273
|
await forkedWorldTrees.close();
|
|
256
274
|
|
|
@@ -268,10 +286,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
268
286
|
isStaticCall: boolean = false,
|
|
269
287
|
) {
|
|
270
288
|
this.logger.verbose(
|
|
271
|
-
`Executing external function ${await this.
|
|
289
|
+
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
272
290
|
);
|
|
273
291
|
|
|
274
|
-
const artifact = await this.
|
|
292
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
275
293
|
if (!artifact) {
|
|
276
294
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
277
295
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -279,51 +297,77 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
279
297
|
throw new Error(message);
|
|
280
298
|
}
|
|
281
299
|
|
|
300
|
+
// When `from` is the zero address (used when creating a new contract account for example),
|
|
301
|
+
// we disable scope filtering by setting effectiveScopes to undefined. This allows these operations
|
|
302
|
+
// to proceed without requiring keys registered for the zero address.
|
|
303
|
+
const effectiveScopes = from.isZero() ? undefined : [from];
|
|
304
|
+
|
|
305
|
+
// Sync notes before executing private function to discover notes from previous transactions
|
|
306
|
+
const utilityExecutor = async (call: FunctionCall) => {
|
|
307
|
+
await this.executeUtilityCall(call, effectiveScopes);
|
|
308
|
+
};
|
|
309
|
+
|
|
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
|
+
);
|
|
318
|
+
|
|
282
319
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
283
320
|
|
|
284
321
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
285
322
|
|
|
286
323
|
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
287
|
-
|
|
288
324
|
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
289
|
-
|
|
290
325
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
291
326
|
|
|
292
327
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
293
328
|
|
|
294
|
-
const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
|
|
295
|
-
|
|
296
329
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
297
330
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
331
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
332
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
333
|
+
// marking all side effects as revertible.
|
|
334
|
+
const minRevertibleSideEffectCounter = 1;
|
|
335
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
298
336
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
299
337
|
|
|
300
338
|
const simulator = new WASMSimulator();
|
|
301
339
|
|
|
302
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
340
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
303
341
|
argsHash,
|
|
304
342
|
txContext,
|
|
305
343
|
callContext,
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
[],
|
|
312
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
344
|
+
anchorBlockHeader: blockHeader,
|
|
345
|
+
utilityExecutor,
|
|
346
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
347
|
+
capsules: [],
|
|
348
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
313
349
|
noteCache,
|
|
314
350
|
taggingIndexCache,
|
|
315
|
-
this.
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
351
|
+
contractStore: this.contractStore,
|
|
352
|
+
noteStore: this.noteStore,
|
|
353
|
+
keyStore: this.keyStore,
|
|
354
|
+
addressStore: this.addressStore,
|
|
355
|
+
aztecNode: this.stateMachine.node,
|
|
356
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
357
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
358
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
359
|
+
capsuleStore: this.capsuleStore,
|
|
360
|
+
privateEventStore: this.privateEventStore,
|
|
361
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
362
|
+
jobId: this.jobId,
|
|
363
|
+
totalPublicCalldataCount: 0,
|
|
364
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
365
|
+
scopes: effectiveScopes,
|
|
366
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
367
|
+
// contract would perform, including setting senderForTags.
|
|
368
|
+
senderForTags: from,
|
|
325
369
|
simulator,
|
|
326
|
-
);
|
|
370
|
+
});
|
|
327
371
|
|
|
328
372
|
// 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.
|
|
329
373
|
let result: PrivateExecutionResult;
|
|
@@ -350,19 +394,22 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
350
394
|
}),
|
|
351
395
|
);
|
|
352
396
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
397
|
+
noteCache.finish();
|
|
398
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
399
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
357
400
|
} catch (err) {
|
|
358
401
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
359
402
|
}
|
|
360
403
|
|
|
361
|
-
// According to the protocol rules,
|
|
362
|
-
//
|
|
363
|
-
//
|
|
364
|
-
const
|
|
365
|
-
|
|
404
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
405
|
+
// the nonce generator for the note hashes.
|
|
406
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
407
|
+
const { publicInputs } = await generateSimulatedProvingResult(
|
|
408
|
+
result,
|
|
409
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
410
|
+
this.stateMachine.node,
|
|
411
|
+
minRevertibleSideEffectCounter,
|
|
412
|
+
);
|
|
366
413
|
|
|
367
414
|
const globals = makeGlobalVariables();
|
|
368
415
|
globals.blockNumber = blockNumber;
|
|
@@ -373,7 +420,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
373
420
|
|
|
374
421
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
375
422
|
|
|
376
|
-
const
|
|
423
|
+
const bindings = this.logger.getBindings();
|
|
424
|
+
const contractsDB = new PublicContractsDB(
|
|
425
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
426
|
+
bindings,
|
|
427
|
+
);
|
|
377
428
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
378
429
|
const config = PublicSimulatorConfig.from({
|
|
379
430
|
skipFeeEnforcement: true,
|
|
@@ -386,8 +437,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
386
437
|
globals,
|
|
387
438
|
guardedMerkleTrees,
|
|
388
439
|
contractsDB,
|
|
389
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
440
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
390
441
|
new TestDateProvider(),
|
|
442
|
+
undefined,
|
|
443
|
+
createLogger('simulator:public-processor', bindings),
|
|
391
444
|
);
|
|
392
445
|
|
|
393
446
|
const tx = await Tx.create({
|
|
@@ -412,7 +465,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
412
465
|
} else if (!processedTx.revertCode.isOK()) {
|
|
413
466
|
if (processedTx.revertReason) {
|
|
414
467
|
try {
|
|
415
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
468
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
416
469
|
// eslint-disable-next-line no-empty
|
|
417
470
|
} catch {}
|
|
418
471
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -441,13 +494,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
441
494
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
442
495
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
443
496
|
|
|
444
|
-
const
|
|
445
|
-
|
|
446
|
-
const l2Block = new L2Block(
|
|
447
|
-
makeAppendOnlyTreeSnapshot(),
|
|
448
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
449
|
-
body,
|
|
450
|
-
);
|
|
497
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
451
498
|
|
|
452
499
|
await this.stateMachine.handleL2Block(l2Block);
|
|
453
500
|
|
|
@@ -463,7 +510,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
463
510
|
isStaticCall: boolean,
|
|
464
511
|
) {
|
|
465
512
|
this.logger.verbose(
|
|
466
|
-
`Executing public function ${await this.
|
|
513
|
+
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
467
514
|
);
|
|
468
515
|
|
|
469
516
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
@@ -476,7 +523,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
476
523
|
|
|
477
524
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
478
525
|
|
|
479
|
-
const anchorBlockHeader = await this.
|
|
526
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
480
527
|
|
|
481
528
|
const calldataHash = await computeCalldataHash(calldata);
|
|
482
529
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
@@ -490,7 +537,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
490
537
|
|
|
491
538
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
492
539
|
|
|
493
|
-
const
|
|
540
|
+
const bindings2 = this.logger.getBindings();
|
|
541
|
+
const contractsDB = new PublicContractsDB(
|
|
542
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
543
|
+
bindings2,
|
|
544
|
+
);
|
|
494
545
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
495
546
|
const config = PublicSimulatorConfig.from({
|
|
496
547
|
skipFeeEnforcement: true,
|
|
@@ -499,8 +550,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
499
550
|
collectStatistics: false,
|
|
500
551
|
collectCallMetadata: true,
|
|
501
552
|
});
|
|
502
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
503
|
-
const processor = new PublicProcessor(
|
|
553
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
554
|
+
const processor = new PublicProcessor(
|
|
555
|
+
globals,
|
|
556
|
+
guardedMerkleTrees,
|
|
557
|
+
contractsDB,
|
|
558
|
+
simulator,
|
|
559
|
+
new TestDateProvider(),
|
|
560
|
+
undefined,
|
|
561
|
+
createLogger('simulator:public-processor', bindings2),
|
|
562
|
+
);
|
|
504
563
|
|
|
505
564
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
506
565
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -558,7 +617,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
558
617
|
} else if (!processedTx.revertCode.isOK()) {
|
|
559
618
|
if (processedTx.revertReason) {
|
|
560
619
|
try {
|
|
561
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
620
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
562
621
|
// eslint-disable-next-line no-empty
|
|
563
622
|
} catch {}
|
|
564
623
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -590,13 +649,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
590
649
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
591
650
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
592
651
|
|
|
593
|
-
const
|
|
594
|
-
|
|
595
|
-
const l2Block = new L2Block(
|
|
596
|
-
makeAppendOnlyTreeSnapshot(),
|
|
597
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
598
|
-
body,
|
|
599
|
-
);
|
|
652
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
600
653
|
|
|
601
654
|
await this.stateMachine.handleL2Block(l2Block);
|
|
602
655
|
|
|
@@ -610,18 +663,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
610
663
|
functionSelector: FunctionSelector,
|
|
611
664
|
args: Fr[],
|
|
612
665
|
) {
|
|
613
|
-
const artifact = await this.
|
|
666
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
614
667
|
if (!artifact) {
|
|
615
668
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
616
669
|
}
|
|
617
670
|
|
|
618
|
-
|
|
671
|
+
// Sync notes before executing utility function to discover notes from previous transactions
|
|
672
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
673
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
674
|
+
targetContractAddress,
|
|
675
|
+
functionSelector,
|
|
676
|
+
async call => {
|
|
677
|
+
await this.executeUtilityCall(call);
|
|
678
|
+
},
|
|
679
|
+
blockHeader,
|
|
680
|
+
this.jobId,
|
|
681
|
+
);
|
|
682
|
+
|
|
683
|
+
const call = FunctionCall.from({
|
|
619
684
|
name: artifact.name,
|
|
620
|
-
selector: functionSelector,
|
|
621
685
|
to: targetContractAddress,
|
|
622
|
-
|
|
686
|
+
selector: functionSelector,
|
|
687
|
+
type: FunctionType.UTILITY,
|
|
688
|
+
hideMsgSender: false,
|
|
689
|
+
isStatic: false,
|
|
690
|
+
args,
|
|
691
|
+
returnTypes: [],
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
return this.executeUtilityCall(call);
|
|
695
|
+
}
|
|
623
696
|
|
|
624
|
-
|
|
697
|
+
private async executeUtilityCall(call: FunctionCall, scopes?: AztecAddress[]): Promise<Fr[]> {
|
|
698
|
+
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
625
699
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
626
700
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
627
701
|
}
|
|
@@ -632,9 +706,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
632
706
|
});
|
|
633
707
|
|
|
634
708
|
try {
|
|
635
|
-
const
|
|
709
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
710
|
+
const oracle = new UtilityExecutionOracle({
|
|
711
|
+
contractAddress: call.to,
|
|
712
|
+
authWitnesses: [],
|
|
713
|
+
capsules: [],
|
|
714
|
+
anchorBlockHeader,
|
|
715
|
+
contractStore: this.contractStore,
|
|
716
|
+
noteStore: this.noteStore,
|
|
717
|
+
keyStore: this.keyStore,
|
|
718
|
+
addressStore: this.addressStore,
|
|
719
|
+
aztecNode: this.stateMachine.node,
|
|
720
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
721
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
722
|
+
capsuleStore: this.capsuleStore,
|
|
723
|
+
privateEventStore: this.privateEventStore,
|
|
724
|
+
jobId: this.jobId,
|
|
725
|
+
scopes,
|
|
726
|
+
});
|
|
636
727
|
const acirExecutionResult = await new WASMSimulator()
|
|
637
|
-
.executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
728
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
638
729
|
.catch((err: Error) => {
|
|
639
730
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
640
731
|
throw new ExecutionError(
|