// Copyright 2017-2019 Parity Technologies (UK) Ltd. // This file is part of Substrate. // Substrate is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Substrate is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Substrate. If not, see . //! Network packet message types. These get serialized and put into the lower level protocol payload. use bitflags::bitflags; use runtime_primitives::{ConsensusEngineId, traits::{Block as BlockT, Header as HeaderT}}; use parity_codec::{Encode, Decode, Input, Output}; pub use self::generic::{ BlockAnnounce, RemoteCallRequest, RemoteReadRequest, RemoteHeaderRequest, RemoteHeaderResponse, RemoteChangesRequest, RemoteChangesResponse, FinalityProofRequest, FinalityProofResponse, FromBlock, RemoteReadChildRequest, }; /// A unique ID of a request. pub type RequestId = u64; /// Type alias for using the message type using block type parameters. pub type Message = generic::Message< ::Header, ::Hash, <::Header as HeaderT>::Number, ::Extrinsic, >; /// Type alias for using the status type using block type parameters. pub type Status = generic::Status< ::Hash, <::Header as HeaderT>::Number, >; /// Type alias for using the block request type using block type parameters. pub type BlockRequest = generic::BlockRequest< ::Hash, <::Header as HeaderT>::Number, >; /// Type alias for using the BlockData type using block type parameters. pub type BlockData = generic::BlockData< ::Header, ::Hash, ::Extrinsic, >; /// Type alias for using the BlockResponse type using block type parameters. pub type BlockResponse = generic::BlockResponse< ::Header, ::Hash, ::Extrinsic, >; /// A set of transactions. pub type Transactions = Vec; // Bits of block data and associated artifacts to request. bitflags! { /// Node roles bitmask. pub struct BlockAttributes: u8 { /// Include block header. const HEADER = 0b00000001; /// Include block body. const BODY = 0b00000010; /// Include block receipt. const RECEIPT = 0b00000100; /// Include block message queue. const MESSAGE_QUEUE = 0b00001000; /// Include a justification for the block. const JUSTIFICATION = 0b00010000; } } impl Encode for BlockAttributes { fn encode_to(&self, dest: &mut T) { dest.push_byte(self.bits()) } } impl Decode for BlockAttributes { fn decode(input: &mut I) -> Option { Self::from_bits(input.read_byte()?) } } #[derive(Debug, PartialEq, Eq, Clone, Copy, Encode, Decode)] /// Block enumeration direction. pub enum Direction { /// Enumerate in ascending order (from child to parent). Ascending = 0, /// Enumerate in descendfing order (from parent to canonical child). Descending = 1, } /// Remote call response. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct RemoteCallResponse { /// Id of a request this response was made for. pub id: RequestId, /// Execution proof. pub proof: Vec>, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote read response. pub struct RemoteReadResponse { /// Id of a request this response was made for. pub id: RequestId, /// Read proof. pub proof: Vec>, } /// Generic types. pub mod generic { use parity_codec::{Encode, Decode}; use network_libp2p::CustomMessage; use runtime_primitives::Justification; use crate::config::Roles; use super::{ RemoteReadResponse, Transactions, Direction, RequestId, BlockAttributes, RemoteCallResponse, ConsensusEngineId, }; /// Consensus is mostly opaque to us #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct ConsensusMessage { /// Identifies consensus engine. pub engine_id: ConsensusEngineId, /// Message payload. pub data: Vec, } /// Block data sent in the response. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct BlockData { /// Block header hash. pub hash: Hash, /// Block header if requested. pub header: Option
, /// Block body if requested. pub body: Option>, /// Block receipt if requested. pub receipt: Option>, /// Block message queue if requested. pub message_queue: Option>, /// Justification if requested. pub justification: Option, } /// Identifies starting point of a block sequence. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub enum FromBlock { /// Start with given hash. Hash(Hash), /// Start with given block number. Number(Number), } /// A network message. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub enum Message { /// Status packet. Status(Status), /// Block request. BlockRequest(BlockRequest), /// Block response. BlockResponse(BlockResponse), /// Block announce. BlockAnnounce(BlockAnnounce
), /// Transactions. Transactions(Transactions), /// Consensus protocol message. Consensus(ConsensusMessage), /// Remote method call request. RemoteCallRequest(RemoteCallRequest), /// Remote method call response. RemoteCallResponse(RemoteCallResponse), /// Remote storage read request. RemoteReadRequest(RemoteReadRequest), /// Remote storage read response. RemoteReadResponse(RemoteReadResponse), /// Remote header request. RemoteHeaderRequest(RemoteHeaderRequest), /// Remote header response. RemoteHeaderResponse(RemoteHeaderResponse
), /// Remote changes request. RemoteChangesRequest(RemoteChangesRequest), /// Remote changes reponse. RemoteChangesResponse(RemoteChangesResponse), /// Remote child storage read request. RemoteReadChildRequest(RemoteReadChildRequest), /// Finality proof request. FinalityProofRequest(FinalityProofRequest), /// Finality proof reponse. FinalityProofResponse(FinalityProofResponse), /// Chain-specific message #[codec(index = "255")] ChainSpecific(Vec), } impl CustomMessage for Message where Self: Decode + Encode { fn into_bytes(self) -> Vec { self.encode() } fn from_bytes(bytes: &[u8]) -> Result { Decode::decode(&mut &bytes[..]).ok_or(()) } } /// Status sent on connection. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct Status { /// Protocol version. pub version: u32, /// Minimum supported version. pub min_supported_version: u32, /// Supported roles. pub roles: Roles, /// Best block number. pub best_number: Number, /// Best block hash. pub best_hash: Hash, /// Genesis block hash. pub genesis_hash: Hash, /// Chain-specific status. pub chain_status: Vec, } /// Request block data from a peer. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct BlockRequest { /// Unique request id. pub id: RequestId, /// Bits of block data to request. pub fields: BlockAttributes, /// Start from this block. pub from: FromBlock, /// End at this block. An implementation defined maximum is used when unspecified. pub to: Option, /// Sequence direction. pub direction: Direction, /// Maximum number of blocks to return. An implementation defined maximum is used when unspecified. pub max: Option, } /// Response to `BlockRequest` #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct BlockResponse { /// Id of a request this response was made for. pub id: RequestId, /// Block data for the requested sequence. pub blocks: Vec>, } /// Announce a new complete relay chain block on the network. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct BlockAnnounce { /// New block header. pub header: H, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote call request. pub struct RemoteCallRequest { /// Unique request id. pub id: RequestId, /// Block at which to perform call. pub block: H, /// Method name. pub method: String, /// Call data. pub data: Vec, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote storage read request. pub struct RemoteReadRequest { /// Unique request id. pub id: RequestId, /// Block at which to perform call. pub block: H, /// Storage key. pub key: Vec, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote storage read child request. pub struct RemoteReadChildRequest { /// Unique request id. pub id: RequestId, /// Block at which to perform call. pub block: H, /// Child Storage key. pub storage_key: Vec, /// Storage key. pub key: Vec, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote header request. pub struct RemoteHeaderRequest { /// Unique request id. pub id: RequestId, /// Block number to request header for. pub block: N, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote header response. pub struct RemoteHeaderResponse
{ /// Id of a request this response was made for. pub id: RequestId, /// Header. None if proof generation has failed (e.g. header is unknown). pub header: Option
, /// Header proof. pub proof: Vec>, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote changes request. pub struct RemoteChangesRequest { /// Unique request id. pub id: RequestId, /// Hash of the first block of the range (including first) where changes are requested. pub first: H, /// Hash of the last block of the range (including last) where changes are requested. pub last: H, /// Hash of the first block for which the requester has the changes trie root. All other /// affected roots must be proved. pub min: H, /// Hash of the last block that we can use when querying changes. pub max: H, /// Storage key which changes are requested. pub key: Vec, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Remote changes response. pub struct RemoteChangesResponse { /// Id of a request this response was made for. pub id: RequestId, /// Proof has been generated using block with this number as a max block. Should be /// less than or equal to the RemoteChangesRequest::max block number. pub max: N, /// Changes proof. pub proof: Vec>, /// Changes tries roots missing on the requester' node. pub roots: Vec<(N, H)>, /// Missing changes tries roots proof. pub roots_proof: Vec>, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Finality proof request. pub struct FinalityProofRequest { /// Unique request id. pub id: RequestId, /// Hash of the block to request proof for. pub block: H, /// Additional data blob (that both requester and provider understood) required for proving finality. pub request: Vec, } #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] /// Finality proof response. pub struct FinalityProofResponse { /// Id of a request this response was made for. pub id: RequestId, /// Hash of the block (the same as in the FinalityProofRequest). pub block: H, /// Finality proof (if available). pub proof: Option>, } }