From 64242d9c84a0b73245bf92842b83786df299dc8a Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Wed, 9 Mar 2022 15:03:58 +0100 Subject: [PATCH] add support for `ResourceUnavailable` p2p error (#3476) The `p2p-interface.md` spec defines a `ResourceUnavailable` error to return in situations where data that exists on the network is locally unavailable, e.g., when a block within `MIN_EPOCHS_FOR_BLOCK_REQUESTS` is requested by `BeaconBlocksByRange` but cannot be provided. This patch adds support for that additional error code. --- beacon_chain/networking/eth2_network.nim | 14 ++++++++++++-- beacon_chain/networking/faststreams_backend.nim | 4 ++-- beacon_chain/networking/libp2p_streams_backend.nim | 4 ++-- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index 7cd4907f7..f402790bb 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -158,6 +158,7 @@ type Success InvalidRequest ServerError + ResourceUnavailable PeerStateInitializer* = proc(peer: Peer): RootRef {.gcsafe, raises: [Defect].} NetworkStateInitializer* = proc(network: EthereumNode): RootRef {.gcsafe, raises: [Defect].} @@ -206,6 +207,8 @@ type InvalidInputsError* = object of CatchableError + ResourceUnavailableError* = object of CatchableError + NetRes*[T] = Result[T, Eth2NetworkingError] ## This is type returned from all network requests @@ -720,6 +723,13 @@ proc handleIncomingStream(network: Eth2Node, template returnInvalidRequest(msg: string) = returnInvalidRequest(ErrorMsg msg.toBytes) + template returnResourceUnavailable(msg: ErrorMsg) = + await sendErrorResponse(peer, conn, ResourceUnavailable, msg) + return + + template returnResourceUnavailable(msg: string) = + returnResourceUnavailable(ErrorMsg msg.toBytes) + let s = when useNativeSnappy: let fs = libp2pInput(conn) @@ -794,8 +804,8 @@ proc handleIncomingStream(network: Eth2Node, await callUserHandler(MsgType, peer, conn, msg.get) except InvalidInputsError as err: returnInvalidRequest err.msg - await sendErrorResponse(peer, conn, ServerError, - ErrorMsg err.msg.toBytes) + except ResourceUnavailableError as err: + returnResourceUnavailable err.msg except CatchableError as err: await sendErrorResponse(peer, conn, ServerError, ErrorMsg err.msg.toBytes) diff --git a/beacon_chain/networking/faststreams_backend.nim b/beacon_chain/networking/faststreams_backend.nim index 91d00aae3..6a465b4ee 100644 --- a/beacon_chain/networking/faststreams_backend.nim +++ b/beacon_chain/networking/faststreams_backend.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH +# Copyright (c) 2018-2022 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). @@ -112,7 +112,7 @@ proc readResponseChunk(s: AsyncInputStream, let responseCode = ResponseCode responseCodeByte case responseCode: - of InvalidRequest, ServerError: + of InvalidRequest, ServerError, ResourceUnavailable: let errorMsgChunk = await readChunkPayload(s, noSnappy, string) let errorMsg = if errorMsgChunk.isOk: errorMsgChunk.value else: return err(errorMsgChunk.error) diff --git a/beacon_chain/networking/libp2p_streams_backend.nim b/beacon_chain/networking/libp2p_streams_backend.nim index 535f14653..0d6073c9f 100644 --- a/beacon_chain/networking/libp2p_streams_backend.nim +++ b/beacon_chain/networking/libp2p_streams_backend.nim @@ -1,5 +1,5 @@ # beacon_chain -# Copyright (c) 2018-2021 Status Research & Development GmbH +# Copyright (c) 2018-2022 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). @@ -148,7 +148,7 @@ proc readResponseChunk(conn: Connection, peer: Peer, let responseCode = ResponseCode responseCodeByte case responseCode: - of InvalidRequest, ServerError: + of InvalidRequest, ServerError, ResourceUnavailable: let errorMsgChunk = await readChunkPayload(conn, peer, ErrorMsg) errorMsg = if errorMsgChunk.isOk: errorMsgChunk.value