@aztec/p2p 0.66.0 → 0.67.0
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.d.ts +4 -1
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +20 -8
- package/dest/client/index.d.ts.map +1 -1
- package/dest/client/index.js +7 -4
- package/dest/client/p2p_client.d.ts +9 -16
- package/dest/client/p2p_client.d.ts.map +1 -1
- package/dest/client/p2p_client.js +23 -7
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/memory_attestation_pool.js +3 -3
- package/dest/mem_pools/instrumentation.d.ts.map +1 -1
- package/dest/mem_pools/instrumentation.js +2 -20
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/aztec_kv_tx_pool.js +4 -4
- package/dest/mem_pools/tx_pool/memory_tx_pool.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool/memory_tx_pool.js +4 -4
- package/dest/mocks/index.js +2 -2
- package/dest/service/discV5_service.d.ts +2 -0
- package/dest/service/discV5_service.d.ts.map +1 -1
- package/dest/service/discV5_service.js +14 -11
- package/dest/service/dummy_service.d.ts +3 -1
- package/dest/service/dummy_service.d.ts.map +1 -1
- package/dest/service/dummy_service.js +5 -1
- package/dest/service/libp2p_service.d.ts +2 -1
- package/dest/service/libp2p_service.d.ts.map +1 -1
- package/dest/service/libp2p_service.js +15 -11
- package/dest/service/peer_manager.d.ts +3 -0
- package/dest/service/peer_manager.d.ts.map +1 -1
- package/dest/service/peer_manager.js +59 -21
- package/dest/service/peer_scoring.d.ts +4 -1
- package/dest/service/peer_scoring.d.ts.map +1 -1
- package/dest/service/peer_scoring.js +6 -1
- package/dest/service/reqresp/reqresp.d.ts.map +1 -1
- package/dest/service/reqresp/reqresp.js +7 -7
- package/dest/service/service.d.ts +2 -1
- package/dest/service/service.d.ts.map +1 -1
- package/dest/tx_validator/data_validator.js +3 -3
- package/dest/tx_validator/double_spend_validator.js +3 -3
- package/dest/tx_validator/metadata_validator.js +3 -3
- package/dest/tx_validator/tx_proof_validator.js +3 -3
- package/package.json +10 -7
- package/src/bootstrap/bootstrap.ts +23 -9
- package/src/client/index.ts +6 -3
- package/src/client/p2p_client.ts +32 -23
- package/src/mem_pools/attestation_pool/memory_attestation_pool.ts +2 -2
- package/src/mem_pools/instrumentation.ts +1 -21
- package/src/mem_pools/tx_pool/aztec_kv_tx_pool.ts +3 -3
- package/src/mem_pools/tx_pool/memory_tx_pool.ts +3 -3
- package/src/mocks/index.ts +1 -1
- package/src/service/discV5_service.ts +17 -12
- package/src/service/dummy_service.ts +6 -1
- package/src/service/libp2p_service.ts +16 -10
- package/src/service/peer_manager.ts +68 -22
- package/src/service/peer_scoring.ts +8 -1
- package/src/service/reqresp/reqresp.ts +6 -6
- package/src/service/service.ts +3 -1
- package/src/tx_validator/data_validator.ts +2 -2
- package/src/tx_validator/double_spend_validator.ts +2 -2
- package/src/tx_validator/metadata_validator.ts +2 -2
- package/src/tx_validator/tx_proof_validator.ts +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type P2PBootstrapApi } from '@aztec/circuit-types/interfaces';
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
3
|
import { type AztecKVStore } from '@aztec/kv-store';
|
|
3
4
|
import { OtelMetricsAdapter, type TelemetryClient } from '@aztec/telemetry-client';
|
|
4
5
|
|
|
@@ -14,14 +15,14 @@ import { convertToMultiaddr, createLibP2PPeerIdFromPrivateKey, getPeerIdPrivateK
|
|
|
14
15
|
/**
|
|
15
16
|
* Encapsulates a 'Bootstrap' node, used for the purpose of assisting new joiners in acquiring peers.
|
|
16
17
|
*/
|
|
17
|
-
export class BootstrapNode {
|
|
18
|
+
export class BootstrapNode implements P2PBootstrapApi {
|
|
18
19
|
private node?: Discv5 = undefined;
|
|
19
20
|
private peerId?: PeerId;
|
|
20
21
|
|
|
21
22
|
constructor(
|
|
22
23
|
private store: AztecKVStore,
|
|
23
24
|
private telemetry: TelemetryClient,
|
|
24
|
-
private logger =
|
|
25
|
+
private logger = createLogger('p2p:bootstrap'),
|
|
25
26
|
) {}
|
|
26
27
|
|
|
27
28
|
/**
|
|
@@ -47,7 +48,7 @@ export class BootstrapNode {
|
|
|
47
48
|
enr.setLocationMultiaddr(publicAddr);
|
|
48
49
|
enr.set(AZTEC_ENR_KEY, Uint8Array.from([AZTEC_NET]));
|
|
49
50
|
|
|
50
|
-
this.logger.
|
|
51
|
+
this.logger.debug(`Starting bootstrap node ${peerId} listening on ${listenAddrUdp.toString()}`);
|
|
51
52
|
const metricsRegistry = new OtelMetricsAdapter(this.telemetry);
|
|
52
53
|
this.node = Discv5.create({
|
|
53
54
|
enr,
|
|
@@ -65,17 +66,15 @@ export class BootstrapNode {
|
|
|
65
66
|
});
|
|
66
67
|
(this.node as Discv5EventEmitter).on('discovered', async (enr: SignableENR) => {
|
|
67
68
|
const addr = await enr.getFullMultiaddr('udp');
|
|
68
|
-
this.logger.verbose(`Discovered new peer
|
|
69
|
+
this.logger.verbose(`Discovered new peer`, { enr: enr.encodeTxt(), addr: addr?.toString() });
|
|
69
70
|
});
|
|
70
71
|
|
|
71
72
|
try {
|
|
72
73
|
await this.node.start();
|
|
73
|
-
this.logger.info('
|
|
74
|
+
this.logger.info('Bootstrap node started', { peerId, enr: enr.encodeTxt(), addr: listenAddrUdp.toString() });
|
|
74
75
|
} catch (e) {
|
|
75
76
|
this.logger.error('Error starting Discv5', e);
|
|
76
77
|
}
|
|
77
|
-
|
|
78
|
-
this.logger.info(`ENR: ${this.node?.enr.encodeTxt()}`);
|
|
79
78
|
}
|
|
80
79
|
|
|
81
80
|
/**
|
|
@@ -84,8 +83,9 @@ export class BootstrapNode {
|
|
|
84
83
|
*/
|
|
85
84
|
public async stop() {
|
|
86
85
|
// stop libp2p
|
|
86
|
+
this.logger.debug('Stopping bootstrap node');
|
|
87
87
|
await this.node?.stop();
|
|
88
|
-
this.logger.
|
|
88
|
+
this.logger.info('Bootstrap node stopped');
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
/**
|
|
@@ -105,4 +105,18 @@ export class BootstrapNode {
|
|
|
105
105
|
}
|
|
106
106
|
return this.node?.enr.toENR();
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
public getEncodedEnr() {
|
|
110
|
+
if (!this.node) {
|
|
111
|
+
throw new Error('Node not started');
|
|
112
|
+
}
|
|
113
|
+
return Promise.resolve(this.node.enr.encodeTxt());
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public getRoutingTable() {
|
|
117
|
+
if (!this.node) {
|
|
118
|
+
throw new Error('Node not started');
|
|
119
|
+
}
|
|
120
|
+
return Promise.resolve(this.node.kadValues().map(enr => enr.encodeTxt()));
|
|
121
|
+
}
|
|
108
122
|
}
|
package/src/client/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ClientProtocolCircuitVerifier, L2BlockSource, WorldStateSynchronizer } from '@aztec/circuit-types';
|
|
2
|
-
import {
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { type AztecKVStore } from '@aztec/kv-store';
|
|
4
4
|
import { type DataStoreConfig } from '@aztec/kv-store/config';
|
|
5
|
-
import { createStore } from '@aztec/kv-store/
|
|
5
|
+
import { createStore } from '@aztec/kv-store/lmdb';
|
|
6
6
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
7
7
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
8
8
|
|
|
@@ -35,7 +35,8 @@ export const createP2PClient = async (
|
|
|
35
35
|
} = {},
|
|
36
36
|
) => {
|
|
37
37
|
let config = { ..._config };
|
|
38
|
-
const
|
|
38
|
+
const logger = createLogger('p2p');
|
|
39
|
+
const store = deps.store ?? (await createStore('p2p', config, createLogger('p2p:lmdb')));
|
|
39
40
|
|
|
40
41
|
const mempools: MemPools = {
|
|
41
42
|
txPool: deps.txPool ?? new AztecKVTxPool(store, telemetry),
|
|
@@ -46,6 +47,7 @@ export const createP2PClient = async (
|
|
|
46
47
|
let p2pService;
|
|
47
48
|
|
|
48
49
|
if (_config.p2pEnabled) {
|
|
50
|
+
logger.verbose('P2P is enabled. Using LibP2P service.');
|
|
49
51
|
config = await configureP2PClientAddresses(_config);
|
|
50
52
|
|
|
51
53
|
// Create peer discovery service
|
|
@@ -65,6 +67,7 @@ export const createP2PClient = async (
|
|
|
65
67
|
telemetry,
|
|
66
68
|
);
|
|
67
69
|
} else {
|
|
70
|
+
logger.verbose('P2P is disabled. Using dummy P2P service');
|
|
68
71
|
p2pService = new DummyP2PService();
|
|
69
72
|
}
|
|
70
73
|
return new P2PClient(store, l2BlockSource, mempools, p2pService, config.keepProvenTxsInPoolFor, telemetry);
|
package/src/client/p2p_client.ts
CHANGED
|
@@ -8,11 +8,13 @@ import {
|
|
|
8
8
|
L2BlockStream,
|
|
9
9
|
type L2BlockStreamEvent,
|
|
10
10
|
type L2Tips,
|
|
11
|
+
type P2PApi,
|
|
12
|
+
type PeerInfo,
|
|
11
13
|
type Tx,
|
|
12
14
|
type TxHash,
|
|
13
15
|
} from '@aztec/circuit-types';
|
|
14
16
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
|
|
15
|
-
import {
|
|
17
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
16
18
|
import { type AztecKVStore, type AztecMap, type AztecSingleton } from '@aztec/kv-store';
|
|
17
19
|
import { Attributes, type TelemetryClient, WithTracer, trackSpan } from '@aztec/telemetry-client';
|
|
18
20
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
@@ -54,7 +56,7 @@ export interface P2PSyncState {
|
|
|
54
56
|
/**
|
|
55
57
|
* Interface of a P2P client.
|
|
56
58
|
**/
|
|
57
|
-
export interface P2P {
|
|
59
|
+
export interface P2P extends P2PApi {
|
|
58
60
|
/**
|
|
59
61
|
* Broadcasts a block proposal to other peers.
|
|
60
62
|
*
|
|
@@ -62,15 +64,6 @@ export interface P2P {
|
|
|
62
64
|
*/
|
|
63
65
|
broadcastProposal(proposal: BlockProposal): void;
|
|
64
66
|
|
|
65
|
-
/**
|
|
66
|
-
* Queries the Attestation pool for attestations for the given slot
|
|
67
|
-
*
|
|
68
|
-
* @param slot - the slot to query
|
|
69
|
-
* @param proposalId - the proposal id to query
|
|
70
|
-
* @returns BlockAttestations
|
|
71
|
-
*/
|
|
72
|
-
getAttestationsForSlot(slot: bigint, proposalId: string): Promise<BlockAttestation[]>;
|
|
73
|
-
|
|
74
67
|
/**
|
|
75
68
|
* Queries the EpochProofQuote pool for quotes for the given epoch
|
|
76
69
|
*
|
|
@@ -122,12 +115,6 @@ export interface P2P {
|
|
|
122
115
|
**/
|
|
123
116
|
deleteTxs(txHashes: TxHash[]): Promise<void>;
|
|
124
117
|
|
|
125
|
-
/**
|
|
126
|
-
* Returns all transactions in the transaction pool.
|
|
127
|
-
* @returns An array of Txs.
|
|
128
|
-
*/
|
|
129
|
-
getTxs(filter: 'all' | 'pending' | 'mined'): Tx[];
|
|
130
|
-
|
|
131
118
|
/**
|
|
132
119
|
* Returns a transaction in the transaction pool by its hash.
|
|
133
120
|
* @param txHash - Hash of tx to return.
|
|
@@ -173,9 +160,12 @@ export interface P2P {
|
|
|
173
160
|
getStatus(): Promise<P2PSyncState>;
|
|
174
161
|
|
|
175
162
|
/**
|
|
176
|
-
* Returns the ENR
|
|
163
|
+
* Returns the ENR of this node, if any.
|
|
177
164
|
*/
|
|
178
165
|
getEnr(): ENR | undefined;
|
|
166
|
+
|
|
167
|
+
/** Identifies a p2p client. */
|
|
168
|
+
isP2PClient(): true;
|
|
179
169
|
}
|
|
180
170
|
|
|
181
171
|
/**
|
|
@@ -223,7 +213,7 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
223
213
|
private p2pService: P2PService,
|
|
224
214
|
private keepProvenTxsFor: number,
|
|
225
215
|
telemetry: TelemetryClient = new NoopTelemetryClient(),
|
|
226
|
-
private log =
|
|
216
|
+
private log = createLogger('p2p'),
|
|
227
217
|
) {
|
|
228
218
|
super(telemetry, 'P2PClient');
|
|
229
219
|
|
|
@@ -231,7 +221,7 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
231
221
|
|
|
232
222
|
this.keepAttestationsInPoolFor = keepAttestationsInPoolFor;
|
|
233
223
|
|
|
234
|
-
this.blockStream = new L2BlockStream(l2BlockSource, this, this, {
|
|
224
|
+
this.blockStream = new L2BlockStream(l2BlockSource, this, this, createLogger('p2p:block_stream'), {
|
|
235
225
|
batchSize: blockRequestBatchSize,
|
|
236
226
|
pollIntervalMS: blockCheckIntervalMS,
|
|
237
227
|
});
|
|
@@ -245,6 +235,14 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
245
235
|
this.epochProofQuotePool = mempools.epochProofQuotePool;
|
|
246
236
|
}
|
|
247
237
|
|
|
238
|
+
public isP2PClient(): true {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public getPeers(includePending?: boolean): Promise<PeerInfo[]> {
|
|
243
|
+
return Promise.resolve(this.p2pService.getPeers(includePending));
|
|
244
|
+
}
|
|
245
|
+
|
|
248
246
|
public getL2BlockHash(number: number): Promise<string | undefined> {
|
|
249
247
|
return Promise.resolve(this.synchedBlockHashes.get(number));
|
|
250
248
|
}
|
|
@@ -361,7 +359,7 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
361
359
|
this.setCurrentState(P2PClientState.RUNNING);
|
|
362
360
|
this.syncPromise = Promise.resolve();
|
|
363
361
|
await this.p2pService.start();
|
|
364
|
-
this.log.
|
|
362
|
+
this.log.debug(`Block ${syncedLatestBlock} (proven ${syncedProvenBlock}) already beyond current block`);
|
|
365
363
|
}
|
|
366
364
|
|
|
367
365
|
// publish any txs in TxPool after its doing initial sync
|
|
@@ -436,14 +434,20 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
436
434
|
public async requestTxByHash(txHash: TxHash): Promise<Tx | undefined> {
|
|
437
435
|
const tx = await this.p2pService.sendRequest(TX_REQ_PROTOCOL, txHash);
|
|
438
436
|
|
|
439
|
-
this.log.debug(`Requested ${txHash.toString()} from peer | success = ${!!tx}`);
|
|
440
437
|
if (tx) {
|
|
438
|
+
this.log.debug(`Received tx ${txHash.toString()} from peer`);
|
|
441
439
|
await this.txPool.addTxs([tx]);
|
|
440
|
+
} else {
|
|
441
|
+
this.log.debug(`Failed to receive tx ${txHash.toString()} from peer`);
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
return tx;
|
|
445
445
|
}
|
|
446
446
|
|
|
447
|
+
public getPendingTxs(): Promise<Tx[]> {
|
|
448
|
+
return Promise.resolve(this.getTxs('pending'));
|
|
449
|
+
}
|
|
450
|
+
|
|
447
451
|
/**
|
|
448
452
|
* Returns all transactions in the transaction pool.
|
|
449
453
|
* @returns An array of Txs.
|
|
@@ -514,6 +518,10 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
514
518
|
return this.p2pService.getEnr();
|
|
515
519
|
}
|
|
516
520
|
|
|
521
|
+
public getEncodedEnr(): Promise<string | undefined> {
|
|
522
|
+
return Promise.resolve(this.p2pService.getEnr()?.encodeTxt());
|
|
523
|
+
}
|
|
524
|
+
|
|
517
525
|
/**
|
|
518
526
|
* Deletes the 'txs' from the pool.
|
|
519
527
|
* NOT used if we use sendTx as reconcileTxPool will handle this.
|
|
@@ -709,8 +717,9 @@ export class P2PClient extends WithTracer implements P2P {
|
|
|
709
717
|
* @param newState - New state value.
|
|
710
718
|
*/
|
|
711
719
|
private setCurrentState(newState: P2PClientState) {
|
|
720
|
+
const oldState = this.currentState;
|
|
712
721
|
this.currentState = newState;
|
|
713
|
-
this.log.debug(`Moved
|
|
722
|
+
this.log.debug(`Moved from state ${P2PClientState[oldState]} to ${P2PClientState[this.currentState]}`);
|
|
714
723
|
}
|
|
715
724
|
|
|
716
725
|
private async publishStoredTxs() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type BlockAttestation } from '@aztec/circuit-types';
|
|
2
|
-
import {
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
3
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
4
4
|
|
|
5
5
|
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
@@ -10,7 +10,7 @@ export class InMemoryAttestationPool implements AttestationPool {
|
|
|
10
10
|
|
|
11
11
|
private attestations: Map</*slot=*/ bigint, Map</*proposalId*/ string, Map</*address=*/ string, BlockAttestation>>>;
|
|
12
12
|
|
|
13
|
-
constructor(telemetry: TelemetryClient, private log =
|
|
13
|
+
constructor(telemetry: TelemetryClient, private log = createLogger('p2p:attestation_pool')) {
|
|
14
14
|
this.attestations = new Map();
|
|
15
15
|
this.metrics = new PoolInstrumentation(telemetry, PoolName.ATTESTATION_POOL);
|
|
16
16
|
}
|
|
@@ -72,32 +72,12 @@ export class PoolInstrumentation<PoolObject extends Gossipable> {
|
|
|
72
72
|
this.objectSize = meter.createHistogram(metricsLabels.objectSize, {
|
|
73
73
|
unit: 'By',
|
|
74
74
|
description: 'The size of transactions in the mempool',
|
|
75
|
-
advice: {
|
|
76
|
-
explicitBucketBoundaries: [
|
|
77
|
-
5_000, // 5KB
|
|
78
|
-
10_000,
|
|
79
|
-
20_000,
|
|
80
|
-
50_000,
|
|
81
|
-
75_000,
|
|
82
|
-
100_000, // 100KB
|
|
83
|
-
200_000,
|
|
84
|
-
],
|
|
85
|
-
},
|
|
86
75
|
});
|
|
87
76
|
|
|
88
77
|
this.dbMetrics = new LmdbMetrics(
|
|
89
78
|
meter,
|
|
90
79
|
{
|
|
91
|
-
|
|
92
|
-
description: 'Database map size for the Tx mempool',
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
name: Metrics.MEMPOOL_DB_USED_SIZE,
|
|
96
|
-
description: 'Database used size for the Tx mempool',
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: Metrics.MEMPOOL_DB_NUM_ITEMS,
|
|
100
|
-
description: 'Num items in database for the Tx mempool',
|
|
80
|
+
[Attributes.DB_DATA_TYPE]: 'tx-pool',
|
|
101
81
|
},
|
|
102
82
|
dbStats,
|
|
103
83
|
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Tx, TxHash } from '@aztec/circuit-types';
|
|
2
2
|
import { type TxAddedToPoolStats } from '@aztec/circuit-types/stats';
|
|
3
|
-
import { type Logger,
|
|
3
|
+
import { type Logger, createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { type AztecKVStore, type AztecMap, type AztecSet } from '@aztec/kv-store';
|
|
5
5
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
6
6
|
|
|
@@ -30,7 +30,7 @@ export class AztecKVTxPool implements TxPool {
|
|
|
30
30
|
* @param store - A KV store.
|
|
31
31
|
* @param log - A logger.
|
|
32
32
|
*/
|
|
33
|
-
constructor(store: AztecKVStore, telemetry: TelemetryClient, log =
|
|
33
|
+
constructor(store: AztecKVStore, telemetry: TelemetryClient, log = createLogger('p2p:tx_pool')) {
|
|
34
34
|
this.#txs = store.openMap('txs');
|
|
35
35
|
this.#minedTxs = store.openMap('minedTxs');
|
|
36
36
|
this.#pendingTxs = store.openSet('pendingTxs');
|
|
@@ -125,7 +125,7 @@ export class AztecKVTxPool implements TxPool {
|
|
|
125
125
|
let pendingCount = 0;
|
|
126
126
|
for (const [i, tx] of txs.entries()) {
|
|
127
127
|
const txHash = txHashes[i];
|
|
128
|
-
this.#log.
|
|
128
|
+
this.#log.verbose(`Adding tx ${txHash.toString()} to pool`, {
|
|
129
129
|
eventName: 'tx-added-to-pool',
|
|
130
130
|
...tx.getStats(),
|
|
131
131
|
} satisfies TxAddedToPoolStats);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Tx, TxHash } from '@aztec/circuit-types';
|
|
2
2
|
import { type TxAddedToPoolStats } from '@aztec/circuit-types/stats';
|
|
3
|
-
import {
|
|
3
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
4
4
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
5
5
|
|
|
6
6
|
import { PoolInstrumentation, PoolName } from '../instrumentation.js';
|
|
@@ -23,7 +23,7 @@ export class InMemoryTxPool implements TxPool {
|
|
|
23
23
|
* Class constructor for in-memory TxPool. Initiates our transaction pool as a JS Map.
|
|
24
24
|
* @param log - A logger.
|
|
25
25
|
*/
|
|
26
|
-
constructor(telemetry: TelemetryClient, private log =
|
|
26
|
+
constructor(telemetry: TelemetryClient, private log = createLogger('p2p:tx_pool')) {
|
|
27
27
|
this.txs = new Map<bigint, Tx>();
|
|
28
28
|
this.minedTxs = new Map();
|
|
29
29
|
this.pendingTxs = new Set();
|
|
@@ -105,7 +105,7 @@ export class InMemoryTxPool implements TxPool {
|
|
|
105
105
|
let pending = 0;
|
|
106
106
|
for (const tx of txs) {
|
|
107
107
|
const txHash = tx.getTxHash();
|
|
108
|
-
this.log.
|
|
108
|
+
this.log.verbose(`Adding tx ${txHash.toString()} to pool`, {
|
|
109
109
|
eventName: 'tx-added-to-pool',
|
|
110
110
|
...tx.getStats(),
|
|
111
111
|
} satisfies TxAddedToPoolStats);
|
package/src/mocks/index.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
type WorldStateSynchronizer,
|
|
6
6
|
} from '@aztec/circuit-types';
|
|
7
7
|
import { type DataStoreConfig } from '@aztec/kv-store/config';
|
|
8
|
-
import { openTmpStore } from '@aztec/kv-store/
|
|
8
|
+
import { openTmpStore } from '@aztec/kv-store/lmdb';
|
|
9
9
|
import { type TelemetryClient } from '@aztec/telemetry-client';
|
|
10
10
|
import { NoopTelemetryClient } from '@aztec/telemetry-client/noop';
|
|
11
11
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
2
2
|
import { sleep } from '@aztec/foundation/sleep';
|
|
3
3
|
import { OtelMetricsAdapter, type TelemetryClient } from '@aztec/telemetry-client';
|
|
4
4
|
|
|
5
5
|
import { Discv5, type Discv5EventEmitter } from '@chainsafe/discv5';
|
|
6
6
|
import { ENR, SignableENR } from '@chainsafe/enr';
|
|
7
7
|
import type { PeerId } from '@libp2p/interface';
|
|
8
|
-
import { multiaddr } from '@multiformats/multiaddr';
|
|
8
|
+
import { type Multiaddr, multiaddr } from '@multiformats/multiaddr';
|
|
9
9
|
import EventEmitter from 'events';
|
|
10
10
|
|
|
11
11
|
import type { P2PConfig } from '../config.js';
|
|
@@ -35,6 +35,9 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
35
35
|
/** This instance's ENR */
|
|
36
36
|
private enr: SignableENR;
|
|
37
37
|
|
|
38
|
+
/** UDP listen addr */
|
|
39
|
+
private listenMultiAddrUdp: Multiaddr;
|
|
40
|
+
|
|
38
41
|
private currentState = PeerDiscoveryState.STOPPED;
|
|
39
42
|
|
|
40
43
|
private bootstrapNodes: string[];
|
|
@@ -46,7 +49,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
46
49
|
private peerId: PeerId,
|
|
47
50
|
config: P2PConfig,
|
|
48
51
|
telemetry: TelemetryClient,
|
|
49
|
-
private logger =
|
|
52
|
+
private logger = createLogger('p2p:discv5_service'),
|
|
50
53
|
) {
|
|
51
54
|
super();
|
|
52
55
|
const { tcpAnnounceAddress, udpAnnounceAddress, udpListenAddress, bootstrapNodes } = config;
|
|
@@ -66,7 +69,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
66
69
|
`${convertToMultiaddr(udpAnnounceAddress || tcpAnnounceAddress, 'udp')}/p2p/${peerId.toString()}`,
|
|
67
70
|
);
|
|
68
71
|
|
|
69
|
-
|
|
72
|
+
this.listenMultiAddrUdp = multiaddr(convertToMultiaddr(udpListenAddress, 'udp'));
|
|
70
73
|
|
|
71
74
|
// set location multiaddr in ENR record
|
|
72
75
|
this.enr.setLocationMultiaddr(multiAddrUdp);
|
|
@@ -76,7 +79,7 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
76
79
|
this.discv5 = Discv5.create({
|
|
77
80
|
enr: this.enr,
|
|
78
81
|
peerId,
|
|
79
|
-
bindAddrs: { ip4: listenMultiAddrUdp },
|
|
82
|
+
bindAddrs: { ip4: this.listenMultiAddrUdp },
|
|
80
83
|
config: {
|
|
81
84
|
lookupTimeout: 2000,
|
|
82
85
|
requestTimeout: 2000,
|
|
@@ -85,14 +88,11 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
85
88
|
metricsRegistry,
|
|
86
89
|
});
|
|
87
90
|
|
|
88
|
-
this.logger.info(`ENR NodeId: ${this.enr.nodeId}`);
|
|
89
|
-
this.logger.info(`ENR UDP: ${multiAddrUdp.toString()}`);
|
|
90
|
-
|
|
91
91
|
(this.discv5 as Discv5EventEmitter).on('discovered', (enr: ENR) => this.onDiscovered(enr));
|
|
92
92
|
(this.discv5 as Discv5EventEmitter).on('enrAdded', async (enr: ENR) => {
|
|
93
93
|
const multiAddrTcp = await enr.getFullMultiaddr('tcp');
|
|
94
94
|
const multiAddrUdp = await enr.getFullMultiaddr('udp');
|
|
95
|
-
this.logger.debug(`ENR
|
|
95
|
+
this.logger.debug(`Added ENR ${enr.encodeTxt()}`, { multiAddrTcp, multiAddrUdp, nodeId: enr.nodeId });
|
|
96
96
|
this.onDiscovered(enr);
|
|
97
97
|
});
|
|
98
98
|
}
|
|
@@ -101,18 +101,23 @@ export class DiscV5Service extends EventEmitter implements PeerDiscoveryService
|
|
|
101
101
|
if (this.currentState === PeerDiscoveryState.RUNNING) {
|
|
102
102
|
throw new Error('DiscV5Service already started');
|
|
103
103
|
}
|
|
104
|
-
this.logger.
|
|
104
|
+
this.logger.debug('Starting DiscV5');
|
|
105
105
|
await this.discv5.start();
|
|
106
106
|
this.startTime = Date.now();
|
|
107
107
|
|
|
108
|
-
this.logger.info(
|
|
108
|
+
this.logger.info(`DiscV5 service started`, {
|
|
109
|
+
nodeId: this.enr.nodeId,
|
|
110
|
+
peerId: this.peerId,
|
|
111
|
+
enrUdp: await this.enr.getFullMultiaddr('udp'),
|
|
112
|
+
enrTcp: await this.enr.getFullMultiaddr('tcp'),
|
|
113
|
+
});
|
|
109
114
|
this.currentState = PeerDiscoveryState.RUNNING;
|
|
110
115
|
|
|
111
116
|
// Add bootnode ENR if provided
|
|
112
117
|
if (this.bootstrapNodes?.length) {
|
|
113
118
|
// Do this conversion once since it involves an async function call
|
|
114
119
|
this.bootstrapNodePeerIds = await Promise.all(this.bootstrapNodes.map(enr => ENR.decodeTxt(enr).peerId()));
|
|
115
|
-
this.logger.info(`Adding bootstrap ENRs: ${this.bootstrapNodes.join(', ')}`);
|
|
120
|
+
this.logger.info(`Adding bootstrap nodes ENRs: ${this.bootstrapNodes.join(', ')}`);
|
|
116
121
|
try {
|
|
117
122
|
this.bootstrapNodes.forEach(enr => {
|
|
118
123
|
this.discv5.addEnr(enr);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlockAttestation, BlockProposal, Gossipable, TxHash } from '@aztec/circuit-types';
|
|
1
|
+
import type { BlockAttestation, BlockProposal, Gossipable, PeerInfo, TxHash } from '@aztec/circuit-types';
|
|
2
2
|
|
|
3
3
|
import type { PeerId } from '@libp2p/interface';
|
|
4
4
|
import EventEmitter from 'events';
|
|
@@ -10,6 +10,11 @@ import { type P2PService, type PeerDiscoveryService, PeerDiscoveryState } from '
|
|
|
10
10
|
* A dummy implementation of the P2P Service.
|
|
11
11
|
*/
|
|
12
12
|
export class DummyP2PService implements P2PService {
|
|
13
|
+
/** Returns an empty array for peers. */
|
|
14
|
+
getPeers(): PeerInfo[] {
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
|
|
13
18
|
/**
|
|
14
19
|
* Starts the dummy implementation.
|
|
15
20
|
* @returns A resolved promise.
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type Gossipable,
|
|
7
7
|
type L2BlockSource,
|
|
8
8
|
MerkleTreeId,
|
|
9
|
+
type PeerInfo,
|
|
9
10
|
type RawGossipMessage,
|
|
10
11
|
TopicType,
|
|
11
12
|
TopicTypeMap,
|
|
@@ -15,7 +16,7 @@ import {
|
|
|
15
16
|
metricsTopicStrToLabels,
|
|
16
17
|
} from '@aztec/circuit-types';
|
|
17
18
|
import { Fr } from '@aztec/circuits.js';
|
|
18
|
-
import {
|
|
19
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
19
20
|
import { SerialQueue } from '@aztec/foundation/queue';
|
|
20
21
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
21
22
|
import type { AztecKVStore } from '@aztec/kv-store';
|
|
@@ -88,7 +89,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
88
89
|
private worldStateSynchronizer: WorldStateSynchronizer,
|
|
89
90
|
private telemetry: TelemetryClient,
|
|
90
91
|
private requestResponseHandlers: ReqRespSubProtocolHandlers = DEFAULT_SUB_PROTOCOL_HANDLERS,
|
|
91
|
-
private logger =
|
|
92
|
+
private logger = createLogger('p2p:libp2p_service'),
|
|
92
93
|
) {
|
|
93
94
|
super(telemetry, 'LibP2PService');
|
|
94
95
|
|
|
@@ -117,20 +118,17 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
117
118
|
throw new Error('P2P service already started');
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
//
|
|
121
|
+
// Get listen & announce addresses for logging
|
|
121
122
|
const { tcpListenAddress, tcpAnnounceAddress } = this.config;
|
|
122
|
-
this.logger.info(`Starting P2P node on ${tcpListenAddress}`);
|
|
123
123
|
if (!tcpAnnounceAddress) {
|
|
124
124
|
throw new Error('Announce address not provided.');
|
|
125
125
|
}
|
|
126
126
|
const announceTcpMultiaddr = convertToMultiaddr(tcpAnnounceAddress, 'tcp');
|
|
127
|
-
this.logger.info(`Announcing at ${announceTcpMultiaddr}`);
|
|
128
127
|
|
|
129
128
|
// Start job queue, peer discovery service and libp2p node
|
|
130
129
|
this.jobQueue.start();
|
|
131
130
|
await this.peerDiscoveryService.start();
|
|
132
131
|
await this.node.start();
|
|
133
|
-
this.logger.info(`Started P2P client with Peer ID ${this.node.peerId.toString()}`);
|
|
134
132
|
|
|
135
133
|
// Subscribe to standard GossipSub topics by default
|
|
136
134
|
for (const topic in TopicType) {
|
|
@@ -157,6 +155,11 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
157
155
|
[TX_REQ_PROTOCOL]: this.validateRequestedTx.bind(this),
|
|
158
156
|
};
|
|
159
157
|
await this.reqresp.start(this.requestResponseHandlers, reqrespSubProtocolValidators);
|
|
158
|
+
this.logger.info(`Started P2P service`, {
|
|
159
|
+
listen: tcpListenAddress,
|
|
160
|
+
announce: announceTcpMultiaddr,
|
|
161
|
+
peerId: this.node.peerId.toString(),
|
|
162
|
+
});
|
|
160
163
|
}
|
|
161
164
|
|
|
162
165
|
/**
|
|
@@ -175,7 +178,6 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
175
178
|
this.logger.debug('Stopping LibP2P...');
|
|
176
179
|
await this.stopLibP2P();
|
|
177
180
|
this.logger.info('LibP2P service stopped');
|
|
178
|
-
this.logger.debug('Stopping request response service...');
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
/**
|
|
@@ -309,6 +311,10 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
309
311
|
);
|
|
310
312
|
}
|
|
311
313
|
|
|
314
|
+
public getPeers(includePending?: boolean): PeerInfo[] {
|
|
315
|
+
return this.peerManager.getPeers(includePending);
|
|
316
|
+
}
|
|
317
|
+
|
|
312
318
|
/**
|
|
313
319
|
* Send Request via the ReqResp service
|
|
314
320
|
* The subprotocol defined will determine the request and response types
|
|
@@ -583,10 +589,10 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
583
589
|
const parent = message.constructor as typeof Gossipable;
|
|
584
590
|
|
|
585
591
|
const identifier = message.p2pMessageIdentifier().toString();
|
|
586
|
-
this.logger.
|
|
592
|
+
this.logger.trace(`Sending message ${identifier}`);
|
|
587
593
|
|
|
588
594
|
const recipientsNum = await this.publishToTopic(parent.p2pTopic, message.toBuffer());
|
|
589
|
-
this.logger.
|
|
595
|
+
this.logger.debug(`Sent message ${identifier} to ${recipientsNum} peers`);
|
|
590
596
|
}
|
|
591
597
|
|
|
592
598
|
// Libp2p seems to hang sometimes if new peers are initiating connections.
|
|
@@ -597,7 +603,7 @@ export class LibP2PService extends WithTracer implements P2PService {
|
|
|
597
603
|
});
|
|
598
604
|
try {
|
|
599
605
|
await Promise.race([this.node.stop(), timeout]);
|
|
600
|
-
this.logger.debug('
|
|
606
|
+
this.logger.debug('LibP2P stopped');
|
|
601
607
|
} catch (error) {
|
|
602
608
|
this.logger.error('Error during stop or timeout:', error);
|
|
603
609
|
}
|