2023-08-16 20:18:13 +05:30
|
|
|
import type { Libp2p } from "@libp2p/interface";
|
2024-01-15 16:12:01 -08:00
|
|
|
import type { Peer, PeerStore, Stream } from "@libp2p/interface";
|
2023-11-28 15:57:18 +05:30
|
|
|
import type {
|
2024-03-11 18:50:34 +05:30
|
|
|
IBaseProtocolCore,
|
2023-11-28 15:57:18 +05:30
|
|
|
Libp2pComponents,
|
2024-01-09 23:34:30 -08:00
|
|
|
ProtocolCreateOptions,
|
|
|
|
|
PubsubTopic
|
2023-11-28 15:57:18 +05:30
|
|
|
} from "@waku/interfaces";
|
2024-01-25 20:07:58 -08:00
|
|
|
import { ensureShardingConfigured, Logger } from "@waku/utils";
|
2024-01-02 15:49:31 +05:30
|
|
|
import {
|
2024-01-19 20:42:52 +05:30
|
|
|
getConnectedPeersForProtocolAndShard,
|
2024-01-02 15:49:31 +05:30
|
|
|
getPeersForProtocol,
|
2024-01-11 17:25:47 +05:30
|
|
|
sortPeersByLatency
|
2024-01-02 15:49:31 +05:30
|
|
|
} from "@waku/utils/libp2p";
|
2023-09-04 10:27:25 +05:30
|
|
|
|
2024-01-11 17:25:47 +05:30
|
|
|
import { filterPeersByDiscovery } from "./filterPeers.js";
|
2024-07-16 18:35:24 +02:00
|
|
|
import { StreamManager } from "./stream_manager/index.js";
|
2023-02-23 14:04:27 +11:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* A class with predefined helpers, to be used as a base to implement Waku
|
|
|
|
|
* Protocols.
|
|
|
|
|
*/
|
2024-03-11 18:50:34 +05:30
|
|
|
export class BaseProtocol implements IBaseProtocolCore {
|
2023-07-25 02:17:52 +02:00
|
|
|
public readonly addLibp2pEventListener: Libp2p["addEventListener"];
|
|
|
|
|
public readonly removeLibp2pEventListener: Libp2p["removeEventListener"];
|
2023-09-04 10:27:25 +05:30
|
|
|
protected streamManager: StreamManager;
|
2023-07-25 02:17:52 +02:00
|
|
|
|
2024-07-19 15:58:17 +05:30
|
|
|
protected constructor(
|
2023-08-11 15:14:02 +02:00
|
|
|
public multicodec: string,
|
2024-01-11 17:25:47 +05:30
|
|
|
private components: Libp2pComponents,
|
2024-01-19 20:42:52 +05:30
|
|
|
private log: Logger,
|
2024-03-11 18:50:34 +05:30
|
|
|
public readonly pubsubTopics: PubsubTopic[],
|
2024-01-19 20:42:52 +05:30
|
|
|
private options?: ProtocolCreateOptions
|
2023-08-11 15:14:02 +02:00
|
|
|
) {
|
2023-07-25 02:17:52 +02:00
|
|
|
this.addLibp2pEventListener = components.events.addEventListener.bind(
|
2023-08-16 20:18:13 +05:30
|
|
|
components.events
|
2023-07-25 02:17:52 +02:00
|
|
|
);
|
|
|
|
|
this.removeLibp2pEventListener = components.events.removeEventListener.bind(
|
2023-08-16 20:18:13 +05:30
|
|
|
components.events
|
2023-07-25 02:17:52 +02:00
|
|
|
);
|
2023-09-04 10:27:25 +05:30
|
|
|
|
|
|
|
|
this.streamManager = new StreamManager(
|
|
|
|
|
multicodec,
|
|
|
|
|
components.connectionManager.getConnections.bind(
|
|
|
|
|
components.connectionManager
|
|
|
|
|
),
|
|
|
|
|
this.addLibp2pEventListener
|
|
|
|
|
);
|
|
|
|
|
}
|
2024-07-16 18:35:24 +02:00
|
|
|
|
2023-09-04 10:27:25 +05:30
|
|
|
protected async getStream(peer: Peer): Promise<Stream> {
|
|
|
|
|
return this.streamManager.getStream(peer);
|
2023-07-25 02:17:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public get peerStore(): PeerStore {
|
|
|
|
|
return this.components.peerStore;
|
|
|
|
|
}
|
2023-02-23 14:04:27 +11:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns known peers from the address book (`libp2p.peerStore`) that support
|
|
|
|
|
* the class protocol. Waku may or may not be currently connected to these
|
|
|
|
|
* peers.
|
|
|
|
|
*/
|
2024-01-19 20:42:52 +05:30
|
|
|
public async allPeers(): Promise<Peer[]> {
|
2023-02-23 14:04:27 +11:00
|
|
|
return getPeersForProtocol(this.peerStore, [this.multicodec]);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-19 20:42:52 +05:30
|
|
|
public async connectedPeers(): Promise<Peer[]> {
|
|
|
|
|
const peers = await this.allPeers();
|
|
|
|
|
return peers.filter((peer) => {
|
|
|
|
|
return (
|
|
|
|
|
this.components.connectionManager.getConnections(peer.id).length > 0
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-07 13:15:49 +05:30
|
|
|
/**
|
2024-01-11 17:25:47 +05:30
|
|
|
* Retrieves a list of connected peers that support the protocol. The list is sorted by latency.
|
2023-09-07 13:15:49 +05:30
|
|
|
*
|
|
|
|
|
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned.
|
|
|
|
|
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
2024-01-15 16:12:01 -08:00
|
|
|
|
2024-01-11 17:25:47 +05:30
|
|
|
* @returns A list of peers that support the protocol sorted by latency.
|
|
|
|
|
*/
|
2024-07-19 15:58:17 +05:30
|
|
|
public async getPeers(
|
2023-09-07 13:15:49 +05:30
|
|
|
{
|
|
|
|
|
numPeers,
|
|
|
|
|
maxBootstrapPeers
|
|
|
|
|
}: {
|
|
|
|
|
numPeers: number;
|
|
|
|
|
maxBootstrapPeers: number;
|
|
|
|
|
} = {
|
|
|
|
|
maxBootstrapPeers: 1,
|
|
|
|
|
numPeers: 0
|
|
|
|
|
}
|
|
|
|
|
): Promise<Peer[]> {
|
2024-01-19 20:42:52 +05:30
|
|
|
// Retrieve all connected peers that support the protocol & shard (if configured)
|
|
|
|
|
const connectedPeersForProtocolAndShard =
|
|
|
|
|
await getConnectedPeersForProtocolAndShard(
|
|
|
|
|
this.components.connectionManager.getConnections(),
|
|
|
|
|
this.peerStore,
|
|
|
|
|
[this.multicodec],
|
|
|
|
|
this.options?.shardInfo
|
2024-01-18 00:37:25 -08:00
|
|
|
? ensureShardingConfigured(this.options.shardInfo).shardInfo
|
|
|
|
|
: undefined
|
2024-01-19 20:42:52 +05:30
|
|
|
);
|
2023-09-07 13:15:49 +05:30
|
|
|
|
2024-01-11 17:25:47 +05:30
|
|
|
// Filter the peers based on discovery & number of peers requested
|
2024-01-19 20:42:52 +05:30
|
|
|
const filteredPeers = filterPeersByDiscovery(
|
|
|
|
|
connectedPeersForProtocolAndShard,
|
2024-01-11 17:25:47 +05:30
|
|
|
numPeers,
|
|
|
|
|
maxBootstrapPeers
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Sort the peers by latency
|
|
|
|
|
const sortedFilteredPeers = await sortPeersByLatency(
|
|
|
|
|
this.peerStore,
|
|
|
|
|
filteredPeers
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (sortedFilteredPeers.length === 0) {
|
|
|
|
|
this.log.warn(
|
|
|
|
|
"No peers found. Ensure you have a connection to the network."
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-24 18:24:03 +05:30
|
|
|
if (sortedFilteredPeers.length < numPeers) {
|
|
|
|
|
this.log.warn(
|
|
|
|
|
`Only ${sortedFilteredPeers.length} peers found. Requested ${numPeers}.`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-11 17:25:47 +05:30
|
|
|
return sortedFilteredPeers;
|
2023-09-07 13:15:49 +05:30
|
|
|
}
|
2023-02-23 14:04:27 +11:00
|
|
|
}
|