Merge branch 'rpc-fix' into docker-env
This commit is contained in:
commit
c975828195
@ -1,6 +1,7 @@
|
|||||||
use super::methods::*;
|
use super::methods::*;
|
||||||
use libp2p::core::{upgrade, InboundUpgrade, OutboundUpgrade, UpgradeInfo};
|
use libp2p::core::{upgrade, InboundUpgrade, OutboundUpgrade, UpgradeInfo};
|
||||||
use ssz::{impl_decode_via_from, impl_encode_via_from, ssz_encode, Decode, Encode};
|
use ssz::{impl_decode_via_from, impl_encode_via_from, ssz_encode, Decode, Encode};
|
||||||
|
use ssz_derive::{Decode, Encode};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
@ -31,7 +32,7 @@ impl Default for RPCProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A monotonic counter for ordering `RPCRequest`s.
|
/// A monotonic counter for ordering `RPCRequest`s.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct RequestId(u64);
|
pub struct RequestId(u64);
|
||||||
|
|
||||||
impl RequestId {
|
impl RequestId {
|
||||||
@ -115,65 +116,67 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A helper structed used to obtain SSZ serialization for RPC messages.
|
||||||
|
#[derive(Encode, Decode, Default)]
|
||||||
|
struct SszContainer {
|
||||||
|
/// Note: the `is_request` field is not included in the spec.
|
||||||
|
///
|
||||||
|
/// We are unable to determine a request from a response unless we add some flag to the
|
||||||
|
/// packet. Here we have added a bool (encoded as 1 byte) which is set to `1` if the
|
||||||
|
/// message is a request.
|
||||||
|
is_request: bool,
|
||||||
|
id: u64,
|
||||||
|
other: u16,
|
||||||
|
bytes: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE!
|
// NOTE!
|
||||||
//
|
//
|
||||||
// This code has not been tested, it is a placeholder until we can update to the new libp2p
|
// This code has not been tested, it is a placeholder until we can update to the new libp2p
|
||||||
// spec.
|
// spec.
|
||||||
fn decode(packet: Vec<u8>) -> Result<RPCEvent, DecodeError> {
|
fn decode(packet: Vec<u8>) -> Result<RPCEvent, DecodeError> {
|
||||||
let mut builder = ssz::SszDecoderBuilder::new(&packet);
|
let msg = SszContainer::from_ssz_bytes(&packet)?;
|
||||||
|
|
||||||
builder.register_type::<bool>()?;
|
if msg.is_request {
|
||||||
builder.register_type::<RequestId>()?;
|
let body = match RPCMethod::from(msg.other) {
|
||||||
builder.register_type::<u16>()?;
|
RPCMethod::Hello => RPCRequest::Hello(HelloMessage::from_ssz_bytes(&msg.bytes)?),
|
||||||
builder.register_type::<Vec<u8>>()?;
|
RPCMethod::Goodbye => RPCRequest::Goodbye(GoodbyeReason::from_ssz_bytes(&msg.bytes)?),
|
||||||
|
|
||||||
let mut decoder = builder.build()?;
|
|
||||||
|
|
||||||
let request: bool = decoder.decode_next()?;
|
|
||||||
let id: RequestId = decoder.decode_next()?;
|
|
||||||
let method_id: u16 = decoder.decode_next()?;
|
|
||||||
let bytes: Vec<u8> = decoder.decode_next()?;
|
|
||||||
|
|
||||||
if request {
|
|
||||||
let body = match RPCMethod::from(method_id) {
|
|
||||||
RPCMethod::Hello => RPCRequest::Hello(HelloMessage::from_ssz_bytes(&bytes)?),
|
|
||||||
RPCMethod::Goodbye => RPCRequest::Goodbye(GoodbyeReason::from_ssz_bytes(&bytes)?),
|
|
||||||
RPCMethod::BeaconBlockRoots => {
|
RPCMethod::BeaconBlockRoots => {
|
||||||
RPCRequest::BeaconBlockRoots(BeaconBlockRootsRequest::from_ssz_bytes(&bytes)?)
|
RPCRequest::BeaconBlockRoots(BeaconBlockRootsRequest::from_ssz_bytes(&msg.bytes)?)
|
||||||
}
|
|
||||||
RPCMethod::BeaconBlockHeaders => {
|
|
||||||
RPCRequest::BeaconBlockHeaders(BeaconBlockHeadersRequest::from_ssz_bytes(&bytes)?)
|
|
||||||
}
|
}
|
||||||
|
RPCMethod::BeaconBlockHeaders => RPCRequest::BeaconBlockHeaders(
|
||||||
|
BeaconBlockHeadersRequest::from_ssz_bytes(&msg.bytes)?,
|
||||||
|
),
|
||||||
RPCMethod::BeaconBlockBodies => {
|
RPCMethod::BeaconBlockBodies => {
|
||||||
RPCRequest::BeaconBlockBodies(BeaconBlockBodiesRequest::from_ssz_bytes(&bytes)?)
|
RPCRequest::BeaconBlockBodies(BeaconBlockBodiesRequest::from_ssz_bytes(&msg.bytes)?)
|
||||||
}
|
}
|
||||||
RPCMethod::BeaconChainState => {
|
RPCMethod::BeaconChainState => {
|
||||||
RPCRequest::BeaconChainState(BeaconChainStateRequest::from_ssz_bytes(&bytes)?)
|
RPCRequest::BeaconChainState(BeaconChainStateRequest::from_ssz_bytes(&msg.bytes)?)
|
||||||
}
|
}
|
||||||
RPCMethod::Unknown => return Err(DecodeError::UnknownRPCMethod),
|
RPCMethod::Unknown => return Err(DecodeError::UnknownRPCMethod),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(RPCEvent::Request {
|
Ok(RPCEvent::Request {
|
||||||
id,
|
id: RequestId::from(msg.id),
|
||||||
method_id,
|
method_id: msg.other,
|
||||||
body,
|
body,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// we have received a response
|
// we have received a response
|
||||||
else {
|
else {
|
||||||
let result = match RPCMethod::from(method_id) {
|
let result = match RPCMethod::from(msg.other) {
|
||||||
RPCMethod::Hello => RPCResponse::Hello(HelloMessage::from_ssz_bytes(&bytes)?),
|
RPCMethod::Hello => RPCResponse::Hello(HelloMessage::from_ssz_bytes(&msg.bytes)?),
|
||||||
RPCMethod::BeaconBlockRoots => {
|
RPCMethod::BeaconBlockRoots => {
|
||||||
RPCResponse::BeaconBlockRoots(BeaconBlockRootsResponse::from_ssz_bytes(&bytes)?)
|
RPCResponse::BeaconBlockRoots(BeaconBlockRootsResponse::from_ssz_bytes(&msg.bytes)?)
|
||||||
}
|
|
||||||
RPCMethod::BeaconBlockHeaders => {
|
|
||||||
RPCResponse::BeaconBlockHeaders(BeaconBlockHeadersResponse::from_ssz_bytes(&bytes)?)
|
|
||||||
}
|
|
||||||
RPCMethod::BeaconBlockBodies => {
|
|
||||||
RPCResponse::BeaconBlockBodies(BeaconBlockBodiesResponse::from_ssz_bytes(&packet)?)
|
|
||||||
}
|
}
|
||||||
|
RPCMethod::BeaconBlockHeaders => RPCResponse::BeaconBlockHeaders(
|
||||||
|
BeaconBlockHeadersResponse::from_ssz_bytes(&msg.bytes)?,
|
||||||
|
),
|
||||||
|
RPCMethod::BeaconBlockBodies => RPCResponse::BeaconBlockBodies(
|
||||||
|
BeaconBlockBodiesResponse::from_ssz_bytes(&msg.bytes)?,
|
||||||
|
),
|
||||||
RPCMethod::BeaconChainState => {
|
RPCMethod::BeaconChainState => {
|
||||||
RPCResponse::BeaconChainState(BeaconChainStateResponse::from_ssz_bytes(&packet)?)
|
RPCResponse::BeaconChainState(BeaconChainStateResponse::from_ssz_bytes(&msg.bytes)?)
|
||||||
}
|
}
|
||||||
// We should never receive a goodbye response; it is invalid.
|
// We should never receive a goodbye response; it is invalid.
|
||||||
RPCMethod::Goodbye => return Err(DecodeError::UnknownRPCMethod),
|
RPCMethod::Goodbye => return Err(DecodeError::UnknownRPCMethod),
|
||||||
@ -181,8 +184,8 @@ fn decode(packet: Vec<u8>) -> Result<RPCEvent, DecodeError> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Ok(RPCEvent::Response {
|
Ok(RPCEvent::Response {
|
||||||
id,
|
id: RequestId::from(msg.id),
|
||||||
method_id,
|
method_id: msg.other,
|
||||||
result,
|
result,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -208,80 +211,44 @@ impl Encode for RPCEvent {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE!
|
|
||||||
//
|
|
||||||
// This code has not been tested, it is a placeholder until we can update to the new libp2p
|
|
||||||
// spec.
|
|
||||||
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
fn ssz_append(&self, buf: &mut Vec<u8>) {
|
||||||
let offset = <bool as Encode>::ssz_fixed_len()
|
let container = match self {
|
||||||
+ <u16 as Encode>::ssz_fixed_len()
|
|
||||||
+ <Vec<u8> as Encode>::ssz_fixed_len();
|
|
||||||
|
|
||||||
let mut encoder = ssz::SszEncoder::container(buf, offset);
|
|
||||||
|
|
||||||
match self {
|
|
||||||
RPCEvent::Request {
|
RPCEvent::Request {
|
||||||
id,
|
id,
|
||||||
method_id,
|
method_id,
|
||||||
body,
|
body,
|
||||||
} => {
|
} => SszContainer {
|
||||||
encoder.append(&true);
|
is_request: true,
|
||||||
encoder.append(id);
|
id: (*id).into(),
|
||||||
encoder.append(method_id);
|
other: (*method_id).into(),
|
||||||
|
bytes: match body {
|
||||||
// Encode the `body` as a `Vec<u8>`.
|
RPCRequest::Hello(body) => body.as_ssz_bytes(),
|
||||||
match body {
|
RPCRequest::Goodbye(body) => body.as_ssz_bytes(),
|
||||||
RPCRequest::Hello(body) => {
|
RPCRequest::BeaconBlockRoots(body) => body.as_ssz_bytes(),
|
||||||
encoder.append(&body.as_ssz_bytes());
|
RPCRequest::BeaconBlockHeaders(body) => body.as_ssz_bytes(),
|
||||||
}
|
RPCRequest::BeaconBlockBodies(body) => body.as_ssz_bytes(),
|
||||||
RPCRequest::Goodbye(body) => {
|
RPCRequest::BeaconChainState(body) => body.as_ssz_bytes(),
|
||||||
encoder.append(&body.as_ssz_bytes());
|
},
|
||||||
}
|
},
|
||||||
RPCRequest::BeaconBlockRoots(body) => {
|
|
||||||
encoder.append(&body.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
RPCRequest::BeaconBlockHeaders(body) => {
|
|
||||||
encoder.append(&body.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
RPCRequest::BeaconBlockBodies(body) => {
|
|
||||||
encoder.append(&body.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
RPCRequest::BeaconChainState(body) => {
|
|
||||||
encoder.append(&body.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RPCEvent::Response {
|
RPCEvent::Response {
|
||||||
id,
|
id,
|
||||||
method_id,
|
method_id,
|
||||||
result,
|
result,
|
||||||
} => {
|
} => SszContainer {
|
||||||
encoder.append(&true);
|
is_request: false,
|
||||||
encoder.append(id);
|
id: (*id).into(),
|
||||||
encoder.append(method_id);
|
other: (*method_id).into(),
|
||||||
|
bytes: match result {
|
||||||
|
RPCResponse::Hello(response) => response.as_ssz_bytes(),
|
||||||
|
RPCResponse::BeaconBlockRoots(response) => response.as_ssz_bytes(),
|
||||||
|
RPCResponse::BeaconBlockHeaders(response) => response.as_ssz_bytes(),
|
||||||
|
RPCResponse::BeaconBlockBodies(response) => response.as_ssz_bytes(),
|
||||||
|
RPCResponse::BeaconChainState(response) => response.as_ssz_bytes(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
match result {
|
container.ssz_append(buf)
|
||||||
RPCResponse::Hello(response) => {
|
|
||||||
encoder.append(&response.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
RPCResponse::BeaconBlockRoots(response) => {
|
|
||||||
encoder.append(&response.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
RPCResponse::BeaconBlockHeaders(response) => {
|
|
||||||
encoder.append(&response.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
RPCResponse::BeaconBlockBodies(response) => {
|
|
||||||
encoder.append(&response.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
RPCResponse::BeaconChainState(response) => {
|
|
||||||
encoder.append(&response.as_ssz_bytes());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finalize the encoder, writing to `buf`.
|
|
||||||
encoder.finalize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user