@aztec/txe 0.0.1-commit.1142ef1 → 0.0.1-commit.11bf3dd6e
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 +1 -2
- package/dest/constants.d.ts.map +1 -1
- package/dest/constants.js +0 -1
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +88 -54
- package/dest/oracle/interfaces.d.ts +29 -28
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +13 -13
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +16 -16
- package/dest/oracle/txe_oracle_top_level_context.d.ts +28 -22
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +165 -71
- package/dest/rpc_translator.d.ts +125 -81
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +426 -179
- package/dest/state_machine/archiver.d.ts +20 -69
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +36 -179
- package/dest/state_machine/dummy_p2p_client.d.ts +18 -13
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +33 -18
- package/dest/state_machine/global_variable_builder.d.ts +9 -4
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +9 -3
- package/dest/state_machine/index.d.ts +7 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +40 -13
- package/dest/state_machine/mock_epoch_cache.d.ts +25 -8
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +46 -9
- package/dest/state_machine/synchronizer.d.ts +6 -6
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +3 -3
- package/dest/txe_session.d.ts +12 -6
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +115 -28
- package/dest/util/encoding.d.ts +88 -18
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +4 -0
- package/dest/util/txe_public_contract_data_source.d.ts +2 -3
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +6 -25
- package/dest/utils/block_creation.d.ts +4 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +18 -4
- package/dest/utils/tx_effect_creation.d.ts +2 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +3 -6
- package/package.json +16 -16
- package/src/constants.ts +0 -1
- package/src/index.ts +89 -52
- package/src/oracle/interfaces.ts +32 -31
- package/src/oracle/txe_oracle_public_context.ts +16 -18
- package/src/oracle/txe_oracle_top_level_context.ts +208 -123
- package/src/rpc_translator.ts +493 -204
- package/src/state_machine/archiver.ts +38 -234
- package/src/state_machine/dummy_p2p_client.ts +46 -24
- package/src/state_machine/global_variable_builder.ts +18 -3
- package/src/state_machine/index.ts +56 -12
- package/src/state_machine/mock_epoch_cache.ts +57 -14
- package/src/state_machine/synchronizer.ts +5 -5
- package/src/txe_session.ts +132 -88
- package/src/util/encoding.ts +5 -0
- package/src/util/txe_public_contract_data_source.ts +10 -38
- package/src/utils/block_creation.ts +19 -16
- package/src/utils/tx_effect_creation.ts +3 -11
- package/dest/util/txe_contract_store.d.ts +0 -12
- package/dest/util/txe_contract_store.d.ts.map +0 -1
- package/dest/util/txe_contract_store.js +0 -22
- package/src/util/txe_contract_store.ts +0 -36
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CONTRACT_INSTANCE_REGISTRY_CONTRACT_ADDRESS,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
DEFAULT_TEARDOWN_DA_GAS_LIMIT,
|
|
6
|
-
DEFAULT_TEARDOWN_L2_GAS_LIMIT,
|
|
3
|
+
MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT,
|
|
4
|
+
MAX_PROCESSABLE_L2_GAS,
|
|
7
5
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
8
6
|
} from '@aztec/constants';
|
|
9
7
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
@@ -14,9 +12,12 @@ import { TestDateProvider } from '@aztec/foundation/timer';
|
|
|
14
12
|
import type { KeyStore } from '@aztec/key-store';
|
|
15
13
|
import {
|
|
16
14
|
AddressStore,
|
|
15
|
+
CapsuleService,
|
|
17
16
|
CapsuleStore,
|
|
17
|
+
type ContractStore,
|
|
18
|
+
type ContractSyncService,
|
|
18
19
|
NoteStore,
|
|
19
|
-
|
|
20
|
+
ORACLE_VERSION_MAJOR,
|
|
20
21
|
PrivateEventStore,
|
|
21
22
|
RecipientTaggingStore,
|
|
22
23
|
SenderAddressBookStore,
|
|
@@ -54,7 +55,13 @@ import { AuthWitness } from '@aztec/stdlib/auth-witness';
|
|
|
54
55
|
import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
55
56
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
56
57
|
import { type ContractInstanceWithAddress, computePartialAddress } from '@aztec/stdlib/contract';
|
|
57
|
-
import {
|
|
58
|
+
import {
|
|
59
|
+
FALLBACK_TEARDOWN_DA_GAS_LIMIT,
|
|
60
|
+
FALLBACK_TEARDOWN_L2_GAS_LIMIT,
|
|
61
|
+
Gas,
|
|
62
|
+
GasFees,
|
|
63
|
+
GasSettings,
|
|
64
|
+
} from '@aztec/stdlib/gas';
|
|
58
65
|
import { computeCalldataHash, computeProtocolNullifier, siloNullifier } from '@aztec/stdlib/hash';
|
|
59
66
|
import {
|
|
60
67
|
PartialPrivateTailPublicInputsForPublic,
|
|
@@ -80,10 +87,9 @@ import {
|
|
|
80
87
|
import type { UInt64 } from '@aztec/stdlib/types';
|
|
81
88
|
import { ForkCheckpoint } from '@aztec/world-state';
|
|
82
89
|
|
|
83
|
-
import { DEFAULT_ADDRESS
|
|
90
|
+
import { DEFAULT_ADDRESS } from '../constants.js';
|
|
84
91
|
import type { TXEStateMachine } from '../state_machine/index.js';
|
|
85
92
|
import type { TXEAccountStore } from '../util/txe_account_store.js';
|
|
86
|
-
import type { TXEContractStore } from '../util/txe_contract_store.js';
|
|
87
93
|
import { TXEPublicContractDataSource } from '../util/txe_public_contract_data_source.js';
|
|
88
94
|
import { getSingleTxBlockRequestHash, insertTxEffectIntoWorldTrees, makeTXEBlock } from '../utils/block_creation.js';
|
|
89
95
|
import type { ITxeExecutionOracle } from './interfaces.js';
|
|
@@ -96,7 +102,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
96
102
|
|
|
97
103
|
constructor(
|
|
98
104
|
private stateMachine: TXEStateMachine,
|
|
99
|
-
private contractStore:
|
|
105
|
+
private contractStore: ContractStore,
|
|
100
106
|
private noteStore: NoteStore,
|
|
101
107
|
private keyStore: KeyStore,
|
|
102
108
|
private addressStore: AddressStore,
|
|
@@ -110,53 +116,68 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
110
116
|
private version: Fr,
|
|
111
117
|
private chainId: Fr,
|
|
112
118
|
private authwits: Map<string, AuthWitness>,
|
|
119
|
+
private readonly contractSyncService: ContractSyncService,
|
|
113
120
|
) {
|
|
114
121
|
this.logger = createLogger('txe:top_level_context');
|
|
115
122
|
this.logger.debug('Entering Top Level Context');
|
|
116
123
|
}
|
|
117
124
|
|
|
118
|
-
|
|
119
|
-
|
|
125
|
+
private contractOracleVersion: { major: number; minor: number } | undefined;
|
|
126
|
+
|
|
127
|
+
assertCompatibleOracleVersion(major: number, minor: number): void {
|
|
128
|
+
if (major !== ORACLE_VERSION_MAJOR) {
|
|
129
|
+
const hint =
|
|
130
|
+
major > ORACLE_VERSION_MAJOR
|
|
131
|
+
? 'The contract was compiled with a newer version of Aztec.nr than this aztec cli version supports. Upgrade your aztec cli version to a compatible version.'
|
|
132
|
+
: 'The contract was compiled with an older version of Aztec.nr than this aztec cli version supports. Recompile the contract with a compatible version of Aztec.nr.';
|
|
120
133
|
throw new Error(
|
|
121
|
-
`Incompatible
|
|
134
|
+
`Incompatible aztec cli version: ${hint} See https://docs.aztec.network/errors/8 (expected oracle major version ${ORACLE_VERSION_MAJOR}, got ${major})`,
|
|
122
135
|
);
|
|
123
136
|
}
|
|
137
|
+
this.contractOracleVersion = { major, minor };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Prefixed with "nonOracleFunction" as it is not used as an oracle handler.
|
|
141
|
+
nonOracleFunctionGetContractOracleVersion(): { major: number; minor: number } | undefined {
|
|
142
|
+
return this.contractOracleVersion;
|
|
124
143
|
}
|
|
125
144
|
|
|
126
145
|
// This is typically only invoked in private contexts, but it is convenient to also have it in top-level for testing
|
|
127
146
|
// setup.
|
|
128
|
-
|
|
147
|
+
getRandomField(): Fr {
|
|
129
148
|
return Fr.random();
|
|
130
149
|
}
|
|
131
150
|
|
|
132
151
|
// We instruct users to debug contracts via this oracle, so it makes sense that they'd expect it to also work in tests
|
|
133
|
-
|
|
152
|
+
log(level: number, message: string, fields: Fr[]): Promise<void> {
|
|
134
153
|
if (!LogLevels[level]) {
|
|
135
|
-
throw new Error(`Invalid
|
|
154
|
+
throw new Error(`Invalid log level: ${level}`);
|
|
136
155
|
}
|
|
137
156
|
const levelName = LogLevels[level];
|
|
138
157
|
|
|
139
158
|
this.logger[levelName](`${applyStringFormatting(message, fields)}`, { module: `${this.logger.module}:debug_log` });
|
|
159
|
+
return Promise.resolve();
|
|
140
160
|
}
|
|
141
161
|
|
|
142
|
-
|
|
162
|
+
getDefaultAddress(): AztecAddress {
|
|
143
163
|
return DEFAULT_ADDRESS;
|
|
144
164
|
}
|
|
145
165
|
|
|
146
|
-
async
|
|
166
|
+
async getNextBlockNumber(): Promise<BlockNumber> {
|
|
147
167
|
return BlockNumber((await this.getLastBlockNumber()) + 1);
|
|
148
168
|
}
|
|
149
169
|
|
|
150
|
-
|
|
170
|
+
getNextBlockTimestamp(): Promise<bigint> {
|
|
151
171
|
return Promise.resolve(this.nextBlockTimestamp);
|
|
152
172
|
}
|
|
153
173
|
|
|
154
|
-
async
|
|
174
|
+
async getLastBlockTimestamp() {
|
|
155
175
|
return (await this.stateMachine.node.getBlockHeader('latest'))!.globalVariables.timestamp;
|
|
156
176
|
}
|
|
157
177
|
|
|
158
|
-
async
|
|
159
|
-
const
|
|
178
|
+
async getLastTxEffects() {
|
|
179
|
+
const latestBlockNumber = await this.stateMachine.archiver.getBlockNumber();
|
|
180
|
+
const block = await this.stateMachine.archiver.getBlock(latestBlockNumber);
|
|
160
181
|
|
|
161
182
|
if (block!.body.txEffects.length != 1) {
|
|
162
183
|
// Note that calls like env.mine() will result in blocks with no transactions, hitting this
|
|
@@ -168,7 +189,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
168
189
|
return { txHash: txEffects.txHash, noteHashes: txEffects.noteHashes, nullifiers: txEffects.nullifiers };
|
|
169
190
|
}
|
|
170
191
|
|
|
171
|
-
async
|
|
192
|
+
async syncContractNonOracleMethod(contractAddress: AztecAddress, scope: AztecAddress, jobId: string) {
|
|
193
|
+
if (contractAddress.equals(DEFAULT_ADDRESS)) {
|
|
194
|
+
this.logger.debug(`Skipping sync in getPrivateEvents because the events correspond to the default address.`);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
199
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
200
|
+
contractAddress,
|
|
201
|
+
null,
|
|
202
|
+
async (call, execScopes) => {
|
|
203
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
204
|
+
},
|
|
205
|
+
blockHeader,
|
|
206
|
+
jobId,
|
|
207
|
+
[scope],
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async getPrivateEvents(selector: EventSelector, contractAddress: AztecAddress, scope: AztecAddress) {
|
|
172
212
|
return (
|
|
173
213
|
await this.privateEventStore.getPrivateEvents(selector, {
|
|
174
214
|
contractAddress,
|
|
@@ -179,7 +219,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
179
219
|
).map(e => e.packedEvent);
|
|
180
220
|
}
|
|
181
221
|
|
|
182
|
-
async
|
|
222
|
+
async advanceBlocksBy(blocks: number) {
|
|
183
223
|
this.logger.debug(`time traveling ${blocks} blocks`);
|
|
184
224
|
|
|
185
225
|
for (let i = 0; i < blocks; i++) {
|
|
@@ -187,12 +227,12 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
187
227
|
}
|
|
188
228
|
}
|
|
189
229
|
|
|
190
|
-
|
|
230
|
+
advanceTimestampBy(duration: UInt64) {
|
|
191
231
|
this.logger.debug(`time traveling ${duration} seconds`);
|
|
192
232
|
this.nextBlockTimestamp += duration;
|
|
193
233
|
}
|
|
194
234
|
|
|
195
|
-
async
|
|
235
|
+
async deploy(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
|
|
196
236
|
// Emit deployment nullifier
|
|
197
237
|
await this.mineBlock({
|
|
198
238
|
nullifiers: [
|
|
@@ -204,20 +244,20 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
204
244
|
});
|
|
205
245
|
|
|
206
246
|
if (!secret.equals(Fr.ZERO)) {
|
|
207
|
-
await this.
|
|
247
|
+
await this.addAccount(artifact, instance, secret);
|
|
208
248
|
} else {
|
|
209
249
|
await this.contractStore.addContractInstance(instance);
|
|
210
|
-
await this.contractStore.addContractArtifact(
|
|
250
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
211
251
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
212
252
|
}
|
|
213
253
|
}
|
|
214
254
|
|
|
215
|
-
async
|
|
255
|
+
async addAccount(artifact: ContractArtifact, instance: ContractInstanceWithAddress, secret: Fr) {
|
|
216
256
|
const partialAddress = await computePartialAddress(instance);
|
|
217
257
|
|
|
218
258
|
this.logger.debug(`Deployed ${artifact.name} at ${instance.address}`);
|
|
219
259
|
await this.contractStore.addContractInstance(instance);
|
|
220
|
-
await this.contractStore.addContractArtifact(
|
|
260
|
+
await this.contractStore.addContractArtifact(artifact);
|
|
221
261
|
|
|
222
262
|
const completeAddress = await this.keyStore.addAccount(secret, partialAddress);
|
|
223
263
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -227,7 +267,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
227
267
|
return completeAddress;
|
|
228
268
|
}
|
|
229
269
|
|
|
230
|
-
async
|
|
270
|
+
async createAccount(secret: Fr) {
|
|
231
271
|
// This is a foot gun !
|
|
232
272
|
const completeAddress = await this.keyStore.addAccount(secret, secret);
|
|
233
273
|
await this.accountStore.setAccount(completeAddress.address, completeAddress);
|
|
@@ -237,7 +277,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
237
277
|
return completeAddress;
|
|
238
278
|
}
|
|
239
279
|
|
|
240
|
-
async
|
|
280
|
+
async addAuthWitness(address: AztecAddress, messageHash: Fr) {
|
|
241
281
|
const account = await this.accountStore.getAccount(address);
|
|
242
282
|
const privateKey = await this.keyStore.getMasterSecretKey(account.publicKeys.masterIncomingViewingPublicKey);
|
|
243
283
|
|
|
@@ -250,7 +290,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
250
290
|
}
|
|
251
291
|
|
|
252
292
|
async mineBlock(options: { nullifiers?: Fr[] } = {}) {
|
|
253
|
-
const blockNumber = await this.
|
|
293
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
254
294
|
|
|
255
295
|
const txEffect = TxEffect.empty();
|
|
256
296
|
txEffect.nullifiers = [getSingleTxBlockRequestHash(blockNumber), ...(options.nullifiers ?? [])];
|
|
@@ -274,13 +314,14 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
274
314
|
await this.stateMachine.handleL2Block(block);
|
|
275
315
|
}
|
|
276
316
|
|
|
277
|
-
async
|
|
317
|
+
async privateCallNewFlow(
|
|
278
318
|
from: AztecAddress,
|
|
279
319
|
targetContractAddress: AztecAddress = AztecAddress.zero(),
|
|
280
320
|
functionSelector: FunctionSelector = FunctionSelector.empty(),
|
|
281
321
|
args: Fr[],
|
|
282
322
|
argsHash: Fr = Fr.zero(),
|
|
283
323
|
isStaticCall: boolean = false,
|
|
324
|
+
jobId: string,
|
|
284
325
|
) {
|
|
285
326
|
this.logger.verbose(
|
|
286
327
|
`Executing external function ${await this.contractStore.getDebugFunctionName(targetContractAddress, functionSelector)}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
@@ -294,68 +335,79 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
294
335
|
throw new Error(message);
|
|
295
336
|
}
|
|
296
337
|
|
|
338
|
+
// When `from` is the zero address (e.g. when deploying a new account contract), we return an
|
|
339
|
+
// empty scope list which acts as deny-all: no notes are visible and no keys are accessible.
|
|
340
|
+
const effectiveScopes = from.isZero() ? [] : [from];
|
|
341
|
+
|
|
297
342
|
// Sync notes before executing private function to discover notes from previous transactions
|
|
298
|
-
const utilityExecutor = async (call: FunctionCall) => {
|
|
299
|
-
await this.executeUtilityCall(call);
|
|
343
|
+
const utilityExecutor = async (call: FunctionCall, execScopes: AztecAddress[]) => {
|
|
344
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
300
345
|
};
|
|
301
346
|
|
|
302
|
-
await this.
|
|
347
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
348
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
349
|
+
targetContractAddress,
|
|
350
|
+
functionSelector,
|
|
351
|
+
utilityExecutor,
|
|
352
|
+
blockHeader,
|
|
353
|
+
jobId,
|
|
354
|
+
effectiveScopes,
|
|
355
|
+
);
|
|
303
356
|
|
|
304
|
-
const blockNumber = await this.
|
|
357
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
305
358
|
|
|
306
359
|
const callContext = new CallContext(from, targetContractAddress, functionSelector, isStaticCall);
|
|
307
360
|
|
|
308
|
-
const gasLimits = new Gas(
|
|
309
|
-
const teardownGasLimits = new Gas(
|
|
361
|
+
const gasLimits = new Gas(MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT, MAX_PROCESSABLE_L2_GAS);
|
|
362
|
+
const teardownGasLimits = new Gas(FALLBACK_TEARDOWN_DA_GAS_LIMIT, FALLBACK_TEARDOWN_L2_GAS_LIMIT);
|
|
310
363
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
311
364
|
|
|
312
365
|
const txContext = new TxContext(this.chainId, this.version, gasSettings);
|
|
313
366
|
|
|
314
|
-
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
315
|
-
|
|
316
367
|
const protocolNullifier = await computeProtocolNullifier(getSingleTxBlockRequestHash(blockNumber));
|
|
317
368
|
const noteCache = new ExecutionNoteCache(protocolNullifier);
|
|
369
|
+
// In production, the account contract sets the min revertible counter before calling the app function.
|
|
370
|
+
// Since TXE bypasses the account contract, we simulate this by setting minRevertibleSideEffectCounter to 1,
|
|
371
|
+
// marking all side effects as revertible.
|
|
372
|
+
const minRevertibleSideEffectCounter = 1;
|
|
373
|
+
await noteCache.setMinRevertibleSideEffectCounter(minRevertibleSideEffectCounter);
|
|
318
374
|
const taggingIndexCache = new ExecutionTaggingIndexCache();
|
|
319
375
|
|
|
320
376
|
const simulator = new WASMSimulator();
|
|
321
377
|
|
|
322
|
-
const privateExecutionOracle = new PrivateExecutionOracle(
|
|
378
|
+
const privateExecutionOracle = new PrivateExecutionOracle({
|
|
323
379
|
argsHash,
|
|
324
380
|
txContext,
|
|
325
381
|
callContext,
|
|
326
|
-
|
|
327
|
-
blockHeader,
|
|
382
|
+
anchorBlockHeader: blockHeader,
|
|
328
383
|
utilityExecutor,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
[],
|
|
333
|
-
HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
384
|
+
authWitnesses: Array.from(this.authwits.values()),
|
|
385
|
+
capsules: [],
|
|
386
|
+
executionCache: HashedValuesCache.create([new HashedValues(args, argsHash)]),
|
|
334
387
|
noteCache,
|
|
335
388
|
taggingIndexCache,
|
|
336
|
-
this.contractStore,
|
|
337
|
-
this.noteStore,
|
|
338
|
-
this.keyStore,
|
|
339
|
-
this.addressStore,
|
|
340
|
-
this.stateMachine.node,
|
|
341
|
-
this.
|
|
342
|
-
this.
|
|
343
|
-
this.
|
|
344
|
-
this.
|
|
345
|
-
this.
|
|
346
|
-
this.
|
|
347
|
-
|
|
348
|
-
0,
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
* contract would perform, including setting senderForTags.
|
|
355
|
-
*/
|
|
356
|
-
from,
|
|
389
|
+
contractStore: this.contractStore,
|
|
390
|
+
noteStore: this.noteStore,
|
|
391
|
+
keyStore: this.keyStore,
|
|
392
|
+
addressStore: this.addressStore,
|
|
393
|
+
aztecNode: this.stateMachine.node,
|
|
394
|
+
senderTaggingStore: this.senderTaggingStore,
|
|
395
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
396
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
397
|
+
capsuleService: new CapsuleService(this.capsuleStore, effectiveScopes),
|
|
398
|
+
privateEventStore: this.privateEventStore,
|
|
399
|
+
contractSyncService: this.stateMachine.contractSyncService,
|
|
400
|
+
jobId,
|
|
401
|
+
totalPublicCalldataCount: 0,
|
|
402
|
+
sideEffectCounter: minRevertibleSideEffectCounter,
|
|
403
|
+
scopes: effectiveScopes,
|
|
404
|
+
// In TXE, the typical transaction entrypoint is skipped, so we need to simulate the actions that such a
|
|
405
|
+
// contract would perform, including setting senderForTags.
|
|
406
|
+
senderForTags: from,
|
|
357
407
|
simulator,
|
|
358
|
-
|
|
408
|
+
messageContextService: this.stateMachine.messageContextService,
|
|
409
|
+
l2TipsStore: this.stateMachine.node,
|
|
410
|
+
});
|
|
359
411
|
|
|
360
412
|
// 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.
|
|
361
413
|
let result: PrivateExecutionResult;
|
|
@@ -377,24 +429,27 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
377
429
|
);
|
|
378
430
|
const publicFunctionsCalldata = await Promise.all(
|
|
379
431
|
publicCallRequests.map(async r => {
|
|
380
|
-
const calldata = await privateExecutionOracle.
|
|
432
|
+
const calldata = await privateExecutionOracle.getHashPreimage(r.calldataHash);
|
|
381
433
|
return new HashedValues(calldata, r.calldataHash);
|
|
382
434
|
}),
|
|
383
435
|
);
|
|
384
436
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
result = new PrivateExecutionResult(executionResult, Fr.ZERO, publicFunctionsCalldata);
|
|
437
|
+
noteCache.finish();
|
|
438
|
+
const nonceGenerator = noteCache.getNonceGenerator();
|
|
439
|
+
result = new PrivateExecutionResult(executionResult, nonceGenerator, publicFunctionsCalldata);
|
|
389
440
|
} catch (err) {
|
|
390
441
|
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during private execution'));
|
|
391
442
|
}
|
|
392
443
|
|
|
393
|
-
// According to the protocol rules,
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
const
|
|
397
|
-
|
|
444
|
+
// According to the protocol rules, there must be at least one nullifier in the tx. The first nullifier is used as
|
|
445
|
+
// the nonce generator for the note hashes.
|
|
446
|
+
// We pass the non-zero minRevertibleSideEffectCounter to make sure the side effects are split correctly.
|
|
447
|
+
const { publicInputs } = await generateSimulatedProvingResult(
|
|
448
|
+
result,
|
|
449
|
+
(addr, sel) => this.contractStore.getDebugFunctionName(addr, sel),
|
|
450
|
+
this.stateMachine.node,
|
|
451
|
+
minRevertibleSideEffectCounter,
|
|
452
|
+
);
|
|
398
453
|
|
|
399
454
|
const globals = makeGlobalVariables();
|
|
400
455
|
globals.blockNumber = blockNumber;
|
|
@@ -405,7 +460,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
405
460
|
|
|
406
461
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
407
462
|
|
|
408
|
-
const
|
|
463
|
+
const bindings = this.logger.getBindings();
|
|
464
|
+
const contractsDB = new PublicContractsDB(
|
|
465
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
466
|
+
bindings,
|
|
467
|
+
);
|
|
409
468
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
410
469
|
const config = PublicSimulatorConfig.from({
|
|
411
470
|
skipFeeEnforcement: true,
|
|
@@ -418,8 +477,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
418
477
|
globals,
|
|
419
478
|
guardedMerkleTrees,
|
|
420
479
|
contractsDB,
|
|
421
|
-
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config),
|
|
480
|
+
new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings),
|
|
422
481
|
new TestDateProvider(),
|
|
482
|
+
undefined,
|
|
483
|
+
createLogger('simulator:public-processor', bindings),
|
|
423
484
|
);
|
|
424
485
|
|
|
425
486
|
const tx = await Tx.create({
|
|
@@ -482,7 +543,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
482
543
|
return executionResult.returnValues ?? [];
|
|
483
544
|
}
|
|
484
545
|
|
|
485
|
-
async
|
|
546
|
+
async publicCallNewFlow(
|
|
486
547
|
from: AztecAddress,
|
|
487
548
|
targetContractAddress: AztecAddress,
|
|
488
549
|
calldata: Fr[],
|
|
@@ -492,11 +553,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
492
553
|
`Executing public function ${await this.contractStore.getDebugFunctionName(targetContractAddress, FunctionSelector.fromField(calldata[0]))}@${targetContractAddress} isStaticCall=${isStaticCall}`,
|
|
493
554
|
);
|
|
494
555
|
|
|
495
|
-
const blockNumber = await this.
|
|
556
|
+
const blockNumber = await this.getNextBlockNumber();
|
|
496
557
|
|
|
497
|
-
const gasLimits = new Gas(
|
|
558
|
+
const gasLimits = new Gas(MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT, MAX_PROCESSABLE_L2_GAS);
|
|
498
559
|
|
|
499
|
-
const teardownGasLimits = new Gas(
|
|
560
|
+
const teardownGasLimits = new Gas(FALLBACK_TEARDOWN_DA_GAS_LIMIT, FALLBACK_TEARDOWN_L2_GAS_LIMIT);
|
|
500
561
|
|
|
501
562
|
const gasSettings = new GasSettings(gasLimits, teardownGasLimits, GasFees.empty(), GasFees.empty());
|
|
502
563
|
|
|
@@ -516,7 +577,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
516
577
|
|
|
517
578
|
const forkedWorldTrees = await this.stateMachine.synchronizer.nativeWorldStateService.fork();
|
|
518
579
|
|
|
519
|
-
const
|
|
580
|
+
const bindings2 = this.logger.getBindings();
|
|
581
|
+
const contractsDB = new PublicContractsDB(
|
|
582
|
+
new TXEPublicContractDataSource(blockNumber, this.contractStore),
|
|
583
|
+
bindings2,
|
|
584
|
+
);
|
|
520
585
|
const guardedMerkleTrees = new GuardedMerkleTreeOperations(forkedWorldTrees);
|
|
521
586
|
const config = PublicSimulatorConfig.from({
|
|
522
587
|
skipFeeEnforcement: true,
|
|
@@ -525,8 +590,16 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
525
590
|
collectStatistics: false,
|
|
526
591
|
collectCallMetadata: true,
|
|
527
592
|
});
|
|
528
|
-
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config);
|
|
529
|
-
const processor = new PublicProcessor(
|
|
593
|
+
const simulator = new CppPublicTxSimulator(guardedMerkleTrees, contractsDB, globals, config, bindings2);
|
|
594
|
+
const processor = new PublicProcessor(
|
|
595
|
+
globals,
|
|
596
|
+
guardedMerkleTrees,
|
|
597
|
+
contractsDB,
|
|
598
|
+
simulator,
|
|
599
|
+
new TestDateProvider(),
|
|
600
|
+
undefined,
|
|
601
|
+
createLogger('simulator:public-processor', bindings2),
|
|
602
|
+
);
|
|
530
603
|
|
|
531
604
|
// We're simulating a scenario in which private execution immediately enqueues a public call and halts. The private
|
|
532
605
|
// kernel init would in this case inject a nullifier with the transaction request hash as a non-revertible
|
|
@@ -557,7 +630,7 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
557
630
|
constantData,
|
|
558
631
|
/*gasUsed=*/ new Gas(0, 0),
|
|
559
632
|
/*feePayer=*/ AztecAddress.zero(),
|
|
560
|
-
/*
|
|
633
|
+
/*expirationTimestamp=*/ 0n,
|
|
561
634
|
inputsForPublic,
|
|
562
635
|
undefined,
|
|
563
636
|
);
|
|
@@ -625,10 +698,11 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
625
698
|
return returnValues ?? [];
|
|
626
699
|
}
|
|
627
700
|
|
|
628
|
-
async
|
|
701
|
+
async executeUtilityFunction(
|
|
629
702
|
targetContractAddress: AztecAddress,
|
|
630
703
|
functionSelector: FunctionSelector,
|
|
631
704
|
args: Fr[],
|
|
705
|
+
jobId: string,
|
|
632
706
|
) {
|
|
633
707
|
const artifact = await this.contractStore.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
634
708
|
if (!artifact) {
|
|
@@ -636,25 +710,33 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
636
710
|
}
|
|
637
711
|
|
|
638
712
|
// Sync notes before executing utility function to discover notes from previous transactions
|
|
639
|
-
await this.
|
|
640
|
-
|
|
641
|
-
});
|
|
642
|
-
|
|
643
|
-
const call = new FunctionCall(
|
|
644
|
-
artifact.name,
|
|
713
|
+
const blockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
714
|
+
await this.stateMachine.contractSyncService.ensureContractSynced(
|
|
645
715
|
targetContractAddress,
|
|
646
716
|
functionSelector,
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
717
|
+
async (call, execScopes) => {
|
|
718
|
+
await this.executeUtilityCall(call, execScopes, jobId);
|
|
719
|
+
},
|
|
720
|
+
blockHeader,
|
|
721
|
+
jobId,
|
|
722
|
+
await this.keyStore.getAccounts(),
|
|
652
723
|
);
|
|
653
724
|
|
|
654
|
-
|
|
725
|
+
const call = FunctionCall.from({
|
|
726
|
+
name: artifact.name,
|
|
727
|
+
to: targetContractAddress,
|
|
728
|
+
selector: functionSelector,
|
|
729
|
+
type: FunctionType.UTILITY,
|
|
730
|
+
hideMsgSender: false,
|
|
731
|
+
isStatic: false,
|
|
732
|
+
args,
|
|
733
|
+
returnTypes: [],
|
|
734
|
+
});
|
|
735
|
+
|
|
736
|
+
return this.executeUtilityCall(call, await this.keyStore.getAccounts(), jobId);
|
|
655
737
|
}
|
|
656
738
|
|
|
657
|
-
private async executeUtilityCall(call: FunctionCall): Promise<Fr[]> {
|
|
739
|
+
private async executeUtilityCall(call: FunctionCall, scopes: AztecAddress[], jobId: string): Promise<Fr[]> {
|
|
658
740
|
const entryPointArtifact = await this.contractStore.getFunctionArtifactWithDebugMetadata(call.to, call.selector);
|
|
659
741
|
if (entryPointArtifact.functionType !== FunctionType.UTILITY) {
|
|
660
742
|
throw new Error(`Cannot run ${entryPointArtifact.functionType} function as utility`);
|
|
@@ -667,23 +749,26 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
667
749
|
|
|
668
750
|
try {
|
|
669
751
|
const anchorBlockHeader = await this.stateMachine.anchorBlockStore.getBlockHeader();
|
|
670
|
-
const oracle = new UtilityExecutionOracle(
|
|
671
|
-
call.to,
|
|
672
|
-
[],
|
|
673
|
-
[],
|
|
752
|
+
const oracle = new UtilityExecutionOracle({
|
|
753
|
+
contractAddress: call.to,
|
|
754
|
+
authWitnesses: [],
|
|
755
|
+
capsules: [],
|
|
674
756
|
anchorBlockHeader,
|
|
675
|
-
this.contractStore,
|
|
676
|
-
this.noteStore,
|
|
677
|
-
this.keyStore,
|
|
678
|
-
this.addressStore,
|
|
679
|
-
this.stateMachine.node,
|
|
680
|
-
this.
|
|
681
|
-
this.
|
|
682
|
-
this.
|
|
683
|
-
this.
|
|
684
|
-
this.
|
|
685
|
-
|
|
686
|
-
|
|
757
|
+
contractStore: this.contractStore,
|
|
758
|
+
noteStore: this.noteStore,
|
|
759
|
+
keyStore: this.keyStore,
|
|
760
|
+
addressStore: this.addressStore,
|
|
761
|
+
aztecNode: this.stateMachine.node,
|
|
762
|
+
recipientTaggingStore: this.recipientTaggingStore,
|
|
763
|
+
senderAddressBookStore: this.senderAddressBookStore,
|
|
764
|
+
capsuleService: new CapsuleService(this.capsuleStore, scopes),
|
|
765
|
+
privateEventStore: this.privateEventStore,
|
|
766
|
+
messageContextService: this.stateMachine.messageContextService,
|
|
767
|
+
contractSyncService: this.contractSyncService,
|
|
768
|
+
l2TipsStore: this.stateMachine.node,
|
|
769
|
+
jobId,
|
|
770
|
+
scopes,
|
|
771
|
+
});
|
|
687
772
|
const acirExecutionResult = await new WASMSimulator()
|
|
688
773
|
.executeUserCircuit(toACVMWitness(0, call.args), entryPointArtifact, new Oracle(oracle).toACIRCallback())
|
|
689
774
|
.catch((err: Error) => {
|
|
@@ -699,10 +784,10 @@ export class TXEOracleTopLevelContext implements IMiscOracle, ITxeExecutionOracl
|
|
|
699
784
|
);
|
|
700
785
|
});
|
|
701
786
|
|
|
702
|
-
this.logger.verbose(`Utility
|
|
787
|
+
this.logger.verbose(`Utility execution for ${call.to}.${call.selector} completed`);
|
|
703
788
|
return witnessMapToFields(acirExecutionResult.returnWitness);
|
|
704
789
|
} catch (err) {
|
|
705
|
-
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility
|
|
790
|
+
throw createSimulationError(err instanceof Error ? err : new Error('Unknown error during utility execution'));
|
|
706
791
|
}
|
|
707
792
|
}
|
|
708
793
|
|