@aztec/txe 0.0.1-commit.24de95ac → 0.0.1-commit.2e2504e2
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/bin/index.d.ts +1 -1
- 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 +11 -8
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +7 -7
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +10 -12
- package/dest/oracle/txe_oracle_top_level_context.d.ts +22 -12
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +128 -79
- package/dest/rpc_translator.d.ts +32 -17
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +134 -60
- package/dest/state_machine/archiver.d.ts +21 -51
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +63 -94
- package/dest/state_machine/dummy_p2p_client.d.ts +9 -6
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +16 -8
- package/dest/state_machine/global_variable_builder.d.ts +6 -4
- 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 +39 -22
- package/dest/state_machine/mock_epoch_cache.d.ts +12 -10
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +17 -13
- package/dest/state_machine/synchronizer.d.ts +3 -2
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +5 -4
- package/dest/txe_session.d.ts +21 -13
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +101 -49
- package/dest/util/encoding.d.ts +615 -16
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +1 -1
- package/dest/util/expected_failure_error.d.ts +1 -1
- package/dest/util/expected_failure_error.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 +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 +21 -6
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +38 -4
- package/dest/utils/tx_effect_creation.d.ts +3 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +4 -7
- package/package.json +18 -17
- package/src/constants.ts +3 -0
- package/src/index.ts +15 -12
- package/src/oracle/interfaces.ts +10 -7
- package/src/oracle/txe_oracle_public_context.ts +12 -19
- package/src/oracle/txe_oracle_top_level_context.ts +205 -107
- package/src/rpc_translator.ts +159 -63
- package/src/state_machine/archiver.ts +63 -117
- package/src/state_machine/dummy_p2p_client.ts +22 -10
- package/src/state_machine/global_variable_builder.ts +22 -4
- package/src/state_machine/index.ts +59 -21
- package/src/state_machine/mock_epoch_cache.ts +20 -20
- package/src/state_machine/synchronizer.ts +6 -5
- package/src/txe_session.ts +197 -85
- 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 +49 -14
- package/src/utils/tx_effect_creation.ts +5 -12
- 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,18 +44,18 @@ 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, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
47
53
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
54
|
+
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
48
55
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
49
|
-
import { Body, L2Block } from '@aztec/stdlib/block';
|
|
50
56
|
import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
|
|
51
57
|
import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
|
|
52
|
-
import { computeCalldataHash, siloNullifier } from '@aztec/stdlib/hash';
|
|
58
|
+
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
53
59
|
import {
|
|
54
60
|
PartialPrivateTailPublicInputsForPublic,
|
|
55
61
|
PrivateKernelTailCircuitPublicInputs,
|
|
@@ -57,7 +63,7 @@ import {
|
|
|
57
63
|
PublicCallRequest,
|
|
58
64
|
} from '@aztec/stdlib/kernel';
|
|
59
65
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
60
|
-
import {
|
|
66
|
+
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
61
67
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
62
68
|
import {
|
|
63
69
|
CallContext,
|
|
@@ -74,15 +80,12 @@ import {
|
|
|
74
80
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
75
81
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
76
82
|
|
|
83
|
+
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
77
84
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
78
|
-
import type {
|
|
79
|
-
import type {
|
|
85
|
+
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
86
|
+
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
80
87
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
81
|
-
import {
|
|
82
|
-
getSingleTxBlockRequestHash,
|
|
83
|
-
insertTxEffectIntoWorldTrees,
|
|
84
|
-
makeTXEBlockHeader,
|
|
85
|
-
} from '../utils/block_creation.js';
|
|
88
|
+
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
86
89
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
87
90
|
|
|
88
91
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
@@ -93,11 +96,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
93
96
|
|
|
94
97
|
constructor(
|
|
95
98
|
private stateMachine: TXEStateMachine,
|
|
96
|
-
private
|
|
99
|
+
private contractStore: TXEContractStore,
|
|
100
|
+
private noteStore: NoteStore,
|
|
97
101
|
private keyStore: KeyStore,
|
|
98
|
-
private
|
|
99
|
-
private
|
|
100
|
-
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,
|
|
101
110
|
private nextBlockTimestamp: bigint,
|
|
102
111
|
private version: Fr,
|
|
103
112
|
private chainId: Fr,
|
|
@@ -131,8 +140,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
131
140
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
132
141
|
}
|
|
133
142
|
|
|
134
|
-
|
|
135
|
-
return
|
|
143
|
+
txeGetDefaultAddress(): AztecAddress {
|
|
144
|
+
return DEFAULT_ADDRESS;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async txeGetNextBlockNumber(): Promise<BlockNumber> {
|
|
148
|
+
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
136
149
|
}
|
|
137
150
|
|
|
138
151
|
txeGetNextBlockTimestamp(): Promise<bigint> {
|
|
@@ -144,7 +157,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
144
157
|
}
|
|
145
158
|
|
|
146
159
|
async txeGetLastTxEffects() {
|
|
147
|
-
const
|
|
160
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
161
|
+
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
148
162
|
|
|
149
163
|
if (block!.body.txEffects.length != 1) {
|
|
150
164
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -156,6 +170,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
156
170
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
157
171
|
}
|
|
158
172
|
|
|
173
|
+
async txeGetPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
174
|
+
return (
|
|
175
|
+
await this.privateEventStore.getPrivateEvents(selector, {
|
|
176
|
+
contractAddress,
|
|
177
|
+
scopes: [scope],
|
|
178
|
+
fromBlock: 0,
|
|
179
|
+
toBlock: (await this.getLastBlockNumber()) + 1,
|
|
180
|
+
})
|
|
181
|
+
).map(e => e.packedEvent);
|
|
182
|
+
}
|
|
183
|
+
|
|
159
184
|
async txeAdvanceBlocksBy(blocks: number) {
|
|
160
185
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
161
186
|
|
|
@@ -183,8 +208,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
183
208
|
if (!secret.equals(Fr.ZERO)) {
|
|
184
209
|
await this.txeAddAccount(artifact, instance, secret);
|
|
185
210
|
} else {
|
|
186
|
-
await this.
|
|
187
|
-
await this.
|
|
211
|
+
await this.contractStore.addContractInstance(instance);
|
|
212
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
188
213
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
189
214
|
}
|
|
190
215
|
}
|
|
@@ -193,29 +218,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
193
218
|
const partialAddress = await computePartialAddress(instance);
|
|
194
219
|
|
|
195
220
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
196
|
-
await this.
|
|
197
|
-
await this.
|
|
221
|
+
await this.contractStore.addContractInstance(instance);
|
|
222
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
198
223
|
|
|
199
224
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
200
|
-
await this.
|
|
201
|
-
await this.
|
|
225
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
226
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
202
227
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
203
228
|
|
|
204
229
|
return completeAddress;
|
|
205
230
|
}
|
|
206
231
|
|
|
207
232
|
async txeCreateAccount(secret: Fr) {
|
|
208
|
-
// This is a
|
|
233
|
+
// This is a foot gun !
|
|
209
234
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
210
|
-
await this.
|
|
211
|
-
await this.
|
|
235
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
236
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
212
237
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
213
238
|
|
|
214
239
|
return completeAddress;
|
|
215
240
|
}
|
|
216
241
|
|
|
217
242
|
async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
218
|
-
const account = await this.
|
|
243
|
+
const account = await this.accountStore.getAccount(address);
|
|
219
244
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
220
245
|
|
|
221
246
|
const schnorr = new Schnorr();
|
|
@@ -236,19 +261,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
236
261
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
237
262
|
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
238
263
|
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
version: this.version,
|
|
247
|
-
chainId: this.chainId,
|
|
248
|
-
}),
|
|
249
|
-
),
|
|
250
|
-
new Body([txEffect]),
|
|
251
|
-
);
|
|
264
|
+
const globals = makeGlobalVariables(undefined, {
|
|
265
|
+
blockNumber,
|
|
266
|
+
timestamp: this.nextBlockTimestamp,
|
|
267
|
+
version: this.version,
|
|
268
|
+
chainId: this.chainId,
|
|
269
|
+
});
|
|
270
|
+
const block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
252
271
|
|
|
253
272
|
await forkedWorldTrees.close();
|
|
254
273
|
|
|
@@ -266,10 +285,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
266
285
|
isStaticCall: boolean = false,
|
|
267
286
|
) {
|
|
268
287
|
this.logger.verbose(
|
|
269
|
-
`Executing external function ${await this.
|
|
288
|
+
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
270
289
|
);
|
|
271
290
|
|
|
272
|
-
const artifact = await this.
|
|
291
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
273
292
|
if (!artifact) {
|
|
274
293
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
275
294
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -277,22 +296,37 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
277
296
|
throw new Error(message);
|
|
278
297
|
}
|
|
279
298
|
|
|
299
|
+
// Sync notes before executing private function to discover notes from previous transactions
|
|
300
|
+
const utilityExecutor = async (call: FunctionCall) => {
|
|
301
|
+
await this.executeUtilityCall(call);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
305
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
306
|
+
targetContractAddress,
|
|
307
|
+
functionSelector,
|
|
308
|
+
utilityExecutor,
|
|
309
|
+
blockHeader,
|
|
310
|
+
this.jobId,
|
|
311
|
+
);
|
|
312
|
+
|
|
280
313
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
281
314
|
|
|
282
315
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
283
316
|
|
|
284
317
|
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
285
|
-
|
|
286
318
|
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
287
|
-
|
|
288
319
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
289
320
|
|
|
290
321
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
291
322
|
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
323
|
+
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
324
|
+
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
325
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
326
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
327
|
+
// marking all side effects as revertible.
|
|
328
|
+
const minRevertibleSideEffectCounter = 1;
|
|
329
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
296
330
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
297
331
|
|
|
298
332
|
const simulator = new WASMSimulator();
|
|
@@ -303,6 +337,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
303
337
|
callContext,
|
|
304
338
|
/** Header of a block whose state is used during private execution (not the block the transaction is included in). */
|
|
305
339
|
blockHeader,
|
|
340
|
+
utilityExecutor,
|
|
306
341
|
/** List of transient auth witnesses to be used during this simulation */
|
|
307
342
|
Array.from(this.authwits.values()),
|
|
308
343
|
/** List of transient auth witnesses to be used during this simulation */
|
|
@@ -310,9 +345,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
310
345
|
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
311
346
|
noteCache,
|
|
312
347
|
taggingIndexCache,
|
|
313
|
-
this.
|
|
314
|
-
|
|
315
|
-
|
|
348
|
+
this.contractStore,
|
|
349
|
+
this.noteStore,
|
|
350
|
+
this.keyStore,
|
|
351
|
+
this.addressStore,
|
|
352
|
+
this.stateMachine.node,
|
|
353
|
+
this.senderTaggingStore,
|
|
354
|
+
this.recipientTaggingStore,
|
|
355
|
+
this.senderAddressBookStore,
|
|
356
|
+
this.capsuleStore,
|
|
357
|
+
this.privateEventStore,
|
|
358
|
+
this.stateMachine.contractSyncService,
|
|
359
|
+
this.jobId,
|
|
360
|
+
0, // totalPublicArgsCount
|
|
361
|
+
minRevertibleSideEffectCounter, // (start) sideEffectCounter
|
|
316
362
|
undefined, // log
|
|
317
363
|
undefined, // scopes
|
|
318
364
|
/**
|
|
@@ -348,19 +394,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
348
394
|
}),
|
|
349
395
|
);
|
|
350
396
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
397
|
+
noteCache.finish();
|
|
398
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
399
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
355
400
|
} catch (err) {
|
|
356
401
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
357
402
|
}
|
|
358
403
|
|
|
359
|
-
// According to the protocol rules,
|
|
360
|
-
//
|
|
361
|
-
//
|
|
362
|
-
const
|
|
363
|
-
|
|
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
|
+
this.contractStore,
|
|
410
|
+
minRevertibleSideEffectCounter,
|
|
411
|
+
);
|
|
364
412
|
|
|
365
413
|
const globals = makeGlobalVariables();
|
|
366
414
|
globals.blockNumber = blockNumber;
|
|
@@ -371,17 +419,27 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
371
419
|
|
|
372
420
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
373
421
|
|
|
374
|
-
const
|
|
422
|
+
const bindings = this.logger.getBindings();
|
|
423
|
+
const contractsDB = new PublicContractsDB(
|
|
424
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
425
|
+
bindings,
|
|
426
|
+
);
|
|
375
427
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
428
|
+
const config = PublicSimulatorConfig.from({
|
|
429
|
+
skipFeeEnforcement: true,
|
|
430
|
+
collectDebugLogs: true,
|
|
431
|
+
collectHints: false,
|
|
432
|
+
collectStatistics: false,
|
|
433
|
+
collectCallMetadata: true,
|
|
434
|
+
});
|
|
376
435
|
const processor = new PublicProcessor(
|
|
377
436
|
globals,
|
|
378
437
|
guardedMerkleTrees,
|
|
379
438
|
contractsDB,
|
|
380
|
-
new
|
|
381
|
-
doMerkleOperations: true,
|
|
382
|
-
skipFeeEnforcement: true,
|
|
383
|
-
}),
|
|
439
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
384
440
|
new TestDateProvider(),
|
|
441
|
+
undefined,
|
|
442
|
+
createLogger('simulator:public-processor', bindings),
|
|
385
443
|
);
|
|
386
444
|
|
|
387
445
|
const tx = await Tx.create({
|
|
@@ -406,7 +464,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
406
464
|
} else if (!processedTx.revertCode.isOK()) {
|
|
407
465
|
if (processedTx.revertReason) {
|
|
408
466
|
try {
|
|
409
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
467
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
410
468
|
// eslint-disable-next-line no-empty
|
|
411
469
|
} catch {}
|
|
412
470
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -435,13 +493,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
435
493
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
436
494
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
437
495
|
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
const l2Block = new L2Block(
|
|
441
|
-
makeAppendOnlyTreeSnapshot(),
|
|
442
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
443
|
-
body,
|
|
444
|
-
);
|
|
496
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
445
497
|
|
|
446
498
|
await this.stateMachine.handleL2Block(l2Block);
|
|
447
499
|
|
|
@@ -457,7 +509,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
457
509
|
isStaticCall: boolean,
|
|
458
510
|
) {
|
|
459
511
|
this.logger.verbose(
|
|
460
|
-
`Executing public function ${await this.
|
|
512
|
+
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
461
513
|
);
|
|
462
514
|
|
|
463
515
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
@@ -470,7 +522,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
470
522
|
|
|
471
523
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
472
524
|
|
|
473
|
-
const anchorBlockHeader = await this.
|
|
525
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
474
526
|
|
|
475
527
|
const calldataHash = await computeCalldataHash(calldata);
|
|
476
528
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
@@ -484,22 +536,36 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
484
536
|
|
|
485
537
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
486
538
|
|
|
487
|
-
const
|
|
539
|
+
const bindings2 = this.logger.getBindings();
|
|
540
|
+
const contractsDB = new PublicContractsDB(
|
|
541
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
542
|
+
bindings2,
|
|
543
|
+
);
|
|
488
544
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
489
|
-
const
|
|
490
|
-
doMerkleOperations: true,
|
|
545
|
+
const config = PublicSimulatorConfig.from({
|
|
491
546
|
skipFeeEnforcement: true,
|
|
547
|
+
collectDebugLogs: true,
|
|
548
|
+
collectHints: false,
|
|
549
|
+
collectStatistics: false,
|
|
550
|
+
collectCallMetadata: true,
|
|
492
551
|
});
|
|
493
|
-
const
|
|
552
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
553
|
+
const processor = new PublicProcessor(
|
|
554
|
+
globals,
|
|
555
|
+
guardedMerkleTrees,
|
|
556
|
+
contractsDB,
|
|
557
|
+
simulator,
|
|
558
|
+
new TestDateProvider(),
|
|
559
|
+
undefined,
|
|
560
|
+
createLogger('simulator:public-processor', bindings2),
|
|
561
|
+
);
|
|
494
562
|
|
|
495
563
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
496
564
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
497
565
|
// side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
|
|
498
566
|
// unique.
|
|
499
567
|
const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
500
|
-
|
|
501
|
-
nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
|
|
502
|
-
}
|
|
568
|
+
nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
|
|
503
569
|
|
|
504
570
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
505
571
|
// may require producing reverts.
|
|
@@ -550,7 +616,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
550
616
|
} else if (!processedTx.revertCode.isOK()) {
|
|
551
617
|
if (processedTx.revertReason) {
|
|
552
618
|
try {
|
|
553
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
619
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
554
620
|
// eslint-disable-next-line no-empty
|
|
555
621
|
} catch {}
|
|
556
622
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -582,13 +648,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
582
648
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
583
649
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
584
650
|
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
const l2Block = new L2Block(
|
|
588
|
-
makeAppendOnlyTreeSnapshot(),
|
|
589
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
590
|
-
body,
|
|
591
|
-
);
|
|
651
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
592
652
|
|
|
593
653
|
await this.stateMachine.handleL2Block(l2Block);
|
|
594
654
|
|
|
@@ -602,18 +662,39 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
602
662
|
functionSelector: FunctionSelector,
|
|
603
663
|
args: Fr[],
|
|
604
664
|
) {
|
|
605
|
-
const artifact = await this.
|
|
665
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
606
666
|
if (!artifact) {
|
|
607
667
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
608
668
|
}
|
|
609
669
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
670
|
+
// Sync notes before executing utility function to discover notes from previous transactions
|
|
671
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
672
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
673
|
+
targetContractAddress,
|
|
674
|
+
functionSelector,
|
|
675
|
+
async call => {
|
|
676
|
+
await this.executeUtilityCall(call);
|
|
677
|
+
},
|
|
678
|
+
blockHeader,
|
|
679
|
+
this.jobId,
|
|
680
|
+
);
|
|
615
681
|
|
|
616
|
-
const
|
|
682
|
+
const call = new FunctionCall(
|
|
683
|
+
artifact.name,
|
|
684
|
+
targetContractAddress,
|
|
685
|
+
functionSelector,
|
|
686
|
+
FunctionType.UTILITY,
|
|
687
|
+
false,
|
|
688
|
+
false,
|
|
689
|
+
args,
|
|
690
|
+
[],
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
return this.executeUtilityCall(call);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
697
|
+
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
617
698
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
618
699
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
619
700
|
}
|
|
@@ -624,9 +705,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
624
705
|
});
|
|
625
706
|
|
|
626
707
|
try {
|
|
627
|
-
const
|
|
708
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
709
|
+
const oracle = new UtilityExecutionOracle(
|
|
710
|
+
call.to,
|
|
711
|
+
[],
|
|
712
|
+
[],
|
|
713
|
+
anchorBlockHeader,
|
|
714
|
+
this.contractStore,
|
|
715
|
+
this.noteStore,
|
|
716
|
+
this.keyStore,
|
|
717
|
+
this.addressStore,
|
|
718
|
+
this.stateMachine.node,
|
|
719
|
+
this.recipientTaggingStore,
|
|
720
|
+
this.senderAddressBookStore,
|
|
721
|
+
this.capsuleStore,
|
|
722
|
+
this.privateEventStore,
|
|
723
|
+
this.jobId,
|
|
724
|
+
);
|
|
628
725
|
const acirExecutionResult = await new WASMSimulator()
|
|
629
|
-
.executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
726
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
630
727
|
.catch((err: Error) => {
|
|
631
728
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
632
729
|
throw new ExecutionError(
|
|
@@ -652,7 +749,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
652
749
|
return [this.nextBlockTimestamp, this.authwits];
|
|
653
750
|
}
|
|
654
751
|
|
|
655
|
-
private async getLastBlockNumber(): Promise<
|
|
656
|
-
|
|
752
|
+
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
753
|
+
const header = await this.stateMachine.node.getBlockHeader('latest');
|
|
754
|
+
return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
657
755
|
}
|
|
658
756
|
}
|