sc_network/protocol/
message.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Network packet message types. These get serialized and put into the lower level protocol
20//! payload.
21
22use codec::{Decode, Encode};
23use sc_client_api::StorageProof;
24use sc_network_common::message::RequestId;
25use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
26
27/// Type alias for using the message type using block type parameters.
28#[allow(unused)]
29pub type Message<B> = generic::Message<
30	<B as BlockT>::Header,
31	<B as BlockT>::Hash,
32	<<B as BlockT>::Header as HeaderT>::Number,
33	<B as BlockT>::Extrinsic,
34>;
35
36/// Remote call response.
37#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
38pub struct RemoteCallResponse {
39	/// Id of a request this response was made for.
40	pub id: RequestId,
41	/// Execution proof.
42	pub proof: StorageProof,
43}
44
45#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
46/// Remote read response.
47pub struct RemoteReadResponse {
48	/// Id of a request this response was made for.
49	pub id: RequestId,
50	/// Read proof.
51	pub proof: StorageProof,
52}
53
54/// Generic types.
55pub mod generic {
56	use super::{RemoteCallResponse, RemoteReadResponse};
57	use codec::{Decode, Encode, Input};
58	use sc_client_api::StorageProof;
59	use sc_network_common::{
60		message::RequestId,
61		role::Roles,
62		sync::message::{
63			generic::{BlockRequest, BlockResponse},
64			BlockAnnounce,
65		},
66	};
67	use sp_runtime::ConsensusEngineId;
68
69	/// Consensus is mostly opaque to us
70	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
71	pub struct ConsensusMessage {
72		/// Identifies consensus engine.
73		pub protocol: ConsensusEngineId,
74		/// Message payload.
75		pub data: Vec<u8>,
76	}
77
78	/// A network message.
79	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
80	pub enum Message<Header, Hash, Number, Extrinsic> {
81		/// Status packet.
82		Status(Status<Hash, Number>),
83		/// Block request.
84		BlockRequest(BlockRequest<Hash, Number>),
85		/// Block response.
86		BlockResponse(BlockResponse<Header, Hash, Extrinsic>),
87		/// Block announce.
88		BlockAnnounce(BlockAnnounce<Header>),
89		/// Consensus protocol message.
90		// NOTE: index is incremented by 1 due to transaction-related
91		// message that was removed
92		#[codec(index = 6)]
93		Consensus(ConsensusMessage),
94		/// Remote method call request.
95		RemoteCallRequest(RemoteCallRequest<Hash>),
96		/// Remote method call response.
97		RemoteCallResponse(RemoteCallResponse),
98		/// Remote storage read request.
99		RemoteReadRequest(RemoteReadRequest<Hash>),
100		/// Remote storage read response.
101		RemoteReadResponse(RemoteReadResponse),
102		/// Remote header request.
103		RemoteHeaderRequest(RemoteHeaderRequest<Number>),
104		/// Remote header response.
105		RemoteHeaderResponse(RemoteHeaderResponse<Header>),
106		/// Remote changes request.
107		RemoteChangesRequest(RemoteChangesRequest<Hash>),
108		/// Remote changes response.
109		RemoteChangesResponse(RemoteChangesResponse<Number, Hash>),
110		/// Remote child storage read request.
111		RemoteReadChildRequest(RemoteReadChildRequest<Hash>),
112		/// Batch of consensus protocol messages.
113		// NOTE: index is incremented by 2 due to finality proof related
114		// messages that were removed.
115		#[codec(index = 17)]
116		ConsensusBatch(Vec<ConsensusMessage>),
117	}
118
119	/// Status sent on connection.
120	// TODO https://github.com/paritytech/substrate/issues/4674: replace the `Status`
121	// struct with this one, after waiting a few releases beyond `NetworkSpecialization`'s
122	// removal (https://github.com/paritytech/substrate/pull/4665)
123	//
124	// and set MIN_VERSION to 6.
125	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
126	pub struct CompactStatus<Hash, Number> {
127		/// Protocol version.
128		pub version: u32,
129		/// Minimum supported version.
130		pub min_supported_version: u32,
131		/// Supported roles.
132		pub roles: Roles,
133		/// Best block number.
134		pub best_number: Number,
135		/// Best block hash.
136		pub best_hash: Hash,
137		/// Genesis block hash.
138		pub genesis_hash: Hash,
139	}
140
141	/// Status sent on connection.
142	#[derive(Debug, PartialEq, Eq, Clone, Encode)]
143	pub struct Status<Hash, Number> {
144		/// Protocol version.
145		pub version: u32,
146		/// Minimum supported version.
147		pub min_supported_version: u32,
148		/// Supported roles.
149		pub roles: Roles,
150		/// Best block number.
151		pub best_number: Number,
152		/// Best block hash.
153		pub best_hash: Hash,
154		/// Genesis block hash.
155		pub genesis_hash: Hash,
156		/// DEPRECATED. Chain-specific status.
157		pub chain_status: Vec<u8>,
158	}
159
160	impl<Hash: Decode, Number: Decode> Decode for Status<Hash, Number> {
161		fn decode<I: Input>(value: &mut I) -> Result<Self, codec::Error> {
162			const LAST_CHAIN_STATUS_VERSION: u32 = 5;
163			let compact = CompactStatus::decode(value)?;
164			let chain_status = match <Vec<u8>>::decode(value) {
165				Ok(v) => v,
166				Err(e) =>
167					if compact.version <= LAST_CHAIN_STATUS_VERSION {
168						return Err(e)
169					} else {
170						Vec::new()
171					},
172			};
173
174			let CompactStatus {
175				version,
176				min_supported_version,
177				roles,
178				best_number,
179				best_hash,
180				genesis_hash,
181			} = compact;
182
183			Ok(Self {
184				version,
185				min_supported_version,
186				roles,
187				best_number,
188				best_hash,
189				genesis_hash,
190				chain_status,
191			})
192		}
193	}
194
195	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
196	/// Remote call request.
197	pub struct RemoteCallRequest<H> {
198		/// Unique request id.
199		pub id: RequestId,
200		/// Block at which to perform call.
201		pub block: H,
202		/// Method name.
203		pub method: String,
204		/// Call data.
205		pub data: Vec<u8>,
206	}
207
208	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
209	/// Remote storage read request.
210	pub struct RemoteReadRequest<H> {
211		/// Unique request id.
212		pub id: RequestId,
213		/// Block at which to perform call.
214		pub block: H,
215		/// Storage key.
216		pub keys: Vec<Vec<u8>>,
217	}
218
219	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
220	/// Remote storage read child request.
221	pub struct RemoteReadChildRequest<H> {
222		/// Unique request id.
223		pub id: RequestId,
224		/// Block at which to perform call.
225		pub block: H,
226		/// Child Storage key.
227		pub storage_key: Vec<u8>,
228		/// Storage key.
229		pub keys: Vec<Vec<u8>>,
230	}
231
232	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
233	/// Remote header request.
234	pub struct RemoteHeaderRequest<N> {
235		/// Unique request id.
236		pub id: RequestId,
237		/// Block number to request header for.
238		pub block: N,
239	}
240
241	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
242	/// Remote header response.
243	pub struct RemoteHeaderResponse<Header> {
244		/// Id of a request this response was made for.
245		pub id: RequestId,
246		/// Header. None if proof generation has failed (e.g. header is unknown).
247		pub header: Option<Header>,
248		/// Header proof.
249		pub proof: StorageProof,
250	}
251
252	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
253	/// Remote changes request.
254	pub struct RemoteChangesRequest<H> {
255		/// Unique request id.
256		pub id: RequestId,
257		/// Hash of the first block of the range (including first) where changes are requested.
258		pub first: H,
259		/// Hash of the last block of the range (including last) where changes are requested.
260		pub last: H,
261		/// Hash of the first block for which the requester has the changes trie root. All other
262		/// affected roots must be proved.
263		pub min: H,
264		/// Hash of the last block that we can use when querying changes.
265		pub max: H,
266		/// Storage child node key which changes are requested.
267		pub storage_key: Option<Vec<u8>>,
268		/// Storage key which changes are requested.
269		pub key: Vec<u8>,
270	}
271
272	#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
273	/// Remote changes response.
274	pub struct RemoteChangesResponse<N, H> {
275		/// Id of a request this response was made for.
276		pub id: RequestId,
277		/// Proof has been generated using block with this number as a max block. Should be
278		/// less than or equal to the RemoteChangesRequest::max block number.
279		pub max: N,
280		/// Changes proof.
281		pub proof: Vec<Vec<u8>>,
282		/// Changes tries roots missing on the requester' node.
283		pub roots: Vec<(N, H)>,
284		/// Missing changes tries roots proof.
285		pub roots_proof: StorageProof,
286	}
287}