Skip to content

Commit b2efce5

Browse files
feat(filter): enhancing protocol peer management with mutex locks (#2137)
* chore: improvements * chore: add logs for subscription maintenance * chore: update logging * chore: trimming down BaseProtocolCore * chore: track peers in a hashmap instead of array * chore: peer mgmt responds to conenction/disconnection and improve logging * feat: add mutex locks to tackle race conditions over shared state * fix: build * chore: some mutex lock-release improvements * feat: peer manager * chore: rm tests for remove internal util * chore: update HealthManager updates * chore: update tests * rm: only * fix: hasPeers management * chore: add modularity to getting connected peers * chore: improve logs & add debug * chore: renewal doesnt disconnect, only removes * chore: await for sequential operations * chore: add TODO * chore: minor improvements * chore: fix rebase * chore: update playright * chore: remove additional arg * chore: update interafce * feat(peer-manager): unit tests * chore: improve hasPeers() * chore: update lockfile * feat: Filter reacts to peer:disconnect event, add tests * chore: fix lock * chore: update playright * chore: update protocol health for lightpush * chore: remove .only * chore: address comments and improvements * fix: tsconfig
1 parent 75fcca4 commit b2efce5

File tree

23 files changed

+4924
-3882
lines changed

23 files changed

+4924
-3882
lines changed

.github/workflows/playwright.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
timeout-minutes: 60
2121
runs-on: ubuntu-latest
2222
container:
23-
image: mcr.microsoft.com/playwright:v1.46.0-jammy
23+
image: mcr.microsoft.com/playwright:v1.48.0-jammy
2424
steps:
2525
- uses: actions/checkout@v3
2626
- uses: actions/setup-node@v3

package-lock.json

Lines changed: 4405 additions & 3151 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/core/src/lib/base_protocol.ts

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
import type { Libp2p } from "@libp2p/interface";
2-
import type { Peer, PeerStore, Stream } from "@libp2p/interface";
2+
import type { Peer, Stream } from "@libp2p/interface";
33
import type {
44
IBaseProtocolCore,
55
Libp2pComponents,
66
PubsubTopic
77
} from "@waku/interfaces";
8-
import { Logger, pubsubTopicsToShardInfo } from "@waku/utils";
9-
import {
10-
getConnectedPeersForProtocolAndShard,
11-
getPeersForProtocol,
12-
sortPeersByLatency
13-
} from "@waku/utils/libp2p";
8+
import { Logger } from "@waku/utils";
9+
import { getPeersForProtocol, sortPeersByLatency } from "@waku/utils/libp2p";
1410

1511
import { filterPeersByDiscovery } from "./filterPeers.js";
1612
import { StreamManager } from "./stream_manager/index.js";
@@ -26,7 +22,7 @@ export class BaseProtocol implements IBaseProtocolCore {
2622

2723
protected constructor(
2824
public multicodec: string,
29-
private components: Libp2pComponents,
25+
protected components: Libp2pComponents,
3026
private log: Logger,
3127
public readonly pubsubTopics: PubsubTopic[]
3228
) {
@@ -50,25 +46,22 @@ export class BaseProtocol implements IBaseProtocolCore {
5046
return this.streamManager.getStream(peer);
5147
}
5248

53-
public get peerStore(): PeerStore {
54-
return this.components.peerStore;
55-
}
56-
5749
/**
5850
* Returns known peers from the address book (`libp2p.peerStore`) that support
5951
* the class protocol. Waku may or may not be currently connected to these
6052
* peers.
6153
*/
6254
public async allPeers(): Promise<Peer[]> {
63-
return getPeersForProtocol(this.peerStore, [this.multicodec]);
55+
return getPeersForProtocol(this.components.peerStore, [this.multicodec]);
6456
}
6557

6658
public async connectedPeers(): Promise<Peer[]> {
6759
const peers = await this.allPeers();
6860
return peers.filter((peer) => {
69-
return (
70-
this.components.connectionManager.getConnections(peer.id).length > 0
61+
const connections = this.components.connectionManager.getConnections(
62+
peer.id
7163
);
64+
return connections.length > 0;
7265
});
7366
}
7467

@@ -77,9 +70,8 @@ export class BaseProtocol implements IBaseProtocolCore {
7770
*
7871
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned.
7972
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
80-
81-
* @returns A list of peers that support the protocol sorted by latency.
82-
*/
73+
* @returns A list of peers that support the protocol sorted by latency. By default, returns all peers available, including bootstrap.
74+
*/
8375
public async getPeers(
8476
{
8577
numPeers,
@@ -88,29 +80,23 @@ export class BaseProtocol implements IBaseProtocolCore {
8880
numPeers: number;
8981
maxBootstrapPeers: number;
9082
} = {
91-
maxBootstrapPeers: 1,
83+
maxBootstrapPeers: 0,
9284
numPeers: 0
9385
}
9486
): Promise<Peer[]> {
9587
// Retrieve all connected peers that support the protocol & shard (if configured)
96-
const connectedPeersForProtocolAndShard =
97-
await getConnectedPeersForProtocolAndShard(
98-
this.components.connectionManager.getConnections(),
99-
this.peerStore,
100-
[this.multicodec],
101-
pubsubTopicsToShardInfo(this.pubsubTopics)
102-
);
88+
const allAvailableConnectedPeers = await this.connectedPeers();
10389

10490
// Filter the peers based on discovery & number of peers requested
10591
const filteredPeers = filterPeersByDiscovery(
106-
connectedPeersForProtocolAndShard,
92+
allAvailableConnectedPeers,
10793
numPeers,
10894
maxBootstrapPeers
10995
);
11096

11197
// Sort the peers by latency
11298
const sortedFilteredPeers = await sortPeersByLatency(
113-
this.peerStore,
99+
this.components.peerStore,
114100
filteredPeers
115101
);
116102

packages/core/src/lib/filter/index.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,11 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
301301
() => {
302302
log.info("Receiving pipe closed.");
303303
},
304-
(e) => {
305-
log.error("Error with receiving pipe", e);
304+
async (e) => {
305+
log.error(
306+
`Error with receiving pipe on peer:${connection.remotePeer.toString()} -- stream:${stream.id} -- protocol:${stream.protocol}: `,
307+
e
308+
);
306309
}
307310
);
308311
} catch (e) {

packages/core/src/lib/metadata/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class Metadata extends BaseProtocol implements IMetadata {
4545
pubsubTopicsToShardInfo(this.pubsubTopics)
4646
);
4747

48-
const peer = await this.peerStore.get(peerId);
48+
const peer = await this.libp2pComponents.peerStore.get(peerId);
4949
if (!peer) {
5050
return {
5151
shardInfo: null,

packages/discovery/src/peer-exchange/waku_peer_exchange.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
4747
numPeers: BigInt(numPeers)
4848
});
4949

50-
const peer = await this.peerStore.get(peerId);
50+
const peer = await this.components.peerStore.get(peerId);
5151
if (!peer) {
5252
return {
5353
peerInfos: null,

packages/interfaces/src/protocols.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Libp2p } from "@libp2p/interface";
22
import type { PeerId } from "@libp2p/interface";
3-
import type { Peer, PeerStore } from "@libp2p/interface";
3+
import type { Peer } from "@libp2p/interface";
44

55
import type { CreateLibp2pOptions } from "./libp2p.js";
66
import type { IDecodedMessage } from "./message.js";
@@ -16,7 +16,6 @@ export enum Protocols {
1616

1717
export type IBaseProtocolCore = {
1818
multicodec: string;
19-
peerStore: PeerStore;
2019
allPeers: () => Promise<Peer[]>;
2120
connectedPeers: () => Promise<Peer[]>;
2221
addLibp2pEventListener: Libp2p["addEventListener"];
@@ -25,7 +24,7 @@ export type IBaseProtocolCore = {
2524

2625
export type IBaseProtocolSDK = {
2726
readonly connectedPeers: Peer[];
28-
renewPeer: (peerToDisconnect: PeerId) => Promise<Peer>;
27+
renewPeer: (peerToDisconnect: PeerId) => Promise<Peer | undefined>;
2928
readonly numPeersToUse: number;
3029
};
3130

@@ -36,10 +35,6 @@ export type NetworkConfig = StaticSharding | AutoSharding;
3635
* Options for using LightPush and Filter
3736
*/
3837
export type ProtocolUseOptions = {
39-
/**
40-
* Optional flag to enable auto-retry with exponential backoff
41-
*/
42-
autoRetry?: boolean;
4338
/**
4439
* Optional flag to force using all available peers
4540
*/
@@ -48,14 +43,6 @@ export type ProtocolUseOptions = {
4843
* Optional maximum number of attempts for exponential backoff
4944
*/
5045
maxAttempts?: number;
51-
/**
52-
* Optional initial delay in milliseconds for exponential backoff
53-
*/
54-
initialDelay?: number;
55-
/**
56-
* Optional maximum delay in milliseconds for exponential backoff
57-
*/
58-
maxDelay?: number;
5946
};
6047

6148
export type ProtocolCreateOptions = {

packages/sdk/package.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
},
6262
"dependencies": {
6363
"@chainsafe/libp2p-noise": "^15.1.0",
64-
"@libp2p/bootstrap": "^10.1.2",
64+
"@libp2p/bootstrap": "^10",
6565
"@libp2p/identify": "^2.1.2",
6666
"@libp2p/mplex": "^10.1.2",
6767
"@libp2p/ping": "^1.1.2",
@@ -73,23 +73,24 @@
7373
"@waku/proto": "^0.0.8",
7474
"@waku/utils": "0.0.20",
7575
"@waku/message-hash": "0.1.16",
76+
"async-mutex": "^0.5.0",
7677
"libp2p": "^1.8.1"
7778
},
7879
"devDependencies": {
79-
"@types/mocha": "^10.0.6",
8080
"@types/chai": "^4.3.11",
8181
"@rollup/plugin-commonjs": "^25.0.7",
8282
"@rollup/plugin-json": "^6.0.0",
8383
"@rollup/plugin-node-resolve": "^15.2.3",
8484
"@rollup/plugin-replace": "^5.0.5",
85+
"@types/mocha": "^10.0.9",
8586
"@waku/build-utils": "*",
86-
"mocha": "^10.3.0",
87-
"sinon": "^18.0.0",
88-
"chai": "^4.3.10",
87+
"chai": "^5.1.1",
8988
"cspell": "^8.6.1",
9089
"interface-datastore": "^8.2.10",
90+
"mocha": "^10.7.3",
9191
"npm-run-all": "^4.1.5",
92-
"rollup": "^4.12.0"
92+
"rollup": "^4.12.0",
93+
"sinon": "^19.0.2"
9394
},
9495
"peerDependencies": {
9596
"@libp2p/bootstrap": "^10"
@@ -109,4 +110,4 @@
109110
"LICENSE",
110111
"README.md"
111112
]
112-
}
113+
}

0 commit comments

Comments
 (0)