@aztec/txe 0.0.1-commit.9b94fc1 → 0.0.1-commit.9d2bcf6d
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 +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 +112 -72
- package/dest/rpc_translator.d.ts +26 -14
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +122 -55
- package/dest/state_machine/archiver.d.ts +21 -52
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +61 -94
- package/dest/state_machine/dummy_p2p_client.d.ts +8 -7
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +16 -11
- package/dest/state_machine/global_variable_builder.d.ts +6 -5
- 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 +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +31 -19
- package/dest/state_machine/mock_epoch_cache.d.ts +7 -6
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +10 -7
- 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 +94 -47
- package/dest/util/encoding.d.ts +618 -19
- 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 +21 -6
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +36 -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 -18
- 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 +195 -100
- package/src/rpc_translator.ts +151 -55
- package/src/state_machine/archiver.ts +57 -114
- package/src/state_machine/dummy_p2p_client.ts +21 -14
- package/src/state_machine/global_variable_builder.ts +21 -4
- package/src/state_machine/index.ts +40 -17
- package/src/state_machine/mock_epoch_cache.ts +10 -11
- package/src/state_machine/synchronizer.ts +6 -5
- package/src/txe_session.ts +188 -83
- 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 +47 -15
- 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,16 +6,23 @@ 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,
|
|
25
|
+
syncState,
|
|
19
26
|
} from '@aztec/pxe/server';
|
|
20
27
|
import {
|
|
21
28
|
ExecutionNoteCache,
|
|
@@ -38,16 +45,15 @@ import {
|
|
|
38
45
|
witnessMapToFields,
|
|
39
46
|
} from '@aztec/simulator/client';
|
|
40
47
|
import {
|
|
48
|
+
CppPublicTxSimulator,
|
|
41
49
|
GuardedMerkleTreeOperations,
|
|
42
50
|
PublicContractsDB,
|
|
43
51
|
PublicProcessor,
|
|
44
|
-
PublicTxSimulator,
|
|
45
52
|
} from '@aztec/simulator/server';
|
|
46
|
-
import { type ContractArtifact, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
53
|
+
import { type ContractArtifact, EventSelector, FunctionCall, FunctionSelector, FunctionType } from '@aztec/stdlib/abi';
|
|
47
54
|
import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
48
55
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
49
56
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
50
|
-
import { Body, L2Block } from '@aztec/stdlib/block';
|
|
51
57
|
import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
|
|
52
58
|
import { Gas, GasFees, GasSettings } from '@aztec/stdlib/gas';
|
|
53
59
|
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
@@ -58,7 +64,7 @@ import {
|
|
|
58
64
|
PublicCallRequest,
|
|
59
65
|
} from '@aztec/stdlib/kernel';
|
|
60
66
|
import { ChonkProof } from '@aztec/stdlib/proofs';
|
|
61
|
-
import {
|
|
67
|
+
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
62
68
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
63
69
|
import {
|
|
64
70
|
CallContext,
|
|
@@ -75,15 +81,12 @@ import {
|
|
|
75
81
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
76
82
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
77
83
|
|
|
84
|
+
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
78
85
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
79
|
-
import type {
|
|
80
|
-
import type {
|
|
86
|
+
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
87
|
+
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
81
88
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
82
|
-
import {
|
|
83
|
-
getSingleTxBlockRequestHash,
|
|
84
|
-
insertTxEffectIntoWorldTrees,
|
|
85
|
-
makeTXEBlockHeader,
|
|
86
|
-
} from '../utils/block_creation.js';
|
|
89
|
+
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
87
90
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
88
91
|
|
|
89
92
|
export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracle {
|
|
@@ -94,11 +97,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
94
97
|
|
|
95
98
|
constructor(
|
|
96
99
|
private stateMachine: TXEStateMachine,
|
|
97
|
-
private
|
|
100
|
+
private contractStore: TXEContractStore,
|
|
101
|
+
private noteStore: NoteStore,
|
|
98
102
|
private keyStore: KeyStore,
|
|
99
|
-
private
|
|
100
|
-
private
|
|
101
|
-
private
|
|
103
|
+
private addressStore: AddressStore,
|
|
104
|
+
private accountStore: TXEAccountStore,
|
|
105
|
+
private senderTaggingStore: SenderTaggingStore,
|
|
106
|
+
private recipientTaggingStore: RecipientTaggingStore,
|
|
107
|
+
private senderAddressBookStore: SenderAddressBookStore,
|
|
108
|
+
private capsuleStore: CapsuleStore,
|
|
109
|
+
private privateEventStore: PrivateEventStore,
|
|
110
|
+
private jobId: string,
|
|
102
111
|
private nextBlockTimestamp: bigint,
|
|
103
112
|
private version: Fr,
|
|
104
113
|
private chainId: Fr,
|
|
@@ -132,8 +141,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
132
141
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
133
142
|
}
|
|
134
143
|
|
|
135
|
-
|
|
136
|
-
return
|
|
144
|
+
txeGetDefaultAddress(): AztecAddress {
|
|
145
|
+
return DEFAULT_ADDRESS;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async txeGetNextBlockNumber(): Promise<BlockNumber> {
|
|
149
|
+
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
137
150
|
}
|
|
138
151
|
|
|
139
152
|
txeGetNextBlockTimestamp(): Promise<bigint> {
|
|
@@ -145,7 +158,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
145
158
|
}
|
|
146
159
|
|
|
147
160
|
async txeGetLastTxEffects() {
|
|
148
|
-
const
|
|
161
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
162
|
+
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
149
163
|
|
|
150
164
|
if (block!.body.txEffects.length != 1) {
|
|
151
165
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -157,6 +171,17 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
157
171
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
158
172
|
}
|
|
159
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
|
+
|
|
160
185
|
async txeAdvanceBlocksBy(blocks: number) {
|
|
161
186
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
162
187
|
|
|
@@ -184,8 +209,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
184
209
|
if (!secret.equals(Fr.ZERO)) {
|
|
185
210
|
await this.txeAddAccount(artifact, instance, secret);
|
|
186
211
|
} else {
|
|
187
|
-
await this.
|
|
188
|
-
await this.
|
|
212
|
+
await this.contractStore.addContractInstance(instance);
|
|
213
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
189
214
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
190
215
|
}
|
|
191
216
|
}
|
|
@@ -194,29 +219,29 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
194
219
|
const partialAddress = await computePartialAddress(instance);
|
|
195
220
|
|
|
196
221
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
197
|
-
await this.
|
|
198
|
-
await this.
|
|
222
|
+
await this.contractStore.addContractInstance(instance);
|
|
223
|
+
await this.contractStore.addContractArtifact(instance.currentContractClassId, artifact);
|
|
199
224
|
|
|
200
225
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
201
|
-
await this.
|
|
202
|
-
await this.
|
|
226
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
227
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
203
228
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
204
229
|
|
|
205
230
|
return completeAddress;
|
|
206
231
|
}
|
|
207
232
|
|
|
208
233
|
async txeCreateAccount(secret: Fr) {
|
|
209
|
-
// This is a
|
|
234
|
+
// This is a foot gun !
|
|
210
235
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
211
|
-
await this.
|
|
212
|
-
await this.
|
|
236
|
+
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
237
|
+
await this.addressStore.addCompleteAddress(completeAddress);
|
|
213
238
|
this.logger.debug(`Created account ${completeAddress.address}`);
|
|
214
239
|
|
|
215
240
|
return completeAddress;
|
|
216
241
|
}
|
|
217
242
|
|
|
218
243
|
async txeAddAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
219
|
-
const account = await this.
|
|
244
|
+
const account = await this.accountStore.getAccount(address);
|
|
220
245
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
221
246
|
|
|
222
247
|
const schnorr = new Schnorr();
|
|
@@ -237,19 +262,13 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
237
262
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
238
263
|
await insertTxEffectIntoWorldTrees(txEffect, forkedWorldTrees);
|
|
239
264
|
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
version: this.version,
|
|
248
|
-
chainId: this.chainId,
|
|
249
|
-
}),
|
|
250
|
-
),
|
|
251
|
-
new Body([txEffect]),
|
|
252
|
-
);
|
|
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]);
|
|
253
272
|
|
|
254
273
|
await forkedWorldTrees.close();
|
|
255
274
|
|
|
@@ -267,10 +286,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
267
286
|
isStaticCall: boolean = false,
|
|
268
287
|
) {
|
|
269
288
|
this.logger.verbose(
|
|
270
|
-
`Executing external function ${await this.
|
|
289
|
+
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
271
290
|
);
|
|
272
291
|
|
|
273
|
-
const artifact = await this.
|
|
292
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
274
293
|
if (!artifact) {
|
|
275
294
|
const message = functionSelector.equals(await FunctionSelector.fromSignature('verify_private_authwit(Field)'))
|
|
276
295
|
? 'Found no account contract artifact for a private authwit check - use `create_contract_account` instead of `create_light_account` for authwit support.'
|
|
@@ -278,22 +297,40 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
278
297
|
throw new Error(message);
|
|
279
298
|
}
|
|
280
299
|
|
|
300
|
+
// Sync notes before executing private function to discover notes from previous transactions
|
|
301
|
+
const utilityExecutor = async (call: FunctionCall) => {
|
|
302
|
+
await this.executeUtilityCall(call);
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
306
|
+
await syncState(
|
|
307
|
+
targetContractAddress,
|
|
308
|
+
this.contractStore,
|
|
309
|
+
functionSelector,
|
|
310
|
+
utilityExecutor,
|
|
311
|
+
this.noteStore,
|
|
312
|
+
this.stateMachine.node,
|
|
313
|
+
blockHeader,
|
|
314
|
+
this.jobId,
|
|
315
|
+
);
|
|
316
|
+
|
|
281
317
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
282
318
|
|
|
283
319
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
284
320
|
|
|
285
321
|
const gasLimits = new Gas(DEFAULT_DA_GAS_LIMIT, DEFAULT_L2_GAS_LIMIT);
|
|
286
|
-
|
|
287
322
|
const teardownGasLimits = new Gas(DEFAULT_TEARDOWN_DA_GAS_LIMIT, DEFAULT_TEARDOWN_L2_GAS_LIMIT);
|
|
288
|
-
|
|
289
323
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
290
324
|
|
|
291
325
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
292
326
|
|
|
293
|
-
const blockHeader = await this.pxeOracleInterface.getAnchorBlockHeader();
|
|
294
|
-
|
|
295
327
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
296
328
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
329
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
330
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
331
|
+
// marking all side effects as revertible.
|
|
332
|
+
const minRevertibleSideEffectCounter = 1;
|
|
333
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
297
334
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
298
335
|
|
|
299
336
|
const simulator = new WASMSimulator();
|
|
@@ -304,6 +341,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
304
341
|
callContext,
|
|
305
342
|
/** Header of a block whose state is used during private execution (not the block the transaction is included in). */
|
|
306
343
|
blockHeader,
|
|
344
|
+
utilityExecutor,
|
|
307
345
|
/** List of transient auth witnesses to be used during this simulation */
|
|
308
346
|
Array.from(this.authwits.values()),
|
|
309
347
|
/** List of transient auth witnesses to be used during this simulation */
|
|
@@ -311,9 +349,19 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
311
349
|
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
312
350
|
noteCache,
|
|
313
351
|
taggingIndexCache,
|
|
314
|
-
this.
|
|
315
|
-
|
|
316
|
-
|
|
352
|
+
this.contractStore,
|
|
353
|
+
this.noteStore,
|
|
354
|
+
this.keyStore,
|
|
355
|
+
this.addressStore,
|
|
356
|
+
this.stateMachine.node,
|
|
357
|
+
this.senderTaggingStore,
|
|
358
|
+
this.recipientTaggingStore,
|
|
359
|
+
this.senderAddressBookStore,
|
|
360
|
+
this.capsuleStore,
|
|
361
|
+
this.privateEventStore,
|
|
362
|
+
this.jobId,
|
|
363
|
+
0, // totalPublicArgsCount
|
|
364
|
+
minRevertibleSideEffectCounter, // (start) sideEffectCounter
|
|
317
365
|
undefined, // log
|
|
318
366
|
undefined, // scopes
|
|
319
367
|
/**
|
|
@@ -349,19 +397,21 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
349
397
|
}),
|
|
350
398
|
);
|
|
351
399
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
400
|
+
noteCache.finish();
|
|
401
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
402
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
356
403
|
} catch (err) {
|
|
357
404
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
358
405
|
}
|
|
359
406
|
|
|
360
|
-
// According to the protocol rules,
|
|
361
|
-
//
|
|
362
|
-
//
|
|
363
|
-
const
|
|
364
|
-
|
|
407
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
408
|
+
// the nonce generator for the note hashes.
|
|
409
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
410
|
+
const { publicInputs } = await generateSimulatedProvingResult(
|
|
411
|
+
result,
|
|
412
|
+
this.contractStore,
|
|
413
|
+
minRevertibleSideEffectCounter,
|
|
414
|
+
);
|
|
365
415
|
|
|
366
416
|
const globals = makeGlobalVariables();
|
|
367
417
|
globals.blockNumber = blockNumber;
|
|
@@ -372,7 +422,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
372
422
|
|
|
373
423
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
374
424
|
|
|
375
|
-
const
|
|
425
|
+
const bindings = this.logger.getBindings();
|
|
426
|
+
const contractsDB = new PublicContractsDB(
|
|
427
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
428
|
+
bindings,
|
|
429
|
+
);
|
|
376
430
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
377
431
|
const config = PublicSimulatorConfig.from({
|
|
378
432
|
skipFeeEnforcement: true,
|
|
@@ -385,8 +439,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
385
439
|
globals,
|
|
386
440
|
guardedMerkleTrees,
|
|
387
441
|
contractsDB,
|
|
388
|
-
new
|
|
442
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
389
443
|
new TestDateProvider(),
|
|
444
|
+
undefined,
|
|
445
|
+
createLogger('simulator:public-processor', bindings),
|
|
390
446
|
);
|
|
391
447
|
|
|
392
448
|
const tx = await Tx.create({
|
|
@@ -411,7 +467,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
411
467
|
} else if (!processedTx.revertCode.isOK()) {
|
|
412
468
|
if (processedTx.revertReason) {
|
|
413
469
|
try {
|
|
414
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
470
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
415
471
|
// eslint-disable-next-line no-empty
|
|
416
472
|
} catch {}
|
|
417
473
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -440,13 +496,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
440
496
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
441
497
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
442
498
|
|
|
443
|
-
const
|
|
444
|
-
|
|
445
|
-
const l2Block = new L2Block(
|
|
446
|
-
makeAppendOnlyTreeSnapshot(),
|
|
447
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
448
|
-
body,
|
|
449
|
-
);
|
|
499
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
450
500
|
|
|
451
501
|
await this.stateMachine.handleL2Block(l2Block);
|
|
452
502
|
|
|
@@ -462,7 +512,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
462
512
|
isStaticCall: boolean,
|
|
463
513
|
) {
|
|
464
514
|
this.logger.verbose(
|
|
465
|
-
`Executing public function ${await this.
|
|
515
|
+
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
466
516
|
);
|
|
467
517
|
|
|
468
518
|
const blockNumber = await this.txeGetNextBlockNumber();
|
|
@@ -475,7 +525,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
475
525
|
|
|
476
526
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
477
527
|
|
|
478
|
-
const anchorBlockHeader = await this.
|
|
528
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
479
529
|
|
|
480
530
|
const calldataHash = await computeCalldataHash(calldata);
|
|
481
531
|
const calldataHashedValues = new HashedValues(calldata, calldataHash);
|
|
@@ -489,7 +539,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
489
539
|
|
|
490
540
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
491
541
|
|
|
492
|
-
const
|
|
542
|
+
const bindings2 = this.logger.getBindings();
|
|
543
|
+
const contractsDB = new PublicContractsDB(
|
|
544
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
545
|
+
bindings2,
|
|
546
|
+
);
|
|
493
547
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
494
548
|
const config = PublicSimulatorConfig.from({
|
|
495
549
|
skipFeeEnforcement: true,
|
|
@@ -498,17 +552,23 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
498
552
|
collectStatistics: false,
|
|
499
553
|
collectCallMetadata: true,
|
|
500
554
|
});
|
|
501
|
-
const simulator = new
|
|
502
|
-
const processor = new PublicProcessor(
|
|
555
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
556
|
+
const processor = new PublicProcessor(
|
|
557
|
+
globals,
|
|
558
|
+
guardedMerkleTrees,
|
|
559
|
+
contractsDB,
|
|
560
|
+
simulator,
|
|
561
|
+
new TestDateProvider(),
|
|
562
|
+
undefined,
|
|
563
|
+
createLogger('simulator:public-processor', bindings2),
|
|
564
|
+
);
|
|
503
565
|
|
|
504
566
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
505
567
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
506
568
|
// side-effect, which the AVM then expects to exist in order to use it as the nonce generator when siloing notes as
|
|
507
569
|
// unique.
|
|
508
570
|
const nonRevertibleAccumulatedData = PrivateToPublicAccumulatedData.empty();
|
|
509
|
-
|
|
510
|
-
nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
|
|
511
|
-
}
|
|
571
|
+
nonRevertibleAccumulatedData.nullifiers[0] = getSingleTxBlockRequestHash(blockNumber);
|
|
512
572
|
|
|
513
573
|
// The enqueued public call itself we make be revertible so that the public execution is itself revertible, as tests
|
|
514
574
|
// may require producing reverts.
|
|
@@ -559,7 +619,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
559
619
|
} else if (!processedTx.revertCode.isOK()) {
|
|
560
620
|
if (processedTx.revertReason) {
|
|
561
621
|
try {
|
|
562
|
-
await enrichPublicSimulationError(processedTx.revertReason, this.
|
|
622
|
+
await enrichPublicSimulationError(processedTx.revertReason, this.contractStore, this.logger);
|
|
563
623
|
// eslint-disable-next-line no-empty
|
|
564
624
|
} catch {}
|
|
565
625
|
throw new Error(`Contract execution has reverted: ${processedTx.revertReason.getMessage()}`);
|
|
@@ -591,13 +651,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
591
651
|
const l1ToL2Messages = Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero);
|
|
592
652
|
await forkedWorldTrees.appendLeaves(MerkleTreeId.L1_TO_L2_MESSAGE_TREE, l1ToL2Messages);
|
|
593
653
|
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
const l2Block = new L2Block(
|
|
597
|
-
makeAppendOnlyTreeSnapshot(),
|
|
598
|
-
await makeTXEBlockHeader(forkedWorldTrees, globals),
|
|
599
|
-
body,
|
|
600
|
-
);
|
|
654
|
+
const l2Block = await makeTXEBlock(forkedWorldTrees, globals, [txEffect]);
|
|
601
655
|
|
|
602
656
|
await this.stateMachine.handleL2Block(l2Block);
|
|
603
657
|
|
|
@@ -611,18 +665,42 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
611
665
|
functionSelector: FunctionSelector,
|
|
612
666
|
args: Fr[],
|
|
613
667
|
) {
|
|
614
|
-
const artifact = await this.
|
|
668
|
+
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
615
669
|
if (!artifact) {
|
|
616
670
|
throw new Error(`Cannot call ${functionSelector} as there is no artifact found at ${targetContractAddress}.`);
|
|
617
671
|
}
|
|
618
672
|
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
673
|
+
// Sync notes before executing utility function to discover notes from previous transactions
|
|
674
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
675
|
+
await syncState(
|
|
676
|
+
targetContractAddress,
|
|
677
|
+
this.contractStore,
|
|
678
|
+
functionSelector,
|
|
679
|
+
async call => {
|
|
680
|
+
await this.executeUtilityCall(call);
|
|
681
|
+
},
|
|
682
|
+
this.noteStore,
|
|
683
|
+
this.stateMachine.node,
|
|
684
|
+
blockHeader,
|
|
685
|
+
this.jobId,
|
|
686
|
+
);
|
|
624
687
|
|
|
625
|
-
const
|
|
688
|
+
const call = new FunctionCall(
|
|
689
|
+
artifact.name,
|
|
690
|
+
targetContractAddress,
|
|
691
|
+
functionSelector,
|
|
692
|
+
FunctionType.UTILITY,
|
|
693
|
+
false,
|
|
694
|
+
false,
|
|
695
|
+
args,
|
|
696
|
+
[],
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
return this.executeUtilityCall(call);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
703
|
+
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
626
704
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
627
705
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
628
706
|
}
|
|
@@ -633,9 +711,25 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
633
711
|
});
|
|
634
712
|
|
|
635
713
|
try {
|
|
636
|
-
const
|
|
714
|
+
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
715
|
+
const oracle = new UtilityExecutionOracle(
|
|
716
|
+
call.to,
|
|
717
|
+
[],
|
|
718
|
+
[],
|
|
719
|
+
anchorBlockHeader,
|
|
720
|
+
this.contractStore,
|
|
721
|
+
this.noteStore,
|
|
722
|
+
this.keyStore,
|
|
723
|
+
this.addressStore,
|
|
724
|
+
this.stateMachine.node,
|
|
725
|
+
this.recipientTaggingStore,
|
|
726
|
+
this.senderAddressBookStore,
|
|
727
|
+
this.capsuleStore,
|
|
728
|
+
this.privateEventStore,
|
|
729
|
+
this.jobId,
|
|
730
|
+
);
|
|
637
731
|
const acirExecutionResult = await new WASMSimulator()
|
|
638
|
-
.executeUserCircuit(toACVMWitness(0, args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
732
|
+
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
639
733
|
.catch((err: Error) => {
|
|
640
734
|
err.message = resolveAssertionMessageFromError(err, entryPointArtifact);
|
|
641
735
|
throw new ExecutionError(
|
|
@@ -661,7 +755,8 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
661
755
|
return [this.nextBlockTimestamp, this.authwits];
|
|
662
756
|
}
|
|
663
757
|
|
|
664
|
-
private async getLastBlockNumber(): Promise<
|
|
665
|
-
|
|
758
|
+
private async getLastBlockNumber(): Promise<BlockNumber> {
|
|
759
|
+
const header = await this.stateMachine.node.getBlockHeader('latest');
|
|
760
|
+
return header ? header.globalVariables.blockNumber : BlockNumber.ZERO;
|
|
666
761
|
}
|
|
667
762
|
}
|