@aztec/txe 0.0.1-commit.b655e406 → 0.0.1-commit.c7c42ec
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/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -2
- package/dest/oracle/interfaces.d.ts +9 -6
- package/dest/oracle/interfaces.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.d.ts +5 -5
- package/dest/oracle/txe_oracle_public_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_public_context.js +4 -6
- package/dest/oracle/txe_oracle_top_level_context.d.ts +20 -12
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +95 -63
- package/dest/rpc_translator.d.ts +17 -8
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +69 -20
- package/dest/state_machine/archiver.d.ts +31 -14
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +105 -17
- package/dest/state_machine/dummy_p2p_client.d.ts +4 -2
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +6 -1
- package/dest/state_machine/global_variable_builder.d.ts +5 -3
- package/dest/state_machine/global_variable_builder.d.ts.map +1 -1
- package/dest/state_machine/global_variable_builder.js +12 -0
- package/dest/state_machine/index.d.ts +5 -5
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +14 -20
- package/dest/state_machine/mock_epoch_cache.d.ts +6 -5
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +8 -7
- package/dest/state_machine/synchronizer.d.ts +5 -4
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/state_machine/synchronizer.js +5 -4
- package/dest/txe_session.d.ts +19 -13
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +55 -41
- package/dest/util/encoding.d.ts +623 -24
- package/dest/util/encoding.d.ts.map +1 -1
- package/dest/util/encoding.js +1 -1
- package/dest/util/expected_failure_error.d.ts +1 -1
- package/dest/util/expected_failure_error.d.ts.map +1 -1
- package/dest/util/txe_account_store.d.ts +10 -0
- package/dest/util/txe_account_store.d.ts.map +1 -0
- package/dest/util/{txe_account_data_provider.js → txe_account_store.js} +1 -1
- package/dest/util/txe_contract_store.d.ts +12 -0
- package/dest/util/txe_contract_store.d.ts.map +1 -0
- package/dest/util/{txe_contract_data_provider.js → txe_contract_store.js} +3 -3
- package/dest/util/txe_public_contract_data_source.d.ts +7 -6
- package/dest/util/txe_public_contract_data_source.d.ts.map +1 -1
- package/dest/util/txe_public_contract_data_source.js +11 -11
- package/dest/utils/block_creation.d.ts +19 -4
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +24 -3
- package/dest/utils/tx_effect_creation.d.ts +4 -3
- package/dest/utils/tx_effect_creation.d.ts.map +1 -1
- package/dest/utils/tx_effect_creation.js +6 -6
- package/package.json +18 -17
- package/src/index.ts +15 -12
- package/src/oracle/interfaces.ts +8 -5
- package/src/oracle/txe_oracle_public_context.ts +6 -11
- package/src/oracle/txe_oracle_top_level_context.ts +126 -88
- package/src/rpc_translator.ts +90 -20
- package/src/state_machine/archiver.ts +141 -29
- package/src/state_machine/dummy_p2p_client.ts +9 -2
- package/src/state_machine/global_variable_builder.ts +21 -3
- package/src/state_machine/index.ts +19 -18
- package/src/state_machine/mock_epoch_cache.ts +12 -11
- package/src/state_machine/synchronizer.ts +8 -7
- package/src/txe_session.ts +113 -72
- package/src/util/encoding.ts +1 -1
- package/src/util/{txe_account_data_provider.ts → txe_account_store.ts} +1 -1
- package/src/util/{txe_contract_data_provider.ts → txe_contract_store.ts} +3 -3
- package/src/util/txe_public_contract_data_source.ts +13 -12
- package/src/utils/block_creation.ts +35 -3
- package/src/utils/tx_effect_creation.ts +8 -7
- 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/src/rpc_translator.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import type { ContractInstanceWithAddress } from '@aztec/aztec.js/contracts';
|
|
2
2
|
import { Fr, Point } from '@aztec/aztec.js/fields';
|
|
3
3
|
import { MAX_NOTE_HASHES_PER_TX, MAX_NULLIFIERS_PER_TX } from '@aztec/constants';
|
|
4
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
4
5
|
import {
|
|
5
6
|
type IMiscOracle,
|
|
6
7
|
type IPrivateExecutionOracle,
|
|
7
8
|
type IUtilityExecutionOracle,
|
|
8
9
|
packAsRetrievedNote,
|
|
9
10
|
} from '@aztec/pxe/simulator';
|
|
10
|
-
import { type ContractArtifact, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
11
|
+
import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
11
12
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
12
13
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
13
14
|
|
|
@@ -29,6 +30,9 @@ import {
|
|
|
29
30
|
toSingle,
|
|
30
31
|
} from './util/encoding.js';
|
|
31
32
|
|
|
33
|
+
const MAX_EVENT_LEN = 12; // This is MAX_MESSAGE_CONTENT_LEN - PRIVATE_EVENT_RESERVED_FIELDS
|
|
34
|
+
const MAX_PRIVATE_EVENTS_PER_TXE_QUERY = 5;
|
|
35
|
+
|
|
32
36
|
export class UnavailableOracleError extends Error {
|
|
33
37
|
constructor(oracleName: string) {
|
|
34
38
|
super(`${oracleName} oracles not available with the current handler`);
|
|
@@ -117,7 +121,7 @@ export class RPCTranslator {
|
|
|
117
121
|
: undefined;
|
|
118
122
|
|
|
119
123
|
const anchorBlockNumber = fromSingle(foreignAnchorBlockNumberIsSome).toBool()
|
|
120
|
-
? fromSingle(foreignAnchorBlockNumberValue).toNumber()
|
|
124
|
+
? BlockNumber(fromSingle(foreignAnchorBlockNumberValue).toNumber())
|
|
121
125
|
: undefined;
|
|
122
126
|
|
|
123
127
|
const privateContextInputs = await this.stateHandler.enterPrivateState(contractAddress, anchorBlockNumber);
|
|
@@ -155,6 +159,12 @@ export class RPCTranslator {
|
|
|
155
159
|
|
|
156
160
|
// TXE-specific oracles
|
|
157
161
|
|
|
162
|
+
txeGetDefaultAddress() {
|
|
163
|
+
const defaultAddress = this.handlerAsTxe().txeGetDefaultAddress();
|
|
164
|
+
|
|
165
|
+
return toForeignCallResult([toSingle(defaultAddress)]);
|
|
166
|
+
}
|
|
167
|
+
|
|
158
168
|
async txeGetNextBlockNumber() {
|
|
159
169
|
const nextBlockNumber = await this.handlerAsTxe().txeGetNextBlockNumber();
|
|
160
170
|
|
|
@@ -266,12 +276,40 @@ export class RPCTranslator {
|
|
|
266
276
|
]);
|
|
267
277
|
}
|
|
268
278
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
foreignHash: ForeignCallSingle,
|
|
279
|
+
async txeGetPrivateEvents(
|
|
280
|
+
foreignSelector: ForeignCallSingle,
|
|
281
|
+
foreignContractAddress: ForeignCallSingle,
|
|
282
|
+
foreignScope: ForeignCallSingle,
|
|
274
283
|
) {
|
|
284
|
+
const selector = EventSelector.fromField(fromSingle(foreignSelector));
|
|
285
|
+
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
286
|
+
const scope = addressFromSingle(foreignScope);
|
|
287
|
+
|
|
288
|
+
const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
|
|
289
|
+
|
|
290
|
+
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
291
|
+
throw new Error(`Array of length ${events.length} larger than maxLen ${MAX_PRIVATE_EVENTS_PER_TXE_QUERY}`);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (events.some(e => e.length > MAX_EVENT_LEN)) {
|
|
295
|
+
throw new Error(`Some private event has length larger than maxLen ${MAX_EVENT_LEN}`);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// This is a workaround as Noir does not currently let us return nested structs with arrays. We instead return a raw
|
|
299
|
+
// multidimensional array in get_private_events_oracle and create the BoundedVecs here.
|
|
300
|
+
const rawArrayStorage = events
|
|
301
|
+
.map(e => e.concat(Array(MAX_EVENT_LEN - e.length).fill(new Fr(0))))
|
|
302
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(Array(MAX_EVENT_LEN).fill(new Fr(0))))
|
|
303
|
+
.flat();
|
|
304
|
+
const eventLengths = events
|
|
305
|
+
.map(e => new Fr(e.length))
|
|
306
|
+
.concat(Array(MAX_PRIVATE_EVENTS_PER_TXE_QUERY - events.length).fill(new Fr(0)));
|
|
307
|
+
const queryLength = new Fr(events.length);
|
|
308
|
+
|
|
309
|
+
return toForeignCallResult([toArray(rawArrayStorage), toArray(eventLengths), toSingle(queryLength)]);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
privateStoreInExecutionCache(foreignValues: ForeignCallArray, foreignHash: ForeignCallSingle) {
|
|
275
313
|
const values = fromArray(foreignValues);
|
|
276
314
|
const hash = fromSingle(foreignHash);
|
|
277
315
|
|
|
@@ -315,7 +353,7 @@ export class RPCTranslator {
|
|
|
315
353
|
) {
|
|
316
354
|
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
317
355
|
const startStorageSlot = fromSingle(foreignStartStorageSlot);
|
|
318
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
356
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
319
357
|
const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
|
|
320
358
|
|
|
321
359
|
const values = await this.handlerAsUtility().utilityStorageRead(
|
|
@@ -329,7 +367,7 @@ export class RPCTranslator {
|
|
|
329
367
|
}
|
|
330
368
|
|
|
331
369
|
async utilityGetPublicDataWitness(foreignBlockNumber: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
|
|
332
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
370
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
333
371
|
const leafSlot = fromSingle(foreignLeafSlot);
|
|
334
372
|
|
|
335
373
|
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockNumber, leafSlot);
|
|
@@ -341,6 +379,8 @@ export class RPCTranslator {
|
|
|
341
379
|
}
|
|
342
380
|
|
|
343
381
|
async utilityGetNotes(
|
|
382
|
+
foreignOwnerIsSome: ForeignCallSingle,
|
|
383
|
+
foreignOwnerValue: ForeignCallSingle,
|
|
344
384
|
foreignStorageSlot: ForeignCallSingle,
|
|
345
385
|
foreignNumSelects: ForeignCallSingle,
|
|
346
386
|
foreignSelectByIndexes: ForeignCallArray,
|
|
@@ -358,6 +398,10 @@ export class RPCTranslator {
|
|
|
358
398
|
foreignMaxNotes: ForeignCallSingle,
|
|
359
399
|
foreignPackedRetrievedNoteLength: ForeignCallSingle,
|
|
360
400
|
) {
|
|
401
|
+
// Parse Option<AztecAddress>: ownerIsSome is 0 for None, 1 for Some
|
|
402
|
+
const owner = fromSingle(foreignOwnerIsSome).toBool()
|
|
403
|
+
? AztecAddress.fromField(fromSingle(foreignOwnerValue))
|
|
404
|
+
: undefined;
|
|
361
405
|
const storageSlot = fromSingle(foreignStorageSlot);
|
|
362
406
|
const numSelects = fromSingle(foreignNumSelects).toNumber();
|
|
363
407
|
const selectByIndexes = fromArray(foreignSelectByIndexes).map(fr => fr.toNumber());
|
|
@@ -376,6 +420,7 @@ export class RPCTranslator {
|
|
|
376
420
|
const packedRetrievedNoteLength = fromSingle(foreignPackedRetrievedNoteLength).toNumber();
|
|
377
421
|
|
|
378
422
|
const noteDatas = await this.handlerAsUtility().utilityGetNotes(
|
|
423
|
+
owner,
|
|
379
424
|
storageSlot,
|
|
380
425
|
numSelects,
|
|
381
426
|
selectByIndexes,
|
|
@@ -392,7 +437,17 @@ export class RPCTranslator {
|
|
|
392
437
|
status,
|
|
393
438
|
);
|
|
394
439
|
|
|
395
|
-
const returnDataAsArrayOfArrays = noteDatas.map(
|
|
440
|
+
const returnDataAsArrayOfArrays = noteDatas.map(noteData =>
|
|
441
|
+
packAsRetrievedNote({
|
|
442
|
+
contractAddress: noteData.contractAddress,
|
|
443
|
+
owner: noteData.owner,
|
|
444
|
+
randomness: noteData.randomness,
|
|
445
|
+
storageSlot: noteData.storageSlot,
|
|
446
|
+
noteNonce: noteData.noteNonce,
|
|
447
|
+
index: noteData.index,
|
|
448
|
+
note: noteData.note,
|
|
449
|
+
}),
|
|
450
|
+
);
|
|
396
451
|
|
|
397
452
|
// Now we convert each sub-array to an array of ForeignCallSingles
|
|
398
453
|
const returnDataAsArrayOfForeignCallSingleArrays = returnDataAsArrayOfArrays.map(subArray =>
|
|
@@ -410,19 +465,31 @@ export class RPCTranslator {
|
|
|
410
465
|
}
|
|
411
466
|
|
|
412
467
|
privateNotifyCreatedNote(
|
|
468
|
+
foreignOwner: ForeignCallSingle,
|
|
413
469
|
foreignStorageSlot: ForeignCallSingle,
|
|
470
|
+
foreignRandomness: ForeignCallSingle,
|
|
414
471
|
foreignNoteTypeId: ForeignCallSingle,
|
|
415
472
|
foreignNote: ForeignCallArray,
|
|
416
473
|
foreignNoteHash: ForeignCallSingle,
|
|
417
474
|
foreignCounter: ForeignCallSingle,
|
|
418
475
|
) {
|
|
476
|
+
const owner = addressFromSingle(foreignOwner);
|
|
419
477
|
const storageSlot = fromSingle(foreignStorageSlot);
|
|
478
|
+
const randomness = fromSingle(foreignRandomness);
|
|
420
479
|
const noteTypeId = NoteSelector.fromField(fromSingle(foreignNoteTypeId));
|
|
421
480
|
const note = fromArray(foreignNote);
|
|
422
481
|
const noteHash = fromSingle(foreignNoteHash);
|
|
423
482
|
const counter = fromSingle(foreignCounter).toNumber();
|
|
424
483
|
|
|
425
|
-
this.handlerAsPrivate().privateNotifyCreatedNote(
|
|
484
|
+
this.handlerAsPrivate().privateNotifyCreatedNote(
|
|
485
|
+
owner,
|
|
486
|
+
storageSlot,
|
|
487
|
+
randomness,
|
|
488
|
+
noteTypeId,
|
|
489
|
+
note,
|
|
490
|
+
noteHash,
|
|
491
|
+
counter,
|
|
492
|
+
);
|
|
426
493
|
|
|
427
494
|
return toForeignCallResult([]);
|
|
428
495
|
}
|
|
@@ -505,7 +572,7 @@ export class RPCTranslator {
|
|
|
505
572
|
foreignBlockNumber: ForeignCallSingle,
|
|
506
573
|
foreignNullifier: ForeignCallSingle,
|
|
507
574
|
) {
|
|
508
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
575
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
509
576
|
const nullifier = fromSingle(foreignNullifier);
|
|
510
577
|
|
|
511
578
|
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockNumber, nullifier);
|
|
@@ -549,14 +616,20 @@ export class RPCTranslator {
|
|
|
549
616
|
throw new Error('Enqueueing public calls is not supported in TestEnvironment::private_context');
|
|
550
617
|
}
|
|
551
618
|
|
|
552
|
-
async
|
|
553
|
-
const
|
|
619
|
+
public async privateIsSideEffectCounterRevertible(foreignSideEffectCounter: ForeignCallSingle) {
|
|
620
|
+
const sideEffectCounter = fromSingle(foreignSideEffectCounter).toNumber();
|
|
621
|
+
const isRevertible = await this.handlerAsPrivate().privateIsSideEffectCounterRevertible(sideEffectCounter);
|
|
622
|
+
return toForeignCallResult([toSingle(new Fr(isRevertible))]);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
utilityGetUtilityContext() {
|
|
626
|
+
const context = this.handlerAsUtility().utilityGetUtilityContext();
|
|
554
627
|
|
|
555
628
|
return toForeignCallResult(context.toNoirRepresentation());
|
|
556
629
|
}
|
|
557
630
|
|
|
558
631
|
async utilityGetBlockHeader(foreignBlockNumber: ForeignCallSingle) {
|
|
559
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
632
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
560
633
|
|
|
561
634
|
const header = await this.handlerAsUtility().utilityGetBlockHeader(blockNumber);
|
|
562
635
|
|
|
@@ -571,7 +644,7 @@ export class RPCTranslator {
|
|
|
571
644
|
foreignTreeId: ForeignCallSingle,
|
|
572
645
|
foreignLeafValue: ForeignCallSingle,
|
|
573
646
|
) {
|
|
574
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
647
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
575
648
|
const treeId = fromSingle(foreignTreeId).toNumber();
|
|
576
649
|
const leafValue = fromSingle(foreignLeafValue);
|
|
577
650
|
|
|
@@ -589,7 +662,7 @@ export class RPCTranslator {
|
|
|
589
662
|
foreignBlockNumber: ForeignCallSingle,
|
|
590
663
|
foreignNullifier: ForeignCallSingle,
|
|
591
664
|
) {
|
|
592
|
-
const blockNumber = fromSingle(foreignBlockNumber).toNumber();
|
|
665
|
+
const blockNumber = BlockNumber(fromSingle(foreignBlockNumber).toNumber());
|
|
593
666
|
const nullifier = fromSingle(foreignNullifier);
|
|
594
667
|
|
|
595
668
|
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockNumber, nullifier);
|
|
@@ -921,7 +994,6 @@ export class RPCTranslator {
|
|
|
921
994
|
foreignFrom: ForeignCallSingle,
|
|
922
995
|
foreignTargetContractAddress: ForeignCallSingle,
|
|
923
996
|
foreignFunctionSelector: ForeignCallSingle,
|
|
924
|
-
_foreignArgsLength: ForeignCallSingle,
|
|
925
997
|
foreignArgs: ForeignCallArray,
|
|
926
998
|
foreignArgsHash: ForeignCallSingle,
|
|
927
999
|
foreignIsStaticCall: ForeignCallSingle,
|
|
@@ -948,7 +1020,6 @@ export class RPCTranslator {
|
|
|
948
1020
|
async txeSimulateUtilityFunction(
|
|
949
1021
|
foreignTargetContractAddress: ForeignCallSingle,
|
|
950
1022
|
foreignFunctionSelector: ForeignCallSingle,
|
|
951
|
-
_foreignArgsLength: ForeignCallSingle,
|
|
952
1023
|
foreignArgs: ForeignCallArray,
|
|
953
1024
|
) {
|
|
954
1025
|
const targetContractAddress = addressFromSingle(foreignTargetContractAddress);
|
|
@@ -967,7 +1038,6 @@ export class RPCTranslator {
|
|
|
967
1038
|
async txePublicCallNewFlow(
|
|
968
1039
|
foreignFrom: ForeignCallSingle,
|
|
969
1040
|
foreignAddress: ForeignCallSingle,
|
|
970
|
-
_foreignLength: ForeignCallSingle,
|
|
971
1041
|
foreignCalldata: ForeignCallArray,
|
|
972
1042
|
foreignIsStaticCall: ForeignCallSingle,
|
|
973
1043
|
) {
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import { ArchiverStoreHelper, KVArchiverDataStore
|
|
1
|
+
import { ArchiverStoreHelper, KVArchiverDataStore } from '@aztec/archiver';
|
|
2
2
|
import { GENESIS_ARCHIVE_ROOT } from '@aztec/constants';
|
|
3
|
+
import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
5
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
-
import {
|
|
6
|
+
import { isDefined } from '@aztec/foundation/types';
|
|
5
7
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
6
8
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
7
|
-
import
|
|
9
|
+
import {
|
|
10
|
+
CommitteeAttestation,
|
|
11
|
+
L2Block,
|
|
12
|
+
type L2BlockId,
|
|
13
|
+
type L2BlockNew,
|
|
14
|
+
type L2BlockSource,
|
|
15
|
+
type L2Tips,
|
|
16
|
+
PublishedL2Block,
|
|
17
|
+
type ValidateBlockResult,
|
|
18
|
+
} from '@aztec/stdlib/block';
|
|
19
|
+
import { Checkpoint, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
8
20
|
import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
|
|
9
21
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
10
22
|
import type { BlockHeader } from '@aztec/stdlib/tx';
|
|
@@ -18,11 +30,28 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
|
|
|
18
30
|
super(new KVArchiverDataStore(db, 9999));
|
|
19
31
|
}
|
|
20
32
|
|
|
21
|
-
public
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
public async getBlock(number: BlockNumber): Promise<L2Block | undefined> {
|
|
34
|
+
if (number === 0) {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
const publishedBlocks = await this.getPublishedBlocks(number, 1);
|
|
38
|
+
if (publishedBlocks.length === 0) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
return publishedBlocks[0].block;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public async getBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<L2Block[]> {
|
|
45
|
+
const publishedBlocks = await this.getPublishedBlocks(from, limit, proven);
|
|
46
|
+
return publishedBlocks.map(x => x.block);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
public override async addCheckpoints(
|
|
50
|
+
checkpoints: PublishedCheckpoint[],
|
|
51
|
+
_result?: ValidateBlockResult,
|
|
52
|
+
): Promise<boolean> {
|
|
53
|
+
const allBlocks = checkpoints.flatMap(ch => ch.checkpoint.blocks);
|
|
54
|
+
const opResults = await Promise.all([this.store.addLogs(allBlocks), this.store.addCheckpoints(checkpoints)]);
|
|
26
55
|
|
|
27
56
|
return opResults.every(Boolean);
|
|
28
57
|
}
|
|
@@ -31,16 +60,16 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
|
|
|
31
60
|
* Gets the number of the latest L2 block processed by the block source implementation.
|
|
32
61
|
* @returns The number of the latest L2 block processed by the block source implementation.
|
|
33
62
|
*/
|
|
34
|
-
public getBlockNumber(): Promise<
|
|
35
|
-
return this.store.
|
|
63
|
+
public getBlockNumber(): Promise<BlockNumber> {
|
|
64
|
+
return this.store.getLatestBlockNumber();
|
|
36
65
|
}
|
|
37
66
|
|
|
38
67
|
/**
|
|
39
68
|
* Gets the number of the latest L2 block proven seen by the block source implementation.
|
|
40
69
|
* @returns The number of the latest L2 block proven seen by the block source implementation.
|
|
41
70
|
*/
|
|
42
|
-
public getProvenBlockNumber(): Promise<
|
|
43
|
-
return this.store.
|
|
71
|
+
public override getProvenBlockNumber(): Promise<BlockNumber> {
|
|
72
|
+
return this.store.getProvenBlockNumber();
|
|
44
73
|
}
|
|
45
74
|
|
|
46
75
|
/**
|
|
@@ -48,16 +77,55 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
|
|
|
48
77
|
* @param number - The block number to return (inclusive).
|
|
49
78
|
* @returns The requested L2 block.
|
|
50
79
|
*/
|
|
51
|
-
public
|
|
80
|
+
public async getPublishedBlock(number: number): Promise<PublishedL2Block | undefined> {
|
|
52
81
|
// If the number provided is -ve, then return the latest block.
|
|
53
82
|
if (number < 0) {
|
|
54
|
-
number = await this.store.
|
|
83
|
+
number = await this.store.getLatestBlockNumber();
|
|
55
84
|
}
|
|
56
85
|
if (number == 0) {
|
|
57
86
|
return undefined;
|
|
58
87
|
}
|
|
59
|
-
const
|
|
60
|
-
return
|
|
88
|
+
const publishedBlocks = await this.retrievePublishedBlocks(BlockNumber(number), 1);
|
|
89
|
+
return publishedBlocks.length === 0 ? undefined : publishedBlocks[0];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getPublishedBlocks(from: BlockNumber, limit: number, proven?: boolean): Promise<PublishedL2Block[]> {
|
|
93
|
+
return this.retrievePublishedBlocks(from, limit, proven);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private async retrievePublishedBlocks(
|
|
97
|
+
from: BlockNumber,
|
|
98
|
+
limit: number,
|
|
99
|
+
proven?: boolean,
|
|
100
|
+
): Promise<PublishedL2Block[]> {
|
|
101
|
+
const checkpoints = await this.store.getRangeOfCheckpoints(CheckpointNumber(from), limit);
|
|
102
|
+
const provenCheckpointNumber = await this.store.getProvenCheckpointNumber();
|
|
103
|
+
const blocks = (
|
|
104
|
+
await Promise.all(checkpoints.map(ch => this.store.getBlocksForCheckpoint(ch.checkpointNumber)))
|
|
105
|
+
).filter(isDefined);
|
|
106
|
+
|
|
107
|
+
const olbBlocks: PublishedL2Block[] = [];
|
|
108
|
+
for (let i = 0; i < checkpoints.length; i++) {
|
|
109
|
+
const blockForCheckpoint = blocks[i][0];
|
|
110
|
+
const checkpoint = checkpoints[i];
|
|
111
|
+
if (proven === true && checkpoint.checkpointNumber > provenCheckpointNumber) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const oldCheckpoint = new Checkpoint(
|
|
115
|
+
blockForCheckpoint.archive,
|
|
116
|
+
checkpoint.header,
|
|
117
|
+
[blockForCheckpoint],
|
|
118
|
+
checkpoint.checkpointNumber,
|
|
119
|
+
);
|
|
120
|
+
const oldBlock = L2Block.fromCheckpoint(oldCheckpoint);
|
|
121
|
+
const publishedBlock = new PublishedL2Block(
|
|
122
|
+
oldBlock,
|
|
123
|
+
checkpoint.l1,
|
|
124
|
+
checkpoint.attestations.map(x => CommitteeAttestation.fromBuffer(x)),
|
|
125
|
+
);
|
|
126
|
+
olbBlocks.push(publishedBlock);
|
|
127
|
+
}
|
|
128
|
+
return olbBlocks;
|
|
61
129
|
}
|
|
62
130
|
|
|
63
131
|
/**
|
|
@@ -65,8 +133,20 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
|
|
|
65
133
|
* @param number - The block number to return (inclusive).
|
|
66
134
|
* @returns The requested L2 block.
|
|
67
135
|
*/
|
|
68
|
-
public
|
|
69
|
-
return this.getPublishedBlock(number != 'latest' ? number : -1).then(
|
|
136
|
+
public getL2Block(number: BlockNumber | 'latest'): Promise<L2Block | undefined> {
|
|
137
|
+
return this.getPublishedBlock(number != 'latest' ? number : -1).then(b => b?.block);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Gets an L2 block (new format).
|
|
142
|
+
* @param number - The block number to return.
|
|
143
|
+
* @returns The requested L2 block.
|
|
144
|
+
*/
|
|
145
|
+
public getL2BlockNew(number: BlockNumber): Promise<L2BlockNew | undefined> {
|
|
146
|
+
if (number === 0) {
|
|
147
|
+
return Promise.resolve(undefined);
|
|
148
|
+
}
|
|
149
|
+
return this.store.getBlock(number);
|
|
70
150
|
}
|
|
71
151
|
|
|
72
152
|
/**
|
|
@@ -76,41 +156,66 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
|
|
|
76
156
|
*/
|
|
77
157
|
public async getBlockHeader(number: number | 'latest'): Promise<BlockHeader | undefined> {
|
|
78
158
|
if (number === 'latest') {
|
|
79
|
-
number = await this.store.
|
|
159
|
+
number = await this.store.getLatestBlockNumber();
|
|
80
160
|
}
|
|
81
161
|
if (number === 0) {
|
|
82
162
|
return undefined;
|
|
83
163
|
}
|
|
84
|
-
const headers = await this.store.getBlockHeaders(number, 1);
|
|
164
|
+
const headers = await this.store.getBlockHeaders(BlockNumber(number), 1);
|
|
85
165
|
return headers.length === 0 ? undefined : headers[0];
|
|
86
166
|
}
|
|
87
167
|
|
|
88
|
-
public
|
|
89
|
-
return this.getPublishedBlocks(from, limit).then(blocks => blocks.map(b => b.block));
|
|
168
|
+
public getBlockRange(from: number, limit: number, _proven?: boolean): Promise<L2Block[]> {
|
|
169
|
+
return this.getPublishedBlocks(BlockNumber(from), limit).then(blocks => blocks.map(b => b.block));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
public getPublishedCheckpoints(_from: CheckpointNumber, _limit: number): Promise<PublishedCheckpoint[]> {
|
|
173
|
+
throw new Error('TXE Archiver does not implement "getPublishedCheckpoints"');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
public getCheckpointByArchive(_archive: Fr): Promise<Checkpoint | undefined> {
|
|
177
|
+
throw new Error('TXE Archiver does not implement "getCheckpointByArchive"');
|
|
90
178
|
}
|
|
91
179
|
|
|
92
|
-
public getL2SlotNumber(): Promise<
|
|
180
|
+
public getL2SlotNumber(): Promise<SlotNumber | undefined> {
|
|
93
181
|
throw new Error('TXE Archiver does not implement "getL2SlotNumber"');
|
|
94
182
|
}
|
|
95
183
|
|
|
96
|
-
public getL2EpochNumber(): Promise<
|
|
184
|
+
public getL2EpochNumber(): Promise<EpochNumber> {
|
|
97
185
|
throw new Error('TXE Archiver does not implement "getL2EpochNumber"');
|
|
98
186
|
}
|
|
99
187
|
|
|
100
|
-
public
|
|
188
|
+
public getCheckpointsForEpoch(_epochNumber: EpochNumber): Promise<Checkpoint[]> {
|
|
189
|
+
throw new Error('TXE Archiver does not implement "getCheckpointsForEpoch"');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
public getBlocksForEpoch(_epochNumber: EpochNumber): Promise<L2Block[]> {
|
|
101
193
|
throw new Error('TXE Archiver does not implement "getBlocksForEpoch"');
|
|
102
194
|
}
|
|
103
195
|
|
|
104
|
-
public getBlockHeadersForEpoch(_epochNumber:
|
|
196
|
+
public getBlockHeadersForEpoch(_epochNumber: EpochNumber): Promise<BlockHeader[]> {
|
|
105
197
|
throw new Error('TXE Archiver does not implement "getBlockHeadersForEpoch"');
|
|
106
198
|
}
|
|
107
199
|
|
|
108
|
-
public isEpochComplete(_epochNumber:
|
|
200
|
+
public isEpochComplete(_epochNumber: EpochNumber): Promise<boolean> {
|
|
109
201
|
throw new Error('TXE Archiver does not implement "isEpochComplete"');
|
|
110
202
|
}
|
|
111
203
|
|
|
112
|
-
public getL2Tips(): Promise<L2Tips> {
|
|
113
|
-
|
|
204
|
+
public async getL2Tips(): Promise<L2Tips> {
|
|
205
|
+
// In TXE there is no possibility of reorgs and no blocks are ever getting proven so we just set 'latest', 'proven'
|
|
206
|
+
// and 'finalized' to the latest block.
|
|
207
|
+
const blockHeader = await this.getBlockHeader('latest');
|
|
208
|
+
if (!blockHeader) {
|
|
209
|
+
throw new Error('L2Tips requested from TXE Archiver but no block header found');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const number = blockHeader.globalVariables.blockNumber;
|
|
213
|
+
const hash = (await blockHeader.hash()).toString();
|
|
214
|
+
return {
|
|
215
|
+
latest: { number, hash } as L2BlockId,
|
|
216
|
+
proven: { number, hash } as L2BlockId,
|
|
217
|
+
finalized: { number, hash } as L2BlockId,
|
|
218
|
+
};
|
|
114
219
|
}
|
|
115
220
|
|
|
116
221
|
public getL1Constants(): Promise<L1RollupConstants> {
|
|
@@ -148,4 +253,11 @@ export class TXEArchiver extends ArchiverStoreHelper implements L2BlockSource {
|
|
|
148
253
|
public override getPendingChainValidationStatus(): Promise<ValidateBlockResult> {
|
|
149
254
|
return Promise.resolve({ valid: true });
|
|
150
255
|
}
|
|
256
|
+
|
|
257
|
+
getPublishedBlockByHash(_blockHash: Fr): Promise<PublishedL2Block | undefined> {
|
|
258
|
+
throw new Error('Method not implemented.');
|
|
259
|
+
}
|
|
260
|
+
getPublishedBlockByArchive(_archive: Fr): Promise<PublishedL2Block | undefined> {
|
|
261
|
+
throw new Error('Method not implemented.');
|
|
262
|
+
}
|
|
151
263
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import type {
|
|
2
3
|
AuthRequest,
|
|
3
4
|
ENR,
|
|
@@ -17,6 +18,10 @@ import type { BlockAttestation, BlockProposal } from '@aztec/stdlib/p2p';
|
|
|
17
18
|
import type { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
18
19
|
|
|
19
20
|
export class DummyP2P implements P2P {
|
|
21
|
+
public broadcastAttestations(_attestations: BlockAttestation[]): Promise<void> {
|
|
22
|
+
return Promise.resolve();
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
public validate(_txs: Tx[]): Promise<void> {
|
|
21
26
|
return Promise.resolve();
|
|
22
27
|
}
|
|
@@ -74,7 +79,9 @@ export class DummyP2P implements P2P {
|
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
public getTxStatus(_txHash: TxHash): Promise<'pending' | 'mined' | undefined> {
|
|
77
|
-
|
|
82
|
+
// In TXE there is no concept of transactions but we need to implement this because of tagging. We return 'mined'
|
|
83
|
+
// tx status for any tx hash.
|
|
84
|
+
return Promise.resolve('mined');
|
|
78
85
|
}
|
|
79
86
|
|
|
80
87
|
public iteratePendingTxs(): AsyncIterableIterator<Tx> {
|
|
@@ -113,7 +120,7 @@ export class DummyP2P implements P2P {
|
|
|
113
120
|
throw new Error('DummyP2P does not implement "getTxsByHash"');
|
|
114
121
|
}
|
|
115
122
|
|
|
116
|
-
public getAttestationsForSlot(_slot:
|
|
123
|
+
public getAttestationsForSlot(_slot: SlotNumber, _proposalId?: string): Promise<BlockAttestation[]> {
|
|
117
124
|
throw new Error('DummyP2P does not implement "getAttestationForSlot"');
|
|
118
125
|
}
|
|
119
126
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { BlockNumber, type SlotNumber } from '@aztec/foundation/branded-types';
|
|
1
2
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
2
3
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
3
4
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
4
5
|
import { makeGlobalVariables } from '@aztec/stdlib/testing';
|
|
5
|
-
import { type GlobalVariableBuilder, GlobalVariables } from '@aztec/stdlib/tx';
|
|
6
|
+
import { type CheckpointGlobalVariables, type GlobalVariableBuilder, GlobalVariables } from '@aztec/stdlib/tx';
|
|
6
7
|
|
|
7
8
|
export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
|
|
8
9
|
public getCurrentBaseFees(): Promise<GasFees> {
|
|
@@ -10,11 +11,28 @@ export class TXEGlobalVariablesBuilder implements GlobalVariableBuilder {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
public buildGlobalVariables(
|
|
13
|
-
_blockNumber:
|
|
14
|
+
_blockNumber: BlockNumber,
|
|
14
15
|
_coinbase: EthAddress,
|
|
15
16
|
_feeRecipient: AztecAddress,
|
|
16
|
-
_slotNumber?:
|
|
17
|
+
_slotNumber?: SlotNumber,
|
|
17
18
|
): Promise<GlobalVariables> {
|
|
18
19
|
return Promise.resolve(makeGlobalVariables());
|
|
19
20
|
}
|
|
21
|
+
|
|
22
|
+
public buildCheckpointGlobalVariables(
|
|
23
|
+
_coinbase: EthAddress,
|
|
24
|
+
_feeRecipient: AztecAddress,
|
|
25
|
+
_slotNumber: SlotNumber,
|
|
26
|
+
): Promise<CheckpointGlobalVariables> {
|
|
27
|
+
const vars = makeGlobalVariables();
|
|
28
|
+
return Promise.resolve({
|
|
29
|
+
chainId: vars.chainId,
|
|
30
|
+
version: vars.version,
|
|
31
|
+
slotNumber: vars.slotNumber,
|
|
32
|
+
timestamp: vars.timestamp,
|
|
33
|
+
coinbase: vars.coinbase,
|
|
34
|
+
feeRecipient: vars.feeRecipient,
|
|
35
|
+
gasFees: vars.gasFees,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
20
38
|
}
|
|
@@ -2,8 +2,9 @@ import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
|
|
|
2
2
|
import { TestCircuitVerifier } from '@aztec/bb-prover/test';
|
|
3
3
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
5
|
+
import { AnchorBlockStore } from '@aztec/pxe/server';
|
|
6
|
+
import { L2Block } from '@aztec/stdlib/block';
|
|
7
|
+
import { L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
7
8
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
8
9
|
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
9
10
|
|
|
@@ -21,13 +22,13 @@ export class TXEStateMachine {
|
|
|
21
22
|
public node: AztecNode,
|
|
22
23
|
public synchronizer: TXESynchronizer,
|
|
23
24
|
public archiver: TXEArchiver,
|
|
24
|
-
public
|
|
25
|
+
public anchorBlockStore: AnchorBlockStore,
|
|
25
26
|
) {}
|
|
26
27
|
|
|
27
28
|
public static async create(db: AztecAsyncKVStore) {
|
|
28
29
|
const archiver = new TXEArchiver(db);
|
|
29
30
|
const synchronizer = await TXESynchronizer.create();
|
|
30
|
-
const
|
|
31
|
+
const anchorBlockStore = new AnchorBlockStore(db);
|
|
31
32
|
|
|
32
33
|
const aztecNodeConfig = {} as AztecNodeConfig;
|
|
33
34
|
|
|
@@ -54,24 +55,24 @@ export class TXEStateMachine {
|
|
|
54
55
|
log,
|
|
55
56
|
);
|
|
56
57
|
|
|
57
|
-
return new this(node, synchronizer, archiver,
|
|
58
|
+
return new this(node, synchronizer, archiver, anchorBlockStore);
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
public async handleL2Block(block: L2Block) {
|
|
62
|
+
const checkpoint = block.toCheckpoint();
|
|
63
|
+
const publishedCheckpoint = new PublishedCheckpoint(
|
|
64
|
+
checkpoint,
|
|
65
|
+
new L1PublishedData(
|
|
66
|
+
BigInt(block.header.globalVariables.blockNumber),
|
|
67
|
+
block.header.globalVariables.timestamp,
|
|
68
|
+
block.header.globalVariables.blockNumber.toString(),
|
|
69
|
+
),
|
|
70
|
+
[],
|
|
71
|
+
);
|
|
61
72
|
await Promise.all([
|
|
62
|
-
this.synchronizer.handleL2Block(block),
|
|
63
|
-
this.archiver.
|
|
64
|
-
|
|
65
|
-
block,
|
|
66
|
-
l1: {
|
|
67
|
-
blockHash: block.header.globalVariables.blockNumber.toString(),
|
|
68
|
-
blockNumber: BigInt(block.header.globalVariables.blockNumber),
|
|
69
|
-
timestamp: block.header.globalVariables.timestamp,
|
|
70
|
-
},
|
|
71
|
-
attestations: [],
|
|
72
|
-
}),
|
|
73
|
-
]),
|
|
74
|
-
this.syncDataProvider.setHeader(block.getBlockHeader()),
|
|
73
|
+
this.synchronizer.handleL2Block(block.toL2Block()),
|
|
74
|
+
this.archiver.addCheckpoints([publishedCheckpoint], undefined),
|
|
75
|
+
this.anchorBlockStore.setHeader(block.getBlockHeader()),
|
|
75
76
|
]);
|
|
76
77
|
}
|
|
77
78
|
}
|