mirror of
https://github.com/waku-org/js-waku.git
synced 2025-02-22 17:18:15 +00:00
Merge branch 'master' of github.com:waku-org/js-waku into feat/shard-peer-selection
This commit is contained in:
commit
62725c18ec
@ -1,13 +1,13 @@
|
||||
{
|
||||
"packages/utils": "0.0.13",
|
||||
"packages/proto": "0.0.5",
|
||||
"packages/interfaces": "0.0.20",
|
||||
"packages/message-hash": "0.1.9",
|
||||
"packages/enr": "0.0.19",
|
||||
"packages/peer-exchange": "0.0.18",
|
||||
"packages/core": "0.0.25",
|
||||
"packages/dns-discovery": "0.0.19",
|
||||
"packages/message-encryption": "0.0.23",
|
||||
"packages/relay": "0.0.8",
|
||||
"packages/sdk": "0.0.21"
|
||||
"packages/utils": "0.0.14",
|
||||
"packages/proto": "0.0.6",
|
||||
"packages/interfaces": "0.0.21",
|
||||
"packages/message-hash": "0.1.10",
|
||||
"packages/enr": "0.0.20",
|
||||
"packages/peer-exchange": "0.0.19",
|
||||
"packages/core": "0.0.26",
|
||||
"packages/dns-discovery": "0.0.20",
|
||||
"packages/message-encryption": "0.0.24",
|
||||
"packages/relay": "0.0.9",
|
||||
"packages/sdk": "0.0.22"
|
||||
}
|
||||
|
14
package-lock.json
generated
14
package-lock.json
generated
@ -10424,9 +10424,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fast-check": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.14.0.tgz",
|
||||
"integrity": "sha512-9Z0zqASzDNjXBox/ileV/fd+4P+V/f3o4shM6QawvcdLFh8yjPG4h5BrHUZ8yzY6amKGDTAmRMyb/JZqe+dCgw==",
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.15.0.tgz",
|
||||
"integrity": "sha512-iBz6c+EXL6+nI931x/sbZs1JYTZtLG6Cko0ouS8LRTikhDR7+wZk4TYzdRavlnByBs2G6+nuuJ7NYL9QplNt8Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@ -26602,6 +26602,7 @@
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"debug": "^4.3.4",
|
||||
"dockerode": "^3.3.5",
|
||||
"fast-check": "^3.15.0",
|
||||
"p-retry": "^6.1.0",
|
||||
"p-timeout": "^6.1.0",
|
||||
"portfinder": "^1.0.32",
|
||||
@ -30072,6 +30073,7 @@
|
||||
"datastore-core": "^9.2.6",
|
||||
"debug": "^4.3.4",
|
||||
"dockerode": "^3.3.5",
|
||||
"fast-check": "^3.15.0",
|
||||
"interface-datastore": "^8.2.5",
|
||||
"libp2p": "^0.46.14",
|
||||
"mocha": "^10.2.0",
|
||||
@ -33454,9 +33456,9 @@
|
||||
"version": "0.1.8"
|
||||
},
|
||||
"fast-check": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.14.0.tgz",
|
||||
"integrity": "sha512-9Z0zqASzDNjXBox/ileV/fd+4P+V/f3o4shM6QawvcdLFh8yjPG4h5BrHUZ8yzY6amKGDTAmRMyb/JZqe+dCgw==",
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-check/-/fast-check-3.15.0.tgz",
|
||||
"integrity": "sha512-iBz6c+EXL6+nI931x/sbZs1JYTZtLG6Cko0ouS8LRTikhDR7+wZk4TYzdRavlnByBs2G6+nuuJ7NYL9QplNt8Q==",
|
||||
"requires": {
|
||||
"pure-rand": "^6.0.0"
|
||||
}
|
||||
|
@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
|
||||
The file is maintained by [Release Please](https://github.com/googleapis/release-please) based on [Conventional Commits](https://www.conventionalcommits.org) specification,
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.0.26](https://github.com/waku-org/js-waku/compare/core-v0.0.25...core-v0.0.26) (2024-01-10)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697))
|
||||
* change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703))
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for autosharded pubsub topics ([2bc3735](https://github.com/waku-org/js-waku/commit/2bc3735e4dcf85f06b3dee542024d7f20a40fac2))
|
||||
* Add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697)) ([4cf2ffe](https://github.com/waku-org/js-waku/commit/4cf2ffefa75e0571805036b71644d2cdd4fe3192))
|
||||
* Metadata protocol ([#1732](https://github.com/waku-org/js-waku/issues/1732)) ([9ac2a3f](https://github.com/waku-org/js-waku/commit/9ac2a3f36352523b79fcd8f8a94bd6e0e109fc30))
|
||||
* Track node connection state ([#1719](https://github.com/waku-org/js-waku/issues/1719)) ([1d0e2ac](https://github.com/waku-org/js-waku/commit/1d0e2ace7fa5b44ab192505c7ebce01a7ce343e0))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* Change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703)) ([3166a51](https://github.com/waku-org/js-waku/commit/3166a5135e77583da4fa722ee2aa47c785854a38))
|
||||
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/enr bumped from ^0.0.19 to ^0.0.20
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
* @waku/proto bumped from 0.0.5 to 0.0.6
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
|
||||
## [0.0.25](https://github.com/waku-org/js-waku/compare/core-v0.0.24...core-v0.0.25) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/core",
|
||||
"version": "0.0.25",
|
||||
"version": "0.0.26",
|
||||
"description": "TypeScript implementation of the Waku v2 protocol",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -73,10 +73,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/enr": "^0.0.19",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/proto": "0.0.5",
|
||||
"@waku/utils": "0.0.13",
|
||||
"@waku/enr": "^0.0.20",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"@waku/proto": "0.0.6",
|
||||
"@waku/utils": "0.0.14",
|
||||
"debug": "^4.3.4",
|
||||
"it-all": "^3.0.4",
|
||||
"it-length-prefixed": "^9.0.1",
|
||||
|
@ -1,6 +1,5 @@
|
||||
import type { Libp2p } from "@libp2p/interface";
|
||||
import type { Stream } from "@libp2p/interface/connection";
|
||||
import type { PeerId } from "@libp2p/interface/peer-id";
|
||||
import { Peer, PeerStore } from "@libp2p/interface/peer-store";
|
||||
import type {
|
||||
IBaseProtocol,
|
||||
@ -9,14 +8,14 @@ import type {
|
||||
PubsubTopic
|
||||
} from "@waku/interfaces";
|
||||
import { DefaultPubsubTopic } from "@waku/interfaces";
|
||||
import { shardInfoToPubsubTopics } from "@waku/utils";
|
||||
import { Logger, shardInfoToPubsubTopics } from "@waku/utils";
|
||||
import {
|
||||
getConnectedPeersForProtocolAndShard,
|
||||
getPeersForProtocol,
|
||||
selectPeerForProtocol
|
||||
sortPeersByLatency
|
||||
} from "@waku/utils/libp2p";
|
||||
|
||||
import { filterPeers } from "./filterPeers.js";
|
||||
import { filterPeersByDiscovery } from "./filterPeers.js";
|
||||
import { StreamManager } from "./stream_manager.js";
|
||||
|
||||
/**
|
||||
@ -32,7 +31,8 @@ export class BaseProtocol implements IBaseProtocol {
|
||||
constructor(
|
||||
public multicodec: string,
|
||||
private components: Libp2pComponents,
|
||||
public options?: ProtocolCreateOptions
|
||||
private log: Logger,
|
||||
private options?: ProtocolCreateOptions
|
||||
) {
|
||||
this.pubsubTopics = this.initializePubsubTopic(options);
|
||||
|
||||
@ -77,22 +77,14 @@ export class BaseProtocol implements IBaseProtocol {
|
||||
});
|
||||
}
|
||||
|
||||
protected async getPeer(peerId?: PeerId): Promise<Peer> {
|
||||
const { peer } = await selectPeerForProtocol(
|
||||
this.peerStore,
|
||||
[this.multicodec],
|
||||
peerId
|
||||
);
|
||||
return peer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of connected peers based on the specified criteria.
|
||||
* Retrieves a list of connected peers that support the protocol. The list is sorted by latency.
|
||||
*
|
||||
* @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.
|
||||
* @returns A Promise that resolves to an array of peers based on the specified criteria.
|
||||
*/
|
||||
|
||||
* @returns A list of peers that support the protocol sorted by latency.
|
||||
*/
|
||||
protected async getPeers(
|
||||
{
|
||||
numPeers,
|
||||
@ -110,15 +102,30 @@ export class BaseProtocol implements IBaseProtocol {
|
||||
await getConnectedPeersForProtocolAndShard(
|
||||
this.components.connectionManager.getConnections(),
|
||||
this.peerStore,
|
||||
[this.multicodec]
|
||||
[this.multicodec],
|
||||
this.options?.shardInfo
|
||||
);
|
||||
|
||||
// Filter the peers based on the specified criteria
|
||||
return filterPeers(
|
||||
// Filter the peers based on discovery & number of peers requested
|
||||
const filteredPeers = filterPeersByDiscovery(
|
||||
connectedPeersForProtocolAndShard,
|
||||
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."
|
||||
);
|
||||
}
|
||||
|
||||
return sortedFilteredPeers;
|
||||
}
|
||||
|
||||
private initializePubsubTopic(
|
||||
|
@ -278,7 +278,7 @@ class Filter extends BaseProtocol implements IReceiver {
|
||||
}
|
||||
|
||||
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
||||
super(FilterCodecs.SUBSCRIBE, libp2p.components, options);
|
||||
super(FilterCodecs.SUBSCRIBE, libp2p.components, log, options);
|
||||
|
||||
libp2p.handle(FilterCodecs.PUSH, this.onRequest.bind(this)).catch((e) => {
|
||||
log.error("Failed to register ", FilterCodecs.PUSH, e);
|
||||
|
@ -4,9 +4,9 @@ import { createSecp256k1PeerId } from "@libp2p/peer-id-factory";
|
||||
import { Tags } from "@waku/interfaces";
|
||||
import { expect } from "chai";
|
||||
|
||||
import { filterPeers } from "./filterPeers.js";
|
||||
import { filterPeersByDiscovery } from "./filterPeers.js";
|
||||
|
||||
describe("filterPeers function", function () {
|
||||
describe("filterPeersByDiscovery function", function () {
|
||||
it("should return all peers when numPeers is 0", async function () {
|
||||
const peer1 = await createSecp256k1PeerId();
|
||||
const peer2 = await createSecp256k1PeerId();
|
||||
@ -27,7 +27,7 @@ describe("filterPeers function", function () {
|
||||
}
|
||||
] as unknown as Peer[];
|
||||
|
||||
const result = filterPeers(mockPeers, 0, 10);
|
||||
const result = filterPeersByDiscovery(mockPeers, 0, 10);
|
||||
expect(result.length).to.deep.equal(mockPeers.length);
|
||||
});
|
||||
|
||||
@ -56,7 +56,7 @@ describe("filterPeers function", function () {
|
||||
}
|
||||
] as unknown as Peer[];
|
||||
|
||||
const result = filterPeers(mockPeers, 0, 0);
|
||||
const result = filterPeersByDiscovery(mockPeers, 0, 0);
|
||||
|
||||
// result should have no bootstrap peers, and a total of 2 peers
|
||||
expect(result.length).to.equal(2);
|
||||
@ -95,7 +95,7 @@ describe("filterPeers function", function () {
|
||||
}
|
||||
] as unknown as Peer[];
|
||||
|
||||
const result = filterPeers(mockPeers, 0, 1);
|
||||
const result = filterPeersByDiscovery(mockPeers, 0, 1);
|
||||
|
||||
// result should have 1 bootstrap peers, and a total of 4 peers
|
||||
expect(result.length).to.equal(4);
|
||||
@ -134,7 +134,7 @@ describe("filterPeers function", function () {
|
||||
}
|
||||
] as unknown as Peer[];
|
||||
|
||||
const result = filterPeers(mockPeers, 5, 2);
|
||||
const result = filterPeersByDiscovery(mockPeers, 5, 2);
|
||||
|
||||
// check that result has at least 2 bootstrap peers and no more than 5 peers
|
||||
expect(result.length).to.be.at.least(2);
|
||||
|
@ -2,23 +2,31 @@ import { Peer } from "@libp2p/interface/peer-store";
|
||||
import { Tags } from "@waku/interfaces";
|
||||
|
||||
/**
|
||||
* Retrieves a list of peers based on the specified criteria.
|
||||
* Retrieves a list of peers based on the specified criteria:
|
||||
* 1. If numPeers is 0, return all peers
|
||||
* 2. Bootstrap peers are prioritized
|
||||
* 3. Non-bootstrap peers are randomly selected to fill up to numPeers
|
||||
*
|
||||
* @param peers - The list of peers to filter from.
|
||||
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned.
|
||||
* @param numPeers - The total number of peers to retrieve. If 0, all peers are returned, irrespective of `maxBootstrapPeers`.
|
||||
* @param maxBootstrapPeers - The maximum number of bootstrap peers to retrieve.
|
||||
* @returns A Promise that resolves to an array of peers based on the specified criteria.
|
||||
* @returns An array of peers based on the specified criteria.
|
||||
*/
|
||||
export function filterPeers(
|
||||
export function filterPeersByDiscovery(
|
||||
peers: Peer[],
|
||||
numPeers: number,
|
||||
maxBootstrapPeers: number
|
||||
): Peer[] {
|
||||
// Collect the bootstrap peers up to the specified maximum
|
||||
const bootstrapPeers = peers
|
||||
let bootstrapPeers = peers
|
||||
.filter((peer) => peer.tags.has(Tags.BOOTSTRAP))
|
||||
.slice(0, maxBootstrapPeers);
|
||||
|
||||
// If numPeers is less than the number of bootstrap peers, adjust the bootstrapPeers array
|
||||
if (numPeers > 0 && numPeers < bootstrapPeers.length) {
|
||||
bootstrapPeers = bootstrapPeers.slice(0, numPeers);
|
||||
}
|
||||
|
||||
// Collect non-bootstrap peers
|
||||
const nonBootstrapPeers = peers.filter(
|
||||
(peer) => !peer.tags.has(Tags.BOOTSTRAP)
|
||||
|
@ -46,7 +46,7 @@ class LightPush extends BaseProtocol implements ILightPush {
|
||||
private readonly NUM_PEERS_PROTOCOL = 1;
|
||||
|
||||
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
||||
super(LightPushCodec, libp2p.components, options);
|
||||
super(LightPushCodec, libp2p.components, log, options);
|
||||
}
|
||||
|
||||
private async preparePushMessage(
|
||||
|
@ -32,7 +32,7 @@ class Metadata extends BaseProtocol implements IMetadata {
|
||||
public shardInfo: ShardingParams,
|
||||
libp2p: Libp2pComponents
|
||||
) {
|
||||
super(MetadataCodec, libp2p.components, shardInfo && { shardInfo });
|
||||
super(MetadataCodec, libp2p.components, log, shardInfo && { shardInfo });
|
||||
this.libp2pComponents = libp2p;
|
||||
void libp2p.registrar.handle(MetadataCodec, (streamData) => {
|
||||
void this.onRequest(streamData);
|
||||
@ -75,7 +75,10 @@ class Metadata extends BaseProtocol implements IMetadata {
|
||||
async query(peerId: PeerId): Promise<ShardInfo> {
|
||||
const request = proto_metadata.WakuMetadataRequest.encode(this.shardInfo);
|
||||
|
||||
const peer = await this.getPeer(peerId);
|
||||
const peer = await this.peerStore.get(peerId);
|
||||
if (!peer) {
|
||||
throw new Error(`Peer ${peerId.toString()} not found`);
|
||||
}
|
||||
|
||||
const stream = await this.getStream(peer);
|
||||
|
||||
|
@ -76,7 +76,7 @@ class Store extends BaseProtocol implements IStore {
|
||||
private readonly NUM_PEERS_PROTOCOL = 1;
|
||||
|
||||
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
||||
super(StoreCodec, libp2p.components, options);
|
||||
super(StoreCodec, libp2p.components, log, options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,6 +46,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.13 to 0.0.14
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/enr bumped from 0.0.19 to 0.0.20
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
|
||||
## [0.0.19](https://github.com/waku-org/js-waku/compare/dns-discovery-v0.0.18...dns-discovery-v0.0.19) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/dns-discovery",
|
||||
"version": "0.0.19",
|
||||
"version": "0.0.20",
|
||||
"description": "DNS Peer Discovery (EIP-1459)",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -51,8 +51,8 @@
|
||||
"node": ">=18"
|
||||
},
|
||||
"dependencies": {
|
||||
"@waku/enr": "0.0.19",
|
||||
"@waku/utils": "0.0.13",
|
||||
"@waku/enr": "0.0.20",
|
||||
"@waku/utils": "0.0.14",
|
||||
"debug": "^4.3.4",
|
||||
"dns-query": "^0.11.2",
|
||||
"hi-base32": "^0.5.1",
|
||||
@ -67,7 +67,7 @@
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@types/chai": "^4.3.11",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"chai": "^4.3.10",
|
||||
"cspell": "^7.3.2",
|
||||
"mocha": "^10.2.0",
|
||||
|
@ -59,6 +59,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.16 to 0.0.17
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
|
||||
## [0.0.19](https://github.com/waku-org/js-waku/compare/enr-v0.0.18...enr-v0.0.19) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/enr",
|
||||
"version": "0.0.19",
|
||||
"version": "0.0.20",
|
||||
"description": "ENR (EIP-778) for Waku",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -56,7 +56,7 @@
|
||||
"@libp2p/peer-id": "^3.0.3",
|
||||
"@multiformats/multiaddr": "^12.0.0",
|
||||
"@noble/secp256k1": "^1.7.1",
|
||||
"@waku/utils": "0.0.13",
|
||||
"@waku/utils": "0.0.14",
|
||||
"debug": "^4.3.4",
|
||||
"js-sha3": "^0.9.2"
|
||||
},
|
||||
@ -68,7 +68,7 @@
|
||||
"@types/chai": "^4.3.11",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"chai": "^4.3.10",
|
||||
"cspell": "^7.3.2",
|
||||
"fast-check": "^3.14.0",
|
||||
|
@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file.
|
||||
The file is maintained by [Release Please](https://github.com/googleapis/release-please) based on [Conventional Commits](https://www.conventionalcommits.org) specification,
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.0.21](https://github.com/waku-org/js-waku/compare/interfaces-v0.0.20...interfaces-v0.0.21) (2024-01-10)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697))
|
||||
* change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703))
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for autosharded pubsub topics ([2bc3735](https://github.com/waku-org/js-waku/commit/2bc3735e4dcf85f06b3dee542024d7f20a40fac2))
|
||||
* Add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697)) ([4cf2ffe](https://github.com/waku-org/js-waku/commit/4cf2ffefa75e0571805036b71644d2cdd4fe3192))
|
||||
* Metadata protocol ([#1732](https://github.com/waku-org/js-waku/issues/1732)) ([9ac2a3f](https://github.com/waku-org/js-waku/commit/9ac2a3f36352523b79fcd8f8a94bd6e0e109fc30))
|
||||
* Track node connection state ([#1719](https://github.com/waku-org/js-waku/issues/1719)) ([1d0e2ac](https://github.com/waku-org/js-waku/commit/1d0e2ace7fa5b44ab192505c7ebce01a7ce343e0))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* Change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703)) ([3166a51](https://github.com/waku-org/js-waku/commit/3166a5135e77583da4fa722ee2aa47c785854a38))
|
||||
|
||||
## [0.0.20](https://github.com/waku-org/js-waku/compare/interfaces-v0.0.19...interfaces-v0.0.20) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/interfaces",
|
||||
"version": "0.0.20",
|
||||
"version": "0.0.21",
|
||||
"description": "Definition of Waku interfaces",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
|
@ -11,7 +11,7 @@ export interface IPeerExchange extends IBaseProtocol {
|
||||
|
||||
export interface PeerExchangeQueryParams {
|
||||
numPeers: number;
|
||||
peerId?: PeerId;
|
||||
peerId: PeerId;
|
||||
}
|
||||
|
||||
export interface PeerExchangeResponse {
|
||||
|
@ -68,6 +68,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
* @waku/interfaces bumped from 0.0.17 to 0.0.18
|
||||
* @waku/utils bumped from 0.0.10 to 0.0.11
|
||||
|
||||
## [0.0.24](https://github.com/waku-org/js-waku/compare/message-encryption-v0.0.23...message-encryption-v0.0.24) (2024-01-10)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697))
|
||||
* export crypto primitives ([#1728](https://github.com/waku-org/js-waku/issues/1728))
|
||||
* change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703))
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for autosharded pubsub topics ([2bc3735](https://github.com/waku-org/js-waku/commit/2bc3735e4dcf85f06b3dee542024d7f20a40fac2))
|
||||
* Add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697)) ([4cf2ffe](https://github.com/waku-org/js-waku/commit/4cf2ffefa75e0571805036b71644d2cdd4fe3192))
|
||||
* Export crypto primitives ([#1728](https://github.com/waku-org/js-waku/issues/1728)) ([7eb3375](https://github.com/waku-org/js-waku/commit/7eb3375f50265240096d70bd2814549c8156a0eb))
|
||||
* New `verifySignature` ([2f67a3b](https://github.com/waku-org/js-waku/commit/2f67a3baffc085d61b057f9fdb5ab404bfd70a1b))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* Change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703)) ([3166a51](https://github.com/waku-org/js-waku/commit/3166a5135e77583da4fa722ee2aa47c785854a38))
|
||||
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/core bumped from 0.0.25 to 0.0.26
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
* @waku/proto bumped from 0.0.5 to 0.0.6
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
|
||||
## [0.0.23](https://github.com/waku-org/js-waku/compare/message-encryption-v0.0.22...message-encryption-v0.0.23) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/message-encryption",
|
||||
"version": "0.0.23",
|
||||
"version": "0.0.24",
|
||||
"description": "Waku Message Payload Encryption",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -76,10 +76,10 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@noble/secp256k1": "^1.7.1",
|
||||
"@waku/core": "0.0.25",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/proto": "0.0.5",
|
||||
"@waku/utils": "0.0.13",
|
||||
"@waku/core": "0.0.26",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"@waku/proto": "0.0.6",
|
||||
"@waku/utils": "0.0.14",
|
||||
"debug": "^4.3.4",
|
||||
"js-sha3": "^0.9.2",
|
||||
"uint8arrays": "^5.0.0"
|
||||
|
@ -40,6 +40,14 @@
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.19 to 0.0.20
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
|
||||
## [0.1.8](https://github.com/waku-org/js-waku/compare/message-hash-v0.1.7...message-hash-v0.1.8) (2023-10-16)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/message-hash",
|
||||
"version": "0.1.9",
|
||||
"version": "0.1.10",
|
||||
"description": "TypeScript implementation of the Deterministic Message Hashing as specified in 14/WAKU2-MESSAGE",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -51,7 +51,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/utils": "0.0.13"
|
||||
"@waku/utils": "0.0.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
@ -61,7 +61,7 @@
|
||||
"@types/debug": "^4.1.12",
|
||||
"@types/mocha": "^10.0.1",
|
||||
"@waku/build-utils": "*",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"chai": "^4.3.10",
|
||||
"cspell": "^7.3.2",
|
||||
"fast-check": "^3.14.0",
|
||||
|
@ -64,6 +64,16 @@
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.14 to 0.0.15
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/core bumped from 0.0.25 to 0.0.26
|
||||
* @waku/enr bumped from 0.0.19 to 0.0.20
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
* @waku/proto bumped from 0.0.5 to 0.0.6
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
|
||||
## [0.0.18](https://github.com/waku-org/js-waku/compare/peer-exchange-v0.0.17...peer-exchange-v0.0.18) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/peer-exchange",
|
||||
"version": "0.0.18",
|
||||
"version": "0.0.19",
|
||||
"description": "Peer Exchange (https://rfc.vac.dev/spec/34/) protocol for Waku",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -49,11 +49,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@libp2p/interfaces": "^3.3.2",
|
||||
"@waku/core": "0.0.25",
|
||||
"@waku/enr": "0.0.19",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/proto": "0.0.5",
|
||||
"@waku/utils": "0.0.13",
|
||||
"@waku/core": "0.0.26",
|
||||
"@waku/enr": "0.0.20",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"@waku/proto": "0.0.6",
|
||||
"@waku/utils": "0.0.14",
|
||||
"debug": "^4.3.4",
|
||||
"it-all": "^3.0.4",
|
||||
"it-length-prefixed": "^9.0.1",
|
||||
|
@ -27,7 +27,7 @@ export class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
|
||||
* @param components - libp2p components
|
||||
*/
|
||||
constructor(components: Libp2pComponents) {
|
||||
super(PeerExchangeCodec, components);
|
||||
super(PeerExchangeCodec, components, log);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +42,10 @@ export class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
|
||||
numPeers: BigInt(numPeers)
|
||||
});
|
||||
|
||||
const peer = await this.getPeer(params.peerId);
|
||||
const peer = await this.peerStore.get(params.peerId);
|
||||
if (!peer) {
|
||||
throw new Error(`Peer ${params.peerId.toString()} not found`);
|
||||
}
|
||||
|
||||
const stream = await this.getStream(peer);
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## [0.0.6](https://github.com/waku-org/js-waku/compare/proto-v0.0.5...proto-v0.0.6) (2024-01-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Metadata protocol ([#1732](https://github.com/waku-org/js-waku/issues/1732)) ([9ac2a3f](https://github.com/waku-org/js-waku/commit/9ac2a3f36352523b79fcd8f8a94bd6e0e109fc30))
|
||||
|
||||
## [0.0.5](https://github.com/waku-org/js-waku/compare/proto-v0.0.4...proto-v0.0.5) (2023-05-26)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/proto",
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.6",
|
||||
"description": "Protobuf definitions for Waku",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
|
@ -25,6 +25,34 @@
|
||||
* @waku/interfaces bumped from 0.0.16 to 0.0.17
|
||||
* @waku/utils bumped from 0.0.9 to 0.0.10
|
||||
|
||||
## [0.0.9](https://github.com/waku-org/js-waku/compare/relay-v0.0.8...relay-v0.0.9) (2024-01-10)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697))
|
||||
* change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703))
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for autosharded pubsub topics ([2bc3735](https://github.com/waku-org/js-waku/commit/2bc3735e4dcf85f06b3dee542024d7f20a40fac2))
|
||||
* Add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697)) ([4cf2ffe](https://github.com/waku-org/js-waku/commit/4cf2ffefa75e0571805036b71644d2cdd4fe3192))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* Change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703)) ([3166a51](https://github.com/waku-org/js-waku/commit/3166a5135e77583da4fa722ee2aa47c785854a38))
|
||||
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/core bumped from 0.0.25 to 0.0.26
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
* @waku/proto bumped from 0.0.5 to 0.0.6
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
|
||||
## [0.0.8](https://github.com/waku-org/js-waku/compare/relay-v0.0.7...relay-v0.0.8) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/relay",
|
||||
"version": "0.0.8",
|
||||
"version": "0.0.9",
|
||||
"description": "Relay Protocol for Waku",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -51,10 +51,10 @@
|
||||
"dependencies": {
|
||||
"@chainsafe/libp2p-gossipsub": "^10.1.1",
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/core": "0.0.25",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/proto": "0.0.5",
|
||||
"@waku/utils": "0.0.13",
|
||||
"@waku/core": "0.0.26",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"@waku/proto": "0.0.6",
|
||||
"@waku/utils": "0.0.14",
|
||||
"chai": "^4.3.10",
|
||||
"debug": "^4.3.4",
|
||||
"fast-check": "^3.14.0"
|
||||
|
@ -47,6 +47,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
* @waku/interfaces bumped from 0.0.19 to 0.0.20
|
||||
* @waku/peer-exchange bumped from ^0.0.17 to ^0.0.18
|
||||
|
||||
## [0.0.22](https://github.com/waku-org/js-waku/compare/sdk-v0.0.21...sdk-v0.0.22) (2024-01-10)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697))
|
||||
* change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703))
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for autosharded pubsub topics ([2bc3735](https://github.com/waku-org/js-waku/commit/2bc3735e4dcf85f06b3dee542024d7f20a40fac2))
|
||||
* Add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697)) ([4cf2ffe](https://github.com/waku-org/js-waku/commit/4cf2ffefa75e0571805036b71644d2cdd4fe3192))
|
||||
* Metadata protocol ([#1732](https://github.com/waku-org/js-waku/issues/1732)) ([9ac2a3f](https://github.com/waku-org/js-waku/commit/9ac2a3f36352523b79fcd8f8a94bd6e0e109fc30))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* Change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703)) ([3166a51](https://github.com/waku-org/js-waku/commit/3166a5135e77583da4fa722ee2aa47c785854a38))
|
||||
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/utils bumped from 0.0.13 to 0.0.14
|
||||
* @waku/relay bumped from 0.0.8 to 0.0.9
|
||||
* @waku/core bumped from 0.0.25 to 0.0.26
|
||||
* @waku/dns-discovery bumped from 0.0.19 to 0.0.20
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
* @waku/peer-exchange bumped from ^0.0.18 to ^0.0.19
|
||||
|
||||
## [0.0.20](https://github.com/waku-org/js-waku/compare/sdk-v0.0.19...sdk-v0.0.20) (2023-10-16)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/sdk",
|
||||
"version": "0.0.21",
|
||||
"version": "0.0.22",
|
||||
"description": "A unified SDK for easy creation and management of js-waku nodes.",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -51,12 +51,12 @@
|
||||
"@chainsafe/libp2p-noise": "^13.0.4",
|
||||
"@libp2p/mplex": "^9.0.10",
|
||||
"@libp2p/websockets": "^7.0.5",
|
||||
"@waku/utils": "0.0.13",
|
||||
"@waku/relay": "0.0.8",
|
||||
"@waku/core": "0.0.25",
|
||||
"@waku/dns-discovery": "0.0.19",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/peer-exchange": "^0.0.18",
|
||||
"@waku/utils": "0.0.14",
|
||||
"@waku/relay": "0.0.9",
|
||||
"@waku/core": "0.0.26",
|
||||
"@waku/dns-discovery": "0.0.20",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"@waku/peer-exchange": "^0.0.19",
|
||||
"libp2p": "^0.46.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -60,6 +60,7 @@
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"debug": "^4.3.4",
|
||||
"dockerode": "^3.3.5",
|
||||
"fast-check": "^3.15.0",
|
||||
"p-retry": "^6.1.0",
|
||||
"p-timeout": "^6.1.0",
|
||||
"portfinder": "^1.0.32",
|
||||
|
@ -13,3 +13,4 @@ export * from "./node/node.js";
|
||||
export * from "./teardown.js";
|
||||
export * from "./message_collector.js";
|
||||
export * from "./utils.js";
|
||||
export * from "./waitForRemotePeerWithCodec.js";
|
||||
|
39
packages/tests/src/waitForRemotePeerWithCodec.ts
Normal file
39
packages/tests/src/waitForRemotePeerWithCodec.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import type { IdentifyResult } from "@libp2p/interface";
|
||||
import type { PeerId } from "@libp2p/interface/peer-id";
|
||||
import type { LightNode } from "@waku/interfaces";
|
||||
|
||||
/**
|
||||
* Wait for a remote peer to be identified with a given codec
|
||||
* @param waku - Waku node
|
||||
* @param codec - Codec to wait for
|
||||
* @returns Promise that resolves when the peer is identified
|
||||
* @internal
|
||||
* This function is introduced as `core/waitForRemotePeer` only accounts for core protocols like Filter, LightPush & Store
|
||||
* While this (currently) is not required by the SDK, it is required for the tests
|
||||
*/
|
||||
export async function waitForRemotePeerWithCodec(
|
||||
waku: LightNode,
|
||||
codec: string,
|
||||
nodePeerId: PeerId
|
||||
): Promise<void> {
|
||||
const connectedPeers = waku.libp2p
|
||||
.getConnections()
|
||||
.map((conn) => conn.remotePeer);
|
||||
if (
|
||||
connectedPeers.find((connectedPeer) => connectedPeer.equals(nodePeerId))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
const cb = (evt: CustomEvent<IdentifyResult>): void => {
|
||||
if (evt.detail.protocols.includes(codec)) {
|
||||
waku.libp2p.removeEventListener("peer:identify", cb);
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
waku.libp2p.addEventListener("peer:identify", cb);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
@ -1,13 +1,22 @@
|
||||
import type { Connection } from "@libp2p/interface/connection";
|
||||
import type { PeerStore } from "@libp2p/interface/peer-store";
|
||||
import type { Peer } from "@libp2p/interface/peer-store";
|
||||
import { createSecp256k1PeerId } from "@libp2p/peer-id-factory";
|
||||
import { LightPushCodec, waitForRemotePeer } from "@waku/core";
|
||||
import {
|
||||
createLightNode,
|
||||
Libp2pComponents,
|
||||
type LightNode,
|
||||
Protocols,
|
||||
ShardInfo
|
||||
ShardInfo,
|
||||
Tags,
|
||||
utf8ToBytes
|
||||
} from "@waku/sdk";
|
||||
import { shardInfoToPubsubTopics } from "@waku/utils";
|
||||
import { getConnectedPeersForProtocolAndShard } from "@waku/utils/libp2p";
|
||||
import { expect } from "chai";
|
||||
import fc from "fast-check";
|
||||
import Sinon from "sinon";
|
||||
|
||||
import { makeLogFileName } from "../src/log_file.js";
|
||||
import { NimGoNode } from "../src/node/node.js";
|
||||
@ -192,3 +201,317 @@ describe("getConnectedPeersForProtocolAndShard", function () {
|
||||
expect(peers.length).to.be.equal(1);
|
||||
});
|
||||
});
|
||||
describe("getPeers", function () {
|
||||
let peerStore: PeerStore;
|
||||
let connectionManager: Libp2pComponents["connectionManager"];
|
||||
let waku: LightNode;
|
||||
const lowPingBytes = utf8ToBytes("50");
|
||||
const midPingBytes = utf8ToBytes("100");
|
||||
const highPingBytes = utf8ToBytes("200");
|
||||
|
||||
let lowPingBootstrapPeer: Peer,
|
||||
lowPingNonBootstrapPeer: Peer,
|
||||
midPingBootstrapPeer: Peer,
|
||||
midPingNonBootstrapPeer: Peer,
|
||||
highPingBootstrapPeer: Peer,
|
||||
highPingNonBootstrapPeer: Peer,
|
||||
differentCodecPeer: Peer,
|
||||
anotherDifferentCodecPeer: Peer;
|
||||
|
||||
let bootstrapPeers: Peer[];
|
||||
let nonBootstrapPeers: Peer[];
|
||||
let allPeers: Peer[];
|
||||
|
||||
beforeEach(async function () {
|
||||
this.timeout(10_000);
|
||||
waku = await createLightNode();
|
||||
peerStore = waku.libp2p.peerStore;
|
||||
connectionManager = waku.libp2p.components.connectionManager;
|
||||
|
||||
const [
|
||||
lowPingBootstrapPeerId,
|
||||
lowPingNonBootstrapPeerId,
|
||||
midPingBootstrapPeerId,
|
||||
midPingNonBootstrapPeerId,
|
||||
highPingBootstrapPeerId,
|
||||
highPingNonBootstrapPeerId,
|
||||
differentCodecPeerId,
|
||||
anotherDifferentCodecPeerId
|
||||
] = await Promise.all([
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId()
|
||||
]);
|
||||
|
||||
lowPingBootstrapPeer = {
|
||||
id: lowPingBootstrapPeerId,
|
||||
protocols: [waku.lightPush.multicodec],
|
||||
metadata: new Map().set("ping", lowPingBytes),
|
||||
tags: new Map().set(Tags.BOOTSTRAP, {})
|
||||
} as Peer;
|
||||
lowPingNonBootstrapPeer = {
|
||||
id: lowPingNonBootstrapPeerId,
|
||||
protocols: [waku.lightPush.multicodec],
|
||||
metadata: new Map().set("ping", lowPingBytes),
|
||||
tags: new Map().set(Tags.PEER_EXCHANGE, {})
|
||||
} as Peer;
|
||||
midPingBootstrapPeer = {
|
||||
id: midPingBootstrapPeerId,
|
||||
protocols: [waku.lightPush.multicodec],
|
||||
metadata: new Map().set("ping", midPingBytes),
|
||||
tags: new Map().set(Tags.BOOTSTRAP, {})
|
||||
} as Peer;
|
||||
midPingNonBootstrapPeer = {
|
||||
id: midPingNonBootstrapPeerId,
|
||||
protocols: [waku.lightPush.multicodec],
|
||||
metadata: new Map().set("ping", midPingBytes),
|
||||
tags: new Map().set(Tags.PEER_EXCHANGE, {})
|
||||
} as Peer;
|
||||
highPingBootstrapPeer = {
|
||||
id: highPingBootstrapPeerId,
|
||||
protocols: [waku.lightPush.multicodec],
|
||||
metadata: new Map().set("ping", highPingBytes),
|
||||
tags: new Map().set(Tags.BOOTSTRAP, {})
|
||||
} as Peer;
|
||||
highPingNonBootstrapPeer = {
|
||||
id: highPingNonBootstrapPeerId,
|
||||
protocols: [waku.lightPush.multicodec],
|
||||
metadata: new Map().set("ping", highPingBytes),
|
||||
tags: new Map().set(Tags.PEER_EXCHANGE, {})
|
||||
} as Peer;
|
||||
differentCodecPeer = {
|
||||
id: differentCodecPeerId,
|
||||
protocols: ["different/1"],
|
||||
metadata: new Map().set("ping", lowPingBytes),
|
||||
tags: new Map().set(Tags.BOOTSTRAP, {})
|
||||
} as Peer;
|
||||
anotherDifferentCodecPeer = {
|
||||
id: anotherDifferentCodecPeerId,
|
||||
protocols: ["different/2"],
|
||||
metadata: new Map().set("ping", lowPingBytes),
|
||||
tags: new Map().set(Tags.BOOTSTRAP, {})
|
||||
} as Peer;
|
||||
|
||||
bootstrapPeers = [
|
||||
lowPingBootstrapPeer,
|
||||
midPingBootstrapPeer,
|
||||
highPingBootstrapPeer
|
||||
];
|
||||
|
||||
nonBootstrapPeers = [
|
||||
lowPingNonBootstrapPeer,
|
||||
midPingNonBootstrapPeer,
|
||||
highPingNonBootstrapPeer
|
||||
];
|
||||
|
||||
allPeers = [
|
||||
...bootstrapPeers,
|
||||
...nonBootstrapPeers,
|
||||
differentCodecPeer,
|
||||
anotherDifferentCodecPeer
|
||||
];
|
||||
|
||||
Sinon.stub(peerStore, "get").callsFake(async (peerId) => {
|
||||
return allPeers.find((peer) => peer.id.equals(peerId))!;
|
||||
});
|
||||
|
||||
Sinon.stub(peerStore, "forEach").callsFake(async (callback) => {
|
||||
for (const peer of allPeers) {
|
||||
callback(peer);
|
||||
}
|
||||
});
|
||||
|
||||
// assume all peers have an opened connection
|
||||
Sinon.stub(connectionManager, "getConnections").callsFake(() => {
|
||||
const connections: Connection[] = [];
|
||||
for (const peer of allPeers) {
|
||||
connections.push({
|
||||
status: "open",
|
||||
remotePeer: peer.id
|
||||
} as unknown as Connection);
|
||||
}
|
||||
return connections;
|
||||
});
|
||||
});
|
||||
|
||||
this.afterEach(function () {
|
||||
Sinon.restore();
|
||||
});
|
||||
|
||||
describe("getPeers with varying maxBootstrapPeers", function () {
|
||||
const maxBootstrapPeersValues = [1, 2, 3, 4, 5, 6, 7];
|
||||
|
||||
maxBootstrapPeersValues.forEach((maxBootstrapPeers) => {
|
||||
describe(`maxBootstrapPeers=${maxBootstrapPeers}`, function () {
|
||||
it(`numPeers=1 -- returns one bootstrap peer `, async function () {
|
||||
const result = (await (waku.lightPush as any).getPeers({
|
||||
numPeers: 1,
|
||||
maxBootstrapPeers
|
||||
})) as Peer[];
|
||||
|
||||
// Should only have 1 peer
|
||||
expect(result).to.have.lengthOf(1);
|
||||
|
||||
// The peer should be a bootstrap peer
|
||||
expect(result[0].tags.has(Tags.BOOTSTRAP)).to.be.true;
|
||||
|
||||
// Peer should be of the same protocol
|
||||
expect(result[0].protocols.includes(waku.lightPush.multicodec)).to.be
|
||||
.true;
|
||||
|
||||
// Peer should have the lowest ping
|
||||
expect(result[0].metadata.get("ping")).to.equal(lowPingBytes);
|
||||
});
|
||||
|
||||
it(`numPeers=2 -- returns total 2 peers, with max ${maxBootstrapPeers} bootstrap peers`, async function () {
|
||||
const result = (await (waku.lightPush as any).getPeers({
|
||||
numPeers: 2,
|
||||
maxBootstrapPeers
|
||||
})) as Peer[];
|
||||
|
||||
// Should only have 2 peers
|
||||
expect(result).to.have.lengthOf(2);
|
||||
|
||||
// Should only have ${maxBootstrapPeers} bootstrap peers
|
||||
expect(
|
||||
result.filter((peer: Peer) => peer.tags.has(Tags.BOOTSTRAP)).length
|
||||
).to.be.lessThanOrEqual(maxBootstrapPeers);
|
||||
|
||||
// Should return peers with the same protocol
|
||||
expect(
|
||||
result.every((peer: Peer) =>
|
||||
peer.protocols.includes(waku.lightPush.multicodec)
|
||||
)
|
||||
).to.be.true;
|
||||
|
||||
// All peers should be sorted by latency
|
||||
// 0th index should be the lowest ping of all peers returned
|
||||
expect(result[0].metadata.get("ping")).to.equal(lowPingBytes);
|
||||
});
|
||||
|
||||
it(`numPeers=3 -- returns total 3 peers, with max ${maxBootstrapPeers} bootstrap peers`, async function () {
|
||||
const result = (await (waku.lightPush as any).getPeers({
|
||||
numPeers: 3,
|
||||
maxBootstrapPeers
|
||||
})) as Peer[];
|
||||
|
||||
// Should only have 3 peers
|
||||
expect(result).to.have.lengthOf(3);
|
||||
|
||||
// Should only have ${maxBootstrapPeers} bootstrap peers
|
||||
expect(
|
||||
result.filter((peer: Peer) => peer.tags.has(Tags.BOOTSTRAP)).length
|
||||
).to.be.lessThanOrEqual(maxBootstrapPeers);
|
||||
|
||||
// Should return peers with the same protocol
|
||||
expect(
|
||||
result.every((peer: Peer) =>
|
||||
peer.protocols.includes(waku.lightPush.multicodec)
|
||||
)
|
||||
).to.be.true;
|
||||
|
||||
// All peers should be sorted by latency
|
||||
// 0th index should be the lowest ping of all peers returned
|
||||
expect(result[0].metadata.get("ping")).to.equal(lowPingBytes);
|
||||
});
|
||||
|
||||
it(`numPeers=4 -- returns total 4 peers, with max ${maxBootstrapPeers} bootstrap peers`, async function () {
|
||||
const result = (await (waku.lightPush as any).getPeers({
|
||||
numPeers: 4,
|
||||
maxBootstrapPeers
|
||||
})) as Peer[];
|
||||
|
||||
// Should only have 4 peers
|
||||
expect(result).to.have.lengthOf(4);
|
||||
|
||||
// Should only have ${maxBootstrapPeers} bootstrap peers
|
||||
expect(
|
||||
result.filter((peer: Peer) => peer.tags.has(Tags.BOOTSTRAP)).length
|
||||
).to.be.lessThanOrEqual(maxBootstrapPeers);
|
||||
|
||||
// Should return peers with the same protocol
|
||||
expect(
|
||||
result.every((peer: Peer) =>
|
||||
peer.protocols.includes(waku.lightPush.multicodec)
|
||||
)
|
||||
).to.be.true;
|
||||
|
||||
// All peers should be sorted by latency
|
||||
// 0th index should be the lowest ping of all peers returned
|
||||
expect(result[0].metadata.get("ping")).to.equal(lowPingBytes);
|
||||
});
|
||||
|
||||
it(`numPeers=0 -- returns all peers including all non-bootstrap with maxBootstrapPeers: ${maxBootstrapPeers}`, async function () {
|
||||
const result = (await (waku.lightPush as any).getPeers({
|
||||
numPeers: 0,
|
||||
maxBootstrapPeers
|
||||
})) as Peer[];
|
||||
|
||||
// Should have all non-bootstrap peers + ${maxBootstrapPeers} bootstrap peers
|
||||
// Unless bootstrapPeers.length < maxBootstrapPeers
|
||||
// Then it should be all non-bootstrap peers + bootstrapPeers.length
|
||||
if (maxBootstrapPeers > bootstrapPeers.length) {
|
||||
expect(result).to.have.lengthOf(
|
||||
nonBootstrapPeers.length + bootstrapPeers.length
|
||||
);
|
||||
} else {
|
||||
expect(result).to.have.lengthOf(
|
||||
nonBootstrapPeers.length + maxBootstrapPeers
|
||||
);
|
||||
}
|
||||
|
||||
// All peers should be bootstrap peers
|
||||
expect(
|
||||
result.filter((peer: Peer) => peer.tags.has(Tags.BOOTSTRAP)).length
|
||||
).to.be.lessThanOrEqual(maxBootstrapPeers);
|
||||
|
||||
// Peers should be of the same protocol
|
||||
expect(
|
||||
result.every((peer: Peer) =>
|
||||
peer.protocols.includes(waku.lightPush.multicodec)
|
||||
)
|
||||
).to.be.true;
|
||||
|
||||
// All peers returned should be sorted by latency
|
||||
// 0th index should be the lowest ping of all peers returned
|
||||
expect(result[0].metadata.get("ping")).to.equal(lowPingBytes);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("getPeers property-based tests", function () {
|
||||
it("should return the correct number of peers based on numPeers and maxBootstrapPeers", async function () {
|
||||
await fc.assert(
|
||||
fc.asyncProperty(
|
||||
//max bootstrap peers
|
||||
fc.integer({ min: 1, max: 100 }),
|
||||
//numPeers
|
||||
fc.integer({ min: 0, max: 100 }),
|
||||
async (maxBootstrapPeers, numPeers) => {
|
||||
const result = (await (waku.lightPush as any).getPeers({
|
||||
numPeers,
|
||||
maxBootstrapPeers
|
||||
})) as Peer[];
|
||||
|
||||
if (numPeers === 0) {
|
||||
// Expect all peers when numPeers is 0
|
||||
expect(result.length).to.be.greaterThanOrEqual(1);
|
||||
} else {
|
||||
// Expect up to numPeers peers
|
||||
expect(result.length).to.be.lessThanOrEqual(numPeers);
|
||||
}
|
||||
}
|
||||
),
|
||||
{
|
||||
verbose: true
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,6 @@
|
||||
import type { PeerId } from "@libp2p/interface/peer-id";
|
||||
import tests from "@libp2p/interface-compliance-tests/peer-discovery";
|
||||
import type { Multiaddr } from "@multiformats/multiaddr";
|
||||
import type { LightNode, PeerInfo } from "@waku/interfaces";
|
||||
import {
|
||||
PeerExchangeCodec,
|
||||
@ -9,7 +11,7 @@ import { createLightNode, Libp2pComponents } from "@waku/sdk";
|
||||
import { expect } from "chai";
|
||||
|
||||
import { delay } from "../src/delay.js";
|
||||
import { tearDownNodes } from "../src/index.js";
|
||||
import { tearDownNodes, waitForRemotePeerWithCodec } from "../src/index.js";
|
||||
import { makeLogFileName } from "../src/log_file.js";
|
||||
import { NimGoNode } from "../src/node/node.js";
|
||||
|
||||
@ -48,11 +50,13 @@ describe("Peer Exchange", () => {
|
||||
});
|
||||
|
||||
const nwaku1PeerId = await nwaku1.getPeerId();
|
||||
const nwaku2PeerId = await nwaku2.getPeerId();
|
||||
const nwaku2Ma = await nwaku2.getMultiaddrWithId();
|
||||
|
||||
waku = await createLightNode();
|
||||
await waku.start();
|
||||
await waku.libp2p.dialProtocol(nwaku2Ma, PeerExchangeCodec);
|
||||
await waitForRemotePeerWithCodec(waku, PeerExchangeCodec, nwaku2PeerId);
|
||||
|
||||
const components = waku.libp2p.components as unknown as Libp2pComponents;
|
||||
const peerExchange = new WakuPeerExchange(components);
|
||||
@ -62,6 +66,7 @@ describe("Peer Exchange", () => {
|
||||
let peerInfos: PeerInfo[] = [];
|
||||
while (peerInfos.length <= 0) {
|
||||
peerInfos = (await peerExchange.query({
|
||||
peerId: nwaku2PeerId,
|
||||
numPeers: numPeersToRequest
|
||||
})) as PeerInfo[];
|
||||
await delay(3000);
|
||||
@ -70,16 +75,35 @@ describe("Peer Exchange", () => {
|
||||
expect(peerInfos.length).to.be.greaterThan(0);
|
||||
expect(peerInfos.length).to.be.lessThanOrEqual(numPeersToRequest);
|
||||
expect(peerInfos[0].ENR).to.not.be.null;
|
||||
expect(peerInfos[0].ENR?.peerInfo?.multiaddrs).to.not.be.null;
|
||||
|
||||
const doesPeerIdExistInResponse =
|
||||
peerInfos.find(
|
||||
({ ENR }) => ENR?.peerInfo?.id.toString() === nwaku1PeerId.toString()
|
||||
) !== undefined;
|
||||
let foundNodeMultiaddrs: Multiaddr[] = [];
|
||||
let foundNodePeerId: PeerId | undefined = undefined;
|
||||
const doesPeerIdExistInResponse = peerInfos.some(({ ENR }) => {
|
||||
foundNodeMultiaddrs = ENR?.peerInfo?.multiaddrs ?? [];
|
||||
foundNodePeerId = ENR?.peerInfo?.id;
|
||||
return ENR?.peerInfo?.id.toString() === nwaku1PeerId.toString();
|
||||
});
|
||||
|
||||
if (!foundNodePeerId) {
|
||||
throw new Error("Peer ID not found");
|
||||
}
|
||||
|
||||
if (!foundNodePeerId) {
|
||||
throw new Error("Peer ID not found");
|
||||
}
|
||||
|
||||
expect(doesPeerIdExistInResponse).to.be.equal(true);
|
||||
|
||||
expect(await waku.libp2p.peerStore.has(await nwaku2.getPeerId())).to.be
|
||||
.true;
|
||||
await waku.libp2p.dialProtocol(foundNodeMultiaddrs, PeerExchangeCodec);
|
||||
await waitForRemotePeerWithCodec(
|
||||
waku,
|
||||
PeerExchangeCodec,
|
||||
foundNodePeerId
|
||||
);
|
||||
|
||||
expect(await waku.libp2p.peerStore.has(nwaku1PeerId)).to.eq(true);
|
||||
expect(waku.libp2p.getConnections()).has.length(2);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,16 +1,14 @@
|
||||
import type { PeerStore } from "@libp2p/interface/peer-store";
|
||||
import type { Peer } from "@libp2p/interface/peer-store";
|
||||
import { createSecp256k1PeerId } from "@libp2p/peer-id-factory";
|
||||
import { createDecoder, createEncoder, waitForRemotePeer } from "@waku/core";
|
||||
import { DefaultPubsubTopic, LightNode } from "@waku/interfaces";
|
||||
import { Protocols } from "@waku/interfaces";
|
||||
import {
|
||||
DefaultPubsubTopic,
|
||||
type LightNode,
|
||||
Protocols
|
||||
} from "@waku/interfaces";
|
||||
import { createLightNode } from "@waku/sdk";
|
||||
import { toAsyncIterator } from "@waku/utils";
|
||||
import { bytesToUtf8, utf8ToBytes } from "@waku/utils/bytes";
|
||||
import { selectPeerForProtocol } from "@waku/utils/libp2p";
|
||||
import chai, { expect } from "chai";
|
||||
import chaiAsPromised from "chai-as-promised";
|
||||
import sinon from "sinon";
|
||||
|
||||
import {
|
||||
delay,
|
||||
@ -116,172 +114,3 @@ describe("Util: toAsyncIterator: Filter", () => {
|
||||
expect(result.done).to.eq(true);
|
||||
});
|
||||
});
|
||||
|
||||
const TestCodec = "test/1";
|
||||
|
||||
describe("selectPeerForProtocol", () => {
|
||||
let peerStore: PeerStore;
|
||||
const protocols = [TestCodec];
|
||||
|
||||
let lowPingPeer: Peer,
|
||||
midPingPeer: Peer,
|
||||
highPingPeer: Peer,
|
||||
differentCodecPeer: Peer,
|
||||
anotherDifferentCodecPeer: Peer;
|
||||
|
||||
beforeEach(async function () {
|
||||
this.timeout(10000);
|
||||
const waku = await createLightNode();
|
||||
await waku.start();
|
||||
await delay(3000);
|
||||
peerStore = waku.libp2p.peerStore;
|
||||
|
||||
const [
|
||||
lowPingPeerId,
|
||||
midPingPeerId,
|
||||
highPingPeerId,
|
||||
differentCodecPeerId,
|
||||
anotherDifferentCodecPeerId
|
||||
] = await Promise.all([
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId(),
|
||||
createSecp256k1PeerId()
|
||||
]);
|
||||
|
||||
lowPingPeer = {
|
||||
id: lowPingPeerId,
|
||||
protocols: [TestCodec],
|
||||
metadata: new Map().set("ping", utf8ToBytes("50"))
|
||||
} as Peer;
|
||||
|
||||
midPingPeer = {
|
||||
id: midPingPeerId,
|
||||
protocols: [TestCodec],
|
||||
metadata: new Map().set("ping", utf8ToBytes("100"))
|
||||
} as Peer;
|
||||
|
||||
highPingPeer = {
|
||||
id: highPingPeerId,
|
||||
protocols: [TestCodec],
|
||||
metadata: new Map().set("ping", utf8ToBytes("500"))
|
||||
} as Peer;
|
||||
|
||||
differentCodecPeer = {
|
||||
id: differentCodecPeerId,
|
||||
protocols: ["DifferentCodec"]
|
||||
} as Peer;
|
||||
|
||||
anotherDifferentCodecPeer = {
|
||||
id: anotherDifferentCodecPeerId,
|
||||
protocols: ["AnotherDifferentCodec"]
|
||||
} as Peer;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it("should return the peer with the lowest ping", async function () {
|
||||
const mockPeers = [highPingPeer, lowPingPeer, midPingPeer];
|
||||
|
||||
sinon.stub(peerStore, "get").callsFake(async (peerId) => {
|
||||
return mockPeers.find((peer) => peer.id.equals(peerId))!;
|
||||
});
|
||||
|
||||
sinon.stub(peerStore, "forEach").callsFake(async (callback) => {
|
||||
for (const peer of mockPeers) {
|
||||
callback(peer);
|
||||
}
|
||||
});
|
||||
|
||||
const result = await selectPeerForProtocol(peerStore, protocols);
|
||||
|
||||
expect(result.peer).to.deep.equal(lowPingPeer);
|
||||
expect(result.protocol).to.equal(TestCodec);
|
||||
});
|
||||
|
||||
it("should return the peer with the provided peerId", async function () {
|
||||
const targetPeer = await createSecp256k1PeerId();
|
||||
const mockPeer = { id: targetPeer, protocols: [TestCodec] } as Peer;
|
||||
sinon.stub(peerStore, "get").withArgs(targetPeer).resolves(mockPeer);
|
||||
|
||||
const result = await selectPeerForProtocol(
|
||||
peerStore,
|
||||
protocols,
|
||||
targetPeer
|
||||
);
|
||||
expect(result.peer).to.deep.equal(mockPeer);
|
||||
});
|
||||
|
||||
it("should return a random peer when all peers have the same latency", async function () {
|
||||
const mockPeers = [highPingPeer, highPingPeer, highPingPeer];
|
||||
|
||||
sinon.stub(peerStore, "get").callsFake(async (peerId) => {
|
||||
return mockPeers.find((peer) => peer.id.equals(peerId))!;
|
||||
});
|
||||
|
||||
sinon.stub(peerStore, "forEach").callsFake(async (callback) => {
|
||||
for (const peer of mockPeers) {
|
||||
callback(peer);
|
||||
}
|
||||
});
|
||||
|
||||
const result = await selectPeerForProtocol(peerStore, protocols);
|
||||
|
||||
expect(mockPeers).to.deep.include(result.peer);
|
||||
});
|
||||
|
||||
it("should throw an error when no peer matches the given protocols", async function () {
|
||||
const mockPeers = [differentCodecPeer, anotherDifferentCodecPeer];
|
||||
|
||||
sinon.stub(peerStore, "forEach").callsFake(async (callback) => {
|
||||
for (const peer of mockPeers) {
|
||||
callback(peer);
|
||||
}
|
||||
});
|
||||
|
||||
await expect(
|
||||
selectPeerForProtocol(peerStore, protocols)
|
||||
).to.be.rejectedWith(
|
||||
`Failed to find known peer that registers protocols: ${protocols}`
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw an error when the selected peer does not register the required protocols", async function () {
|
||||
const targetPeer = await createSecp256k1PeerId();
|
||||
const mockPeer = { id: targetPeer, protocols: ["DifferentCodec"] } as Peer;
|
||||
sinon.stub(peerStore, "get").withArgs(targetPeer).resolves(mockPeer);
|
||||
|
||||
await expect(
|
||||
selectPeerForProtocol(peerStore, protocols, targetPeer)
|
||||
).to.be.rejectedWith(
|
||||
`Peer does not register required protocols (${targetPeer.toString()}): ${protocols}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("getConnectedPeersForProtocol", function () {
|
||||
let waku: LightNode;
|
||||
let nwaku: NimGoNode;
|
||||
|
||||
beforeEach(async function () {
|
||||
this.timeout(15000);
|
||||
nwaku = new NimGoNode(makeLogFileName(this));
|
||||
await nwaku.start({
|
||||
filter: true,
|
||||
lightpush: true,
|
||||
relay: true
|
||||
});
|
||||
waku = await createLightNode();
|
||||
await waku.start();
|
||||
await waku.dial(await nwaku.getMultiaddrWithId());
|
||||
await waitForRemotePeer(waku, [Protocols.Filter]);
|
||||
});
|
||||
|
||||
afterEach(async function () {
|
||||
this.timeout(10000);
|
||||
await tearDownNodes(nwaku, waku);
|
||||
});
|
||||
});
|
||||
|
@ -12,6 +12,33 @@
|
||||
* devDependencies
|
||||
* @waku/interfaces bumped from 0.0.16 to 0.0.17
|
||||
|
||||
## [0.0.14](https://github.com/waku-org/js-waku/compare/utils-v0.0.13...utils-v0.0.14) (2024-01-10)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697))
|
||||
* change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703))
|
||||
|
||||
### Features
|
||||
|
||||
* Add function for determining shard index from content topic ([86da696](https://github.com/waku-org/js-waku/commit/86da6962bac91a8719de1f9cd60e9f7bc13e48f1))
|
||||
* Add function to validate autoshard content topic ([1bc1eb5](https://github.com/waku-org/js-waku/commit/1bc1eb509166e6dfcb24c59a90eb05f5dc16de78))
|
||||
* Add support for autosharded pubsub topics ([2bc3735](https://github.com/waku-org/js-waku/commit/2bc3735e4dcf85f06b3dee542024d7f20a40fac2))
|
||||
* Add support for sharded pubsub topics & remove support for named pubsub topics ([#1697](https://github.com/waku-org/js-waku/issues/1697)) ([4cf2ffe](https://github.com/waku-org/js-waku/commit/4cf2ffefa75e0571805036b71644d2cdd4fe3192))
|
||||
|
||||
|
||||
### Miscellaneous Chores
|
||||
|
||||
* Change all instances of `PubSubTopic` to `PubsubTopic` ([#1703](https://github.com/waku-org/js-waku/issues/1703)) ([3166a51](https://github.com/waku-org/js-waku/commit/3166a5135e77583da4fa722ee2aa47c785854a38))
|
||||
|
||||
|
||||
### Dependencies
|
||||
|
||||
* The following workspace dependencies were updated
|
||||
* dependencies
|
||||
* @waku/interfaces bumped from 0.0.20 to 0.0.21
|
||||
|
||||
## [0.0.13](https://github.com/waku-org/js-waku/compare/utils-v0.0.12...utils-v0.0.13) (2023-11-01)
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@waku/utils",
|
||||
"version": "0.0.13",
|
||||
"version": "0.0.14",
|
||||
"description": "Different utilities for Waku",
|
||||
"types": "./dist/index.d.ts",
|
||||
"module": "./dist/index.js",
|
||||
@ -68,7 +68,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@noble/hashes": "^1.3.2",
|
||||
"@waku/interfaces": "0.0.20",
|
||||
"@waku/interfaces": "0.0.21",
|
||||
"chai": "^4.3.10",
|
||||
"debug": "^4.3.4",
|
||||
"fast-check": "^3.14.0",
|
||||
|
@ -22,6 +22,7 @@ export const shardInfoToPubsubTopics = (
|
||||
): PubsubTopic[] => {
|
||||
if (shardInfo.clusterId === undefined)
|
||||
throw new Error("Cluster ID must be specified");
|
||||
|
||||
if ("contentTopics" in shardInfo) {
|
||||
// Autosharding: explicitly defined content topics
|
||||
return Array.from(
|
||||
|
@ -1,7 +1,6 @@
|
||||
import type { Connection } from "@libp2p/interface/connection";
|
||||
import type { PeerId } from "@libp2p/interface/peer-id";
|
||||
import type { Peer, PeerStore } from "@libp2p/interface/peer-store";
|
||||
import type { ShardInfo } from "@waku/interfaces";
|
||||
import type { ShardingParams } from "@waku/interfaces";
|
||||
|
||||
import { bytesToUtf8 } from "../bytes/index.js";
|
||||
import { decodeRelayShard } from "../common/relay_shard_codec.js";
|
||||
@ -18,35 +17,39 @@ export function selectRandomPeer(peers: Peer[]): Peer | undefined {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the peer with the lowest latency.
|
||||
* Function to sort peers by latency from lowest to highest
|
||||
* @param peerStore - The Libp2p PeerStore
|
||||
* @param peers - The list of peers to choose from
|
||||
* @returns The peer with the lowest latency, or undefined if no peer could be reached
|
||||
* @returns Sorted array of peers by latency
|
||||
*/
|
||||
export async function selectLowestLatencyPeer(
|
||||
export async function sortPeersByLatency(
|
||||
peerStore: PeerStore,
|
||||
peers: Peer[]
|
||||
): Promise<Peer | undefined> {
|
||||
if (peers.length === 0) return;
|
||||
): Promise<Peer[]> {
|
||||
if (peers.length === 0) return [];
|
||||
|
||||
const results = await Promise.all(
|
||||
peers.map(async (peer) => {
|
||||
const pingBytes = (await peerStore.get(peer.id)).metadata.get("ping");
|
||||
if (!pingBytes) return { peer, ping: Infinity };
|
||||
try {
|
||||
const pingBytes = (await peerStore.get(peer.id)).metadata.get("ping");
|
||||
if (!pingBytes) return { peer, ping: Infinity };
|
||||
|
||||
const ping = Number(bytesToUtf8(pingBytes)) ?? Infinity;
|
||||
return { peer, ping };
|
||||
const ping = Number(bytesToUtf8(pingBytes));
|
||||
return { peer, ping };
|
||||
} catch (error) {
|
||||
return { peer, ping: Infinity };
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const lowestLatencyResult = results.sort((a, b) => a.ping - b.ping)[0];
|
||||
if (!lowestLatencyResult) {
|
||||
return undefined;
|
||||
}
|
||||
// filter out null values
|
||||
const validResults = results.filter(
|
||||
(result): result is { peer: Peer; ping: number } => result !== null
|
||||
);
|
||||
|
||||
return lowestLatencyResult.ping !== Infinity
|
||||
? lowestLatencyResult.peer
|
||||
: undefined;
|
||||
return validResults
|
||||
.sort((a, b) => a.ping - b.ping)
|
||||
.map((result) => result.peer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -72,7 +75,7 @@ export async function getConnectedPeersForProtocolAndShard(
|
||||
connections: Connection[],
|
||||
peerStore: PeerStore,
|
||||
protocols: string[],
|
||||
shardInfo?: ShardInfo
|
||||
shardInfo?: ShardingParams
|
||||
): Promise<Peer[]> {
|
||||
const openConnections = connections.filter(
|
||||
(connection) => connection.status === "open"
|
||||
@ -86,6 +89,12 @@ export async function getConnectedPeersForProtocolAndShard(
|
||||
|
||||
if (supportsProtocol) {
|
||||
if (shardInfo) {
|
||||
//TODO: support auto-sharding
|
||||
if (!("shards" in shardInfo)) {
|
||||
throw new Error(
|
||||
`Connections Manager only supports static sharding for now. Autosharding is not supported.`
|
||||
);
|
||||
}
|
||||
const encodedPeerShardInfo = peer.metadata.get("shardInfo");
|
||||
const peerShardInfo =
|
||||
encodedPeerShardInfo && decodeRelayShard(encodedPeerShardInfo);
|
||||
@ -104,53 +113,6 @@ export async function getConnectedPeersForProtocolAndShard(
|
||||
return peersWithNulls.filter((peer): peer is Peer => peer !== null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a peer that supports the given protocol.
|
||||
* If peerId is provided, the peer with that id is returned.
|
||||
* Otherwise, the peer with the lowest latency is returned.
|
||||
* If no peer is found from the above criteria, a random peer is returned.
|
||||
*/
|
||||
export async function selectPeerForProtocol(
|
||||
peerStore: PeerStore,
|
||||
protocols: string[],
|
||||
peerId?: PeerId
|
||||
): Promise<{ peer: Peer; protocol: string }> {
|
||||
let peer: Peer | undefined;
|
||||
if (peerId) {
|
||||
peer = await peerStore.get(peerId);
|
||||
if (!peer) {
|
||||
throw new Error(
|
||||
`Failed to retrieve connection details for provided peer in peer store: ${peerId.toString()}`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const peers = await getPeersForProtocol(peerStore, protocols);
|
||||
peer = await selectLowestLatencyPeer(peerStore, peers);
|
||||
if (!peer) {
|
||||
peer = selectRandomPeer(peers);
|
||||
if (!peer)
|
||||
throw new Error(
|
||||
`Failed to find known peer that registers protocols: ${protocols}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let protocol;
|
||||
for (const codec of protocols) {
|
||||
if (peer.protocols.includes(codec)) {
|
||||
protocol = codec;
|
||||
// Do not break as we want to keep the last value
|
||||
}
|
||||
}
|
||||
if (!protocol) {
|
||||
throw new Error(
|
||||
`Peer does not register required protocols (${peer.id.toString()}): ${protocols}`
|
||||
);
|
||||
}
|
||||
|
||||
return { peer, protocol };
|
||||
}
|
||||
|
||||
export function selectConnection(
|
||||
connections: Connection[]
|
||||
): Connection | undefined {
|
||||
|
Loading…
x
Reference in New Issue
Block a user