Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Retain compatibility with network protocol.
Browse files Browse the repository at this point in the history
  • Loading branch information
cheme committed Apr 15, 2020
1 parent ecb1c39 commit 619b454
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 8 deletions.
28 changes: 20 additions & 8 deletions client/network/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use sp_runtime::traits::{
Block as BlockT, Header as HeaderT, NumberFor, One, Zero, CheckedSub
};
use sp_arithmetic::traits::SaturatedConversion;
use message::{BlockAnnounce, Message};
use message::{BlockAnnounce, Message, MessageV6};
use message::generic::{Message as GenericMessage, ConsensusMessage, Roles};
use prometheus_endpoint::{Registry, Gauge, GaugeVec, HistogramVec, PrometheusError, Opts, register, U64};
use sync::{ChainSync, SyncState};
Expand Down Expand Up @@ -91,7 +91,7 @@ const MAX_KNOWN_BLOCKS: usize = 1024; // ~32kb per peer + LruHashSet overhead
const MAX_KNOWN_EXTRINSICS: usize = 4096; // ~128kb per peer + overhead

/// Current protocol version.
pub(crate) const CURRENT_VERSION: u32 = 6;
pub(crate) const CURRENT_VERSION: u32 = 7;
/// Lowest version we support
pub(crate) const MIN_VERSION: u32 = 3;

Expand Down Expand Up @@ -524,12 +524,24 @@ impl<B: BlockT, H: ExHashT> Protocol<B, H> {
data: BytesMut,
) -> CustomMessageOutcome<B> {

let message = match <Message<B> as Decode>::decode(&mut &data[..]) {
Ok(message) => message,
Err(err) => {
debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what());
self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE);
return CustomMessageOutcome::None;
let input = &mut &data[..];
let decoded_result = <Message<B> as Decode>::decode(input);
let all_read = input.is_empty();
let message = match (all_read, decoded_result) {
(true, Ok(message)) => message,
(false, _) | (_, Err(_)) => match <MessageV6<B> as Decode>::decode(&mut &data[..]) {
Ok(message) => if let Some(message) = message.into_latest() {
message
} else {
debug!(target: "sync", "Couldn't call packet sent by {}: {:?}: {}", who, data, "Invalid input.");
self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE);
return CustomMessageOutcome::None;
},
Err(err) => {
debug!(target: "sync", "Couldn't decode packet sent by {}: {:?}: {}", who, data, err.what());
self.peerset_handle.report_peer(who.clone(), rep::BAD_MESSAGE);
return CustomMessageOutcome::None;
}
}
};

Expand Down
106 changes: 106 additions & 0 deletions client/network/src/protocol/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub use self::generic::{
RemoteChangesRequest, RemoteChangesResponse,
FinalityProofRequest, FinalityProofResponse,
FromBlock, RemoteReadChildRequest, Roles,
RemoteReadChildRequestV6,
};
use sc_client_api::StorageProof;

Expand All @@ -39,6 +40,17 @@ pub type Message<B> = generic::Message<
<B as BlockT>::Extrinsic,
>;

/// Type alias for using the message type using block type parameters.
///
/// This could be removed as soon as MIN_VERSION switch to 7.
pub type MessageV6<B> = generic::MessageV6<
<B as BlockT>::Header,
<B as BlockT>::Hash,
<<B as BlockT>::Header as HeaderT>::Number,
<B as BlockT>::Extrinsic,
>;


/// Type alias for using the status type using block type parameters.
pub type Status<B> = generic::Status<
<B as BlockT>::Hash,
Expand Down Expand Up @@ -237,6 +249,49 @@ pub mod generic {
Number(Number),
}

/// A protocol V6 network message, this is only for backward compatibility.
/// It should only be use when we fail to decode a message
/// with the latest encoding.
#[derive(Decode)]
pub enum MessageV6<Header, Hash, Number, Extrinsic> {
/// Status packet.
Status(Status<Hash, Number>),
/// Block request.
BlockRequest(BlockRequest<Hash, Number>),
/// Block response.
BlockResponse(BlockResponse<Header, Hash, Extrinsic>),
/// Block announce.
BlockAnnounce(BlockAnnounce<Header>),
/// Transactions.
Transactions(Transactions<Extrinsic>),
/// Consensus protocol message.
Consensus(ConsensusMessage),
/// Remote method call request.
RemoteCallRequest(RemoteCallRequest<Hash>),
/// Remote method call response.
RemoteCallResponse(RemoteCallResponse),
/// Remote storage read request.
RemoteReadRequest(RemoteReadRequest<Hash>),
/// Remote storage read response.
RemoteReadResponse(RemoteReadResponse),
/// Remote header request.
RemoteHeaderRequest(RemoteHeaderRequest<Number>),
/// Remote header response.
RemoteHeaderResponse(RemoteHeaderResponse<Header>),
/// Remote changes request.
RemoteChangesRequest(RemoteChangesRequest<Hash>),
/// Remote changes response.
RemoteChangesResponse(RemoteChangesResponse<Number, Hash>),
/// Remote child storage read request.
RemoteReadChildRequest(RemoteReadChildRequestV6<Hash>),
/// Finality proof request.
FinalityProofRequest(FinalityProofRequest<Hash>),
/// Finality proof response.
FinalityProofResponse(FinalityProofResponse<Hash>),
/// Batch of consensus protocol messages.
ConsensusBatch(Vec<ConsensusMessage>),
}

/// A network message.
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
pub enum Message<Header, Hash, Number, Extrinsic> {
Expand Down Expand Up @@ -278,6 +333,39 @@ pub mod generic {
ConsensusBatch(Vec<ConsensusMessage>),
}

impl<Header, Hash, Number, Extrinsic> MessageV6<Header, Hash, Number, Extrinsic> {
/// Get matching latest protocol message for a protocol V6 message.
///
/// Note that this function expect that V6 message are only created
/// after a failed latest message decoding, so we do only convert for diverging
/// decoding path.
pub fn into_latest(self) -> Option<Message<Header, Hash, Number, Extrinsic>> {
match self {
MessageV6::RemoteReadChildRequest(RemoteReadChildRequestV6 {
id,
block,
storage_key,
child_info: _,
child_type,
keys,
}) => {
// V6 protocol only got implementation for child type 1.
if child_type != 1 {
None
} else {
Some(Message::RemoteReadChildRequest(RemoteReadChildRequest {
id,
block,
storage_key,
keys,
}))
}
},
_ => None,
}
}
}

impl<Header, Hash, Number, Extrinsic> Message<Header, Hash, Number, Extrinsic> {
/// Message id useful for logging.
pub fn id(&self) -> &'static str {
Expand Down Expand Up @@ -468,6 +556,24 @@ pub mod generic {
pub keys: Vec<Vec<u8>>,
}

#[derive(Decode)]
/// Backward compatibility remote storage read child request.
pub struct RemoteReadChildRequestV6<H> {
/// Unique request id.
pub id: RequestId,
/// Block at which to perform call.
pub block: H,
/// Child Storage key.
pub storage_key: Vec<u8>,
/// Child trie source information.
pub child_info: Vec<u8>,
/// Child type, its required to resolve `child_info`
/// content and choose child implementation.
pub child_type: u32,
/// Storage key.
pub keys: Vec<Vec<u8>>,
}

#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
/// Remote storage read child request.
pub struct RemoteReadChildRequest<H> {
Expand Down

0 comments on commit 619b454

Please sign in to comment.