@aztec/p2p 0.67.0 → 0.67.1-devnet
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/bootstrap/bootstrap.js +2 -2
- package/dest/client/index.d.ts +5 -4
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +12 -9
- package/dest/client/p2p_client.d.ts +6 -6
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +12 -11
- package/dest/config.d.ts +1 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -2
- package/dest/errors/reqresp.error.d.ts +12 -1
- package/dest/errors/reqresp.error.d.ts.map +1 -1
- package/dest/errors/reqresp.error.js +15 -2
- package/dest/index.d.ts +1 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -2
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +9 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +3 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +171 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts +29 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.d.ts.map +1 -0
- package/dest/mem_pools/attestation_pool/kv_attestation_pool.js +114 -0
- package/dest/mem_pools/interface.d.ts +4 -3
- package/dest/mem_pools/interface.d.ts.map +1 -1
- package/dest/mocks/index.d.ts +6 -6
- package/dest/mocks/index.d.ts.map +1 -1
- package/dest/mocks/index.js +8 -8
- package/dest/services/data_store.d.ts.map +1 -0
- package/dest/services/data_store.js +188 -0
- package/dest/{service → services/discv5}/discV5_service.d.ts +2 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -0
- package/dest/services/discv5/discV5_service.js +144 -0
- package/dest/services/dummy_service.d.ts.map +1 -0
- package/dest/{service → services}/dummy_service.js +1 -1
- package/dest/{service → services}/encoding.d.ts +5 -0
- package/dest/services/encoding.d.ts.map +1 -0
- package/dest/services/encoding.js +65 -0
- package/dest/services/index.d.ts +3 -0
- package/dest/services/index.d.ts.map +1 -0
- package/dest/services/index.js +3 -0
- package/dest/{service → services/libp2p}/libp2p_service.d.ts +48 -10
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -0
- package/dest/services/libp2p/libp2p_service.js +573 -0
- package/dest/{service → services/peer-scoring}/peer_scoring.d.ts +1 -1
- package/dest/services/peer-scoring/peer_scoring.d.ts.map +1 -0
- package/dest/services/peer-scoring/peer_scoring.js +72 -0
- package/dest/{service → services}/peer_manager.d.ts +5 -3
- package/dest/services/peer_manager.d.ts.map +1 -0
- package/dest/services/peer_manager.js +230 -0
- package/dest/services/reqresp/config.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/config.js +1 -1
- package/dest/services/reqresp/handlers.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/handlers.js +1 -1
- package/dest/services/reqresp/index.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/index.js +1 -1
- package/dest/services/reqresp/interface.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/interface.js +1 -1
- package/dest/services/reqresp/rate_limiter/index.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/rate_limiter/index.js +1 -1
- package/dest/services/reqresp/rate_limiter/rate_limiter.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/rate_limiter/rate_limiter.js +2 -2
- package/dest/services/reqresp/rate_limiter/rate_limits.d.ts.map +1 -0
- package/dest/{service → services}/reqresp/rate_limiter/rate_limits.js +1 -1
- package/dest/{service → services}/reqresp/reqresp.d.ts +16 -0
- package/dest/services/reqresp/reqresp.d.ts.map +1 -0
- package/dest/services/reqresp/reqresp.js +279 -0
- package/dest/services/service.d.ts.map +1 -0
- package/dest/{service → services}/service.js +1 -1
- package/dest/tx_validator/aggregate_tx_validator.d.ts +1 -1
- package/dest/tx_validator/aggregate_tx_validator.d.ts.map +1 -1
- package/dest/tx_validator/aggregate_tx_validator.js +5 -3
- package/dest/tx_validator/double_spend_validator.d.ts +3 -2
- package/dest/tx_validator/double_spend_validator.d.ts.map +1 -1
- package/dest/tx_validator/double_spend_validator.js +6 -6
- package/package.json +8 -7
- package/src/bootstrap/bootstrap.ts +1 -1
- package/src/client/index.ts +38 -16
- package/src/client/p2p_client.ts +28 -15
- package/src/config.ts +1 -1
- package/src/errors/reqresp.error.ts +15 -1
- package/src/index.ts +1 -1
- package/src/mem_pools/attestation_pool/attestation_pool.ts +10 -0
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +237 -0
- package/src/mem_pools/attestation_pool/kv_attestation_pool.ts +153 -0
- package/src/mem_pools/interface.ts +5 -3
- package/src/mocks/index.ts +13 -10
- package/src/{service → services/discv5}/discV5_service.ts +3 -3
- package/src/{service → services}/encoding.ts +21 -3
- package/src/services/index.ts +2 -0
- package/src/{service → services/libp2p}/libp2p_service.ts +192 -86
- package/src/{service → services/peer-scoring}/peer_scoring.ts +1 -1
- package/src/{service → services}/peer_manager.ts +5 -2
- package/src/{service → services}/reqresp/rate_limiter/rate_limiter.ts +1 -1
- package/src/{service → services}/reqresp/reqresp.ts +83 -17
- package/src/tx_validator/aggregate_tx_validator.ts +5 -3
- package/src/tx_validator/double_spend_validator.ts +6 -8
- package/dest/service/data_store.d.ts.map +0 -1
- package/dest/service/data_store.js +0 -188
- package/dest/service/discV5_service.d.ts.map +0 -1
- package/dest/service/discV5_service.js +0 -144
- package/dest/service/dummy_service.d.ts.map +0 -1
- package/dest/service/encoding.d.ts.map +0 -1
- package/dest/service/encoding.js +0 -49
- package/dest/service/index.d.ts +0 -3
- package/dest/service/index.d.ts.map +0 -1
- package/dest/service/index.js +0 -3
- package/dest/service/libp2p_service.d.ts.map +0 -1
- package/dest/service/libp2p_service.js +0 -500
- package/dest/service/peer_manager.d.ts.map +0 -1
- package/dest/service/peer_manager.js +0 -214
- package/dest/service/peer_scoring.d.ts.map +0 -1
- package/dest/service/peer_scoring.js +0 -72
- package/dest/service/reqresp/config.d.ts.map +0 -1
- package/dest/service/reqresp/handlers.d.ts.map +0 -1
- package/dest/service/reqresp/index.d.ts.map +0 -1
- package/dest/service/reqresp/interface.d.ts.map +0 -1
- package/dest/service/reqresp/rate_limiter/index.d.ts.map +0 -1
- package/dest/service/reqresp/rate_limiter/rate_limiter.d.ts.map +0 -1
- package/dest/service/reqresp/rate_limiter/rate_limits.d.ts.map +0 -1
- package/dest/service/reqresp/reqresp.d.ts.map +0 -1
- package/dest/service/reqresp/reqresp.js +0 -230
- package/dest/service/service.d.ts.map +0 -1
- package/src/service/index.ts +0 -2
- /package/dest/{service → services}/data_store.d.ts +0 -0
- /package/dest/{service → services}/dummy_service.d.ts +0 -0
- /package/dest/{service → services}/reqresp/config.d.ts +0 -0
- /package/dest/{service → services}/reqresp/handlers.d.ts +0 -0
- /package/dest/{service → services}/reqresp/index.d.ts +0 -0
- /package/dest/{service → services}/reqresp/interface.d.ts +0 -0
- /package/dest/{service → services}/reqresp/rate_limiter/index.d.ts +0 -0
- /package/dest/{service → services}/reqresp/rate_limiter/rate_limiter.d.ts +0 -0
- /package/dest/{service → services}/reqresp/rate_limiter/rate_limits.d.ts +0 -0
- /package/dest/{service → services}/service.d.ts +0 -0
- /package/src/{service → services}/data_store.ts +0 -0
- /package/src/{service → services}/dummy_service.ts +0 -0
- /package/src/{service → services}/reqresp/config.ts +0 -0
- /package/src/{service → services}/reqresp/handlers.ts +0 -0
- /package/src/{service → services}/reqresp/index.ts +0 -0
- /package/src/{service → services}/reqresp/interface.ts +0 -0
- /package/src/{service → services}/reqresp/rate_limiter/index.ts +0 -0
- /package/src/{service → services}/reqresp/rate_limiter/rate_limits.ts +0 -0
- /package/src/{service → services}/service.ts +0 -0
package/src/client/p2p_client.ts
CHANGED
|
@@ -5,10 +5,10 @@ import {
|
|
|
5
5
|
type L2Block,
|
|
6
6
|
type L2BlockId,
|
|
7
7
|
type L2BlockSource,
|
|
8
|
-
L2BlockStream,
|
|
9
8
|
type L2BlockStreamEvent,
|
|
10
9
|
type L2Tips,
|
|
11
10
|
type P2PApi,
|
|
11
|
+
type P2PClientType,
|
|
12
12
|
type PeerInfo,
|
|
13
13
|
type Tx,
|
|
14
14
|
type TxHash,
|
|
@@ -16,7 +16,13 @@ import {
|
|
|
16
16
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
|
|
17
17
|
import { createLogger } from '@aztec/foundation/log';
|
|
18
18
|
import { type AztecKVStore, type AztecMap, type AztecSingleton } from '@aztec/kv-store';
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
Attributes,
|
|
21
|
+
type TelemetryClient,
|
|
22
|
+
TraceableL2BlockStream,
|
|
23
|
+
WithTracer,
|
|
24
|
+
trackSpan,
|
|
25
|
+
} from '@aztec/telemetry-client';
|
|
20
26
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
21
27
|
|
|
22
28
|
import { type ENR } from '@chainsafe/enr';
|
|
@@ -26,8 +32,8 @@ import { type AttestationPool } from '../mem_pools/attestation_pool/attestation_
|
|
|
26
32
|
import { type EpochProofQuotePool } from '../mem_pools/epoch_proof_quote_pool/epoch_proof_quote_pool.js';
|
|
27
33
|
import { type MemPools } from '../mem_pools/interface.js';
|
|
28
34
|
import { type TxPool } from '../mem_pools/tx_pool/index.js';
|
|
29
|
-
import { TX_REQ_PROTOCOL } from '../
|
|
30
|
-
import type { P2PService } from '../
|
|
35
|
+
import { TX_REQ_PROTOCOL } from '../services/reqresp/interface.js';
|
|
36
|
+
import type { P2PService } from '../services/service.js';
|
|
31
37
|
|
|
32
38
|
/**
|
|
33
39
|
* Enum defining the possible states of the p2p client.
|
|
@@ -56,7 +62,7 @@ export interface P2PSyncState {
|
|
|
56
62
|
/**
|
|
57
63
|
* Interface of a P2P client.
|
|
58
64
|
**/
|
|
59
|
-
export
|
|
65
|
+
export type P2P<T extends P2PClientType = P2PClientType.Full> = P2PApi<T> & {
|
|
60
66
|
/**
|
|
61
67
|
* Broadcasts a block proposal to other peers.
|
|
62
68
|
*
|
|
@@ -166,12 +172,15 @@ export interface P2P extends P2PApi {
|
|
|
166
172
|
|
|
167
173
|
/** Identifies a p2p client. */
|
|
168
174
|
isP2PClient(): true;
|
|
169
|
-
}
|
|
175
|
+
};
|
|
170
176
|
|
|
171
177
|
/**
|
|
172
178
|
* The P2P client implementation.
|
|
173
179
|
*/
|
|
174
|
-
export class P2PClient extends
|
|
180
|
+
export class P2PClient<T extends P2PClientType = P2PClientType.Full>
|
|
181
|
+
extends WithTracer
|
|
182
|
+
implements P2P, P2P<P2PClientType.Prover>
|
|
183
|
+
{
|
|
175
184
|
/** Property that indicates whether the client is running. */
|
|
176
185
|
private stopping = false;
|
|
177
186
|
|
|
@@ -189,7 +198,7 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
189
198
|
private synchedProvenBlockNumber: AztecSingleton<number>;
|
|
190
199
|
|
|
191
200
|
private txPool: TxPool;
|
|
192
|
-
private attestationPool: AttestationPool;
|
|
201
|
+
private attestationPool: T extends P2PClientType.Full ? AttestationPool : undefined;
|
|
193
202
|
private epochProofQuotePool: EpochProofQuotePool;
|
|
194
203
|
|
|
195
204
|
/** How many slots to keep attestations for. */
|
|
@@ -207,9 +216,10 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
207
216
|
* @param log - A logger.
|
|
208
217
|
*/
|
|
209
218
|
constructor(
|
|
219
|
+
clientType: T,
|
|
210
220
|
store: AztecKVStore,
|
|
211
221
|
private l2BlockSource: L2BlockSource,
|
|
212
|
-
mempools: MemPools
|
|
222
|
+
mempools: MemPools<T>,
|
|
213
223
|
private p2pService: P2PService,
|
|
214
224
|
private keepProvenTxsFor: number,
|
|
215
225
|
telemetry: TelemetryClient = new NoopTelemetryClient(),
|
|
@@ -221,7 +231,9 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
221
231
|
|
|
222
232
|
this.keepAttestationsInPoolFor = keepAttestationsInPoolFor;
|
|
223
233
|
|
|
224
|
-
|
|
234
|
+
const tracer = telemetry.getTracer('P2PL2BlockStream');
|
|
235
|
+
const logger = createLogger('p2p:l2-block-stream');
|
|
236
|
+
this.blockStream = new TraceableL2BlockStream(l2BlockSource, this, this, tracer, 'P2PL2BlockStream', logger, {
|
|
225
237
|
batchSize: blockRequestBatchSize,
|
|
226
238
|
pollIntervalMS: blockCheckIntervalMS,
|
|
227
239
|
});
|
|
@@ -231,8 +243,8 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
231
243
|
this.synchedProvenBlockNumber = store.openSingleton('p2p_pool_last_proven_l2_block');
|
|
232
244
|
|
|
233
245
|
this.txPool = mempools.txPool;
|
|
234
|
-
this.attestationPool = mempools.attestationPool;
|
|
235
246
|
this.epochProofQuotePool = mempools.epochProofQuotePool;
|
|
247
|
+
this.attestationPool = mempools.attestationPool!;
|
|
236
248
|
}
|
|
237
249
|
|
|
238
250
|
public isP2PClient(): true {
|
|
@@ -399,7 +411,7 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
399
411
|
}
|
|
400
412
|
|
|
401
413
|
public getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]> {
|
|
402
|
-
return Promise.resolve(this.attestationPool
|
|
414
|
+
return Promise.resolve(this.attestationPool?.getAttestationsForSlot(slot, proposalId) ?? []);
|
|
403
415
|
}
|
|
404
416
|
|
|
405
417
|
// REVIEW: https://github.com/AztecProtocol/aztec-packages/issues/7963
|
|
@@ -644,16 +656,17 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
644
656
|
// We delete attestations older than the last block slot minus the number of slots we want to keep in the pool.
|
|
645
657
|
const lastBlockSlotMinusKeepAttestationsInPoolFor = lastBlockSlot - BigInt(this.keepAttestationsInPoolFor);
|
|
646
658
|
if (lastBlockSlotMinusKeepAttestationsInPoolFor >= BigInt(INITIAL_L2_BLOCK_NUM)) {
|
|
647
|
-
await this.attestationPool
|
|
659
|
+
await this.attestationPool?.deleteAttestationsOlderThan(lastBlockSlotMinusKeepAttestationsInPoolFor);
|
|
648
660
|
}
|
|
649
661
|
|
|
650
|
-
await this.synchedProvenBlockNumber.set(lastBlockNum);
|
|
651
|
-
this.log.debug(`Synched to proven block ${lastBlockNum}`);
|
|
652
662
|
const provenEpochNumber = await this.l2BlockSource.getProvenL2EpochNumber();
|
|
653
663
|
if (provenEpochNumber !== undefined) {
|
|
654
664
|
this.epochProofQuotePool.deleteQuotesToEpoch(BigInt(provenEpochNumber));
|
|
655
665
|
}
|
|
656
666
|
|
|
667
|
+
await this.synchedProvenBlockNumber.set(lastBlockNum);
|
|
668
|
+
this.log.debug(`Synched to proven block ${lastBlockNum}`);
|
|
669
|
+
|
|
657
670
|
await this.startServiceIfSynched();
|
|
658
671
|
}
|
|
659
672
|
|
package/src/config.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
} from '@aztec/foundation/config';
|
|
9
9
|
import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
|
|
10
10
|
|
|
11
|
-
import { type P2PReqRespConfig, p2pReqRespConfigMappings } from './
|
|
11
|
+
import { type P2PReqRespConfig, p2pReqRespConfigMappings } from './services/reqresp/config.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* P2P client configuration values.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* This error will be thrown when a request to a specific peer times out.
|
|
4
4
|
* @category Errors
|
|
5
5
|
*/
|
|
6
|
-
export class
|
|
6
|
+
export class IndividualReqRespTimeoutError extends Error {
|
|
7
7
|
constructor() {
|
|
8
8
|
super(`Request to peer timed out`);
|
|
9
9
|
}
|
|
@@ -19,3 +19,17 @@ export class CollectiveReqRespTimeoutError extends Error {
|
|
|
19
19
|
super(`Request to all peers timed out`);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
/** Invalid response error
|
|
24
|
+
*
|
|
25
|
+
* This error will be thrown when a response is received that is not valid.
|
|
26
|
+
*
|
|
27
|
+
* This error does not need to be punished as message validators will handle punishing invalid
|
|
28
|
+
* requests
|
|
29
|
+
* @category Errors
|
|
30
|
+
*/
|
|
31
|
+
export class InvalidResponseError extends Error {
|
|
32
|
+
constructor() {
|
|
33
|
+
super(`Invalid response received`);
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,6 @@ export * from './bootstrap/bootstrap.js';
|
|
|
3
3
|
export * from './client/index.js';
|
|
4
4
|
export * from './config.js';
|
|
5
5
|
export * from './mem_pools/epoch_proof_quote_pool/index.js';
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './services/index.js';
|
|
7
7
|
export * from './mem_pools/tx_pool/index.js';
|
|
8
8
|
export * from './tx_validator/index.js';
|
|
@@ -39,6 +39,16 @@ export interface AttestationPool {
|
|
|
39
39
|
*/
|
|
40
40
|
deleteAttestationsForSlot(slot: bigint): Promise<void>;
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Delete Attestations for slot and proposal
|
|
44
|
+
*
|
|
45
|
+
* Removes all attestations associated with a slot and proposal
|
|
46
|
+
*
|
|
47
|
+
* @param slot - The slot to delete.
|
|
48
|
+
* @param proposalId - The proposal to delete.
|
|
49
|
+
*/
|
|
50
|
+
deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void>;
|
|
51
|
+
|
|
42
52
|
/**
|
|
43
53
|
* Get Attestations for slot
|
|
44
54
|
*
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { type BlockAttestation, TxHash } from '@aztec/circuit-types';
|
|
2
|
+
import { Secp256k1Signer } from '@aztec/foundation/crypto';
|
|
3
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
4
|
+
|
|
5
|
+
import { jest } from '@jest/globals';
|
|
6
|
+
import { type MockProxy, mock } from 'jest-mock-extended';
|
|
7
|
+
|
|
8
|
+
import { type PoolInstrumentation } from '../instrumentation.js';
|
|
9
|
+
import { type AttestationPool } from './attestation_pool.js';
|
|
10
|
+
import { mockAttestation } from './mocks.js';
|
|
11
|
+
|
|
12
|
+
const NUMBER_OF_SIGNERS_PER_TEST = 4;
|
|
13
|
+
|
|
14
|
+
export function describeAttestationPool(getAttestationPool: () => AttestationPool) {
|
|
15
|
+
let ap: AttestationPool;
|
|
16
|
+
let signers: Secp256k1Signer[];
|
|
17
|
+
|
|
18
|
+
// Check that metrics are recorded correctly
|
|
19
|
+
let metricsMock: MockProxy<PoolInstrumentation<BlockAttestation>>;
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
ap = getAttestationPool();
|
|
23
|
+
signers = Array.from({ length: NUMBER_OF_SIGNERS_PER_TEST }, () => Secp256k1Signer.random());
|
|
24
|
+
|
|
25
|
+
metricsMock = mock<PoolInstrumentation<BlockAttestation>>();
|
|
26
|
+
// Can i overwrite this like this??
|
|
27
|
+
(ap as any).metrics = metricsMock;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const createAttestationsForSlot = (slotNumber: number) => {
|
|
31
|
+
const archive = Fr.random();
|
|
32
|
+
return signers.map(signer => mockAttestation(signer, slotNumber, archive));
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// We compare buffers as the objects can have cached values attached to them which are not serialised
|
|
36
|
+
// using array containing as the kv store does not respect insertion order
|
|
37
|
+
const compareAttestations = (a1: BlockAttestation[], a2: BlockAttestation[]) => {
|
|
38
|
+
const a1Buffer = a1.map(attestation => attestation.toBuffer());
|
|
39
|
+
const a2Buffer = a2.map(attestation => attestation.toBuffer());
|
|
40
|
+
expect(a1Buffer.length).toBe(a2Buffer.length);
|
|
41
|
+
expect(a1Buffer).toEqual(expect.arrayContaining(a2Buffer));
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
it('should add attestations to pool', async () => {
|
|
45
|
+
const slotNumber = 420;
|
|
46
|
+
const archive = Fr.random();
|
|
47
|
+
const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
|
|
48
|
+
|
|
49
|
+
await ap.addAttestations(attestations);
|
|
50
|
+
|
|
51
|
+
// Check metrics have been updated.
|
|
52
|
+
expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
|
|
53
|
+
|
|
54
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString());
|
|
55
|
+
|
|
56
|
+
expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
57
|
+
|
|
58
|
+
compareAttestations(retreivedAttestations, attestations);
|
|
59
|
+
|
|
60
|
+
// Delete by slot
|
|
61
|
+
await ap.deleteAttestationsForSlot(BigInt(slotNumber));
|
|
62
|
+
|
|
63
|
+
expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length);
|
|
64
|
+
|
|
65
|
+
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString());
|
|
66
|
+
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('Should handle duplicate proposals in a slot', async () => {
|
|
70
|
+
const slotNumber = 420;
|
|
71
|
+
const archive = Fr.random();
|
|
72
|
+
const txs = [0, 1, 2, 3, 4, 5].map(() => TxHash.random());
|
|
73
|
+
|
|
74
|
+
// Use the same signer for all attestations
|
|
75
|
+
const attestations: BlockAttestation[] = [];
|
|
76
|
+
const signer = signers[0];
|
|
77
|
+
for (let i = 0; i < NUMBER_OF_SIGNERS_PER_TEST; i++) {
|
|
78
|
+
attestations.push(mockAttestation(signer, slotNumber, archive, txs));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await ap.addAttestations(attestations);
|
|
82
|
+
|
|
83
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), archive.toString());
|
|
84
|
+
expect(retreivedAttestations.length).toBe(1);
|
|
85
|
+
expect(retreivedAttestations[0].toBuffer()).toEqual(attestations[0].toBuffer());
|
|
86
|
+
expect(retreivedAttestations[0].payload.txHashes).toEqual(txs);
|
|
87
|
+
expect(retreivedAttestations[0].getSender().toString()).toEqual(signer.address.toString());
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('Should store attestations by differing slot', async () => {
|
|
91
|
+
const slotNumbers = [1, 2, 3, 4];
|
|
92
|
+
const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i]));
|
|
93
|
+
|
|
94
|
+
await ap.addAttestations(attestations);
|
|
95
|
+
|
|
96
|
+
for (const attestation of attestations) {
|
|
97
|
+
const slot = attestation.payload.header.globalVariables.slotNumber;
|
|
98
|
+
const archive = attestation.archive.toString();
|
|
99
|
+
|
|
100
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), archive);
|
|
101
|
+
expect(retreivedAttestations.length).toBe(1);
|
|
102
|
+
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
103
|
+
expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('Should store attestations by differing slot and archive', async () => {
|
|
108
|
+
const slotNumbers = [1, 1, 2, 3];
|
|
109
|
+
const archives = [Fr.random(), Fr.random(), Fr.random(), Fr.random()];
|
|
110
|
+
const attestations = signers.map((signer, i) => mockAttestation(signer, slotNumbers[i], archives[i]));
|
|
111
|
+
|
|
112
|
+
await ap.addAttestations(attestations);
|
|
113
|
+
|
|
114
|
+
for (const attestation of attestations) {
|
|
115
|
+
const slot = attestation.payload.header.globalVariables.slotNumber;
|
|
116
|
+
const proposalId = attestation.archive.toString();
|
|
117
|
+
|
|
118
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(slot.toBigInt(), proposalId);
|
|
119
|
+
expect(retreivedAttestations.length).toBe(1);
|
|
120
|
+
expect(retreivedAttestations[0].toBuffer()).toEqual(attestation.toBuffer());
|
|
121
|
+
expect(retreivedAttestations[0].payload.header.globalVariables.slotNumber).toEqual(slot);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('Should delete attestations', async () => {
|
|
126
|
+
const slotNumber = 420;
|
|
127
|
+
const archive = Fr.random();
|
|
128
|
+
const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
|
|
129
|
+
const proposalId = attestations[0].archive.toString();
|
|
130
|
+
|
|
131
|
+
await ap.addAttestations(attestations);
|
|
132
|
+
|
|
133
|
+
expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
|
|
134
|
+
|
|
135
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
136
|
+
expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
137
|
+
compareAttestations(retreivedAttestations, attestations);
|
|
138
|
+
|
|
139
|
+
await ap.deleteAttestations(attestations);
|
|
140
|
+
|
|
141
|
+
expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length);
|
|
142
|
+
|
|
143
|
+
const gottenAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
144
|
+
expect(gottenAfterDelete.length).toBe(0);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('Should blanket delete attestations per slot', async () => {
|
|
148
|
+
const slotNumber = 420;
|
|
149
|
+
const archive = Fr.random();
|
|
150
|
+
const attestations = await Promise.all(signers.map(signer => mockAttestation(signer, slotNumber, archive)));
|
|
151
|
+
const proposalId = attestations[0].archive.toString();
|
|
152
|
+
|
|
153
|
+
await ap.addAttestations(attestations);
|
|
154
|
+
|
|
155
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
156
|
+
expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
157
|
+
compareAttestations(retreivedAttestations, attestations);
|
|
158
|
+
|
|
159
|
+
await ap.deleteAttestationsForSlot(BigInt(slotNumber));
|
|
160
|
+
|
|
161
|
+
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
162
|
+
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('Should blanket delete attestations per slot and proposal', async () => {
|
|
166
|
+
const slotNumber = 420;
|
|
167
|
+
const archive = Fr.random();
|
|
168
|
+
const attestations = signers.map(signer => mockAttestation(signer, slotNumber, archive));
|
|
169
|
+
const proposalId = attestations[0].archive.toString();
|
|
170
|
+
|
|
171
|
+
// Add another set of attestations with a different proposalId, yet the same slot
|
|
172
|
+
const archive2 = Fr.random();
|
|
173
|
+
const attestations2 = signers.map(signer => mockAttestation(signer, slotNumber, archive2));
|
|
174
|
+
const proposalId2 = attestations2[0].archive.toString();
|
|
175
|
+
|
|
176
|
+
await ap.addAttestations(attestations);
|
|
177
|
+
await ap.addAttestations(attestations2);
|
|
178
|
+
|
|
179
|
+
expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations.length);
|
|
180
|
+
expect(metricsMock.recordAddedObjects).toHaveBeenCalledWith(attestations2.length);
|
|
181
|
+
|
|
182
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
183
|
+
expect(retreivedAttestations.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
184
|
+
compareAttestations(retreivedAttestations, attestations);
|
|
185
|
+
|
|
186
|
+
await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId);
|
|
187
|
+
|
|
188
|
+
expect(metricsMock.recordRemovedObjects).toHaveBeenCalledWith(attestations.length);
|
|
189
|
+
|
|
190
|
+
const retreivedAttestationsAfterDelete = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
191
|
+
expect(retreivedAttestationsAfterDelete.length).toBe(0);
|
|
192
|
+
|
|
193
|
+
const retreivedAttestationsAfterDeleteForOtherProposal = await ap.getAttestationsForSlot(
|
|
194
|
+
BigInt(slotNumber),
|
|
195
|
+
proposalId2,
|
|
196
|
+
);
|
|
197
|
+
expect(retreivedAttestationsAfterDeleteForOtherProposal.length).toBe(NUMBER_OF_SIGNERS_PER_TEST);
|
|
198
|
+
compareAttestations(retreivedAttestationsAfterDeleteForOtherProposal, attestations2);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('Should blanket delete attestations per slot and proposal (does not perform db ops if there are no attestations)', async () => {
|
|
202
|
+
const slotNumber = 420;
|
|
203
|
+
const proposalId = 'proposalId';
|
|
204
|
+
|
|
205
|
+
const retreivedAttestations = await ap.getAttestationsForSlot(BigInt(slotNumber), proposalId);
|
|
206
|
+
expect(retreivedAttestations.length).toBe(0);
|
|
207
|
+
|
|
208
|
+
await ap.deleteAttestationsForSlotAndProposal(BigInt(slotNumber), proposalId);
|
|
209
|
+
|
|
210
|
+
expect(metricsMock.recordRemovedObjects).toHaveBeenCalledTimes(0);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('Should delete attestations older than a given slot', async () => {
|
|
214
|
+
const slotNumbers = [1, 2, 3, 69, 72, 74, 88, 420];
|
|
215
|
+
const attestations = slotNumbers.map(slotNumber => createAttestationsForSlot(slotNumber)).flat();
|
|
216
|
+
const proposalId = attestations[0].archive.toString();
|
|
217
|
+
|
|
218
|
+
await ap.addAttestations(attestations);
|
|
219
|
+
|
|
220
|
+
const attestationsForSlot1 = await ap.getAttestationsForSlot(BigInt(1), proposalId);
|
|
221
|
+
expect(attestationsForSlot1.length).toBe(signers.length);
|
|
222
|
+
|
|
223
|
+
const deleteAttestationsSpy = jest.spyOn(ap, 'deleteAttestationsForSlot');
|
|
224
|
+
|
|
225
|
+
await ap.deleteAttestationsOlderThan(BigInt(73));
|
|
226
|
+
|
|
227
|
+
const attestationsForSlot1AfterDelete = await ap.getAttestationsForSlot(BigInt(1), proposalId);
|
|
228
|
+
expect(attestationsForSlot1AfterDelete.length).toBe(0);
|
|
229
|
+
|
|
230
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledTimes(5);
|
|
231
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(1));
|
|
232
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(2));
|
|
233
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(3));
|
|
234
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(69));
|
|
235
|
+
expect(deleteAttestationsSpy).toHaveBeenCalledWith(BigInt(72));
|
|
236
|
+
});
|
|
237
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { BlockAttestation } from '@aztec/circuit-types';
|
|
2
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
3
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
4
|
+
import { type AztecKVStore, type AztecMapWithSize, type AztecMultiMap } from '@aztec/kv-store';
|
|
5
|
+
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
6
|
+
|
|
7
|
+
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
8
|
+
import { type AttestationPool } from './attestation_pool.js';
|
|
9
|
+
|
|
10
|
+
export class KvAttestationPool implements AttestationPool {
|
|
11
|
+
private metrics: PoolInstrumentation<BlockAttestation>;
|
|
12
|
+
|
|
13
|
+
// Index of all proposal ids in a slot
|
|
14
|
+
private attestations: AztecMultiMap<string, string>;
|
|
15
|
+
|
|
16
|
+
constructor(
|
|
17
|
+
private store: AztecKVStore,
|
|
18
|
+
telemetry: TelemetryClient,
|
|
19
|
+
private log = createLogger('aztec:attestation_pool'),
|
|
20
|
+
) {
|
|
21
|
+
this.attestations = store.openMultiMap('attestations');
|
|
22
|
+
this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private getProposalMapKey(slot: string, proposalId: string): string {
|
|
26
|
+
return `proposal-${slot}-${proposalId}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get the proposal map for a given slot and proposalId
|
|
31
|
+
*
|
|
32
|
+
* Essentially a nested mapping of address -> attestation
|
|
33
|
+
*
|
|
34
|
+
* @param slot - The slot to get the proposal map for
|
|
35
|
+
* @param proposalId - The proposalId to get the map for
|
|
36
|
+
* @returns The proposal map
|
|
37
|
+
*/
|
|
38
|
+
private getProposalMap(slot: string, proposalId: string): AztecMapWithSize<string, Buffer> {
|
|
39
|
+
const mapKey = this.getProposalMapKey(slot, proposalId);
|
|
40
|
+
return this.store.openMapWithSize(mapKey);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async addAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
44
|
+
for (const attestation of attestations) {
|
|
45
|
+
const slotNumber = attestation.payload.header.globalVariables.slotNumber.toString();
|
|
46
|
+
const proposalId = attestation.archive.toString();
|
|
47
|
+
const address = attestation.getSender().toString();
|
|
48
|
+
|
|
49
|
+
// Index the proposalId in the slot map
|
|
50
|
+
await this.attestations.set(slotNumber, proposalId);
|
|
51
|
+
|
|
52
|
+
// Store the actual attestation in the proposal map
|
|
53
|
+
const proposalMap = this.getProposalMap(slotNumber, proposalId);
|
|
54
|
+
await proposalMap.set(address, attestation.toBuffer());
|
|
55
|
+
|
|
56
|
+
this.log.verbose(`Added attestation for slot ${slotNumber} from ${address}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
this.metrics.recordAddedObjects(attestations.length);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]> {
|
|
63
|
+
const slotNumber = new Fr(slot).toString();
|
|
64
|
+
const proposalMap = this.getProposalMap(slotNumber, proposalId);
|
|
65
|
+
const attestations = proposalMap.values();
|
|
66
|
+
const attestationsArray = Array.from(attestations).map(attestation => BlockAttestation.fromBuffer(attestation));
|
|
67
|
+
return Promise.resolve(attestationsArray);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public async deleteAttestationsOlderThan(oldestSlot: bigint): Promise<void> {
|
|
71
|
+
const olderThan = [];
|
|
72
|
+
|
|
73
|
+
const slots = this.attestations.keys();
|
|
74
|
+
for (const slot of slots) {
|
|
75
|
+
if (BigInt(slot) < oldestSlot) {
|
|
76
|
+
olderThan.push(slot);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await Promise.all(olderThan.map(oldSlot => this.deleteAttestationsForSlot(BigInt(oldSlot))));
|
|
81
|
+
return Promise.resolve();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
public async deleteAttestationsForSlot(slot: bigint): Promise<void> {
|
|
85
|
+
const deletionPromises = [];
|
|
86
|
+
|
|
87
|
+
const slotString = new Fr(slot).toString();
|
|
88
|
+
let numberOfAttestations = 0;
|
|
89
|
+
const proposalIds = this.attestations.getValues(slotString);
|
|
90
|
+
|
|
91
|
+
if (proposalIds) {
|
|
92
|
+
for (const proposalId of proposalIds) {
|
|
93
|
+
const proposalMap = this.getProposalMap(slotString, proposalId);
|
|
94
|
+
numberOfAttestations += proposalMap.size();
|
|
95
|
+
deletionPromises.push(proposalMap.clear());
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
await Promise.all(deletionPromises);
|
|
100
|
+
|
|
101
|
+
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot}`);
|
|
102
|
+
this.metrics.recordRemovedObjects(numberOfAttestations);
|
|
103
|
+
return Promise.resolve();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public async deleteAttestationsForSlotAndProposal(slot: bigint, proposalId: string): Promise<void> {
|
|
107
|
+
const deletionPromises = [];
|
|
108
|
+
|
|
109
|
+
const slotString = new Fr(slot).toString();
|
|
110
|
+
const exists = this.attestations.get(slotString);
|
|
111
|
+
|
|
112
|
+
if (exists) {
|
|
113
|
+
// Remove the proposalId from the slot index
|
|
114
|
+
deletionPromises.push(this.attestations.deleteValue(slotString, proposalId));
|
|
115
|
+
|
|
116
|
+
// Delete all attestations for the proposalId
|
|
117
|
+
const proposalMap = this.getProposalMap(slotString, proposalId);
|
|
118
|
+
const numberOfAttestations = proposalMap.size();
|
|
119
|
+
deletionPromises.push(proposalMap.clear());
|
|
120
|
+
|
|
121
|
+
this.log.verbose(`Removed ${numberOfAttestations} attestations for slot ${slot} and proposal ${proposalId}`);
|
|
122
|
+
this.metrics.recordRemovedObjects(numberOfAttestations);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
await Promise.all(deletionPromises);
|
|
126
|
+
return Promise.resolve();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
public async deleteAttestations(attestations: BlockAttestation[]): Promise<void> {
|
|
130
|
+
const deletionPromises = [];
|
|
131
|
+
|
|
132
|
+
for (const attestation of attestations) {
|
|
133
|
+
const slotNumber = attestation.payload.header.globalVariables.slotNumber.toString();
|
|
134
|
+
const proposalId = attestation.archive.toString();
|
|
135
|
+
const proposalMap = this.getProposalMap(slotNumber, proposalId);
|
|
136
|
+
|
|
137
|
+
if (proposalMap) {
|
|
138
|
+
const address = attestation.getSender().toString();
|
|
139
|
+
deletionPromises.push(proposalMap.delete(address));
|
|
140
|
+
this.log.debug(`Deleted attestation for slot ${slotNumber} from ${address}`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (proposalMap.size() === 0) {
|
|
144
|
+
deletionPromises.push(this.attestations.deleteValue(slotNumber, proposalId));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
await Promise.all(deletionPromises);
|
|
149
|
+
|
|
150
|
+
this.metrics.recordRemovedObjects(attestations.length);
|
|
151
|
+
return Promise.resolve();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type P2PClientType } from '@aztec/circuit-types';
|
|
2
|
+
|
|
1
3
|
import { type AttestationPool } from './attestation_pool/attestation_pool.js';
|
|
2
4
|
import { type EpochProofQuotePool } from './epoch_proof_quote_pool/epoch_proof_quote_pool.js';
|
|
3
5
|
import { type TxPool } from './tx_pool/tx_pool.js';
|
|
@@ -5,8 +7,8 @@ import { type TxPool } from './tx_pool/tx_pool.js';
|
|
|
5
7
|
/**
|
|
6
8
|
* A interface the combines all mempools
|
|
7
9
|
*/
|
|
8
|
-
export
|
|
10
|
+
export type MemPools<T extends P2PClientType = P2PClientType.Full> = {
|
|
9
11
|
txPool: TxPool;
|
|
10
|
-
attestationPool:
|
|
12
|
+
attestationPool?: T extends P2PClientType.Full ? AttestationPool : undefined;
|
|
11
13
|
epochProofQuotePool: EpochProofQuotePool;
|
|
12
|
-
}
|
|
14
|
+
};
|
package/src/mocks/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ClientProtocolCircuitVerifier,
|
|
3
3
|
type L2BlockSource,
|
|
4
|
+
type P2PClientType,
|
|
4
5
|
type Tx,
|
|
5
6
|
type WorldStateSynchronizer,
|
|
6
7
|
} from '@aztec/circuit-types';
|
|
@@ -23,11 +24,11 @@ import { type Libp2p, type Libp2pOptions, createLibp2p } from 'libp2p';
|
|
|
23
24
|
import { BootstrapNode } from '../bootstrap/bootstrap.js';
|
|
24
25
|
import { type BootnodeConfig, type P2PConfig } from '../config.js';
|
|
25
26
|
import { type MemPools } from '../mem_pools/interface.js';
|
|
26
|
-
import { DiscV5Service } from '../
|
|
27
|
-
import { LibP2PService } from '../
|
|
28
|
-
import { type PeerManager } from '../
|
|
29
|
-
import { type P2PReqRespConfig } from '../
|
|
30
|
-
import { pingHandler, statusHandler } from '../
|
|
27
|
+
import { DiscV5Service } from '../services/discv5/discV5_service.js';
|
|
28
|
+
import { LibP2PService } from '../services/libp2p/libp2p_service.js';
|
|
29
|
+
import { type PeerManager } from '../services/peer_manager.js';
|
|
30
|
+
import { type P2PReqRespConfig } from '../services/reqresp/config.js';
|
|
31
|
+
import { pingHandler, statusHandler } from '../services/reqresp/handlers.js';
|
|
31
32
|
import {
|
|
32
33
|
PING_PROTOCOL,
|
|
33
34
|
type ReqRespSubProtocolHandlers,
|
|
@@ -35,8 +36,8 @@ import {
|
|
|
35
36
|
STATUS_PROTOCOL,
|
|
36
37
|
TX_REQ_PROTOCOL,
|
|
37
38
|
noopValidator,
|
|
38
|
-
} from '../
|
|
39
|
-
import { ReqResp } from '../
|
|
39
|
+
} from '../services/reqresp/interface.js';
|
|
40
|
+
import { ReqResp } from '../services/reqresp/reqresp.js';
|
|
40
41
|
import { type PubSubLibp2p } from '../util.js';
|
|
41
42
|
|
|
42
43
|
/**
|
|
@@ -95,11 +96,12 @@ export async function createLibp2pNode(
|
|
|
95
96
|
*
|
|
96
97
|
*
|
|
97
98
|
*/
|
|
98
|
-
export async function createTestLibP2PService(
|
|
99
|
+
export async function createTestLibP2PService<T extends P2PClientType>(
|
|
100
|
+
clientType: T,
|
|
99
101
|
boostrapAddrs: string[] = [],
|
|
100
102
|
l2BlockSource: L2BlockSource,
|
|
101
103
|
worldStateSynchronizer: WorldStateSynchronizer,
|
|
102
|
-
mempools: MemPools
|
|
104
|
+
mempools: MemPools<T>,
|
|
103
105
|
telemetry: TelemetryClient,
|
|
104
106
|
port: number = 0,
|
|
105
107
|
peerId?: PeerId,
|
|
@@ -123,7 +125,8 @@ export async function createTestLibP2PService(
|
|
|
123
125
|
// No bootstrap nodes provided as the libp2p service will register them in the constructor
|
|
124
126
|
const p2pNode = await createLibp2pNode([], peerId, port, /*enable gossip */ true, /**start */ false);
|
|
125
127
|
|
|
126
|
-
return new LibP2PService(
|
|
128
|
+
return new LibP2PService<T>(
|
|
129
|
+
clientType,
|
|
127
130
|
config,
|
|
128
131
|
p2pNode as PubSubLibp2p,
|
|
129
132
|
discoveryService,
|
|
@@ -8,9 +8,9 @@ import type { PeerId } from '@libp2p/interface';
|
|
|
8
8
|
import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
|
|
9
9
|
import EventEmitter from 'events';
|
|
10
10
|
|
|
11
|
-
import type { P2PConfig } from '
|
|
12
|
-
import { convertToMultiaddr } from '
|
|
13
|
-
import { type PeerDiscoveryService, PeerDiscoveryState } from '
|
|
11
|
+
import type { P2PConfig } from '../../config.js';
|
|
12
|
+
import { convertToMultiaddr } from '../../util.js';
|
|
13
|
+
import { type PeerDiscoveryService, PeerDiscoveryState } from '../service.js';
|
|
14
14
|
|
|
15
15
|
export const AZTEC_ENR_KEY = 'aztec_network';
|
|
16
16
|
|