2024-08-31 15:18:51 +02:00
|
|
|
import {
|
|
|
|
|
GossipSub,
|
|
|
|
|
GossipSubComponents,
|
|
|
|
|
GossipsubMessage,
|
|
|
|
|
GossipsubOpts
|
|
|
|
|
} from "@chainsafe/libp2p-gossipsub";
|
|
|
|
|
import type { PeerIdStr, TopicStr } from "@chainsafe/libp2p-gossipsub/types";
|
|
|
|
|
import { SignaturePolicy } from "@chainsafe/libp2p-gossipsub/types";
|
2025-02-25 22:40:03 +01:00
|
|
|
import type { PubSub as Libp2pPubsub } from "@libp2p/interface";
|
2024-08-31 15:18:51 +02:00
|
|
|
import { sha256 } from "@noble/hashes/sha256";
|
|
|
|
|
import {
|
|
|
|
|
Callback,
|
2025-01-31 00:16:00 +01:00
|
|
|
CreateNodeOptions,
|
2024-08-31 15:18:51 +02:00
|
|
|
IAsyncIterator,
|
|
|
|
|
IDecodedMessage,
|
|
|
|
|
IDecoder,
|
|
|
|
|
IEncoder,
|
|
|
|
|
IMessage,
|
|
|
|
|
IRelay,
|
2025-07-19 14:30:44 +10:00
|
|
|
type IRoutingInfo,
|
2024-08-31 15:18:51 +02:00
|
|
|
Libp2p,
|
2025-09-04 15:52:37 -07:00
|
|
|
LightPushError,
|
|
|
|
|
LightPushSDKResult,
|
|
|
|
|
PubsubTopic
|
2024-08-31 15:18:51 +02:00
|
|
|
} from "@waku/interfaces";
|
2025-07-19 14:30:44 +10:00
|
|
|
import { isWireSizeUnderCap, toAsyncIterator } from "@waku/utils";
|
2024-08-31 15:18:51 +02:00
|
|
|
import { pushOrInitMapSet } from "@waku/utils";
|
|
|
|
|
import { Logger } from "@waku/utils";
|
2024-10-09 00:43:34 +02:00
|
|
|
import { pEvent } from "p-event";
|
2024-08-31 15:18:51 +02:00
|
|
|
|
|
|
|
|
import { RelayCodecs } from "./constants.js";
|
|
|
|
|
import { messageValidator } from "./message_validator.js";
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
import { ContentTopicOnlyDecoder } from "./topic_only_message.js";
|
2024-08-31 15:18:51 +02:00
|
|
|
|
|
|
|
|
const log = new Logger("relay");
|
|
|
|
|
|
|
|
|
|
export type Observer<T extends IDecodedMessage> = {
|
|
|
|
|
decoder: IDecoder<T>;
|
|
|
|
|
callback: Callback<T>;
|
|
|
|
|
};
|
|
|
|
|
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
export type RelayCreateOptions = CreateNodeOptions & {
|
2025-07-19 14:30:44 +10:00
|
|
|
routingInfos: IRoutingInfo[];
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
} & Partial<GossipsubOpts>;
|
2024-08-31 15:18:51 +02:00
|
|
|
export type ContentTopic = string;
|
|
|
|
|
|
2025-07-02 12:37:54 +02:00
|
|
|
type ActiveSubscriptions = Map<PubsubTopic, ContentTopic[]>;
|
|
|
|
|
|
2025-02-25 18:41:32 +01:00
|
|
|
type RelayConstructorParams = {
|
|
|
|
|
libp2p: Libp2p;
|
|
|
|
|
pubsubTopics: PubsubTopic[];
|
|
|
|
|
};
|
|
|
|
|
|
2024-08-31 15:18:51 +02:00
|
|
|
/**
|
|
|
|
|
* Implements the [Waku v2 Relay protocol](https://rfc.vac.dev/spec/11/).
|
|
|
|
|
* Throws if libp2p.pubsub does not support Waku Relay
|
|
|
|
|
*/
|
2025-02-25 18:41:32 +01:00
|
|
|
export class Relay implements IRelay {
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
public pubsubTopics: Set<PubsubTopic>;
|
2024-08-31 15:18:51 +02:00
|
|
|
private defaultDecoder: IDecoder<IDecodedMessage>;
|
|
|
|
|
|
|
|
|
|
public static multicodec: string = RelayCodecs[0];
|
|
|
|
|
public readonly gossipSub: GossipSub;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* observers called when receiving new message.
|
|
|
|
|
* Observers under key `""` are always called.
|
|
|
|
|
*/
|
|
|
|
|
private observers: Map<PubsubTopic, Map<ContentTopic, Set<unknown>>>;
|
2025-11-13 12:32:15 +11:00
|
|
|
private messageEventHandlers: Map<
|
|
|
|
|
PubsubTopic,
|
|
|
|
|
(event: CustomEvent<GossipsubMessage>) => void
|
|
|
|
|
> = new Map();
|
2024-08-31 15:18:51 +02:00
|
|
|
|
2025-02-25 18:41:32 +01:00
|
|
|
public constructor(params: RelayConstructorParams) {
|
|
|
|
|
if (!this.isRelayPubsub(params.libp2p.services.pubsub)) {
|
2024-08-31 15:18:51 +02:00
|
|
|
throw Error(
|
|
|
|
|
`Failed to initialize Relay. libp2p.pubsub does not support ${Relay.multicodec}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-25 18:41:32 +01:00
|
|
|
this.gossipSub = params.libp2p.services.pubsub as GossipSub;
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
|
2025-02-25 18:41:32 +01:00
|
|
|
this.pubsubTopics = new Set(params.pubsubTopics);
|
2024-08-31 15:18:51 +02:00
|
|
|
|
|
|
|
|
if (this.gossipSub.isStarted()) {
|
|
|
|
|
this.subscribeToAllTopics();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.observers = new Map();
|
|
|
|
|
|
|
|
|
|
// TODO: User might want to decide what decoder should be used (e.g. for RLN)
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
this.defaultDecoder = new ContentTopicOnlyDecoder();
|
2024-08-31 15:18:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Mounts the gossipsub protocol onto the libp2p node
|
|
|
|
|
* and subscribes to all the topics.
|
|
|
|
|
*
|
|
|
|
|
* @override
|
|
|
|
|
* @returns {void}
|
|
|
|
|
*/
|
|
|
|
|
public async start(): Promise<void> {
|
|
|
|
|
if (this.gossipSub.isStarted()) {
|
|
|
|
|
throw Error("GossipSub already started.");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await this.gossipSub.start();
|
|
|
|
|
this.subscribeToAllTopics();
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-13 12:32:15 +11:00
|
|
|
public async stop(): Promise<void> {
|
|
|
|
|
for (const pubsubTopic of this.pubsubTopics) {
|
|
|
|
|
const handler = this.messageEventHandlers.get(pubsubTopic);
|
|
|
|
|
if (handler) {
|
|
|
|
|
this.gossipSub.removeEventListener("gossipsub:message", handler);
|
|
|
|
|
}
|
|
|
|
|
this.gossipSub.topicValidators.delete(pubsubTopic);
|
|
|
|
|
this.gossipSub.unsubscribe(pubsubTopic);
|
|
|
|
|
}
|
|
|
|
|
this.messageEventHandlers.clear();
|
|
|
|
|
this.observers.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-09 00:43:34 +02:00
|
|
|
/**
|
|
|
|
|
* Wait for at least one peer with the given protocol to be connected and in the gossipsub
|
|
|
|
|
* mesh for all pubsubTopics.
|
|
|
|
|
*/
|
|
|
|
|
public async waitForPeers(): Promise<void> {
|
|
|
|
|
let peers = this.getMeshPeers();
|
|
|
|
|
const pubsubTopics = this.pubsubTopics;
|
|
|
|
|
|
|
|
|
|
for (const topic of pubsubTopics) {
|
|
|
|
|
while (peers.length == 0) {
|
|
|
|
|
await pEvent(this.gossipSub, "gossipsub:heartbeat");
|
|
|
|
|
peers = this.getMeshPeers(topic);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-31 15:18:51 +02:00
|
|
|
/**
|
|
|
|
|
* Send Waku message.
|
|
|
|
|
*/
|
|
|
|
|
public async send(
|
|
|
|
|
encoder: IEncoder,
|
|
|
|
|
message: IMessage
|
2025-09-04 15:52:37 -07:00
|
|
|
): Promise<LightPushSDKResult> {
|
2025-07-19 21:25:21 +10:00
|
|
|
const { pubsubTopic } = encoder;
|
2024-08-31 15:18:51 +02:00
|
|
|
if (!this.pubsubTopics.has(pubsubTopic)) {
|
|
|
|
|
log.error("Failed to send waku relay: topic not configured");
|
|
|
|
|
return {
|
2025-02-25 22:40:03 +01:00
|
|
|
successes: [],
|
2024-08-31 15:18:51 +02:00
|
|
|
failures: [
|
|
|
|
|
{
|
2025-09-04 15:52:37 -07:00
|
|
|
error: LightPushError.TOPIC_NOT_CONFIGURED
|
2024-08-31 15:18:51 +02:00
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const msg = await encoder.toWire(message);
|
|
|
|
|
if (!msg) {
|
|
|
|
|
log.error("Failed to encode message, aborting publish");
|
|
|
|
|
return {
|
2025-02-25 22:40:03 +01:00
|
|
|
successes: [],
|
2024-08-31 15:18:51 +02:00
|
|
|
failures: [
|
|
|
|
|
{
|
2025-09-04 15:52:37 -07:00
|
|
|
error: LightPushError.ENCODE_FAILED
|
2024-08-31 15:18:51 +02:00
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!isWireSizeUnderCap(msg)) {
|
|
|
|
|
log.error("Failed to send waku relay: message is bigger that 1MB");
|
|
|
|
|
return {
|
2025-02-25 22:40:03 +01:00
|
|
|
successes: [],
|
2024-08-31 15:18:51 +02:00
|
|
|
failures: [
|
|
|
|
|
{
|
2025-09-04 15:52:37 -07:00
|
|
|
error: LightPushError.SIZE_TOO_BIG
|
2024-08-31 15:18:51 +02:00
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { recipients } = await this.gossipSub.publish(pubsubTopic, msg);
|
|
|
|
|
return {
|
|
|
|
|
successes: recipients,
|
|
|
|
|
failures: []
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public subscribeWithUnsubscribe<T extends IDecodedMessage>(
|
|
|
|
|
decoders: IDecoder<T> | IDecoder<T>[],
|
|
|
|
|
callback: Callback<T>
|
|
|
|
|
): () => void {
|
|
|
|
|
const observers: Array<[PubsubTopic, Observer<T>]> = [];
|
|
|
|
|
|
|
|
|
|
for (const decoder of Array.isArray(decoders) ? decoders : [decoders]) {
|
2025-07-19 21:25:21 +10:00
|
|
|
const { pubsubTopic } = decoder;
|
2024-08-31 15:18:51 +02:00
|
|
|
const ctObs: Map<ContentTopic, Set<Observer<T>>> = this.observers.get(
|
|
|
|
|
pubsubTopic
|
|
|
|
|
) ?? new Map();
|
|
|
|
|
const observer = { pubsubTopic, decoder, callback };
|
|
|
|
|
pushOrInitMapSet(ctObs, decoder.contentTopic, observer);
|
|
|
|
|
|
|
|
|
|
this.observers.set(pubsubTopic, ctObs);
|
|
|
|
|
observers.push([pubsubTopic, observer]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
|
this.removeObservers(observers);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public subscribe = this.subscribeWithUnsubscribe;
|
|
|
|
|
|
|
|
|
|
private removeObservers<T extends IDecodedMessage>(
|
|
|
|
|
observers: Array<[PubsubTopic, Observer<T>]>
|
|
|
|
|
): void {
|
|
|
|
|
for (const [pubsubTopic, observer] of observers) {
|
|
|
|
|
const ctObs = this.observers.get(pubsubTopic);
|
|
|
|
|
if (!ctObs) continue;
|
|
|
|
|
|
|
|
|
|
const contentTopic = observer.decoder.contentTopic;
|
|
|
|
|
const _obs = ctObs.get(contentTopic);
|
|
|
|
|
if (!_obs) continue;
|
|
|
|
|
|
|
|
|
|
_obs.delete(observer);
|
|
|
|
|
ctObs.set(contentTopic, _obs);
|
|
|
|
|
this.observers.set(pubsubTopic, ctObs);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public toSubscriptionIterator<T extends IDecodedMessage>(
|
|
|
|
|
decoders: IDecoder<T> | IDecoder<T>[]
|
|
|
|
|
): Promise<IAsyncIterator<T>> {
|
|
|
|
|
return toAsyncIterator(this, decoders);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public getActiveSubscriptions(): ActiveSubscriptions {
|
|
|
|
|
const map = new Map();
|
|
|
|
|
for (const pubsubTopic of this.pubsubTopics) {
|
|
|
|
|
map.set(pubsubTopic, Array.from(this.observers.keys()));
|
|
|
|
|
}
|
|
|
|
|
return map;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public getMeshPeers(topic?: TopicStr): PeerIdStr[] {
|
|
|
|
|
// if no TopicStr is provided - returns empty array
|
|
|
|
|
return this.gossipSub.getMeshPeers(topic || "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private subscribeToAllTopics(): void {
|
|
|
|
|
for (const pubsubTopic of this.pubsubTopics) {
|
|
|
|
|
this.gossipSubSubscribe(pubsubTopic);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async processIncomingMessage<T extends IDecodedMessage>(
|
|
|
|
|
pubsubTopic: string,
|
|
|
|
|
bytes: Uint8Array
|
|
|
|
|
): Promise<void> {
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
const contentTopicOnlyMsg =
|
|
|
|
|
await this.defaultDecoder.fromWireToProtoObj(bytes);
|
|
|
|
|
if (!contentTopicOnlyMsg || !contentTopicOnlyMsg.contentTopic) {
|
2024-08-31 15:18:51 +02:00
|
|
|
log.warn("Message does not have a content topic, skipping");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Retrieve the map of content topics for the given pubsubTopic
|
|
|
|
|
const contentTopicMap = this.observers.get(pubsubTopic);
|
|
|
|
|
if (!contentTopicMap) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Retrieve the set of observers for the given contentTopic
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
const observers = contentTopicMap.get(
|
|
|
|
|
contentTopicOnlyMsg.contentTopic
|
|
|
|
|
) as Set<Observer<T>>;
|
2024-08-31 15:18:51 +02:00
|
|
|
if (!observers) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await Promise.all(
|
|
|
|
|
Array.from(observers).map(({ decoder, callback }) => {
|
|
|
|
|
return (async () => {
|
|
|
|
|
try {
|
|
|
|
|
const protoMsg = await decoder.fromWireToProtoObj(bytes);
|
|
|
|
|
if (!protoMsg) {
|
|
|
|
|
log.error(
|
|
|
|
|
"Internal error: message previously decoded failed on 2nd pass."
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const msg = await decoder.fromProtoObj(pubsubTopic, protoMsg);
|
|
|
|
|
if (msg) {
|
|
|
|
|
await callback(msg);
|
|
|
|
|
} else {
|
|
|
|
|
log.error(
|
|
|
|
|
"Failed to decode messages on",
|
feat!: Introduce routing info concept
Concepts are being mixed up between the global network config (static vs auto sharding), that needs to be the same of all nodes in the network, individual node configuration (eg relay node subscribing to a given shard), and the routing characteristic of a specific message (eg pubsub topic, shard).
This stops proper configuration of nwaku post 0.36.0 because we know need to be deliberate on whether nwaku nodes are running with auto or static sharding.
It also included various back and forth conversions between shards, pubsub topics, etc.
With this change, we tidy up the network configuration, and make it explicit whether it is static or auto sharded.
We also introduce the concept of routing info, which is specific to a message, and tied to the overall network configuration.
Routing info abstract pubsub topic, shard, and autosharding needs. Which should lead to easier tidy up of the pubsub concept at a later stage.
# Conflicts:
# packages/core/src/lib/connection_manager/connection_manager.ts
# packages/core/src/lib/metadata/metadata.ts
# packages/interfaces/src/metadata.ts
# packages/interfaces/src/sharding.ts
# packages/relay/src/create.ts
# packages/sdk/src/filter/filter.ts
# packages/sdk/src/filter/types.ts
# packages/sdk/src/light_push/light_push.spec.ts
# packages/tests/tests/sharding/auto_sharding.spec.ts
# packages/tests/tests/sharding/static_sharding.spec.ts
# Conflicts:
# packages/sdk/src/store/store.ts
2025-07-11 13:33:45 +10:00
|
|
|
contentTopicOnlyMsg.contentTopic
|
2024-08-31 15:18:51 +02:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
log.error("Error while decoding message:", error);
|
|
|
|
|
}
|
|
|
|
|
})();
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Subscribe to a pubsub topic and start emitting Waku messages to observers.
|
|
|
|
|
*
|
|
|
|
|
* @override
|
|
|
|
|
*/
|
|
|
|
|
private gossipSubSubscribe(pubsubTopic: string): void {
|
2025-11-13 12:32:15 +11:00
|
|
|
const handler = (event: CustomEvent<GossipsubMessage>): void => {
|
|
|
|
|
if (event.detail.msg.topic !== pubsubTopic) return;
|
|
|
|
|
|
|
|
|
|
this.processIncomingMessage(
|
|
|
|
|
event.detail.msg.topic,
|
|
|
|
|
event.detail.msg.data
|
|
|
|
|
).catch((e) => log.error("Failed to process incoming message", e));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.messageEventHandlers.set(pubsubTopic, handler);
|
|
|
|
|
this.gossipSub.addEventListener("gossipsub:message", handler);
|
2024-08-31 15:18:51 +02:00
|
|
|
|
|
|
|
|
this.gossipSub.topicValidators.set(pubsubTopic, messageValidator);
|
|
|
|
|
this.gossipSub.subscribe(pubsubTopic);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private isRelayPubsub(pubsub: Libp2pPubsub | undefined): boolean {
|
|
|
|
|
return pubsub?.multicodecs?.includes(Relay.multicodec) ?? false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function wakuGossipSub(
|
|
|
|
|
init: Partial<RelayCreateOptions> = {}
|
|
|
|
|
): (components: GossipSubComponents) => GossipSub {
|
|
|
|
|
return (components: GossipSubComponents) => {
|
|
|
|
|
init = {
|
|
|
|
|
...init,
|
|
|
|
|
msgIdFn: ({ data }) => sha256(data),
|
|
|
|
|
// Ensure that no signature is included nor expected in the messages.
|
|
|
|
|
globalSignaturePolicy: SignaturePolicy.StrictNoSign,
|
|
|
|
|
fallbackToFloodsub: false
|
|
|
|
|
};
|
|
|
|
|
const pubsub = new GossipSub(components, init);
|
|
|
|
|
pubsub.multicodecs = RelayCodecs;
|
|
|
|
|
return pubsub;
|
|
|
|
|
};
|
|
|
|
|
}
|