mirror of
https://github.com/waku-org/js-waku.git
synced 2025-02-23 17:48:19 +00:00
chore: enforce access modifiers (#2068)
* feat: introduce eslint flag * chore: update logger * chore: update enr * chore: update core * chore: update sdk * chore: update relay * chore: update discovery * chore: update message-encryption * chore: update tests * chore: fix modifiers * chore(tests): fix access modifiers * chore: fix rebase
This commit is contained in:
parent
9b0f1e855a
commit
169a09d552
@ -25,6 +25,7 @@
|
|||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"@typescript-eslint/explicit-member-accessibility": "error",
|
||||||
"prettier/prettier": [
|
"prettier/prettier": [
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
|
@ -25,7 +25,7 @@ export class BaseProtocol implements IBaseProtocolCore {
|
|||||||
public readonly removeLibp2pEventListener: Libp2p["removeEventListener"];
|
public readonly removeLibp2pEventListener: Libp2p["removeEventListener"];
|
||||||
protected streamManager: StreamManager;
|
protected streamManager: StreamManager;
|
||||||
|
|
||||||
constructor(
|
protected constructor(
|
||||||
public multicodec: string,
|
public multicodec: string,
|
||||||
private components: Libp2pComponents,
|
private components: Libp2pComponents,
|
||||||
private log: Logger,
|
private log: Logger,
|
||||||
@ -82,7 +82,7 @@ export class BaseProtocol implements IBaseProtocolCore {
|
|||||||
|
|
||||||
* @returns A list of peers that support the protocol sorted by latency.
|
* @returns A list of peers that support the protocol sorted by latency.
|
||||||
*/
|
*/
|
||||||
async getPeers(
|
public async getPeers(
|
||||||
{
|
{
|
||||||
numPeers,
|
numPeers,
|
||||||
maxBootstrapPeers
|
maxBootstrapPeers
|
||||||
|
@ -8,16 +8,16 @@ import { v4 as uuid } from "uuid";
|
|||||||
export class FilterPushRpc {
|
export class FilterPushRpc {
|
||||||
public constructor(public proto: proto.MessagePush) {}
|
public constructor(public proto: proto.MessagePush) {}
|
||||||
|
|
||||||
static decode(bytes: Uint8Array): FilterPushRpc {
|
public static decode(bytes: Uint8Array): FilterPushRpc {
|
||||||
const res = proto.MessagePush.decode(bytes);
|
const res = proto.MessagePush.decode(bytes);
|
||||||
return new FilterPushRpc(res);
|
return new FilterPushRpc(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
encode(): Uint8Array {
|
public encode(): Uint8Array {
|
||||||
return proto.MessagePush.encode(this.proto);
|
return proto.MessagePush.encode(this.proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
get wakuMessage(): WakuMessage | undefined {
|
public get wakuMessage(): WakuMessage | undefined {
|
||||||
return this.proto.wakuMessage;
|
return this.proto.wakuMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ export class FilterPushRpc {
|
|||||||
* Get the pubsub topic from the FilterPushRpc object.
|
* Get the pubsub topic from the FilterPushRpc object.
|
||||||
* @returns string
|
* @returns string
|
||||||
*/
|
*/
|
||||||
get pubsubTopic(): string | undefined {
|
public get pubsubTopic(): string | undefined {
|
||||||
return this.proto.pubsubTopic;
|
return this.proto.pubsubTopic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ export class FilterPushRpc {
|
|||||||
export class FilterSubscribeRpc {
|
export class FilterSubscribeRpc {
|
||||||
public constructor(public proto: proto.FilterSubscribeRequest) {}
|
public constructor(public proto: proto.FilterSubscribeRequest) {}
|
||||||
|
|
||||||
static createSubscribeRequest(
|
public static createSubscribeRequest(
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
contentTopics: string[]
|
contentTopics: string[]
|
||||||
): FilterSubscribeRpc {
|
): FilterSubscribeRpc {
|
||||||
@ -46,7 +46,7 @@ export class FilterSubscribeRpc {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static createUnsubscribeRequest(
|
public static createUnsubscribeRequest(
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
contentTopics: string[]
|
contentTopics: string[]
|
||||||
): FilterSubscribeRpc {
|
): FilterSubscribeRpc {
|
||||||
@ -59,7 +59,9 @@ export class FilterSubscribeRpc {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static createUnsubscribeAllRequest(pubsubTopic: string): FilterSubscribeRpc {
|
public static createUnsubscribeAllRequest(
|
||||||
|
pubsubTopic: string
|
||||||
|
): FilterSubscribeRpc {
|
||||||
return new FilterSubscribeRpc({
|
return new FilterSubscribeRpc({
|
||||||
requestId: uuid(),
|
requestId: uuid(),
|
||||||
filterSubscribeType:
|
filterSubscribeType:
|
||||||
@ -69,7 +71,7 @@ export class FilterSubscribeRpc {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static createSubscriberPingRequest(): FilterSubscribeRpc {
|
public static createSubscriberPingRequest(): FilterSubscribeRpc {
|
||||||
return new FilterSubscribeRpc({
|
return new FilterSubscribeRpc({
|
||||||
requestId: uuid(),
|
requestId: uuid(),
|
||||||
filterSubscribeType:
|
filterSubscribeType:
|
||||||
@ -79,28 +81,28 @@ export class FilterSubscribeRpc {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static decode(bytes: Uint8Array): FilterSubscribeRpc {
|
public static decode(bytes: Uint8Array): FilterSubscribeRpc {
|
||||||
const res = proto.FilterSubscribeRequest.decode(bytes);
|
const res = proto.FilterSubscribeRequest.decode(bytes);
|
||||||
return new FilterSubscribeRpc(res);
|
return new FilterSubscribeRpc(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
encode(): Uint8Array {
|
public encode(): Uint8Array {
|
||||||
return proto.FilterSubscribeRequest.encode(this.proto);
|
return proto.FilterSubscribeRequest.encode(this.proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
get filterSubscribeType(): proto.FilterSubscribeRequest.FilterSubscribeType {
|
public get filterSubscribeType(): proto.FilterSubscribeRequest.FilterSubscribeType {
|
||||||
return this.proto.filterSubscribeType;
|
return this.proto.filterSubscribeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
get requestId(): string {
|
public get requestId(): string {
|
||||||
return this.proto.requestId;
|
return this.proto.requestId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get pubsubTopic(): string | undefined {
|
public get pubsubTopic(): string | undefined {
|
||||||
return this.proto.pubsubTopic;
|
return this.proto.pubsubTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
get contentTopics(): string[] {
|
public get contentTopics(): string[] {
|
||||||
return this.proto.contentTopics;
|
return this.proto.contentTopics;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,24 +110,24 @@ export class FilterSubscribeRpc {
|
|||||||
export class FilterSubscribeResponse {
|
export class FilterSubscribeResponse {
|
||||||
public constructor(public proto: proto.FilterSubscribeResponse) {}
|
public constructor(public proto: proto.FilterSubscribeResponse) {}
|
||||||
|
|
||||||
static decode(bytes: Uint8Array): FilterSubscribeResponse {
|
public static decode(bytes: Uint8Array): FilterSubscribeResponse {
|
||||||
const res = proto.FilterSubscribeResponse.decode(bytes);
|
const res = proto.FilterSubscribeResponse.decode(bytes);
|
||||||
return new FilterSubscribeResponse(res);
|
return new FilterSubscribeResponse(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
encode(): Uint8Array {
|
public encode(): Uint8Array {
|
||||||
return proto.FilterSubscribeResponse.encode(this.proto);
|
return proto.FilterSubscribeResponse.encode(this.proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
get statusCode(): number {
|
public get statusCode(): number {
|
||||||
return this.proto.statusCode;
|
return this.proto.statusCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
get statusDesc(): string | undefined {
|
public get statusDesc(): string | undefined {
|
||||||
return this.proto.statusDesc;
|
return this.proto.statusDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
get requestId(): string {
|
public get requestId(): string {
|
||||||
return this.proto.requestId;
|
return this.proto.requestId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ export const FilterCodecs = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
|
export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
|
||||||
constructor(
|
public constructor(
|
||||||
private handleIncomingMessage: (
|
private handleIncomingMessage: (
|
||||||
pubsubTopic: PubsubTopic,
|
pubsubTopic: PubsubTopic,
|
||||||
wakuMessage: WakuMessage,
|
wakuMessage: WakuMessage,
|
||||||
@ -58,47 +58,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private onRequest(streamData: IncomingStreamData): void {
|
public async subscribe(
|
||||||
const { connection, stream } = streamData;
|
|
||||||
const { remotePeer } = connection;
|
|
||||||
log.info(`Received message from ${remotePeer.toString()}`);
|
|
||||||
try {
|
|
||||||
pipe(stream, lp.decode, async (source) => {
|
|
||||||
for await (const bytes of source) {
|
|
||||||
const response = FilterPushRpc.decode(bytes.slice());
|
|
||||||
|
|
||||||
const { pubsubTopic, wakuMessage } = response;
|
|
||||||
|
|
||||||
if (!wakuMessage) {
|
|
||||||
log.error("Received empty message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pubsubTopic) {
|
|
||||||
log.error("Pubsub topic missing from push message");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.handleIncomingMessage(
|
|
||||||
pubsubTopic,
|
|
||||||
wakuMessage,
|
|
||||||
connection.remotePeer.toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).then(
|
|
||||||
() => {
|
|
||||||
log.info("Receiving pipe closed.");
|
|
||||||
},
|
|
||||||
(e) => {
|
|
||||||
log.error("Error with receiving pipe", e);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
log.error("Error decoding message", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async subscribe(
|
|
||||||
pubsubTopic: PubsubTopic,
|
pubsubTopic: PubsubTopic,
|
||||||
peer: Peer,
|
peer: Peer,
|
||||||
contentTopics: ContentTopic[]
|
contentTopics: ContentTopic[]
|
||||||
@ -152,7 +112,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async unsubscribe(
|
public async unsubscribe(
|
||||||
pubsubTopic: PubsubTopic,
|
pubsubTopic: PubsubTopic,
|
||||||
peer: Peer,
|
peer: Peer,
|
||||||
contentTopics: ContentTopic[]
|
contentTopics: ContentTopic[]
|
||||||
@ -198,7 +158,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async unsubscribeAll(
|
public async unsubscribeAll(
|
||||||
pubsubTopic: PubsubTopic,
|
pubsubTopic: PubsubTopic,
|
||||||
peer: Peer
|
peer: Peer
|
||||||
): Promise<CoreProtocolResult> {
|
): Promise<CoreProtocolResult> {
|
||||||
@ -246,7 +206,7 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async ping(peer: Peer): Promise<CoreProtocolResult> {
|
public async ping(peer: Peer): Promise<CoreProtocolResult> {
|
||||||
let stream: Stream | undefined;
|
let stream: Stream | undefined;
|
||||||
try {
|
try {
|
||||||
stream = await this.getStream(peer);
|
stream = await this.getStream(peer);
|
||||||
@ -316,4 +276,44 @@ export class FilterCore extends BaseProtocol implements IBaseProtocolCore {
|
|||||||
failure: null
|
failure: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onRequest(streamData: IncomingStreamData): void {
|
||||||
|
const { connection, stream } = streamData;
|
||||||
|
const { remotePeer } = connection;
|
||||||
|
log.info(`Received message from ${remotePeer.toString()}`);
|
||||||
|
try {
|
||||||
|
pipe(stream, lp.decode, async (source) => {
|
||||||
|
for await (const bytes of source) {
|
||||||
|
const response = FilterPushRpc.decode(bytes.slice());
|
||||||
|
|
||||||
|
const { pubsubTopic, wakuMessage } = response;
|
||||||
|
|
||||||
|
if (!wakuMessage) {
|
||||||
|
log.error("Received empty message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pubsubTopic) {
|
||||||
|
log.error("Pubsub topic missing from push message");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.handleIncomingMessage(
|
||||||
|
pubsubTopic,
|
||||||
|
wakuMessage,
|
||||||
|
connection.remotePeer.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).then(
|
||||||
|
() => {
|
||||||
|
log.info("Receiving pipe closed.");
|
||||||
|
},
|
||||||
|
(e) => {
|
||||||
|
log.error("Error with receiving pipe", e);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
log.error("Error decoding message", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,11 @@ export class KeepAliveManager {
|
|||||||
private relayKeepAliveTimers: Map<PeerId, ReturnType<typeof setInterval>[]> =
|
private relayKeepAliveTimers: Map<PeerId, ReturnType<typeof setInterval>[]> =
|
||||||
new Map();
|
new Map();
|
||||||
|
|
||||||
constructor({ options, relay, libp2p }: CreateKeepAliveManagerOptions) {
|
public constructor({
|
||||||
|
options,
|
||||||
|
relay,
|
||||||
|
libp2p
|
||||||
|
}: CreateKeepAliveManagerOptions) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.relay = relay;
|
this.relay = relay;
|
||||||
this.libp2p = libp2p;
|
this.libp2p = libp2p;
|
||||||
|
@ -32,7 +32,7 @@ type PreparePushMessageResult = ThisOrThat<"query", PushRpc>;
|
|||||||
* Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
|
* Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
|
||||||
*/
|
*/
|
||||||
export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
|
export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
|
||||||
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
public constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
||||||
super(
|
super(
|
||||||
LightPushCodec,
|
LightPushCodec,
|
||||||
libp2p.components,
|
libp2p.components,
|
||||||
@ -78,7 +78,7 @@ export class LightPushCore extends BaseProtocol implements IBaseProtocolCore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async send(
|
public async send(
|
||||||
encoder: IEncoder,
|
encoder: IEncoder,
|
||||||
message: IMessage,
|
message: IMessage,
|
||||||
peer: Peer
|
peer: Peer
|
||||||
|
@ -5,7 +5,7 @@ import { v4 as uuid } from "uuid";
|
|||||||
export class PushRpc {
|
export class PushRpc {
|
||||||
public constructor(public proto: proto.PushRpc) {}
|
public constructor(public proto: proto.PushRpc) {}
|
||||||
|
|
||||||
static createRequest(
|
public static createRequest(
|
||||||
message: proto.WakuMessage,
|
message: proto.WakuMessage,
|
||||||
pubsubTopic: string
|
pubsubTopic: string
|
||||||
): PushRpc {
|
): PushRpc {
|
||||||
@ -19,20 +19,20 @@ export class PushRpc {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static decode(bytes: Uint8ArrayList): PushRpc {
|
public static decode(bytes: Uint8ArrayList): PushRpc {
|
||||||
const res = proto.PushRpc.decode(bytes);
|
const res = proto.PushRpc.decode(bytes);
|
||||||
return new PushRpc(res);
|
return new PushRpc(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
encode(): Uint8Array {
|
public encode(): Uint8Array {
|
||||||
return proto.PushRpc.encode(this.proto);
|
return proto.PushRpc.encode(this.proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
get query(): proto.PushRequest | undefined {
|
public get query(): proto.PushRequest | undefined {
|
||||||
return this.proto.request;
|
return this.proto.request;
|
||||||
}
|
}
|
||||||
|
|
||||||
get response(): proto.PushResponse | undefined {
|
public get response(): proto.PushResponse | undefined {
|
||||||
return this.proto.response;
|
return this.proto.response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,28 +20,28 @@ export const Version = 0;
|
|||||||
export { proto };
|
export { proto };
|
||||||
|
|
||||||
export class DecodedMessage implements IDecodedMessage {
|
export class DecodedMessage implements IDecodedMessage {
|
||||||
constructor(
|
public constructor(
|
||||||
public pubsubTopic: string,
|
public pubsubTopic: string,
|
||||||
protected proto: proto.WakuMessage
|
protected proto: proto.WakuMessage
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
get ephemeral(): boolean {
|
public get ephemeral(): boolean {
|
||||||
return Boolean(this.proto.ephemeral);
|
return Boolean(this.proto.ephemeral);
|
||||||
}
|
}
|
||||||
|
|
||||||
get payload(): Uint8Array {
|
public get payload(): Uint8Array {
|
||||||
return this.proto.payload;
|
return this.proto.payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
get contentTopic(): string {
|
public get contentTopic(): string {
|
||||||
return this.proto.contentTopic;
|
return this.proto.contentTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
get _rawTimestamp(): bigint | undefined {
|
public get _rawTimestamp(): bigint | undefined {
|
||||||
return this.proto.timestamp;
|
return this.proto.timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
get timestamp(): Date | undefined {
|
public get timestamp(): Date | undefined {
|
||||||
// In the case we receive a value that is bigger than JS's max number,
|
// In the case we receive a value that is bigger than JS's max number,
|
||||||
// we catch the error and return undefined.
|
// we catch the error and return undefined.
|
||||||
try {
|
try {
|
||||||
@ -56,23 +56,23 @@ export class DecodedMessage implements IDecodedMessage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get meta(): Uint8Array | undefined {
|
public get meta(): Uint8Array | undefined {
|
||||||
return this.proto.meta;
|
return this.proto.meta;
|
||||||
}
|
}
|
||||||
|
|
||||||
get version(): number {
|
public get version(): number {
|
||||||
// https://rfc.vac.dev/spec/14/
|
// https://rfc.vac.dev/spec/14/
|
||||||
// > If omitted, the value SHOULD be interpreted as version 0.
|
// > If omitted, the value SHOULD be interpreted as version 0.
|
||||||
return this.proto.version ?? 0;
|
return this.proto.version ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
get rateLimitProof(): IRateLimitProof | undefined {
|
public get rateLimitProof(): IRateLimitProof | undefined {
|
||||||
return this.proto.rateLimitProof;
|
return this.proto.rateLimitProof;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Encoder implements IEncoder {
|
export class Encoder implements IEncoder {
|
||||||
constructor(
|
public constructor(
|
||||||
public contentTopic: string,
|
public contentTopic: string,
|
||||||
public ephemeral: boolean = false,
|
public ephemeral: boolean = false,
|
||||||
public pubsubTopic: PubsubTopic,
|
public pubsubTopic: PubsubTopic,
|
||||||
@ -83,11 +83,11 @@ export class Encoder implements IEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async toWire(message: IMessage): Promise<Uint8Array> {
|
public async toWire(message: IMessage): Promise<Uint8Array> {
|
||||||
return proto.WakuMessage.encode(await this.toProtoObj(message));
|
return proto.WakuMessage.encode(await this.toProtoObj(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
async toProtoObj(message: IMessage): Promise<IProtoMessage> {
|
public async toProtoObj(message: IMessage): Promise<IProtoMessage> {
|
||||||
const timestamp = message.timestamp ?? new Date();
|
const timestamp = message.timestamp ?? new Date();
|
||||||
|
|
||||||
const protoMessage = {
|
const protoMessage = {
|
||||||
@ -133,7 +133,7 @@ export function createEncoder({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Decoder implements IDecoder<DecodedMessage> {
|
export class Decoder implements IDecoder<DecodedMessage> {
|
||||||
constructor(
|
public constructor(
|
||||||
public pubsubTopic: PubsubTopic,
|
public pubsubTopic: PubsubTopic,
|
||||||
public contentTopic: string
|
public contentTopic: string
|
||||||
) {
|
) {
|
||||||
@ -142,7 +142,9 @@ export class Decoder implements IDecoder<DecodedMessage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
|
public fromWireToProtoObj(
|
||||||
|
bytes: Uint8Array
|
||||||
|
): Promise<IProtoMessage | undefined> {
|
||||||
const protoMessage = proto.WakuMessage.decode(bytes);
|
const protoMessage = proto.WakuMessage.decode(bytes);
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
payload: protoMessage.payload,
|
payload: protoMessage.payload,
|
||||||
@ -155,7 +157,7 @@ export class Decoder implements IDecoder<DecodedMessage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fromProtoObj(
|
public async fromProtoObj(
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
proto: IProtoMessage
|
proto: IProtoMessage
|
||||||
): Promise<DecodedMessage | undefined> {
|
): Promise<DecodedMessage | undefined> {
|
||||||
|
@ -23,9 +23,9 @@ export const MetadataCodec = "/vac/waku/metadata/1.0.0";
|
|||||||
|
|
||||||
class Metadata extends BaseProtocol implements IMetadata {
|
class Metadata extends BaseProtocol implements IMetadata {
|
||||||
private libp2pComponents: Libp2pComponents;
|
private libp2pComponents: Libp2pComponents;
|
||||||
handshakesConfirmed: Map<PeerIdStr, ShardInfo> = new Map();
|
protected handshakesConfirmed: Map<PeerIdStr, ShardInfo> = new Map();
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
public shardInfo: ShardInfo,
|
public shardInfo: ShardInfo,
|
||||||
libp2p: Libp2pComponents
|
libp2p: Libp2pComponents
|
||||||
) {
|
) {
|
||||||
@ -41,40 +41,10 @@ class Metadata extends BaseProtocol implements IMetadata {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle an incoming metadata request
|
|
||||||
*/
|
|
||||||
private async onRequest(streamData: IncomingStreamData): Promise<void> {
|
|
||||||
try {
|
|
||||||
const { stream, connection } = streamData;
|
|
||||||
const encodedShardInfo = proto_metadata.WakuMetadataResponse.encode(
|
|
||||||
this.shardInfo
|
|
||||||
);
|
|
||||||
|
|
||||||
const encodedResponse = await pipe(
|
|
||||||
[encodedShardInfo],
|
|
||||||
lp.encode,
|
|
||||||
stream,
|
|
||||||
lp.decode,
|
|
||||||
async (source) => await all(source)
|
|
||||||
);
|
|
||||||
|
|
||||||
const { error, shardInfo } = this.decodeMetadataResponse(encodedResponse);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.savePeerShardInfo(connection.remotePeer, shardInfo);
|
|
||||||
} catch (error) {
|
|
||||||
log.error("Error handling metadata request", error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a metadata query to a peer
|
* Make a metadata query to a peer
|
||||||
*/
|
*/
|
||||||
async query(peerId: PeerId): Promise<MetadataQueryResult> {
|
public async query(peerId: PeerId): Promise<MetadataQueryResult> {
|
||||||
const request = proto_metadata.WakuMetadataRequest.encode(this.shardInfo);
|
const request = proto_metadata.WakuMetadataRequest.encode(this.shardInfo);
|
||||||
|
|
||||||
const peer = await this.peerStore.get(peerId);
|
const peer = await this.peerStore.get(peerId);
|
||||||
@ -135,6 +105,36 @@ class Metadata extends BaseProtocol implements IMetadata {
|
|||||||
return await this.query(peerId);
|
return await this.query(peerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle an incoming metadata request
|
||||||
|
*/
|
||||||
|
private async onRequest(streamData: IncomingStreamData): Promise<void> {
|
||||||
|
try {
|
||||||
|
const { stream, connection } = streamData;
|
||||||
|
const encodedShardInfo = proto_metadata.WakuMetadataResponse.encode(
|
||||||
|
this.shardInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
const encodedResponse = await pipe(
|
||||||
|
[encodedShardInfo],
|
||||||
|
lp.encode,
|
||||||
|
stream,
|
||||||
|
lp.decode,
|
||||||
|
async (source) => await all(source)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { error, shardInfo } = this.decodeMetadataResponse(encodedResponse);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.savePeerShardInfo(connection.remotePeer, shardInfo);
|
||||||
|
} catch (error) {
|
||||||
|
log.error("Error handling metadata request", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private decodeMetadataResponse(
|
private decodeMetadataResponse(
|
||||||
encodedResponse: Uint8ArrayList[]
|
encodedResponse: Uint8ArrayList[]
|
||||||
): MetadataQueryResult {
|
): MetadataQueryResult {
|
||||||
|
@ -22,18 +22,18 @@ export interface Params {
|
|||||||
export class HistoryRpc {
|
export class HistoryRpc {
|
||||||
private constructor(public readonly proto: proto.HistoryRpc) {}
|
private constructor(public readonly proto: proto.HistoryRpc) {}
|
||||||
|
|
||||||
get query(): proto.HistoryQuery | undefined {
|
public get query(): proto.HistoryQuery | undefined {
|
||||||
return this.proto.query;
|
return this.proto.query;
|
||||||
}
|
}
|
||||||
|
|
||||||
get response(): proto.HistoryResponse | undefined {
|
public get response(): proto.HistoryResponse | undefined {
|
||||||
return this.proto.response;
|
return this.proto.response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create History Query.
|
* Create History Query.
|
||||||
*/
|
*/
|
||||||
static createQuery(params: Params): HistoryRpc {
|
public static createQuery(params: Params): HistoryRpc {
|
||||||
const contentFilters = params.contentTopics.map((contentTopic) => {
|
const contentFilters = params.contentTopics.map((contentTopic) => {
|
||||||
return { contentTopic };
|
return { contentTopic };
|
||||||
});
|
});
|
||||||
@ -69,12 +69,12 @@ export class HistoryRpc {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
decode(bytes: Uint8ArrayList): HistoryRpc {
|
public decode(bytes: Uint8ArrayList): HistoryRpc {
|
||||||
const res = proto.HistoryRpc.decode(bytes);
|
const res = proto.HistoryRpc.decode(bytes);
|
||||||
return new HistoryRpc(res);
|
return new HistoryRpc(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
encode(): Uint8Array {
|
public encode(): Uint8Array {
|
||||||
return proto.HistoryRpc.encode(this.proto);
|
return proto.HistoryRpc.encode(this.proto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,11 +68,11 @@ export interface QueryOptions {
|
|||||||
* The Waku Store protocol can be used to retrieved historical messages.
|
* The Waku Store protocol can be used to retrieved historical messages.
|
||||||
*/
|
*/
|
||||||
export class StoreCore extends BaseProtocol implements IStoreCore {
|
export class StoreCore extends BaseProtocol implements IStoreCore {
|
||||||
constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
public constructor(libp2p: Libp2p, options?: ProtocolCreateOptions) {
|
||||||
super(StoreCodec, libp2p.components, log, options!.pubsubTopics!, options);
|
super(StoreCodec, libp2p.components, log, options!.pubsubTopics!, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async *queryPerPage<T extends IDecodedMessage>(
|
public async *queryPerPage<T extends IDecodedMessage>(
|
||||||
queryOpts: Params,
|
queryOpts: Params,
|
||||||
decoders: Map<string, IDecoder<T>>,
|
decoders: Map<string, IDecoder<T>>,
|
||||||
peer: Peer
|
peer: Peer
|
||||||
|
@ -13,7 +13,7 @@ export class StreamManager {
|
|||||||
private readonly streamPool: Map<string, Promise<Stream | void>>;
|
private readonly streamPool: Map<string, Promise<Stream | void>>;
|
||||||
private readonly log: Logger;
|
private readonly log: Logger;
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
public multicodec: string,
|
public multicodec: string,
|
||||||
public getConnections: Libp2p["getConnections"],
|
public getConnections: Libp2p["getConnections"],
|
||||||
public addEventListener: Libp2p["addEventListener"]
|
public addEventListener: Libp2p["addEventListener"]
|
||||||
|
@ -32,23 +32,23 @@ const errorBranchB = `enrtree-branch:${branchDomainD}`;
|
|||||||
* Mocks DNS resolution.
|
* Mocks DNS resolution.
|
||||||
*/
|
*/
|
||||||
class MockDNS implements DnsClient {
|
class MockDNS implements DnsClient {
|
||||||
fqdnRes: Map<string, string[]>;
|
private fqdnRes: Map<string, string[]>;
|
||||||
fqdnThrows: string[];
|
private fqdnThrows: string[];
|
||||||
|
|
||||||
constructor() {
|
public constructor() {
|
||||||
this.fqdnRes = new Map();
|
this.fqdnRes = new Map();
|
||||||
this.fqdnThrows = [];
|
this.fqdnThrows = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
addRes(fqdn: string, res: string[]): void {
|
public addRes(fqdn: string, res: string[]): void {
|
||||||
this.fqdnRes.set(fqdn, res);
|
this.fqdnRes.set(fqdn, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
addThrow(fqdn: string): void {
|
public addThrow(fqdn: string): void {
|
||||||
this.fqdnThrows.push(fqdn);
|
this.fqdnThrows.push(fqdn);
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveTXT(fqdn: string): Promise<string[]> {
|
public resolveTXT(fqdn: string): Promise<string[]> {
|
||||||
if (this.fqdnThrows.includes(fqdn)) throw "Mock DNS throws.";
|
if (this.fqdnThrows.includes(fqdn)) throw "Mock DNS throws.";
|
||||||
|
|
||||||
const res = this.fqdnRes.get(fqdn);
|
const res = this.fqdnRes.get(fqdn);
|
||||||
|
@ -37,7 +37,7 @@ export class DnsNodeDiscovery {
|
|||||||
* peers encountered by randomized search exceeds the sum of the fields of
|
* peers encountered by randomized search exceeds the sum of the fields of
|
||||||
* @link wantedNodeCapabilityCount plus the @link _errorTolerance factor.
|
* @link wantedNodeCapabilityCount plus the @link _errorTolerance factor.
|
||||||
*/
|
*/
|
||||||
async getPeers(
|
public async getPeers(
|
||||||
enrTreeUrls: string[],
|
enrTreeUrls: string[],
|
||||||
wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
|
wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
|
||||||
): Promise<IEnr[]> {
|
): Promise<IEnr[]> {
|
||||||
@ -74,7 +74,7 @@ export class DnsNodeDiscovery {
|
|||||||
/**
|
/**
|
||||||
* {@inheritDoc getPeers}
|
* {@inheritDoc getPeers}
|
||||||
*/
|
*/
|
||||||
async *getNextPeer(
|
public async *getNextPeer(
|
||||||
enrTreeUrls: string[],
|
enrTreeUrls: string[],
|
||||||
wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
|
wantedNodeCapabilityCount: Partial<NodeCapabilityCount>
|
||||||
): AsyncGenerator<IEnr> {
|
): AsyncGenerator<IEnr> {
|
||||||
|
@ -36,7 +36,10 @@ export class PeerDiscoveryDns
|
|||||||
private _components: DnsDiscoveryComponents;
|
private _components: DnsDiscoveryComponents;
|
||||||
private _options: DnsDiscOptions;
|
private _options: DnsDiscOptions;
|
||||||
|
|
||||||
constructor(components: DnsDiscoveryComponents, options: DnsDiscOptions) {
|
public constructor(
|
||||||
|
components: DnsDiscoveryComponents,
|
||||||
|
options: DnsDiscOptions
|
||||||
|
) {
|
||||||
super();
|
super();
|
||||||
this._started = false;
|
this._started = false;
|
||||||
this._components = components;
|
this._components = components;
|
||||||
@ -49,7 +52,7 @@ export class PeerDiscoveryDns
|
|||||||
/**
|
/**
|
||||||
* Start discovery process
|
* Start discovery process
|
||||||
*/
|
*/
|
||||||
async start(): Promise<void> {
|
public async start(): Promise<void> {
|
||||||
log.info("Starting peer discovery via dns");
|
log.info("Starting peer discovery via dns");
|
||||||
|
|
||||||
this._started = true;
|
this._started = true;
|
||||||
@ -122,15 +125,15 @@ export class PeerDiscoveryDns
|
|||||||
/**
|
/**
|
||||||
* Stop emitting events
|
* Stop emitting events
|
||||||
*/
|
*/
|
||||||
stop(): void {
|
public stop(): void {
|
||||||
this._started = false;
|
this._started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get [symbol](): true {
|
public get [symbol](): true {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get [Symbol.toStringTag](): string {
|
public get [Symbol.toStringTag](): string {
|
||||||
return "@waku/bootstrap";
|
return "@waku/bootstrap";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ export class DnsOverHttps implements DnsClient {
|
|||||||
*
|
*
|
||||||
* @throws if the query fails
|
* @throws if the query fails
|
||||||
*/
|
*/
|
||||||
async resolveTXT(domain: string): Promise<string[]> {
|
public async resolveTXT(domain: string): Promise<string[]> {
|
||||||
let answers;
|
let answers;
|
||||||
try {
|
try {
|
||||||
const res = await query(
|
const res = await query(
|
||||||
|
@ -26,7 +26,7 @@ export class ENRTree {
|
|||||||
* Extracts the branch subdomain referenced by a DNS tree root string after verifying
|
* Extracts the branch subdomain referenced by a DNS tree root string after verifying
|
||||||
* the root record signature with its base32 compressed public key.
|
* the root record signature with its base32 compressed public key.
|
||||||
*/
|
*/
|
||||||
static parseAndVerifyRoot(root: string, publicKey: string): string {
|
public static parseAndVerifyRoot(root: string, publicKey: string): string {
|
||||||
if (!root.startsWith(this.ROOT_PREFIX))
|
if (!root.startsWith(this.ROOT_PREFIX))
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`ENRTree root entry must start with '${this.ROOT_PREFIX}'`
|
`ENRTree root entry must start with '${this.ROOT_PREFIX}'`
|
||||||
@ -57,7 +57,7 @@ export class ENRTree {
|
|||||||
return rootValues.eRoot;
|
return rootValues.eRoot;
|
||||||
}
|
}
|
||||||
|
|
||||||
static parseRootValues(txt: string): ENRRootValues {
|
public static parseRootValues(txt: string): ENRRootValues {
|
||||||
const matches = txt.match(
|
const matches = txt.match(
|
||||||
/^enrtree-root:v1 e=([^ ]+) l=([^ ]+) seq=(\d+) sig=([^ ]+)$/
|
/^enrtree-root:v1 e=([^ ]+) l=([^ ]+) seq=(\d+) sig=([^ ]+)$/
|
||||||
);
|
);
|
||||||
@ -86,7 +86,7 @@ export class ENRTree {
|
|||||||
* The domain is the starting point for traversing a set of linked DNS TXT records
|
* The domain is the starting point for traversing a set of linked DNS TXT records
|
||||||
* and the public key is used to verify the root entry record
|
* and the public key is used to verify the root entry record
|
||||||
*/
|
*/
|
||||||
static parseTree(tree: string): ENRTreeValues {
|
public static parseTree(tree: string): ENRTreeValues {
|
||||||
if (!tree.startsWith(this.TREE_PREFIX))
|
if (!tree.startsWith(this.TREE_PREFIX))
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`ENRTree tree entry must start with '${this.TREE_PREFIX}'`
|
`ENRTree tree entry must start with '${this.TREE_PREFIX}'`
|
||||||
@ -112,7 +112,7 @@ export class ENRTree {
|
|||||||
* Returns subdomains listed in an ENR branch entry. These in turn lead to
|
* Returns subdomains listed in an ENR branch entry. These in turn lead to
|
||||||
* either further branch entries or ENR records.
|
* either further branch entries or ENR records.
|
||||||
*/
|
*/
|
||||||
static parseBranch(branch: string): string[] {
|
public static parseBranch(branch: string): string[] {
|
||||||
if (!branch.startsWith(this.BRANCH_PREFIX))
|
if (!branch.startsWith(this.BRANCH_PREFIX))
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`ENRTree branch entry must start with '${this.BRANCH_PREFIX}'`
|
`ENRTree branch entry must start with '${this.BRANCH_PREFIX}'`
|
||||||
|
@ -35,7 +35,7 @@ export class LocalPeerCacheDiscovery
|
|||||||
private isStarted: boolean;
|
private isStarted: boolean;
|
||||||
private peers: LocalStoragePeerInfo[] = [];
|
private peers: LocalStoragePeerInfo[] = [];
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
private readonly components: Libp2pComponents,
|
private readonly components: Libp2pComponents,
|
||||||
private readonly options?: LocalPeerCacheDiscoveryOptions
|
private readonly options?: LocalPeerCacheDiscoveryOptions
|
||||||
) {
|
) {
|
||||||
@ -44,11 +44,11 @@ export class LocalPeerCacheDiscovery
|
|||||||
this.peers = this.getPeersFromLocalStorage();
|
this.peers = this.getPeersFromLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
get [Symbol.toStringTag](): string {
|
public get [Symbol.toStringTag](): string {
|
||||||
return "@waku/local-peer-cache-discovery";
|
return "@waku/local-peer-cache-discovery";
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(): Promise<void> {
|
public async start(): Promise<void> {
|
||||||
if (this.isStarted) return;
|
if (this.isStarted) return;
|
||||||
|
|
||||||
log.info("Starting Local Storage Discovery");
|
log.info("Starting Local Storage Discovery");
|
||||||
@ -86,7 +86,7 @@ export class LocalPeerCacheDiscovery
|
|||||||
this.isStarted = true;
|
this.isStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
stop(): void | Promise<void> {
|
public stop(): void | Promise<void> {
|
||||||
if (!this.isStarted) return;
|
if (!this.isStarted) return;
|
||||||
log.info("Stopping Local Storage Discovery");
|
log.info("Stopping Local Storage Discovery");
|
||||||
this.components.events.removeEventListener(
|
this.components.events.removeEventListener(
|
||||||
@ -98,7 +98,7 @@ export class LocalPeerCacheDiscovery
|
|||||||
this.savePeersToLocalStorage();
|
this.savePeersToLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNewPeers = (event: CustomEvent<IdentifyResult>): void => {
|
public handleNewPeers = (event: CustomEvent<IdentifyResult>): void => {
|
||||||
const { peerId, listenAddrs } = event.detail;
|
const { peerId, listenAddrs } = event.detail;
|
||||||
|
|
||||||
const websocketMultiaddr = getWsMultiaddrFromMultiaddrs(listenAddrs);
|
const websocketMultiaddr = getWsMultiaddrFromMultiaddrs(listenAddrs);
|
||||||
|
@ -7,7 +7,9 @@ import type { Uint8ArrayList } from "uint8arraylist";
|
|||||||
export class PeerExchangeRPC {
|
export class PeerExchangeRPC {
|
||||||
public constructor(public proto: proto.PeerExchangeRPC) {}
|
public constructor(public proto: proto.PeerExchangeRPC) {}
|
||||||
|
|
||||||
static createRequest(params: proto.PeerExchangeQuery): PeerExchangeRPC {
|
public static createRequest(
|
||||||
|
params: proto.PeerExchangeQuery
|
||||||
|
): PeerExchangeRPC {
|
||||||
const { numPeers } = params;
|
const { numPeers } = params;
|
||||||
return new PeerExchangeRPC({
|
return new PeerExchangeRPC({
|
||||||
query: {
|
query: {
|
||||||
@ -21,7 +23,7 @@ export class PeerExchangeRPC {
|
|||||||
* Encode the current PeerExchangeRPC request to bytes
|
* Encode the current PeerExchangeRPC request to bytes
|
||||||
* @returns Uint8Array
|
* @returns Uint8Array
|
||||||
*/
|
*/
|
||||||
encode(): Uint8Array {
|
public encode(): Uint8Array {
|
||||||
return proto.PeerExchangeRPC.encode(this.proto);
|
return proto.PeerExchangeRPC.encode(this.proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,16 +31,16 @@ export class PeerExchangeRPC {
|
|||||||
* Decode the current PeerExchangeRPC request to bytes
|
* Decode the current PeerExchangeRPC request to bytes
|
||||||
* @returns Uint8Array
|
* @returns Uint8Array
|
||||||
*/
|
*/
|
||||||
static decode(bytes: Uint8ArrayList): PeerExchangeRPC {
|
public static decode(bytes: Uint8ArrayList): PeerExchangeRPC {
|
||||||
const res = proto.PeerExchangeRPC.decode(bytes);
|
const res = proto.PeerExchangeRPC.decode(bytes);
|
||||||
return new PeerExchangeRPC(res);
|
return new PeerExchangeRPC(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
get query(): proto.PeerExchangeQuery | undefined {
|
public get query(): proto.PeerExchangeQuery | undefined {
|
||||||
return this.proto.query;
|
return this.proto.query;
|
||||||
}
|
}
|
||||||
|
|
||||||
get response(): proto.PeerExchangeResponse | undefined {
|
public get response(): proto.PeerExchangeResponse | undefined {
|
||||||
return this.proto.response;
|
return this.proto.response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,14 +28,17 @@ export class WakuPeerExchange extends BaseProtocol implements IPeerExchange {
|
|||||||
/**
|
/**
|
||||||
* @param components - libp2p components
|
* @param components - libp2p components
|
||||||
*/
|
*/
|
||||||
constructor(components: Libp2pComponents, pubsubTopics: PubsubTopic[]) {
|
public constructor(
|
||||||
|
components: Libp2pComponents,
|
||||||
|
pubsubTopics: PubsubTopic[]
|
||||||
|
) {
|
||||||
super(PeerExchangeCodec, components, log, pubsubTopics);
|
super(PeerExchangeCodec, components, log, pubsubTopics);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a peer exchange query to a peer
|
* Make a peer exchange query to a peer
|
||||||
*/
|
*/
|
||||||
async query(
|
public async query(
|
||||||
params: PeerExchangeQueryParams
|
params: PeerExchangeQueryParams
|
||||||
): Promise<PeerExchangeQueryResult> {
|
): Promise<PeerExchangeQueryResult> {
|
||||||
const { numPeers } = params;
|
const { numPeers } = params;
|
||||||
|
@ -82,7 +82,7 @@ export class PeerExchangeDiscovery
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
components: Libp2pComponents,
|
components: Libp2pComponents,
|
||||||
pubsubTopics: PubsubTopic[],
|
pubsubTopics: PubsubTopic[],
|
||||||
options: Options = {}
|
options: Options = {}
|
||||||
@ -97,7 +97,7 @@ export class PeerExchangeDiscovery
|
|||||||
/**
|
/**
|
||||||
* Start emitting events
|
* Start emitting events
|
||||||
*/
|
*/
|
||||||
start(): void {
|
public start(): void {
|
||||||
if (this.isStarted) {
|
if (this.isStarted) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -114,7 +114,7 @@ export class PeerExchangeDiscovery
|
|||||||
/**
|
/**
|
||||||
* Remove event listener
|
* Remove event listener
|
||||||
*/
|
*/
|
||||||
stop(): void {
|
public stop(): void {
|
||||||
if (!this.isStarted) return;
|
if (!this.isStarted) return;
|
||||||
log.info("Stopping peer exchange node discovery");
|
log.info("Stopping peer exchange node discovery");
|
||||||
this.isStarted = false;
|
this.isStarted = false;
|
||||||
@ -125,11 +125,11 @@ export class PeerExchangeDiscovery
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get [symbol](): true {
|
public get [symbol](): true {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get [Symbol.toStringTag](): string {
|
public get [Symbol.toStringTag](): string {
|
||||||
return "@waku/peer-exchange";
|
return "@waku/peer-exchange";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { ENR } from "./enr.js";
|
|||||||
import { getPublicKeyFromPeerId } from "./peer_id.js";
|
import { getPublicKeyFromPeerId } from "./peer_id.js";
|
||||||
|
|
||||||
export class EnrCreator {
|
export class EnrCreator {
|
||||||
static fromPublicKey(
|
public static fromPublicKey(
|
||||||
publicKey: Uint8Array,
|
publicKey: Uint8Array,
|
||||||
kvs: Record<ENRKey, ENRValue> = {}
|
kvs: Record<ENRKey, ENRValue> = {}
|
||||||
): Promise<ENR> {
|
): Promise<ENR> {
|
||||||
@ -22,7 +22,7 @@ export class EnrCreator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static async fromPeerId(
|
public static async fromPeerId(
|
||||||
peerId: PeerId,
|
peerId: PeerId,
|
||||||
kvs: Record<ENRKey, ENRValue> = {}
|
kvs: Record<ENRKey, ENRValue> = {}
|
||||||
): Promise<ENR> {
|
): Promise<ENR> {
|
||||||
|
@ -9,7 +9,7 @@ import { ENR } from "./enr.js";
|
|||||||
const log = new Logger("enr:decoder");
|
const log = new Logger("enr:decoder");
|
||||||
|
|
||||||
export class EnrDecoder {
|
export class EnrDecoder {
|
||||||
static fromString(encoded: string): Promise<ENR> {
|
public static fromString(encoded: string): Promise<ENR> {
|
||||||
if (!encoded.startsWith(ENR.RECORD_PREFIX)) {
|
if (!encoded.startsWith(ENR.RECORD_PREFIX)) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`"string encoded ENR must start with '${ENR.RECORD_PREFIX}'`
|
`"string encoded ENR must start with '${ENR.RECORD_PREFIX}'`
|
||||||
@ -18,7 +18,7 @@ export class EnrDecoder {
|
|||||||
return EnrDecoder.fromRLP(fromString(encoded.slice(4), "base64url"));
|
return EnrDecoder.fromRLP(fromString(encoded.slice(4), "base64url"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static fromRLP(encoded: Uint8Array): Promise<ENR> {
|
public static fromRLP(encoded: Uint8Array): Promise<ENR> {
|
||||||
const decoded = RLP.decode(encoded).map(hexToBytes);
|
const decoded = RLP.decode(encoded).map(hexToBytes);
|
||||||
return fromValues(decoded);
|
return fromValues(decoded);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import { ERR_NO_SIGNATURE, MAX_RECORD_SIZE } from "./constants.js";
|
|||||||
import { ENR } from "./enr.js";
|
import { ENR } from "./enr.js";
|
||||||
|
|
||||||
export class EnrEncoder {
|
export class EnrEncoder {
|
||||||
static async toValues(
|
public static async toValues(
|
||||||
enr: ENR,
|
enr: ENR,
|
||||||
privateKey?: Uint8Array
|
privateKey?: Uint8Array
|
||||||
): Promise<(ENRKey | ENRValue | number[])[]> {
|
): Promise<(ENRKey | ENRValue | number[])[]> {
|
||||||
@ -31,7 +31,10 @@ export class EnrEncoder {
|
|||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async toBytes(enr: ENR, privateKey?: Uint8Array): Promise<Uint8Array> {
|
public static async toBytes(
|
||||||
|
enr: ENR,
|
||||||
|
privateKey?: Uint8Array
|
||||||
|
): Promise<Uint8Array> {
|
||||||
const encoded = hexToBytes(
|
const encoded = hexToBytes(
|
||||||
RLP.encode(await EnrEncoder.toValues(enr, privateKey))
|
RLP.encode(await EnrEncoder.toValues(enr, privateKey))
|
||||||
);
|
);
|
||||||
@ -41,7 +44,10 @@ export class EnrEncoder {
|
|||||||
return encoded;
|
return encoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
static async toString(enr: ENR, privateKey?: Uint8Array): Promise<string> {
|
public static async toString(
|
||||||
|
enr: ENR,
|
||||||
|
privateKey?: Uint8Array
|
||||||
|
): Promise<string> {
|
||||||
return (
|
return (
|
||||||
ENR.RECORD_PREFIX +
|
ENR.RECORD_PREFIX +
|
||||||
toString(await EnrEncoder.toBytes(enr, privateKey), "base64url")
|
toString(await EnrEncoder.toBytes(enr, privateKey), "base64url")
|
||||||
|
@ -34,7 +34,7 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
public static readonly RECORD_PREFIX = "enr:";
|
public static readonly RECORD_PREFIX = "enr:";
|
||||||
public peerId?: PeerId;
|
public peerId?: PeerId;
|
||||||
|
|
||||||
static async create(
|
public static async create(
|
||||||
kvs: Record<ENRKey, ENRValue> = {},
|
kvs: Record<ENRKey, ENRValue> = {},
|
||||||
seq: SequenceNumber = BigInt(1),
|
seq: SequenceNumber = BigInt(1),
|
||||||
signature?: Uint8Array
|
signature?: Uint8Array
|
||||||
@ -52,7 +52,7 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
return enr;
|
return enr;
|
||||||
}
|
}
|
||||||
|
|
||||||
get nodeId(): NodeId | undefined {
|
public get nodeId(): NodeId | undefined {
|
||||||
switch (this.id) {
|
switch (this.id) {
|
||||||
case "v4":
|
case "v4":
|
||||||
return this.publicKey ? v4.nodeId(this.publicKey) : undefined;
|
return this.publicKey ? v4.nodeId(this.publicKey) : undefined;
|
||||||
@ -60,18 +60,18 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
throw new Error(ERR_INVALID_ID);
|
throw new Error(ERR_INVALID_ID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getLocationMultiaddr: (
|
public getLocationMultiaddr: (
|
||||||
protocol: TransportProtocol | TransportProtocolPerIpVersion
|
protocol: TransportProtocol | TransportProtocolPerIpVersion
|
||||||
) => Multiaddr | undefined = locationMultiaddrFromEnrFields.bind({}, this);
|
) => Multiaddr | undefined = locationMultiaddrFromEnrFields.bind({}, this);
|
||||||
|
|
||||||
get shardInfo(): ShardInfo | undefined {
|
public get shardInfo(): ShardInfo | undefined {
|
||||||
if (this.rs && this.rsv) {
|
if (this.rs && this.rsv) {
|
||||||
log.warn("ENR contains both `rs` and `rsv` fields.");
|
log.warn("ENR contains both `rs` and `rsv` fields.");
|
||||||
}
|
}
|
||||||
return this.rs || this.rsv;
|
return this.rs || this.rsv;
|
||||||
}
|
}
|
||||||
|
|
||||||
setLocationMultiaddr(multiaddr: Multiaddr): void {
|
public setLocationMultiaddr(multiaddr: Multiaddr): void {
|
||||||
const protoNames = multiaddr.protoNames();
|
const protoNames = multiaddr.protoNames();
|
||||||
if (
|
if (
|
||||||
protoNames.length !== 2 &&
|
protoNames.length !== 2 &&
|
||||||
@ -95,7 +95,7 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllLocationMultiaddrs(): Multiaddr[] {
|
public getAllLocationMultiaddrs(): Multiaddr[] {
|
||||||
const multiaddrs = [];
|
const multiaddrs = [];
|
||||||
|
|
||||||
for (const protocol of Object.values(TransportProtocolPerIpVersion)) {
|
for (const protocol of Object.values(TransportProtocolPerIpVersion)) {
|
||||||
@ -115,7 +115,7 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get peerInfo(): PeerInfo | undefined {
|
public get peerInfo(): PeerInfo | undefined {
|
||||||
const id = this.peerId;
|
const id = this.peerId;
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
return {
|
return {
|
||||||
@ -132,7 +132,7 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
*
|
*
|
||||||
* @param protocol
|
* @param protocol
|
||||||
*/
|
*/
|
||||||
getFullMultiaddr(
|
public getFullMultiaddr(
|
||||||
protocol: TransportProtocol | TransportProtocolPerIpVersion
|
protocol: TransportProtocol | TransportProtocolPerIpVersion
|
||||||
): Multiaddr | undefined {
|
): Multiaddr | undefined {
|
||||||
if (this.peerId) {
|
if (this.peerId) {
|
||||||
@ -147,7 +147,7 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
/**
|
/**
|
||||||
* Returns the full multiaddrs from the `multiaddrs` ENR field.
|
* Returns the full multiaddrs from the `multiaddrs` ENR field.
|
||||||
*/
|
*/
|
||||||
getFullMultiaddrs(): Multiaddr[] {
|
public getFullMultiaddrs(): Multiaddr[] {
|
||||||
if (this.peerId && this.multiaddrs) {
|
if (this.peerId && this.multiaddrs) {
|
||||||
const peerId = this.peerId;
|
const peerId = this.peerId;
|
||||||
return this.multiaddrs.map((ma) => {
|
return this.multiaddrs.map((ma) => {
|
||||||
@ -157,7 +157,7 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
verify(data: Uint8Array, signature: Uint8Array): boolean {
|
public verify(data: Uint8Array, signature: Uint8Array): boolean {
|
||||||
if (!this.get("id") || this.id !== "v4") {
|
if (!this.get("id") || this.id !== "v4") {
|
||||||
throw new Error(ERR_INVALID_ID);
|
throw new Error(ERR_INVALID_ID);
|
||||||
}
|
}
|
||||||
@ -167,7 +167,10 @@ export class ENR extends RawEnr implements IEnr {
|
|||||||
return verifySignature(signature, keccak256(data), this.publicKey);
|
return verifySignature(signature, keccak256(data), this.publicKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sign(data: Uint8Array, privateKey: Uint8Array): Promise<Uint8Array> {
|
public async sign(
|
||||||
|
data: Uint8Array,
|
||||||
|
privateKey: Uint8Array
|
||||||
|
): Promise<Uint8Array> {
|
||||||
switch (this.id) {
|
switch (this.id) {
|
||||||
case "v4":
|
case "v4":
|
||||||
this.signature = await v4.sign(privateKey, data);
|
this.signature = await v4.sign(privateKey, data);
|
||||||
|
@ -31,19 +31,19 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
|
|||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
set(k: ENRKey, v: ENRValue): this {
|
public set(k: ENRKey, v: ENRValue): this {
|
||||||
this.signature = undefined;
|
this.signature = undefined;
|
||||||
this.seq++;
|
this.seq++;
|
||||||
return super.set(k, v);
|
return super.set(k, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
get id(): string {
|
public get id(): string {
|
||||||
const id = this.get("id");
|
const id = this.get("id");
|
||||||
if (!id) throw new Error("id not found.");
|
if (!id) throw new Error("id not found.");
|
||||||
return bytesToUtf8(id);
|
return bytesToUtf8(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
get publicKey(): Uint8Array | undefined {
|
public get publicKey(): Uint8Array | undefined {
|
||||||
switch (this.id) {
|
switch (this.id) {
|
||||||
case "v4":
|
case "v4":
|
||||||
return this.get("secp256k1");
|
return this.get("secp256k1");
|
||||||
@ -52,63 +52,63 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get rs(): ShardInfo | undefined {
|
public get rs(): ShardInfo | undefined {
|
||||||
const rs = this.get("rs");
|
const rs = this.get("rs");
|
||||||
if (!rs) return undefined;
|
if (!rs) return undefined;
|
||||||
return decodeRelayShard(rs);
|
return decodeRelayShard(rs);
|
||||||
}
|
}
|
||||||
|
|
||||||
get rsv(): ShardInfo | undefined {
|
public get rsv(): ShardInfo | undefined {
|
||||||
const rsv = this.get("rsv");
|
const rsv = this.get("rsv");
|
||||||
if (!rsv) return undefined;
|
if (!rsv) return undefined;
|
||||||
return decodeRelayShard(rsv);
|
return decodeRelayShard(rsv);
|
||||||
}
|
}
|
||||||
|
|
||||||
get ip(): string | undefined {
|
public get ip(): string | undefined {
|
||||||
return getStringValue(this, "ip", "ip4");
|
return getStringValue(this, "ip", "ip4");
|
||||||
}
|
}
|
||||||
|
|
||||||
set ip(ip: string | undefined) {
|
public set ip(ip: string | undefined) {
|
||||||
setStringValue(this, "ip", "ip4", ip);
|
setStringValue(this, "ip", "ip4", ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
get tcp(): number | undefined {
|
public get tcp(): number | undefined {
|
||||||
return getNumberAsStringValue(this, "tcp", "tcp");
|
return getNumberAsStringValue(this, "tcp", "tcp");
|
||||||
}
|
}
|
||||||
|
|
||||||
set tcp(port: number | undefined) {
|
public set tcp(port: number | undefined) {
|
||||||
setNumberAsStringValue(this, "tcp", "tcp", port);
|
setNumberAsStringValue(this, "tcp", "tcp", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
get udp(): number | undefined {
|
public get udp(): number | undefined {
|
||||||
return getNumberAsStringValue(this, "udp", "udp");
|
return getNumberAsStringValue(this, "udp", "udp");
|
||||||
}
|
}
|
||||||
|
|
||||||
set udp(port: number | undefined) {
|
public set udp(port: number | undefined) {
|
||||||
setNumberAsStringValue(this, "udp", "udp", port);
|
setNumberAsStringValue(this, "udp", "udp", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
get ip6(): string | undefined {
|
public get ip6(): string | undefined {
|
||||||
return getStringValue(this, "ip6", "ip6");
|
return getStringValue(this, "ip6", "ip6");
|
||||||
}
|
}
|
||||||
|
|
||||||
set ip6(ip: string | undefined) {
|
public set ip6(ip: string | undefined) {
|
||||||
setStringValue(this, "ip6", "ip6", ip);
|
setStringValue(this, "ip6", "ip6", ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
get tcp6(): number | undefined {
|
public get tcp6(): number | undefined {
|
||||||
return getNumberAsStringValue(this, "tcp6", "tcp");
|
return getNumberAsStringValue(this, "tcp6", "tcp");
|
||||||
}
|
}
|
||||||
|
|
||||||
set tcp6(port: number | undefined) {
|
public set tcp6(port: number | undefined) {
|
||||||
setNumberAsStringValue(this, "tcp6", "tcp", port);
|
setNumberAsStringValue(this, "tcp6", "tcp", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
get udp6(): number | undefined {
|
public get udp6(): number | undefined {
|
||||||
return getNumberAsStringValue(this, "udp6", "udp");
|
return getNumberAsStringValue(this, "udp6", "udp");
|
||||||
}
|
}
|
||||||
|
|
||||||
set udp6(port: number | undefined) {
|
public set udp6(port: number | undefined) {
|
||||||
setNumberAsStringValue(this, "udp6", "udp", port);
|
setNumberAsStringValue(this, "udp6", "udp", port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
|
|||||||
*
|
*
|
||||||
* The multiaddresses stored in this field are expected to be location multiaddresses, ie, peer id less.
|
* The multiaddresses stored in this field are expected to be location multiaddresses, ie, peer id less.
|
||||||
*/
|
*/
|
||||||
get multiaddrs(): Multiaddr[] | undefined {
|
public get multiaddrs(): Multiaddr[] | undefined {
|
||||||
const raw = this.get("multiaddrs");
|
const raw = this.get("multiaddrs");
|
||||||
|
|
||||||
if (raw) return decodeMultiaddrs(raw);
|
if (raw) return decodeMultiaddrs(raw);
|
||||||
@ -144,14 +144,14 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
|
|||||||
* The multiaddresses stored in this field must be location multiaddresses,
|
* The multiaddresses stored in this field must be location multiaddresses,
|
||||||
* ie, without a peer id.
|
* ie, without a peer id.
|
||||||
*/
|
*/
|
||||||
set multiaddrs(multiaddrs: Multiaddr[] | undefined) {
|
public set multiaddrs(multiaddrs: Multiaddr[] | undefined) {
|
||||||
deleteUndefined(this, "multiaddrs", multiaddrs, encodeMultiaddrs);
|
deleteUndefined(this, "multiaddrs", multiaddrs, encodeMultiaddrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the `waku2` field from ENR.
|
* Get the `waku2` field from ENR.
|
||||||
*/
|
*/
|
||||||
get waku2(): Waku2 | undefined {
|
public get waku2(): Waku2 | undefined {
|
||||||
const raw = this.get("waku2");
|
const raw = this.get("waku2");
|
||||||
if (raw) return decodeWaku2(raw[0]);
|
if (raw) return decodeWaku2(raw[0]);
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ export class RawEnr extends Map<ENRKey, ENRValue> {
|
|||||||
/**
|
/**
|
||||||
* Set the `waku2` field on the ENR.
|
* Set the `waku2` field on the ENR.
|
||||||
*/
|
*/
|
||||||
set waku2(waku2: Waku2 | undefined) {
|
public set waku2(waku2: Waku2 | undefined) {
|
||||||
deleteUndefined(
|
deleteUndefined(
|
||||||
this,
|
this,
|
||||||
"waku2",
|
"waku2",
|
||||||
|
@ -11,7 +11,7 @@ export class DecodedMessage
|
|||||||
{
|
{
|
||||||
private readonly _decodedPayload: Uint8Array;
|
private readonly _decodedPayload: Uint8Array;
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
proto: proto.WakuMessage,
|
proto: proto.WakuMessage,
|
||||||
decodedPayload: Uint8Array,
|
decodedPayload: Uint8Array,
|
||||||
@ -22,7 +22,7 @@ export class DecodedMessage
|
|||||||
this._decodedPayload = decodedPayload;
|
this._decodedPayload = decodedPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
get payload(): Uint8Array {
|
public get payload(): Uint8Array {
|
||||||
return this._decodedPayload;
|
return this._decodedPayload;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ export class DecodedMessage
|
|||||||
*
|
*
|
||||||
* @returns true if the signature matches the public key, false if not or if no signature is present.
|
* @returns true if the signature matches the public key, false if not or if no signature is present.
|
||||||
*/
|
*/
|
||||||
verifySignature(publicKey: Uint8Array): boolean {
|
public verifySignature(publicKey: Uint8Array): boolean {
|
||||||
if (this.signaturePublicKey) {
|
if (this.signaturePublicKey) {
|
||||||
return equals(this.signaturePublicKey, publicKey);
|
return equals(this.signaturePublicKey, publicKey);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ export {
|
|||||||
const log = new Logger("message-encryption:ecies");
|
const log = new Logger("message-encryption:ecies");
|
||||||
|
|
||||||
class Encoder implements IEncoder {
|
class Encoder implements IEncoder {
|
||||||
constructor(
|
public constructor(
|
||||||
public pubsubTopic: PubsubTopic,
|
public pubsubTopic: PubsubTopic,
|
||||||
public contentTopic: string,
|
public contentTopic: string,
|
||||||
private publicKey: Uint8Array,
|
private publicKey: Uint8Array,
|
||||||
@ -46,14 +46,16 @@ class Encoder implements IEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
public async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
||||||
const protoMessage = await this.toProtoObj(message);
|
const protoMessage = await this.toProtoObj(message);
|
||||||
if (!protoMessage) return;
|
if (!protoMessage) return;
|
||||||
|
|
||||||
return WakuMessage.encode(protoMessage);
|
return WakuMessage.encode(protoMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
async toProtoObj(message: IMessage): Promise<IProtoMessage | undefined> {
|
public async toProtoObj(
|
||||||
|
message: IMessage
|
||||||
|
): Promise<IProtoMessage | undefined> {
|
||||||
const timestamp = message.timestamp ?? new Date();
|
const timestamp = message.timestamp ?? new Date();
|
||||||
const preparedPayload = await preCipher(message.payload, this.sigPrivKey);
|
const preparedPayload = await preCipher(message.payload, this.sigPrivKey);
|
||||||
|
|
||||||
@ -121,7 +123,7 @@ export function createEncoder({
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
|
class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
|
||||||
constructor(
|
public constructor(
|
||||||
pubsubTopic: PubsubTopic,
|
pubsubTopic: PubsubTopic,
|
||||||
contentTopic: string,
|
contentTopic: string,
|
||||||
private privateKey: Uint8Array
|
private privateKey: Uint8Array
|
||||||
@ -129,7 +131,7 @@ class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
|
|||||||
super(pubsubTopic, contentTopic);
|
super(pubsubTopic, contentTopic);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fromProtoObj(
|
public async fromProtoObj(
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
protoMessage: IProtoMessage
|
protoMessage: IProtoMessage
|
||||||
): Promise<DecodedMessage | undefined> {
|
): Promise<DecodedMessage | undefined> {
|
||||||
|
@ -34,7 +34,7 @@ export {
|
|||||||
const log = new Logger("message-encryption:symmetric");
|
const log = new Logger("message-encryption:symmetric");
|
||||||
|
|
||||||
class Encoder implements IEncoder {
|
class Encoder implements IEncoder {
|
||||||
constructor(
|
public constructor(
|
||||||
public pubsubTopic: PubsubTopic,
|
public pubsubTopic: PubsubTopic,
|
||||||
public contentTopic: string,
|
public contentTopic: string,
|
||||||
private symKey: Uint8Array,
|
private symKey: Uint8Array,
|
||||||
@ -47,14 +47,16 @@ class Encoder implements IEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
public async toWire(message: IMessage): Promise<Uint8Array | undefined> {
|
||||||
const protoMessage = await this.toProtoObj(message);
|
const protoMessage = await this.toProtoObj(message);
|
||||||
if (!protoMessage) return;
|
if (!protoMessage) return;
|
||||||
|
|
||||||
return WakuMessage.encode(protoMessage);
|
return WakuMessage.encode(protoMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
async toProtoObj(message: IMessage): Promise<IProtoMessage | undefined> {
|
public async toProtoObj(
|
||||||
|
message: IMessage
|
||||||
|
): Promise<IProtoMessage | undefined> {
|
||||||
const timestamp = message.timestamp ?? new Date();
|
const timestamp = message.timestamp ?? new Date();
|
||||||
const preparedPayload = await preCipher(message.payload, this.sigPrivKey);
|
const preparedPayload = await preCipher(message.payload, this.sigPrivKey);
|
||||||
|
|
||||||
@ -118,7 +120,7 @@ export function createEncoder({
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
|
class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
|
||||||
constructor(
|
public constructor(
|
||||||
pubsubTopic: PubsubTopic,
|
pubsubTopic: PubsubTopic,
|
||||||
contentTopic: string,
|
contentTopic: string,
|
||||||
private symKey: Uint8Array
|
private symKey: Uint8Array
|
||||||
@ -126,7 +128,7 @@ class Decoder extends DecoderV0 implements IDecoder<DecodedMessage> {
|
|||||||
super(pubsubTopic, contentTopic);
|
super(pubsubTopic, contentTopic);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fromProtoObj(
|
public async fromProtoObj(
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
protoMessage: IProtoMessage
|
protoMessage: IProtoMessage
|
||||||
): Promise<DecodedMessage | undefined> {
|
): Promise<DecodedMessage | undefined> {
|
||||||
|
@ -59,7 +59,7 @@ class Relay implements IRelay {
|
|||||||
*/
|
*/
|
||||||
private observers: Map<PubsubTopic, Map<ContentTopic, Set<unknown>>>;
|
private observers: Map<PubsubTopic, Map<ContentTopic, Set<unknown>>>;
|
||||||
|
|
||||||
constructor(libp2p: Libp2p, pubsubTopics: PubsubTopic[]) {
|
public constructor(libp2p: Libp2p, pubsubTopics: PubsubTopic[]) {
|
||||||
if (!this.isRelayPubsub(libp2p.services.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}`
|
||||||
|
@ -13,21 +13,23 @@ export class TopicOnlyMessage implements IDecodedMessage {
|
|||||||
public meta: undefined;
|
public meta: undefined;
|
||||||
public ephemeral: undefined;
|
public ephemeral: undefined;
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
public pubsubTopic: string,
|
public pubsubTopic: string,
|
||||||
private proto: ProtoTopicOnlyMessage
|
private proto: ProtoTopicOnlyMessage
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
get contentTopic(): string {
|
public get contentTopic(): string {
|
||||||
return this.proto.contentTopic;
|
return this.proto.contentTopic;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TopicOnlyDecoder implements IDecoder<TopicOnlyMessage> {
|
export class TopicOnlyDecoder implements IDecoder<TopicOnlyMessage> {
|
||||||
pubsubTopic = DefaultPubsubTopic;
|
public pubsubTopic = DefaultPubsubTopic;
|
||||||
public contentTopic = "";
|
public contentTopic = "";
|
||||||
|
|
||||||
fromWireToProtoObj(bytes: Uint8Array): Promise<IProtoMessage | undefined> {
|
public fromWireToProtoObj(
|
||||||
|
bytes: Uint8Array
|
||||||
|
): Promise<IProtoMessage | undefined> {
|
||||||
const protoMessage = ProtoTopicOnlyMessage.decode(bytes);
|
const protoMessage = ProtoTopicOnlyMessage.decode(bytes);
|
||||||
return Promise.resolve({
|
return Promise.resolve({
|
||||||
contentTopic: protoMessage.contentTopic,
|
contentTopic: protoMessage.contentTopic,
|
||||||
@ -40,7 +42,7 @@ export class TopicOnlyDecoder implements IDecoder<TopicOnlyMessage> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fromProtoObj(
|
public async fromProtoObj(
|
||||||
pubsubTopic: string,
|
pubsubTopic: string,
|
||||||
proto: IProtoMessage
|
proto: IProtoMessage
|
||||||
): Promise<TopicOnlyMessage | undefined> {
|
): Promise<TopicOnlyMessage | undefined> {
|
||||||
|
@ -19,14 +19,14 @@ export class BaseProtocolSDK implements IBaseProtocolSDK {
|
|||||||
private maintainPeersIntervalId: ReturnType<
|
private maintainPeersIntervalId: ReturnType<
|
||||||
typeof window.setInterval
|
typeof window.setInterval
|
||||||
> | null = null;
|
> | null = null;
|
||||||
log: Logger;
|
private log: Logger;
|
||||||
|
|
||||||
private maintainPeersLock = false;
|
private maintainPeersLock = false;
|
||||||
private readonly renewPeersLocker = new RenewPeerLocker(
|
private readonly renewPeersLocker = new RenewPeerLocker(
|
||||||
RENEW_TIME_LOCK_DURATION
|
RENEW_TIME_LOCK_DURATION
|
||||||
);
|
);
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
protected core: BaseProtocol,
|
protected core: BaseProtocol,
|
||||||
private connectionManager: ConnectionManager,
|
private connectionManager: ConnectionManager,
|
||||||
options: Options
|
options: Options
|
||||||
@ -39,7 +39,7 @@ export class BaseProtocolSDK implements IBaseProtocolSDK {
|
|||||||
void this.startMaintainPeersInterval(maintainPeersInterval);
|
void this.startMaintainPeersInterval(maintainPeersInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
get connectedPeers(): Peer[] {
|
public get connectedPeers(): Peer[] {
|
||||||
return this.peers;
|
return this.peers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ export class BaseProtocolSDK implements IBaseProtocolSDK {
|
|||||||
class RenewPeerLocker {
|
class RenewPeerLocker {
|
||||||
private readonly peers: Map<string, number> = new Map();
|
private readonly peers: Map<string, number> = new Map();
|
||||||
|
|
||||||
constructor(private lockDuration: number) {}
|
public constructor(private lockDuration: number) {}
|
||||||
|
|
||||||
public lock(id: PeerId): void {
|
public lock(id: PeerId): void {
|
||||||
this.peers.set(id.toString(), Date.now());
|
this.peers.set(id.toString(), Date.now());
|
||||||
|
@ -57,8 +57,7 @@ const DEFAULT_SUBSCRIBE_OPTIONS = {
|
|||||||
keepAlive: DEFAULT_KEEP_ALIVE
|
keepAlive: DEFAULT_KEEP_ALIVE
|
||||||
};
|
};
|
||||||
export class SubscriptionManager implements ISubscriptionSDK {
|
export class SubscriptionManager implements ISubscriptionSDK {
|
||||||
private readonly pubsubTopic: PubsubTopic;
|
private readonly receivedMessagesHashStr: string[] = [];
|
||||||
readonly receivedMessagesHashStr: string[] = [];
|
|
||||||
private keepAliveTimer: number | null = null;
|
private keepAliveTimer: number | null = null;
|
||||||
private readonly receivedMessagesHashes: ReceivedMessageHashes;
|
private readonly receivedMessagesHashes: ReceivedMessageHashes;
|
||||||
private peerFailures: Map<string, number> = new Map();
|
private peerFailures: Map<string, number> = new Map();
|
||||||
@ -71,8 +70,8 @@ export class SubscriptionManager implements ISubscriptionSDK {
|
|||||||
SubscriptionCallback<IDecodedMessage>
|
SubscriptionCallback<IDecodedMessage>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
pubsubTopic: PubsubTopic,
|
private readonly pubsubTopic: PubsubTopic,
|
||||||
private protocol: FilterCore,
|
private protocol: FilterCore,
|
||||||
private getPeers: () => Peer[],
|
private getPeers: () => Peer[],
|
||||||
private readonly renewPeer: (peerToDisconnect: PeerId) => Promise<Peer>
|
private readonly renewPeer: (peerToDisconnect: PeerId) => Promise<Peer>
|
||||||
@ -89,7 +88,7 @@ export class SubscriptionManager implements ISubscriptionSDK {
|
|||||||
allPeerIdStr.forEach((peerId) => this.missedMessagesByPeer.set(peerId, 0));
|
allPeerIdStr.forEach((peerId) => this.missedMessagesByPeer.set(peerId, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
get messageHashes(): string[] {
|
public get messageHashes(): string[] {
|
||||||
return [...this.receivedMessagesHashes.all];
|
return [...this.receivedMessagesHashes.all];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,9 +248,9 @@ export class SubscriptionManager implements ISubscriptionSDK {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async processIncomingMessage(
|
public async processIncomingMessage(
|
||||||
message: WakuMessage,
|
message: WakuMessage,
|
||||||
peerIdStr: string
|
peerIdStr: PeerIdStr
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const hashedMessageStr = messageHashStr(
|
const hashedMessageStr = messageHashStr(
|
||||||
this.pubsubTopic,
|
this.pubsubTopic,
|
||||||
@ -419,7 +418,7 @@ class FilterSDK extends BaseProtocolSDK implements IFilterSDK {
|
|||||||
|
|
||||||
private activeSubscriptions = new Map<string, SubscriptionManager>();
|
private activeSubscriptions = new Map<string, SubscriptionManager>();
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
connectionManager: ConnectionManager,
|
connectionManager: ConnectionManager,
|
||||||
libp2p: Libp2p,
|
libp2p: Libp2p,
|
||||||
options?: ProtocolCreateOptions
|
options?: ProtocolCreateOptions
|
||||||
@ -470,7 +469,7 @@ class FilterSDK extends BaseProtocolSDK implements IFilterSDK {
|
|||||||
* @param pubsubTopicShardInfo The pubsub topic to subscribe to.
|
* @param pubsubTopicShardInfo The pubsub topic to subscribe to.
|
||||||
* @returns The subscription object.
|
* @returns The subscription object.
|
||||||
*/
|
*/
|
||||||
async createSubscription(
|
public async createSubscription(
|
||||||
pubsubTopicShardInfo: ShardingParams | PubsubTopic,
|
pubsubTopicShardInfo: ShardingParams | PubsubTopic,
|
||||||
options?: ProtocolUseOptions
|
options?: ProtocolUseOptions
|
||||||
): Promise<CreateSubscriptionResult> {
|
): Promise<CreateSubscriptionResult> {
|
||||||
@ -533,7 +532,7 @@ class FilterSDK extends BaseProtocolSDK implements IFilterSDK {
|
|||||||
* This method should not be used directly.
|
* This method should not be used directly.
|
||||||
* Instead, use `createSubscription` to create a new subscription.
|
* Instead, use `createSubscription` to create a new subscription.
|
||||||
*/
|
*/
|
||||||
async subscribe<T extends IDecodedMessage>(
|
public async subscribe<T extends IDecodedMessage>(
|
||||||
decoders: IDecoder<T> | IDecoder<T>[],
|
decoders: IDecoder<T> | IDecoder<T>[],
|
||||||
callback: Callback<T>,
|
callback: Callback<T>,
|
||||||
options: SubscribeOptions = DEFAULT_SUBSCRIBE_OPTIONS
|
options: SubscribeOptions = DEFAULT_SUBSCRIBE_OPTIONS
|
||||||
|
@ -20,7 +20,7 @@ const log = new Logger("sdk:light-push");
|
|||||||
class LightPushSDK extends BaseProtocolSDK implements ILightPushSDK {
|
class LightPushSDK extends BaseProtocolSDK implements ILightPushSDK {
|
||||||
public readonly protocol: LightPushCore;
|
public readonly protocol: LightPushCore;
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
connectionManager: ConnectionManager,
|
connectionManager: ConnectionManager,
|
||||||
libp2p: Libp2p,
|
libp2p: Libp2p,
|
||||||
options?: ProtocolCreateOptions
|
options?: ProtocolCreateOptions
|
||||||
@ -32,7 +32,7 @@ class LightPushSDK extends BaseProtocolSDK implements ILightPushSDK {
|
|||||||
this.protocol = this.core as LightPushCore;
|
this.protocol = this.core as LightPushCore;
|
||||||
}
|
}
|
||||||
|
|
||||||
async send(
|
public async send(
|
||||||
encoder: IEncoder,
|
encoder: IEncoder,
|
||||||
message: IMessage,
|
message: IMessage,
|
||||||
_options?: ProtocolUseOptions
|
_options?: ProtocolUseOptions
|
||||||
|
@ -25,7 +25,7 @@ const log = new Logger("waku:store:protocol");
|
|||||||
export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
|
export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
|
||||||
public readonly protocol: StoreCore;
|
public readonly protocol: StoreCore;
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
connectionManager: ConnectionManager,
|
connectionManager: ConnectionManager,
|
||||||
libp2p: Libp2p,
|
libp2p: Libp2p,
|
||||||
options?: ProtocolCreateOptions
|
options?: ProtocolCreateOptions
|
||||||
@ -58,7 +58,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
|
|||||||
* @throws If no decoders are provided.
|
* @throws If no decoders are provided.
|
||||||
* @throws If no decoders are found for the provided pubsub topic.
|
* @throws If no decoders are found for the provided pubsub topic.
|
||||||
*/
|
*/
|
||||||
async *queryGenerator<T extends IDecodedMessage>(
|
public async *queryGenerator<T extends IDecodedMessage>(
|
||||||
decoders: IDecoder<T>[],
|
decoders: IDecoder<T>[],
|
||||||
options?: waku_store.QueryOptions
|
options?: waku_store.QueryOptions
|
||||||
): AsyncGenerator<Promise<T | undefined>[]> {
|
): AsyncGenerator<Promise<T | undefined>[]> {
|
||||||
@ -108,7 +108,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
|
|||||||
* or if an error is encountered when processing the reply,
|
* or if an error is encountered when processing the reply,
|
||||||
* or if two decoders with the same content topic are passed.
|
* or if two decoders with the same content topic are passed.
|
||||||
*/
|
*/
|
||||||
async queryWithOrderedCallback<T extends IDecodedMessage>(
|
public async queryWithOrderedCallback<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,
|
||||||
options?: waku_store.QueryOptions
|
options?: waku_store.QueryOptions
|
||||||
@ -135,7 +135,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
|
|||||||
* or if an error is encountered when processing the reply,
|
* or if an error is encountered when processing the reply,
|
||||||
* or if two decoders with the same content topic are passed.
|
* or if two decoders with the same content topic are passed.
|
||||||
*/
|
*/
|
||||||
async queryWithPromiseCallback<T extends IDecodedMessage>(
|
public async queryWithPromiseCallback<T extends IDecodedMessage>(
|
||||||
decoders: IDecoder<T>[],
|
decoders: IDecoder<T>[],
|
||||||
callback: (
|
callback: (
|
||||||
message: Promise<T | undefined>
|
message: Promise<T | undefined>
|
||||||
@ -154,7 +154,7 @@ export class StoreSDK extends BaseProtocolSDK implements IStoreSDK {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createCursor(message: IDecodedMessage): Cursor {
|
public createCursor(message: IDecodedMessage): Cursor {
|
||||||
if (
|
if (
|
||||||
!message ||
|
!message ||
|
||||||
!message.timestamp ||
|
!message.timestamp ||
|
||||||
|
@ -73,7 +73,7 @@ export class WakuNode implements Waku {
|
|||||||
public connectionManager: ConnectionManager;
|
public connectionManager: ConnectionManager;
|
||||||
public readonly pubsubTopics: PubsubTopic[];
|
public readonly pubsubTopics: PubsubTopic[];
|
||||||
|
|
||||||
constructor(
|
public constructor(
|
||||||
options: WakuOptions,
|
options: WakuOptions,
|
||||||
libp2p: Libp2p,
|
libp2p: Libp2p,
|
||||||
protocolsEnabled: ProtocolsEnabled
|
protocolsEnabled: ProtocolsEnabled
|
||||||
@ -143,7 +143,7 @@ export class WakuNode implements Waku {
|
|||||||
* @param peer The peer to dial
|
* @param peer The peer to dial
|
||||||
* @param protocols Waku protocols we expect from the peer; Defaults to mounted protocols
|
* @param protocols Waku protocols we expect from the peer; Defaults to mounted protocols
|
||||||
*/
|
*/
|
||||||
async dial(
|
public async dial(
|
||||||
peer: PeerId | MultiaddrInput,
|
peer: PeerId | MultiaddrInput,
|
||||||
protocols?: Protocols[]
|
protocols?: Protocols[]
|
||||||
): Promise<Stream> {
|
): Promise<Stream> {
|
||||||
@ -202,16 +202,16 @@ export class WakuNode implements Waku {
|
|||||||
return this.libp2p.dialProtocol(peerId, codecs);
|
return this.libp2p.dialProtocol(peerId, codecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(): Promise<void> {
|
public async start(): Promise<void> {
|
||||||
await this.libp2p.start();
|
await this.libp2p.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop(): Promise<void> {
|
public async stop(): Promise<void> {
|
||||||
this.connectionManager.stop();
|
this.connectionManager.stop();
|
||||||
await this.libp2p.stop();
|
await this.libp2p.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
async subscribeToContentTopic(
|
public async subscribeToContentTopic(
|
||||||
contentTopic: string,
|
contentTopic: string,
|
||||||
peer: Multiaddr,
|
peer: Multiaddr,
|
||||||
callback: Callback<DecodedMessage>
|
callback: Callback<DecodedMessage>
|
||||||
@ -224,11 +224,11 @@ export class WakuNode implements Waku {
|
|||||||
).subscription;
|
).subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
isStarted(): boolean {
|
public isStarted(): boolean {
|
||||||
return this.libp2p.status == "started";
|
return this.libp2p.status == "started";
|
||||||
}
|
}
|
||||||
|
|
||||||
isConnected(): boolean {
|
public isConnected(): boolean {
|
||||||
return this.connectionManager.isConnected();
|
return this.connectionManager.isConnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ export class WakuNode implements Waku {
|
|||||||
*
|
*
|
||||||
* @throws if libp2p is not listening on localhost.
|
* @throws if libp2p is not listening on localhost.
|
||||||
*/
|
*/
|
||||||
getLocalMultiaddrWithID(): string {
|
public getLocalMultiaddrWithID(): string {
|
||||||
const localMultiaddr = this.libp2p
|
const localMultiaddr = this.libp2p
|
||||||
.getMultiaddrs()
|
.getMultiaddrs()
|
||||||
.find((addr) => addr.toString().match(/127\.0\.0\.1/));
|
.find((addr) => addr.toString().match(/127\.0\.0\.1/));
|
||||||
|
@ -79,14 +79,14 @@ export default class Dockerode {
|
|||||||
return newIp;
|
return newIp;
|
||||||
}
|
}
|
||||||
|
|
||||||
get container(): Docker.Container | undefined {
|
public get container(): Docker.Container | undefined {
|
||||||
if (!this.containerId) {
|
if (!this.containerId) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
return this.docker.getContainer(this.containerId);
|
return this.docker.getContainer(this.containerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
async startContainer(
|
public async startContainer(
|
||||||
ports: Ports,
|
ports: Ports,
|
||||||
args: Args,
|
args: Args,
|
||||||
logPath: string,
|
logPath: string,
|
||||||
@ -168,7 +168,7 @@ export default class Dockerode {
|
|||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop(): Promise<void> {
|
public async stop(): Promise<void> {
|
||||||
if (!this.container) {
|
if (!this.container) {
|
||||||
log.error("ContainerId not set");
|
log.error("ContainerId not set");
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,7 +24,7 @@ const log = new Logger("test:message-collector");
|
|||||||
* that allows for the creation & handling of multiple ServiceNodes
|
* that allows for the creation & handling of multiple ServiceNodes
|
||||||
*/
|
*/
|
||||||
export class ServiceNodesFleet {
|
export class ServiceNodesFleet {
|
||||||
static async createAndRun(
|
public static async createAndRun(
|
||||||
mochaContext: Mocha.Context,
|
mochaContext: Mocha.Context,
|
||||||
pubsubTopics: PubsubTopic[],
|
pubsubTopics: PubsubTopic[],
|
||||||
nodesToCreate: number = 3,
|
nodesToCreate: number = 3,
|
||||||
@ -61,7 +61,7 @@ export class ServiceNodesFleet {
|
|||||||
* Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used
|
* Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used
|
||||||
* by the nwaku JSON-RPC API.
|
* by the nwaku JSON-RPC API.
|
||||||
*/
|
*/
|
||||||
static toMessageRpcQuery(message: {
|
public static toMessageRpcQuery(message: {
|
||||||
payload: Uint8Array;
|
payload: Uint8Array;
|
||||||
contentTopic: string;
|
contentTopic: string;
|
||||||
timestamp?: Date;
|
timestamp?: Date;
|
||||||
@ -86,7 +86,7 @@ export class ServiceNodesFleet {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
get type(): "go-waku" | "nwaku" {
|
public get type(): "go-waku" | "nwaku" {
|
||||||
const nodeType = new Set(
|
const nodeType = new Set(
|
||||||
this.nodes.map((node) => {
|
this.nodes.map((node) => {
|
||||||
return node.type;
|
return node.type;
|
||||||
@ -98,12 +98,12 @@ export class ServiceNodesFleet {
|
|||||||
return nodeType.values().next().value;
|
return nodeType.values().next().value;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(): Promise<void> {
|
public async start(): Promise<void> {
|
||||||
const startPromises = this.nodes.map((node) => node.start());
|
const startPromises = this.nodes.map((node) => node.start());
|
||||||
await Promise.all(startPromises);
|
await Promise.all(startPromises);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendRelayMessage(
|
public async sendRelayMessage(
|
||||||
message: MessageRpcQuery,
|
message: MessageRpcQuery,
|
||||||
pubsubTopic: string = DefaultPubsubTopic
|
pubsubTopic: string = DefaultPubsubTopic
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
@ -114,7 +114,7 @@ export class ServiceNodesFleet {
|
|||||||
return relayMessages.every((message) => message);
|
return relayMessages.every((message) => message);
|
||||||
}
|
}
|
||||||
|
|
||||||
async confirmMessageLength(numMessages: number): Promise<void> {
|
public async confirmMessageLength(numMessages: number): Promise<void> {
|
||||||
if (this.strictChecking) {
|
if (this.strictChecking) {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
this.nodes.map(async (node) =>
|
this.nodes.map(async (node) =>
|
||||||
@ -138,9 +138,9 @@ export class ServiceNodesFleet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MultipleNodesMessageCollector {
|
class MultipleNodesMessageCollector {
|
||||||
callback: (msg: DecodedMessage) => void = () => {};
|
public callback: (msg: DecodedMessage) => void = () => {};
|
||||||
messageList: Array<DecodedMessage> = [];
|
protected messageList: Array<DecodedMessage> = [];
|
||||||
constructor(
|
public constructor(
|
||||||
private messageCollectors: MessageCollector[],
|
private messageCollectors: MessageCollector[],
|
||||||
private relayNodes?: ServiceNode[],
|
private relayNodes?: ServiceNode[],
|
||||||
private strictChecking: boolean = false
|
private strictChecking: boolean = false
|
||||||
@ -151,7 +151,7 @@ class MultipleNodesMessageCollector {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get count(): number {
|
public get count(): number {
|
||||||
return this.messageList.length;
|
return this.messageList.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ class MultipleNodesMessageCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getMessage(index: number): MessageRpcResponse | DecodedMessage {
|
public getMessage(index: number): MessageRpcResponse | DecodedMessage {
|
||||||
return this.messageList[index];
|
return this.messageList[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ class MultipleNodesMessageCollector {
|
|||||||
* Verifies a received message against expected values on all nodes.
|
* Verifies a received message against expected values on all nodes.
|
||||||
* Returns true if any node's collector verifies the message successfully.
|
* Returns true if any node's collector verifies the message successfully.
|
||||||
*/
|
*/
|
||||||
verifyReceivedMessage(
|
public verifyReceivedMessage(
|
||||||
index: number,
|
index: number,
|
||||||
options: {
|
options: {
|
||||||
expectedMessageText: string | Uint8Array | undefined;
|
expectedMessageText: string | Uint8Array | undefined;
|
||||||
@ -212,7 +212,7 @@ class MultipleNodesMessageCollector {
|
|||||||
/**
|
/**
|
||||||
* Waits for a total number of messages across all nodes.
|
* Waits for a total number of messages across all nodes.
|
||||||
*/
|
*/
|
||||||
async waitForMessages(
|
public async waitForMessages(
|
||||||
numMessages: number,
|
numMessages: number,
|
||||||
options?: {
|
options?: {
|
||||||
pubsubTopic?: string;
|
pubsubTopic?: string;
|
||||||
|
@ -19,10 +19,10 @@ const log = new Logger("test:message-collector");
|
|||||||
* and offers a way to wait for incoming messages.
|
* and offers a way to wait for incoming messages.
|
||||||
*/
|
*/
|
||||||
export class MessageCollector {
|
export class MessageCollector {
|
||||||
list: Array<MessageRpcResponse | DecodedMessage> = [];
|
public list: Array<MessageRpcResponse | DecodedMessage> = [];
|
||||||
callback: (msg: DecodedMessage) => void = () => {};
|
public callback: (msg: DecodedMessage) => void = () => {};
|
||||||
|
|
||||||
constructor(private nwaku?: ServiceNode) {
|
public constructor(private nwaku?: ServiceNode) {
|
||||||
if (!this.nwaku) {
|
if (!this.nwaku) {
|
||||||
this.callback = (msg: DecodedMessage): void => {
|
this.callback = (msg: DecodedMessage): void => {
|
||||||
log.info("Got a message");
|
log.info("Got a message");
|
||||||
@ -31,15 +31,15 @@ export class MessageCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get count(): number {
|
public get count(): number {
|
||||||
return this.list.length;
|
return this.list.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMessage(index: number): MessageRpcResponse | DecodedMessage {
|
public getMessage(index: number): MessageRpcResponse | DecodedMessage {
|
||||||
return this.list[index];
|
return this.list[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMessage(topic: string, text: string): boolean {
|
public hasMessage(topic: string, text: string): boolean {
|
||||||
return this.list.some((message) => {
|
return this.list.some((message) => {
|
||||||
if (message.contentTopic !== topic) {
|
if (message.contentTopic !== topic) {
|
||||||
return false;
|
return false;
|
||||||
@ -55,7 +55,7 @@ export class MessageCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Type guard to determine if a message is of type MessageRpcResponse
|
// Type guard to determine if a message is of type MessageRpcResponse
|
||||||
isMessageRpcResponse(
|
public isMessageRpcResponse(
|
||||||
message: MessageRpcResponse | DecodedMessage
|
message: MessageRpcResponse | DecodedMessage
|
||||||
): message is MessageRpcResponse {
|
): message is MessageRpcResponse {
|
||||||
return (
|
return (
|
||||||
@ -64,7 +64,7 @@ export class MessageCollector {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForMessages(
|
public async waitForMessages(
|
||||||
numMessages: number,
|
numMessages: number,
|
||||||
options?: {
|
options?: {
|
||||||
pubsubTopic?: string;
|
pubsubTopic?: string;
|
||||||
@ -106,7 +106,7 @@ export class MessageCollector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForMessagesAutosharding(
|
public async waitForMessagesAutosharding(
|
||||||
numMessages: number,
|
numMessages: number,
|
||||||
options?: {
|
options?: {
|
||||||
contentTopic: string;
|
contentTopic: string;
|
||||||
@ -150,7 +150,7 @@ export class MessageCollector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verifies a received message against expected values.
|
// Verifies a received message against expected values.
|
||||||
verifyReceivedMessage(
|
public verifyReceivedMessage(
|
||||||
index: number,
|
index: number,
|
||||||
options: {
|
options: {
|
||||||
expectedMessageText: string | Uint8Array | undefined;
|
expectedMessageText: string | Uint8Array | undefined;
|
||||||
|
@ -54,7 +54,7 @@ export class ServiceNode {
|
|||||||
* Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used
|
* Convert a [[WakuMessage]] to a [[WakuRelayMessage]]. The latter is used
|
||||||
* by the nwaku JSON-RPC API.
|
* by the nwaku JSON-RPC API.
|
||||||
*/
|
*/
|
||||||
static toMessageRpcQuery(message: {
|
public static toMessageRpcQuery(message: {
|
||||||
payload: Uint8Array;
|
payload: Uint8Array;
|
||||||
contentTopic: string;
|
contentTopic: string;
|
||||||
timestamp?: Date;
|
timestamp?: Date;
|
||||||
@ -75,23 +75,23 @@ export class ServiceNode {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(logName: string) {
|
public constructor(logName: string) {
|
||||||
this.logPath = `${LOG_DIR}/wakunode_${logName}.log`;
|
this.logPath = `${LOG_DIR}/wakunode_${logName}.log`;
|
||||||
}
|
}
|
||||||
|
|
||||||
get type(): "go-waku" | "nwaku" {
|
public get type(): "go-waku" | "nwaku" {
|
||||||
return isGoWaku ? "go-waku" : "nwaku";
|
return isGoWaku ? "go-waku" : "nwaku";
|
||||||
}
|
}
|
||||||
|
|
||||||
get nodeType(): "go-waku" | "nwaku" {
|
public get nodeType(): "go-waku" | "nwaku" {
|
||||||
return isGoWaku ? "go-waku" : "nwaku";
|
return isGoWaku ? "go-waku" : "nwaku";
|
||||||
}
|
}
|
||||||
|
|
||||||
get containerName(): string | undefined {
|
public get containerName(): string | undefined {
|
||||||
return this.docker?.container?.id;
|
return this.docker?.container?.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(
|
public async start(
|
||||||
args: Args = {},
|
args: Args = {},
|
||||||
options: {
|
options: {
|
||||||
retries?: number;
|
retries?: number;
|
||||||
@ -200,7 +200,7 @@ export class ServiceNode {
|
|||||||
delete this.docker;
|
delete this.docker;
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForLog(msg: string, timeout: number): Promise<void> {
|
public async waitForLog(msg: string, timeout: number): Promise<void> {
|
||||||
return waitForLine(this.logPath, msg, timeout);
|
return waitForLine(this.logPath, msg, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +208,7 @@ export class ServiceNode {
|
|||||||
* Calls nwaku REST API "/admin/v1/peers" to check for known peers
|
* Calls nwaku REST API "/admin/v1/peers" to check for known peers
|
||||||
* @throws
|
* @throws
|
||||||
*/
|
*/
|
||||||
async peers(): Promise<string[]> {
|
public async peers(): Promise<string[]> {
|
||||||
this.checkProcess();
|
this.checkProcess();
|
||||||
|
|
||||||
return this.restCall<string[]>(
|
return this.restCall<string[]>(
|
||||||
@ -222,7 +222,7 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async info(): Promise<RpcInfoResponse> {
|
public async info(): Promise<RpcInfoResponse> {
|
||||||
this.checkProcess();
|
this.checkProcess();
|
||||||
|
|
||||||
return this.restCall<RpcInfoResponse>(
|
return this.restCall<RpcInfoResponse>(
|
||||||
@ -233,7 +233,7 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async healthy(): Promise<boolean> {
|
public async healthy(): Promise<boolean> {
|
||||||
this.checkProcess();
|
this.checkProcess();
|
||||||
|
|
||||||
return this.restCall<boolean>(
|
return this.restCall<boolean>(
|
||||||
@ -244,7 +244,7 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureSubscriptions(
|
public async ensureSubscriptions(
|
||||||
pubsubTopics: string[] = [DefaultPubsubTopic]
|
pubsubTopics: string[] = [DefaultPubsubTopic]
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
return this.restCall<boolean>(
|
return this.restCall<boolean>(
|
||||||
@ -255,7 +255,7 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async messages(pubsubTopic?: string): Promise<MessageRpcResponse[]> {
|
public async messages(pubsubTopic?: string): Promise<MessageRpcResponse[]> {
|
||||||
return this.restCall<MessageRpcResponse[]>(
|
return this.restCall<MessageRpcResponse[]>(
|
||||||
`/relay/v1/messages/${encodeURIComponent(pubsubTopic || this?.args?.pubsubTopic?.[0] || DefaultPubsubTopic)}`,
|
`/relay/v1/messages/${encodeURIComponent(pubsubTopic || this?.args?.pubsubTopic?.[0] || DefaultPubsubTopic)}`,
|
||||||
"GET",
|
"GET",
|
||||||
@ -267,7 +267,7 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureSubscriptionsAutosharding(
|
public async ensureSubscriptionsAutosharding(
|
||||||
contentTopics: string[]
|
contentTopics: string[]
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
this.checkProcess();
|
this.checkProcess();
|
||||||
@ -280,7 +280,7 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendMessage(
|
public async sendMessage(
|
||||||
message: MessageRpcQuery,
|
message: MessageRpcQuery,
|
||||||
pubsubTopic?: string
|
pubsubTopic?: string
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
@ -298,7 +298,9 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendMessageAutosharding(message: MessageRpcQuery): Promise<boolean> {
|
public async sendMessageAutosharding(
|
||||||
|
message: MessageRpcQuery
|
||||||
|
): Promise<boolean> {
|
||||||
this.checkProcess();
|
this.checkProcess();
|
||||||
|
|
||||||
if (typeof message.timestamp === "undefined") {
|
if (typeof message.timestamp === "undefined") {
|
||||||
@ -313,7 +315,7 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async messagesAutosharding(
|
public async messagesAutosharding(
|
||||||
contentTopic: string
|
contentTopic: string
|
||||||
): Promise<MessageRpcResponse[]> {
|
): Promise<MessageRpcResponse[]> {
|
||||||
this.checkProcess();
|
this.checkProcess();
|
||||||
@ -329,13 +331,13 @@ export class ServiceNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getPeerId(): Promise<PeerId> {
|
public async getPeerId(): Promise<PeerId> {
|
||||||
if (this.peerId) return this.peerId;
|
if (this.peerId) return this.peerId;
|
||||||
this.peerId = await this._getPeerId();
|
this.peerId = await this._getPeerId();
|
||||||
return this.peerId;
|
return this.peerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMultiaddrWithId(): Promise<Multiaddr> {
|
public async getMultiaddrWithId(): Promise<Multiaddr> {
|
||||||
if (this.multiaddrWithId) return this.multiaddrWithId;
|
if (this.multiaddrWithId) return this.multiaddrWithId;
|
||||||
|
|
||||||
const peerId = await this.getPeerId();
|
const peerId = await this.getPeerId();
|
||||||
@ -362,15 +364,15 @@ export class ServiceNode {
|
|||||||
return this.peerId;
|
return this.peerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get httpUrl(): string {
|
public get httpUrl(): string {
|
||||||
return `http://127.0.0.1:${this.restPort}`;
|
return `http://127.0.0.1:${this.restPort}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
get pubsubTopics(): string[] {
|
public get pubsubTopics(): string[] {
|
||||||
return this.args?.pubsubTopic ?? [];
|
return this.args?.pubsubTopic ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
async restCall<T>(
|
public async restCall<T>(
|
||||||
endpoint: string,
|
endpoint: string,
|
||||||
method: "GET" | "POST",
|
method: "GET" | "POST",
|
||||||
body: any = null,
|
body: any = null,
|
||||||
|
@ -7,29 +7,29 @@ export class Logger {
|
|||||||
private _warn: Debugger;
|
private _warn: Debugger;
|
||||||
private _error: Debugger;
|
private _error: Debugger;
|
||||||
|
|
||||||
static createDebugNamespace(level: string, prefix?: string): string {
|
private static createDebugNamespace(level: string, prefix?: string): string {
|
||||||
return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
|
return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(prefix?: string) {
|
public constructor(prefix?: string) {
|
||||||
this._info = debug(Logger.createDebugNamespace("info", prefix));
|
this._info = debug(Logger.createDebugNamespace("info", prefix));
|
||||||
this._warn = debug(Logger.createDebugNamespace("warn", prefix));
|
this._warn = debug(Logger.createDebugNamespace("warn", prefix));
|
||||||
this._error = debug(Logger.createDebugNamespace("error", prefix));
|
this._error = debug(Logger.createDebugNamespace("error", prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
get info(): Debugger {
|
public get info(): Debugger {
|
||||||
return this._info;
|
return this._info;
|
||||||
}
|
}
|
||||||
|
|
||||||
get warn(): Debugger {
|
public get warn(): Debugger {
|
||||||
return this._warn;
|
return this._warn;
|
||||||
}
|
}
|
||||||
|
|
||||||
get error(): Debugger {
|
public get error(): Debugger {
|
||||||
return this._error;
|
return this._error;
|
||||||
}
|
}
|
||||||
|
|
||||||
log(level: "info" | "warn" | "error", ...args: unknown[]): void {
|
public log(level: "info" | "warn" | "error", ...args: unknown[]): void {
|
||||||
const logger = this[level] as (...args: unknown[]) => void;
|
const logger = this[level] as (...args: unknown[]) => void;
|
||||||
logger(...args);
|
logger(...args);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user