@aztec/txe 0.81.0 → 0.82.1-alpha-testnet.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bin/index.js +1 -0
- package/dest/node/txe_node.d.ts +3 -33
- package/dest/node/txe_node.d.ts.map +1 -1
- package/dest/node/txe_node.js +50 -55
- package/dest/oracle/txe_oracle.d.ts +9 -8
- package/dest/oracle/txe_oracle.d.ts.map +1 -1
- package/dest/oracle/txe_oracle.js +42 -55
- package/dest/txe_service/txe_service.d.ts +8 -6
- package/dest/txe_service/txe_service.d.ts.map +1 -1
- package/dest/txe_service/txe_service.js +31 -54
- package/dest/util/encoding.d.ts +2 -2
- package/dest/util/txe_public_contract_data_source.d.ts +1 -2
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +15 -37
- package/package.json +12 -12
- package/src/bin/index.ts +1 -0
- package/src/node/txe_node.ts +56 -76
- package/src/oracle/txe_oracle.ts +62 -67
- package/src/txe_service/txe_service.ts +32 -34
- package/src/util/txe_public_contract_data_source.ts +21 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/txe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.82.1-alpha-testnet.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": "./dest/index.js",
|
|
6
6
|
"bin": "./dest/bin/index.js",
|
|
@@ -59,17 +59,17 @@
|
|
|
59
59
|
]
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@aztec/accounts": "0.
|
|
63
|
-
"@aztec/aztec.js": "0.
|
|
64
|
-
"@aztec/constants": "0.
|
|
65
|
-
"@aztec/foundation": "0.
|
|
66
|
-
"@aztec/key-store": "0.
|
|
67
|
-
"@aztec/kv-store": "0.
|
|
68
|
-
"@aztec/protocol-contracts": "0.
|
|
69
|
-
"@aztec/pxe": "0.
|
|
70
|
-
"@aztec/simulator": "0.
|
|
71
|
-
"@aztec/stdlib": "0.
|
|
72
|
-
"@aztec/world-state": "0.
|
|
62
|
+
"@aztec/accounts": "0.82.1-alpha-testnet.1",
|
|
63
|
+
"@aztec/aztec.js": "0.82.1-alpha-testnet.1",
|
|
64
|
+
"@aztec/constants": "0.82.1-alpha-testnet.1",
|
|
65
|
+
"@aztec/foundation": "0.82.1-alpha-testnet.1",
|
|
66
|
+
"@aztec/key-store": "0.82.1-alpha-testnet.1",
|
|
67
|
+
"@aztec/kv-store": "0.82.1-alpha-testnet.1",
|
|
68
|
+
"@aztec/protocol-contracts": "0.82.1-alpha-testnet.1",
|
|
69
|
+
"@aztec/pxe": "0.82.1-alpha-testnet.1",
|
|
70
|
+
"@aztec/simulator": "0.82.1-alpha-testnet.1",
|
|
71
|
+
"@aztec/stdlib": "0.82.1-alpha-testnet.1",
|
|
72
|
+
"@aztec/world-state": "0.82.1-alpha-testnet.1",
|
|
73
73
|
"zod": "^3.23.8"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
package/src/bin/index.ts
CHANGED
package/src/node/txe_node.ts
CHANGED
|
@@ -57,7 +57,6 @@ export class TXENode implements AztecNode {
|
|
|
57
57
|
#logsByTags = new Map<string, TxScopedL2Log[]>();
|
|
58
58
|
#txEffectsByTxHash = new Map<string, InBlock<TxEffect>>();
|
|
59
59
|
#txReceiptsByTxHash = new Map<string, TxReceipt>();
|
|
60
|
-
#blockNumberToNullifiers = new Map<number, Fr[]>();
|
|
61
60
|
#noteIndex = 0;
|
|
62
61
|
|
|
63
62
|
#logger = createLogger('aztec:txe_node');
|
|
@@ -125,56 +124,10 @@ export class TXENode implements AztecNode {
|
|
|
125
124
|
undefined,
|
|
126
125
|
new L2BlockHash(blockHash.toBuffer()),
|
|
127
126
|
blockNumber,
|
|
128
|
-
undefined,
|
|
129
127
|
),
|
|
130
128
|
);
|
|
131
129
|
}
|
|
132
130
|
|
|
133
|
-
/**
|
|
134
|
-
* Returns the indexes of the given nullifiers in the nullifier tree,
|
|
135
|
-
* scoped to the block they were included in.
|
|
136
|
-
* @param blockNumber - The block number at which to get the data.
|
|
137
|
-
* @param nullifiers - The nullifiers to search for.
|
|
138
|
-
* @returns The block scoped indexes of the given nullifiers in the nullifier tree, or undefined if not found.
|
|
139
|
-
*/
|
|
140
|
-
async findNullifiersIndexesWithBlock(
|
|
141
|
-
blockNumber: L2BlockNumber,
|
|
142
|
-
nullifiers: Fr[],
|
|
143
|
-
): Promise<(InBlock<bigint> | undefined)[]> {
|
|
144
|
-
const parsedBlockNumber = blockNumber === 'latest' ? await this.getBlockNumber() : blockNumber;
|
|
145
|
-
|
|
146
|
-
const nullifiersInBlock: Fr[] = [];
|
|
147
|
-
for (const [key, val] of this.#blockNumberToNullifiers.entries()) {
|
|
148
|
-
if (key <= parsedBlockNumber) {
|
|
149
|
-
nullifiersInBlock.push(...val);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return nullifiers.map(nullifier => {
|
|
154
|
-
const possibleNullifierIndex = nullifiersInBlock.findIndex(nullifierInBlock =>
|
|
155
|
-
nullifierInBlock.equals(nullifier),
|
|
156
|
-
);
|
|
157
|
-
return possibleNullifierIndex === -1
|
|
158
|
-
? undefined
|
|
159
|
-
: {
|
|
160
|
-
l2BlockNumber: parsedBlockNumber,
|
|
161
|
-
l2BlockHash: new Fr(parsedBlockNumber).toString(),
|
|
162
|
-
data: BigInt(possibleNullifierIndex),
|
|
163
|
-
};
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Returns the indexes of the given nullifiers in the nullifier tree,
|
|
169
|
-
* scoped to the block they were included in.
|
|
170
|
-
* @param blockNumber - The block number at which to get the data.
|
|
171
|
-
* @param nullifiers - The nullifiers to search for.
|
|
172
|
-
* @returns The block scoped indexes of the given nullifiers in the nullifier tree, or undefined if not found.
|
|
173
|
-
*/
|
|
174
|
-
setNullifiersIndexesWithBlock(blockNumber: number, nullifiers: Fr[]) {
|
|
175
|
-
this.#blockNumberToNullifiers.set(blockNumber, nullifiers);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
131
|
/**
|
|
179
132
|
* Adds private logs to the txe node, given a block
|
|
180
133
|
* @param blockNumber - The block number at which to add the private logs.
|
|
@@ -235,13 +188,13 @@ export class TXENode implements AztecNode {
|
|
|
235
188
|
* @param blockNumber - The block number at which to get the data or 'latest' for latest data
|
|
236
189
|
* @param treeId - The tree to search in.
|
|
237
190
|
* @param leafValue - The values to search for
|
|
238
|
-
* @returns The
|
|
191
|
+
* @returns The indices of leaves and the block metadata of a block in which the leaf was inserted.
|
|
239
192
|
*/
|
|
240
193
|
async findLeavesIndexes(
|
|
241
194
|
blockNumber: L2BlockNumber,
|
|
242
195
|
treeId: MerkleTreeId,
|
|
243
196
|
leafValues: Fr[],
|
|
244
|
-
): Promise<(bigint | undefined)[]> {
|
|
197
|
+
): Promise<(InBlock<bigint> | undefined)[]> {
|
|
245
198
|
// Temporary workaround to be able to respond this query: the trees are currently stored in the TXE oracle, but we
|
|
246
199
|
// hold a reference to them.
|
|
247
200
|
// We should likely migrate this so that the trees are owned by the node.
|
|
@@ -252,10 +205,61 @@ export class TXENode implements AztecNode {
|
|
|
252
205
|
? this.baseFork
|
|
253
206
|
: this.nativeWorldStateService.getSnapshot(blockNumber);
|
|
254
207
|
|
|
255
|
-
|
|
208
|
+
const maybeIndices = await db.findLeafIndices(
|
|
256
209
|
treeId,
|
|
257
210
|
leafValues.map(x => x.toBuffer()),
|
|
258
211
|
);
|
|
212
|
+
|
|
213
|
+
// We filter out undefined values
|
|
214
|
+
const indices = maybeIndices.filter(x => x !== undefined) as bigint[];
|
|
215
|
+
|
|
216
|
+
// Now we find the block numbers for the indices
|
|
217
|
+
const blockNumbers = await db.getBlockNumbersForLeafIndices(treeId, indices);
|
|
218
|
+
|
|
219
|
+
// If any of the block numbers are undefined, we throw an error.
|
|
220
|
+
for (let i = 0; i < indices.length; i++) {
|
|
221
|
+
if (blockNumbers[i] === undefined) {
|
|
222
|
+
throw new Error(`Block number is undefined for leaf index ${indices[i]} in tree ${MerkleTreeId[treeId]}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
// Get unique block numbers in order to optimize num calls to getLeafValue function.
|
|
226
|
+
const uniqueBlockNumbers = [...new Set(blockNumbers.filter(x => x !== undefined))];
|
|
227
|
+
|
|
228
|
+
// Now we obtain the block hashes from the archive tree by calling await `committedDb.getLeafValue(treeId, index)`
|
|
229
|
+
// (note that block number corresponds to the leaf index in the archive tree).
|
|
230
|
+
const blockHashes = await Promise.all(
|
|
231
|
+
uniqueBlockNumbers.map(blockNumber => {
|
|
232
|
+
return db.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber!);
|
|
233
|
+
}),
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
// If any of the block hashes are undefined, we throw an error.
|
|
237
|
+
for (let i = 0; i < uniqueBlockNumbers.length; i++) {
|
|
238
|
+
if (blockHashes[i] === undefined) {
|
|
239
|
+
throw new Error(`Block hash is undefined for block number ${uniqueBlockNumbers[i]}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Create InBlock objects by combining indices, blockNumbers and blockHashes
|
|
244
|
+
return maybeIndices.map((index, i) => {
|
|
245
|
+
if (index === undefined) {
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
const blockNumber = blockNumbers[i];
|
|
249
|
+
if (blockNumber === undefined) {
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
const blockHashIndex = uniqueBlockNumbers.indexOf(blockNumber);
|
|
253
|
+
const blockHash = blockHashes[blockHashIndex]?.toString();
|
|
254
|
+
if (!blockHash) {
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
l2BlockNumber: Number(blockNumber),
|
|
259
|
+
l2BlockHash: blockHash,
|
|
260
|
+
data: index,
|
|
261
|
+
};
|
|
262
|
+
});
|
|
259
263
|
}
|
|
260
264
|
|
|
261
265
|
/**
|
|
@@ -384,8 +388,8 @@ export class TXENode implements AztecNode {
|
|
|
384
388
|
* "in range" slot, means that the slot doesn't exist and the value is 0. If the low leaf preimage corresponds to the exact slot, the current value
|
|
385
389
|
* is contained in the leaf preimage.
|
|
386
390
|
*/
|
|
387
|
-
|
|
388
|
-
throw new Error('TXE Node method
|
|
391
|
+
getPublicDataWitness(_blockNumber: L2BlockNumber, _leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
392
|
+
throw new Error('TXE Node method getPublicDataWitness not implemented');
|
|
389
393
|
}
|
|
390
394
|
|
|
391
395
|
/**
|
|
@@ -642,15 +646,6 @@ export class TXENode implements AztecNode {
|
|
|
642
646
|
throw new Error('TXE Node method getEncodedEnr not implemented');
|
|
643
647
|
}
|
|
644
648
|
|
|
645
|
-
/**
|
|
646
|
-
* Adds a contract class bypassing the registerer.
|
|
647
|
-
* TODO(#10007): Remove this method.
|
|
648
|
-
* @param contractClass - The class to register.
|
|
649
|
-
*/
|
|
650
|
-
addContractClass(_contractClass: ContractClassPublic): Promise<void> {
|
|
651
|
-
throw new Error('TXE Node method addContractClass not implemented');
|
|
652
|
-
}
|
|
653
|
-
|
|
654
649
|
/**
|
|
655
650
|
* Method to fetch the current base fees.
|
|
656
651
|
* @returns The current base fees.
|
|
@@ -669,21 +664,6 @@ export class TXENode implements AztecNode {
|
|
|
669
664
|
throw new Error('TXE Node method getPrivateLogs not implemented');
|
|
670
665
|
}
|
|
671
666
|
|
|
672
|
-
/**
|
|
673
|
-
* Find the block numbers of the given leaf indices in the given tree.
|
|
674
|
-
* @param blockNumber - The block number at which to get the data or 'latest' for latest data
|
|
675
|
-
* @param treeId - The tree to search in.
|
|
676
|
-
* @param leafIndices - The values to search for
|
|
677
|
-
* @returns The indexes of the given leaves in the given tree or undefined if not found.
|
|
678
|
-
*/
|
|
679
|
-
findBlockNumbersForIndexes(
|
|
680
|
-
_blockNumber: L2BlockNumber,
|
|
681
|
-
_treeId: MerkleTreeId,
|
|
682
|
-
_leafIndices: bigint[],
|
|
683
|
-
): Promise<(bigint | undefined)[]> {
|
|
684
|
-
throw new Error('TXE Node method findBlockNumbersForIndexes not implemented');
|
|
685
|
-
}
|
|
686
|
-
|
|
687
667
|
/**
|
|
688
668
|
* Returns the information about the server's node. Includes current Node version, compatible Noir version,
|
|
689
669
|
* L1 chain identifier, protocol version, and L1 address of the rollup contract.
|
package/src/oracle/txe_oracle.ts
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP,
|
|
9
9
|
PRIVATE_CONTEXT_INPUTS_LENGTH,
|
|
10
10
|
type PUBLIC_DATA_TREE_HEIGHT,
|
|
11
|
-
PUBLIC_DISPATCH_SELECTOR,
|
|
12
11
|
} from '@aztec/constants';
|
|
13
12
|
import { padArrayEnd } from '@aztec/foundation/collection';
|
|
14
13
|
import { Aes128, Schnorr, poseidon2Hash } from '@aztec/foundation/crypto';
|
|
@@ -20,7 +19,6 @@ import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
|
20
19
|
import type { ProtocolContract } from '@aztec/protocol-contracts';
|
|
21
20
|
import {
|
|
22
21
|
AddressDataProvider,
|
|
23
|
-
AuthWitnessDataProvider,
|
|
24
22
|
CapsuleDataProvider,
|
|
25
23
|
ContractDataProvider,
|
|
26
24
|
NoteDataProvider,
|
|
@@ -73,7 +71,7 @@ import {
|
|
|
73
71
|
siloNullifier,
|
|
74
72
|
} from '@aztec/stdlib/hash';
|
|
75
73
|
import type { MerkleTreeReadOperations, MerkleTreeWriteOperations } from '@aztec/stdlib/interfaces/server';
|
|
76
|
-
import { type KeyValidationRequest, PrivateContextInputs } from '@aztec/stdlib/kernel';
|
|
74
|
+
import { type KeyValidationRequest, PrivateContextInputs, PublicCallRequest } from '@aztec/stdlib/kernel';
|
|
77
75
|
import { deriveKeys } from '@aztec/stdlib/keys';
|
|
78
76
|
import {
|
|
79
77
|
ContractClassLog,
|
|
@@ -99,7 +97,14 @@ import {
|
|
|
99
97
|
type PublicDataTreeLeafPreimage,
|
|
100
98
|
PublicDataWitness,
|
|
101
99
|
} from '@aztec/stdlib/trees';
|
|
102
|
-
import {
|
|
100
|
+
import {
|
|
101
|
+
BlockHeader,
|
|
102
|
+
CallContext,
|
|
103
|
+
GlobalVariables,
|
|
104
|
+
PublicCallRequestWithCalldata,
|
|
105
|
+
TxEffect,
|
|
106
|
+
TxHash,
|
|
107
|
+
} from '@aztec/stdlib/tx';
|
|
103
108
|
import { ForkCheckpoint, NativeWorldStateService } from '@aztec/world-state/native';
|
|
104
109
|
|
|
105
110
|
import { TXENode } from '../node/txe_node.js';
|
|
@@ -136,6 +141,8 @@ export class TXE implements TypedOracle {
|
|
|
136
141
|
|
|
137
142
|
private noteCache: ExecutionNoteCache;
|
|
138
143
|
|
|
144
|
+
private authwits: Map<string, AuthWitness> = new Map();
|
|
145
|
+
|
|
139
146
|
private constructor(
|
|
140
147
|
private logger: Logger,
|
|
141
148
|
private keyStore: KeyStore,
|
|
@@ -145,7 +152,6 @@ export class TXE implements TypedOracle {
|
|
|
145
152
|
private syncDataProvider: SyncDataProvider,
|
|
146
153
|
private taggingDataProvider: TaggingDataProvider,
|
|
147
154
|
private addressDataProvider: AddressDataProvider,
|
|
148
|
-
private authWitnessDataProvider: AuthWitnessDataProvider,
|
|
149
155
|
private accountDataProvider: TXEAccountDataProvider,
|
|
150
156
|
private executionCache: HashedValuesCache,
|
|
151
157
|
private contractAddress: AztecAddress,
|
|
@@ -168,7 +174,6 @@ export class TXE implements TypedOracle {
|
|
|
168
174
|
this.syncDataProvider,
|
|
169
175
|
this.taggingDataProvider,
|
|
170
176
|
this.addressDataProvider,
|
|
171
|
-
this.authWitnessDataProvider,
|
|
172
177
|
this.logger,
|
|
173
178
|
);
|
|
174
179
|
}
|
|
@@ -179,7 +184,6 @@ export class TXE implements TypedOracle {
|
|
|
179
184
|
const baseFork = await nativeWorldStateService.fork();
|
|
180
185
|
|
|
181
186
|
const addressDataProvider = new AddressDataProvider(store);
|
|
182
|
-
const authWitnessDataProvider = new AuthWitnessDataProvider(store);
|
|
183
187
|
const contractDataProvider = new ContractDataProvider(store);
|
|
184
188
|
const noteDataProvider = await NoteDataProvider.create(store);
|
|
185
189
|
const syncDataProvider = new SyncDataProvider(store);
|
|
@@ -204,7 +208,6 @@ export class TXE implements TypedOracle {
|
|
|
204
208
|
syncDataProvider,
|
|
205
209
|
taggingDataProvider,
|
|
206
210
|
addressDataProvider,
|
|
207
|
-
authWitnessDataProvider,
|
|
208
211
|
accountDataProvider,
|
|
209
212
|
executionCache,
|
|
210
213
|
await AztecAddress.random(),
|
|
@@ -331,7 +334,7 @@ export class TXE implements TypedOracle {
|
|
|
331
334
|
const schnorr = new Schnorr();
|
|
332
335
|
const signature = await schnorr.constructSignature(messageHash.toBuffer(), privateKey);
|
|
333
336
|
const authWitness = new AuthWitness(messageHash, [...signature.toBuffer()]);
|
|
334
|
-
return this.
|
|
337
|
+
return this.authwits.set(authWitness.requestHash.toString(), authWitness);
|
|
335
338
|
}
|
|
336
339
|
|
|
337
340
|
async addPublicDataWrites(writes: PublicDataWrite[]) {
|
|
@@ -407,12 +410,16 @@ export class TXE implements TypedOracle {
|
|
|
407
410
|
return Fr.random();
|
|
408
411
|
}
|
|
409
412
|
|
|
410
|
-
storeInExecutionCache(values: Fr[]) {
|
|
411
|
-
return this.executionCache.store(values);
|
|
413
|
+
storeInExecutionCache(values: Fr[], hash: Fr) {
|
|
414
|
+
return this.executionCache.store(values, hash);
|
|
412
415
|
}
|
|
413
416
|
|
|
414
|
-
loadFromExecutionCache(
|
|
415
|
-
|
|
417
|
+
loadFromExecutionCache(hash: Fr) {
|
|
418
|
+
const preimage = this.executionCache.getPreimage(hash);
|
|
419
|
+
if (!preimage) {
|
|
420
|
+
throw new Error(`Preimage for hash ${hash.toString()} not found in cache`);
|
|
421
|
+
}
|
|
422
|
+
return Promise.resolve(preimage);
|
|
416
423
|
}
|
|
417
424
|
|
|
418
425
|
getKeyValidationRequest(pkMHash: Fr): Promise<KeyValidationRequest> {
|
|
@@ -471,7 +478,7 @@ export class TXE implements TypedOracle {
|
|
|
471
478
|
return new NullifierMembershipWitness(BigInt(index), leafPreimage as NullifierLeafPreimage, siblingPath);
|
|
472
479
|
}
|
|
473
480
|
|
|
474
|
-
async
|
|
481
|
+
async getPublicDataWitness(blockNumber: number, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
|
|
475
482
|
const snap = this.nativeWorldStateService.getSnapshot(blockNumber);
|
|
476
483
|
|
|
477
484
|
const lowLeafResult = await snap.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
|
|
@@ -544,7 +551,8 @@ export class TXE implements TypedOracle {
|
|
|
544
551
|
}
|
|
545
552
|
|
|
546
553
|
getAuthWitness(messageHash: Fr) {
|
|
547
|
-
|
|
554
|
+
const authwit = this.authwits.get(messageHash.toString());
|
|
555
|
+
return Promise.resolve(authwit?.witness);
|
|
548
556
|
}
|
|
549
557
|
|
|
550
558
|
async getNotes(
|
|
@@ -758,7 +766,6 @@ export class TXE implements TypedOracle {
|
|
|
758
766
|
}
|
|
759
767
|
|
|
760
768
|
await this.node.setTxEffect(blockNumber, new TxHash(new Fr(blockNumber)), txEffect);
|
|
761
|
-
this.node.setNullifiersIndexesWithBlock(blockNumber, txEffect.nullifiers);
|
|
762
769
|
this.node.addPrivateLogsByTags(this.blockNumber, this.privateLogs);
|
|
763
770
|
this.node.addPublicLogsByTags(this.blockNumber, this.publicLogs);
|
|
764
771
|
|
|
@@ -828,13 +835,15 @@ export class TXE implements TypedOracle {
|
|
|
828
835
|
this.setFunctionSelector(functionSelector);
|
|
829
836
|
|
|
830
837
|
const artifact = await this.contractDataProvider.getFunctionArtifact(targetContractAddress, functionSelector);
|
|
838
|
+
if (!artifact) {
|
|
839
|
+
throw new Error(`Artifact not found when calling private function. Contract address: ${targetContractAddress}.`);
|
|
840
|
+
}
|
|
831
841
|
|
|
832
|
-
const acir = artifact.bytecode;
|
|
833
842
|
const initialWitness = await this.getInitialWitness(artifact, argsHash, sideEffectCounter, isStaticCall);
|
|
834
843
|
const acvmCallback = new Oracle(this);
|
|
835
844
|
const timer = new Timer();
|
|
836
845
|
const acirExecutionResult = await this.simulationProvider
|
|
837
|
-
.executeUserCircuit(
|
|
846
|
+
.executeUserCircuit(initialWitness, artifact, acvmCallback)
|
|
838
847
|
.catch((err: Error) => {
|
|
839
848
|
err.message = resolveAssertionMessageFromError(err, artifact);
|
|
840
849
|
|
|
@@ -884,7 +893,7 @@ export class TXE implements TypedOracle {
|
|
|
884
893
|
|
|
885
894
|
const args = this.executionCache.getPreimage(argsHash);
|
|
886
895
|
|
|
887
|
-
if (args
|
|
896
|
+
if (args?.length !== argumentsSize) {
|
|
888
897
|
throw new Error('Invalid arguments size');
|
|
889
898
|
}
|
|
890
899
|
|
|
@@ -903,30 +912,18 @@ export class TXE implements TypedOracle {
|
|
|
903
912
|
}
|
|
904
913
|
|
|
905
914
|
public async getDebugFunctionName(address: AztecAddress, selector: FunctionSelector): Promise<string | undefined> {
|
|
906
|
-
|
|
907
|
-
if (!instance) {
|
|
908
|
-
return undefined;
|
|
909
|
-
}
|
|
910
|
-
const artifact = await this.contractDataProvider.getContractArtifact(instance!.currentContractClassId);
|
|
911
|
-
if (!artifact) {
|
|
912
|
-
return undefined;
|
|
913
|
-
}
|
|
914
|
-
const functionSelectorsAndNames = await Promise.all(
|
|
915
|
-
artifact.functions.map(async f => ({
|
|
916
|
-
name: f.name,
|
|
917
|
-
selector: await FunctionSelector.fromNameAndParameters(f.name, f.parameters),
|
|
918
|
-
})),
|
|
919
|
-
);
|
|
920
|
-
const functionSelectorAndName = functionSelectorsAndNames.find(f => f.selector.equals(selector));
|
|
921
|
-
if (!functionSelectorAndName) {
|
|
922
|
-
return undefined;
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
return `${artifact.name}:${functionSelectorAndName.name}`;
|
|
915
|
+
return await this.contractDataProvider.getDebugFunctionName(address, selector);
|
|
926
916
|
}
|
|
927
917
|
|
|
928
|
-
private async executePublicFunction(
|
|
929
|
-
|
|
918
|
+
private async executePublicFunction(
|
|
919
|
+
calldata: Fr[],
|
|
920
|
+
msgSender: AztecAddress,
|
|
921
|
+
contractAddress: AztecAddress,
|
|
922
|
+
isStaticCall: boolean,
|
|
923
|
+
isTeardown: boolean = false,
|
|
924
|
+
) {
|
|
925
|
+
const callRequest = await PublicCallRequest.fromCalldata(msgSender, contractAddress, isStaticCall, calldata);
|
|
926
|
+
const executionRequest = new PublicCallRequestWithCalldata(callRequest, calldata);
|
|
930
927
|
|
|
931
928
|
const db = this.baseFork;
|
|
932
929
|
|
|
@@ -953,7 +950,7 @@ export class TXE implements TypedOracle {
|
|
|
953
950
|
// When setting up a teardown call, we tell it that
|
|
954
951
|
// private execution used Gas(1, 1) so it can compute a tx fee.
|
|
955
952
|
const gasUsedByPrivate = isTeardown ? new Gas(1, 1) : Gas.empty();
|
|
956
|
-
const tx =
|
|
953
|
+
const tx = createTxForPublicCalls(
|
|
957
954
|
firstNullifier,
|
|
958
955
|
/*setupExecutionRequests=*/ [],
|
|
959
956
|
/*appExecutionRequests=*/ isTeardown ? [] : [executionRequest],
|
|
@@ -993,34 +990,34 @@ export class TXE implements TypedOracle {
|
|
|
993
990
|
return Promise.resolve(result);
|
|
994
991
|
}
|
|
995
992
|
|
|
996
|
-
async
|
|
993
|
+
async notifyEnqueuedPublicFunctionCall(
|
|
997
994
|
targetContractAddress: AztecAddress,
|
|
998
|
-
|
|
999
|
-
argsHash: Fr,
|
|
995
|
+
calldataHash: Fr,
|
|
1000
996
|
_sideEffectCounter: number,
|
|
1001
997
|
isStaticCall: boolean,
|
|
1002
998
|
isTeardown = false,
|
|
1003
|
-
): Promise<
|
|
999
|
+
): Promise<void> {
|
|
1004
1000
|
// Store and modify env
|
|
1005
1001
|
const currentContractAddress = this.contractAddress;
|
|
1006
1002
|
const currentMessageSender = this.msgSender;
|
|
1007
1003
|
const currentFunctionSelector = FunctionSelector.fromField(this.functionSelector.toField());
|
|
1004
|
+
const calldata = this.executionCache.getPreimage(calldataHash);
|
|
1005
|
+
if (!calldata) {
|
|
1006
|
+
throw new Error('Calldata for enqueued call not found in cache');
|
|
1007
|
+
}
|
|
1008
|
+
const functionSelector = FunctionSelector.fromField(calldata[0]);
|
|
1008
1009
|
this.setMsgSender(this.contractAddress);
|
|
1009
1010
|
this.setContractAddress(targetContractAddress);
|
|
1010
1011
|
this.setFunctionSelector(functionSelector);
|
|
1011
1012
|
|
|
1012
|
-
const
|
|
1013
|
+
const executionResult = await this.executePublicFunction(
|
|
1014
|
+
calldata,
|
|
1013
1015
|
/* msgSender */ currentContractAddress,
|
|
1014
1016
|
targetContractAddress,
|
|
1015
|
-
FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
|
|
1016
1017
|
isStaticCall,
|
|
1018
|
+
isTeardown,
|
|
1017
1019
|
);
|
|
1018
1020
|
|
|
1019
|
-
const args = [this.functionSelector.toField(), ...this.executionCache.getPreimage(argsHash)];
|
|
1020
|
-
const newArgsHash = await this.executionCache.store(args);
|
|
1021
|
-
|
|
1022
|
-
const executionResult = await this.executePublicFunction(args, callContext, isTeardown);
|
|
1023
|
-
|
|
1024
1021
|
// Poor man's revert handling
|
|
1025
1022
|
if (!executionResult.revertCode.isOK()) {
|
|
1026
1023
|
if (executionResult.revertReason && executionResult.revertReason instanceof SimulationError) {
|
|
@@ -1044,23 +1041,19 @@ export class TXE implements TypedOracle {
|
|
|
1044
1041
|
this.setContractAddress(currentContractAddress);
|
|
1045
1042
|
this.setMsgSender(currentMessageSender);
|
|
1046
1043
|
this.setFunctionSelector(currentFunctionSelector);
|
|
1047
|
-
|
|
1048
|
-
return newArgsHash;
|
|
1049
1044
|
}
|
|
1050
1045
|
|
|
1051
|
-
async
|
|
1046
|
+
async notifySetPublicTeardownFunctionCall(
|
|
1052
1047
|
targetContractAddress: AztecAddress,
|
|
1053
|
-
|
|
1054
|
-
argsHash: Fr,
|
|
1048
|
+
calldataHash: Fr,
|
|
1055
1049
|
sideEffectCounter: number,
|
|
1056
1050
|
isStaticCall: boolean,
|
|
1057
|
-
): Promise<
|
|
1051
|
+
): Promise<void> {
|
|
1058
1052
|
// Definitely not right, in that the teardown should always be last.
|
|
1059
1053
|
// But useful for executing flows.
|
|
1060
|
-
|
|
1054
|
+
await this.notifyEnqueuedPublicFunctionCall(
|
|
1061
1055
|
targetContractAddress,
|
|
1062
|
-
|
|
1063
|
-
argsHash,
|
|
1056
|
+
calldataHash,
|
|
1064
1057
|
sideEffectCounter,
|
|
1065
1058
|
isStaticCall,
|
|
1066
1059
|
/*isTeardown=*/ true,
|
|
@@ -1131,21 +1124,23 @@ export class TXE implements TypedOracle {
|
|
|
1131
1124
|
|
|
1132
1125
|
// AVM oracles
|
|
1133
1126
|
|
|
1134
|
-
async avmOpcodeCall(
|
|
1127
|
+
async avmOpcodeCall(
|
|
1128
|
+
targetContractAddress: AztecAddress,
|
|
1129
|
+
calldata: Fr[],
|
|
1130
|
+
isStaticCall: boolean,
|
|
1131
|
+
): Promise<PublicTxResult> {
|
|
1135
1132
|
// Store and modify env
|
|
1136
1133
|
const currentContractAddress = this.contractAddress;
|
|
1137
1134
|
const currentMessageSender = this.msgSender;
|
|
1138
1135
|
this.setMsgSender(this.contractAddress);
|
|
1139
1136
|
this.setContractAddress(targetContractAddress);
|
|
1140
1137
|
|
|
1141
|
-
const
|
|
1138
|
+
const executionResult = await this.executePublicFunction(
|
|
1139
|
+
calldata,
|
|
1142
1140
|
/* msgSender */ currentContractAddress,
|
|
1143
1141
|
targetContractAddress,
|
|
1144
|
-
FunctionSelector.fromField(new Fr(PUBLIC_DISPATCH_SELECTOR)),
|
|
1145
1142
|
isStaticCall,
|
|
1146
1143
|
);
|
|
1147
|
-
|
|
1148
|
-
const executionResult = await this.executePublicFunction(args, callContext);
|
|
1149
1144
|
// Save return/revert data for later.
|
|
1150
1145
|
this.nestedCallReturndata = executionResult.processedPhases[0]!.returnValues[0].values!;
|
|
1151
1146
|
this.nestedCallSuccess = executionResult.revertCode.isOK();
|