@aztec/txe 0.0.1-commit.d431d1c → 0.0.1-commit.dbf9cec
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/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +82 -50
- package/dest/oracle/interfaces.d.ts +6 -5
- 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 +6 -6
- package/dest/oracle/txe_oracle_top_level_context.d.ts +7 -8
- package/dest/oracle/txe_oracle_top_level_context.d.ts.map +1 -1
- package/dest/oracle/txe_oracle_top_level_context.js +105 -34
- package/dest/rpc_translator.d.ts +16 -10
- package/dest/rpc_translator.d.ts.map +1 -1
- package/dest/rpc_translator.js +74 -38
- package/dest/state_machine/archiver.d.ts +2 -2
- package/dest/state_machine/archiver.d.ts.map +1 -1
- package/dest/state_machine/archiver.js +7 -6
- package/dest/state_machine/dummy_p2p_client.d.ts +16 -12
- package/dest/state_machine/dummy_p2p_client.d.ts.map +1 -1
- package/dest/state_machine/dummy_p2p_client.js +28 -16
- package/dest/state_machine/index.d.ts +7 -7
- package/dest/state_machine/index.d.ts.map +1 -1
- package/dest/state_machine/index.js +31 -17
- package/dest/state_machine/mock_epoch_cache.d.ts +6 -2
- package/dest/state_machine/mock_epoch_cache.d.ts.map +1 -1
- package/dest/state_machine/mock_epoch_cache.js +6 -1
- package/dest/state_machine/synchronizer.d.ts +3 -3
- package/dest/state_machine/synchronizer.d.ts.map +1 -1
- package/dest/txe_session.d.ts +9 -6
- package/dest/txe_session.d.ts.map +1 -1
- package/dest/txe_session.js +83 -23
- 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 +5 -22
- package/dest/utils/block_creation.d.ts +5 -5
- package/dest/utils/block_creation.d.ts.map +1 -1
- package/dest/utils/block_creation.js +7 -5
- package/package.json +15 -15
- package/src/index.ts +83 -49
- package/src/oracle/interfaces.ts +8 -3
- package/src/oracle/txe_oracle_public_context.ts +8 -10
- package/src/oracle/txe_oracle_top_level_context.ts +134 -81
- package/src/rpc_translator.ts +78 -31
- package/src/state_machine/archiver.ts +6 -8
- package/src/state_machine/dummy_p2p_client.ts +40 -22
- package/src/state_machine/index.ts +49 -19
- package/src/state_machine/mock_epoch_cache.ts +7 -1
- package/src/state_machine/synchronizer.ts +2 -2
- package/src/txe_session.ts +98 -82
- package/src/util/txe_public_contract_data_source.ts +10 -36
- package/src/utils/block_creation.ts +8 -6
- 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
package/src/rpc_translator.ts
CHANGED
|
@@ -10,8 +10,7 @@ import {
|
|
|
10
10
|
} from '@aztec/pxe/simulator';
|
|
11
11
|
import { type ContractArtifact, EventSelector, FunctionSelector, NoteSelector } from '@aztec/stdlib/abi';
|
|
12
12
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
13
|
-
import {
|
|
14
|
-
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
13
|
+
import { BlockHash } from '@aztec/stdlib/block';
|
|
15
14
|
|
|
16
15
|
import type { IAvmExecutionOracle, ITxeExecutionOracle } from './oracle/interfaces.js';
|
|
17
16
|
import type { TXESessionStateHandler } from './txe_session.js';
|
|
@@ -286,6 +285,13 @@ export class RPCTranslator {
|
|
|
286
285
|
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
287
286
|
const scope = addressFromSingle(foreignScope);
|
|
288
287
|
|
|
288
|
+
// TODO(F-335): Avoid doing the following 2 calls here.
|
|
289
|
+
{
|
|
290
|
+
await this.handlerAsTxe().syncContractNonOracleMethod(contractAddress, scope, this.stateHandler.getCurrentJob());
|
|
291
|
+
// We cycle job to commit the stores after the contract sync.
|
|
292
|
+
await this.stateHandler.cycleJob();
|
|
293
|
+
}
|
|
294
|
+
|
|
289
295
|
const events = await this.handlerAsTxe().txeGetPrivateEvents(selector, contractAddress, scope);
|
|
290
296
|
|
|
291
297
|
if (events.length > MAX_PRIVATE_EVENTS_PER_TXE_QUERY) {
|
|
@@ -329,7 +335,7 @@ export class RPCTranslator {
|
|
|
329
335
|
|
|
330
336
|
// When the argument is a slice, noir automatically adds a length field to oracle call.
|
|
331
337
|
// When the argument is an array, we add the field length manually to the signature.
|
|
332
|
-
|
|
338
|
+
async utilityLog(
|
|
333
339
|
foreignLevel: ForeignCallSingle,
|
|
334
340
|
foreignMessage: ForeignCallArray,
|
|
335
341
|
_foreignLength: ForeignCallSingle,
|
|
@@ -341,7 +347,7 @@ export class RPCTranslator {
|
|
|
341
347
|
.join('');
|
|
342
348
|
const fields = fromArray(foreignFields);
|
|
343
349
|
|
|
344
|
-
this.handlerAsMisc().
|
|
350
|
+
await this.handlerAsMisc().utilityLog(level, message, fields);
|
|
345
351
|
|
|
346
352
|
return toForeignCallResult([]);
|
|
347
353
|
}
|
|
@@ -352,7 +358,7 @@ export class RPCTranslator {
|
|
|
352
358
|
foreignStartStorageSlot: ForeignCallSingle,
|
|
353
359
|
foreignNumberOfElements: ForeignCallSingle,
|
|
354
360
|
) {
|
|
355
|
-
const blockHash =
|
|
361
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
356
362
|
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
357
363
|
const startStorageSlot = fromSingle(foreignStartStorageSlot);
|
|
358
364
|
const numberOfElements = fromSingle(foreignNumberOfElements).toNumber();
|
|
@@ -368,7 +374,7 @@ export class RPCTranslator {
|
|
|
368
374
|
}
|
|
369
375
|
|
|
370
376
|
async utilityGetPublicDataWitness(foreignBlockHash: ForeignCallSingle, foreignLeafSlot: ForeignCallSingle) {
|
|
371
|
-
const blockHash =
|
|
377
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
372
378
|
const leafSlot = fromSingle(foreignLeafSlot);
|
|
373
379
|
|
|
374
380
|
const witness = await this.handlerAsUtility().utilityGetPublicDataWitness(blockHash, leafSlot);
|
|
@@ -513,6 +519,15 @@ export class RPCTranslator {
|
|
|
513
519
|
return toForeignCallResult([]);
|
|
514
520
|
}
|
|
515
521
|
|
|
522
|
+
async privateIsNullifierPending(foreignInnerNullifier: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
523
|
+
const innerNullifier = fromSingle(foreignInnerNullifier);
|
|
524
|
+
const contractAddress = addressFromSingle(foreignContractAddress);
|
|
525
|
+
|
|
526
|
+
const isPending = await this.handlerAsPrivate().privateIsNullifierPending(innerNullifier, contractAddress);
|
|
527
|
+
|
|
528
|
+
return toForeignCallResult([toSingle(new Fr(isPending))]);
|
|
529
|
+
}
|
|
530
|
+
|
|
516
531
|
async utilityCheckNullifierExists(foreignInnerNullifier: ForeignCallSingle) {
|
|
517
532
|
const innerNullifier = fromSingle(foreignInnerNullifier);
|
|
518
533
|
|
|
@@ -537,12 +552,23 @@ export class RPCTranslator {
|
|
|
537
552
|
);
|
|
538
553
|
}
|
|
539
554
|
|
|
540
|
-
async
|
|
555
|
+
async utilityTryGetPublicKeysAndPartialAddress(foreignAddress: ForeignCallSingle) {
|
|
541
556
|
const address = addressFromSingle(foreignAddress);
|
|
542
557
|
|
|
543
|
-
const
|
|
558
|
+
const result = await this.handlerAsUtility().utilityTryGetPublicKeysAndPartialAddress(address);
|
|
544
559
|
|
|
545
|
-
return
|
|
560
|
+
// We are going to return a Noir Option struct to represent the possibility of null values. Options are a struct
|
|
561
|
+
// with two fields: `some` (a boolean) and `value` (a field array in this case).
|
|
562
|
+
if (result === undefined) {
|
|
563
|
+
// No data was found so we set `some` to 0 and pad `value` with zeros get the correct return size.
|
|
564
|
+
return toForeignCallResult([toSingle(new Fr(0)), toArray(Array(13).fill(new Fr(0)))]);
|
|
565
|
+
} else {
|
|
566
|
+
// Data was found so we set `some` to 1 and return it along with `value`.
|
|
567
|
+
return toForeignCallResult([
|
|
568
|
+
toSingle(new Fr(1)),
|
|
569
|
+
toArray([...result.publicKeys.toFields(), result.partialAddress]),
|
|
570
|
+
]);
|
|
571
|
+
}
|
|
546
572
|
}
|
|
547
573
|
|
|
548
574
|
async utilityGetKeyValidationRequest(foreignPkMHash: ForeignCallSingle) {
|
|
@@ -566,7 +592,7 @@ export class RPCTranslator {
|
|
|
566
592
|
}
|
|
567
593
|
|
|
568
594
|
async utilityGetNullifierMembershipWitness(foreignBlockHash: ForeignCallSingle, foreignNullifier: ForeignCallSingle) {
|
|
569
|
-
const blockHash =
|
|
595
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
570
596
|
const nullifier = fromSingle(foreignNullifier);
|
|
571
597
|
|
|
572
598
|
const witness = await this.handlerAsUtility().utilityGetNullifierMembershipWitness(blockHash, nullifier);
|
|
@@ -633,30 +659,43 @@ export class RPCTranslator {
|
|
|
633
659
|
return toForeignCallResult(header.toFields().map(toSingle));
|
|
634
660
|
}
|
|
635
661
|
|
|
636
|
-
async
|
|
662
|
+
async utilityGetNoteHashMembershipWitness(
|
|
663
|
+
foreignAnchorBlockHash: ForeignCallSingle,
|
|
664
|
+
foreignNoteHash: ForeignCallSingle,
|
|
665
|
+
) {
|
|
666
|
+
const blockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
|
|
667
|
+
const noteHash = fromSingle(foreignNoteHash);
|
|
668
|
+
|
|
669
|
+
const witness = await this.handlerAsUtility().utilityGetNoteHashMembershipWitness(blockHash, noteHash);
|
|
670
|
+
|
|
671
|
+
if (!witness) {
|
|
672
|
+
throw new Error(`Note hash ${noteHash} not found in the note hash tree at block ${blockHash.toString()}.`);
|
|
673
|
+
}
|
|
674
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
async utilityGetBlockHashMembershipWitness(
|
|
678
|
+
foreignAnchorBlockHash: ForeignCallSingle,
|
|
637
679
|
foreignBlockHash: ForeignCallSingle,
|
|
638
|
-
foreignTreeId: ForeignCallSingle,
|
|
639
|
-
foreignLeafValue: ForeignCallSingle,
|
|
640
680
|
) {
|
|
641
|
-
const
|
|
642
|
-
const
|
|
643
|
-
const leafValue = fromSingle(foreignLeafValue);
|
|
681
|
+
const anchorBlockHash = new BlockHash(fromSingle(foreignAnchorBlockHash));
|
|
682
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
644
683
|
|
|
645
|
-
const witness = await this.handlerAsUtility().
|
|
684
|
+
const witness = await this.handlerAsUtility().utilityGetBlockHashMembershipWitness(anchorBlockHash, blockHash);
|
|
646
685
|
|
|
647
686
|
if (!witness) {
|
|
648
687
|
throw new Error(
|
|
649
|
-
`
|
|
688
|
+
`Block hash ${blockHash.toString()} not found in the archive tree at anchor block ${anchorBlockHash.toString()}.`,
|
|
650
689
|
);
|
|
651
690
|
}
|
|
652
|
-
return toForeignCallResult(
|
|
691
|
+
return toForeignCallResult(witness.toNoirRepresentation());
|
|
653
692
|
}
|
|
654
693
|
|
|
655
694
|
async utilityGetLowNullifierMembershipWitness(
|
|
656
695
|
foreignBlockHash: ForeignCallSingle,
|
|
657
696
|
foreignNullifier: ForeignCallSingle,
|
|
658
697
|
) {
|
|
659
|
-
const blockHash =
|
|
698
|
+
const blockHash = new BlockHash(fromSingle(foreignBlockHash));
|
|
660
699
|
const nullifier = fromSingle(foreignNullifier);
|
|
661
700
|
|
|
662
701
|
const witness = await this.handlerAsUtility().utilityGetLowNullifierMembershipWitness(blockHash, nullifier);
|
|
@@ -675,7 +714,7 @@ export class RPCTranslator {
|
|
|
675
714
|
return toForeignCallResult([]);
|
|
676
715
|
}
|
|
677
716
|
|
|
678
|
-
public async
|
|
717
|
+
public async utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
679
718
|
foreignContractAddress: ForeignCallSingle,
|
|
680
719
|
foreignNoteValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
681
720
|
foreignEventValidationRequestsArrayBaseSlot: ForeignCallSingle,
|
|
@@ -684,7 +723,7 @@ export class RPCTranslator {
|
|
|
684
723
|
const noteValidationRequestsArrayBaseSlot = fromSingle(foreignNoteValidationRequestsArrayBaseSlot);
|
|
685
724
|
const eventValidationRequestsArrayBaseSlot = fromSingle(foreignEventValidationRequestsArrayBaseSlot);
|
|
686
725
|
|
|
687
|
-
await this.handlerAsUtility().
|
|
726
|
+
await this.handlerAsUtility().utilityValidateAndStoreEnqueuedNotesAndEvents(
|
|
688
727
|
contractAddress,
|
|
689
728
|
noteValidationRequestsArrayBaseSlot,
|
|
690
729
|
eventValidationRequestsArrayBaseSlot,
|
|
@@ -817,15 +856,16 @@ export class RPCTranslator {
|
|
|
817
856
|
|
|
818
857
|
// AVM opcodes
|
|
819
858
|
|
|
820
|
-
|
|
859
|
+
avmOpcodeEmitPublicLog(_foreignMessage: ForeignCallArray) {
|
|
821
860
|
// TODO(#8811): Implement
|
|
822
861
|
return toForeignCallResult([]);
|
|
823
862
|
}
|
|
824
863
|
|
|
825
|
-
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle) {
|
|
864
|
+
async avmOpcodeStorageRead(foreignSlot: ForeignCallSingle, foreignContractAddress: ForeignCallSingle) {
|
|
826
865
|
const slot = fromSingle(foreignSlot);
|
|
866
|
+
const contractAddress = AztecAddress.fromField(fromSingle(foreignContractAddress));
|
|
827
867
|
|
|
828
|
-
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot)).value;
|
|
868
|
+
const value = (await this.handlerAsAvm().avmOpcodeStorageRead(slot, contractAddress)).value;
|
|
829
869
|
|
|
830
870
|
return toForeignCallResult([toSingle(new Fr(value))]);
|
|
831
871
|
}
|
|
@@ -897,11 +937,10 @@ export class RPCTranslator {
|
|
|
897
937
|
return toForeignCallResult([]);
|
|
898
938
|
}
|
|
899
939
|
|
|
900
|
-
async avmOpcodeNullifierExists(
|
|
901
|
-
const
|
|
902
|
-
const targetAddress = AztecAddress.fromField(fromSingle(foreignTargetAddress));
|
|
940
|
+
async avmOpcodeNullifierExists(foreignSiloedNullifier: ForeignCallSingle) {
|
|
941
|
+
const siloedNullifier = fromSingle(foreignSiloedNullifier);
|
|
903
942
|
|
|
904
|
-
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(
|
|
943
|
+
const exists = await this.handlerAsAvm().avmOpcodeNullifierExists(siloedNullifier);
|
|
905
944
|
|
|
906
945
|
return toForeignCallResult([toSingle(new Fr(exists))]);
|
|
907
946
|
}
|
|
@@ -1006,12 +1045,15 @@ export class RPCTranslator {
|
|
|
1006
1045
|
args,
|
|
1007
1046
|
argsHash,
|
|
1008
1047
|
isStaticCall,
|
|
1048
|
+
this.stateHandler.getCurrentJob(),
|
|
1009
1049
|
);
|
|
1010
1050
|
|
|
1051
|
+
// TODO(F-335): Avoid doing the following call here.
|
|
1052
|
+
await this.stateHandler.cycleJob();
|
|
1011
1053
|
return toForeignCallResult([toArray(returnValues)]);
|
|
1012
1054
|
}
|
|
1013
1055
|
|
|
1014
|
-
async
|
|
1056
|
+
async txeExecuteUtilityFunction(
|
|
1015
1057
|
foreignTargetContractAddress: ForeignCallSingle,
|
|
1016
1058
|
foreignFunctionSelector: ForeignCallSingle,
|
|
1017
1059
|
foreignArgs: ForeignCallArray,
|
|
@@ -1020,12 +1062,15 @@ export class RPCTranslator {
|
|
|
1020
1062
|
const functionSelector = FunctionSelector.fromField(fromSingle(foreignFunctionSelector));
|
|
1021
1063
|
const args = fromArray(foreignArgs);
|
|
1022
1064
|
|
|
1023
|
-
const returnValues = await this.handlerAsTxe().
|
|
1065
|
+
const returnValues = await this.handlerAsTxe().txeExecuteUtilityFunction(
|
|
1024
1066
|
targetContractAddress,
|
|
1025
1067
|
functionSelector,
|
|
1026
1068
|
args,
|
|
1069
|
+
this.stateHandler.getCurrentJob(),
|
|
1027
1070
|
);
|
|
1028
1071
|
|
|
1072
|
+
// TODO(F-335): Avoid doing the following call here.
|
|
1073
|
+
await this.stateHandler.cycleJob();
|
|
1029
1074
|
return toForeignCallResult([toArray(returnValues)]);
|
|
1030
1075
|
}
|
|
1031
1076
|
|
|
@@ -1042,6 +1087,8 @@ export class RPCTranslator {
|
|
|
1042
1087
|
|
|
1043
1088
|
const returnValues = await this.handlerAsTxe().txePublicCallNewFlow(from, address, calldata, isStaticCall);
|
|
1044
1089
|
|
|
1090
|
+
// TODO(F-335): Avoid doing the following call here.
|
|
1091
|
+
await this.stateHandler.cycleJob();
|
|
1045
1092
|
return toForeignCallResult([toArray(returnValues)]);
|
|
1046
1093
|
}
|
|
1047
1094
|
|
|
@@ -17,18 +17,14 @@ export class TXEArchiver extends ArchiverDataSourceBase {
|
|
|
17
17
|
private readonly updater = new ArchiverDataStoreUpdater(this.store);
|
|
18
18
|
|
|
19
19
|
constructor(db: AztecAsyncKVStore) {
|
|
20
|
-
const store = new KVArchiverDataStore(db, 9999);
|
|
20
|
+
const store = new KVArchiverDataStore(db, 9999, { epochDuration: 32 });
|
|
21
21
|
super(store);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
await this.updater.setNewCheckpointData(checkpoints, result);
|
|
27
|
-
return true;
|
|
24
|
+
public async addCheckpoints(checkpoints: PublishedCheckpoint[], result?: ValidateCheckpointResult): Promise<void> {
|
|
25
|
+
await this.updater.addCheckpoints(checkpoints, result);
|
|
28
26
|
}
|
|
29
27
|
|
|
30
|
-
// Abstract method implementations
|
|
31
|
-
|
|
32
28
|
public getRollupAddress(): Promise<EthAddress> {
|
|
33
29
|
throw new Error('TXE Archiver does not implement "getRollupAddress"');
|
|
34
30
|
}
|
|
@@ -63,7 +59,9 @@ export class TXEArchiver extends ArchiverDataSourceBase {
|
|
|
63
59
|
if (!checkpointedBlock) {
|
|
64
60
|
throw new Error(`L2Tips requested from TXE Archiver but no checkpointed block found for block number ${number}`);
|
|
65
61
|
}
|
|
66
|
-
|
|
62
|
+
// TXE uses 1-block-per-checkpoint for testing simplicity, so we can use block number as checkpoint number.
|
|
63
|
+
// This uses the deprecated fromBlockNumber method intentionally for the TXE testing environment.
|
|
64
|
+
const checkpoint = await this.store.getRangeOfCheckpoints(CheckpointNumber.fromBlockNumber(number), 1);
|
|
67
65
|
if (checkpoint.length === 0) {
|
|
68
66
|
throw new Error(`L2Tips requested from TXE Archiver but no checkpoint found for block number ${number}`);
|
|
69
67
|
}
|
|
@@ -6,6 +6,8 @@ import type {
|
|
|
6
6
|
P2PBlockReceivedCallback,
|
|
7
7
|
P2PCheckpointReceivedCallback,
|
|
8
8
|
P2PConfig,
|
|
9
|
+
P2PDuplicateAttestationCallback,
|
|
10
|
+
P2PDuplicateProposalCallback,
|
|
9
11
|
P2PSyncState,
|
|
10
12
|
PeerId,
|
|
11
13
|
ReqRespSubProtocol,
|
|
@@ -14,12 +16,12 @@ import type {
|
|
|
14
16
|
StatusMessage,
|
|
15
17
|
} from '@aztec/p2p';
|
|
16
18
|
import type { EthAddress, L2BlockStreamEvent, L2Tips } from '@aztec/stdlib/block';
|
|
17
|
-
import type { PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
18
|
-
import type { BlockProposal, CheckpointAttestation, CheckpointProposal } from '@aztec/stdlib/p2p';
|
|
19
|
-
import type { Tx, TxHash } from '@aztec/stdlib/tx';
|
|
19
|
+
import type { ITxProvider, PeerInfo } from '@aztec/stdlib/interfaces/server';
|
|
20
|
+
import type { BlockProposal, CheckpointAttestation, CheckpointProposal, TopicType } from '@aztec/stdlib/p2p';
|
|
21
|
+
import type { BlockHeader, Tx, TxHash } from '@aztec/stdlib/tx';
|
|
20
22
|
|
|
21
23
|
export class DummyP2P implements P2P {
|
|
22
|
-
public
|
|
24
|
+
public validateTxsReceivedInBlockProposal(_txs: Tx[]): Promise<void> {
|
|
23
25
|
return Promise.resolve();
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -39,6 +41,10 @@ export class DummyP2P implements P2P {
|
|
|
39
41
|
throw new Error('DummyP2P does not implement "getPeers"');
|
|
40
42
|
}
|
|
41
43
|
|
|
44
|
+
public getGossipMeshPeerCount(_topicType: TopicType): Promise<number> {
|
|
45
|
+
return Promise.resolve(0);
|
|
46
|
+
}
|
|
47
|
+
|
|
42
48
|
public broadcastProposal(_proposal: BlockProposal): Promise<void> {
|
|
43
49
|
throw new Error('DummyP2P does not implement "broadcastProposal"');
|
|
44
50
|
}
|
|
@@ -71,8 +77,8 @@ export class DummyP2P implements P2P {
|
|
|
71
77
|
throw new Error('DummyP2P does not implement "sendTx"');
|
|
72
78
|
}
|
|
73
79
|
|
|
74
|
-
public
|
|
75
|
-
throw new Error('DummyP2P does not implement "
|
|
80
|
+
public handleFailedExecution(_txHashes: TxHash[]): Promise<void> {
|
|
81
|
+
throw new Error('DummyP2P does not implement "handleFailedExecution"');
|
|
76
82
|
}
|
|
77
83
|
|
|
78
84
|
public getTxByHashFromPool(_txHash: TxHash): Promise<Tx | undefined> {
|
|
@@ -97,6 +103,10 @@ export class DummyP2P implements P2P {
|
|
|
97
103
|
throw new Error('DummyP2P does not implement "iteratePendingTxs"');
|
|
98
104
|
}
|
|
99
105
|
|
|
106
|
+
public iterateEligiblePendingTxs(): AsyncIterableIterator<Tx> {
|
|
107
|
+
throw new Error('DummyP2P does not implement "iterateEligiblePendingTxs"');
|
|
108
|
+
}
|
|
109
|
+
|
|
100
110
|
public getPendingTxCount(): Promise<number> {
|
|
101
111
|
throw new Error('DummyP2P does not implement "getPendingTxCount"');
|
|
102
112
|
}
|
|
@@ -125,6 +135,10 @@ export class DummyP2P implements P2P {
|
|
|
125
135
|
throw new Error('DummyP2P does not implement "isP2PClient"');
|
|
126
136
|
}
|
|
127
137
|
|
|
138
|
+
public getTxProvider(): ITxProvider {
|
|
139
|
+
throw new Error('DummyP2P does not implement "getTxProvider"');
|
|
140
|
+
}
|
|
141
|
+
|
|
128
142
|
public getTxsByHash(_txHashes: TxHash[]): Promise<Tx[]> {
|
|
129
143
|
throw new Error('DummyP2P does not implement "getTxsByHash"');
|
|
130
144
|
}
|
|
@@ -133,8 +147,8 @@ export class DummyP2P implements P2P {
|
|
|
133
147
|
throw new Error('DummyP2P does not implement "getCheckpointAttestationsForSlot"');
|
|
134
148
|
}
|
|
135
149
|
|
|
136
|
-
public
|
|
137
|
-
throw new Error('DummyP2P does not implement "
|
|
150
|
+
public addOwnCheckpointAttestations(_attestations: CheckpointAttestation[]): Promise<void> {
|
|
151
|
+
throw new Error('DummyP2P does not implement "addOwnCheckpointAttestations"');
|
|
138
152
|
}
|
|
139
153
|
|
|
140
154
|
public getL2BlockHash(_number: number): Promise<string | undefined> {
|
|
@@ -157,14 +171,6 @@ export class DummyP2P implements P2P {
|
|
|
157
171
|
throw new Error('DummyP2P does not implement "sync"');
|
|
158
172
|
}
|
|
159
173
|
|
|
160
|
-
public requestTxsByHash(_txHashes: TxHash[]): Promise<Tx[]> {
|
|
161
|
-
throw new Error('DummyP2P does not implement "requestTxsByHash"');
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
public getTxs(_filter: 'all' | 'pending' | 'mined'): Promise<Tx[]> {
|
|
165
|
-
throw new Error('DummyP2P does not implement "getTxs"');
|
|
166
|
-
}
|
|
167
|
-
|
|
168
174
|
public getTxsByHashFromPool(_txHashes: TxHash[]): Promise<(Tx | undefined)[]> {
|
|
169
175
|
throw new Error('DummyP2P does not implement "getTxsByHashFromPool"');
|
|
170
176
|
}
|
|
@@ -173,10 +179,6 @@ export class DummyP2P implements P2P {
|
|
|
173
179
|
throw new Error('DummyP2P does not implement "hasTxsInPool"');
|
|
174
180
|
}
|
|
175
181
|
|
|
176
|
-
public addTxsToPool(_txs: Tx[]): Promise<number> {
|
|
177
|
-
throw new Error('DummyP2P does not implement "addTxs"');
|
|
178
|
-
}
|
|
179
|
-
|
|
180
182
|
public getSyncedLatestBlockNum(): Promise<number> {
|
|
181
183
|
throw new Error('DummyP2P does not implement "getSyncedLatestBlockNum"');
|
|
182
184
|
}
|
|
@@ -189,8 +191,12 @@ export class DummyP2P implements P2P {
|
|
|
189
191
|
throw new Error('DummyP2P does not implement "getSyncedLatestSlot"');
|
|
190
192
|
}
|
|
191
193
|
|
|
192
|
-
|
|
193
|
-
throw new Error('DummyP2P does not implement "
|
|
194
|
+
protectTxs(_txHashes: TxHash[], _blockHeader: BlockHeader): Promise<TxHash[]> {
|
|
195
|
+
throw new Error('DummyP2P does not implement "protectTxs".');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
prepareForSlot(_slotNumber: SlotNumber): Promise<void> {
|
|
199
|
+
return Promise.resolve();
|
|
194
200
|
}
|
|
195
201
|
|
|
196
202
|
addReqRespSubProtocol(
|
|
@@ -206,4 +212,16 @@ export class DummyP2P implements P2P {
|
|
|
206
212
|
|
|
207
213
|
//This is no-op
|
|
208
214
|
public registerThisValidatorAddresses(_address: EthAddress[]): void {}
|
|
215
|
+
|
|
216
|
+
public registerDuplicateProposalCallback(_callback: P2PDuplicateProposalCallback): void {
|
|
217
|
+
throw new Error('DummyP2P does not implement "registerDuplicateProposalCallback"');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
public registerDuplicateAttestationCallback(_callback: P2PDuplicateAttestationCallback): void {
|
|
221
|
+
throw new Error('DummyP2P does not implement "registerDuplicateAttestationCallback"');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
public hasBlockProposalsForSlot(_slot: SlotNumber): Promise<boolean> {
|
|
225
|
+
throw new Error('DummyP2P does not implement "hasBlockProposalsForSlot"');
|
|
226
|
+
}
|
|
209
227
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
|
|
2
2
|
import { TestCircuitVerifier } from '@aztec/bb-prover/test';
|
|
3
|
+
import { CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
4
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
3
5
|
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
-
import type
|
|
5
|
-
import {
|
|
6
|
-
import { L2BlockNew } from '@aztec/stdlib/block';
|
|
6
|
+
import { type AnchorBlockStore, type ContractStore, ContractSyncService, type NoteStore } from '@aztec/pxe/server';
|
|
7
|
+
import { L2Block } from '@aztec/stdlib/block';
|
|
7
8
|
import { Checkpoint, L1PublishedData, PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
8
9
|
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
10
|
+
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
9
11
|
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
10
12
|
|
|
11
13
|
import { TXEArchiver } from './archiver.js';
|
|
@@ -23,13 +25,16 @@ export class TXEStateMachine {
|
|
|
23
25
|
public synchronizer: TXESynchronizer,
|
|
24
26
|
public archiver: TXEArchiver,
|
|
25
27
|
public anchorBlockStore: AnchorBlockStore,
|
|
28
|
+
public contractSyncService: ContractSyncService,
|
|
26
29
|
) {}
|
|
27
30
|
|
|
28
|
-
public static async create(
|
|
29
|
-
|
|
31
|
+
public static async create(
|
|
32
|
+
archiver: TXEArchiver,
|
|
33
|
+
anchorBlockStore: AnchorBlockStore,
|
|
34
|
+
contractStore: ContractStore,
|
|
35
|
+
noteStore: NoteStore,
|
|
36
|
+
) {
|
|
30
37
|
const synchronizer = await TXESynchronizer.create();
|
|
31
|
-
const anchorBlockStore = new AnchorBlockStore(db);
|
|
32
|
-
|
|
33
38
|
const aztecNodeConfig = {} as AztecNodeConfig;
|
|
34
39
|
|
|
35
40
|
const log = createLogger('txe_node');
|
|
@@ -45,6 +50,7 @@ export class TXEStateMachine {
|
|
|
45
50
|
undefined,
|
|
46
51
|
undefined,
|
|
47
52
|
undefined,
|
|
53
|
+
undefined,
|
|
48
54
|
VERSION,
|
|
49
55
|
CHAIN_ID,
|
|
50
56
|
new TXEGlobalVariablesBuilder(),
|
|
@@ -55,18 +61,39 @@ export class TXEStateMachine {
|
|
|
55
61
|
log,
|
|
56
62
|
);
|
|
57
63
|
|
|
58
|
-
|
|
64
|
+
const contractSyncService = new ContractSyncService(
|
|
65
|
+
node,
|
|
66
|
+
contractStore,
|
|
67
|
+
noteStore,
|
|
68
|
+
createLogger('txe:contract_sync'),
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
return new this(node, synchronizer, archiver, anchorBlockStore, contractSyncService);
|
|
59
72
|
}
|
|
60
73
|
|
|
61
|
-
public async handleL2Block(block:
|
|
62
|
-
// Create a checkpoint from the block
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
public async handleL2Block(block: L2Block) {
|
|
75
|
+
// Create a checkpoint from the block manually.
|
|
76
|
+
// TXE uses 1-block-per-checkpoint for testing simplicity, so we can use block number as checkpoint number.
|
|
77
|
+
// This uses the deprecated fromBlockNumber method intentionally for the TXE testing environment.
|
|
78
|
+
const checkpointNumber = CheckpointNumber.fromBlockNumber(block.number);
|
|
79
|
+
const checkpoint = new Checkpoint(
|
|
80
|
+
block.archive,
|
|
81
|
+
CheckpointHeader.from({
|
|
82
|
+
lastArchiveRoot: block.header.lastArchive.root,
|
|
83
|
+
inHash: Fr.ZERO,
|
|
84
|
+
blobsHash: Fr.ZERO,
|
|
85
|
+
blockHeadersHash: Fr.ZERO,
|
|
86
|
+
epochOutHash: Fr.ZERO,
|
|
87
|
+
slotNumber: block.header.globalVariables.slotNumber,
|
|
88
|
+
timestamp: block.header.globalVariables.timestamp,
|
|
89
|
+
coinbase: block.header.globalVariables.coinbase,
|
|
90
|
+
feeRecipient: block.header.globalVariables.feeRecipient,
|
|
91
|
+
gasFees: block.header.globalVariables.gasFees,
|
|
92
|
+
totalManaUsed: block.header.totalManaUsed,
|
|
93
|
+
}),
|
|
94
|
+
[block],
|
|
95
|
+
checkpointNumber,
|
|
96
|
+
);
|
|
70
97
|
|
|
71
98
|
const publishedCheckpoint = new PublishedCheckpoint(
|
|
72
99
|
checkpoint,
|
|
@@ -77,10 +104,13 @@ export class TXEStateMachine {
|
|
|
77
104
|
),
|
|
78
105
|
[],
|
|
79
106
|
);
|
|
107
|
+
// Wipe contract sync cache when anchor block changes (mirrors BlockSynchronizer behavior)
|
|
108
|
+
this.contractSyncService.wipe();
|
|
109
|
+
|
|
80
110
|
await Promise.all([
|
|
81
|
-
this.synchronizer.handleL2Block(block),
|
|
111
|
+
this.synchronizer.handleL2Block(block),
|
|
82
112
|
this.archiver.addCheckpoints([publishedCheckpoint], undefined),
|
|
83
|
-
this.anchorBlockStore.setHeader(block.header),
|
|
113
|
+
this.anchorBlockStore.setHeader(block.header),
|
|
84
114
|
]);
|
|
85
115
|
}
|
|
86
116
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { EpochAndSlot, EpochCacheInterface, EpochCommitteeInfo, SlotTag } from '@aztec/epoch-cache';
|
|
2
2
|
import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
4
|
+
import { EmptyL1RollupConstants, type L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Mock implementation of the EpochCacheInterface used to satisfy dependencies of AztecNodeService.
|
|
@@ -16,11 +17,12 @@ export class MockEpochCache implements EpochCacheInterface {
|
|
|
16
17
|
});
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
getEpochAndSlotNow(): EpochAndSlot {
|
|
20
|
+
getEpochAndSlotNow(): EpochAndSlot & { nowMs: bigint } {
|
|
20
21
|
return {
|
|
21
22
|
epoch: EpochNumber.ZERO,
|
|
22
23
|
slot: SlotNumber(0),
|
|
23
24
|
ts: 0n,
|
|
25
|
+
nowMs: 0n,
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -63,4 +65,8 @@ export class MockEpochCache implements EpochCacheInterface {
|
|
|
63
65
|
filterInCommittee(_slot: SlotTag, _validators: EthAddress[]): Promise<EthAddress[]> {
|
|
64
66
|
return Promise.resolve([]);
|
|
65
67
|
}
|
|
68
|
+
|
|
69
|
+
getL1Constants(): L1RollupConstants {
|
|
70
|
+
return EmptyL1RollupConstants;
|
|
71
|
+
}
|
|
66
72
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP } from '@aztec/constants';
|
|
2
2
|
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
3
3
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
4
|
-
import type {
|
|
4
|
+
import type { L2Block } from '@aztec/stdlib/block';
|
|
5
5
|
import type {
|
|
6
6
|
MerkleTreeReadOperations,
|
|
7
7
|
MerkleTreeWriteOperations,
|
|
@@ -23,7 +23,7 @@ export class TXESynchronizer implements WorldStateSynchronizer {
|
|
|
23
23
|
return new this(nativeWorldStateService);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
public async handleL2Block(block:
|
|
26
|
+
public async handleL2Block(block: L2Block) {
|
|
27
27
|
await this.nativeWorldStateService.handleL2BlockAndMessages(
|
|
28
28
|
block,
|
|
29
29
|
Array(NUMBER_OF_L1_L2_MESSAGES_PER_ROLLUP).fill(0).map(Fr.zero),
|