From e8619399f254ac301db7591ddb6c5905347960e7 Mon Sep 17 00:00:00 2001 From: Age Manning Date: Sun, 8 Sep 2019 07:10:36 +1000 Subject: [PATCH] Patch to correct for single byte RPC responses --- beacon_node/eth2-libp2p/src/rpc/codec/base.rs | 8 +++++--- beacon_node/eth2-libp2p/src/rpc/codec/ssz.rs | 10 +++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/beacon_node/eth2-libp2p/src/rpc/codec/base.rs b/beacon_node/eth2-libp2p/src/rpc/codec/base.rs index a8a239867..973567473 100644 --- a/beacon_node/eth2-libp2p/src/rpc/codec/base.rs +++ b/beacon_node/eth2-libp2p/src/rpc/codec/base.rs @@ -101,13 +101,15 @@ where type Error = ::Error; fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { + // if we have only received the response code, wait for more bytes + if src.len() == 1 { + return Ok(None); + } + // using the response code determine which kind of payload needs to be decoded. let response_code = { if let Some(resp_code) = self.response_code { resp_code } else { - // buffer should not be empty - debug_assert!(!src.is_empty()); - let resp_byte = src.split_to(1); let mut resp_code_byte = [0; 1]; resp_code_byte.copy_from_slice(&resp_byte); diff --git a/beacon_node/eth2-libp2p/src/rpc/codec/ssz.rs b/beacon_node/eth2-libp2p/src/rpc/codec/ssz.rs index 1966bab62..d0e4d01cf 100644 --- a/beacon_node/eth2-libp2p/src/rpc/codec/ssz.rs +++ b/beacon_node/eth2-libp2p/src/rpc/codec/ssz.rs @@ -4,7 +4,7 @@ use crate::rpc::{ protocol::{ProtocolId, RPCError}, }; use crate::rpc::{ErrorMessage, RPCErrorResponse, RPCRequest, RPCResponse}; -use bytes::{Bytes, BytesMut}; +use bytes::{BufMut, Bytes, BytesMut}; use ssz::{Decode, Encode}; use tokio::codec::{Decoder, Encoder}; use unsigned_varint::codec::UviBytes; @@ -56,6 +56,10 @@ impl Encoder for SSZInboundCodec { .inner .encode(Bytes::from(bytes), dst) .map_err(RPCError::from); + } else { + // payload is empty, add a 0-byte length prefix + dst.reserve(1); + dst.put_u8(0); } Ok(()) } @@ -152,8 +156,8 @@ impl Decoder for SSZOutboundCodec { type Error = RPCError; fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { - if src.is_empty() { - // the object sent could be empty. We return the empty object if this is the case + if src.len() == 1 && src[0] == 0_u8 { + // the object is empty. We return the empty object if this is the case match self.protocol.message_name.as_str() { "hello" => match self.protocol.version.as_str() { "1" => Err(RPCError::Custom(