// This file is part of Substrate. // Copyright (C) Parity Technologies (UK) Ltd. // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 // This program 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. // This program 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 this program. If not, see . //! Network packet message types. These get serialized and put into the lower level protocol //! payload. use codec::{Decode, Encode}; use sc_client_api::StorageProof; use sc_network_common::message::RequestId; use sp_runtime::traits::{Block as BlockT, Header as HeaderT}; /// Type alias for using the message type using block type parameters. #[allow(unused)] pub type Message = generic::Message< ::Header, ::Hash, <::Header as HeaderT>::Number, ::Extrinsic, >; /// 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: StorageProof, } #[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: StorageProof, } /// Generic types. pub mod generic { use super::{RemoteCallResponse, RemoteReadResponse}; use codec::{Decode, Encode, Input}; use sc_client_api::StorageProof; use sc_network_common::{ message::RequestId, role::Roles, sync::message::{ generic::{BlockRequest, BlockResponse}, BlockAnnounce, }, }; use sp_runtime::ConsensusEngineId; /// Consensus is mostly opaque to us #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct ConsensusMessage { /// Identifies consensus engine. pub protocol: ConsensusEngineId, /// Message payload. pub data: Vec, } /// 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
), /// Consensus protocol message. // NOTE: index is incremented by 1 due to transaction-related // message that was removed #[codec(index = 6)] 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 response. RemoteChangesResponse(RemoteChangesResponse), /// Remote child storage read request. RemoteReadChildRequest(RemoteReadChildRequest), /// Batch of consensus protocol messages. // NOTE: index is incremented by 2 due to finality proof related // messages that were removed. #[codec(index = 17)] ConsensusBatch(Vec), } /// Status sent on connection. // TODO https://github.com/paritytech/substrate/issues/4674: replace the `Status` // struct with this one, after waiting a few releases beyond `NetworkSpecialization`'s // removal (https://github.com/paritytech/substrate/pull/4665) // // and set MIN_VERSION to 6. #[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)] pub struct CompactStatus { /// 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, } /// Status sent on connection. #[derive(Debug, PartialEq, Eq, Clone, Encode)] 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, /// DEPRECATED. Chain-specific status. pub chain_status: Vec, } impl Decode for Status { fn decode(value: &mut I) -> Result { const LAST_CHAIN_STATUS_VERSION: u32 = 5; let compact = CompactStatus::decode(value)?; let chain_status = match >::decode(value) { Ok(v) => v, Err(e) => if compact.version <= LAST_CHAIN_STATUS_VERSION { return Err(e) } else { Vec::new() }, }; let CompactStatus { version, min_supported_version, roles, best_number, best_hash, genesis_hash, } = compact; Ok(Self { version, min_supported_version, roles, best_number, best_hash, genesis_hash, chain_status, }) } } #[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 keys: 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 keys: 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: StorageProof, } #[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 child node key which changes are requested. pub storage_key: Option>, /// 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: StorageProof, } }