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