feat!: upgrade to libp2p@0.45 (#1400)

* upgrade libp2p version, partially update protocols, rename to IBaseProtocol

* complete transition for protocols

* complete transition of connection maanger

* finish sdk

* complete core

* complete relay

* complete peer-exchange

* complete dns-discovery

* add components field to Libp2p interface and use it in core

* add type hack for Libp2p creation:

* finish waku node test

* complete relay test

* complete peer exchange

* complete dns peer discovery test

* add missing dependency to relay

* fix new peer store integration

* improve initialization of pubsub

* add catch for missing peer

* update test and remove extra dependency

* prevent error throw

* fix edge case with peerStore

* fix peer exchange

* fix protocols used

* fix test with another evnet

* bump libp2p and interfaces

* add missing package

* fix peer-exchange problem

* prefer libp2p peerDiscovery for integration tests

* fix import

* increate timeout

* return test against Test fleet

* remove await for peer:update

* increase timeout

* add await for peerStore

* comment event for testing

* fix lint

* remove bind

* fix stub

* decouple to separate test case

* move back to explicit build

* remove only

* do not test event
This commit is contained in:
Sasha 2023-07-25 02:17:52 +02:00 committed by GitHub
parent 376bcf2a0a
commit 420e6c698d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 4667 additions and 13005 deletions

16924
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -85,11 +85,11 @@
"uuid": "^9.0.0" "uuid": "^9.0.0"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-connection": "^3.0.8", "@libp2p/interface-connection": "^5.1.1",
"@libp2p/interface-libp2p": "^1.1.2", "@libp2p/interface-libp2p": "^3.2.0",
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-peer-id": "^2.0.2",
"@libp2p/interface-peer-store": "^1.2.8", "@libp2p/interface-peer-store": "^2.0.4",
"@libp2p/interface-registrar": "^2.0.8", "@libp2p/interface-registrar": "^2.0.12",
"@multiformats/multiaddr": "^12.0.0", "@multiformats/multiaddr": "^12.0.0",
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
@ -120,7 +120,7 @@
}, },
"peerDependencies": { "peerDependencies": {
"@multiformats/multiaddr": "^12.0.0", "@multiformats/multiaddr": "^12.0.0",
"libp2p": "^0.42.2" "libp2p": "^0.45.9"
}, },
"peerDependenciesMeta": { "peerDependenciesMeta": {
"@multiformats/multiaddr": { "@multiformats/multiaddr": {

View File

@ -1,6 +1,8 @@
import type { Connection, Stream } from "@libp2p/interface-connection"; import type { Stream } from "@libp2p/interface-connection";
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import { Peer, PeerStore } from "@libp2p/interface-peer-store"; import { Peer, PeerStore } from "@libp2p/interface-peer-store";
import type { IBaseProtocol, Libp2pComponents } from "@waku/interfaces";
import { import {
getPeersForProtocol, getPeersForProtocol,
selectConnection, selectConnection,
@ -11,19 +13,29 @@ import {
* A class with predefined helpers, to be used as a base to implement Waku * A class with predefined helpers, to be used as a base to implement Waku
* Protocols. * Protocols.
*/ */
export class BaseProtocol { export class BaseProtocol implements IBaseProtocol {
constructor( public readonly addLibp2pEventListener: Libp2p["addEventListener"];
public multicodec: string, public readonly removeLibp2pEventListener: Libp2p["removeEventListener"];
public peerStore: PeerStore,
protected getConnections: (peerId?: PeerId) => Connection[] constructor(public multicodec: string, private components: Libp2pComponents) {
) {} this.addLibp2pEventListener = components.events.addEventListener.bind(
components.events
);
this.removeLibp2pEventListener = components.events.removeEventListener.bind(
components.events
);
}
public get peerStore(): PeerStore {
return this.components.peerStore;
}
/** /**
* Returns known peers from the address book (`libp2p.peerStore`) that support * Returns known peers from the address book (`libp2p.peerStore`) that support
* the class protocol. Waku may or may not be currently connected to these * the class protocol. Waku may or may not be currently connected to these
* peers. * peers.
*/ */
async peers(): Promise<Peer[]> { public async peers(): Promise<Peer[]> {
return getPeersForProtocol(this.peerStore, [this.multicodec]); return getPeersForProtocol(this.peerStore, [this.multicodec]);
} }
@ -36,7 +48,9 @@ export class BaseProtocol {
return peer; return peer;
} }
protected async newStream(peer: Peer): Promise<Stream> { protected async newStream(peer: Peer): Promise<Stream> {
const connections = this.getConnections(peer.id); const connections = this.components.connectionManager.getConnections(
peer.id
);
const connection = selectConnection(connections); const connection = selectConnection(connections);
if (!connection) { if (!connection) {
throw new Error("Failed to get a connection to the peer"); throw new Error("Failed to get a connection to the peer");

View File

@ -1,9 +1,7 @@
import type { Connection } from "@libp2p/interface-connection";
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import type { PeerInfo } from "@libp2p/interface-peer-info"; import type { PeerInfo } from "@libp2p/interface-peer-info";
import type { ConnectionManagerOptions, IRelay } from "@waku/interfaces"; import type { ConnectionManagerOptions, IRelay } from "@waku/interfaces";
import { Tags } from "@waku/interfaces"; import { Libp2p, Tags } from "@waku/interfaces";
import debug from "debug"; import debug from "debug";
import { KeepAliveManager, KeepAliveOptions } from "./keep_alive_manager.js"; import { KeepAliveManager, KeepAliveOptions } from "./keep_alive_manager.js";
@ -18,7 +16,7 @@ export class ConnectionManager {
private static instances = new Map<string, ConnectionManager>(); private static instances = new Map<string, ConnectionManager>();
private keepAliveManager: KeepAliveManager; private keepAliveManager: KeepAliveManager;
private options: ConnectionManagerOptions; private options: ConnectionManagerOptions;
private libp2pComponents: Libp2p; private libp2p: Libp2p;
private dialAttemptsForPeer: Map<string, number> = new Map(); private dialAttemptsForPeer: Map<string, number> = new Map();
private dialErrorsForPeer: Map<string, any> = new Map(); private dialErrorsForPeer: Map<string, any> = new Map();
@ -47,12 +45,12 @@ export class ConnectionManager {
} }
private constructor( private constructor(
libp2pComponents: Libp2p, libp2p: Libp2p,
keepAliveOptions: KeepAliveOptions, keepAliveOptions: KeepAliveOptions,
relay?: IRelay, relay?: IRelay,
options?: Partial<ConnectionManagerOptions> options?: Partial<ConnectionManagerOptions>
) { ) {
this.libp2pComponents = libp2pComponents; this.libp2p = libp2p;
this.options = { this.options = {
maxDialAttemptsForPeer: DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER, maxDialAttemptsForPeer: DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER,
maxBootstrapPeersAllowed: DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED, maxBootstrapPeersAllowed: DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED,
@ -75,13 +73,11 @@ export class ConnectionManager {
} }
private async dialPeerStorePeers(): Promise<void> { private async dialPeerStorePeers(): Promise<void> {
const peerInfos = await this.libp2pComponents.peerStore.all(); const peerInfos = await this.libp2p.peerStore.all();
const dialPromises = []; const dialPromises = [];
for (const peerInfo of peerInfos) { for (const peerInfo of peerInfos) {
if ( if (
this.libp2pComponents this.libp2p.getConnections().find((c) => c.remotePeer === peerInfo.id)
.getConnections()
.find((c) => c.remotePeer === peerInfo.id)
) )
continue; continue;
@ -103,15 +99,15 @@ export class ConnectionManager {
stop(): void { stop(): void {
this.keepAliveManager.stopAll(); this.keepAliveManager.stopAll();
this.libp2pComponents.removeEventListener( this.libp2p.removeEventListener(
"peer:connect", "peer:connect",
this.onEventHandlers["peer:connect"] this.onEventHandlers["peer:connect"]
); );
this.libp2pComponents.removeEventListener( this.libp2p.removeEventListener(
"peer:disconnect", "peer:disconnect",
this.onEventHandlers["peer:disconnect"] this.onEventHandlers["peer:disconnect"]
); );
this.libp2pComponents.removeEventListener( this.libp2p.removeEventListener(
"peer:discovery", "peer:discovery",
this.onEventHandlers["peer:discovery"] this.onEventHandlers["peer:discovery"]
); );
@ -123,12 +119,12 @@ export class ConnectionManager {
while (dialAttempt <= this.options.maxDialAttemptsForPeer) { while (dialAttempt <= this.options.maxDialAttemptsForPeer) {
try { try {
log(`Dialing peer ${peerId.toString()}`); log(`Dialing peer ${peerId.toString()}`);
await this.libp2pComponents.dial(peerId); await this.libp2p.dial(peerId);
const tags = await this.getTagNamesForPeer(peerId); const tags = await this.getTagNamesForPeer(peerId);
// add tag to connection describing discovery mechanism // add tag to connection describing discovery mechanism
// don't add duplicate tags // don't add duplicate tags
this.libp2pComponents this.libp2p
.getConnections(peerId) .getConnections(peerId)
.forEach( .forEach(
(conn) => (conn.tags = Array.from(new Set([...conn.tags, ...tags]))) (conn) => (conn.tags = Array.from(new Set([...conn.tags, ...tags])))
@ -159,7 +155,7 @@ export class ConnectionManager {
}` }`
); );
this.dialErrorsForPeer.delete(peerId.toString()); this.dialErrorsForPeer.delete(peerId.toString());
return await this.libp2pComponents.peerStore.delete(peerId); return await this.libp2p.peerStore.delete(peerId);
} catch (error) { } catch (error) {
throw `Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`; throw `Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`;
} finally { } finally {
@ -170,7 +166,7 @@ export class ConnectionManager {
async dropConnection(peerId: PeerId): Promise<void> { async dropConnection(peerId: PeerId): Promise<void> {
try { try {
await this.libp2pComponents.hangUp(peerId); await this.libp2p.hangUp(peerId);
log(`Dropped connection with peer ${peerId.toString()}`); log(`Dropped connection with peer ${peerId.toString()}`);
} catch (error) { } catch (error) {
log( log(
@ -193,14 +189,14 @@ export class ConnectionManager {
} }
private startPeerDiscoveryListener(): void { private startPeerDiscoveryListener(): void {
this.libp2pComponents.addEventListener( this.libp2p.addEventListener(
"peer:discovery", "peer:discovery",
this.onEventHandlers["peer:discovery"] this.onEventHandlers["peer:discovery"]
); );
} }
private startPeerConnectionListener(): void { private startPeerConnectionListener(): void {
this.libp2pComponents.addEventListener( this.libp2p.addEventListener(
"peer:connect", "peer:connect",
this.onEventHandlers["peer:connect"] this.onEventHandlers["peer:connect"]
); );
@ -219,7 +215,7 @@ export class ConnectionManager {
* >this event will **only** be triggered when the last connection is closed. * >this event will **only** be triggered when the last connection is closed.
* @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100 * @see https://github.com/libp2p/js-libp2p/blob/bad9e8c0ff58d60a78314077720c82ae331cc55b/doc/API.md?plain=1#L2100
*/ */
this.libp2pComponents.addEventListener( this.libp2p.addEventListener(
"peer:disconnect", "peer:disconnect",
this.onEventHandlers["peer:disconnect"] this.onEventHandlers["peer:disconnect"]
); );
@ -250,21 +246,18 @@ export class ConnectionManager {
} }
})(); })();
}, },
"peer:connect": (evt: CustomEvent<Connection>): void => { "peer:connect": (evt: CustomEvent<PeerId>): void => {
void (async () => { void (async () => {
const { remotePeer: peerId } = evt.detail; const peerId = evt.detail;
this.keepAliveManager.start( this.keepAliveManager.start(peerId, this.libp2p.services.ping);
peerId,
this.libp2pComponents.ping.bind(this)
);
const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes( const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(
Tags.BOOTSTRAP Tags.BOOTSTRAP
); );
if (isBootstrap) { if (isBootstrap) {
const bootstrapConnections = this.libp2pComponents const bootstrapConnections = this.libp2p
.getConnections() .getConnections()
.filter((conn) => conn.tags.includes(Tags.BOOTSTRAP)); .filter((conn) => conn.tags.includes(Tags.BOOTSTRAP));
@ -278,8 +271,8 @@ export class ConnectionManager {
})(); })();
}, },
"peer:disconnect": () => { "peer:disconnect": () => {
return (evt: CustomEvent<Connection>): void => { return (evt: CustomEvent<PeerId>): void => {
this.keepAliveManager.stop(evt.detail.remotePeer); this.keepAliveManager.stop(evt.detail);
}; };
}, },
}; };
@ -290,7 +283,7 @@ export class ConnectionManager {
* 2. If the peer is not a bootstrap peer * 2. If the peer is not a bootstrap peer
*/ */
private async shouldDialPeer(peerId: PeerId): Promise<boolean> { private async shouldDialPeer(peerId: PeerId): Promise<boolean> {
const isConnected = this.libp2pComponents.getConnections(peerId).length > 0; const isConnected = this.libp2p.getConnections(peerId).length > 0;
if (isConnected) return false; if (isConnected) return false;
@ -299,7 +292,7 @@ export class ConnectionManager {
const isBootstrap = tagNames.some((tagName) => tagName === Tags.BOOTSTRAP); const isBootstrap = tagNames.some((tagName) => tagName === Tags.BOOTSTRAP);
if (isBootstrap) { if (isBootstrap) {
const currentBootstrapConnections = this.libp2pComponents const currentBootstrapConnections = this.libp2p
.getConnections() .getConnections()
.filter((conn) => { .filter((conn) => {
return conn.tags.find((name) => name === Tags.BOOTSTRAP); return conn.tags.find((name) => name === Tags.BOOTSTRAP);
@ -317,9 +310,12 @@ export class ConnectionManager {
* Fetches the tag names for a given peer * Fetches the tag names for a given peer
*/ */
private async getTagNamesForPeer(peerId: PeerId): Promise<string[]> { private async getTagNamesForPeer(peerId: PeerId): Promise<string[]> {
const tags = (await this.libp2pComponents.peerStore.getTags(peerId)).map( try {
(tag) => tag.name const peer = await this.libp2p.peerStore.get(peerId);
); return Array.from(peer.tags.keys());
return tags; } catch (error) {
log(`Failed to get peer ${peerId}, error: ${error}`);
return [];
}
} }
} }

View File

@ -1,4 +1,3 @@
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { Peer } from "@libp2p/interface-peer-store"; import type { Peer } from "@libp2p/interface-peer-store";
import type { IncomingStreamData } from "@libp2p/interface-registrar"; import type { IncomingStreamData } from "@libp2p/interface-registrar";
import type { import type {
@ -9,6 +8,7 @@ import type {
IDecodedMessage, IDecodedMessage,
IDecoder, IDecoder,
IFilter, IFilter,
Libp2p,
ProtocolCreateOptions, ProtocolCreateOptions,
ProtocolOptions, ProtocolOptions,
} from "@waku/interfaces"; } from "@waku/interfaces";
@ -50,11 +50,11 @@ class Filter extends BaseProtocol implements IFilter {
options: ProtocolCreateOptions; options: ProtocolCreateOptions;
private subscriptions: Map<RequestID, unknown>; private subscriptions: Map<RequestID, unknown>;
constructor(public libp2p: Libp2p, options?: ProtocolCreateOptions) { constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
super(FilterCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p)); super(FilterCodec, libp2p.components);
this.options = options ?? {}; this.options = options ?? {};
this.subscriptions = new Map(); this.subscriptions = new Map();
this.libp2p libp2p
.handle(this.multicodec, this.onRequest.bind(this)) .handle(this.multicodec, this.onRequest.bind(this))
.catch((e) => log("Failed to register filter protocol", e)); .catch((e) => log("Failed to register filter protocol", e));
} }

View File

@ -1,5 +1,4 @@
import { Stream } from "@libp2p/interface-connection"; import { Stream } from "@libp2p/interface-connection";
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import type { Peer } from "@libp2p/interface-peer-store"; import type { Peer } from "@libp2p/interface-peer-store";
import type { IncomingStreamData } from "@libp2p/interface-registrar"; import type { IncomingStreamData } from "@libp2p/interface-registrar";
@ -12,6 +11,7 @@ import type {
IFilterV2, IFilterV2,
IProtoMessage, IProtoMessage,
IReceiver, IReceiver,
Libp2p,
PeerIdStr, PeerIdStr,
ProtocolCreateOptions, ProtocolCreateOptions,
ProtocolOptions, ProtocolOptions,
@ -245,18 +245,12 @@ class FilterV2 extends BaseProtocol implements IReceiver {
return subscription; return subscription;
} }
constructor(public libp2p: Libp2p, options?: ProtocolCreateOptions) { constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
super( super(FilterV2Codecs.SUBSCRIBE, libp2p.components);
FilterV2Codecs.SUBSCRIBE,
libp2p.peerStore,
libp2p.getConnections.bind(libp2p)
);
this.libp2p libp2p.handle(FilterV2Codecs.PUSH, this.onRequest.bind(this)).catch((e) => {
.handle(FilterV2Codecs.PUSH, this.onRequest.bind(this)) log("Failed to register ", FilterV2Codecs.PUSH, e);
.catch((e) => { });
log("Failed to register ", FilterV2Codecs.PUSH, e);
});
this.activeSubscriptions = new Map(); this.activeSubscriptions = new Map();

View File

@ -1,7 +1,7 @@
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import type { IRelay } from "@waku/interfaces"; import type { IRelay } from "@waku/interfaces";
import debug from "debug"; import debug from "debug";
import type { Libp2p } from "libp2p"; import type { PingService } from "libp2p/ping";
import { createEncoder } from "../index.js"; import { createEncoder } from "../index.js";
@ -26,7 +26,7 @@ export class KeepAliveManager {
this.relay = relay; this.relay = relay;
} }
public start(peerId: PeerId, libp2pPing: Libp2p["ping"]): void { public start(peerId: PeerId, libp2pPing: PingService): void {
// Just in case a timer already exist for this peer // Just in case a timer already exist for this peer
this.stop(peerId); this.stop(peerId);
@ -37,7 +37,7 @@ export class KeepAliveManager {
if (pingPeriodSecs !== 0) { if (pingPeriodSecs !== 0) {
const interval = setInterval(() => { const interval = setInterval(() => {
libp2pPing(peerId).catch((e) => { libp2pPing.ping(peerId).catch((e) => {
log(`Ping failed (${peerIdStr})`, e); log(`Ping failed (${peerIdStr})`, e);
}); });
}, pingPeriodSecs * 1000); }, pingPeriodSecs * 1000);

View File

@ -1,9 +1,9 @@
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import { import {
IEncoder, IEncoder,
ILightPush, ILightPush,
IMessage, IMessage,
Libp2p,
ProtocolCreateOptions, ProtocolCreateOptions,
ProtocolOptions, ProtocolOptions,
SendError, SendError,
@ -33,8 +33,8 @@ export { PushResponse };
class LightPush extends BaseProtocol implements ILightPush { class LightPush extends BaseProtocol implements ILightPush {
options: ProtocolCreateOptions; options: ProtocolCreateOptions;
constructor(public libp2p: Libp2p, options?: ProtocolCreateOptions) { constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
super(LightPushCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p)); super(LightPushCodec, libp2p.components);
this.options = options || {}; this.options = options || {};
} }

View File

@ -1,5 +1,4 @@
import type { Stream } from "@libp2p/interface-connection"; import type { Stream } from "@libp2p/interface-connection";
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import { sha256 } from "@noble/hashes/sha256"; import { sha256 } from "@noble/hashes/sha256";
import { import {
@ -7,6 +6,7 @@ import {
IDecodedMessage, IDecodedMessage,
IDecoder, IDecoder,
IStore, IStore,
Libp2p,
ProtocolCreateOptions, ProtocolCreateOptions,
} from "@waku/interfaces"; } from "@waku/interfaces";
import { proto_store as proto } from "@waku/proto"; import { proto_store as proto } from "@waku/proto";
@ -81,8 +81,8 @@ export interface QueryOptions {
class Store extends BaseProtocol implements IStore { class Store extends BaseProtocol implements IStore {
options: ProtocolCreateOptions; options: ProtocolCreateOptions;
constructor(public libp2p: Libp2p, options?: ProtocolCreateOptions) { constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
super(StoreCodec, libp2p.peerStore, libp2p.getConnections.bind(libp2p)); super(StoreCodec, libp2p.components);
this.options = options ?? {}; this.options = options ?? {};
} }

View File

@ -1,5 +1,5 @@
import type { PeerProtocolsChangeData } from "@libp2p/interface-peer-store"; import type { IdentifyResult } from "@libp2p/interface-libp2p";
import type { IRelay, PointToPointProtocol, Waku } from "@waku/interfaces"; import type { IBaseProtocol, IRelay, Waku } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces"; import { Protocols } from "@waku/interfaces";
import debug from "debug"; import debug from "debug";
import { pEvent } from "p-event"; import { pEvent } from "p-event";
@ -74,9 +74,7 @@ export async function waitForRemotePeer(
/** /**
* Wait for a peer with the given protocol to be connected. * Wait for a peer with the given protocol to be connected.
*/ */
async function waitForConnectedPeer( async function waitForConnectedPeer(protocol: IBaseProtocol): Promise<void> {
protocol: PointToPointProtocol
): Promise<void> {
const codec = protocol.multicodec; const codec = protocol.multicodec;
const peers = await protocol.peers(); const peers = await protocol.peers();
@ -86,14 +84,14 @@ async function waitForConnectedPeer(
} }
await new Promise<void>((resolve) => { await new Promise<void>((resolve) => {
const cb = (evt: CustomEvent<PeerProtocolsChangeData>): void => { const cb = (evt: CustomEvent<IdentifyResult>): void => {
if (evt.detail.protocols.includes(codec)) { if (evt.detail?.protocols?.includes(codec)) {
log("Resolving for", codec, evt.detail.protocols); log("Resolving for", codec, evt.detail.protocols);
protocol.peerStore.removeEventListener("change:protocols", cb); protocol.removeLibp2pEventListener("peer:identify", cb);
resolve(); resolve();
} }
}; };
protocol.peerStore.addEventListener("change:protocols", cb); protocol.addLibp2pEventListener("peer:identify", cb);
}); });
} }

View File

@ -1,5 +1,4 @@
import type { Stream } from "@libp2p/interface-connection"; import type { Stream } from "@libp2p/interface-connection";
import type { Libp2p } from "@libp2p/interface-libp2p";
import { isPeerId, PeerId } from "@libp2p/interface-peer-id"; import { isPeerId, PeerId } from "@libp2p/interface-peer-id";
import { multiaddr, Multiaddr, MultiaddrInput } from "@multiformats/multiaddr"; import { multiaddr, Multiaddr, MultiaddrInput } from "@multiformats/multiaddr";
import type { import type {
@ -8,6 +7,7 @@ import type {
ILightPush, ILightPush,
IRelay, IRelay,
IStore, IStore,
Libp2p,
Waku, Waku,
} from "@waku/interfaces"; } from "@waku/interfaces";
import { Protocols } from "@waku/interfaces"; import { Protocols } from "@waku/interfaces";

View File

@ -51,8 +51,8 @@
"node": ">=16" "node": ">=16"
}, },
"dependencies": { "dependencies": {
"@libp2p/interface-peer-discovery": "^1.0.5", "@libp2p/interface-peer-discovery": "^2.0.0",
"@libp2p/interfaces": "^3.3.1", "@libp2p/interfaces": "^3.3.2",
"@waku/enr": "0.0.14", "@waku/enr": "0.0.14",
"@waku/utils": "0.0.8", "@waku/utils": "0.0.8",
"debug": "^4.3.4", "debug": "^4.3.4",
@ -61,10 +61,10 @@
"uint8arrays": "^4.0.3" "uint8arrays": "^4.0.3"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-peer-info": "^1.0.8", "@libp2p/interface-peer-info": "^1.0.10",
"@libp2p/interface-peer-store": "^1.2.8", "@libp2p/interface-peer-store": "^2.0.4",
"@libp2p/peer-id": "^2.0.3", "@libp2p/peer-id": "^2.0.4",
"@libp2p/peer-id-factory": "^2.0.3", "@libp2p/peer-id-factory": "^2.0.4",
"@multiformats/multiaddr": "^12.0.0", "@multiformats/multiaddr": "^12.0.0",
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",

View File

@ -2,7 +2,7 @@ import type {
PeerDiscovery, PeerDiscovery,
PeerDiscoveryEvents, PeerDiscoveryEvents,
} from "@libp2p/interface-peer-discovery"; } from "@libp2p/interface-peer-discovery";
import { symbol } from "@libp2p/interface-peer-discovery"; import { peerDiscovery as symbol } from "@libp2p/interface-peer-discovery";
import type { PeerInfo } from "@libp2p/interface-peer-info"; import type { PeerInfo } from "@libp2p/interface-peer-info";
import type { PeerStore } from "@libp2p/interface-peer-store"; import type { PeerStore } from "@libp2p/interface-peer-store";
import { CustomEvent, EventEmitter } from "@libp2p/interfaces/events"; import { CustomEvent, EventEmitter } from "@libp2p/interfaces/events";
@ -97,30 +97,47 @@ export class PeerDiscoveryDns
); );
} }
for await (const peer of this.nextPeer()) { for await (const peerEnr of this.nextPeer()) {
if (!this._started) return; if (!this._started) {
return;
}
const peerInfo = peer.peerInfo; const peerInfo = peerEnr.peerInfo;
if (!peerInfo) continue;
if ( if (!peerInfo) {
(await this._components.peerStore.getTags(peerInfo.id)).find(
({ name }) => name === DEFAULT_BOOTSTRAP_TAG_NAME
)
)
continue; continue;
}
await this._components.peerStore.tagPeer( const tagsToUpdate = {
peerInfo.id, tags: {
DEFAULT_BOOTSTRAP_TAG_NAME, [DEFAULT_BOOTSTRAP_TAG_NAME]: {
{ value: this._options.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE,
value: this._options.tagValue ?? DEFAULT_BOOTSTRAP_TAG_VALUE, ttl: this._options.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL,
ttl: this._options.tagTTL ?? DEFAULT_BOOTSTRAP_TAG_TTL, },
},
};
let isPeerChanged = false;
const isPeerExists = await this._components.peerStore.has(peerInfo.id);
if (isPeerExists) {
const peer = await this._components.peerStore.get(peerInfo.id);
const hasBootstrapTag = peer.tags.has(DEFAULT_BOOTSTRAP_TAG_NAME);
if (!hasBootstrapTag) {
isPeerChanged = true;
await this._components.peerStore.merge(peerInfo.id, tagsToUpdate);
} }
); } else {
this.dispatchEvent( isPeerChanged = true;
new CustomEvent<PeerInfo>("peer", { detail: peerInfo }) await this._components.peerStore.save(peerInfo.id, tagsToUpdate);
); }
if (isPeerChanged) {
this.dispatchEvent(
new CustomEvent<PeerInfo>("peer", { detail: peerInfo })
);
}
} }
} }

View File

@ -53,7 +53,7 @@
"dependencies": { "dependencies": {
"@ethersproject/rlp": "^5.7.0", "@ethersproject/rlp": "^5.7.0",
"@libp2p/crypto": "^1.0.17", "@libp2p/crypto": "^1.0.17",
"@libp2p/peer-id": "^2.0.3", "@libp2p/peer-id": "^2.0.4",
"@multiformats/multiaddr": "^12.0.0", "@multiformats/multiaddr": "^12.0.0",
"@noble/secp256k1": "^1.7.1", "@noble/secp256k1": "^1.7.1",
"@waku/utils": "0.0.8", "@waku/utils": "0.0.8",
@ -61,9 +61,9 @@
"js-sha3": "^0.8.0" "js-sha3": "^0.8.0"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-peer-id": "^2.0.2",
"@libp2p/interface-peer-info": "^1.0.8", "@libp2p/interface-peer-info": "^1.0.10",
"@libp2p/peer-id-factory": "^2.0.3", "@libp2p/peer-id-factory": "^2.0.4",
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-node-resolve": "^15.0.2",

View File

@ -47,19 +47,20 @@
"node": ">=16" "node": ">=16"
}, },
"devDependencies": { "devDependencies": {
"@chainsafe/libp2p-gossipsub": "^6.1.0", "@chainsafe/libp2p-gossipsub": "^9.0.0",
"@libp2p/interface-connection": "^3.0.8", "@libp2p/interface-connection": "^5.1.1",
"@libp2p/interface-connection-manager": "^1.3.7", "@libp2p/interface-connection-manager": "^3.0.1",
"@libp2p/interface-libp2p": "^1.1.2", "@libp2p/interface-libp2p": "^3.2.0",
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-peer-id": "^2.0.2",
"@libp2p/interface-peer-info": "^1.0.8", "@libp2p/interface-peer-info": "^1.0.10",
"@libp2p/interface-peer-store": "^1.2.8", "@libp2p/interface-peer-store": "^2.0.4",
"@libp2p/interface-registrar": "^2.0.8", "@libp2p/interface-registrar": "^2.0.12",
"@multiformats/multiaddr": "^12.0.0", "@multiformats/multiaddr": "^12.0.0",
"cspell": "^6.31.1", "cspell": "^6.31.1",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"typescript": "^5.0.4" "typescript": "^5.0.4",
"libp2p": "^0.45.9"
}, },
"typedoc": { "typedoc": {
"entryPoint": "./src/index.ts" "entryPoint": "./src/index.ts"

View File

@ -2,14 +2,14 @@ import type { PeerId } from "@libp2p/interface-peer-id";
import type { IDecodedMessage, IDecoder } from "./message.js"; import type { IDecodedMessage, IDecoder } from "./message.js";
import type { ContentTopic } from "./misc.js"; import type { ContentTopic } from "./misc.js";
import type { Callback, PointToPointProtocol } from "./protocols.js"; import type { Callback, IBaseProtocol } from "./protocols.js";
import type { IReceiver } from "./receiver.js"; import type { IReceiver } from "./receiver.js";
export type ContentFilter = { export type ContentFilter = {
contentTopic: string; contentTopic: string;
}; };
export type IFilter = IReceiver & PointToPointProtocol; export type IFilter = IReceiver & IBaseProtocol;
export interface IFilterV2Subscription { export interface IFilterV2Subscription {
subscribe<T extends IDecodedMessage>( subscribe<T extends IDecodedMessage>(
@ -25,7 +25,7 @@ export interface IFilterV2Subscription {
} }
export type IFilterV2 = IReceiver & export type IFilterV2 = IReceiver &
PointToPointProtocol & { IBaseProtocol & {
createSubscription( createSubscription(
pubSubTopic?: string, pubSubTopic?: string,
peerId?: PeerId peerId?: PeerId

View File

@ -11,3 +11,4 @@ export * from "./connection_manager.js";
export * from "./sender.js"; export * from "./sender.js";
export * from "./receiver.js"; export * from "./receiver.js";
export * from "./misc.js"; export * from "./misc.js";
export * from "./libp2p.js";

View File

@ -0,0 +1,21 @@
import type { GossipSub } from "@chainsafe/libp2p-gossipsub";
import type { Libp2p as BaseLibp2p } from "@libp2p/interface-libp2p";
import type { Libp2pInit } from "libp2p";
import type { identifyService } from "libp2p/identify";
import type { PingService } from "libp2p/ping";
export type Libp2pServices = {
ping: PingService;
pubsub?: GossipSub;
identify: ReturnType<ReturnType<typeof identifyService>>;
};
// TODO: Get libp2p to export this.
export type Libp2pComponents = Parameters<
Exclude<Libp2pInit["metrics"], undefined>
>[0];
// thought components are not defined on the Libp2p interface they are present on Libp2pNode class
export type Libp2p = BaseLibp2p<Libp2pServices> & {
components: Libp2pComponents;
};

View File

@ -1,4 +1,4 @@
import type { PointToPointProtocol } from "./protocols.js"; import type { IBaseProtocol } from "./protocols.js";
import type { ISender } from "./sender.js"; import type { ISender } from "./sender.js";
export type ILightPush = ISender & PointToPointProtocol; export type ILightPush = ISender & IBaseProtocol;

View File

@ -3,9 +3,9 @@ import type { PeerId } from "@libp2p/interface-peer-id";
import type { PeerStore } from "@libp2p/interface-peer-store"; import type { PeerStore } from "@libp2p/interface-peer-store";
import { IEnr } from "./enr.js"; import { IEnr } from "./enr.js";
import { PointToPointProtocol } from "./protocols.js"; import { IBaseProtocol } from "./protocols.js";
export interface IPeerExchange extends PointToPointProtocol { export interface IPeerExchange extends IBaseProtocol {
query(params: PeerExchangeQueryParams): Promise<PeerInfo[] | undefined>; query(params: PeerExchangeQueryParams): Promise<PeerInfo[] | undefined>;
} }

View File

@ -1,3 +1,4 @@
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import type { Peer, PeerStore } from "@libp2p/interface-peer-store"; import type { Peer, PeerStore } from "@libp2p/interface-peer-store";
import type { Libp2pOptions } from "libp2p"; import type { Libp2pOptions } from "libp2p";
@ -11,10 +12,12 @@ export enum Protocols {
Filter = "filter", Filter = "filter",
} }
export interface PointToPointProtocol { export interface IBaseProtocol {
multicodec: string; multicodec: string;
peerStore: PeerStore; peerStore: PeerStore;
peers: () => Promise<Peer[]>; peers: () => Promise<Peer[]>;
addLibp2pEventListener: Libp2p["addEventListener"];
removeLibp2pEventListener: Libp2p["removeEventListener"];
} }
export type ProtocolCreateOptions = { export type ProtocolCreateOptions = {

View File

@ -1,5 +1,5 @@
import type { IDecodedMessage, IDecoder } from "./message.js"; import type { IDecodedMessage, IDecoder } from "./message.js";
import type { PointToPointProtocol, ProtocolOptions } from "./protocols.js"; import type { IBaseProtocol, ProtocolOptions } from "./protocols.js";
export enum PageDirection { export enum PageDirection {
BACKWARD = "backward", BACKWARD = "backward",
@ -45,7 +45,7 @@ export type StoreQueryOptions = {
cursor?: Cursor; cursor?: Cursor;
} & ProtocolOptions; } & ProtocolOptions;
export interface IStore extends PointToPointProtocol { export interface IStore extends IBaseProtocol {
queryOrderedCallback: <T extends IDecodedMessage>( queryOrderedCallback: <T extends IDecodedMessage>(
decoders: IDecoder<T>[], decoders: IDecoder<T>[],
callback: (message: T) => Promise<void | boolean> | boolean | void, callback: (message: T) => Promise<void | boolean> | boolean | void,

View File

@ -1,9 +1,9 @@
import type { Stream } from "@libp2p/interface-connection"; import type { Stream } from "@libp2p/interface-connection";
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import type { Multiaddr } from "@multiformats/multiaddr"; import type { Multiaddr } from "@multiformats/multiaddr";
import type { IFilter, IFilterV2 } from "./filter.js"; import type { IFilter, IFilterV2 } from "./filter.js";
import type { Libp2p } from "./libp2p.js";
import type { ILightPush } from "./light_push.js"; import type { ILightPush } from "./light_push.js";
import { Protocols } from "./protocols.js"; import { Protocols } from "./protocols.js";
import type { IRelay } from "./relay.js"; import type { IRelay } from "./relay.js";

View File

@ -80,12 +80,12 @@
"js-sha3": "^0.8.0" "js-sha3": "^0.8.0"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-connection": "^3.0.8", "@libp2p/interface-connection": "^5.1.1",
"@libp2p/interface-connection-manager": "^1.3.7", "@libp2p/interface-connection-manager": "^3.0.1",
"@libp2p/interface-libp2p": "^1.1.2", "@libp2p/interface-libp2p": "^3.2.0",
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-peer-id": "^2.0.2",
"@libp2p/interface-peer-store": "^1.2.8", "@libp2p/interface-peer-store": "^2.0.4",
"@libp2p/interface-registrar": "^2.0.8", "@libp2p/interface-registrar": "^2.0.12",
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-node-resolve": "^15.0.2",

View File

@ -48,28 +48,29 @@
"node": ">=16" "node": ">=16"
}, },
"dependencies": { "dependencies": {
"@libp2p/interface-peer-discovery": "^1.0.5", "@libp2p/interface-peer-discovery": "^2.0.0",
"@libp2p/interfaces": "^3.3.1", "@libp2p/interfaces": "^3.3.2",
"@waku/core": "0.0.20", "@waku/core": "0.0.20",
"@waku/enr": "0.0.14", "@waku/enr": "0.0.14",
"@waku/proto": "0.0.5", "@waku/proto": "0.0.5",
"@waku/utils": "0.0.8", "@waku/utils": "0.0.8",
"@waku/interfaces": "0.0.15",
"debug": "^4.3.4", "debug": "^4.3.4",
"it-all": "^3.0.2", "it-all": "^3.0.2",
"it-length-prefixed": "^9.0.1", "it-length-prefixed": "^9.0.1",
"it-pipe": "^3.0.1" "it-pipe": "^3.0.1"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-connection-manager": "^1.3.7", "@libp2p/interface-connection-manager": "^3.0.1",
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-libp2p": "^3.2.0",
"@libp2p/interface-peer-info": "^1.0.8", "@libp2p/interface-peer-id": "^2.0.2",
"@libp2p/interface-peer-store": "^1.2.8", "@libp2p/interface-peer-info": "^1.0.10",
"@libp2p/interface-registrar": "^2.0.8", "@libp2p/interface-peer-store": "^2.0.4",
"@libp2p/interface-registrar": "^2.0.12",
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-node-resolve": "^15.0.2",
"@waku/build-utils": "*", "@waku/build-utils": "*",
"@waku/interfaces": "0.0.15",
"chai": "^4.3.7", "chai": "^4.3.7",
"cspell": "^6.31.1", "cspell": "^6.31.1",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",

View File

@ -1,9 +1,8 @@
import type { ConnectionManager } from "@libp2p/interface-connection-manager";
import type { PeerStore } from "@libp2p/interface-peer-store";
import { BaseProtocol } from "@waku/core/lib/base_protocol"; import { BaseProtocol } from "@waku/core/lib/base_protocol";
import { EnrDecoder } from "@waku/enr"; import { EnrDecoder } from "@waku/enr";
import type { import type {
IPeerExchange, IPeerExchange,
Libp2pComponents,
PeerExchangeQueryParams, PeerExchangeQueryParams,
PeerInfo, PeerInfo,
} from "@waku/interfaces"; } from "@waku/interfaces";
@ -20,11 +19,6 @@ export const PeerExchangeCodec = "/vac/waku/peer-exchange/2.0.0-alpha1";
const log = debug("waku:peer-exchange"); const log = debug("waku:peer-exchange");
export interface PeerExchangeComponents {
peerStore: PeerStore;
connectionManager: ConnectionManager;
}
/** /**
* Implementation of the Peer Exchange protocol (https://rfc.vac.dev/spec/34/) * Implementation of the Peer Exchange protocol (https://rfc.vac.dev/spec/34/)
*/ */
@ -34,14 +28,8 @@ export class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
/** /**
* @param components - libp2p components * @param components - libp2p components
*/ */
constructor(public components: PeerExchangeComponents) { constructor(components: Libp2pComponents) {
super( super(PeerExchangeCodec, components);
PeerExchangeCodec,
components.peerStore,
components.connectionManager.getConnections.bind(
components.connectionManager
)
);
this.multicodec = PeerExchangeCodec; this.multicodec = PeerExchangeCodec;
} }
@ -102,8 +90,7 @@ export class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
* @returns A function that creates a new peer exchange protocol * @returns A function that creates a new peer exchange protocol
*/ */
export function wakuPeerExchange(): ( export function wakuPeerExchange(): (
components: PeerExchangeComponents components: Libp2pComponents
) => WakuPeerExchange { ) => WakuPeerExchange {
return (components: PeerExchangeComponents) => return (components: Libp2pComponents) => new WakuPeerExchange(components);
new WakuPeerExchange(components);
} }

View File

@ -1,19 +1,16 @@
import type { PeerUpdate } from "@libp2p/interface-libp2p";
import type { import type {
PeerDiscovery, PeerDiscovery,
PeerDiscoveryEvents, PeerDiscoveryEvents,
} from "@libp2p/interface-peer-discovery"; } from "@libp2p/interface-peer-discovery";
import { symbol } from "@libp2p/interface-peer-discovery"; import { peerDiscovery as symbol } from "@libp2p/interface-peer-discovery";
import type { PeerId } from "@libp2p/interface-peer-id"; import type { PeerId } from "@libp2p/interface-peer-id";
import type { PeerInfo } from "@libp2p/interface-peer-info"; import type { PeerInfo } from "@libp2p/interface-peer-info";
import type { PeerProtocolsChangeData } from "@libp2p/interface-peer-store";
import { CustomEvent, EventEmitter } from "@libp2p/interfaces/events"; import { CustomEvent, EventEmitter } from "@libp2p/interfaces/events";
import type { Libp2pComponents } from "@waku/interfaces";
import debug from "debug"; import debug from "debug";
import { import { PeerExchangeCodec, WakuPeerExchange } from "./waku_peer_exchange.js";
PeerExchangeCodec,
PeerExchangeComponents,
WakuPeerExchange,
} from "./waku_peer_exchange.js";
const log = debug("waku:peer-exchange-discovery"); const log = debug("waku:peer-exchange-discovery");
@ -56,17 +53,19 @@ export class PeerExchangeDiscovery
extends EventEmitter<PeerDiscoveryEvents> extends EventEmitter<PeerDiscoveryEvents>
implements PeerDiscovery implements PeerDiscovery
{ {
private readonly components: PeerExchangeComponents; private readonly components: Libp2pComponents;
private readonly peerExchange: WakuPeerExchange; private readonly peerExchange: WakuPeerExchange;
private readonly options: Options; private readonly options: Options;
private isStarted: boolean; private isStarted: boolean;
private queryingPeers: Set<string> = new Set(); private queryingPeers: Set<string> = new Set();
private queryAttempts: Map<string, number> = new Map(); private queryAttempts: Map<string, number> = new Map();
private readonly eventHandler = ( private readonly handleDiscoveredPeer = (
event: CustomEvent<PeerProtocolsChangeData> event: CustomEvent<PeerUpdate>
): void => { ): void => {
const { protocols, peerId } = event.detail; const {
peer: { protocols, id: peerId },
} = event.detail;
if ( if (
!protocols.includes(PeerExchangeCodec) || !protocols.includes(PeerExchangeCodec) ||
this.queryingPeers.has(peerId.toString()) this.queryingPeers.has(peerId.toString())
@ -79,7 +78,7 @@ export class PeerExchangeDiscovery
); );
}; };
constructor(components: PeerExchangeComponents, options: Options = {}) { constructor(components: Libp2pComponents, options: Options = {}) {
super(); super();
this.components = components; this.components = components;
this.peerExchange = new WakuPeerExchange(components); this.peerExchange = new WakuPeerExchange(components);
@ -97,9 +96,10 @@ export class PeerExchangeDiscovery
log("Starting peer exchange node discovery, discovering peers"); log("Starting peer exchange node discovery, discovering peers");
this.components.peerStore.addEventListener( // might be better to use "peer:identify" or "peer:update"
"change:protocols", this.components.events.addEventListener(
this.eventHandler "peer:update",
this.handleDiscoveredPeer
); );
} }
@ -111,9 +111,9 @@ export class PeerExchangeDiscovery
log("Stopping peer exchange node discovery"); log("Stopping peer exchange node discovery");
this.isStarted = false; this.isStarted = false;
this.queryingPeers.clear(); this.queryingPeers.clear();
this.components.peerStore.removeEventListener( this.components.events.removeEventListener(
"change:protocols", "peer:update",
this.eventHandler this.handleDiscoveredPeer
); );
} }
@ -170,33 +170,31 @@ export class PeerExchangeDiscovery
} }
const { peerId, peerInfo } = ENR; const { peerId, peerInfo } = ENR;
if (!peerId || !peerInfo) {
if (!peerId || !peerInfo) continue;
const { multiaddrs } = peerInfo;
if (
(await this.components.peerStore.getTags(peerId)).find(
({ name }) => name === DEFAULT_PEER_EXCHANGE_TAG_NAME
)
)
continue; continue;
}
await this.components.peerStore.tagPeer( const hasPeer = await this.components.peerStore.has(peerId);
peerId, if (hasPeer) {
DEFAULT_PEER_EXCHANGE_TAG_NAME, continue;
{ }
value: this.options.tagValue ?? DEFAULT_PEER_EXCHANGE_TAG_VALUE,
ttl: this.options.tagTTL ?? DEFAULT_PEER_EXCHANGE_TAG_TTL, // update the tags for the peer
} await this.components.peerStore.save(peerId, {
); tags: {
[DEFAULT_PEER_EXCHANGE_TAG_NAME]: {
value: this.options.tagValue ?? DEFAULT_PEER_EXCHANGE_TAG_VALUE,
ttl: this.options.tagTTL ?? DEFAULT_PEER_EXCHANGE_TAG_TTL,
},
},
});
this.dispatchEvent( this.dispatchEvent(
new CustomEvent<PeerInfo>("peer", { new CustomEvent<PeerInfo>("peer", {
detail: { detail: {
id: peerId, id: peerId,
multiaddrs,
protocols: [], protocols: [],
multiaddrs: peerInfo.multiaddrs,
}, },
}) })
); );
@ -211,8 +209,8 @@ export class PeerExchangeDiscovery
} }
export function wakuPeerExchangeDiscovery(): ( export function wakuPeerExchangeDiscovery(): (
components: PeerExchangeComponents components: Libp2pComponents
) => PeerExchangeDiscovery { ) => PeerExchangeDiscovery {
return (components: PeerExchangeComponents) => return (components: Libp2pComponents) =>
new PeerExchangeDiscovery(components); new PeerExchangeDiscovery(components);
} }

View File

@ -49,7 +49,7 @@
"node": ">=16" "node": ">=16"
}, },
"dependencies": { "dependencies": {
"@chainsafe/libp2p-gossipsub": "^6.1.0", "@chainsafe/libp2p-gossipsub": "^9.0.0",
"@noble/hashes": "^1.3.0", "@noble/hashes": "^1.3.0",
"@waku/core": "0.0.20", "@waku/core": "0.0.20",
"@waku/interfaces": "0.0.15", "@waku/interfaces": "0.0.15",
@ -60,6 +60,7 @@
"fast-check": "^3.8.1" "fast-check": "^3.8.1"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-pubsub": "^4.0.1",
"@rollup/plugin-commonjs": "^24.1.0", "@rollup/plugin-commonjs": "^24.1.0",
"@waku/build-utils": "*", "@waku/build-utils": "*",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",

View File

@ -6,7 +6,6 @@ import {
} from "@chainsafe/libp2p-gossipsub"; } from "@chainsafe/libp2p-gossipsub";
import type { PeerIdStr, TopicStr } from "@chainsafe/libp2p-gossipsub/types"; import type { PeerIdStr, TopicStr } from "@chainsafe/libp2p-gossipsub/types";
import { SignaturePolicy } from "@chainsafe/libp2p-gossipsub/types"; import { SignaturePolicy } from "@chainsafe/libp2p-gossipsub/types";
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PubSub } from "@libp2p/interface-pubsub"; import type { PubSub } from "@libp2p/interface-pubsub";
import { sha256 } from "@noble/hashes/sha256"; import { sha256 } from "@noble/hashes/sha256";
import { DefaultPubSubTopic } from "@waku/core"; import { DefaultPubSubTopic } from "@waku/core";
@ -19,6 +18,7 @@ import {
IEncoder, IEncoder,
IMessage, IMessage,
IRelay, IRelay,
Libp2p,
ProtocolCreateOptions, ProtocolCreateOptions,
ProtocolOptions, ProtocolOptions,
SendError, SendError,
@ -59,13 +59,13 @@ class Relay implements IRelay {
private observers: Map<ContentTopic, Set<unknown>>; private observers: Map<ContentTopic, Set<unknown>>;
constructor(libp2p: Libp2p, options?: Partial<RelayCreateOptions>) { constructor(libp2p: Libp2p, options?: Partial<RelayCreateOptions>) {
if (!this.isRelayPubSub(libp2p.pubsub)) { if (!this.isRelayPubSub(libp2p.services.pubsub)) {
throw Error( throw Error(
`Failed to initialize Relay. libp2p.pubsub does not support ${Relay.multicodec}` `Failed to initialize Relay. libp2p.pubsub does not support ${Relay.multicodec}`
); );
} }
this.gossipSub = libp2p.pubsub as GossipSub; this.gossipSub = libp2p.services.pubsub as GossipSub;
this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic; this.pubSubTopic = options?.pubSubTopic ?? DefaultPubSubTopic;
if (this.gossipSub.isStarted()) { if (this.gossipSub.isStarted()) {
@ -240,7 +240,7 @@ class Relay implements IRelay {
this.gossipSub.subscribe(pubSubTopic); this.gossipSub.subscribe(pubSubTopic);
} }
private isRelayPubSub(pubsub: PubSub): boolean { private isRelayPubSub(pubsub: PubSub | undefined): boolean {
return pubsub?.multicodecs?.includes(Relay.multicodec) || false; return pubsub?.multicodecs?.includes(Relay.multicodec) || false;
} }
} }

View File

@ -48,35 +48,36 @@
"node": ">=16" "node": ">=16"
}, },
"dependencies": { "dependencies": {
"@chainsafe/libp2p-noise": "^11.0.0", "@chainsafe/libp2p-noise": "^12.0.1",
"@libp2p/mplex": "^7.1.1", "@libp2p/mplex": "^8.0.4",
"@libp2p/websockets": "^5.0.3", "@libp2p/websockets": "^6.0.3",
"@waku/utils": "0.0.8", "@waku/utils": "0.0.8",
"@waku/relay": "0.0.3", "@waku/relay": "0.0.3",
"@waku/core": "0.0.20", "@waku/core": "0.0.20",
"@waku/interfaces": "0.0.15", "@waku/interfaces": "0.0.15",
"@waku/dns-discovery": "0.0.14", "@waku/dns-discovery": "0.0.14",
"libp2p": "^0.42.2" "libp2p": "^0.45.9"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-address-manager": "^2.0.4", "@libp2p/interface-address-manager": "^3.0.1",
"@libp2p/interface-connection": "^3.0.8", "@libp2p/interface-connection": "^5.1.1",
"@libp2p/interface-connection-manager": "^1.3.7", "@libp2p/interface-connection-manager": "^3.0.1",
"@libp2p/interface-content-routing": "^2.1.1", "@libp2p/interface-content-routing": "^2.1.1",
"@libp2p/interface-dht": "^2.0.1", "@libp2p/interface-dht": "^2.0.3",
"@libp2p/interface-libp2p": "^1.1.2", "@libp2p/interface-libp2p": "^3.2.0",
"@libp2p/interface-metrics": "^4.0.7", "@libp2p/interface-metrics": "^4.0.8",
"@libp2p/interface-peer-discovery": "^1.0.5", "@libp2p/interface-peer-discovery": "^2.0.0",
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-peer-id": "^2.0.2",
"@libp2p/interface-peer-routing": "^1.0.8", "@libp2p/interface-peer-routing": "^1.1.1",
"@libp2p/interface-peer-store": "^1.2.8", "@libp2p/interface-peer-store": "^2.0.4",
"@libp2p/interface-pubsub": "^3.0.6", "@libp2p/interface-pubsub": "^4.0.1",
"@libp2p/interface-registrar": "^2.0.8", "@libp2p/interface-registrar": "^2.0.12",
"@libp2p/interface-transport": "^2.1.1", "@libp2p/interface-transport": "^4.0.3",
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-node-resolve": "^15.0.2",
"@waku/build-utils": "*", "@waku/build-utils": "*",
"@chainsafe/libp2p-gossipsub": "^9.0.0",
"cspell": "^6.31.1", "cspell": "^6.31.1",
"interface-datastore": "^7.0.4", "interface-datastore": "^7.0.4",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",

View File

@ -1,6 +1,5 @@
import type { GossipSub } from "@chainsafe/libp2p-gossipsub"; import type { GossipSub } from "@chainsafe/libp2p-gossipsub";
import { noise } from "@chainsafe/libp2p-noise"; import { noise } from "@chainsafe/libp2p-noise";
import type { Libp2p } from "@libp2p/interface-libp2p";
import type { PeerDiscovery } from "@libp2p/interface-peer-discovery"; import type { PeerDiscovery } from "@libp2p/interface-peer-discovery";
import { mplex } from "@libp2p/mplex"; import { mplex } from "@libp2p/mplex";
import { webSockets } from "@libp2p/websockets"; import { webSockets } from "@libp2p/websockets";
@ -19,14 +18,16 @@ import type {
FullNode, FullNode,
IFilter, IFilter,
IFilterV2, IFilterV2,
Libp2p,
Libp2pComponents,
LightNode, LightNode,
ProtocolCreateOptions, ProtocolCreateOptions,
RelayNode, RelayNode,
} from "@waku/interfaces"; } from "@waku/interfaces";
import { RelayCreateOptions, wakuGossipSub, wakuRelay } from "@waku/relay"; import { RelayCreateOptions, wakuGossipSub, wakuRelay } from "@waku/relay";
import { createLibp2p, Libp2pOptions } from "libp2p"; import { createLibp2p, Libp2pOptions } from "libp2p";
import { identifyService } from "libp2p/identify";
import type { Libp2pComponents } from "./libp2p_components.js"; import { pingService } from "libp2p/ping";
const DEFAULT_NODE_REQUIREMENTS = { const DEFAULT_NODE_REQUIREMENTS = {
lightPush: 1, lightPush: 1,
@ -174,25 +175,31 @@ export function defaultPeerDiscovery(): (
return wakuDnsDiscovery([enrTree["PROD"]], DEFAULT_NODE_REQUIREMENTS); return wakuDnsDiscovery([enrTree["PROD"]], DEFAULT_NODE_REQUIREMENTS);
} }
type PubsubService = {
pubsub?: (components: Libp2pComponents) => GossipSub;
};
export async function defaultLibp2p( export async function defaultLibp2p(
wakuGossipSub?: (components: Libp2pComponents) => GossipSub, wakuGossipSub?: PubsubService["pubsub"],
options?: Partial<Libp2pOptions>, options?: Partial<Libp2pOptions>,
userAgent?: string userAgent?: string
): Promise<Libp2p> { ): Promise<Libp2p> {
const libp2pOpts = Object.assign( const pubsubService: PubsubService = wakuGossipSub
{ ? { pubsub: wakuGossipSub }
transports: [webSockets({ filter: filterAll })], : {};
streamMuxers: [mplex()],
connectionEncryption: [noise()],
identify: {
host: {
agentVersion: userAgent ?? DefaultUserAgent,
},
},
} as Libp2pOptions,
wakuGossipSub ? { pubsub: wakuGossipSub } : {},
options ?? {}
);
return createLibp2p(libp2pOpts); return createLibp2p({
transports: [webSockets({ filter: filterAll })],
streamMuxers: [mplex()],
connectionEncryption: [noise()],
...options,
services: {
identify: identifyService({
agentVersion: userAgent ?? DefaultUserAgent,
}),
ping: pingService(),
...pubsubService,
...options?.services,
},
}) as any as Libp2p; // TODO: make libp2p include it;
} }

View File

@ -1,39 +0,0 @@
import type { AddressManager } from "@libp2p/interface-address-manager";
import type {
ConnectionGater,
ConnectionProtector,
} from "@libp2p/interface-connection";
import type {
ConnectionManager,
Dialer,
} from "@libp2p/interface-connection-manager";
import type { ContentRouting } from "@libp2p/interface-content-routing";
import type { DualDHT } from "@libp2p/interface-dht";
import type { Metrics } from "@libp2p/interface-metrics";
import type { PeerId } from "@libp2p/interface-peer-id";
import type { PeerRouting } from "@libp2p/interface-peer-routing";
import type { PeerStore } from "@libp2p/interface-peer-store";
import type { PubSub } from "@libp2p/interface-pubsub";
import type { Registrar } from "@libp2p/interface-registrar";
import type { TransportManager, Upgrader } from "@libp2p/interface-transport";
import type { Datastore } from "interface-datastore";
// TODO: Get libp2p to export this.
export interface Libp2pComponents {
peerId: PeerId;
addressManager: AddressManager;
peerStore: PeerStore;
upgrader: Upgrader;
registrar: Registrar;
connectionManager: ConnectionManager;
transportManager: TransportManager;
connectionGater: ConnectionGater;
contentRouting: ContentRouting;
peerRouting: PeerRouting;
datastore: Datastore;
connectionProtector?: ConnectionProtector;
dialer: Dialer;
metrics?: Metrics;
dht?: DualDHT;
pubsub?: PubSub;
}

View File

@ -49,7 +49,7 @@
"node": ">=16" "node": ">=16"
}, },
"dependencies": { "dependencies": {
"@libp2p/peer-id": "^2.0.3", "@libp2p/peer-id": "^2.0.4",
"@waku/core": "*", "@waku/core": "*",
"@waku/enr": "*", "@waku/enr": "*",
"@waku/interfaces": "*", "@waku/interfaces": "*",
@ -63,10 +63,9 @@
"tail": "^2.2.6" "tail": "^2.2.6"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/bootstrap": "^6.0.3", "@libp2p/bootstrap": "^8.0.0",
"@libp2p/components": "^3.1.1",
"@libp2p/interface-peer-discovery-compliance-tests": "^2.0.8", "@libp2p/interface-peer-discovery-compliance-tests": "^2.0.8",
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-peer-id": "^2.0.2",
"@types/chai": "^4.3.4", "@types/chai": "^4.3.4",
"@types/dockerode": "^3.3.17", "@types/dockerode": "^3.3.17",
"@types/mocha": "^10.0.1", "@types/mocha": "^10.0.1",
@ -84,6 +83,9 @@
"mocha": "^10.2.0", "mocha": "^10.2.0",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"typescript": "^5.0.4" "typescript": "^5.0.4",
"interface-datastore": "^8.2.3",
"libp2p": "^0.45.9",
"datastore-core": "^9.2.0"
} }
} }

View File

@ -68,7 +68,7 @@ describe("ConnectionManager", function () {
describe("dialPeer method", function () { describe("dialPeer method", function () {
beforeEach(function () { beforeEach(function () {
getConnectionsStub = sinon.stub( getConnectionsStub = sinon.stub(
(connectionManager as any).libp2pComponents, (connectionManager as any).libp2p,
"getConnections" "getConnections"
); );
getTagNamesForPeerStub = sinon.stub( getTagNamesForPeerStub = sinon.stub(

View File

@ -1,6 +1,5 @@
import { Components } from "@libp2p/components";
import tests from "@libp2p/interface-peer-discovery-compliance-tests"; import tests from "@libp2p/interface-peer-discovery-compliance-tests";
import { Peer } from "@libp2p/interface-peer-store"; import { EventEmitter } from "@libp2p/interfaces/events";
import { createSecp256k1PeerId } from "@libp2p/peer-id-factory"; import { createSecp256k1PeerId } from "@libp2p/peer-id-factory";
import { PersistentPeerStore } from "@libp2p/peer-store"; import { PersistentPeerStore } from "@libp2p/peer-store";
import { import {
@ -9,9 +8,11 @@ import {
PeerDiscoveryDns, PeerDiscoveryDns,
wakuDnsDiscovery, wakuDnsDiscovery,
} from "@waku/dns-discovery"; } from "@waku/dns-discovery";
import { Libp2pComponents } from "@waku/interfaces";
import { createLightNode } from "@waku/sdk"; import { createLightNode } from "@waku/sdk";
import { expect } from "chai"; import { expect } from "chai";
import { MemoryDatastore } from "datastore-core"; import { MemoryDatastore } from "datastore-core/memory";
import { Datastore } from "interface-datastore";
import { delay } from "../src/delay.js"; import { delay } from "../src/delay.js";
@ -22,12 +23,13 @@ describe("DNS Discovery: Compliance Test", function () {
tests({ tests({
async setup() { async setup() {
// create libp2p mock peerStore // create libp2p mock peerStore
const components = new Components({ const components = {
peerStore: new PersistentPeerStore({ peerStore: new PersistentPeerStore({
events: new EventEmitter(),
peerId: await createSecp256k1PeerId(), peerId: await createSecp256k1PeerId(),
datastore: new MemoryDatastore(), datastore: new MemoryDatastore() as any as Datastore,
}), }),
}); } as unknown as Libp2pComponents;
return new PeerDiscoveryDns(components, { return new PeerDiscoveryDns(components, {
enrUrls: [enrTree["PROD"]], enrUrls: [enrTree["PROD"]],
@ -69,22 +71,16 @@ describe("DNS Node Discovery [live data]", function () {
await waku.start(); await waku.start();
const allPeers = await waku.libp2p.peerStore.all(); const allPeers = await waku.libp2p.peerStore.all();
let dnsPeers = 0;
const dnsPeers: Peer[] = [];
for (const peer of allPeers) { for (const peer of allPeers) {
const tags = await waku.libp2p.peerStore.getTags(peer.id); const hasTag = peer.tags.has("bootstrap");
let hasTag = false; if (hasTag) {
for (const tag of tags) { dnsPeers += 1;
hasTag = tag.name === "bootstrap";
if (hasTag) {
dnsPeers.push(peer);
break;
}
} }
expect(hasTag).to.be.eq(true); expect(hasTag).to.be.eq(true);
} }
expect(dnsPeers.length).to.eq(maxQuantity); expect(dnsPeers).to.eq(maxQuantity);
}); });
it(`should retrieve ${maxQuantity} multiaddrs for test.waku.nodes.status.im`, async function () { it(`should retrieve ${maxQuantity} multiaddrs for test.waku.nodes.status.im`, async function () {

View File

@ -49,13 +49,11 @@ describe("Peer Exchange", () => {
const foundPxPeer = await new Promise<boolean>((resolve) => { const foundPxPeer = await new Promise<boolean>((resolve) => {
const testNodes = getPredefinedBootstrapNodes(Fleet.Test, 3); const testNodes = getPredefinedBootstrapNodes(Fleet.Test, 3);
waku.libp2p.addEventListener("peer:discovery", (evt) => { waku.libp2p.addEventListener("peer:discovery", (evt) => {
const { multiaddrs } = evt.detail; const peerId = evt.detail.id.toString();
multiaddrs.forEach((ma) => { const isBootstrapNode = testNodes.find((n) => n.includes(peerId));
const isBootstrapNode = testNodes.find((n) => n === ma.toString()); if (!isBootstrapNode) {
if (!isBootstrapNode) { resolve(true);
resolve(true); }
}
});
}); });
}); });
@ -105,23 +103,7 @@ describe("Peer Exchange", () => {
await waku.start(); await waku.start();
await waku.libp2p.dialProtocol(nwaku2Ma, PeerExchangeCodec); await waku.libp2p.dialProtocol(nwaku2Ma, PeerExchangeCodec);
await new Promise<void>((resolve) => { const components = waku.libp2p.components as unknown as Libp2pComponents;
waku.libp2p.peerStore.addEventListener("change:protocols", (evt) => {
if (evt.detail.protocols.includes(PeerExchangeCodec)) {
resolve();
}
});
});
// the forced type casting is done in ref to https://github.com/libp2p/js-libp2p-interfaces/issues/338#issuecomment-1431643645
const { connectionManager, registrar, peerStore } =
waku.libp2p as unknown as Libp2pComponents;
const components = {
connectionManager: connectionManager,
registrar: registrar,
peerStore: peerStore,
};
const peerExchange = new WakuPeerExchange(components); const peerExchange = new WakuPeerExchange(components);
const numPeersToRequest = 1; const numPeersToRequest = 1;
@ -145,7 +127,8 @@ describe("Peer Exchange", () => {
expect(doesPeerIdExistInResponse).to.be.equal(true); expect(doesPeerIdExistInResponse).to.be.equal(true);
expect(waku.libp2p.peerStore.has(await nwaku2.getPeerId())).to.be.true; expect(await waku.libp2p.peerStore.has(await nwaku2.getPeerId())).to.be
.true;
}); });
}); });
@ -178,30 +161,21 @@ describe("Peer Exchange", () => {
discv5BootstrapNode: enr, discv5BootstrapNode: enr,
}); });
waku = await createLightNode(); waku = await createLightNode({
libp2p: {
peerDiscovery: [wakuPeerExchangeDiscovery()],
},
});
const peerExchange = waku.libp2p.components["components"][
"peer-discovery-0"
] as PeerExchangeDiscovery;
await waku.start(); await waku.start();
const nwaku2Ma = await nwaku2.getMultiaddrWithId(); const nwaku2Ma = await nwaku2.getMultiaddrWithId();
await waku.libp2p.dialProtocol(nwaku2Ma, PeerExchangeCodec); await waku.libp2p.dialProtocol(nwaku2Ma, PeerExchangeCodec);
await new Promise<void>((resolve) => {
waku.libp2p.peerStore.addEventListener("change:protocols", (evt) => {
if (evt.detail.protocols.includes(PeerExchangeCodec)) {
resolve();
}
});
});
// the forced type casting is done in ref to https://github.com/libp2p/js-libp2p-interfaces/issues/338#issuecomment-1431643645 return peerExchange;
const { connectionManager, registrar, peerStore } =
waku.libp2p as unknown as Libp2pComponents;
const components = {
connectionManager: connectionManager,
registrar: registrar,
peerStore: peerStore,
};
return new PeerExchangeDiscovery(components);
}, },
teardown: async () => { teardown: async () => {
await nwaku1?.stop(); await nwaku1?.stop();

View File

@ -67,10 +67,9 @@ describe("Waku Relay [node only]", () => {
}).then((waku) => waku.start().then(() => waku)), }).then((waku) => waku.start().then(() => waku)),
]); ]);
log("Instances started, adding waku2 to waku1's address book"); log("Instances started, adding waku2 to waku1's address book");
await waku1.libp2p.peerStore.addressBook.set( await waku1.libp2p.peerStore.merge(waku2.libp2p.peerId, {
waku2.libp2p.peerId, multiaddrs: waku2.libp2p.getMultiaddrs(),
waku2.libp2p.getMultiaddrs() });
);
await waku1.dial(waku2.libp2p.peerId); await waku1.dial(waku2.libp2p.peerId);
log("Wait for mutual pubsub subscription"); log("Wait for mutual pubsub subscription");
@ -90,11 +89,11 @@ describe("Waku Relay [node only]", () => {
it("Subscribe", async function () { it("Subscribe", async function () {
log("Getting subscribers"); log("Getting subscribers");
const subscribers1 = waku1.libp2p.pubsub const subscribers1 = waku1.libp2p.services
.getSubscribers(DefaultPubSubTopic) .pubsub!.getSubscribers(DefaultPubSubTopic)
.map((p) => p.toString()); .map((p) => p.toString());
const subscribers2 = waku2.libp2p.pubsub const subscribers2 = waku2.libp2p.services
.getSubscribers(DefaultPubSubTopic) .pubsub!.getSubscribers(DefaultPubSubTopic)
.map((p) => p.toString()); .map((p) => p.toString());
log("Asserting mutual subscription"); log("Asserting mutual subscription");
@ -291,14 +290,12 @@ describe("Waku Relay [node only]", () => {
}).then((waku) => waku.start().then(() => waku)), }).then((waku) => waku.start().then(() => waku)),
]); ]);
await waku1.libp2p.peerStore.addressBook.set( await waku1.libp2p.peerStore.merge(waku2.libp2p.peerId, {
waku2.libp2p.peerId, multiaddrs: waku2.libp2p.getMultiaddrs(),
waku2.libp2p.getMultiaddrs() });
); await waku3.libp2p.peerStore.merge(waku2.libp2p.peerId, {
await waku3.libp2p.peerStore.addressBook.set( multiaddrs: waku2.libp2p.getMultiaddrs(),
waku2.libp2p.peerId, });
waku2.libp2p.getMultiaddrs()
);
await Promise.all([ await Promise.all([
waku1.dial(waku2.libp2p.peerId), waku1.dial(waku2.libp2p.peerId),
waku3.dial(waku2.libp2p.peerId), waku3.dial(waku2.libp2p.peerId),
@ -356,10 +353,9 @@ describe("Waku Relay [node only]", () => {
}).then((waku) => waku.start().then(() => waku)), }).then((waku) => waku.start().then(() => waku)),
]); ]);
await waku1.libp2p.peerStore.addressBook.set( await waku1.libp2p.peerStore.merge(waku2.libp2p.peerId, {
waku2.libp2p.peerId, multiaddrs: waku2.libp2p.getMultiaddrs(),
waku2.libp2p.getMultiaddrs() });
);
await Promise.all([waku1.dial(waku2.libp2p.peerId)]); await Promise.all([waku1.dial(waku2.libp2p.peerId)]);
await Promise.all([ await Promise.all([
@ -428,7 +424,8 @@ describe("Waku Relay [node only]", () => {
while (subscribers.length === 0) { while (subscribers.length === 0) {
await delay(200); await delay(200);
subscribers = waku.libp2p.pubsub.getSubscribers(DefaultPubSubTopic); subscribers =
waku.libp2p.services.pubsub!.getSubscribers(DefaultPubSubTopic);
} }
const nimPeerId = await nwaku.getPeerId(); const nimPeerId = await nwaku.getPeerId();

View File

@ -83,7 +83,7 @@ describe("Waku Dial [node only]", function () {
const connectedPeerID: PeerId = await new Promise((resolve) => { const connectedPeerID: PeerId = await new Promise((resolve) => {
waku.libp2p.addEventListener("peer:connect", (evt) => { waku.libp2p.addEventListener("peer:connect", (evt) => {
resolve(evt.detail.remotePeer); resolve(evt.detail);
}); });
}); });
@ -108,7 +108,7 @@ describe("Waku Dial [node only]", function () {
const connectedPeerID: PeerId = await new Promise((resolve) => { const connectedPeerID: PeerId = await new Promise((resolve) => {
waku.libp2p.addEventListener("peer:connect", (evt) => { waku.libp2p.addEventListener("peer:connect", (evt) => {
resolve(evt.detail.remotePeer); resolve(evt.detail);
}); });
}); });
@ -139,10 +139,9 @@ describe("Decryption Keys", () => {
}).then((waku) => waku.start().then(() => waku)), }).then((waku) => waku.start().then(() => waku)),
]); ]);
await waku1.libp2p.peerStore.addressBook.set( await waku1.libp2p.peerStore.merge(waku2.libp2p.peerId, {
waku2.libp2p.peerId, multiaddrs: waku2.libp2p.getMultiaddrs(),
waku2.libp2p.getMultiaddrs() });
);
await waku1.dial(waku2.libp2p.peerId); await waku1.dial(waku2.libp2p.peerId);
await Promise.all([ await Promise.all([
@ -214,22 +213,21 @@ describe("User Agent", () => {
}).then((waku) => waku.start().then(() => waku)), }).then((waku) => waku.start().then(() => waku)),
]); ]);
await waku1.libp2p.peerStore.addressBook.set( await waku1.libp2p.peerStore.save(waku2.libp2p.peerId, {
waku2.libp2p.peerId, multiaddrs: waku2.libp2p.getMultiaddrs(),
waku2.libp2p.getMultiaddrs() });
);
await waku1.dial(waku2.libp2p.peerId); await waku1.dial(waku2.libp2p.peerId);
await waitForRemotePeer(waku1); await waitForRemotePeer(waku1);
const [waku1PeerInfo, waku2PeerInfo] = await Promise.all([ const [waku1PeerInfo, waku2PeerInfo] = await Promise.all([
waku2.libp2p.peerStore.metadataBook.get(waku1.libp2p.peerId), waku2.libp2p.peerStore.get(waku1.libp2p.peerId),
waku1.libp2p.peerStore.metadataBook.get(waku2.libp2p.peerId), waku1.libp2p.peerStore.get(waku2.libp2p.peerId),
]); ]);
expect(bytesToUtf8(waku1PeerInfo.get("AgentVersion")!)).to.eq( expect(bytesToUtf8(waku1PeerInfo.metadata.get("AgentVersion")!)).to.eq(
waku1UserAgent waku1UserAgent
); );
expect(bytesToUtf8(waku2PeerInfo.get("AgentVersion")!)).to.eq( expect(bytesToUtf8(waku2PeerInfo.metadata.get("AgentVersion")!)).to.eq(
DefaultUserAgent DefaultUserAgent
); );
}); });

View File

@ -69,9 +69,9 @@
"uint8arrays": "^4.0.3" "uint8arrays": "^4.0.3"
}, },
"devDependencies": { "devDependencies": {
"@libp2p/interface-connection": "^3.0.8", "@libp2p/interface-connection": "^5.1.1",
"@libp2p/interface-peer-id": "^2.0.1", "@libp2p/interface-peer-id": "^2.0.2",
"@libp2p/interface-peer-store": "^1.2.8", "@libp2p/interface-peer-store": "^2.0.4",
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-json": "^6.0.0", "@rollup/plugin-json": "^6.0.0",
"@rollup/plugin-node-resolve": "^15.0.2", "@rollup/plugin-node-resolve": "^15.0.2",