mirror of https://github.com/waku-org/js-waku.git
Merge pull request #1585 from waku-org/fix/light-error-1553
This commit is contained in:
commit
6d7b235eec
|
@ -1,3 +1,4 @@
|
||||||
|
import type { Stream } from "@libp2p/interface/connection";
|
||||||
import type { PeerId } from "@libp2p/interface/peer-id";
|
import type { PeerId } from "@libp2p/interface/peer-id";
|
||||||
import {
|
import {
|
||||||
IEncoder,
|
IEncoder,
|
||||||
|
@ -102,43 +103,63 @@ class LightPush extends BaseProtocol implements ILightPush {
|
||||||
numPeers: this.NUM_PEERS_PROTOCOL
|
numPeers: this.NUM_PEERS_PROTOCOL
|
||||||
});
|
});
|
||||||
|
|
||||||
const promises = peers.map(async (peer) => {
|
if (!peers.length) {
|
||||||
let error: SendError | undefined;
|
return {
|
||||||
const stream = await this.getStream(peer);
|
recipients,
|
||||||
|
errors: [SendError.NO_PEER_AVAILABLE]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const promises = peers.map(async (peer) => {
|
||||||
|
let stream: Stream | undefined;
|
||||||
try {
|
try {
|
||||||
const res = await pipe(
|
stream = await this.getStream(peer);
|
||||||
|
} catch (err) {
|
||||||
|
log(`Failed to get a stream for remote peer${peer.id.toString()}`, err);
|
||||||
|
return { recipients, error: SendError.REMOTE_PEER_FAULT };
|
||||||
|
}
|
||||||
|
|
||||||
|
let res: Uint8ArrayList[] | undefined;
|
||||||
|
try {
|
||||||
|
res = await pipe(
|
||||||
[query.encode()],
|
[query.encode()],
|
||||||
lp.encode,
|
lp.encode,
|
||||||
stream,
|
stream,
|
||||||
lp.decode,
|
lp.decode,
|
||||||
async (source) => await all(source)
|
async (source) => await all(source)
|
||||||
);
|
);
|
||||||
try {
|
} catch (err) {
|
||||||
|
log("Failed to send waku light push request", err);
|
||||||
|
return { recipients, error: SendError.GENERIC_FAIL };
|
||||||
|
}
|
||||||
|
|
||||||
const bytes = new Uint8ArrayList();
|
const bytes = new Uint8ArrayList();
|
||||||
res.forEach((chunk) => {
|
res.forEach((chunk) => {
|
||||||
bytes.append(chunk);
|
bytes.append(chunk);
|
||||||
});
|
});
|
||||||
|
|
||||||
const response = PushRpc.decode(bytes).response;
|
let response: PushResponse | undefined;
|
||||||
|
try {
|
||||||
if (response?.isSuccess) {
|
response = PushRpc.decode(bytes).response;
|
||||||
recipients.some((recipient) => recipient.equals(peer.id)) ||
|
|
||||||
recipients.push(peer.id);
|
|
||||||
} else {
|
|
||||||
log("No response in PushRPC");
|
|
||||||
error = SendError.NO_RPC_RESPONSE;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log("Failed to decode push reply", err);
|
log("Failed to decode push reply", err);
|
||||||
error = SendError.DECODE_FAILED;
|
return { recipients, error: SendError.DECODE_FAILED };
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
log("Failed to send waku light push request", err);
|
|
||||||
error = SendError.GENERIC_FAIL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { recipients, error };
|
if (!response) {
|
||||||
|
log("Remote peer fault: No response in PushRPC");
|
||||||
|
return { recipients, error: SendError.REMOTE_PEER_FAULT };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response.isSuccess) {
|
||||||
|
log("Remote peer rejected the message: ", response.info);
|
||||||
|
return { recipients, error: SendError.REMOTE_PEER_REJECTED };
|
||||||
|
}
|
||||||
|
|
||||||
|
recipients.some((recipient) => recipient.equals(peer.id)) ||
|
||||||
|
recipients.push(peer.id);
|
||||||
|
|
||||||
|
return { recipients };
|
||||||
});
|
});
|
||||||
|
|
||||||
const results = await Promise.allSettled(promises);
|
const results = await Promise.allSettled(promises);
|
||||||
|
|
|
@ -59,11 +59,36 @@ export type Callback<T extends IDecodedMessage> = (
|
||||||
) => void | Promise<void>;
|
) => void | Promise<void>;
|
||||||
|
|
||||||
export enum SendError {
|
export enum SendError {
|
||||||
|
/** Could not determine the origin of the fault. Best to check connectivity and try again */
|
||||||
GENERIC_FAIL = "Generic error",
|
GENERIC_FAIL = "Generic error",
|
||||||
|
/** Failure to protobuf encode the message. This is not recoverable and needs
|
||||||
|
* further investigation. */
|
||||||
ENCODE_FAILED = "Failed to encode",
|
ENCODE_FAILED = "Failed to encode",
|
||||||
|
/** Failure to protobuf decode the message. May be due to a remote peer issue,
|
||||||
|
* ensuring that messages are sent via several peer enable mitigation of this error.. */
|
||||||
DECODE_FAILED = "Failed to decode",
|
DECODE_FAILED = "Failed to decode",
|
||||||
|
/** The message size is above the maximum message size allowed on the Waku Network.
|
||||||
|
* Compressing the message or using an alternative strategy for large messages is recommended.
|
||||||
|
*/
|
||||||
SIZE_TOO_BIG = "Size is too big",
|
SIZE_TOO_BIG = "Size is too big",
|
||||||
NO_RPC_RESPONSE = "No RPC response"
|
/**
|
||||||
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
||||||
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
||||||
|
* to user or listening for `peer:connected:bootstrap` or `peer:connected:peer-exchange`
|
||||||
|
* on the connection manager before retrying.
|
||||||
|
*/
|
||||||
|
NO_PEER_AVAILABLE = "No peer available",
|
||||||
|
/**
|
||||||
|
* The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE`
|
||||||
|
* or `DECODE_FAILED` can be used.
|
||||||
|
*/
|
||||||
|
REMOTE_PEER_FAULT = "Remote peer fault",
|
||||||
|
/**
|
||||||
|
* The remote peer rejected the message. Information provided by the remote peer
|
||||||
|
* is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
|
||||||
|
* or `DECODE_FAILED` can be used.
|
||||||
|
*/
|
||||||
|
REMOTE_PEER_REJECTED = "Remote peer rejected"
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SendResult {
|
export interface SendResult {
|
||||||
|
|
|
@ -86,7 +86,8 @@ describe("Waku Light Push [node only]", function () {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
expect(pushResponse.recipients.length).to.eq(0);
|
expect(pushResponse.recipients.length).to.eq(0);
|
||||||
expect(pushResponse.errors).to.include(SendError.NO_RPC_RESPONSE);
|
// This should be `REMOTE_PEER_REJECTED`, tracked with https://github.com/waku-org/nwaku/issues/1641
|
||||||
|
expect(pushResponse.errors).to.include(SendError.REMOTE_PEER_FAULT);
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(false);
|
expect(await messageCollector.waitForMessages(1)).to.eq(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -158,7 +159,8 @@ describe("Waku Light Push [node only]", function () {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
expect(pushResponse.recipients.length).to.eq(0);
|
expect(pushResponse.recipients.length).to.eq(0);
|
||||||
expect(pushResponse.errors).to.include(SendError.NO_RPC_RESPONSE);
|
// Should be `REMOTE_PEER_REJECTED`, tracked with https://github.com/waku-org/nwaku/issues/2059
|
||||||
|
expect(pushResponse.errors).to.include(SendError.REMOTE_PEER_FAULT);
|
||||||
expect(await messageCollector.waitForMessages(1)).to.eq(false);
|
expect(await messageCollector.waitForMessages(1)).to.eq(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue