@waku/core 0.0.39-9684e7b.0 → 0.0.39-c0ee9ec.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.js +497 -256
- package/bundle/lib/message/version_0.js +1 -1
- package/bundle/{version_0-DV1Db0r-.js → version_0-DQUncDnb.js} +3 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/connection_manager/connection_limiter.js +3 -3
- package/dist/lib/connection_manager/connection_limiter.js.map +1 -1
- package/dist/lib/connection_manager/network_monitor.js +1 -2
- package/dist/lib/connection_manager/network_monitor.js.map +1 -1
- package/dist/lib/filter/filter.d.ts +6 -6
- package/dist/lib/filter/filter.js +14 -14
- package/dist/lib/filter/filter.js.map +1 -1
- package/dist/lib/light_push/index.d.ts +1 -1
- package/dist/lib/light_push/index.js +1 -1
- package/dist/lib/light_push/index.js.map +1 -1
- package/dist/lib/light_push/light_push.d.ts +8 -6
- package/dist/lib/light_push/light_push.js +40 -79
- package/dist/lib/light_push/light_push.js.map +1 -1
- package/dist/lib/light_push/protocol_handler.d.ts +27 -0
- package/dist/lib/light_push/protocol_handler.js +145 -0
- package/dist/lib/light_push/protocol_handler.js.map +1 -0
- package/dist/lib/light_push/push_rpc.d.ts +3 -3
- package/dist/lib/light_push/push_rpc.js +3 -3
- package/dist/lib/light_push/push_rpc.js.map +1 -1
- package/dist/lib/light_push/push_rpc_v3.d.ts +73 -0
- package/dist/lib/light_push/push_rpc_v3.js +136 -0
- package/dist/lib/light_push/push_rpc_v3.js.map +1 -0
- package/dist/lib/metadata/metadata.js +1 -1
- package/dist/lib/metadata/metadata.js.map +1 -1
- package/dist/lib/store/store.d.ts +1 -1
- package/dist/lib/store/store.js +1 -1
- package/dist/lib/store/store.js.map +1 -1
- package/dist/lib/stream_manager/stream_manager.d.ts +1 -1
- package/dist/lib/stream_manager/stream_manager.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +5 -1
- package/src/lib/connection_manager/connection_limiter.ts +3 -7
- package/src/lib/connection_manager/network_monitor.ts +2 -2
- package/src/lib/filter/filter.ts +19 -19
- package/src/lib/light_push/index.ts +5 -1
- package/src/lib/light_push/light_push.ts +59 -106
- package/src/lib/light_push/protocol_handler.ts +192 -0
- package/src/lib/light_push/push_rpc.ts +5 -5
- package/src/lib/light_push/push_rpc_v3.ts +162 -0
- package/src/lib/metadata/metadata.ts +1 -1
- package/src/lib/store/store.ts +1 -1
- package/src/lib/stream_manager/stream_manager.ts +1 -1
package/bundle/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { e as equals$2, c as coerce, b as base32, a as base58btc, d as base36, s as sha256$1, f as concat$1, u as utf8ToBytes, v as version_0, g as allocUnsafe, h as alloc, i as encodingLength$1, j as encode$3, k as decode$4, L as Logger, F as FilterSubscribeRequest, l as FilterSubscribeResponse$1, M as MessagePush, P as PushRpc$1, m as
|
|
2
|
-
export {
|
|
1
|
+
import { e as equals$2, c as coerce, b as base32, a as base58btc, d as base36, s as sha256$1, f as concat$1, u as utf8ToBytes, v as version_0, g as allocUnsafe, h as alloc, i as encodingLength$1, j as encode$3, k as decode$4, L as Logger, F as FilterSubscribeRequest, l as FilterSubscribeResponse$1, M as MessagePush, P as PushRpc$1, m as LightPushRequestV3, n as LightPushResponseV3, S as StoreQueryRequest$1, o as StoreQueryResponse$1, p as createEncoder, t as toString, q as fromString, r as hexToBytes, w as isBytes, x as abytes, y as bytesToHex, z as concatBytes, A as anumber, B as randomBytes, C as sha512, D as enumeration, E as message, G as encodeMessage, H as decodeMessage, I as Hash, J as ahash, K as toBytes, N as clean, O as aexists, Q as sha256$2, R as bases, T as base64url, U as encodeUint8Array, V as bytesToUtf8, W as WakuMetadataRequest, X as WakuMetadataResponse } from './version_0-DQUncDnb.js';
|
|
2
|
+
export { Y as createDecoder, Z as messageHash, _ as messageHashStr } from './version_0-DQUncDnb.js';
|
|
3
3
|
|
|
4
4
|
/* eslint-disable */
|
|
5
5
|
var encode_1 = encode$2;
|
|
@@ -581,86 +581,6 @@ function isAutoSharding(config) {
|
|
|
581
581
|
return "clusterId" in config && "numShardsInCluster" in config;
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
-
const formatPubsubTopic = (clusterId, shard) => {
|
|
585
|
-
return `/waku/2/rs/${clusterId}/${shard}`;
|
|
586
|
-
};
|
|
587
|
-
/**
|
|
588
|
-
* @deprecated will be removed
|
|
589
|
-
*/
|
|
590
|
-
const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
|
|
591
|
-
const parts = pubsubTopics.split("/");
|
|
592
|
-
if (parts.length != 6 ||
|
|
593
|
-
parts[1] !== "waku" ||
|
|
594
|
-
parts[2] !== "2" ||
|
|
595
|
-
parts[3] !== "rs")
|
|
596
|
-
throw new Error("Invalid pubsub topic");
|
|
597
|
-
const clusterId = parseInt(parts[4]);
|
|
598
|
-
const shard = parseInt(parts[5]);
|
|
599
|
-
if (isNaN(clusterId) || isNaN(shard))
|
|
600
|
-
throw new Error("Invalid clusterId or shard");
|
|
601
|
-
return {
|
|
602
|
-
clusterId,
|
|
603
|
-
shard
|
|
604
|
-
};
|
|
605
|
-
};
|
|
606
|
-
/**
|
|
607
|
-
* Given a string, will throw an error if it is not formatted as a valid content topic for autosharding based on https://rfc.vac.dev/spec/51/
|
|
608
|
-
* @param contentTopic String to validate
|
|
609
|
-
* @returns Object with each content topic field as an attribute
|
|
610
|
-
*/
|
|
611
|
-
function ensureValidContentTopic(contentTopic) {
|
|
612
|
-
const parts = contentTopic.split("/");
|
|
613
|
-
if (parts.length < 5 || parts.length > 6) {
|
|
614
|
-
throw Error(`Content topic format is invalid: ${contentTopic}`);
|
|
615
|
-
}
|
|
616
|
-
// Validate generation field if present
|
|
617
|
-
let generation = 0;
|
|
618
|
-
if (parts.length == 6) {
|
|
619
|
-
generation = parseInt(parts[1]);
|
|
620
|
-
if (isNaN(generation)) {
|
|
621
|
-
throw new Error(`Invalid generation field in content topic: ${contentTopic}`);
|
|
622
|
-
}
|
|
623
|
-
if (generation > 0) {
|
|
624
|
-
throw new Error(`Generation greater than 0 is not supported: ${contentTopic}`);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
// Validate remaining fields
|
|
628
|
-
const fields = parts.splice(-4);
|
|
629
|
-
// Validate application field
|
|
630
|
-
if (fields[0].length == 0) {
|
|
631
|
-
throw new Error(`Application field cannot be empty: ${contentTopic}`);
|
|
632
|
-
}
|
|
633
|
-
// Validate version field
|
|
634
|
-
if (fields[1].length == 0) {
|
|
635
|
-
throw new Error(`Version field cannot be empty: ${contentTopic}`);
|
|
636
|
-
}
|
|
637
|
-
// Validate topic name field
|
|
638
|
-
if (fields[2].length == 0) {
|
|
639
|
-
throw new Error(`Topic name field cannot be empty: ${contentTopic}`);
|
|
640
|
-
}
|
|
641
|
-
// Validate encoding field
|
|
642
|
-
if (fields[3].length == 0) {
|
|
643
|
-
throw new Error(`Encoding field cannot be empty: ${contentTopic}`);
|
|
644
|
-
}
|
|
645
|
-
return {
|
|
646
|
-
generation,
|
|
647
|
-
application: fields[0],
|
|
648
|
-
version: fields[1],
|
|
649
|
-
topicName: fields[2],
|
|
650
|
-
encoding: fields[3]
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Given a string, determines which autoshard index to use for its pubsub topic.
|
|
655
|
-
* Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
|
|
656
|
-
*/
|
|
657
|
-
function contentTopicToShardIndex(contentTopic, numShardsInCluster) {
|
|
658
|
-
const { application, version } = ensureValidContentTopic(contentTopic);
|
|
659
|
-
const digest = sha256$1(concat$1([utf8ToBytes(application), utf8ToBytes(version)]));
|
|
660
|
-
const dataview = new DataView(digest.buffer.slice(-8));
|
|
661
|
-
return Number(dataview.getBigUint64(0, false) % BigInt(numShardsInCluster));
|
|
662
|
-
}
|
|
663
|
-
|
|
664
584
|
class BaseRoutingInfo {
|
|
665
585
|
networkConfig;
|
|
666
586
|
pubsubTopic;
|
|
@@ -771,6 +691,86 @@ function createRoutingInfo(networkConfig, options) {
|
|
|
771
691
|
}
|
|
772
692
|
}
|
|
773
693
|
|
|
694
|
+
const formatPubsubTopic = (clusterId, shard) => {
|
|
695
|
+
return `/waku/2/rs/${clusterId}/${shard}`;
|
|
696
|
+
};
|
|
697
|
+
/**
|
|
698
|
+
* @deprecated will be removed
|
|
699
|
+
*/
|
|
700
|
+
const pubsubTopicToSingleShardInfo = (pubsubTopics) => {
|
|
701
|
+
const parts = pubsubTopics.split("/");
|
|
702
|
+
if (parts.length != 6 ||
|
|
703
|
+
parts[1] !== "waku" ||
|
|
704
|
+
parts[2] !== "2" ||
|
|
705
|
+
parts[3] !== "rs")
|
|
706
|
+
throw new Error("Invalid pubsub topic");
|
|
707
|
+
const clusterId = parseInt(parts[4]);
|
|
708
|
+
const shard = parseInt(parts[5]);
|
|
709
|
+
if (isNaN(clusterId) || isNaN(shard))
|
|
710
|
+
throw new Error("Invalid clusterId or shard");
|
|
711
|
+
return {
|
|
712
|
+
clusterId,
|
|
713
|
+
shard
|
|
714
|
+
};
|
|
715
|
+
};
|
|
716
|
+
/**
|
|
717
|
+
* Given a string, will throw an error if it is not formatted as a valid content topic for autosharding based on https://rfc.vac.dev/spec/51/
|
|
718
|
+
* @param contentTopic String to validate
|
|
719
|
+
* @returns Object with each content topic field as an attribute
|
|
720
|
+
*/
|
|
721
|
+
function ensureValidContentTopic(contentTopic) {
|
|
722
|
+
const parts = contentTopic.split("/");
|
|
723
|
+
if (parts.length < 5 || parts.length > 6) {
|
|
724
|
+
throw Error(`Content topic format is invalid: ${contentTopic}`);
|
|
725
|
+
}
|
|
726
|
+
// Validate generation field if present
|
|
727
|
+
let generation = 0;
|
|
728
|
+
if (parts.length == 6) {
|
|
729
|
+
generation = parseInt(parts[1]);
|
|
730
|
+
if (isNaN(generation)) {
|
|
731
|
+
throw new Error(`Invalid generation field in content topic: ${contentTopic}`);
|
|
732
|
+
}
|
|
733
|
+
if (generation > 0) {
|
|
734
|
+
throw new Error(`Generation greater than 0 is not supported: ${contentTopic}`);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
// Validate remaining fields
|
|
738
|
+
const fields = parts.splice(-4);
|
|
739
|
+
// Validate application field
|
|
740
|
+
if (fields[0].length == 0) {
|
|
741
|
+
throw new Error(`Application field cannot be empty: ${contentTopic}`);
|
|
742
|
+
}
|
|
743
|
+
// Validate version field
|
|
744
|
+
if (fields[1].length == 0) {
|
|
745
|
+
throw new Error(`Version field cannot be empty: ${contentTopic}`);
|
|
746
|
+
}
|
|
747
|
+
// Validate topic name field
|
|
748
|
+
if (fields[2].length == 0) {
|
|
749
|
+
throw new Error(`Topic name field cannot be empty: ${contentTopic}`);
|
|
750
|
+
}
|
|
751
|
+
// Validate encoding field
|
|
752
|
+
if (fields[3].length == 0) {
|
|
753
|
+
throw new Error(`Encoding field cannot be empty: ${contentTopic}`);
|
|
754
|
+
}
|
|
755
|
+
return {
|
|
756
|
+
generation,
|
|
757
|
+
application: fields[0],
|
|
758
|
+
version: fields[1],
|
|
759
|
+
topicName: fields[2],
|
|
760
|
+
encoding: fields[3]
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Given a string, determines which autoshard index to use for its pubsub topic.
|
|
765
|
+
* Based on the algorithm described in the RFC: https://rfc.vac.dev/spec/51//#algorithm
|
|
766
|
+
*/
|
|
767
|
+
function contentTopicToShardIndex(contentTopic, numShardsInCluster) {
|
|
768
|
+
const { application, version } = ensureValidContentTopic(contentTopic);
|
|
769
|
+
const digest = sha256$1(concat$1([utf8ToBytes(application), utf8ToBytes(version)]));
|
|
770
|
+
const dataview = new DataView(digest.buffer.slice(-8));
|
|
771
|
+
return Number(dataview.getBigUint64(0, false) % BigInt(numShardsInCluster));
|
|
772
|
+
}
|
|
773
|
+
|
|
774
774
|
const decodeRelayShard = (bytes) => {
|
|
775
775
|
// explicitly converting to Uint8Array to avoid Buffer
|
|
776
776
|
// https://github.com/libp2p/js-libp2p/issues/2146
|
|
@@ -830,6 +830,32 @@ var index$3 = /*#__PURE__*/Object.freeze({
|
|
|
830
830
|
version_0: version_0
|
|
831
831
|
});
|
|
832
832
|
|
|
833
|
+
var LightPushStatusCode;
|
|
834
|
+
(function (LightPushStatusCode) {
|
|
835
|
+
LightPushStatusCode[LightPushStatusCode["SUCCESS"] = 200] = "SUCCESS";
|
|
836
|
+
LightPushStatusCode[LightPushStatusCode["BAD_REQUEST"] = 400] = "BAD_REQUEST";
|
|
837
|
+
LightPushStatusCode[LightPushStatusCode["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
|
|
838
|
+
LightPushStatusCode[LightPushStatusCode["INVALID_MESSAGE"] = 420] = "INVALID_MESSAGE";
|
|
839
|
+
LightPushStatusCode[LightPushStatusCode["UNSUPPORTED_TOPIC"] = 421] = "UNSUPPORTED_TOPIC";
|
|
840
|
+
LightPushStatusCode[LightPushStatusCode["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
|
|
841
|
+
LightPushStatusCode[LightPushStatusCode["INTERNAL_ERROR"] = 500] = "INTERNAL_ERROR";
|
|
842
|
+
LightPushStatusCode[LightPushStatusCode["UNAVAILABLE"] = 503] = "UNAVAILABLE";
|
|
843
|
+
LightPushStatusCode[LightPushStatusCode["NO_RLN_PROOF"] = 504] = "NO_RLN_PROOF";
|
|
844
|
+
LightPushStatusCode[LightPushStatusCode["NO_PEERS"] = 505] = "NO_PEERS";
|
|
845
|
+
})(LightPushStatusCode || (LightPushStatusCode = {}));
|
|
846
|
+
({
|
|
847
|
+
[LightPushStatusCode.SUCCESS]: "Message sent successfully",
|
|
848
|
+
[LightPushStatusCode.BAD_REQUEST]: "Bad request format",
|
|
849
|
+
[LightPushStatusCode.PAYLOAD_TOO_LARGE]: "Message payload exceeds maximum size",
|
|
850
|
+
[LightPushStatusCode.INVALID_MESSAGE]: "Message validation failed",
|
|
851
|
+
[LightPushStatusCode.UNSUPPORTED_TOPIC]: "Unsupported pubsub topic",
|
|
852
|
+
[LightPushStatusCode.TOO_MANY_REQUESTS]: "Rate limit exceeded",
|
|
853
|
+
[LightPushStatusCode.INTERNAL_ERROR]: "Internal server error",
|
|
854
|
+
[LightPushStatusCode.UNAVAILABLE]: "Service temporarily unavailable",
|
|
855
|
+
[LightPushStatusCode.NO_RLN_PROOF]: "RLN proof generation failed",
|
|
856
|
+
[LightPushStatusCode.NO_PEERS]: "No relay peers available"
|
|
857
|
+
});
|
|
858
|
+
|
|
833
859
|
var Protocols;
|
|
834
860
|
(function (Protocols) {
|
|
835
861
|
Protocols["Relay"] = "relay";
|
|
@@ -837,96 +863,74 @@ var Protocols;
|
|
|
837
863
|
Protocols["LightPush"] = "lightpush";
|
|
838
864
|
Protocols["Filter"] = "filter";
|
|
839
865
|
})(Protocols || (Protocols = {}));
|
|
866
|
+
var LightPushError;
|
|
867
|
+
(function (LightPushError) {
|
|
868
|
+
LightPushError["GENERIC_FAIL"] = "Generic error";
|
|
869
|
+
LightPushError["DECODE_FAILED"] = "Failed to decode";
|
|
870
|
+
LightPushError["NO_PEER_AVAILABLE"] = "No peer available";
|
|
871
|
+
LightPushError["NO_STREAM_AVAILABLE"] = "No stream available";
|
|
872
|
+
LightPushError["NO_RESPONSE"] = "No response received";
|
|
873
|
+
LightPushError["STREAM_ABORTED"] = "Stream aborted";
|
|
874
|
+
LightPushError["ENCODE_FAILED"] = "Failed to encode";
|
|
875
|
+
LightPushError["EMPTY_PAYLOAD"] = "Payload is empty";
|
|
876
|
+
LightPushError["SIZE_TOO_BIG"] = "Size is too big";
|
|
877
|
+
LightPushError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
|
878
|
+
LightPushError["RLN_PROOF_GENERATION"] = "Proof generation failed";
|
|
879
|
+
LightPushError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
|
880
|
+
LightPushError["BAD_REQUEST"] = "Bad request format";
|
|
881
|
+
LightPushError["PAYLOAD_TOO_LARGE"] = "Message payload exceeds maximum size";
|
|
882
|
+
LightPushError["INVALID_MESSAGE"] = "Message validation failed";
|
|
883
|
+
LightPushError["UNSUPPORTED_TOPIC"] = "Unsupported pubsub topic";
|
|
884
|
+
LightPushError["TOO_MANY_REQUESTS"] = "Rate limit exceeded";
|
|
885
|
+
LightPushError["INTERNAL_ERROR"] = "Internal server error";
|
|
886
|
+
LightPushError["UNAVAILABLE"] = "Service temporarily unavailable";
|
|
887
|
+
LightPushError["NO_RLN_PROOF"] = "RLN proof generation failed";
|
|
888
|
+
LightPushError["NO_PEERS"] = "No relay peers available";
|
|
889
|
+
})(LightPushError || (LightPushError = {}));
|
|
890
|
+
var FilterError;
|
|
891
|
+
(function (FilterError) {
|
|
892
|
+
// General errors
|
|
893
|
+
FilterError["GENERIC_FAIL"] = "Generic error";
|
|
894
|
+
FilterError["DECODE_FAILED"] = "Failed to decode";
|
|
895
|
+
FilterError["NO_PEER_AVAILABLE"] = "No peer available";
|
|
896
|
+
FilterError["NO_STREAM_AVAILABLE"] = "No stream available";
|
|
897
|
+
FilterError["NO_RESPONSE"] = "No response received";
|
|
898
|
+
FilterError["STREAM_ABORTED"] = "Stream aborted";
|
|
899
|
+
// Filter specific errors
|
|
900
|
+
FilterError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
|
901
|
+
FilterError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
|
902
|
+
FilterError["SUBSCRIPTION_FAILED"] = "Subscription failed";
|
|
903
|
+
FilterError["UNSUBSCRIBE_FAILED"] = "Unsubscribe failed";
|
|
904
|
+
FilterError["PING_FAILED"] = "Ping failed";
|
|
905
|
+
FilterError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
|
906
|
+
FilterError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
|
907
|
+
FilterError["SUBSCRIPTION_LIMIT_EXCEEDED"] = "Subscription limit exceeded";
|
|
908
|
+
FilterError["INVALID_CONTENT_TOPIC"] = "Invalid content topic";
|
|
909
|
+
FilterError["PUSH_MESSAGE_FAILED"] = "Push message failed";
|
|
910
|
+
FilterError["EMPTY_MESSAGE"] = "Empty message received";
|
|
911
|
+
FilterError["MISSING_PUBSUB_TOPIC"] = "Pubsub topic missing from push message";
|
|
912
|
+
})(FilterError || (FilterError = {}));
|
|
913
|
+
/**
|
|
914
|
+
* @deprecated Use LightPushError or FilterError instead
|
|
915
|
+
*/
|
|
840
916
|
var ProtocolError;
|
|
841
917
|
(function (ProtocolError) {
|
|
842
|
-
//
|
|
843
|
-
// GENERAL ERRORS SECTION
|
|
844
|
-
//
|
|
845
|
-
/**
|
|
846
|
-
* Could not determine the origin of the fault. Best to check connectivity and try again
|
|
847
|
-
* */
|
|
848
918
|
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
|
849
|
-
/**
|
|
850
|
-
* The remote peer rejected the message. Information provided by the remote peer
|
|
851
|
-
* is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
|
|
852
|
-
* or `DECODE_FAILED` can be used.
|
|
853
|
-
*/
|
|
854
919
|
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
|
855
|
-
/**
|
|
856
|
-
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
|
857
|
-
* ensuring that messages are sent via several peer enable mitigation of this error.
|
|
858
|
-
*/
|
|
859
920
|
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
|
860
|
-
/**
|
|
861
|
-
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
|
862
|
-
* Mitigation can be: retrying after a given time period, display connectivity issue
|
|
863
|
-
* to user or listening for `peer:connected:bootstrap` or `peer:connected:peer-exchange`
|
|
864
|
-
* on the connection manager before retrying.
|
|
865
|
-
*/
|
|
866
921
|
ProtocolError["NO_PEER_AVAILABLE"] = "No peer available";
|
|
867
|
-
/**
|
|
868
|
-
* Failure to find a stream to the peer. This may be because the connection with the peer is not still alive.
|
|
869
|
-
* Mitigation can be: retrying after a given time period, or mitigation for `NO_PEER_AVAILABLE` can be used.
|
|
870
|
-
*/
|
|
871
922
|
ProtocolError["NO_STREAM_AVAILABLE"] = "No stream available";
|
|
872
|
-
/**
|
|
873
|
-
* The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE`
|
|
874
|
-
* or `DECODE_FAILED` can be used.
|
|
875
|
-
*/
|
|
876
923
|
ProtocolError["NO_RESPONSE"] = "No response received";
|
|
877
|
-
//
|
|
878
|
-
// SEND ERRORS SECTION
|
|
879
|
-
//
|
|
880
|
-
/**
|
|
881
|
-
* Failure to protobuf encode the message. This is not recoverable and needs
|
|
882
|
-
* further investigation.
|
|
883
|
-
*/
|
|
884
924
|
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
|
885
|
-
/**
|
|
886
|
-
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
|
887
|
-
* payload is set on the outgoing message.
|
|
888
|
-
*/
|
|
889
925
|
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
|
890
|
-
/**
|
|
891
|
-
* The message size is above the maximum message size allowed on the Waku Network.
|
|
892
|
-
* Compressing the message or using an alternative strategy for large messages is recommended.
|
|
893
|
-
*/
|
|
894
926
|
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
|
895
|
-
/**
|
|
896
|
-
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
|
897
|
-
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
|
898
|
-
*/
|
|
899
927
|
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
|
900
|
-
/**
|
|
901
|
-
* Fails when
|
|
902
|
-
*/
|
|
903
928
|
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
|
904
|
-
/**
|
|
905
|
-
* General proof generation error message.
|
|
906
|
-
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
|
907
|
-
*/
|
|
908
929
|
ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
|
|
909
|
-
//
|
|
910
|
-
// RECEIVE ERRORS SECTION
|
|
911
|
-
//
|
|
912
|
-
/**
|
|
913
|
-
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
|
914
|
-
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
|
915
|
-
*/
|
|
916
930
|
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
|
917
|
-
/**
|
|
918
|
-
* The topics passed in the decoders do not match each other, or don't exist at all.
|
|
919
|
-
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
|
920
|
-
*/
|
|
921
931
|
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
|
922
932
|
})(ProtocolError || (ProtocolError = {}));
|
|
923
933
|
|
|
924
|
-
var WakuEventType;
|
|
925
|
-
(function (WakuEventType) {
|
|
926
|
-
WakuEventType["Connection"] = "waku:connection";
|
|
927
|
-
WakuEventType["Health"] = "waku:health";
|
|
928
|
-
})(WakuEventType || (WakuEventType = {}));
|
|
929
|
-
|
|
930
934
|
// Peer tags
|
|
931
935
|
var Tags;
|
|
932
936
|
(function (Tags) {
|
|
@@ -2801,7 +2805,7 @@ class FilterSubscribeResponse {
|
|
|
2801
2805
|
}
|
|
2802
2806
|
}
|
|
2803
2807
|
|
|
2804
|
-
const log$
|
|
2808
|
+
const log$a = new Logger("filter-core");
|
|
2805
2809
|
const FilterCodecs = {
|
|
2806
2810
|
SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
|
|
2807
2811
|
PUSH: "/vac/waku/filter-push/2.0.0-beta1"
|
|
@@ -2809,7 +2813,7 @@ const FilterCodecs = {
|
|
|
2809
2813
|
class FilterCore {
|
|
2810
2814
|
handleIncomingMessage;
|
|
2811
2815
|
streamManager;
|
|
2812
|
-
multicodec = FilterCodecs.SUBSCRIBE;
|
|
2816
|
+
multicodec = [FilterCodecs.SUBSCRIBE];
|
|
2813
2817
|
constructor(handleIncomingMessage, libp2p) {
|
|
2814
2818
|
this.handleIncomingMessage = handleIncomingMessage;
|
|
2815
2819
|
this.streamManager = new StreamManager(FilterCodecs.SUBSCRIBE, libp2p.components);
|
|
@@ -2818,7 +2822,7 @@ class FilterCore {
|
|
|
2818
2822
|
maxInboundStreams: 100
|
|
2819
2823
|
})
|
|
2820
2824
|
.catch((e) => {
|
|
2821
|
-
log$
|
|
2825
|
+
log$a.error("Failed to register ", FilterCodecs.PUSH, e);
|
|
2822
2826
|
});
|
|
2823
2827
|
}
|
|
2824
2828
|
async subscribe(pubsubTopic, peerId, contentTopics) {
|
|
@@ -2827,7 +2831,7 @@ class FilterCore {
|
|
|
2827
2831
|
return {
|
|
2828
2832
|
success: null,
|
|
2829
2833
|
failure: {
|
|
2830
|
-
error:
|
|
2834
|
+
error: FilterError.NO_STREAM_AVAILABLE,
|
|
2831
2835
|
peerId: peerId
|
|
2832
2836
|
}
|
|
2833
2837
|
};
|
|
@@ -2841,21 +2845,21 @@ class FilterCore {
|
|
|
2841
2845
|
}
|
|
2842
2846
|
}
|
|
2843
2847
|
catch (error) {
|
|
2844
|
-
log$
|
|
2848
|
+
log$a.error("Failed to send subscribe request", error);
|
|
2845
2849
|
return {
|
|
2846
2850
|
success: null,
|
|
2847
2851
|
failure: {
|
|
2848
|
-
error:
|
|
2852
|
+
error: FilterError.GENERIC_FAIL,
|
|
2849
2853
|
peerId: peerId
|
|
2850
2854
|
}
|
|
2851
2855
|
};
|
|
2852
2856
|
}
|
|
2853
2857
|
const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
|
|
2854
2858
|
if (statusCode < 200 || statusCode >= 300) {
|
|
2855
|
-
log$
|
|
2859
|
+
log$a.error(`Filter subscribe request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
|
|
2856
2860
|
return {
|
|
2857
2861
|
failure: {
|
|
2858
|
-
error:
|
|
2862
|
+
error: FilterError.REMOTE_PEER_REJECTED,
|
|
2859
2863
|
peerId: peerId
|
|
2860
2864
|
},
|
|
2861
2865
|
success: null
|
|
@@ -2869,11 +2873,11 @@ class FilterCore {
|
|
|
2869
2873
|
async unsubscribe(pubsubTopic, peerId, contentTopics) {
|
|
2870
2874
|
const stream = await this.streamManager.getStream(peerId);
|
|
2871
2875
|
if (!stream) {
|
|
2872
|
-
log$
|
|
2876
|
+
log$a.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
|
|
2873
2877
|
return {
|
|
2874
2878
|
success: null,
|
|
2875
2879
|
failure: {
|
|
2876
|
-
error:
|
|
2880
|
+
error: FilterError.NO_STREAM_AVAILABLE,
|
|
2877
2881
|
peerId: peerId
|
|
2878
2882
|
}
|
|
2879
2883
|
};
|
|
@@ -2883,11 +2887,11 @@ class FilterCore {
|
|
|
2883
2887
|
await pipe([unsubscribeRequest.encode()], encode, stream.sink);
|
|
2884
2888
|
}
|
|
2885
2889
|
catch (error) {
|
|
2886
|
-
log$
|
|
2890
|
+
log$a.error("Failed to send unsubscribe request", error);
|
|
2887
2891
|
return {
|
|
2888
2892
|
success: null,
|
|
2889
2893
|
failure: {
|
|
2890
|
-
error:
|
|
2894
|
+
error: FilterError.GENERIC_FAIL,
|
|
2891
2895
|
peerId: peerId
|
|
2892
2896
|
}
|
|
2893
2897
|
};
|
|
@@ -2900,11 +2904,11 @@ class FilterCore {
|
|
|
2900
2904
|
async unsubscribeAll(pubsubTopic, peerId) {
|
|
2901
2905
|
const stream = await this.streamManager.getStream(peerId);
|
|
2902
2906
|
if (!stream) {
|
|
2903
|
-
log$
|
|
2907
|
+
log$a.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
|
|
2904
2908
|
return {
|
|
2905
2909
|
success: null,
|
|
2906
2910
|
failure: {
|
|
2907
|
-
error:
|
|
2911
|
+
error: FilterError.NO_STREAM_AVAILABLE,
|
|
2908
2912
|
peerId: peerId
|
|
2909
2913
|
}
|
|
2910
2914
|
};
|
|
@@ -2914,7 +2918,7 @@ class FilterCore {
|
|
|
2914
2918
|
if (!res || !res.length) {
|
|
2915
2919
|
return {
|
|
2916
2920
|
failure: {
|
|
2917
|
-
error:
|
|
2921
|
+
error: FilterError.NO_RESPONSE,
|
|
2918
2922
|
peerId: peerId
|
|
2919
2923
|
},
|
|
2920
2924
|
success: null
|
|
@@ -2922,10 +2926,10 @@ class FilterCore {
|
|
|
2922
2926
|
}
|
|
2923
2927
|
const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
|
|
2924
2928
|
if (statusCode < 200 || statusCode >= 300) {
|
|
2925
|
-
log$
|
|
2929
|
+
log$a.error(`Filter unsubscribe all request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
|
|
2926
2930
|
return {
|
|
2927
2931
|
failure: {
|
|
2928
|
-
error:
|
|
2932
|
+
error: FilterError.REMOTE_PEER_REJECTED,
|
|
2929
2933
|
peerId: peerId
|
|
2930
2934
|
},
|
|
2931
2935
|
success: null
|
|
@@ -2939,11 +2943,11 @@ class FilterCore {
|
|
|
2939
2943
|
async ping(peerId) {
|
|
2940
2944
|
const stream = await this.streamManager.getStream(peerId);
|
|
2941
2945
|
if (!stream) {
|
|
2942
|
-
log$
|
|
2946
|
+
log$a.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
|
|
2943
2947
|
return {
|
|
2944
2948
|
success: null,
|
|
2945
2949
|
failure: {
|
|
2946
|
-
error:
|
|
2950
|
+
error: FilterError.NO_STREAM_AVAILABLE,
|
|
2947
2951
|
peerId: peerId
|
|
2948
2952
|
}
|
|
2949
2953
|
};
|
|
@@ -2954,11 +2958,11 @@ class FilterCore {
|
|
|
2954
2958
|
res = await pipe([request.encode()], encode, stream, decode, async (source) => await all(source));
|
|
2955
2959
|
}
|
|
2956
2960
|
catch (error) {
|
|
2957
|
-
log$
|
|
2961
|
+
log$a.error("Failed to send ping request", error);
|
|
2958
2962
|
return {
|
|
2959
2963
|
success: null,
|
|
2960
2964
|
failure: {
|
|
2961
|
-
error:
|
|
2965
|
+
error: FilterError.GENERIC_FAIL,
|
|
2962
2966
|
peerId: peerId
|
|
2963
2967
|
}
|
|
2964
2968
|
};
|
|
@@ -2967,18 +2971,18 @@ class FilterCore {
|
|
|
2967
2971
|
return {
|
|
2968
2972
|
success: null,
|
|
2969
2973
|
failure: {
|
|
2970
|
-
error:
|
|
2974
|
+
error: FilterError.NO_RESPONSE,
|
|
2971
2975
|
peerId: peerId
|
|
2972
2976
|
}
|
|
2973
2977
|
};
|
|
2974
2978
|
}
|
|
2975
2979
|
const { statusCode, requestId, statusDesc } = FilterSubscribeResponse.decode(res[0].slice());
|
|
2976
2980
|
if (statusCode < 200 || statusCode >= 300) {
|
|
2977
|
-
log$
|
|
2981
|
+
log$a.error(`Filter ping request ${requestId} failed with status code ${statusCode}: ${statusDesc}`);
|
|
2978
2982
|
return {
|
|
2979
2983
|
success: null,
|
|
2980
2984
|
failure: {
|
|
2981
|
-
error:
|
|
2985
|
+
error: FilterError.REMOTE_PEER_REJECTED,
|
|
2982
2986
|
peerId: peerId
|
|
2983
2987
|
}
|
|
2984
2988
|
};
|
|
@@ -2991,30 +2995,30 @@ class FilterCore {
|
|
|
2991
2995
|
onRequest(streamData) {
|
|
2992
2996
|
const { connection, stream } = streamData;
|
|
2993
2997
|
const { remotePeer } = connection;
|
|
2994
|
-
log$
|
|
2998
|
+
log$a.info(`Received message from ${remotePeer.toString()}`);
|
|
2995
2999
|
try {
|
|
2996
3000
|
pipe(stream, decode, async (source) => {
|
|
2997
3001
|
for await (const bytes of source) {
|
|
2998
3002
|
const response = FilterPushRpc.decode(bytes.slice());
|
|
2999
3003
|
const { pubsubTopic, wakuMessage } = response;
|
|
3000
3004
|
if (!wakuMessage) {
|
|
3001
|
-
log$
|
|
3005
|
+
log$a.error("Received empty message");
|
|
3002
3006
|
return;
|
|
3003
3007
|
}
|
|
3004
3008
|
if (!pubsubTopic) {
|
|
3005
|
-
log$
|
|
3009
|
+
log$a.error("Pubsub topic missing from push message");
|
|
3006
3010
|
return;
|
|
3007
3011
|
}
|
|
3008
3012
|
await this.handleIncomingMessage(pubsubTopic, wakuMessage, connection.remotePeer.toString());
|
|
3009
3013
|
}
|
|
3010
3014
|
}).then(() => {
|
|
3011
|
-
log$
|
|
3015
|
+
log$a.info("Receiving pipe closed.");
|
|
3012
3016
|
}, async (e) => {
|
|
3013
|
-
log$
|
|
3017
|
+
log$a.error(`Error with receiving pipe on peer:${connection.remotePeer.toString()} -- stream:${stream.id} -- protocol:${stream.protocol}: `, e);
|
|
3014
3018
|
});
|
|
3015
3019
|
}
|
|
3016
3020
|
catch (e) {
|
|
3017
|
-
log$
|
|
3021
|
+
log$a.error("Error decoding message", e);
|
|
3018
3022
|
}
|
|
3019
3023
|
}
|
|
3020
3024
|
}
|
|
@@ -3025,13 +3029,13 @@ var index$2 = /*#__PURE__*/Object.freeze({
|
|
|
3025
3029
|
FilterCore: FilterCore
|
|
3026
3030
|
});
|
|
3027
3031
|
|
|
3028
|
-
class
|
|
3032
|
+
class PushRpcV2 {
|
|
3029
3033
|
proto;
|
|
3030
3034
|
constructor(proto) {
|
|
3031
3035
|
this.proto = proto;
|
|
3032
3036
|
}
|
|
3033
3037
|
static createRequest(message, pubsubTopic) {
|
|
3034
|
-
return new
|
|
3038
|
+
return new PushRpcV2({
|
|
3035
3039
|
requestId: v4(),
|
|
3036
3040
|
request: {
|
|
3037
3041
|
message: message,
|
|
@@ -3042,7 +3046,7 @@ class PushRpc {
|
|
|
3042
3046
|
}
|
|
3043
3047
|
static decode(bytes) {
|
|
3044
3048
|
const res = PushRpc$1.decode(bytes);
|
|
3045
|
-
return new
|
|
3049
|
+
return new PushRpcV2(res);
|
|
3046
3050
|
}
|
|
3047
3051
|
encode() {
|
|
3048
3052
|
return PushRpc$1.encode(this.proto);
|
|
@@ -3055,6 +3059,140 @@ class PushRpc {
|
|
|
3055
3059
|
}
|
|
3056
3060
|
}
|
|
3057
3061
|
|
|
3062
|
+
/**
|
|
3063
|
+
* LightPush v3 protocol RPC handler.
|
|
3064
|
+
* Implements the v3 message format with correct field numbers:
|
|
3065
|
+
* - requestId: 1
|
|
3066
|
+
* - pubsubTopic: 20
|
|
3067
|
+
* - message: 21
|
|
3068
|
+
*/
|
|
3069
|
+
class PushRpc {
|
|
3070
|
+
proto;
|
|
3071
|
+
constructor(proto) {
|
|
3072
|
+
this.proto = proto;
|
|
3073
|
+
}
|
|
3074
|
+
/**
|
|
3075
|
+
* Create a v3 request message with proper field numbering
|
|
3076
|
+
*/
|
|
3077
|
+
static createRequest(message, pubsubTopic) {
|
|
3078
|
+
return new PushRpc({
|
|
3079
|
+
requestId: v4(),
|
|
3080
|
+
pubsubTopic: pubsubTopic,
|
|
3081
|
+
message: message
|
|
3082
|
+
});
|
|
3083
|
+
}
|
|
3084
|
+
/**
|
|
3085
|
+
* Create a v3 response message with status code handling
|
|
3086
|
+
*/
|
|
3087
|
+
static createResponse(requestId, statusCode, statusDesc, relayPeerCount) {
|
|
3088
|
+
return new PushRpc({
|
|
3089
|
+
requestId,
|
|
3090
|
+
statusCode,
|
|
3091
|
+
statusDesc,
|
|
3092
|
+
relayPeerCount
|
|
3093
|
+
});
|
|
3094
|
+
}
|
|
3095
|
+
/**
|
|
3096
|
+
* Decode v3 request message
|
|
3097
|
+
*/
|
|
3098
|
+
static decodeRequest(bytes) {
|
|
3099
|
+
const res = LightPushRequestV3.decode(bytes);
|
|
3100
|
+
return new PushRpc(res);
|
|
3101
|
+
}
|
|
3102
|
+
/**
|
|
3103
|
+
* Decode v3 response message
|
|
3104
|
+
*/
|
|
3105
|
+
static decodeResponse(bytes) {
|
|
3106
|
+
const res = LightPushResponseV3.decode(bytes);
|
|
3107
|
+
return new PushRpc(res);
|
|
3108
|
+
}
|
|
3109
|
+
/**
|
|
3110
|
+
* Encode message to bytes
|
|
3111
|
+
*/
|
|
3112
|
+
encode() {
|
|
3113
|
+
if (this.isRequest()) {
|
|
3114
|
+
return LightPushRequestV3.encode(this.proto);
|
|
3115
|
+
}
|
|
3116
|
+
else {
|
|
3117
|
+
return LightPushResponseV3.encode(this.proto);
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
/**
|
|
3121
|
+
* Get request data (if this is a request message)
|
|
3122
|
+
*/
|
|
3123
|
+
get request() {
|
|
3124
|
+
return this.isRequest()
|
|
3125
|
+
? this.proto
|
|
3126
|
+
: undefined;
|
|
3127
|
+
}
|
|
3128
|
+
/**
|
|
3129
|
+
* Get response data (if this is a response message)
|
|
3130
|
+
*/
|
|
3131
|
+
get response() {
|
|
3132
|
+
return this.isResponse()
|
|
3133
|
+
? this.proto
|
|
3134
|
+
: undefined;
|
|
3135
|
+
}
|
|
3136
|
+
/**
|
|
3137
|
+
* Get the request ID
|
|
3138
|
+
*/
|
|
3139
|
+
get requestId() {
|
|
3140
|
+
return this.proto.requestId;
|
|
3141
|
+
}
|
|
3142
|
+
/**
|
|
3143
|
+
* Get the pubsub topic (only available in requests)
|
|
3144
|
+
*/
|
|
3145
|
+
get pubsubTopic() {
|
|
3146
|
+
return this.isRequest()
|
|
3147
|
+
? this.proto.pubsubTopic
|
|
3148
|
+
: undefined;
|
|
3149
|
+
}
|
|
3150
|
+
/**
|
|
3151
|
+
* Get the message (only available in requests)
|
|
3152
|
+
*/
|
|
3153
|
+
get message() {
|
|
3154
|
+
return this.isRequest()
|
|
3155
|
+
? this.proto.message
|
|
3156
|
+
: undefined;
|
|
3157
|
+
}
|
|
3158
|
+
/**
|
|
3159
|
+
* Get the status code (only available in responses)
|
|
3160
|
+
*/
|
|
3161
|
+
get statusCode() {
|
|
3162
|
+
return this.isResponse()
|
|
3163
|
+
? this.proto.statusCode
|
|
3164
|
+
: undefined;
|
|
3165
|
+
}
|
|
3166
|
+
/**
|
|
3167
|
+
* Get the status description (only available in responses)
|
|
3168
|
+
*/
|
|
3169
|
+
get statusDesc() {
|
|
3170
|
+
return this.isResponse()
|
|
3171
|
+
? this.proto.statusDesc
|
|
3172
|
+
: undefined;
|
|
3173
|
+
}
|
|
3174
|
+
/**
|
|
3175
|
+
* Get the relay peer count (only available in responses)
|
|
3176
|
+
*/
|
|
3177
|
+
get relayPeerCount() {
|
|
3178
|
+
return this.isResponse()
|
|
3179
|
+
? this.proto.relayPeerCount
|
|
3180
|
+
: undefined;
|
|
3181
|
+
}
|
|
3182
|
+
/**
|
|
3183
|
+
* Check if this is a request message
|
|
3184
|
+
*/
|
|
3185
|
+
isRequest() {
|
|
3186
|
+
return "pubsubTopic" in this.proto && "message" in this.proto;
|
|
3187
|
+
}
|
|
3188
|
+
/**
|
|
3189
|
+
* Check if this is a response message
|
|
3190
|
+
*/
|
|
3191
|
+
isResponse() {
|
|
3192
|
+
return "statusCode" in this.proto;
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
|
|
3058
3196
|
// should match nwaku
|
|
3059
3197
|
// https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/rln_relay.nim#L309
|
|
3060
3198
|
// https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/tests/waku_rln_relay/rln/waku_rln_relay_utils.nim#L20
|
|
@@ -3073,140 +3211,243 @@ const isRLNResponseError = (info) => {
|
|
|
3073
3211
|
info.includes(RLN_REMOTE_VALIDATION));
|
|
3074
3212
|
};
|
|
3075
3213
|
|
|
3076
|
-
const
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
class
|
|
3082
|
-
|
|
3083
|
-
multicodec = LightPushCodec;
|
|
3084
|
-
constructor(libp2p) {
|
|
3085
|
-
this.streamManager = new StreamManager(LightPushCodec, libp2p.components);
|
|
3086
|
-
}
|
|
3087
|
-
async preparePushMessage(encoder, message) {
|
|
3214
|
+
const CODECS = {
|
|
3215
|
+
v2: "/vac/waku/lightpush/2.0.0-beta1",
|
|
3216
|
+
v3: "/vac/waku/lightpush/3.0.0"
|
|
3217
|
+
};
|
|
3218
|
+
const log$9 = new Logger("light-push:protocol-handler");
|
|
3219
|
+
class ProtocolHandler {
|
|
3220
|
+
static async preparePushMessage(encoder, message, protocol) {
|
|
3088
3221
|
try {
|
|
3089
3222
|
if (!message.payload || message.payload.length === 0) {
|
|
3090
|
-
log$
|
|
3091
|
-
return {
|
|
3223
|
+
log$9.error("Failed to send waku light push: payload is empty");
|
|
3224
|
+
return { rpc: null, error: LightPushError.EMPTY_PAYLOAD };
|
|
3092
3225
|
}
|
|
3093
3226
|
if (!(await isMessageSizeUnderCap(encoder, message))) {
|
|
3094
|
-
log$
|
|
3095
|
-
return {
|
|
3227
|
+
log$9.error("Failed to send waku light push: message is bigger than 1MB");
|
|
3228
|
+
return { rpc: null, error: LightPushError.SIZE_TOO_BIG };
|
|
3096
3229
|
}
|
|
3097
3230
|
const protoMessage = await encoder.toProtoObj(message);
|
|
3098
3231
|
if (!protoMessage) {
|
|
3099
|
-
log$
|
|
3232
|
+
log$9.error("Failed to encode to protoMessage, aborting push");
|
|
3233
|
+
return { rpc: null, error: LightPushError.ENCODE_FAILED };
|
|
3234
|
+
}
|
|
3235
|
+
// Select version implementation
|
|
3236
|
+
if (protocol === CODECS.v3) {
|
|
3237
|
+
log$9.info("Creating v3 RPC message");
|
|
3100
3238
|
return {
|
|
3101
|
-
|
|
3102
|
-
error:
|
|
3239
|
+
rpc: createV3Rpc(protoMessage, encoder.pubsubTopic),
|
|
3240
|
+
error: null
|
|
3103
3241
|
};
|
|
3104
3242
|
}
|
|
3105
|
-
|
|
3106
|
-
|
|
3243
|
+
// Default to v2
|
|
3244
|
+
log$9.info("Creating v2 RPC message");
|
|
3245
|
+
return {
|
|
3246
|
+
rpc: createV2Rpc(protoMessage, encoder.pubsubTopic),
|
|
3247
|
+
error: null
|
|
3248
|
+
};
|
|
3107
3249
|
}
|
|
3108
|
-
catch (
|
|
3109
|
-
log$
|
|
3250
|
+
catch (err) {
|
|
3251
|
+
log$9.error("Failed to prepare push message", err);
|
|
3252
|
+
return { rpc: null, error: LightPushError.GENERIC_FAIL };
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
/**
|
|
3256
|
+
* Decode and evaluate a LightPush response according to the protocol version
|
|
3257
|
+
*/
|
|
3258
|
+
static handleResponse(bytes, protocol, peerId) {
|
|
3259
|
+
if (protocol === CODECS.v3) {
|
|
3260
|
+
return ProtocolHandler.handleV3Response(bytes, peerId);
|
|
3261
|
+
}
|
|
3262
|
+
return ProtocolHandler.handleV2Response(bytes, peerId);
|
|
3263
|
+
}
|
|
3264
|
+
static handleV3Response(bytes, peerId) {
|
|
3265
|
+
try {
|
|
3266
|
+
const decodedRpcV3 = PushRpc.decodeResponse(bytes);
|
|
3267
|
+
const statusCode = decodedRpcV3.statusCode;
|
|
3268
|
+
const statusDesc = decodedRpcV3.statusDesc;
|
|
3269
|
+
if (statusCode !== LightPushStatusCode.SUCCESS) {
|
|
3270
|
+
const error = LightPushError.REMOTE_PEER_REJECTED;
|
|
3271
|
+
log$9.error(`Remote peer rejected with v3 status code ${statusCode}: ${statusDesc}`);
|
|
3272
|
+
return {
|
|
3273
|
+
success: null,
|
|
3274
|
+
failure: {
|
|
3275
|
+
error,
|
|
3276
|
+
peerId: peerId
|
|
3277
|
+
}
|
|
3278
|
+
};
|
|
3279
|
+
}
|
|
3280
|
+
if (decodedRpcV3.relayPeerCount !== undefined) {
|
|
3281
|
+
log$9.info(`Message relayed to ${decodedRpcV3.relayPeerCount} peers`);
|
|
3282
|
+
}
|
|
3283
|
+
return { success: peerId, failure: null };
|
|
3284
|
+
}
|
|
3285
|
+
catch (err) {
|
|
3110
3286
|
return {
|
|
3111
|
-
|
|
3112
|
-
|
|
3287
|
+
success: null,
|
|
3288
|
+
failure: {
|
|
3289
|
+
error: LightPushError.DECODE_FAILED,
|
|
3290
|
+
peerId: peerId
|
|
3291
|
+
}
|
|
3113
3292
|
};
|
|
3114
3293
|
}
|
|
3115
3294
|
}
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3295
|
+
static handleV2Response(bytes, peerId) {
|
|
3296
|
+
let response;
|
|
3297
|
+
try {
|
|
3298
|
+
const decodedRpc = PushRpcV2.decode(bytes);
|
|
3299
|
+
response = decodedRpc.response;
|
|
3300
|
+
}
|
|
3301
|
+
catch (err) {
|
|
3119
3302
|
return {
|
|
3120
3303
|
success: null,
|
|
3121
3304
|
failure: {
|
|
3122
|
-
error:
|
|
3123
|
-
peerId
|
|
3305
|
+
error: LightPushError.DECODE_FAILED,
|
|
3306
|
+
peerId: peerId
|
|
3124
3307
|
}
|
|
3125
3308
|
};
|
|
3126
3309
|
}
|
|
3127
|
-
|
|
3128
|
-
if (!stream) {
|
|
3129
|
-
log$8.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
|
|
3310
|
+
if (!response) {
|
|
3130
3311
|
return {
|
|
3131
3312
|
success: null,
|
|
3132
3313
|
failure: {
|
|
3133
|
-
error:
|
|
3314
|
+
error: LightPushError.NO_RESPONSE,
|
|
3134
3315
|
peerId: peerId
|
|
3135
3316
|
}
|
|
3136
3317
|
};
|
|
3137
3318
|
}
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3319
|
+
if (isRLNResponseError(response.info)) {
|
|
3320
|
+
log$9.error("Remote peer fault: RLN generation");
|
|
3321
|
+
return {
|
|
3322
|
+
success: null,
|
|
3323
|
+
failure: {
|
|
3324
|
+
error: LightPushError.RLN_PROOF_GENERATION,
|
|
3325
|
+
peerId: peerId
|
|
3326
|
+
}
|
|
3327
|
+
};
|
|
3141
3328
|
}
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
log$8.error("Failed to send waku light push request", err);
|
|
3329
|
+
if (!response.isSuccess) {
|
|
3330
|
+
log$9.error("Remote peer rejected the message: ", response.info);
|
|
3145
3331
|
return {
|
|
3146
3332
|
success: null,
|
|
3147
3333
|
failure: {
|
|
3148
|
-
error:
|
|
3334
|
+
error: LightPushError.REMOTE_PEER_REJECTED,
|
|
3149
3335
|
peerId: peerId
|
|
3150
3336
|
}
|
|
3151
3337
|
};
|
|
3152
3338
|
}
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3339
|
+
return { success: peerId, failure: null };
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
function createV2Rpc(message, pubsubTopic) {
|
|
3343
|
+
const v2Rpc = PushRpcV2.createRequest(message, pubsubTopic);
|
|
3344
|
+
return Object.assign(v2Rpc, { version: "v2" });
|
|
3345
|
+
}
|
|
3346
|
+
function createV3Rpc(message, pubsubTopic) {
|
|
3347
|
+
if (!message.timestamp) {
|
|
3348
|
+
message.timestamp = BigInt(Date.now()) * BigInt(1_000_000);
|
|
3349
|
+
}
|
|
3350
|
+
const v3Rpc = PushRpc.createRequest(message, pubsubTopic);
|
|
3351
|
+
return Object.assign(v3Rpc, { version: "v3" });
|
|
3352
|
+
}
|
|
3353
|
+
|
|
3354
|
+
const log$8 = new Logger("light-push");
|
|
3355
|
+
const LightPushCodec = CODECS.v3;
|
|
3356
|
+
const LightPushCodecV2 = CODECS.v2;
|
|
3357
|
+
/**
|
|
3358
|
+
* Implements the [Waku v2 Light Push protocol](https://rfc.vac.dev/spec/19/).
|
|
3359
|
+
*/
|
|
3360
|
+
class LightPushCore {
|
|
3361
|
+
libp2p;
|
|
3362
|
+
streamManager;
|
|
3363
|
+
streamManagerV2;
|
|
3364
|
+
multicodec = [CODECS.v3, CODECS.v2];
|
|
3365
|
+
constructor(libp2p, legacy) {
|
|
3366
|
+
this.libp2p = libp2p;
|
|
3367
|
+
this.streamManagerV2 = new StreamManager(CODECS.v2, libp2p.components);
|
|
3368
|
+
this.streamManager = legacy
|
|
3369
|
+
? this.streamManagerV2
|
|
3370
|
+
: new StreamManager(CODECS.v3, libp2p.components);
|
|
3371
|
+
}
|
|
3372
|
+
async send(encoder, message, peerId) {
|
|
3373
|
+
let stream;
|
|
3374
|
+
let protocol;
|
|
3158
3375
|
try {
|
|
3159
|
-
|
|
3376
|
+
const peer = await this.libp2p.peerStore.get(peerId);
|
|
3377
|
+
if (this.streamManager.multicodec === CODECS.v3 &&
|
|
3378
|
+
peer.protocols.includes(CODECS.v3)) {
|
|
3379
|
+
stream = await this.streamManager.getStream(peerId);
|
|
3380
|
+
protocol = CODECS.v3;
|
|
3381
|
+
}
|
|
3382
|
+
else {
|
|
3383
|
+
stream = await this.streamManagerV2.getStream(peerId);
|
|
3384
|
+
protocol = CODECS.v2;
|
|
3385
|
+
}
|
|
3160
3386
|
}
|
|
3161
|
-
catch (
|
|
3162
|
-
log$8.error("Failed to
|
|
3387
|
+
catch (error) {
|
|
3388
|
+
log$8.error("Failed to get stream", error);
|
|
3163
3389
|
return {
|
|
3164
3390
|
success: null,
|
|
3165
3391
|
failure: {
|
|
3166
|
-
error:
|
|
3167
|
-
peerId
|
|
3392
|
+
error: LightPushError.GENERIC_FAIL,
|
|
3393
|
+
peerId
|
|
3168
3394
|
}
|
|
3169
3395
|
};
|
|
3170
3396
|
}
|
|
3171
|
-
if (!
|
|
3172
|
-
log$8.error(
|
|
3397
|
+
if (!stream) {
|
|
3398
|
+
log$8.error(`Failed to get a stream for remote peer:${peerId.toString()}`);
|
|
3173
3399
|
return {
|
|
3174
3400
|
success: null,
|
|
3175
3401
|
failure: {
|
|
3176
|
-
error:
|
|
3402
|
+
error: LightPushError.NO_STREAM_AVAILABLE,
|
|
3177
3403
|
peerId: peerId
|
|
3178
3404
|
}
|
|
3179
3405
|
};
|
|
3180
3406
|
}
|
|
3181
|
-
|
|
3182
|
-
|
|
3407
|
+
const { rpc, error: prepError } = await ProtocolHandler.preparePushMessage(encoder, message, protocol);
|
|
3408
|
+
if (prepError || !rpc) {
|
|
3183
3409
|
return {
|
|
3184
3410
|
success: null,
|
|
3185
3411
|
failure: {
|
|
3186
|
-
error:
|
|
3412
|
+
error: prepError ?? LightPushError.GENERIC_FAIL,
|
|
3413
|
+
peerId
|
|
3414
|
+
}
|
|
3415
|
+
};
|
|
3416
|
+
}
|
|
3417
|
+
let res;
|
|
3418
|
+
try {
|
|
3419
|
+
res = await pipe([rpc.encode()], encode, stream, decode, async (source) => await all(source));
|
|
3420
|
+
}
|
|
3421
|
+
catch (err) {
|
|
3422
|
+
log$8.error("Failed to send waku light push request", err);
|
|
3423
|
+
return {
|
|
3424
|
+
success: null,
|
|
3425
|
+
failure: {
|
|
3426
|
+
error: LightPushError.STREAM_ABORTED,
|
|
3187
3427
|
peerId: peerId
|
|
3188
3428
|
}
|
|
3189
3429
|
};
|
|
3190
3430
|
}
|
|
3191
|
-
|
|
3192
|
-
|
|
3431
|
+
const bytes = new Uint8ArrayList();
|
|
3432
|
+
res.forEach((chunk) => bytes.append(chunk));
|
|
3433
|
+
if (bytes.length === 0) {
|
|
3193
3434
|
return {
|
|
3194
3435
|
success: null,
|
|
3195
3436
|
failure: {
|
|
3196
|
-
error:
|
|
3437
|
+
error: LightPushError.NO_RESPONSE,
|
|
3197
3438
|
peerId: peerId
|
|
3198
3439
|
}
|
|
3199
3440
|
};
|
|
3200
3441
|
}
|
|
3201
|
-
return
|
|
3442
|
+
return ProtocolHandler.handleResponse(bytes, protocol, peerId);
|
|
3202
3443
|
}
|
|
3203
3444
|
}
|
|
3204
3445
|
|
|
3205
3446
|
var index$1 = /*#__PURE__*/Object.freeze({
|
|
3206
3447
|
__proto__: null,
|
|
3207
3448
|
LightPushCodec: LightPushCodec,
|
|
3208
|
-
|
|
3209
|
-
|
|
3449
|
+
LightPushCodecV2: LightPushCodecV2,
|
|
3450
|
+
LightPushCore: LightPushCore
|
|
3210
3451
|
});
|
|
3211
3452
|
|
|
3212
3453
|
const EmptyMessage = {
|
|
@@ -3305,7 +3546,7 @@ const log$7 = new Logger("store");
|
|
|
3305
3546
|
const StoreCodec = "/vac/waku/store-query/3.0.0";
|
|
3306
3547
|
class StoreCore {
|
|
3307
3548
|
streamManager;
|
|
3308
|
-
multicodec = StoreCodec;
|
|
3549
|
+
multicodec = [StoreCodec];
|
|
3309
3550
|
constructor(libp2p) {
|
|
3310
3551
|
this.streamManager = new StreamManager(StoreCodec, libp2p.components);
|
|
3311
3552
|
}
|
|
@@ -3428,7 +3669,7 @@ class ConnectionLimiter {
|
|
|
3428
3669
|
this.connectionMonitorInterval === null) {
|
|
3429
3670
|
this.connectionMonitorInterval = setInterval(() => void this.maintainConnections(), DEFAULT_CONNECTION_MONITOR_INTERVAL);
|
|
3430
3671
|
}
|
|
3431
|
-
this.events.addEventListener(
|
|
3672
|
+
this.events.addEventListener("waku:connection", this.onWakuConnectionEvent);
|
|
3432
3673
|
/**
|
|
3433
3674
|
* NOTE: Event is not being emitted on closing nor losing a connection.
|
|
3434
3675
|
* @see https://github.com/libp2p/js-libp2p/issues/939
|
|
@@ -3443,7 +3684,7 @@ class ConnectionLimiter {
|
|
|
3443
3684
|
this.libp2p.addEventListener("peer:disconnect", this.onDisconnectedEvent);
|
|
3444
3685
|
}
|
|
3445
3686
|
stop() {
|
|
3446
|
-
this.events.removeEventListener(
|
|
3687
|
+
this.events.removeEventListener("waku:connection", this.onWakuConnectionEvent);
|
|
3447
3688
|
this.libp2p.removeEventListener("peer:disconnect", this.onDisconnectedEvent);
|
|
3448
3689
|
if (this.connectionMonitorInterval) {
|
|
3449
3690
|
clearInterval(this.connectionMonitorInterval);
|
|
@@ -4000,7 +4241,7 @@ class NetworkMonitor {
|
|
|
4000
4241
|
}
|
|
4001
4242
|
}
|
|
4002
4243
|
dispatchNetworkEvent() {
|
|
4003
|
-
this.events.dispatchEvent(new CustomEvent(
|
|
4244
|
+
this.events.dispatchEvent(new CustomEvent("waku:connection", {
|
|
4004
4245
|
detail: this.isConnected()
|
|
4005
4246
|
}));
|
|
4006
4247
|
}
|
|
@@ -9484,7 +9725,7 @@ class Metadata {
|
|
|
9484
9725
|
streamManager;
|
|
9485
9726
|
libp2pComponents;
|
|
9486
9727
|
handshakesConfirmed = new Map();
|
|
9487
|
-
multicodec = MetadataCodec;
|
|
9728
|
+
multicodec = [MetadataCodec];
|
|
9488
9729
|
constructor(clusterId, libp2p) {
|
|
9489
9730
|
this.clusterId = clusterId;
|
|
9490
9731
|
this.streamManager = new StreamManager(MetadataCodec, libp2p);
|
|
@@ -9593,4 +9834,4 @@ function wakuMetadata(clusterId) {
|
|
|
9593
9834
|
return (components) => new Metadata(clusterId, components);
|
|
9594
9835
|
}
|
|
9595
9836
|
|
|
9596
|
-
export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCore, MetadataCodec, StoreCodec, StoreCore, StreamManager, createEncoder, index$3 as message, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
|
|
9837
|
+
export { ConnectionManager, FilterCodecs, FilterCore, LightPushCodec, LightPushCodecV2, LightPushCore, MetadataCodec, StoreCodec, StoreCore, StreamManager, createEncoder, index$3 as message, wakuMetadata, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
|