chore: simplify protocol creation (#2283)

* simplify protocol creation

* up relay

* fix check

* up size limit config
This commit is contained in:
Sasha 2025-02-25 18:41:32 +01:00 committed by GitHub
parent 87a918d9cc
commit 0ede57f387
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 108 additions and 102 deletions

View File

@ -40,22 +40,22 @@ module.exports = [
{
name: "Privacy preserving protocols",
path: "packages/relay/bundle/index.js",
import: "{ wakuRelay }",
import: "{ Relay }",
},
{
name: "Waku Filter",
path: "packages/sdk/bundle/index.js",
import: "{ wakuFilter }",
import: "{ Filter }",
},
{
name: "Waku LightPush",
path: "packages/sdk/bundle/index.js",
import: "{ wakuLightPush }",
import: "{ LightPush }",
},
{
name: "History retrieval protocols",
path: "packages/sdk/bundle/index.js",
import: "{ wakuStore }",
import: "{ Store }",
},
{
name: "Deterministic Message Hashing",

View File

@ -1,7 +1,7 @@
import type { CreateNodeOptions, RelayNode } from "@waku/interfaces";
import { createLibp2pAndUpdateOptions, WakuNode } from "@waku/sdk";
import { RelayCreateOptions, wakuGossipSub, wakuRelay } from "./relay.js";
import { Relay, RelayCreateOptions, wakuGossipSub } from "./relay.js";
/**
* Create a Waku node that uses Waku Relay to send and receive messages,
@ -27,7 +27,10 @@ export async function createRelayNode(
};
const { libp2p, pubsubTopics } = await createLibp2pAndUpdateOptions(options);
const relay = wakuRelay(pubsubTopics || [])(libp2p);
const relay = new Relay({
pubsubTopics: pubsubTopics || [],
libp2p
});
return new WakuNode(
pubsubTopics,

View File

@ -42,11 +42,16 @@ export type Observer<T extends IDecodedMessage> = {
export type RelayCreateOptions = CreateNodeOptions & GossipsubOpts;
export type ContentTopic = string;
type RelayConstructorParams = {
libp2p: Libp2p;
pubsubTopics: PubsubTopic[];
};
/**
* Implements the [Waku v2 Relay protocol](https://rfc.vac.dev/spec/11/).
* Throws if libp2p.pubsub does not support Waku Relay
*/
class Relay implements IRelay {
export class Relay implements IRelay {
public readonly pubsubTopics: Set<PubsubTopic>;
private defaultDecoder: IDecoder<IDecodedMessage>;
@ -59,15 +64,15 @@ class Relay implements IRelay {
*/
private observers: Map<PubsubTopic, Map<ContentTopic, Set<unknown>>>;
public constructor(libp2p: Libp2p, pubsubTopics: PubsubTopic[]) {
if (!this.isRelayPubsub(libp2p.services.pubsub)) {
public constructor(params: RelayConstructorParams) {
if (!this.isRelayPubsub(params.libp2p.services.pubsub)) {
throw Error(
`Failed to initialize Relay. libp2p.pubsub does not support ${Relay.multicodec}`
);
}
this.gossipSub = libp2p.services.pubsub as GossipSub;
this.pubsubTopics = new Set(pubsubTopics);
this.gossipSub = params.libp2p.services.pubsub as GossipSub;
this.pubsubTopics = new Set(params.pubsubTopics);
if (this.gossipSub.isStarted()) {
this.subscribeToAllTopics();
@ -76,7 +81,7 @@ class Relay implements IRelay {
this.observers = new Map();
// TODO: User might want to decide what decoder should be used (e.g. for RLN)
this.defaultDecoder = new TopicOnlyDecoder(pubsubTopics[0]);
this.defaultDecoder = new TopicOnlyDecoder(params.pubsubTopics[0]);
}
/**
@ -311,12 +316,6 @@ class Relay implements IRelay {
}
}
export function wakuRelay(
pubsubTopics: PubsubTopic[]
): (libp2p: Libp2p) => IRelay {
return (libp2p: Libp2p) => new Relay(libp2p, pubsubTopics);
}
export function wakuGossipSub(
init: Partial<RelayCreateOptions> = {}
): (components: GossipSubComponents) => GossipSub {

View File

@ -29,20 +29,30 @@ import { buildConfig } from "./utils.js";
const log = new Logger("sdk:filter");
class Filter implements IFilter {
type FilterConstructorParams = {
connectionManager: ConnectionManager;
libp2p: Libp2p;
peerManager: PeerManager;
lightPush?: ILightPush;
options?: Partial<FilterProtocolOptions>;
};
export class Filter implements IFilter {
public readonly protocol: FilterCore;
private readonly config: FilterProtocolOptions;
private connectionManager: ConnectionManager;
private libp2p: Libp2p;
private peerManager: PeerManager;
private lightPush?: ILightPush;
private activeSubscriptions = new Map<string, Subscription>();
public constructor(
private connectionManager: ConnectionManager,
private libp2p: Libp2p,
private peerManager: PeerManager,
private lightPush?: ILightPush,
config?: Partial<FilterProtocolOptions>
) {
this.config = buildConfig(config);
public constructor(params: FilterConstructorParams) {
this.config = buildConfig(params.options);
this.lightPush = params.lightPush;
this.peerManager = params.peerManager;
this.libp2p = params.libp2p;
this.connectionManager = params.connectionManager;
this.protocol = new FilterCore(
async (pubsubTopic, wakuMessage, peerIdStr) => {
@ -57,8 +67,8 @@ class Filter implements IFilter {
await subscription.processIncomingMessage(wakuMessage, peerIdStr);
},
connectionManager.pubsubTopics,
libp2p
params.connectionManager.pubsubTopics,
params.libp2p
);
this.activeSubscriptions = new Map();
@ -281,13 +291,3 @@ class Filter implements IFilter {
return [...pubsubTopics];
}
}
export function wakuFilter(
connectionManager: ConnectionManager,
peerManager: PeerManager,
lightPush?: ILightPush,
config?: Partial<FilterProtocolOptions>
): (libp2p: Libp2p) => IFilter {
return (libp2p: Libp2p) =>
new Filter(connectionManager, libp2p, peerManager, lightPush, config);
}

View File

@ -1 +1 @@
export { wakuFilter } from "./filter.js";
export { Filter } from "./filter.js";

View File

@ -14,9 +14,9 @@ export {
defaultLibp2p,
createLibp2pAndUpdateOptions
} from "./create/index.js";
export { wakuLightPush } from "./light_push/index.js";
export { wakuFilter } from "./filter/index.js";
export { wakuStore } from "./store/index.js";
export { LightPush } from "./light_push/index.js";
export { Filter } from "./filter/index.js";
export { Store } from "./store/index.js";
export * as waku from "@waku/core";
export * as utils from "@waku/utils";

View File

@ -1 +1 @@
export { LightPush, wakuLightPush } from "./light_push.js";
export { LightPush } from "./light_push.js";

View File

@ -154,18 +154,18 @@ type MockLightPushOptions = {
};
function mockLightPush(options: MockLightPushOptions): LightPush {
return new LightPush(
{
return new LightPush({
connectionManager: {
pubsubTopics: options.pubsubTopics || [PUBSUB_TOPIC]
} as ConnectionManager,
{
peerManager: {
getPeers: () =>
options.libp2p
.getPeers()
.slice(0, options.numPeersToUse || options.libp2p.getPeers().length)
} as unknown as PeerManager,
options.libp2p
);
libp2p: options.libp2p
});
}
function mockPeer(id: string): Peer {

View File

@ -25,15 +25,23 @@ const DEFAULT_SEND_OPTIONS: ISenderOptions = {
type RetryCallback = (peerId: PeerId) => Promise<CoreProtocolResult>;
type LightPushConstructorParams = {
connectionManager: ConnectionManager;
peerManager: PeerManager;
libp2p: Libp2p;
};
export class LightPush implements ILightPush {
private peerManager: PeerManager;
public readonly protocol: LightPushCore;
public constructor(
connectionManager: ConnectionManager,
private peerManager: PeerManager,
libp2p: Libp2p
) {
this.protocol = new LightPushCore(connectionManager.pubsubTopics, libp2p);
public constructor(params: LightPushConstructorParams) {
this.peerManager = params.peerManager;
this.protocol = new LightPushCore(
params.connectionManager.pubsubTopics,
params.libp2p
);
}
public async send(
@ -133,11 +141,3 @@ export class LightPush implements ILightPush {
}
}
}
export function wakuLightPush(
connectionManager: ConnectionManager,
peerManager: PeerManager
): (libp2p: Libp2p) => ILightPush {
return (libp2p: Libp2p) =>
new LightPush(connectionManager, peerManager, libp2p);
}

View File

@ -1 +1 @@
export { Store, wakuStore } from "./store.js";
export { Store } from "./store.js";

View File

@ -16,20 +16,33 @@ import { PeerManager } from "../peer_manager/index.js";
const log = new Logger("waku:store:sdk");
type StoreConstructorParams = {
connectionManager: ConnectionManager;
libp2p: Libp2p;
peerManager: PeerManager;
options?: Partial<StoreProtocolOptions>;
};
/**
* StoreSDK is an implementation of the IStoreSDK interface.
* It provides methods to interact with the Waku Store protocol.
*/
export class Store implements IStore {
private options: Partial<StoreProtocolOptions>;
private peerManager: PeerManager;
private connectionManager: ConnectionManager;
public readonly protocol: StoreCore;
public constructor(
private connectionManager: ConnectionManager,
libp2p: Libp2p,
private peerManager: PeerManager,
private options?: Partial<StoreProtocolOptions>
) {
this.protocol = new StoreCore(connectionManager.pubsubTopics, libp2p);
public constructor(params: StoreConstructorParams) {
this.options = params.options || {};
this.peerManager = params.peerManager;
this.connectionManager = params.connectionManager;
this.protocol = new StoreCore(
params.connectionManager.pubsubTopics,
params.libp2p
);
}
/**
@ -252,19 +265,3 @@ export class Store implements IStore {
return;
}
}
/**
* Factory function to create an instance of the StoreSDK.
*
* @param init - Partial options for protocol creation.
* @returns A function that takes a Libp2p instance and returns a StoreSDK instance.
*/
export function wakuStore(
connectionManager: ConnectionManager,
peerManager: PeerManager,
options?: Partial<StoreProtocolOptions>
): (libp2p: Libp2p) => IStore {
return (libp2p: Libp2p) => {
return new Store(connectionManager, libp2p, peerManager, options);
};
}

View File

@ -15,11 +15,11 @@ import type {
import { Protocols } from "@waku/interfaces";
import { Logger } from "@waku/utils";
import { wakuFilter } from "../filter/index.js";
import { Filter } from "../filter/index.js";
import { HealthIndicator } from "../health_indicator/index.js";
import { wakuLightPush } from "../light_push/index.js";
import { LightPush } from "../light_push/index.js";
import { PeerManager } from "../peer_manager/index.js";
import { wakuStore } from "../store/index.js";
import { Store } from "../store/index.js";
import { waitForRemotePeer } from "./wait_for_remote_peer.js";
@ -86,25 +86,32 @@ export class WakuNode implements IWaku {
});
}
const store = wakuStore(this.connectionManager, this.peerManager, {
peer: options.store?.peer
this.store = new Store({
libp2p,
connectionManager: this.connectionManager,
peerManager: this.peerManager,
options: {
peer: options.store?.peer
}
});
this.store = store(libp2p);
}
if (protocolsEnabled.lightpush) {
const lightPush = wakuLightPush(this.connectionManager, this.peerManager);
this.lightPush = lightPush(libp2p);
this.lightPush = new LightPush({
libp2p,
peerManager: this.peerManager,
connectionManager: this.connectionManager
});
}
if (protocolsEnabled.filter) {
const filter = wakuFilter(
this.connectionManager,
this.peerManager,
this.lightPush,
options.filter
);
this.filter = filter(libp2p);
this.filter = new Filter({
libp2p,
connectionManager: this.connectionManager,
peerManager: this.peerManager,
lightPush: this.lightPush,
options: options.filter
});
}
log.info(