@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
73 lines (64 loc) • 2.59 kB
text/typescript
import {RequestError, RequestErrorCode} from "@lodestar/reqresp";
import {PeerAction} from "../peers/score/index.js";
import {ReqRespMethod} from "./types.js";
/**
* libp2p-ts does not include types for the error codes.
* When libp2p has native types, this object won't be necessary.
* https://github.com/libp2p/js-libp2p/blob/6350a187c7c207086e42436ccbcabd59af6f5e3d/src/errors.js#L32
*/
const libp2pErrorCodes = {
ERR_UNSUPPORTED_PROTOCOL: "ERR_UNSUPPORTED_PROTOCOL",
};
/**
* Multi stream select error code
* https://github.com/multiformats/js-multistream-select/blame/cf4e297b362a43bde2ea117085ceba78cbce1c12/src/select.js#L50
*/
const multiStreamSelectErrorCodes = {
protocolSelectionFailed: "protocol selection failed",
};
export function onOutgoingReqRespError(e: RequestError, method: ReqRespMethod): PeerAction | null {
switch (e.type.code) {
case RequestErrorCode.INVALID_REQUEST:
case RequestErrorCode.INVALID_RESPONSE_SSZ:
case RequestErrorCode.SSZ_OVER_MAX_SIZE:
return PeerAction.LowToleranceError;
case RequestErrorCode.SERVER_ERROR:
return PeerAction.MidToleranceError;
case RequestErrorCode.UNKNOWN_ERROR_STATUS:
return PeerAction.HighToleranceError;
case RequestErrorCode.DIAL_TIMEOUT:
case RequestErrorCode.DIAL_ERROR:
return e.message.includes(multiStreamSelectErrorCodes.protocolSelectionFailed) && method === ReqRespMethod.Ping
? PeerAction.Fatal
: PeerAction.LowToleranceError;
// TODO: Detect SSZDecodeError and return PeerAction.Fatal
case RequestErrorCode.RESP_TIMEOUT:
switch (method) {
case ReqRespMethod.Ping:
case ReqRespMethod.Status:
case ReqRespMethod.Metadata:
return PeerAction.LowToleranceError;
case ReqRespMethod.BeaconBlocksByRange:
case ReqRespMethod.BeaconBlocksByRoot:
case ReqRespMethod.BeaconBlocksByHead:
case ReqRespMethod.ExecutionPayloadEnvelopesByRoot:
case ReqRespMethod.ExecutionPayloadEnvelopesByRange:
return PeerAction.MidToleranceError;
default:
return null;
}
}
if (e.message.includes(libp2pErrorCodes.ERR_UNSUPPORTED_PROTOCOL)) {
switch (method) {
case ReqRespMethod.Ping:
return PeerAction.Fatal;
case ReqRespMethod.Metadata:
case ReqRespMethod.Status:
return PeerAction.LowToleranceError;
default:
return null;
}
}
// other errors like RequestErrorCode.RESP_RATE_LIMITED could come from ourself, not the peer so we should not penalize them
return null;
}