New `peers` and `randomPeer` methods to return available peers

This commit is contained in:
Franck Royer 2021-07-12 13:11:43 +10:00
parent c5cb37ee49
commit d68ee3fb74
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
4 changed files with 55 additions and 13 deletions

View File

@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Keep alive feature that pings host regularly, reducing the chance of connections being dropped due to idle. - Keep alive feature that pings host regularly, reducing the chance of connections being dropped due to idle.
Can be disabled or default frequency (10s) can be changed when calling `Waku.create`. Can be disabled or default frequency (10s) can be changed when calling `Waku.create`.
- New `lib/utils` module for easy, dependency-less hex/bytes conversions. - New `lib/utils` module for easy, dependency-less hex/bytes conversions.
- New `peers` and `randomPeer` methods on `WakuStore` and `WakuLightPush` to have a better idea of available peers;
Note that it does not check whether Waku node is currently connected to said peers.
### Changed ### Changed
- **Breaking**: Auto select peer if none provided for store and light push protocols. - **Breaking**: Auto select peer if none provided for store and light push protocols.

View File

@ -5,14 +5,18 @@ import { Peer } from 'libp2p/src/peer-store';
* Returns a pseudo-random peer that supports the given protocol. * Returns a pseudo-random peer that supports the given protocol.
* Useful for protocols such as store and light push * Useful for protocols such as store and light push
*/ */
export function selectRandomPeer( export function selectRandomPeer(peers: Peer[]): Peer | undefined {
libp2p: Libp2p,
protocol: string
): Peer | undefined {
const allPeers = Array.from(libp2p.peerStore.peers.values());
const size = allPeers.length;
const peers = allPeers.filter((peer) => peer.protocols.includes(protocol));
if (peers.length === 0) return; if (peers.length === 0) return;
const index = Math.round(Math.random() * (size - 1));
return allPeers[index]; const index = Math.round(Math.random() * (peers.length - 1));
return peers[index];
}
/**
* Returns the list of peers that supports the given protocol.
*/
export function getPeersForProtocol(libp2p: Libp2p, protocol: string): Peer[] {
return Array.from(libp2p.peerStore.peers.values()).filter((peer) =>
peer.protocols.includes(protocol)
);
} }

View File

@ -2,10 +2,11 @@ import concat from 'it-concat';
import lp from 'it-length-prefixed'; import lp from 'it-length-prefixed';
import pipe from 'it-pipe'; import pipe from 'it-pipe';
import Libp2p from 'libp2p'; import Libp2p from 'libp2p';
import { Peer } from 'libp2p/src/peer-store';
import PeerId from 'peer-id'; import PeerId from 'peer-id';
import { PushResponse } from '../../proto/waku/v2/light_push'; import { PushResponse } from '../../proto/waku/v2/light_push';
import { selectRandomPeer } from '../select_peer'; import { getPeersForProtocol, selectRandomPeer } from '../select_peer';
import { WakuMessage } from '../waku_message'; import { WakuMessage } from '../waku_message';
import { DefaultPubsubTopic } from '../waku_relay'; import { DefaultPubsubTopic } from '../waku_relay';
@ -54,7 +55,7 @@ export class WakuLightPush {
peer = this.libp2p.peerStore.get(opts.peerId); peer = this.libp2p.peerStore.get(opts.peerId);
if (!peer) throw 'Peer is unknown'; if (!peer) throw 'Peer is unknown';
} else { } else {
peer = selectRandomPeer(this.libp2p, LightPushCodec); peer = this.randomPeer;
} }
if (!peer) throw 'No peer available'; if (!peer) throw 'No peer available';
if (!peer.protocols.includes(LightPushCodec)) if (!peer.protocols.includes(LightPushCodec))
@ -93,4 +94,21 @@ export class WakuLightPush {
} }
return null; return null;
} }
/**
* Returns known peers from the address book (`libp2p.peerStore`) that support
* light push protocol. Waku may or may not be currently connected to these peers.
*/
get peers(): Peer[] {
return getPeersForProtocol(this.libp2p, LightPushCodec);
}
/**
* Returns a random peer that supports light push protocol from the address
* book (`libp2p.peerStore`). Waku may or may not be currently connected to
* this peer.
*/
get randomPeer(): Peer | undefined {
return selectRandomPeer(this.peers);
}
} }

View File

@ -2,9 +2,10 @@ import concat from 'it-concat';
import lp from 'it-length-prefixed'; import lp from 'it-length-prefixed';
import pipe from 'it-pipe'; import pipe from 'it-pipe';
import Libp2p from 'libp2p'; import Libp2p from 'libp2p';
import { Peer } from 'libp2p/src/peer-store';
import PeerId from 'peer-id'; import PeerId from 'peer-id';
import { selectRandomPeer } from '../select_peer'; import { getPeersForProtocol, selectRandomPeer } from '../select_peer';
import { WakuMessage } from '../waku_message'; import { WakuMessage } from '../waku_message';
import { DefaultPubsubTopic } from '../waku_relay'; import { DefaultPubsubTopic } from '../waku_relay';
@ -76,7 +77,7 @@ export class WakuStore {
peer = this.libp2p.peerStore.get(opts.peerId); peer = this.libp2p.peerStore.get(opts.peerId);
if (!peer) throw 'Peer is unknown'; if (!peer) throw 'Peer is unknown';
} else { } else {
peer = selectRandomPeer(this.libp2p, StoreCodec); peer = this.randomPeer;
} }
if (!peer) throw 'No peer available'; if (!peer) throw 'No peer available';
if (!peer.protocols.includes(StoreCodec)) if (!peer.protocols.includes(StoreCodec))
@ -164,4 +165,21 @@ export class WakuStore {
} }
} }
} }
/**
* Returns known peers from the address book (`libp2p.peerStore`) that support
* store protocol. Waku may or may not be currently connected to these peers.
*/
get peers(): Peer[] {
return getPeersForProtocol(this.libp2p, StoreCodec);
}
/**
* Returns a random peer that supports store protocol from the address
* book (`libp2p.peerStore`). Waku may or may not be currently connected to
* this peer.
*/
get randomPeer(): Peer | undefined {
return selectRandomPeer(this.peers);
}
} }